QuickNode Raises $60M Series B!
Read the Letter from our CEO.

How to Connect Your Dapp With MetaMask Using Ethers.js

November 14, 2022

Overview

In our dApp, we will have a simple react user interface that has a material button asking the user to connect to MetaMask. And if they do not have an account, they can create one or log in to their account. They will then view their wallet balance and address displayed on the UI.

Prerequisites

  • Basic knowledge of React.js
  • Basic knowledge of Ethereum and Blockchain
  • NPM
  • Ethers.js library

What are dApps

A dApp is an application that builds on a decentralized network. It has a user interface and a smart contract.

DApps run on blockchains that are open-source, decentralized environments free from the control of any single actor. For example, a developer can create a Facebook-like app and run it on the Ethereum blockchain, and when any user makes a post, no one can delete it. On decentralized apps, no one person is fully managing user data.

A dApp can have a frontend that is built using any language. It can run on decentralized servers like IPFS or Swarm.

What is MetaMask

MetaMask is a popular browser extension that serves as a cryptocurrency wallet that connects to the Ethereum blockchain. MetaMask is a secure wallet that enables users to interact with Ethereum's dApps. It allows users to store Ether and other ERC-20 tokens. Users can then spend these tokens on games, stake them on DeFi apps, and trade them on exchanges. MetaMask does not store only ERC-20 tokens but can also store ERC-721 tokens.
In this article, we will be connecting our dApp with MetaMask so users can connect to the Ethereum blockchain.

Install MetaMask

We will need to install the MetaMask extension in our browser to complete this tutorial.
To add MetaMask to your browser for Chrome, follow this link, but if you are using a different browser than Chrome, you can search for the extension for the browser you are using.

Why Ethers.js

Ethers.js is a lightweight JavaScript library that allows developers to connect and interact with the Ethereum blockchain. The library includes utility functions and has all the capabilities of an Ethereum wallet.

Ethers.js makes it easier to connect to the Ethereum blockchain with just a few lines of code.

With that bit of context, you are now armed with the knowledge of why we are using the technologies we are. You are now prepared with everything you need to start coding!

Build a dApp frontend using React

With this application, we will explore the basic concepts of the react framework and the blockchain. We will create paths to communicate with the Ethereum blockchain, query it and fetch data to render in our dApp.
At the end of this tutorial, we will have a working webpage that interacts with Ethereum.



Run the command npx create-react-app ethersjs_meta to create a new react app named ethersjs_meta.

Next, run the command

build a dapp frontend using react

Copy
npm install ethers

This will  install the Ethers.js library and every dependency we will need.

Next, delete the dummy code in the App.js file, and copy-paste the code below.

build a dapp frontend using react

Copy
function App() {
  return (
    <div className="App-header">
      <div className="centerCard">
        <div className = "card">
          <div className="App">
            <WalletCard/>
          </div>
        </div>
      </div>
    </div>
  );
}
export default App;

Next, we want to create a new file called WalletCard.js in our src folder. WalletCard.js will contain all of the UI and logic for our project.

build a dapp frontend using react

Copy
import React, { useState } from 'react';
import { Button } from '@material-ui/core';
import Ethereum from './Ethereum.png'
import { ethers } from 'ethers';
const provider = new ethers.providers.Web3Provider(window.Ethereum)
const WalletCard = () => {
    const [errorMessage, setErrorMessage] = useState(null);
    const [defaultAccount, setDefaultAccount] = useState(null);
    const [userBalance, setUserBalance] = useState(null);
    const connectwalletHandler = () => {
        if (window.Ethereum) {
            provider.send("eth_requestAccounts", []).then(async () => {
                await accountChangedHandler(provider.getSigner());
            })
        } else {
            setErrorMessage("Please Install Metamask!!!");
        }
    }
    const accountChangedHandler = async (newAccount) => {
        const address = await newAccount.getAddress();
        setDefaultAccount(address);
        const balance = await newAccount.getBalance()
        setUserBalance(ethers.utils.formatEther(balance));
        await getuserBalance(address)
    }
    const getuserBalance = async (address) => {
        const balance = await provider.getBalance(address, "latest")
    }
    return (
        <div className="WalletCard">
            <img src={Ethereum} className="App-logo" alt="logo" />
            <h3 className="h4">
                Welcome to a decentralized Application
            </h3>
            <Button
                style={{ background: defaultAccount ? "#A5CC82" : "white" }}
                onClick={connectwalletHandler}>
                {defaultAccount ? "Connected!!" : "Connect"}
            </Button>
            <div className="displayAccount">
                <h4 className="walletAddress">Address:{defaultAccount}</h4>
                <div className="balanceDisplay">
                    <h3>
                        Wallet Amount: {userBalance}
                    </h3>
                </div>
            </div>
            {errorMessage}
        </div>
    )
}
export default WalletCard;

In the code above, we created a constant variable called provider and assigned it to new ethers.providers.Web3Provider(window.ethereum), which is a read-only abstraction for accessing blockchain data.
We can access the whole Ethereum API using window.ethereum, which is why we passed it as a parameter to Ethers web3 provider.

Inside the WalletCard component, we created three states to mutate the app. We change the state when an error occurs, the account display changes, or the user balance changes.

build a dapp frontend using react

Copy
const [errorMessage, setErrorMessage] = useState(null);
const [defaultAccount, setDefaultAccount] = useState(null);
const [userBalance, setUserBalance] = useState(null);

The variable errorMessage takes the state setter setErrorMessage as it is the only way to mutate the app state, there are other ways of doing it, but the code above is less complex to use.
This method is called state hooks in React. We are setting states for three(3) events to occur in our app.

Create a connection with MetaMask

Next, we will create a function called connectwalletHandler that will contain a request for permission to connect to MetaMask. The function includes the following.

create a connection with metamask

Copy
const connectwalletHandler = () => {
    if (window.ethereum) {
        provider.send("eth_requestAccounts", [])
            .then(async () => {
                await accountChangedHandler(provider.getSigner());
            })
    } else {
        setErrorMessage("Please Install MetaMask!!!");
    }
}
In the code above, we did a little check to assert that the user has MetaMask installed; if the user does not have it installed, it should ask the user to install MetaMask. If it is installed, it should connect to MetaMask.

Build a connect Button

We will create a button that allows a user to connect to Ethereum. This button will call the function onClick. When this button is clicked, we will connect to MetaMask.

create a connection with metamask

Copy
<Button
  style={{ background: defaultAccount ? "#A5CC82" : "white" }}
  onClick={connectwalletHandler}>
    {defaultAccount ? "Connected!!" : "Connect"}
</Button>

The defaultAccount displays the wallet address, and we use the wallet address to show connected when the address is available. Otherwise, it should just show connect.

It should look like this when connected.



While MetaMask has public nodes that it connects to by default, if you would like to use your QuickNode Provider instead, you can absolutely do that. You can follow along this guide to configure your MetaMask wallet appropriately.

Login to MetaMask

After connecting to MetaMask, we are prompted to log in.

Display User Wallet Address

To handle the wallet address of the account and balance we signed up for, or any other newly created account, we created an async function that awaits the the provider.getSigner() function passed as a parameter to the accountChnagedHandler function. The accountChangedHandler contains the following:

display user wallet address

Copy
const accountChangedHandler = async (newAccount) => {
        const address = await newAccount.getAddress();
        setDefaultAccount(address);
    }
Inside this function from the code above, we pass a new parameter newAccount which is assigned to provider.signer() , so we can access the getAddress() function and pass the address to our state variable using the account setter setDefaultAccount(address).
To display the Wallet Address, we will call the defaultAccount variable.

display user wallet address

Copy
<h4 className="walletAddress">Address:{defaultAccount}</h4>



Display User Wallet Balance

This section will show us how to get the user balance from the blockchain.

display user wallet balance

Copy
const accountChangedHandler = async (newAccount) => {
        const address = await newAccount.getAddress();
        setDefaultAccount(address);
        const balance = await newAccount.getBalance()
        setUserBalance(ethers.utils.formatEther(balance));
        await getuserBalance(address)
    }
Based on the above code, we can access the balance of the wallet using the provider.signer() passed as newAccount , using the getBalance() function but this would return a hexadecimal value and that would be very large and unreadable, so we have to covert it from Wei to Ether ( Wei is the smallest denomination of Ether). To do this, we will do the following

display user wallet balance

Copy
setUserBalance(ethers.utils.formatEther(balance));
Next, we will pass the address into the getuserBalance() to be specific as to what wallet we will be needing its balance.

display user wallet balance

Copy
const getuserBalance = async (address) => {
        const balance = await provider.getBalance(address, "latest")
    }
Inside the getuserBalance() function, we will pass the address to the provider.getBalance() that takes the address and blockTag as parameters. To render it in our UI, use the code below

display user wallet balance

Copy
<div className="balanceDisplay">
  <h3>
    Wallet Amount: {userBalance}
  </h3>
</div>

Conclusion

In this tutorial, we demonstrated how to build a decentralized application using the Ethers.js library and react framework.

You can also extend the blockchain concept to build your own DeFi project where you can create a wallet that allows you to send and receive Ethereum or other tokens on the Ethereum blockchain.

You can take a look at the Ethers.js library to see how to use other functions of the library to build even more advanced projects on the blockchain.

Related articles 37

How to Access Bitcoin Mempool
Published: Aug 16, 2021
Updated: Sep 21, 2022

Bitcoin is the father of blockchain technology. With Bitcoin started a new era of blockchain and decentralization. Bitcoin enabled everyone to make the peer-to-peer transactions they enjoy...

Continue reading
How to access Ethereum Mempool
Published: Oct 15, 2020
Updated: Sep 15, 2022

On Ethereum, when a transaction is sent, before being added to a block, it resides in what is called a Mempool. To receive information about this transaction, the Mempool must be queried. This...

Continue reading
The Web3 Developer Stack
Published: Jul 3, 2021
Updated: Sep 15, 2022

A developer stack is a bag of technologies a developer possesses. For example, MEAN (MongoDB, Express.js, AngularJS/Angular, and Node.js) and MERN (MongoDB, Express.js, React, and Node.js) are...

Continue reading
Introduction to Scaffold-ETH 🏗
Published: Oct 7, 2021
Updated: Sep 9, 2022

Developing applications involves juggling several moving pieces like front-ends, back-ends, and databases. But developing a decentralized application on a blockchain adds a few more elements...

Continue reading
How to create your own DAO with Aragon
Published: Aug 8, 2021
Updated: Sep 9, 2022

Blockchain provides us with the power of decentralization. Decentralization means the transfer of power to users/members rather than having a single centralized authority governing everything;...

Continue reading
How to connect to Ethereum using PHP
Published: Jun 11, 2021
Updated: Sep 9, 2022

PHP is a very popular choice among developers and has a vast community due to its long presence in web development. In this guide, we’ll cover how to connect to Ethereum with PHP using the

Continue reading
How to use Subspace with QuickNode
Published: Sep 8, 2020
Updated: Sep 9, 2022

In this guide, we'll understand a bit about reactive development and how to use Subspace with QuickNode.JavaScript is the programming language behind most of the internet apps and...

Continue reading