protocols/wagmi-viem-integration
wagmi + viem Frontend Integration
ethereumguide🏛️ Officialconfidence highhealth 100%
v1.0.0·Updated 3/20/2026
Installation
npm install wagmi viem @tanstack/react-query
Configuration Setup
// config.ts
import { createConfig, http } from 'wagmi'
import { mainnet, sepolia, polygon, base } from 'wagmi/chains'
import { injected, walletConnect, coinbaseWallet } from 'wagmi/connectors'
export const config = createConfig({
chains: [mainnet, sepolia, polygon, base],
connectors: [
injected(),
walletConnect({ projectId: 'YOUR_PROJECT_ID' }),
coinbaseWallet({ appName: 'My App' }),
],
transports: {
[mainnet.id]: http(),
[sepolia.id]: http(),
},
})
// App.tsx
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { config } from './config'
const queryClient = new QueryClient()
export function App() {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<YourApp />
</QueryClientProvider>
</WagmiProvider>
)
}
Common Hooks
import { useAccount, useConnect, useDisconnect, useBalance, useReadContract, useWriteContract, useWaitForTransactionReceipt } from 'wagmi'
// Connection status
const { address, isConnected, chain } = useAccount()
// Balance
const { data: balance } = useBalance({ address, token: USDC_ADDRESS })
// Read contract
const { data: totalSupply } = useReadContract({
address: TOKEN_ADDRESS, abi: ERC20_ABI, functionName: 'totalSupply',
})
// Write contract
const { writeContract, data: hash } = useWriteContract()
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash })
function sendTx() {
writeContract({ address: CONTRACT, abi: ABI, functionName: 'transfer', args: [to, amount] })
}
Direct viem Usage (Without React)
import { createPublicClient, createWalletClient, http, parseEther } from 'viem'
import { mainnet } from 'viem/chains'
// Read
const publicClient = createPublicClient({ chain: mainnet, transport: http() })
const balance = await publicClient.getBalance({ address: '0x...' })
const result = await publicClient.readContract({ address, abi, functionName: 'balanceOf', args: [userAddr] })
// Write
const walletClient = createWalletClient({ account, chain: mainnet, transport: http() })
const hash = await walletClient.writeContract({ address, abi, functionName: 'transfer', args: [to, parseEther('1')] })
await publicClient.waitForTransactionReceipt({ hash })
TypeScript ABI Type Inference
// Use const assertion to preserve type information
const ERC20_ABI = [...] as const
// Or use viem's parseAbi
import { parseAbi } from 'viem'
const abi = parseAbi(['function balanceOf(address) returns (uint256)', 'event Transfer(address indexed from, address indexed to, uint256 value)'])
Common Pitfalls
useReadContracthas a default refetch interval of 4s; setwatch: truefor real-time monitoring- After
writeContractreturns a hash, you still needuseWaitForTransactionReceiptto wait for confirmation - In multi-chain projects, note that when switching chains the address remains the same but chainId changes—monitor
chain.id - WalletConnect projectId must be obtained from cloud.walletconnect.com