Web3-React (V6)

This tutorial is a step-by-step guide on how to integrate Phantom into your dApp using the Web3-React (v6) library. Web3-React is an EVM library that exposes hooks for common web3 primitives such as wallets, addresses, and the like. Web3-React has a V8 version that is out now, but many dapps are still using V6. If you want to be using the most up-to-date version, you can check out our guide here Web3-React (V8)

We will be going through step by step how to go from zero to a fully integrated web3-react-powered Phantom connect button.

Prerequisites

  • Node version >=16.12.0

  • A text editor/IDE (such as VSCode)

  • Some Knowledge of React

  • Yarn (v1)

Creating The App

We recommend using Vite to create new React applications.

To create a new React application using Vite, run the following command in your terminal:

yarn create vite
  1. This will ask you for a project name. Provide it a name here. For purposes of this tutorial, I used "Web3-React-V6-Sandbox".

  2. It will then ask you to select a framework. Select "React" here.

  3. Next, it will ask for a variant. Select "Typescript" here.

Now change directory into your project and run:

yarn install

And make sure your app runs by running the command:

yarn dev

Configuring TypeScript

You will need to change the moduleResolution keys to be switched from "bundler" to "node".

Each file should look as follows.

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

Configuring Vite

The code that we are using is a bit older and uses some node modules that Vite doesn't polyfill by default. To correct this we will need to tell Vite that we want to polyfill the node modules. To do so we will use a plugin. Install the plugin with the following command.

yarn add --dev vite-plugin-node-polyfills

Now you can modify your Vite config to look like this

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { nodePolyfills } from 'vite-plugin-node-polyfills'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    nodePolyfills(),
  ],
})

Now with all of the config out of the way, we can install the rest of our dependencies.

Installing Dependencies

To install the appropriate packages, run the following:

yarn add web3-react-v6-phantom ethers@5 @web3-react/[email protected] @web3-react/[email protected]

NOTE: Be sure to specify the versions like we do above, otherwise you will download the v8 packages, which have a different API.

Now you can use the web3-react and web3-react-phantom packages in your project and integrate Phantom as a wallet in the app.

Initializing Web3-React

Web3-react is entirely based on the idea of connectors, and how it handles them.web3-react works as a huge global state machine, that allows you to interact with any wallet anywhere in your application once you wrap it in the provider component as we will do below

First, we will need to import the packages into our project. At the top of the main.tsx file add these imports:

// main.tsx
import { Web3ReactProvider } from '@web3-react/core';
import { Web3Provider } from '@ethersproject/providers';

Next, we will configure web3-react like so.

// main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'

import { Web3ReactProvider } from '@web3-react/core';
import { Web3Provider, ExternalProvider } from '@ethersproject/providers';

function getLibrary(provider: unknown): Web3Provider {
    const library = new Web3Provider(provider as ExternalProvider);
    library.pollingInterval = 12000;
    return library;
}

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
    <Web3ReactProvider getLibrary={getLibrary}>
        <React.StrictMode>
          <App />
        </React.StrictMode>
    </Web3ReactProvider>
)

This will wrap our Vite app in this <Web3ReactProvider> JSX component which will give us global access to interact with Phantom wherever we are in our app.

Adding a Connect Button

Now we will move to our App.tsx file to add the connect button to the app.

Before doing so, you can pull out the useState hook, its import, and the button that calls the function to increase the counter.

- import { useState } from 'react'

- const [count, setCount] = useState(0)

- <button onClick={() => setCount((count) => count + 1)}>
-    count is {count}
- </button>

After deleting that, we must import our Phantom connector and the Web3React hook.

import { PhantomConnector } from "web3-react-v6-phantom"
import { useWeb3React } from '@web3-react/core';

Then we will initialize our PhantomConnector

const phantom = new PhantomConnector({
  supportedChainIds: [1, 5], // Mainnet and Goerli ChainIds
});

Now the last thing to do is invoke the useWeb3React hook and set up the connection logic in the app. Your entire App.tsx file should look like this

// App.tsx
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";

import { useWeb3React } from "@web3-react/core";
import { PhantomConnector } from "web3-react-v6-phantom";

const phantom = new PhantomConnector({
  supportedChainIds: [1, 5], // Mainnet and Goerli ChainIds
});

function App() {
  const { activate, deactivate, account } = useWeb3React();
  const handleConnect = async () => {
    try {
      await activate(phantom);
    } catch (e) {
      console.error(e);
    }
  };
  const handleDisconnect = () => {
    try {
      deactivate();
    } catch (e) {
      console.error(e);
    }
  };

  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="App">
        <h1>Web3-React Connector Playbox</h1>
        <div className="wallet-connector">
          <button onClick={handleConnect}>Connect to Phantom!</button>
          <button onClick={handleDisconnect}>Disconnect</button>
          <p>{account ? account : "no account connected"}</p>
        </div>
      </div>
    </>
  );
}

export default App;

Here you can see that we're using the Phantom connector, and passing it as an argument to the useWeb3React activate and disconnect hooks that we initialized. There are other hooks that you can pull in from useWeb3React that will track various things, such as the chain id or connection status.

Here in this app we just track the account which is the address of the wallet that's currently connected.

When you first run the app with yarn dev , it should look like this

And then, once you click the connect button, Phantom's connect screen will pop open. Once you hit approve, you will see your address displayed like the image below.

Conclusion

You've now added your very own Phantom connect button using Web3-React!

You can use this as the basis for your dApp if you're looking to build out something or use it for reference to add a Phantom connect button to your existing dApp.

Either way, we hope you found this helpful.

Last updated