Login to MetaMask with ethers

Login to MetaMask with ethers

Okay, this might seem really straight forward, but I actually had some problems figuring this out. I just started learning how to build dapps and found myself ripping my hair out because I couldn't figure out such a simple thing.

Logging in with your crypto wallet is one of the most basic features of a dapp, so knowing how to do it is an essential part of working with Web3. I'm going to walkthrough how I solved this, and the potential pitfalls a newcomer might come across.

No built in method

I scoured the ethers docs for a method that would let me connect to MetaMask. I thought the provider.listAccounts() method would work, but it doesn't actually trigger the signing process.

Another method that seemed reasonable was the provider.getSigner() method, but this didn't work either.

I later found out that there is no actual method in the ethers library that triggers this process.

The solution

Use the provider.send() method. The following example demonstrates how to use it.

async function login(){
  // Get the metamask provider which exists in `window.ethereum`
  const provider = new ethers.providers.Web3Provider((window as any).ethereum);
  // Use the `eth_requestAccounts` method to trigger metamask signing
  await provider.send("eth_requestAccounts", []);

  const signer = provider.getSigner();
  // Get the address
  const address = await signer.getAddress();
  // Get the balance
  const balance = await signer.getBalance();
}

As you can see, we use the window.ethereum object to create a new Web3Provider instance. window.ethereum only exists in a context where the user has installed a wallet extension or is using a Web3 enabled browser.

We then use the provider.send() method with eth_requestAccounts and empty params (the [] part) to trigger the connection process. Then, we can access the user's address and balance among many other things.

It is as simply as that.

Alternative solution (but don't use it)

If you are searching for how to login in with ethereum using ethers, you might come across another solution. That solution looks like this:

async function login(){
  // This will trigger the same process
  (window as any).ethereum.enable();

  // Get the metamask provider which exists in `window.ethereum`
  const provider = new ethers.providers.Web3Provider((window as any).ethereum);

  const signer = provider.getSigner();
  // Get the address
  const address = await signer.getAddress();
  // Get the balance
  const balance = await signer.getBalance();
}

As you can see, instead of using provider.send("eth_requestAccounts", []), we are using (window as any).ethereum.enable(). This actually works, and it might be tempting to use this method (it actually looks cleaner in my opinion). But this method is deprecated in favor of the previous solution.

That's it

That's all I had to say about signing in with ethereum using the ethers library. It's not complicated, but if you expect it to exist as a method in the library it might be confusing.