Learn how to set up Wagmi with Base Account to enable Base Account SDK functionality with familiar React hooks.
Overview
Wagmi is a collection of React hooks for Ethereum Virtual Machine (EVM) compatible networks that makes it easy to work with wallets, contracts, transactions, and signing. Base Account integrates perfectly with Wagmi, allowing you to use all your familiar hooks.
You can jump ahead and use the Base Account Wagmi Template to get started.
Base Account Wagmi Template https://github.com/base/demos/tree/master/base-account/base-account-wagmi-template
Installation
Option 1: New Wagmi Project
Create a new Wagmi Project
To create a new wagmi project, you can use the command line:
Override the Base Account SDK version
To get access to the latest version of the Base Account SDK within Wagmi, you can use the following command to override it: npm pkg set overrides.@base-org/account="latest"
# OR manually add to package.json:
# "overrides": { "@base-org/account": "latest" }
# pnpm requires manual addition to package.json:
# "pnpm": { "overrides": { "@base-org/account": "latest" } }
# yarn uses resolutions - add manually to package.json:
# "resolutions": { "@base-org/account": "latest" }
# bun supports overrides - add manually to package.json:
# "overrides": { "@base-org/account": "latest" }
Or you can use a specific version by adding the version to the overrides: npm pkg set overrides.@base-org/account="2.2.0"
# OR manually add to package.json:
# "overrides": { "@base-org/account": "2.2.0" }
# pnpm requires manual addition to package.json:
# "pnpm": { "overrides": { "@base-org/account": "2.2.0" } }
# yarn uses resolutions - add manually to package.json:
# "resolutions": { "@base-org/account": "2.2.0" }
# bun supports overrides - add manually to package.json:
# "overrides": { "@base-org/account": "2.2.0" }
Install the dependencies
Install the dependencies with your package manager of choice:
If this is not your first install Make sure to delete your node_modules and package-lock.json and run a new install to ensure the overrides are applied.
Option 2: Existing Project
Override the Base Account SDK version
To get access to the latest version of the Base Account SDK within Wagmi, you can use the following command to override it: npm pkg set overrides.@base-org/account="latest"
# OR manually add to package.json:
# "overrides": { "@base-org/account": "latest" }
# pnpm requires manual addition to package.json:
# "pnpm": { "overrides": { "@base-org/account": "latest" } }
# yarn uses resolutions - add manually to package.json:
# "resolutions": { "@base-org/account": "latest" }
# bun supports overrides - add manually to package.json:
# "overrides": { "@base-org/account": "latest" }
Or you can use a specific version by adding the version to the overrides: npm pkg set overrides.@base-org/account="2.2.0"
# OR manually add to package.json:
# "overrides": { "@base-org/account": "2.2.0" }
# pnpm requires manual addition to package.json:
# "pnpm": { "overrides": { "@base-org/account": "2.2.0" } }
# yarn uses resolutions - add manually to package.json:
# "resolutions": { "@base-org/account": "2.2.0" }
# bun supports overrides - add manually to package.json:
# "overrides": { "@base-org/account": "2.2.0" }
Install the dependencies
Install the dependencies with your package manager of choice: npm install viem wagmi @tanstack/react-query
pnpm add viem wagmi @tanstack/react-query
yarn add viem wagmi @tanstack/react-query
bun add viem wagmi @tanstack/react-query
If this is not your first install Make sure to delete your node_modules and package-lock.json and run a new install to ensure the overrides are applied.
Configuration
Create your Wagmi configuration with the Base Account connector configured for Base Account:
import { cookieStorage , createConfig , createStorage , http } from "wagmi" ;
import { base , baseSepolia } from "wagmi/chains" ;
import { baseAccount } from "wagmi/connectors" ;
export function getConfig () {
return createConfig ({
chains: [ base , baseSepolia ],
multiInjectedProviderDiscovery: false ,
connectors: [
baseAccount ({
appName: "My Wagmi App" ,
}),
],
storage: createStorage ({
storage: cookieStorage ,
}),
ssr: true ,
transports: {
[base.id]: http (),
[baseSepolia.id]: http (),
},
});
}
declare module "wagmi" {
interface Register {
config : ReturnType < typeof getConfig >;
}
}
2. Wrap Your App
Wrap your application with the Wagmi provider and QueryClient provider:
app/providers.tsx
app/layout.tsx
'use client'
import { QueryClient , QueryClientProvider } from '@tanstack/react-query'
import { type ReactNode , useState } from 'react'
import { type State , WagmiProvider } from 'wagmi'
import { getConfig } from '@/wagmi'
export function Providers ( props : {
children : ReactNode
initialState ?: State
}) {
const [ config ] = useState (() => getConfig ())
const [ queryClient ] = useState (() => new QueryClient ())
return (
< WagmiProvider config = { config } initialState = { props . initialState } >
< QueryClientProvider client = { queryClient } >
{ props . children }
</ QueryClientProvider >
</ WagmiProvider >
)
}
'use client'
import { QueryClient , QueryClientProvider } from '@tanstack/react-query'
import { type ReactNode , useState } from 'react'
import { type State , WagmiProvider } from 'wagmi'
import { getConfig } from '@/wagmi'
export function Providers ( props : {
children : ReactNode
initialState ?: State
}) {
const [ config ] = useState (() => getConfig ())
const [ queryClient ] = useState (() => new QueryClient ())
return (
< WagmiProvider config = { config } initialState = { props . initialState } >
< QueryClientProvider client = { queryClient } >
{ props . children }
</ QueryClientProvider >
</ WagmiProvider >
)
}
Create a Simple Page (Sign in with Base)
Create a simple landing page that uses Sign In With Base to authenticate the user
app/components/SignInWithBase.tsx
app/page.tsx
"use client" ;
import { Connector } from "wagmi" ;
import { SignInWithBaseButton } from "@base-org/account-ui/react" ;
import { useState } from "react" ;
interface SignInWithBaseProps {
connector : Connector ;
}
export function SignInWithBase ({ connector } : SignInWithBaseProps ) {
const [ verificationResult , setVerificationResult ] = useState < string >( "" );
async function handleBaseAccountConnect () {
const provider = await connector . getProvider ();
if ( provider ) {
try {
// Generate a fresh nonce (this will be overwritten with the backend nonce)
const clientNonce =
Math . random (). toString ( 36 ). substring ( 2 , 15 ) +
Math . random (). toString ( 36 ). substring ( 2 , 15 );
console . log ( "clientNonce" , clientNonce );
// Connect with SIWE to get signature, message, and address
const accounts = await ( provider as any ). request ({
method: "wallet_connect" ,
params: [
{
version: "1" ,
capabilities: {
signInWithEthereum: {
nonce: clientNonce ,
chainId: "0x2105" , // Base Mainnet - 8453
},
},
},
],
});
// Verify the signature on the backend
/*
const walletAddress = accounts.accounts[0].address;
const signature =
accounts.accounts[0].capabilities.signInWithEthereum.signature;
const message =
accounts.accounts[0].capabilities.signInWithEthereum.message;
const verifyResponse = await fetch("/api/auth/verify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
address: walletAddress,
message,
signature,
}),
});
const result = await verifyResponse.json();
*/
const result = { success: true , address:accounts [ 0 ]. address } // Mock response
if ( result . success ) {
setVerificationResult ( `Verified! Address: ${ result . address } ` );
} else {
setVerificationResult ( `Verification failed: ${ result . error } ` );
}
} catch ( err ) {
console . error ( "Error:" , err );
setVerificationResult (
`Error: ${ err instanceof Error ? err . message : "Unknown error" } `
);
}
} else {
console . error ( "No provider" );
}
}
return (
< div >
< div style = { { width: "300px" } } >
< SignInWithBaseButton
onClick = { handleBaseAccountConnect }
variant = "solid"
colorScheme = "system"
align = "center"
/>
</ div >
{ verificationResult && (
< div style = { { marginTop: "10px" } } > { verificationResult } </ div >
) }
</ div >
);
}
"use client" ;
import { useAccount , useConnect , useDisconnect } from "wagmi" ;
import { SignInWithBase } from "../components/SignInWithBase" ;
function App () {
const account = useAccount ();
const { connectors , connect , status , error } = useConnect ();
const { disconnect } = useDisconnect ();
return (
<>
< div >
< h2 > Account </ h2 >
< div >
status: { account . status }
< br />
addresses: { JSON . stringify ( account . addresses ) }
< br />
chainId: { account . chainId }
</ div >
{ account . status === "connected" && (
< button type = "button" onClick = { () => disconnect () } >
Disconnect
</ button >
) }
</ div >
< div >
< h2 > Connect </ h2 >
{ connectors . map (( connector ) => {
if ( connector . name === "Base Account" ) {
return (
< SignInWithBase key = { connector . uid } connector = { connector } />
);
} else {
return (
< button
key = { connector . uid }
onClick = { () => connect ({ connector }) }
type = "button"
>
{ connector . name }
</ button >
);
}
}) }
< div > { status } </ div >
< div > { error ?. message } </ div >
</ div >
</>
);
}
export default App ;
This is a simple example to get you started.
You will need to add your own backend logic to verify the signature and authenticate the user. You can find a complete example in the Base Account Wagmi Template .
Run the Wagmi App
Run the application with your package manager of choice:
What you will see when you navigate to the page
Next Steps
Now that you have Wagmi configured with Base Account, you can: