web3-react icon indicating copy to clipboard operation
web3-react copied to clipboard

How to properly handle Signer or Provider when using ethers Contract in v8?

Open bomb-on opened this issue 3 years ago • 4 comments

I have an app wrapped in <Web3ReactProvider>:

// App.js
import ethers from 'ethers';
import { useEffect } from 'react';
import { Web3ReactProvider } from '@web3-react/core';
import { hooks, metaMask } from '../connectors/MetaMask';
import Home from './Home';


const connectors = [[metaMask, hooks]];
const getLibrary = provider => new ethers.providers.Web3Provider(provider);

const App = () => {
  useEffect(() => {
    void metaMask.activate(43114);
  }, []);
  return (
    <Web3ReactProvider connectors={connectors} getLibrary={getLibrary}>
      <Home />
    </Web3ReactProvider>
  );
}

export default App;

And I'm trying to read a contract like this:

// Home.js
import { useWeb3React } from '@web3-react/core';
import { useEffect, useMemo } from 'react';
import { Contract } from 'ethers';


const Home = () => {
  const { provider } = useWeb3React();
  const address = '...';
  const abi = '...'

  const signerOrProvider = useMemo(() => {
    if (provider?.['getSigner']) {
      return provider.getSigner();
    } else {
      return provider;
    }
  }, [provider]);

  useEffect(() => {
    try {
        const contract = new Contract(address, abi, signerOrProvider);
        console.log(contract);
    } catch (e) {
      console.error(e)
    }
  }, [abi, address, signerOrProvider]);

  return (
    <div>
      ...
    </div>
  )
}

export default Home;

The error I'm getting:

Error: invalid signer or provider (arg="signerOrProvider", value="[object Object]", version=4.0.49)
    at Object.n [as throwError] (ethers.min.js:1:1)
    at new A (ethers.min.js:1:1)
    at Wallet.js:25:1
    at commitHookEffectListMount (react-dom.development.js:22969:1)
    at commitPassiveMountOnFiber (react-dom.development.js:24702:1)
    at commitPassiveMountEffects_complete (react-dom.development.js:24666:1)
    at commitPassiveMountEffects_begin (react-dom.development.js:24653:1)
    at commitPassiveMountEffects (react-dom.development.js:24641:1)
    at flushPassiveEffectsImpl (react-dom.development.js:26848:1)
    at flushPassiveEffects (react-dom.development.js:26801:1)
    at commitRootImpl (react-dom.development.js:26752:1)
    at commitRoot (react-dom.development.js:26517:1)
    at performSyncWorkOnRoot (react-dom.development.js:25956:1)
    at flushSyncCallbacks (react-dom.development.js:11982:1)
    at react-dom.development.js:25490:1

How exactly can I read a contract if I use web3 versions "@web3-react/core": "^8.0.23-beta.0" and "@web3-react/metamask": "^8.0.19-beta.0"? Thanks!

bomb-on avatar Apr 25 '22 11:04 bomb-on

Can't really tell what exactly is going wrong. However, this is how I've been handling it:

function useContract(contract) {
  const connector = usePriorityConnector();
  const provider = usePriorityProvider();

  contract = contract.connect(provider);

  if (getConnectorName(connector) !== "Network") {
    const signer = provider?.getSigner?.();
    if (signer !== undefined) contract = contract.connect(signer);
  }

  return contract;
}

Then you would simply call it like this:

const address = '...';
const abi = '...'
const myContract = new Contract(address, abi);

const Home = () => {
  const  contract = useContract(myContract);
  ...
}

0xPhaze avatar May 18 '22 00:05 0xPhaze

Hey could you please help with a full example in js? I can't seem to make it work, I couldn't figure out how to use usePriorityConnector... Thanks

Nickblaq avatar Jun 04 '22 13:06 Nickblaq

@0xPhaze Can you please tell how to import usePriorityProvider() or is it a self-written hook?

happy-cutman avatar Sep 29 '22 08:09 happy-cutman

Almost all my projects use this

 async function getLibrary(provider) {
    return new Web3Provider(provider); // From @ethersproject/providers
  } 
   const library = getLibrary(provider)
  const claim = async () => {
    if (isActive && connector.provider) {
      const contract = new Contract(
        ADDRESS,
        ABI,
        await library.getSigner()
      );
    }
  };

qnxdev avatar Apr 27 '23 11:04 qnxdev