[Ethereum] web3-react does not appear to be exposing Ethers.js instance

ethers.jsreactweb3-providers

I've configured the web3-react package in my project (set up with the React Truffle box) but I don't seem to be getting an ethers.js instance in the context.

According to the package page, the web3-react context provides "library: An instantiated ethers.js or web3.js instance (or the low-level provider object)". It seems that I am getting the low-level provider object.

I set things up as follows (I have Ganache configured locally with networkId 13):

App.js

export default function App() {
  const { InjectedConnector } = Connectors;
  const MetaMask = new InjectedConnector({ supportedNetworks: [1, 4, 13] });
  const connectors = { MetaMask };
  return (
    <Web3Provider connectors={connectors} libraryName={'ethers.js'}>
      <Router>
        <Switch>
          <Route exact path='/simple-storage' component={SimpleStorage} />
        </Switch>
      </Router>
    </Web3Provider>
  );
}

SimpleStorage.js

import React, { useEffect, useState } from 'react';
import { useWeb3Context } from 'web3-react';
import SimpleStorageContract from './contracts/SimpleStorage.json'; // ABI

export default function SimpleStorage() {
  const context = useWeb3Context();
  const [storageValue, setStorageValue] = useState(0);
  const [contract, setContract] = useState(null);
  useEffect(() => context.setFirstValidConnector(['MetaMask']), [context]);
  const { account, active, error, library, networkId } = context;

  if (!active && !error) return <div>loading</div>;
  if (error) return <div>error</div>;

  const { Contract, providers } = ethers;

  const instantiate = () => {
    const { networks, abi } = SimpleStorageContract;
    const { address } = networks[networkId];
    const provider = new providers.Web3Provider(library.provider);
    const signer = provider.getSigner();
    const instance = new Contract(address, abi, signer);
    setContract(instance);
  };
...

Here is what I get from the context, which I believe is the MetaMask-injected web3 provider:

react3-web library

{
  "_isProvider": true,
  "_events": [],
  "_emitted": {
    "block": -2
  },
  "formatter": {
    "formats": {
      "transaction": {},
      "transactionRequest": {},
      "receiptLog": {},
      "receipt": {},
      "block": {},
      "blockWithTransactions": {},
      "filter": {},
      "filterLog": {}
    }
  },
  "anyNetwork": false,
  "_networkPromise": {},
  "_maxInternalBlockNumber": -1024,
  "_lastBlockNumber": -2,
  "_pollingInterval": 4000,
  "_fastQueryDate": 0,
  "connection": {
    "url": "metamask"
  },
  "_nextId": 42,
  "provider": {
    "_events": {},
    "_eventsCount": 3,
    "_maxListeners": 100,
    "isMetaMask": true,
    "_state": {
      "sentWarnings": {
        "enable": true,
        "experimentalMethods": false,
        "send": false,
        "events": {
          "chainIdChanged": false,
          "close": false,
          "data": false,
          "networkChanged": true,
          "notification": false
        },
        "autoRefresh": true,
        "publicConfigStore": false
      },
      "isConnected": true,
      "accounts": [
        "0x8cab72aad873e9450b10fa785df981986c3dea18"
      ],
      "isUnlocked": true
    },
    "_metamask": {},
    "selectedAddress": "0x8cab72aad873e9450b10fa785df981986c3dea18",
    "networkVersion": "13",
    "chainId": "0xd",
    "_publicConfigStore": {
      "_events": {
        "update": [
          null,
          null,
          null
        ]
      },
      "_eventsCount": 1,
      "_state": {
        "isUnlocked": true,
        "chainId": "0xd",
        "networkVersion": "13"
      }
    },
    "_rpcEngine": {
      "_events": {},
      "_eventsCount": 0,
      "_middleware": [
        null,
        null,
        null
      ]
    },
    "autoRefreshOnNetworkChange": false
  }
}

How can I get the instantiated Ethers.js from the context? As you can see I've imported ethers to interact with the contract but but doesn't that defeat the purpose of (presumably) having it available from the context?

Best Answer

In fact with web3-react:

const provider = new providers.Web3Provider(library.provider);

is equal to:

const context = useWeb3React();
const { library } = context;

Then you can do everything that provider do using library

Related Topic