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.
wagmi 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.
- Node version >=16.12.0
- A text editor/IDE (such as VSCode)
- Some Knowledge of React
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
You will need to change the
moduleResolution
keys to be switched from "bundler" to "node".Each file should look as follows.
tsconfig.json
tsconfig.node.json
{
"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" }]
}
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}
With that out of the way we can install all of our dependencies.
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.
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.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.
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 soimport 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.

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 modified 3mo ago