The default SDK implementation does not use Wagmi, but you can add full support for it by following the steps below.

Installing packages

First, you want to install the DynamicWagmiConnector package using npm or yarn

Configure Wagmi and Dynamic

Here’s a full code snippet with all the setup code required.

import {
  DynamicContextProvider,
  DynamicWidget,
} from '@dynamic-labs/sdk-react-core';
import { EthereumWalletConnectors } from '@dynamic-labs/ethereum';
import { DynamicWagmiConnector } from '@dynamic-labs/wagmi-connector';
import {
  createConfig,
  WagmiProvider,
  useAccount,
} from 'wagmi';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { http } from 'viem';
import { mainnet } from 'viem/chains';

const config = createConfig({
  chains: [mainnet],
  multiInjectedProviderDiscovery: false,
  transports: {
    [mainnet.id]: http(),
  },
});

const queryClient = new QueryClient();

export default function App() {
  return (
    <DynamicContextProvider
      settings={{
        environmentId: 'ENV_ID',
        walletConnectors: [EthereumWalletConnectors],
      }}
    >
      <WagmiProvider config={config}>
        <QueryClientProvider client={queryClient}>
          <DynamicWagmiConnector>
            <DynamicWidget />
            <AccountInfo />
          </DynamicWagmiConnector>
        </QueryClientProvider>
      </WagmiProvider>
    </DynamicContextProvider>
  );
}

function AccountInfo() {
  const { address, isConnected, chain } = useAccount();

  return (
    <div>
      <p>
        wagmi connected: {isConnected ? 'true' : 'false'}
      </p>
      <p>wagmi address: {address}</p>
      <p>wagmi network: {chain?.id}</p>
    </div>
  );
};

Two things to note here:

  1. multiInjectedProviderDiscovery is set to false – this is because Dynamic implements the multi injected provider discovery protocol itself. If you’d like to keep this enabled on Wagmi, please do, but you might see some undefined behavior and we might not be able to debug.
  2. While this example configures mainnet as the only chain, you can pass in all your supported chains to the chains array. For more info, see the “Chain Configuration” section below.

Throughout your app, you can now use Wagmi hooks like useAccount and they will automatically sync to the wallet that you logged in with via Dynamic.

Make sure to call createConfig at the top-level of your app. If you call it inside of a component, it will be called during each render, which can lead to unexpected behavior.

Chain Configuration

If you are upgrading from Dynamic + Wagmi v1, then this config will look new to you. Previously, Dynamic was automatically updating the Wagmi config with the chains that you configured in your Dynamic Dashboard. This behavior has changed in v2 to give you more control over your Wagmi config and for a simpler integration. What this means is that you will need to pass to Wagmi all of the chains you have configured with Dynamic.

For example, if in Dynamic you have enabled Ethereum Mainnet, Optimism and Base, you will need to update your Wagmi config to look like this:

import {
  createConfig,
  WagmiProvider,
} from 'wagmi';
import { http } from 'viem';
import { mainnet, optimism, base } from 'viem/chains';

const config = createConfig({
  chains: [mainnet, optimism, base],
  multiInjectedProviderDiscovery: false,
  transports: {
    [mainnet.id]: http(),
    [optimism.id]: http(),
    [base.id]: http(),
  },
});

Adding Custom Networks

As you probably already know, you can add a custom EVM network through Dynamic using the evmNetworks prop. If you want to use these custom networks with Wagmi, you will need to declare it in your Wagmi config.

You can use our util function called getOrMapViemChain to convert the EVM network object to a Viem chain object.

Here’s an example of adding the Morph network to both Dynamic and to the Wagmi config:

import {
  createConfig,
  WagmiProvider,
} from 'wagmi';

import { http } from 'viem';

import { getOrMapViemChain } from '@dynamic-labs/ethereum-core';

const customEvmNetworks = [
  {
    blockExplorerUrls: ["https://explorer-holesky.morphl2.io/"],
    chainId: 2810,
    name: "Morph",
    rpcUrls: ["https://rpc-quicknode-holesky.morphl2.io"],
    iconUrls: ["https://avatars.githubusercontent.com/u/132543920?v=4"],
    nativeCurrency: {
      name: "Ethereum",
      symbol: "ETH",
      decimals: 18,
    },
    networkId: 2810,
  },
]

export const wagmiConfig = createConfig({
  chains: [
    mainnet,
    ...customEvmNetworks.map(getOrMapViemChain),
  ],
  client({ chain }) {
    return createClient({
      chain,
      transport: http(),
    });
  },
});

Adding Private RPCs

Note that if you are using a private RPC in Dynamic, you will also need to declare that in your Wagmi config. Luckily this is as simple as passing it into your http transport in Wagmi:

import {
  createConfig,
  WagmiProvider,
} from 'wagmi';

export const wagmiConfig = createConfig({
  chains: [mainnet],
  multiInjectedProviderDiscovery: false,
  transports: {
    [mainnet.id]: http('your-private-rpc-url'),
  },
});

Further Resources

For docs on createConfig, see: https://wagmi.sh/react/api/createConfig

For more general information on what you can do with Wagmi, check out their getting started docs: https://wagmi.sh/react/getting-started