Skip to content

Integrating with wagmi

Wagmi is a set of React hooks for interfacing with Ethereum wallets, allowing you read wallet state, request signatures or transactions, and take read and write actions on the blockchain.

Privy is fully compatible with wagmi, and you can use wagmi's React hooks to interface with external and embedded wallets from Privy. Just follow the steps below!

INFO

This guide describes how to integrate Privy with wagmi version 2.x. If you need to integrate Privy with wagmi version 1.x or below, follow this legacy guide instead.

TIP

Migrating from wagmi version 1.x? Jump to the migration guide below.

Integration steps

This guide assumes you have already integrated Privy into your app. If not, please begin with the Privy Quickstart.

1. Install dependencies

Install the latest versions of wagmi, @tanstack/react-query, @privy-io/react-auth, and @privy-io/wagmi:

sh
npm i wagmi @privy-io/react-auth @privy-io/wagmi @tanstack/react-query

2. Setup TanStack Query

To start, set up your app with the TanStack Query's React Provider. Wagmi uses TanStack Query under the hood to power its data fetching and caching of wallet and blockchain data.

To set up your app with TanStack Query, in the component where you render your PrivyProvider, import the QueryClient class and the QueryClientProvider component from @tanstack/react-query:

tsx
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';

Next, create a new instance of the QueryClient:

tsx
const queryClient = new QueryClient();

Then, like the PrivyProvider, wrap your app's components with the QueryClientProvider. This must be rendered inside the PrivyProvider component.

tsx
<PrivyProvider appId="your-privy-app-id" config={insertYourPrivyConfig}>
  <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</PrivyProvider>

For the client property of the QueryClientProvider, pass the queryClient instance you created.

3. Setup wagmi

Next, setup wagmi. This involves creating your wagmi config and wrapping your app with the WagmiProvider.

WARNING

While completing the wagmi setup, make sure to import createConfig and WagmiProvider from @privy-io/wagmi. Do not import these from wagmi directly.

Build your wagmi config

To build your wagmi config, import the createConfig method from @privy-io/wagmi:

tsx
import {createConfig} from '@privy-io/wagmi';

This is a drop-in replacement for wagmi's native createConfig, but ensures that the appropriate configuration options are set for the Privy integration. Specifically, it allows Privy to drive wagmi's connectors state, enabling the two libraries to stay in sync.

Next, import your app's required chains from viem/chains and the http transport from wagmi. Your app's required chains should match whatever you configure as supportedChains for Privy.

tsx
import {mainnet, sepolia} from 'viem/chains';
import {http} from 'wagmi';

// Replace this with your app's required chains

Lastly, call createConfig with your imported chains and the http transport like so:

tsx
// Make sure to import `createConfig` from `@privy-io/wagmi`, not `wagmi`
import {createConfig} from '@privy-io/wagmi';
...
export const config = createConfig({
  chains: [mainnet, sepolia], // Pass your required chains as an array
  transports: {
    [mainnet.id]: http(),
    [sepolia.id]: http(),
    // For each of your required chains, add an entry to `transports` with
    // a key of the chain's `id` and a value of `http()`
  },
});

Wrap your app with the WagmiProvider

Once you've built your wagmi config, in the same component where you render your PrivyProvider, import the WagmiProvider component from @privy-io/wagmi.

tsx
import {WagmiProvider} from '@privy-io/wagmi';

This is a drop-in replacement for wagmi's native WagmiProvider, but ensures the necessary configuration properties for Privy are set. Specifically, it ensures that the reconnectOnMount prop is set to false, which is required for handling the embedded wallet. Wallets will still be automatically reconnected on mount.

Then, like the PrivyProvider, wrap your app's components with the WagmiProvider. This must be rendered inside both the PrivyProvider and QueryClientProvider components.

tsx
import {PrivyProvider} from '@privy-io/react-auth';
// Make sure to import `WagmiProvider` from `@privy-io/wagmi`, not `wagmi`
import {WagmiProvider} from '@privy-io/wagmi';
import {QueryClientProvider} from '@tanstack/react-query';
...
<PrivyProvider appId='insert-your-privy-app-id' config={insertYourPrivyConfig}>
  <QueryClientProvider client={queryClient}>
    <WagmiProvider config={config}>
      {children}
    </WagmiProvider>
  </QueryClientProvider>
</PrivyProvider>

For the config property of the WagmiProvider, pass the config you created earlier.

Complete example

Altogether, this should look like:

tsx
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';

import {PrivyProvider} from '@privy-io/react-auth';
// Make sure to import these from `@privy-io/wagmi`, not `wagmi`
import {WagmiProvider, createConfig} from '@privy-io/wagmi';

import {privyConfig} from './privyConfig';
import {wagmiConfig} from './wagmiConfig';

const queryClient = new QueryClient();

export default function Providers({children}: {children: React.ReactNode}) {
  return (
    <PrivyProvider appId="insert-your-privy-app-id" config={privyConfig}>
      <QueryClientProvider client={queryClient}>
        <WagmiProvider config={wagmiConfig}>{children}</WagmiProvider>
      </QueryClientProvider>
    </PrivyProvider>
  );
}

That's it! You've successfully integrated Privy alongside wagmi in your app! 🎉

4. Use wagmi throughout your app

Once you've completed the setup above, you can use wagmi's React hooks throughout your app to interface with wallets and take read and write actions on the blockchain.

Using wagmi hooks

To use wagmi hooks, like useAccount, in your components, import the hook directly from wagmi and call it as usual:

tsx
import {useAccount} from 'wagmi';

export default const WalletAddress = () => {
  const {address} = useAccount();
  return <p>Wallet address: {address}</p>;
}

INFO

Injected wallets, like the MetaMask browser extension, cannot be programmatically disconnected from your site; they can only be manually disconnected. In kind, Privy does not currently support programmatically disconnecting a wallet via wagmi's useDisconnect hook. This hook "shims" a disconnection, which can create discrepancies between what wallets are connected to an app vs. wagmi.


Instead of disconnecting a given wallet, you can always prompt a user to connect a different wallet via the connectWallet method.

When to use Privy vs. wagmi

Both Privy's out-of-the-box interfaces and wagmi's React hooks enable you to interface with wallets and to request signatures and transactions.

If your app integrates Privy alongside wagmi, you should:

  • use Privy to connect external wallets and create embedded wallets
  • use wagmi to take read or write actions from a connected wallet

Updating the active wallet

With Privy, users may have multiple wallets connected to your app, but wagmi's React hooks return information for only one connected wallet at a time. This is referred to as the active wallet.

To update wagmi to return information for a different connected wallet, first import the useWallets hook from @privy-io/react-auth and the useSetActiveWallet hook from @privy-io/wagmi:

tsx
import {useWallets} from '@privy-io/react-auth';
import {useSetActiveWallet} from '@privy-io/wagmi';

Then, find your desired active wallet from the wallets array returned by useWallets

tsx
const {wallets} = useWallets();
// Replace this logic to find your desired wallet
const newActiveWallet = wallets.find((wallet) => wallet.address === 'insert-your-desired-address');

Lastly, pass your desired active wallet to the setActiveWallet method returned by the useSetActiveWallet hook:

tsx
await setActiveWallet(newActiveWallet);

Demo app

Check out our wagmi demo app to see the hooks listed above in action.

Feel free to take a look at the app's source code to see an end-to-end implementation of Privy with wagmi.

Migrating from wagmi v1

If your app previously used wagmi version 1.x with Privy's @privy-io/wagmi-connector package, follow the steps below to migrate to wagmi version 2.x.

1. Install wagmi v2 and @privy-io/wagmi

Privy's wagmi integration is now managed by the @privy-io/wagmi package instead of @privy-io/wagmi-connector. The former is maintained only for apps using wagmi version 1.x.

To migrate to the new package, first upgrade your@privy-io/react-auth and wagmi versions to the latest:

sh
npm i @privy-io/react-auth@latest wagmi@latest

Then, install @privy-io/wagmi and the new dependencies required by wagmi version 2.x, including @tanstack/react-query and viem

2. Replace configureChains with createConfig

Previously, your app configured wagmi via the configureChains method exported by wagmi. You should now configure wagmi via the createConfig method exported by @privy-io/wagmi:

tsx
import {configureChains} from 'wagmi'; 
// Make sure to import `createConfig` from `@privy-io/wagmi`, not `wagmi`
import {createConfig} from '@privy-io/wagmi'; 

...

const configureChainsConfig = configureChains([mainnet, sepolia], [publicProvider()]); 
const config = createConfig({ 
  chains: [mainnet, sepolia], 
  transports: { 
    [mainnet.id]: http(), 
    [sepolia.id]: http(), 
  }, 
}); 

3. Replace the PrivyWagmiConnector with the WagmiProvider and QueryClientProvider

Previously, your app's components were wrapped with the PrivyWagmiConnector exported by @privy-io/wagmi-connector. You should now wrap your components with the WagmiProvider exported by @privy-io/wagmi and the QueryClientProvider exported by @tanstack/react-query:

tsx
import {PrivyProvider} from '@privy-io/react-auth';
import {PrivyWagmiConnector} from '@privy-io/wagmi-connector'; 
// Make sure to import `WagmiProvider` from `@privy-io/wagmi`, not `wagmi`
import {WagmiProvider} from '@privy-io/wagmi'; 
import {QueryClient, QueryClientProvider} from '@tanstack/react-query'; 

const queryClient = new QueryClient(); 

...

<PrivyProvider appId='your-privy-app-id' config={insertYourPrivyConfig}>
  <PrivyWagmiConnector wagmiChainsConfig={configureChainsConfig}>
  <QueryClientProvider client={queryClient}>
    <WagmiProvider config={config}>
      {children}
    </WagmiProvider>
  </QueryClientProvider>
  </PrivyWagmiConnector>
</PrivyProvider>

4. Replace usePrivyWagmi with useSetActiveWallet

Previously, your app used the setActiveWallet method returned by the usePrivyWagmi hook. You should now use the setActiveWallet method returned by the useSetActiveWallet hook:

tsx
import {usePrivyWagmi} from '@privy-io/wagmi-connector'; 
import {useSetActiveWallet} from '@privy-io/wagmi'; 

...
const {activeWallet, setActiveWallet} = usePrivyWagmi(); 
const {setActiveWallet} = useSetActiveWallet(); 

If you need to get the current active wallet for the user, you can get the active wallet's address from useAccount and filter Privy's useWallets array for the ConnectedWallet object with the same address.

At this point, you should have replaced all usages of @privy-io/wagmi-connector and you can uninstall the package.

5. Migrate wagmi's hooks

Follow wagmi's migration guide to update how you call wagmi hooks to match their new interfaces.