
Wagmi
- 13 installs
- 4 repo stars
- Updated February 25, 2026
- hairyf/blockchain-master
Build Ethereum frontends with Wagmi - React/Vue/Solid hooks and Core for config, connectors, wallet connect, and contract read/write.
About
Wagmi provides reactive Ethereum primitives as React/Vue/Solid hooks and a vanilla Core, built on Viem and TanStack Query. A developer uses it to connect wallets and read/write contracts in a frontend.
- Config, connectors, connect wallet, and contract read/write
- Built on Viem and TanStack Query with a codegen CLI
Wagmi by the numbers
- 13 all-time installs (skills.sh)
- Ranked #289 of 479 Web3 & Blockchain skills by installs in the Skillselion catalog
- Data as of Jul 13, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hairyf/blockchain-master --skill wagmiAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 13 |
|---|---|
| repo stars | ★ 4 |
| Last updated | February 25, 2026 |
| Repository | hairyf/blockchain-master ↗ |
What it does
Build Ethereum frontends with Wagmi - React/Vue/Solid hooks and Core for config, connectors, wallet connect, and contract read/write.
Files
Skill based on Wagmi v3.4.2, generated 2026-02-09. Docs: https://wagmi.sh
Wagmi provides reactive Ethereum primitives: React/Vue/Solid hooks and Wagmi Core (vanilla). Built on Viem and TanStack Query. This skill focuses on agent capabilities — config, connectors, connect wallet, read/write contract, query/mutation options, CLI, and TypeScript.
Core References
| Topic | Description | Reference |
|---|---|---|
| createConfig | Chains, transports, connectors, storage, Config API | core-config |
| Transports | http, fallback, webSocket, custom — RPC configuration per chain | core-transports |
| Storage | createStorage — custom persistence (cookie, IndexedDB), serialize/deserialize | core-storage |
| Core Actions | Vanilla usage: getConnection, ENS, readContract, writeContract | core-actions |
| Connectors | injected, WalletConnect, MetaMask, Coinbase, Safe, EIP-6963 | core-connectors |
React
| Topic | Description | Reference |
|---|---|---|
| Setup | WagmiProvider, QueryClientProvider, config | react-setup |
| Connect Wallet | useConnect, useAccount, useDisconnect, useConnectors, useConnection | react-connect-wallet |
| Reconnect | useReconnect, reconnectOnMount | react-reconnect |
| Chain & Network | useChainId, useChains, useSwitchChain | react-chain-network |
| Block & Balance | useBlockNumber, useBalance | react-block-balance |
| Send Transaction | useSendTransaction, useWaitForTransactionReceipt — raw ETH/tx | react-send-transaction |
| Read/Write Contract | useReadContract, useWriteContract, useSimulateContract, useWaitForTransactionReceipt | react-read-write-contract |
| ENS | useEnsName, useEnsAddress, useEnsAvatar, useEnsResolver, useEnsText | react-ens |
| Sign Message | useSignMessage, useSignTypedData — EIP-191 and EIP-712 | react-sign-message |
| TanStack Query | query/mutation options, caching, SSR, Devtools | react-tanstack-query |
Features
| Topic | Description | Reference |
|---|---|---|
| create-wagmi CLI | Scaffold Next/Nuxt/Vite React/Vue/Vanilla projects | features-cli |
| SSR | ssr flag, cookie storage, cookieToInitialState, serialize/deserialize | features-ssr |
Best Practices
| Topic | Description | Reference |
|---|---|---|
| TypeScript | Register config, chain/ABI inference, strict types | best-practices-typescript |
| Error Handling | Typed errors, BaseError, discriminating by error.name | best-practices-error-handling |
External Links
Generation Info
- Source:
sources/wagmi(site docs:site/) - Git SHA:
79caafe2c6d16b3d5820963a803eb42672b16339 - Generated: 2026-02-09
- Wagmi version: 3.4.2 (packages/react)
- Supplemented (more): 2026-02-25 — core-transports, react-send-transaction, react-ens, react-sign-message, react-chain-network; best-practices-error-handling, features-ssr, react-block-balance, core-storage, react-reconnect
Error Handling
Wagmi hook error is strongly typed. Discriminate by `error.name` for granular handling. Use BaseError for a shared shortMessage when displaying to users.
Discriminating by error name
const { data, error } = useBlockNumber()
if (error?.name === 'HttpRequestError') {
const { status } = error
return <div>HTTP error. Status: {status}</div>
}
if (error?.name === 'LimitExceededRpcError') {
const { code } = error
return <div>Rate limit exceeded. Code: {code}</div>
}BaseError
All Wagmi errors extend BaseError. For UI, use (error as BaseError).shortMessage or error.message for a readable string.
import type { BaseError } from 'wagmi'
{error && (
<div>Error: {(error as BaseError).shortMessage || error.message}</div>
)}Config / connector errors
- ChainNotConfiguredError — Chain not in
createConfigchains. - ConnectorNotFoundError / ConnectorNotConnectedError — Connector missing or not connected.
- ConnectorAlreadyConnectedError — Connect called when already connected.
- ConnectorAccountNotFoundError — Account not available on connector.
- ConnectorChainMismatchError — Config chain out of sync with connector (rare).
- ConnectorUnavailableReconnectingError — Connector not fully available during reconnect.
- ProviderNotFoundError — Connector provider (e.g.
window.ethereum) not found. - SwitchChainNotSupportedError — Connector doesn’t support chain switching.
WagmiProviderNotFoundError
Thrown when a Wagmi hook is used outside WagmiProvider. Ensure the component tree is wrapped in WagmiProvider.
Key points
- Prefer
error?.name === '...'for branching; useBaseErrorfor display. - Handle user rejection and RPC/rate-limit errors in connect, send, and sign flows.
<!-- Source references:
- https://wagmi.sh/react/guides/error-handling
- https://wagmi.sh/react/api/errors
- sources/wagmi/site/shared/errors.md
-->
TypeScript Best Practices
Register config (recommended)
Register the app config so hooks infer chainId and chains from your config instead of number:
import { type Config } from 'wagmi'
import { mainnet, sepolia } from 'wagmi/chains'
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
export const config = createConfig({
chains: [mainnet, sepolia],
transports: { [mainnet.id]: http(), [sepolia.id]: http() },
})Then useBlockNumber({ chainId: 123 }) will error; only mainnet.id / sepolia.id allowed.
Hook config property
Alternatively pass config to each hook so types use that config: useBlockNumber({ config, chainId: mainnet.id }). Useful for tests or multiple configs.
ABI inference
Pass const ABIs for inferred types and autocomplete:
const erc20Abi = [
{ type: 'function', name: 'balanceOf', stateMutability: 'view', inputs: [{ name: 'account', type: 'address' }], outputs: [{ type: 'uint256' }] },
] as const
useReadContract({ address: '0x...', abi: erc20Abi, functionName: 'balanceOf', args: [addr] })
// args and return type inferredLock wagmi and TypeScript to patch versions when upgrading to avoid type churn.
<!-- Source references:
- https://wagmi.sh/react/typescript
- sources/wagmi/site/react/typescript.md
- sources/wagmi/site/react/getting-started.md (register config snippet)
-->
Wagmi Core Actions
Wagmi Core (@wagmi/core) is framework-agnostic. Pass config to actions to read/write chain data, resolve ENS, and interact with contracts without React/Vue.
Setup
import { createConfig, http } from '@wagmi/core'
import { mainnet, sepolia } from '@wagmi/core/chains'
const config = createConfig({
chains: [mainnet, sepolia],
transports: { [mainnet.id]: http(), [sepolia.id]: http() },
})Common Actions
- getConnection(config) — Get current connection (
address,chainId,connector). Returnsundefinedwhen disconnected. - getEnsName(config, { address }) — Resolve ENS name for address.
- getEnsAddress(config, { name }) — Resolve address for ENS name.
- getBlockNumber(config, { chainId? }) — Latest block number.
- readContract(config, { address, abi, functionName, args?, chainId? }) — Read from contract (view/pure).
- writeContract(config, { address, abi, functionName, args?, account?, chainId? }) — Write to contract (returns tx hash).
- sendTransaction(config, { to, value?, data?, account?, chainId? }) — Send a transaction.
All async actions accept config as first argument; chain-specific options use chainId from config or override.
Usage
import { getConnection, getEnsName, readContract } from '@wagmi/core'
import { config } from './config'
const { address } = getConnection(config) ?? {}
const ensName = address ? await getEnsName(config, { address }) : null
const balance = await readContract(config, {
address: '0x...',
abi: erc20Abi,
functionName: 'balanceOf',
args: [address],
})Framework Adapters
Core is the base for React (wagmi), Vue (@wagmi/vue), and Solid (@wagmi/solid). Hooks/composables wrap these actions with reactive state and TanStack Query. For custom frameworks, use Core actions directly or build an adapter that subscribes to config.subscribe.
<!-- Source references:
- https://wagmi.sh/core/getting-started
- sources/wagmi/site/core/getting-started.md
- sources/wagmi/site/core/api/actions
-->
createConfig
Creates the Wagmi Config object that manages chains, transports, connectors, and internal state. Used by both Core (vanilla) and React/Vue/Solid.
Usage
import { createConfig, http } from 'wagmi'
import { mainnet, sepolia } from 'wagmi/chains'
const config = createConfig({
chains: [mainnet, sepolia],
transports: {
[mainnet.id]: http('https://mainnet.example.com'),
[sepolia.id]: http('https://sepolia.example.com'),
},
})With connectors (React/Vue):
import { createConfig, http } from 'wagmi'
import { mainnet, sepolia } from 'wagmi/chains'
import { injected, walletConnect } from 'wagmi/connectors'
const config = createConfig({
chains: [mainnet, sepolia],
connectors: [injected(), walletConnect({ projectId: '...' })],
transports: {
[mainnet.id]: http(),
[sepolia.id]: http(),
},
})Key Parameters
- chains —
readonly [Chain, ...Chain[]]. Chains the config uses; built-in chains fromwagmi/chains. - transports —
Record<chainId, Transport>. Map chain ID to transport (e.g.http(),fallback([...]),webSocket()). Used to create internal Viem clients. - connectors — Optional. Connectors for wallet connection (injected, metaMask, walletConnect, etc.).
- client — Optional. Function
({ chain }) => Clientfor custom Viem client creation instead oftransports. - storage — Optional. Persists config state (e.g.
createStorage({ storage: window.localStorage })). Defaults to localStorage when available. - ssr — Set
truefor server-side rendering. - syncConnectedChain — Keep
state.chainIdin sync with current connection (defaulttrue). - multiInjectedProviderDiscovery — EIP-6963 injected provider discovery (default
true). - batch, cacheTime, pollingInterval — Tune batching and polling; see Viem client docs.
Config API
config.getClient({ chainId })— Get Viem client for a chain.config.setState(updater)— Update internal state (advanced).config.subscribe(selector, listener)— Subscribe to state slices; returns unsubscribe.
State Shape
Config.state includes: chainId, connections (Map of connector id → Connection), current (active connection id), status ('connected' | 'connecting' | 'disconnected' | 'reconnecting').
<!-- Source references:
- https://wagmi.sh/react/api/createConfig
- sources/wagmi/site/shared/createConfig.md
-->
Connectors
Connectors link wallets to Wagmi. Import from wagmi/connectors (React) or @wagmi/vue/connectors (Vue), etc.
Built-in Connectors
- injected() — EIP-1193 injected provider (MetaMask, Brave, etc.). Use
shimDisconnect: true(default) to simulate disconnect in storage. Optionaltargetfor EIP-6963 provider. - walletConnect({ projectId }) — WalletConnect v2; requires Project ID.
- metaMask() — MetaMask extension.
- coinbaseWallet({ appName, preference }) — Coinbase Wallet.
- safe() — Safe (formerly Gnosis Safe) wallet.
- baseAccount() — Base ecosystem account connector.
Usage
import { createConfig, http } from 'wagmi'
import { mainnet } from 'wagmi/chains'
import { injected, walletConnect, metaMask } from 'wagmi/connectors'
const config = createConfig({
chains: [mainnet],
connectors: [
injected(),
walletConnect({ projectId: 'YOUR_PROJECT_ID' }),
metaMask(),
],
transports: { [mainnet.id]: http() },
})EIP-6963 (multi-injected)
createConfig has multiInjectedProviderDiscovery (default true), which uses mipd to discover EIP-6963 providers and expose them as injected connectors. Set to false to disable.
Creating Connectors
See dev docs for implementing custom connectors (e.g. createConnector and connector interface).
<!-- Source references:
- https://wagmi.sh/react/api/connectors
- sources/wagmi/site/shared/connectors/injected.md
- sources/wagmi/site/react/guides/connect-wallet.md
-->
createStorage
Creates a Storage object used by createConfig({ storage }) to persist Wagmi state (connections, chainId, etc.). Default is localStorage; use createStorage for cookies, IndexedDB, or a custom backend.
Usage
import { createStorage } from 'wagmi'
const storage = createStorage({ storage: localStorage })
const config = createConfig({
chains: [mainnet, sepolia],
storage,
transports: { ... },
})Parameters
- storage — Object with
getItem(key),setItem(key, value),removeItem(key)(sync or async). Default:localStorage. - key — Prefix for stored keys. Default:
'wagmi'. - serialize / deserialize — Custom serializers. Defaults use Wagmi’s serialize and deserialize (support
bigint,Map). If custom, must handle those types.
Cookie storage
Use cookieStorage from wagmi with createStorage for SSR/cookie persistence:
import { createStorage, cookieStorage } from 'wagmi'
const storage = createStorage({ storage: cookieStorage })Custom async storage (e.g. IndexedDB)
import { createStorage } from 'wagmi'
import { get, set, del } from 'idb-keyval'
const storage = createStorage({
storage: {
getItem: (name) => get(name),
setItem: (name, value) => set(name, value),
removeItem: (name) => del(name),
},
})Storage interface
Returned storage has getItem(key, defaultValue?), setItem(key, value), removeItem(key). Used internally by config; you can also read/write for debugging (e.g. storage.getItem('recentConnectorId')).
Key points
- Use createStorage when you need cookies (SSR), IndexedDB, or a custom backend.
- Custom serialize/deserialize must support bigint and Map for Wagmi state.
<!-- Source references:
- https://wagmi.sh/react/api/createStorage
- sources/wagmi/site/shared/createStorage.md
-->
Transports
Transports are the layer that executes JSON-RPC requests to RPC providers. Pass them in createConfig({ transports: { [chainId]: transport } }). Available from wagmi: http, fallback, webSocket, custom (EIP-1193).
http
Connects via HTTP. Provide a dedicated RPC URL to avoid rate limits; omitting URL falls back to public RPC.
import { createConfig, http } from 'wagmi'
import { mainnet, sepolia } from 'wagmi/chains'
const config = createConfig({
chains: [mainnet, sepolia],
transports: {
[mainnet.id]: http('https://mainnet.example.com'),
[sepolia.id]: http('https://sepolia.example.com'),
},
})Options: batch: true (or { batchSize, wait }) for batch JSON-RPC; fetchOptions (e.g. headers); key, name; retryCount, retryDelay, timeout.
fallback
Tries multiple transports in order; on failure, uses the next.
import { createConfig, fallback, http } from 'wagmi'
import { mainnet } from 'wagmi/chains'
const config = createConfig({
chains: [mainnet],
transports: {
[mainnet.id]: fallback([
http('https://primary.example.com'),
http('https://backup.example.com'),
]),
},
})webSocket
Connects via WebSocket. Use for subscriptions (e.g. watchBlockNumber, watchContractEvent). Options: key, name, retryCount, retryDelay, timeout.
import { createConfig, webSocket } from 'wagmi'
import { mainnet } from 'wagmi/chains'
const config = createConfig({
chains: [mainnet],
transports: {
[mainnet.id]: webSocket('wss://mainnet.example.com'),
},
})custom (EIP-1193)
Wraps a custom EIP-1193 provider. Use when integrating a non-standard RPC provider that exposes request({ method, params }).
Key points
- Prefer explicit RPC URLs for
http()andwebSocket()in production. - Use
fallback([http(...), http(...)])for resilience. - Use
http(..., { batch: true })to batch multiple RPC calls into one request.
<!-- Source references:
- https://wagmi.sh/react/api/transports
- sources/wagmi/site/shared/transports/http.md
- sources/wagmi/site/shared/transports/fallback.md
- sources/wagmi/site/shared/transports/webSocket.md
-->
create-wagmi CLI
Scaffolds new Wagmi projects with config, providers, and optional framework.
Usage
pnpm create wagmi
# or
npm create wagmi@latest
yarn create wagmi
bun create wagmiPrompts: project name, framework (React / Vanilla), variant. Use -t / --template to skip prompts.
Templates
- next — Next.js + Wagmi
- nuxt — Nuxt + Wagmi
- vite-react — Vite + React
- vite-vanilla — Vite + Wagmi Core (no React)
- vite-vue — Vite + Vue
Example:
pnpm create wagmi --template nextPackage manager
Use --pnpm, --npm, --yarn, or --bun to force package manager for install.
Other CLI commands
@wagmi/cli provides generate (from ABIs/config) and init; see CLI docs and config (wagmi.config.*) for codegen.
<!-- Source references:
- https://wagmi.sh/cli/create-wagmi
- sources/wagmi/site/cli/create-wagmi.md
-->
Block Number & Balance
useBlockNumber — most recent block number. useBalance — native currency balance for an address.
useBlockNumber
import { useBlockNumber } from 'wagmi'
const { data: blockNumber } = useBlockNumber()
// blockNumber: bigint | undefinedParameters: chainId, config, scopeKey, cacheTime, and watch — set watch: true to subscribe to new blocks (or pass options for useWatchBlockNumber). Query options (enabled, etc.) apply.
useBalance
import { useBalance } from 'wagmi'
const { data } = useBalance({
address: '0x4557B18E779944BFE9d78A672452331C186a9f48',
})
// data: { decimals, symbol, value: bigint } | undefinedParameters: address (required for balance), chainId, blockNumber, blockTag, config, scopeKey, plus query options.
Typical usage with connected account:
const { address } = useAccount()
const { data: balance } = useBalance({ address })
// balance.value is wei (bigint); use formatEther(balance.value) for displayCore actions
- getBlockNumber / watchBlockNumber
- getBalance
Key points
- Use
watch: trueonuseBlockNumberfor live block updates (e.g. countdowns). - Balance is in wei; use viem’s
formatEther/formatUnitsfor display. - Omit
addressor setenabled: falsewhen address is not yet available.
<!-- Source references:
- https://wagmi.sh/react/api/hooks/useBlockNumber
- https://wagmi.sh/react/api/hooks/useBalance
-->
Chain and Network
Hooks for reading the current chain and switching: useChainId, useChains, useSwitchChain.
useChainId
Returns the current chain ID (from config state / active connection).
import { useChainId } from 'wagmi'
const chainId = useChainId()
// number — only from chains in createConfig chainsIf the connected wallet is on a chain not in your config, Wagmi returns the last configured chain ID.
useChains
Returns the list of chains passed to createConfig({ chains }).
import { useChains } from 'wagmi'
const chains = useChains()
// readonly [Chain, ...Chain[]]Use to render a chain selector or guard by supported chain.
useSwitchChain
Switches the target chain. When connected, switches the connector's chain; when disconnected, updates the config's default chain.
import { useChains, useSwitchChain } from 'wagmi'
const switchChain = useSwitchChain()
const chains = useChains()
return (
<div>
{chains.map((chain) => (
<button
key={chain.id}
onClick={() => switchChain.mutate({ chainId: chain.id })}
>
{chain.name}
</button>
))}
</div>
)Return: mutation-style { mutate, mutateAsync, data, isPending, error, chains (deprecated) }. Prefer useChains() for the chain list instead of switchChain.chains.
Core actions
- getChainId / watchChainId
- getChains
- switchChain
Key points
- Chain IDs returned are limited to those in
createConfig'schains. - Use
useSwitchChainfor network switcher UI; handle errors (e.g. user rejection, unsupported chain).
<!-- Source references:
- https://wagmi.sh/react/api/hooks/useChainId
- https://wagmi.sh/react/api/hooks/useChains
- https://wagmi.sh/react/api/hooks/useSwitchChain
- https://wagmi.sh/react/guides/chain-properties
-->
Connect Wallet (React)
Hooks for connection state and connecting/disconnecting wallets.
Hooks
- useConnectors() — List of available connectors from config.
- useConnect() —
connect({ connector }),pendingConnector,error,status. Callconnect({ connector })to connect. - useAccount() —
address,addresses,chain,chainId,connector,status,isConnected,isConnecting,isDisconnected,isReconnecting. - useConnection() — Current connection (same as active account);
connection(address, chainId, connector). - useDisconnect() —
disconnect()to disconnect. - useChainId() — Current chain ID from config/connection.
Pattern
function ConnectButton() {
const { connectors, connect, status, error } = useConnect()
const { address, isConnected } = useAccount()
const { disconnect } = useDisconnect()
if (isConnected) {
return (
<>
<span>{address}</span>
<button onClick={() => disconnect()}>Disconnect</button>
</>
)
}
return (
<>
{connectors.map((c) => (
<button key={c.uid} onClick={() => connect({ connector: c })}>
{c.name}
</button>
))}
{status === 'pending' && <span>Connecting...</span>}
{error && <span>{error.message}</span>}
</>
)
}Multiple Connections
Wagmi supports multiple connections (e.g. EIP-6963). Use useConnections() for list and useSwitchConnection() to switch active connection.
<!-- Source references:
- https://wagmi.sh/react/guides/connect-wallet
- sources/wagmi/site/react/guides/connect-wallet.md
-->
ENS
Wagmi provides React hooks for ENS lookups. Primary ones: useEnsName (address → name), useEnsAddress (name → address), useEnsAvatar (address → avatar URL). Optional: useEnsResolver, useEnsText for custom resolver/text records.
useEnsName
Resolve primary ENS name for an address.
import { useEnsName } from 'wagmi'
const { data: name } = useEnsName({
address: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
})
// name: string | nullParameters: address (required), chainId, blockNumber, blockTag, universalResolverAddress, scopeKey, query options (enabled, etc.).
useEnsAddress
Resolve address for an ENS name.
import { useEnsAddress } from 'wagmi'
const { data: address } = useEnsAddress({
name: 'vitalik.eth',
})
// address: Address | nulluseEnsAvatar
Get avatar URL for an address (ENS avatar or default).
import { useEnsAvatar } from 'wagmi'
const { data: avatarUrl } = useEnsAvatar({
address: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
})
// avatarUrl: string | nulluseEnsResolver / useEnsText
- useEnsResolver: Get resolver address for a name.
- useEnsText: Read a text record (e.g.
description,url) from ENS.
Core actions
Same capabilities exist in Core (vanilla): getEnsName, getEnsAddress, getEnsAvatar, getEnsResolver, getEnsText.
Key points
- ENS resolution is typically on mainnet; pass
chainId: mainnet.idif your config has multiple chains. - Use
enabled: !!address(or similar) to avoid running when input is missing.
<!-- Source references:
- https://wagmi.sh/react/api/hooks/useEnsName
- https://wagmi.sh/react/api/hooks/useEnsAddress
- https://wagmi.sh/react/api/hooks/useEnsAvatar
- sources/wagmi/site/react/api/hooks/useEnsName.md
-->
Read & Write Contract (React)
useReadContract
Read from contract view/pure functions. No gas; cached via TanStack Query.
const { data, error, isPending, refetch } = useReadContract({
address: '0x...',
abi: erc20Abi,
functionName: 'balanceOf',
args: [address],
query: { enabled: !!address },
})- address, abi, functionName, args (optional) — Contract call.
- query — TanStack Query options (e.g.
enabled,staleTime). Do not overridequeryKey/queryFn. - Returns data (decoded result), error, isPending, refetch.
useWriteContract
Write (mutate) contract. Returns mutation: writeContract, writeContractAsync, data (hash), error, isPending, reset.
const { writeContract, data: hash, isPending } = useWriteContract()
// call
writeContract({
address: nftAddress,
abi: nftAbi,
functionName: 'mint',
args: [tokenId],
})Then wait for receipt with useWaitForTransactionReceipt({ hash }); data is the receipt.
useSimulateContract
Simulate a write (estimate gas, validate args) before calling useWriteContract. Use useSimulateContract result in writeContract for type-safe args and gas estimation.
const { data: simulation } = useSimulateContract({
address,
abi,
functionName: 'mint',
args: [tokenId],
})
const { writeContract } = useWriteContract()
// writeContract(simulation?.request)useReadContracts
Batch multiple read contracts in one hook for multiple contracts or functions; returns array of results.
Chain-specific Behavior
Some chains (e.g. Celo, zkSync) have custom properties; use useBlock, useBlockNumber, or chain config. For gas/time estimates use useSimulateContract or chain-specific hooks.
<!-- Source references:
- https://wagmi.sh/react/guides/read-from-contract
- https://wagmi.sh/react/guides/write-to-contract
- sources/wagmi/site/react/guides/read-from-contract.md
- sources/wagmi/site/react/guides/write-to-contract.md
-->
Reconnect
Wagmi can restore the last used connector(s) when the app loads. useReconnect triggers reconnection manually; WagmiProvider’s reconnectOnMount enables automatic reconnect on mount.
useReconnect
Mutation-style hook: call reconnect.mutate() to attempt to reconnect previously used connectors.
import { useReconnect } from 'wagmi'
import { useEffect } from 'react'
const reconnect = useReconnect()
useEffect(() => {
reconnect.mutate()
}, [])Return: { mutate, mutateAsync, data, isPending, error }. Optional mutate({ connectors }) to limit which connectors to try (deprecated to pass connectors; prefer global config).
Automatic reconnect (reconnectOnMount)
WagmiProvider accepts reconnectOnMount (default true). When true, Wagmi calls reconnect automatically on mount so you usually don’t need to call useReconnect yourself.
<WagmiProvider config={config} reconnectOnMount={true}>
{children}
</WagmiProvider>When to use
- Rely on reconnectOnMount for typical “remember last wallet” behavior.
- Use useReconnect only when you need to trigger reconnect at a custom time (e.g. after login) or when reconnectOnMount is disabled.
Core action
reconnect — same in Core.
Key points
- Reconnection runs on mount by default; disable with reconnectOnMount={false} if you want full control.
- During reconnect, some connector methods may be unavailable until reconnection completes (ConnectorUnavailableReconnectingError).
<!-- Source references:
- https://wagmi.sh/react/api/hooks/useReconnect
- https://wagmi.sh/react/api/WagmiProvider
-->
Send Transaction
Sending a raw transaction (e.g. transfer ETH) is separate from writing to a contract. Use useSendTransaction to create, sign, and send; use useWaitForTransactionReceipt to wait for confirmation.
Usage
import { useSendTransaction, useWaitForTransactionReceipt } from 'wagmi'
import { parseEther } from 'viem'
function SendTransaction() {
const { data: hash, isPending, error, sendTransaction } = useSendTransaction()
const { isLoading: isConfirming, isSuccess: isConfirmed } =
useWaitForTransactionReceipt({ hash })
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault()
const formData = new FormData(e.target as HTMLFormElement)
const to = formData.get('address') as `0x${string}`
const value = formData.get('value') as string
sendTransaction({ to, value: parseEther(value) })
}
return (
<form onSubmit={handleSubmit}>
<input name="address" placeholder="0xA0Cf…251e" required />
<input name="value" placeholder="0.05" required />
<button type="submit" disabled={isPending}>
{isPending ? 'Confirming...' : 'Send'}
</button>
{hash && <div>Tx Hash: {hash}</div>}
{isConfirming && <div>Waiting for confirmation...</div>}
{isConfirmed && <div>Confirmed.</div>}
{error && <div>Error: {error.message}</div>}
</form>
)
}useSendTransaction
- Return:
{ data: hash, sendTransaction, isPending, error, ... }— mutation-style; callsendTransaction({ to, value?, data?, gas?, ... })to send. - useSendTransactionSync: Waits for inclusion before resolving; use when you need the receipt before continuing.
useWaitForTransactionReceipt
- Parameters:
{ hash }— transaction hash fromuseSendTransaction().data. - Return:
{ data: receipt, isLoading: isConfirming, isSuccess: isConfirmed }— use for UI feedback.
Key points
- Use
parseEther(value)from viem for ETH amounts; for contract calls useuseWriteContractinstead. - Handle
error(e.g. user rejection, insufficient funds) and showisPending/isConfirmingfor UX.
<!-- Source references:
- https://wagmi.sh/react/guides/send-transaction
- https://wagmi.sh/react/api/hooks/useSendTransaction
- https://wagmi.sh/react/api/hooks/useWaitForTransactionReceipt
-->
React Setup
Wagmi React uses a single config, WagmiProvider, and TanStack Query for caching and reactivity.
Provider Tree
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { WagmiProvider } from 'wagmi'
import { config } from './config'
const queryClient = new QueryClient()
function App() {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
{/* app */}
</QueryClientProvider>
</WagmiProvider>
)
}Order: WagmiProvider wraps QueryClientProvider (or vice versa per docs; typically Wagmi outer so config is available everywhere).
Config
Create config with createConfig from wagmi: set chains, connectors, and transports. Same config is used by all hooks via context; optional config argument on hooks overrides for testing or multiple configs.
Hooks Scope
Hooks (useAccount, useReadContract, etc.) must run under both providers. Pass config to a hook to use a specific config instead of context.
<!-- Source references:
- https://wagmi.sh/react/getting-started
- sources/wagmi/site/react/getting-started.md
- sources/wagmi/site/react/guides/connect-wallet.md
-->
Sign Message
Signing messages (EIP-191 personal sign or EIP-712 typed data) does not send a transaction; it prompts the wallet and returns a signature. Use useSignMessage for raw strings and useSignTypedData for structured EIP-712 data.
useSignMessage
Signs a string (EIP-191). Mutation-style: call signMessage.mutate({ message }).
import { useSignMessage } from 'wagmi'
const signMessage = useSignMessage()
return (
<button onClick={() => signMessage.mutate({ message: 'hello world' })}>
Sign message
</button>
)Return: { mutate, mutateAsync, data: signature, isPending, error, ... }. Parameters: config, plus mutation options (mutationKey, onSuccess, etc.).
useSignTypedData
Signs EIP-712 typed data. Pass domain, types, primaryType, and message.
import { useSignTypedData } from 'wagmi'
const signTypedData = useSignTypedData()
signTypedData.mutate({
domain: { name: 'Example', chainId: 1, version: '1' },
types: {
Person: [
{ name: 'name', type: 'string' },
{ name: 'wallet', type: 'address' },
],
Mail: [
{ name: 'from', type: 'Person' },
{ name: 'to', type: 'Person' },
{ name: 'contents', type: 'string' },
],
},
primaryType: 'Mail',
message: {
from: { name: 'Alice', wallet: '0x...' },
to: { name: 'Bob', wallet: '0x...' },
contents: 'Hello!',
},
})With TypeScript, use as const on types for inferred domain and message types.
Core actions
- signMessage — same in Core.
- signTypedData — same in Core.
Key points
- Signing does not broadcast a tx; use for auth, SIWE, or off-chain agreements.
- For verification: verifyMessage and verifyTypedData (Core/React) use the signature and recovered address.
<!-- Source references:
- https://wagmi.sh/react/api/hooks/useSignMessage
- https://wagmi.sh/react/api/hooks/useSignTypedData
- sources/wagmi/site/react/api/hooks/useSignMessage.md
- sources/wagmi/site/react/api/hooks/useSignTypedData.md
-->
TanStack Query Integration
Wagmi hooks are built on TanStack Query. Query hooks (e.g. useReadContract, useBlockNumber) use query options; mutation hooks (e.g. useWriteContract, useSendTransaction) use mutation options.
Query Options (supported)
Pass query to hooks that support it (e.g. useReadContract, useBalance):
- enabled — Disable auto-run (e.g. dependent queries).
- gcTime — Cache retention (ms); default 5 min (or
Infinityin SSR). - staleTime — Consider data fresh for this duration.
- initialData — Initial cache value.
- refetchInterval, refetchOnWindowFocus, etc. — Per TanStack Query;
queryKey/queryFnare reserved by Wagmi.
Mutation Options
Pass mutation to write hooks:
- onSuccess, onError, onSettled — Callbacks with (data, variables, context).
- onMutate — Optimistic updates; return value passed to onError/onSettled for rollback.
- retry, networkMode, queryClient — Standard TanStack mutation options.
QueryClient
Default: from nearest QueryClientProvider. Override per hook with mutation: { queryClient } or query: { queryClient }.
SSR
Use cookieToInitialState (React) or framework-specific helpers to hydrate from cookies so client state matches server. Persist with createStorage and same backend (e.g. cookie) for connection/chain.
Devtools
TanStack Query Devtools work with Wagmi. Use a custom queryKeyFn or Wagmi’s hashFn from @wagmi/core/query so BigInt serializes correctly in devtools.
<!-- Source references:
- https://wagmi.sh/react/guides/tanstack-query
- sources/wagmi/site/shared/query-options.md
- sources/wagmi/site/shared/mutation-options.md
- sources/wagmi/site/react/guides/tanstack-query.md
-->