wagmi

This tutorial is a step-by-step guide on how to integrate a wallet such as Phantom into your dApp using the wagmi library.

w is a collection of React Hooks containing everything you need to start working with Ethereum. wagmi makes it easy to "Connect Wallet," display ENS and balance information, sign messages, interact with contracts, and generally facilitate programmatic on-chain activity.

We will be going through step by step how to go from zero to a fully integrated wagmi button. If you already have a dApp that you are trying to integrate Phantom in, you can use our project as reference.

Prerequisites

  • Node version >=16.12.0

  • A text editor/IDE (such as VSCode)

  • Some Knowledge of React

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 "wagmi-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,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "allowSyntheticDefaultImports": true,
    "jsx": "react-jsx",

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

With that out of the way we can install all of our dependencies.

Installing wagmi

To install the appropriate package, run the following:

yarn add wagmi viem phantom-wagmi-connector

Now you can use the wagmi package in your project and integrate a Phantom connection button into your app.

Initializing Wagmi

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

import {
  configureChains,
  createConfig,
  WagmiConfig,
} from 'wagmi';
import { publicProvider } from 'wagmi/providers/public';
import { PhantomConnector } from 'phantom-wagmi-connector';
import { goerli } from 'wagmi/chains'

Next, we will configure wagmi like so.

// =============================================================================
// wagmi configuration
// =============================================================================
// initalize which chains your dapp will use, and set up a provider
const { publicClient, webSocketPublicClient, chains } = configureChains([goerli], [publicProvider()]);

const wagmiConfig = createConfig({
  publicClient,
  webSocketPublicClient,
  connectors: [
    new PhantomConnector({ chains }),
  ]
});

Here we configure what chains we will support in our dApp, as well as the client that wagmi requires to interface with the blockchain.

Then we set up our connectors. This is all of the wallets that you want your dApp to support. You can have as many connectors as you would like in this array. But for example purposes we're just using the PhantomConnector that we imported from phantom-wagmi-connector.

With this bit of prep done, we can now go to our app and wrap it in the <WagmiConfig> component.

Wrapping Your App In WagmiConfig

In main.tsx wrap your <App />component with the providers. Your file should look like this with all of the configuration and wrapping completed.

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

import {
  configureChains,
  createConfig,
  WagmiConfig,
} from 'wagmi';
import { publicProvider } from 'wagmi/providers/public';
import { PhantomConnector } from 'phantom-wagmi-connector';
import { goerli } from 'wagmi/chains'


// =============================================================================
// wagmi configuration
// =============================================================================
// initalize which chains your dapp will use, and set up a provider
const { publicClient, webSocketPublicClient, chains } = configureChains([goerli], [publicProvider()]);

const wagmiConfig = createConfig({
  publicClient,
  webSocketPublicClient,
  connectors: [
    new PhantomConnector({ chains }),
  ]
});

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <WagmiConfig config={wagmiConfig}>
      <App />
    </WagmiConfig>
  </React.StrictMode>,
)

Now we have everything we need done to add a connect wallet button to the app.

Adding A Connect Button

At the top of your App.tsx file you can import the useConnect hook from wagmi. We will also display the address once connected, so we will import the useAccount hook as well. We also want to make sure we're connecting to Goerli, so we will import the chain as well.

import { useAccount, useConnect } from 'wagmi';
import { goerli } from 'wagmi/chains';

Then inside our App component, we will need to call the hooks. You can replace the useState hook that is keeping track of the counter with the following

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

+ const { address } = useAccount();
+ const { connect, connectors, isLoading, pendingConnector } = useConnect();

Next, you can add this connect button in place of the counter button that is there by default.

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

+ {connectors.map((connector) => (
+  <Button disabled={!connector.ready} key={connector.id} onClick={() => connect({ connector, chainId: goerli.id })}>
+    Connect to {connector.name}
+    {isLoading && pendingConnector?.id === connector.id && ' (connecting)'}
+  </Button>
+ ))}
+ <p>Connected to: {address ? address : 'not connected yet'}</p>

Then delete the useState import as we don't need it anymore.

Your entire App.tsx file should look like so

import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";
import { useAccount, useConnect } from "wagmi";
import { goerli } from 'wagmi/chains';

function App() {
  const { address } = useAccount();
  const { connect, connectors, isLoading, pendingConnector } = useConnect();
  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="card">
        {connectors.map((connector) => (
          <button
            disabled={!connector.ready}
            key={connector.id}
            onClick={() => connect({ connector, chainId: goerli.id })}
          >
            Connect to {connector.name}
            {isLoading &&
              pendingConnector?.id === connector.id &&
              " (connecting)"}
          </button>
        ))}
        <p>Connected to: {address ? address : "not connected yet"}</p>
        <p>
          Edit <code>src/App.tsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  );
}

export default App;

Now when you run everything locally it should look like this!

Once you click the connect button, it will prompt you to connect with Phantom, and then look like the picture below. Be sure to enable testnet mode, otherwise, you will encounter an error when trying to connect.

Conclusion

wagmi lets you easily manage a bunch of different web3 primitives through their typesafe hooks, and as you can see adding a connect button is very straightforward with just a bit of configuration up front.

Now that you've connected through wagmi and done all of the necessary config, you can use the other wagmi hooks to do things like sign messages, and send transactions. To see what a more advanced app might look like, you can look at the code for our sandbox for wagmi. And you can also check out the functionality here for a live demo.

We hope that you enjoyed this guide!

Last updated