Are you building a dApp? If yes, then you must need to connect your dApp to a wallet. Web3-react might just be the tool you are looking for!
Web3-react is a web3 framework made by Noah Zinsmeister to help blockchain developers make modern Ethereum dApps using React hooks.
Let’s explore web3-react! πβ
Web3-react is a React-based framework that helps to ease the frontend development for your dApp.
Web3-react also acts as a state machine that maintains the data relevant to your dApp and injects it wherever needed in the component tree. Web3-React supports a wide range of wallets, from browser wallets like Metamask and Coinbase to hardware wallets like Trezor and Ledger.
In LearnWeb3, we use Web3-Modal for wallet connection in dApps. Web3-Modal is great for beginners, but as we scale our projects, handling Web3-Modal gets harder.
Thus web3-react can be a better option because:
Web3-React provides flexibility in many ways. It has great support for many wallets as discussed earlier.
But even if the wallet is not included in web3-react packages, you can create your custom connectors and connect wallets other than those listed with web3-react!
Web3-react uses Ethers.js or Web3.js under the hood thus providing a smooth experience as connecting wallet using only ether.js can be a really painful process.
Note: Before moving forward, make sure you understand ContextAPI in other words, useContext hook. It is the key feature of Web3-React.
Let’s install web3-react!
In this article, we assume that you have your ReactJS/NextJS app already set up.
In your app directory, run the following command to install web-react:
COPYCOPYCOPY
npm install @web-react/core
or
COPYCOPYCOPY
yarn add @web3-react/core
Now, for connecting browser-based wallets, we need to install the following web3-react package:
COPYCOPYCOPY
npm install @web3-react/injected-connector
or
COPYCOPYCOPY
yarn add @web3-react/injected-connector
And.. you have all the ingredients required to connect your dApp to a browser wallet! Let’s start writing code to connect the wallet!
This section assumes you have already created the app and installed the previous dependencies. Now that it’s taken care of, let’s get straight into this!
Let’s jump into your _app.js
(for Next) file under the pages
folder!
Edit the code such that it looks like this πβ
COPYCOPYCOPY
import '../styles/globals.css'
import { Web3ReactProvider } from '@web3-react/core'
import { providers, Web3Provider } from 'ethers'
function getLibrary(provider, connector) {
return new providers.Web3Provider(provider)
}
function MyApp({ Component, pageProps }) {
return(
<Web3ReactProvider getLibrary={getLibrary}>
<Component {...pageProps} />
</Web3ReactProvider>
)
}
export default MyApp
Done? Now let’s understand the code!
function getLibrary(provider, connector) { return new providers.Web3Provider(provider) }
function MyApp({ Component, pageProps }) { return ( <Web3ReactProvider getLibrary={getLibrary}> <Component {...pageProps} /> </Web3ReactProvider> ) }
Now let’s jump into your index.js
in the pages
folder.
COPYCOPYCOPY
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
import { InjectedConnector } from '@web3-react/injected-connector'
import { useWeb3React } from '@web3-react/core'
import { useState } from 'react'
import { CONTRACT_ADDRESS, CONTRACT_ABI } from '../constants'
export default function Home() {
const [ result, setResult ] = useState("")
// web3-react hook, helps in fetching
// the data passed by Web3ReactProvider
const { active, activate, deactivate, account, library, connector, error } = useWeb3React()
// injected provider identifier
const injected = new InjectedConnector(
{
supportedChainIds:[80001]
}
)
const connectWallet = async () => {
try {
await activate(injected)
} catch (err) {
console.error(err)
}
}
const disconnectWallet = async () => {
try {
deactivate(injected)
} catch (err) {
console.error(err)
}
}
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<button onClick={connectWallet}>Connect Wallet</button>
{active? <span>Connected with <b>{account}</b></span>: <span>Not Connected</span>}
<button onClick={disconnectWallet}>Disconnect Wallet</button>
</div>
)
}
Okay, so now let’s look at useWeb3React hook
COPYCOPYCOPY
const { active, activate, deactivate, account, library, connector, error } = useWeb3React()
useWeb3React
is a custom hook from the web-react library that returns a lot of useful functionalities. connector; // connector object returns some useful connection // methods like activate() and deactivate() library; // library is the provider object that we // passed with the Web3ReactProvider chainId; // returns the chainId for the account that // is connected to the dApp account; // the account address of the connected account active; // active is a state variable which returns boolean values // that determines whether the wallet connection is // active or inactive error; // returns any error happening with the wallet connection
Now let’s look at the injected variable –
COPYCOPYCOPY
const injected = new InjectedConnector({
supportedChainIds:[80001]
})
// we can list multiple networks by listing their
// chainIds, separated by comma
UnsupportedChainId
error if the wallet is not connected to the right network. This error can be accessed from the error
object returned by the useWeb3React
hook.As for the activate(injected)
and deactivate(injected)
, they are methods that will connect or disconnect the injected provider (browser wallet).
And BOOMπ₯ you have a wallet connection setup ready!
Now that we have connected our wallets, all that is left is the way to read from and write to the blockchain!
How do we achieve that?
We will be using the web3-react library
(provider) object to read/write from/on the blockchain
So, we are going to use the Mood dApp Contract that was built in LearnWeb3DAO’s Freshman Track. Click here to get the smart contract.
Before we go deeper into this, make sure you have made an index.js
in the constants
folder(in the root directory), and it should have the following code –
COPYCOPYCOPY
// put your contract address in place of this gibberish
export const CONTRACT_ADDRESS = "0xabcabcabcabcabcabc";
// put your abi in this variable, it will be of the form [{},{}]
export const CONTRACT_ABI = [...]
For reading from smart contracts, we need two things-
So let’s write a function for reading from the smart contract!
COPYCOPYCOPY
const getMood = async () => {
const provider = library;
const contract = new Contract(
CONRTACT_ADDRESS,
CONTRACT_ABI,
provider
);
const tx = await contract.getMood();
tx.wait();
setResult(tx);
}
provider
variable to library
. Remember, library
was returned from the useWeb3React
hook and it is a provider object. Handy, isn’t it?tx.wait()
waits for the transaction to complete.setResult(tx)
sets the value of the state variable result
to tx
‘s value.For writing through the smart contracts, we need two things-
Let’s create a writing function!
COPYCOPYCOPY
const setMood = async ( mood ) => {
const signer = await library.getSigner()
const contract = new Contract(
CONRTACT_ADDRESS,
CONTRACT_ABI,
signer
)
const tx = await contract.setMood(mood)
tx.wait()
alert("Mood set!")
}
The things have changed now, let’s explore each of them step by step –
library
is a provider object, but we needed a signer, right? Well, a provider object has a method called getSigner()
that returns the signer object attached to this provider!contract
is a Contract instance, but here, instead of passing the provider, we are passing a signer, because, for writing transactions, we need a signer to sign the transaction.LFG!! You have made a dApp frontend with web3-react! It can read, and write on the blockchain too!πͺβ
Web3-react is a very handy framework for building the dApp frontend in React/NextJS.
It is a very easy-to-use tool, but it can be confusing for beginners. For using this tool, you may need some knowledge of Context API.
Note: The Web3-React is not well documented, and the main branch of their repo does not even have docs. For reading their docs, shift to their v6
branch.
That’s it for this blog!
See you around next time. π
Source: Learn Web3