Ethers.js: Metamask issue, no account 0 (resolved: call window.ethereum.enable first)

Created on 23 Feb 2019  路  11Comments  路  Source: ethers-io/ethers.js

I'm trying to use metamask with ethersjs to sign transactions.

I wrap the provider and get the signer according to the docs and the discussion here: #308

This is my code:

        if (typeof  window.web3 !== undefined) {
            const provider = new providers.Web3Provider(window.web3.currentProvider)
            const network = (await provider.getNetwork()).chainId
            const staking = new Contract(
                Staking.networks[network].address,
                Staking.abi,
                provider.getSigner(0)
            )
            let tx = await staking.stake(utils.parseEther(amount.toString()))
            await provider.waitForTransaction(tx.hash)
        }

When I try to execute the transaction the metamask window never pops up, instead I get an error:

Error: unknown account #0 (operation="getAddress", version=4.0.25)
    at Object.n [as throwError] (ethers.min.js?e7ea:1)
    at eval (ethers.min.js?e7ea:1)

Extra info: I have turned metamask privacy settings off and am using Ganache

discussion

Most helpful comment

Awesome!

A couple beers keep you happy after finding a bug though, because you can legitimately blame the beer. :)

All 11 comments

Have you called window.ethereum.enable()? This was a recent addition to MetaMask...

No I thought disabling privacy settings would circumvent this. Will try and post update.

Is it called on that object specifically or on the ethersjs wrapped provider? I find different examples.

Sorry wasn't home and on mobile therefore the stupid question.

It seems that window.ethereum is different than window.web3 , they both exist.
Calling window.ethereum.enable() results in a metamask popup

image

However what I find kind of inefficient is thatwindow.ethereum doesn't include a provider. Thus I have to install the web3 dependency to call new Web3(window.ethereum) to then wrap that in an ethers.js provider.

Sidenote: I don't like using web3 but I don't like to bloat up my bundle size either

After calling window.ethereum.enable() I am receiving

inpage.js:1 MetaMask - RPC Error: Internal JSON-RPC error. {code: -32603, message: "Internal JSON-RPC error."}

if (typeof window.ethereum !== undefined) { await window.ethereum.enable() window.web3 = new Web3(window.ethereum) const provider = new providers.Web3Provider(window.web3.currentProvider) const network = (await provider.getNetwork()).chainId const staking = new Contract( Staking.networks[network].address, Staking.abi, provider.getSigner() ) let tx = await staking.stake(utils.parseEther(amount.toString())) await provider.waitForTransaction(tx.hash) }

Sorry I shouldn't be coding after having beers lol.
Forgot to call token.approve()

MetaMask seems to not properly propagate reverts into errors, would have been clearer with reasoning strings.

Anyway, working code below for reference and web3.js isn't needed as wrapper for window.ethereum either!

export async function stake (amount) {
    try {
        if (typeof  window.ethereum !== undefined) {
            await window.ethereum.enable()
            const provider = new providers.Web3Provider(window.ethereum)
            const network = (await provider.getNetwork()).chainId
            const token = new Contract (
                Token.networks[network].address,
                Token.abi,
                provider.getSigner()
            )            
            const staking = new Contract(
                Staking.networks[network].address,
                Staking.abi,
                provider.getSigner()
            )
            await token.approve(staking.address, utils.parseEther(amount.toString()))
            await staking.stake(utils.parseEther(amount.toString()))
        } else {
            throw new Error("No injected web3 found")
        }
    } catch (e) {
        console.log(e)
        throw Error(e.message)
    }
}

Awesome!

A couple beers keep you happy after finding a bug though, because you can legitimately blame the beer. :)

I get the same error with the code below, I am not connecting to Metamask instead I am using Infura as my providerwhat could be wrong here?

let provider = new ethers.providers.JsonRpcProvider('https://rinkeby.infura.io/v3/05c12b07721045d2824c506f3aef90c2');
    let wallet = new ethers.Wallet("c8c49b67b4878582a6ff17f6f86d83f1c8c3f0778ad51041c2d3b9360bec4772");
    let signer = provider.getSigner();

    wallet = wallet.connect(provider);

    signer.getAddress()
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log(error);
    })

You cannot get the Signer of an INFURA provider. INFURA does not provide or manage private keys.

You should get rid of the signer variable entirely and just use your wallet object instead. A Wallet is a Signer. :)

Thank you @ricmoo. Sometimes trying to many wrong things makes thing obscure

Was this page helpful?
0 / 5 - 0 ratings