@dynamic-labs-sdk/wagmi
Official wagmi support for the Dynamic JS SDK. Expose a
Dynamic-managed EVM wallet account (embedded/OTP or external) as a wagmi
connector so useAccount, useSendTransaction, useReadContract, and the rest
of the wagmi/viem hook ecosystem work against Dynamic wallets — with Dynamic
remaining the source of truth for wallet state.
Installation
npm install @dynamic-labs-sdk/wagmi wagmi @wagmi/core viem @tanstack/react-query
wagmi, @wagmi/core and viem are peer dependencies. wagmi and
@tanstack/react-query are only required for the React helpers.
Which API to use
Use the automatic sync — syncDynamicWagmi in vanilla JS, SyncDynamicWagmi /
useSyncDynamicWagmi in React. Both keep wagmi pointed at Dynamic's selected
EVM wallet account, so setSelectedWalletAccount(...) is all you ever call to
move wagmi.
| Vanilla JS | React | |
|---|---|---|
| Keep wagmi on Dynamic's selected account | syncDynamicWagmi | SyncDynamicWagmi (or the useSyncDynamicWagmi hook) |
| Bridge one specific account yourself | createDynamicWagmiConnector | createDynamicWagmiConnector |
createDynamicWagmiConnector is the primitive both sync helpers are built on. It
bridges exactly one account — the one you pass in — and never follows
Dynamic's selection, so reach for it only when you deliberately want to pin wagmi
to a specific account.
Vanilla JS
syncDynamicWagmi keeps a wagmi config on Dynamic's selected EVM wallet account,
with no React involved. It subscribes to Dynamic's wallet events and drives
wagmi's connect / disconnect whenever that selection changes — login, wallet
switch, or logout — and returns a function that stops the sync.
Create your wagmi config once at startup — you don't have a wallet account
yet, and you never rebuild the config. There is no Dynamic connector in
createConfig:
import { createConfig, http } from '@wagmi/core';
import { mainnet } from 'viem/chains';
export const config = createConfig({
chains: [mainnet],
transports: { [mainnet.id]: http() },
});
Then start the sync once — there is no walletAccount argument, and you never
build a connector yourself:
import { setSelectedWalletAccount } from '@dynamic-labs-sdk/client';
import { syncDynamicWagmi } from '@dynamic-labs-sdk/wagmi';
const stopSync = syncDynamicWagmi({ config });
// When you're done (teardown / logout):
stopSync();
It can start before the user has a wallet: wagmi stays disconnected until an EVM wallet account is selected.
If you use multiple Dynamic clients, pass the client as the second argument:
const stopSync = syncDynamicWagmi({ config }, client);
Switching the target wallet account
Switching is a Dynamic call — no wagmi code:
import { setSelectedWalletAccount } from '@dynamic-labs-sdk/client';
// wagmi re-points to nextWalletAccount automatically.
await setSelectedWalletAccount({ walletAccount: nextWalletAccount });
Pinning wagmi to one specific account
If you want wagmi on an account of your choosing rather than Dynamic's selected one, build the connector yourself. The wallet provider is derived from the account, so you only ever pass the account:
import { connect, disconnect, getConnections } from '@wagmi/core';
import { createDynamicWagmiConnector } from '@dynamic-labs-sdk/wagmi';
await connect(config, {
connector: createDynamicWagmiConnector({ walletAccount }),
});
// Dynamic-backed connectors carry `type: 'dynamic'`, so you can disconnect
// yours by name and leave connections your app made elsewhere untouched.
const dynamicConnections = getConnections(config).filter(
(connection) => connection.connector.type === 'dynamic'
);
for (const { connector } of dynamicConnections) {
await disconnect(config, { connector });
}
This connector is bound to that single account and does not react to
setSelectedWalletAccount(...); to point it elsewhere, disconnect it and connect
a connector built for the other account.
If you use multiple Dynamic clients, pass the client as the second argument:
const connector = createDynamicWagmiConnector({ walletAccount }, client);
React
SyncDynamicWagmi (or the useSyncDynamicWagmi hook) is the React wrapper
around syncDynamicWagmi — it runs the sync for the component's lifetime. It
watches Dynamic's selected EVM wallet account and drives wagmi's connect /
disconnect for you whenever that selection changes — login, wallet switch, or
logout. You do not pass a walletAccount, and you never build a connector
yourself.
The payoff: call Dynamic's setSelectedWalletAccount(...) anywhere in your app
and wagmi follows automatically — useAccount and friends re-point to the newly
selected account with no extra wiring. Dynamic stays the source of truth; wagmi
is a read-only mirror. It renders nothing.
import { DynamicProvider } from '@dynamic-labs-sdk/react-hooks';
import { SyncDynamicWagmi } from '@dynamic-labs-sdk/wagmi/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { WagmiProvider, createConfig, http } from 'wagmi';
import { mainnet } from 'wagmi/chains';
// Your Dynamic client, created once via createDynamicClient(...).
import { client } from './dynamicClient';
// Dynamic handles wallet discovery, so disable wagmi's own injected discovery.
const config = createConfig({
chains: [mainnet],
multiInjectedProviderDiscovery: false,
transports: { [mainnet.id]: http() },
});
const queryClient = new QueryClient();
// DynamicProvider makes the client available to the rest of Dynamic's React
// hooks (useUser, useGetWalletAccounts, ...). SyncDynamicWagmi uses the same
// client to keep wagmi in sync.
export const Providers = ({ children }) => (
<DynamicProvider client={client}>
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<SyncDynamicWagmi config={config} />
{children}
</QueryClientProvider>
</WagmiProvider>
</DynamicProvider>
);
Once mounted, any wagmi hook mirrors the selected Dynamic wallet, and switching accounts is just a Dynamic call — no wagmi code:
import { setSelectedWalletAccount } from '@dynamic-labs-sdk/client';
import { useAccount } from 'wagmi';
const { address, isConnected } = useAccount();
// wagmi re-points to nextWalletAccount automatically.
await setSelectedWalletAccount({ walletAccount: nextWalletAccount });
The hook is also available directly:
import { useSyncDynamicWagmi } from '@dynamic-labs-sdk/wagmi/react';
useSyncDynamicWagmi({ config });
What's supported
connect/disconnectgetAccounts/getChainId/isAuthorizedswitchChain- Forwarding Dynamic wallet events (account change, network change, disconnect) to wagmi.
Notes & limitations
- v1 bridges a single EVM account at a time (the selected one when syncing, the one you pass otherwise). Bridging multiple EVM accounts simultaneously is a follow-up — let us know if you need this feature.
- Only EVM wallet accounts are bridged. Selecting a non-EVM wallet account (e.g. Solana) leaves wagmi disconnected until an EVM wallet account is selected again.
- Not every Dynamic wallet provider can change networks. When the underlying
provider cannot,
switchChain— andconnect(config, { connector, chainId })with a chain other than the wallet's current one — rejects with wagmi'sSwitchChainNotSupportedErrorinstead of silently staying on the old network.