本文档基于Wagmi v2+版本整理,已替换所有过期API
本文档基于 Wagmi v2+ 版本整理,已替换所有过期 API:
useContractRead
→ 替换为 useReadContract
useContractWrite
→ 替换为 useWriteContract
useContractEvent
→ 替换为 useWatchContractEvent
所有 Hooks 按功能分类,统一包含「功能、参数、示例、使用场景」,确保代码可直接复用且类型安全。
useAccount
获取当前连接的账户信息(地址、连接状态等),并监听连接/断开事件。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
onConnect |
(data) => void |
账户连接成功时的回调(data 含address /connector ) |
否 |
onDisconnect |
() => void |
账户断开连接时的回调 | 否 |
import { useAccount } from 'wagmi';
function AccountStatus() {
const {
address, // 账户地址(未连接时为undefined)
isConnected, // 是否已连接
isConnecting, // 是否正在连接中
connector // 当前连接的钱包连接器
} = useAccount({
onConnect: (data) => console.log('已连接账户:', data.address),
onDisconnect: () => console.log('已断开连接'),
});
if (isConnecting) return <div>连接中...</div>;
if (!isConnected) return <div>请连接钱包</div>;
return (
<div>
<p>当前账户: {address.slice(0, 6)}...{address.slice(-4)}</p>
<p>钱包: {connector?.name}</p>
</div>
);
}
useAccountEffect
仅监听账户连接/断开状态变化,无 UI 依赖(适合日志记录、状态重置)。
同 useAccount
的 onConnect
和 onDisconnect
。
import { useAccountEffect } from 'wagmi';
function AccountEffectListener() {
useAccountEffect({
onConnect: (data) => {
console.log('账户连接:', data.address);
// 加载用户数据(如持仓、订单)
},
onDisconnect: () => {
console.log('账户断开');
// 重置应用状态(如清空余额缓存)
},
});
return null; // 无 UI 渲染
}
useConnect
处理钱包连接逻辑,支持多连接器(如 MetaMask、WalletConnect)。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
connector |
Connector |
指定连接器(可选,默认用所有配置的连接器) | 否 |
onError |
(error) => void |
连接错误时的回调 | 否 |
import { useConnect } from 'wagmi';
import { InjectedConnector } from 'wagmi/connectors/injected';
function WalletConnectButtons() {
const {
connect, // 触发连接的函数
connectors, // 所有配置的连接器列表
isLoading, // 是否正在连接
error // 连接错误信息
} = useConnect();
return (
<div>
{connectors.map((connector) => (
<button
key={connector.uid}
onClick={() => connect({ connector })}
disabled={!connector.ready || isLoading}
style={{ margin: '0 8px', padding: '8px 16px' }}
>
连接 {connector.name}
{isLoading && ' (连接中...)'}
</button>
))}
{error && <div style={{ color: 'red', marginTop: 8 }}>{error.message}</div>}
</div>
);
}
useDisconnect
断开当前钱包连接。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
onSuccess |
() => void |
断开成功后的回调 | 否 |
import { useDisconnect, useAccount } from 'wagmi';
function DisconnectButton() {
const { isConnected } = useAccount();
const { disconnect, isLoading } = useDisconnect({
onSuccess: () => alert('已断开钱包连接'),
});
if (!isConnected) return null;
return (
<button
onClick={disconnect}
disabled={isLoading}
style={{ color: 'red', padding: '8px 16px' }}
>
{isLoading ? '断开中...' : '断开连接'}
</button>
);
}
Hook 名称 | 功能描述 | 核心参数/使用场景 |
---|---|---|
useConnections |
获取所有当前连接的钱包信息 | 无参数;多钱包管理(如显示已连接账户列表) |
useConnectors |
获取配置中的所有钱包连接器 | 无参数;生成钱包连接按钮列表 |
useReconnect |
重新连接钱包(自动/手动触发) | 无参数;页面刷新后自动重连 |
useSwitchAccount |
切换钱包内的多账户(如 MetaMask 多账户) | 无参数;多账户切换场景 |
useSwitchChain |
切换当前连接的区块链网络 | chainId ;如切换到 Polygon(137) |
useReadContract
(替代 useContractRead
)调用合约只读方法(获取链上数据,不消耗 Gas),支持实时监听。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
address |
Address |
合约地址(0x 开头42位字符串,建议用as const 断言) |
是 |
abi |
Abi |
合约 ABI(需包含目标方法,推荐用 Wagmi 内置 ABI 如erc20Abi ) |
是 |
functionName |
string |
只读方法名(如balanceOf 、totalSupply ) |
是 |
args |
any[] |
方法参数(与 ABI 输入参数顺序/类型匹配,可选) | 否 |
watch |
boolean |
是否实时监听数据变化(默认false ,true 时自动重渲染) |
否 |
chainId |
number |
目标链 ID(可选,默认当前连接链) | 否 |
import { useReadContract } from 'wagmi';
import { erc20Abi } from 'wagmi/abi'; // 内置 ERC20 ABI
// 固定地址用 as const 确保类型安全
const DAI_ADDRESS = '0x6B175474E89094C44Da98b954EedeAC495271d0F' as const;
const USER_ADDRESS = '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e' as const;
function TokenBalance() {
const {
data: balance, // 方法返回结果(uint256 类型,单位 wei)
isLoading, // 加载中状态
isError, // 错误状态
error // 错误信息
} = useReadContract({
address: DAI_ADDRESS,
abi: erc20Abi,
functionName: 'balanceOf', // 只读方法名
args: [USER_ADDRESS], // 参数:查询目标账户
watch: true, // 实时更新余额
});
if (isLoading) return <div>加载中...</div>;
if (isError) return <div>错误: {error.message}</div>;
// 格式化余额(18 小数位转换为可读格式)
const formatted = balance ? (Number(balance) / 10 ** 18).toFixed(4) : '0';
return <div>DAI 余额: {formatted} DAI</div>;
}
totalSupply
)。useWriteContract
(替代 useContractWrite
)调用合约写入方法(发送交易,消耗 Gas,修改链上状态),支持跟踪交易生命周期。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
address |
Address |
合约地址(as const 断言) |
是 |
abi |
Abi |
合约 ABI(包含目标写入方法) | 是 |
functionName |
string |
写入方法名(如transfer 、mint ) |
是 |
args |
any[] |
方法参数(与 ABI 匹配,可选) | 否 |
onSuccess |
(hash) => void |
交易发送成功回调(hash 为交易哈希) |
否 |
onError |
(error) => void |
交易失败回调 | 否 |
import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi';
import { erc20Abi } from 'wagmi/abi';
import { parseEther } from 'viem'; // 转换单位(18 小数位)
const DAI_ADDRESS = '0x6B175474E89094C44Da98b954EedeAC495271d0F' as const;
const RECIPIENT = '0xBbBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as const;
function TokenTransfer() {
// 1. 初始化写入 Hook
const {
writeContract, // 触发交易的函数
data: txHash, // 交易哈希(发送成功后返回)
isLoading: isSending, // 发送中状态
isError: isSendError, // 发送错误
error: sendError // 发送错误信息
} = useWriteContract();
// 2. 监听交易确认状态(确保上链)
const {
isLoading: isConfirming, // 确认中状态
isSuccess: isTxSuccess // 交易成功状态
} = useWaitForTransactionReceipt({ hash: txHash });
// 触发转账:转 1 DAI
const handleTransfer = () => {
writeContract({
address: DAI_ADDRESS,
abi: erc20Abi,
functionName: 'transfer',
args: [
RECIPIENT, // 接收地址
parseEther('1.0') // 转账金额(1 DAI → wei)
]
});
};
return (
<div>
<button
onClick={handleTransfer}
disabled={isSending || isConfirming}
style={{ padding: '8px 16px' }}
>
{isSending && '发送中...'}
{isConfirming && '确认中...'}
{!isSending && !isConfirming && '转账 1 DAI'}
</button>
{isSendError && <div style={{ color: 'red' }}>发送失败: {sendError.message}</div>}
{isTxSuccess && txHash && (
<div style={{ color: 'green', marginTop: 8 }}>
转账成功!哈希: <a href={`https://etherscan.io/tx/${txHash}`} target="_blank">
{txHash.slice(0, 10)}...
</a>
</div>
)}
</div>
);
}
useWatchContractEvent
(替代 useContractEvent
)实时监听合约指定事件(如 Transfer
、Approval
),触发自定义逻辑。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
address |
Address |
合约地址 | 是 |
abi |
Abi |
合约 ABI(包含目标事件) | 是 |
eventName |
string |
事件名(如Transfer 、Mint ) |
是 |
listener |
(...args) => void |
事件触发回调(参数与事件输出字段顺序匹配) | 是 |
enabled |
boolean |
是否启用监听(默认true ,false 暂停) |
否 |
chainId |
number |
目标链 ID(可选) | 否 |
import { useWatchContractEvent } from 'wagmi';
import { erc20Abi } from 'wagmi/abi';
import { useCallback, useState } from 'react';
const DAI_ADDRESS = '0x6B175474E89094C44Da98b954EedeAC495271d0F' as const;
function TransferMonitor() {
const [transfers, setTransfers] = useState<Array<{ from: string; to: string; value: string }>>([]);
// 用 useCallback 确保 listener 引用稳定,避免重复注册
const handleTransfer = useCallback((from: string, to: string, value: bigint) => {
const formattedValue = (Number(value) / 10 ** 18).toFixed(4);
setTransfers(prev => [{ from, to, value: formattedValue }, ...prev].slice(0, 10)); // 保留最新10条
}, []);
// 监听 Transfer 事件
useWatchContractEvent({
address: DAI_ADDRESS,
abi: erc20Abi,
eventName: 'Transfer',
listener: handleTransfer,
});
return (
<div>
<h3>最新 DAI 转账(10条)</h3>
{transfers.length === 0 ? (
<p>暂无转账记录</p>
) : (
<ul>
{transfers.map((tx, idx) => (
<li key={idx}>
{tx.from.slice(0, 6)}... → {tx.to.slice(0, 6)}... | {tx.value} DAI
</li>
))}
</ul>
)}
</div>
);
}
Hook 名称 | 功能描述 | 核心参数/使用场景 |
---|---|---|
useDeployContract |
部署智能合约 | abi 、bytecode 、args ;如部署 ERC20 合约 |
useReadContracts |
批量调用多个合约只读方法 | contracts 数组;一次查多代币余额 |
useInfiniteReadContracts |
无限滚动加载多合约数据 | queryFn 、getNextPageParam ;分页查 NFT 所有者 |
useSimulateContract |
模拟合约调用(不发送交易,验证可行性) | address 、abi 、functionName ;检查转账是否可行 |
useBlock
获取指定区块的详细信息(哈希、时间戳、交易列表)。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
blockNumber |
bigint |
区块号(如17829139n ) |
二选一 |
blockTag |
'latest' |'pending' |
区块标签(替代区块号) | 二选一 |
import { useBlock } from 'wagmi';
function BlockDetails() {
const { data: block, isLoading } = useBlock({
blockNumber: 17829139n, // 指定区块号
});
if (isLoading) return <div>加载区块信息中...</div>;
return (
<div>
<p>区块号: {block?.number.toString()}</p>
<p>哈希: {block?.hash}</p>
<p>时间戳: {new Date(Number(block?.timestamp) * 1000).toLocaleString()}</p>
<p>交易数: {block?.transactions.length}</p>
</div>
);
}
useBlockNumber
获取当前最新区块号,支持实时监听。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
watch |
boolean |
是否实时监听(默认false ) |
否 |
chainId |
number |
目标链 ID(可选) | 否 |
import { useBlockNumber } from 'wagmi';
function LatestBlock() {
const { data: blockNumber, isLoading } = useBlockNumber({ watch: true });
if (isLoading) return <div>加载中...</div>;
return <div>当前区块号: {blockNumber?.toString()}</div>;
}
useSendTransaction
发送原生代币(如 ETH)转账交易。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
to |
Address |
接收地址 | 是 |
value |
bigint |
转账金额(wei 单位,用parseEther 转换) |
是 |
chainId |
number |
目标链 ID(可选) | 否 |
import { useSendTransaction, useWaitForTransactionReceipt } from 'wagmi';
import { parseEther } from 'viem';
function SendEth() {
const {
sendTransaction,
data: txHash,
isLoading: isSending
} = useSendTransaction();
const { isSuccess: isTxSuccess } = useWaitForTransactionReceipt({ hash: txHash });
const handleSend = () => {
sendTransaction({
to: '0xBbBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as const,
value: parseEther('0.01') // 0.01 ETH → wei
});
};
return (
<div>
<button onClick={handleSend} disabled={isSending}>
{isSending ? '发送中...' : '发送 0.01 ETH'}
</button>
{isTxSuccess && txHash && <div>发送成功!哈希: {txHash.slice(0, 10)}...</div>}
</div>
);
}
Hook 名称 | 功能描述 | 核心参数/使用场景 |
---|---|---|
useBlockTransactionCount |
获取指定区块的交易数量 | blockNumber /blockHash ;分析区块活跃度 |
useTransactionConfirmations |
获取交易确认次数 | hash ;判断交易是否足够确认(如 6 次) |
useTransactionCount |
获取账户 nonce(交易次数) | address ;手动管理交易顺序 |
useWatchBlocks |
监听新区块产生 | onBlock ;实时跟踪区块 |
useWatchPendingTransactions |
监听待处理交易 | onTransactions ;监控未确认交易 |
useEnsAddress
将 ENS 名称解析为以太坊地址(如 vitalik.eth
→ 地址)。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
name |
string |
ENS 名称(如'vitalik.eth' ) |
是 |
chainId |
number |
链 ID(默认主网 1) | 否 |
import { useEnsAddress } from 'wagmi';
function EnsToAddress() {
const { data: address, isLoading, isError } = useEnsAddress({
name: 'vitalik.eth',
});
if (isLoading) return <div>解析中...</div>;
if (isError) return <div>解析失败</div>;
return <div>vitalik.eth → {address || '未找到地址'}</div>;
}
useEnsName
通过地址反向查询 ENS 名称(如地址 → vitalik.eth
)。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
address |
Address |
以太坊地址 | 是 |
chainId |
number |
链 ID(默认主网 1) | 否 |
import { useEnsName } from 'wagmi';
function AddressToEns() {
const { data: ensName, isLoading } = useEnsName({
address: '0xd8dA6BF26964aF9D7eEd9e03E53415D37AA96045' as const, // Vitalik 地址
});
if (isLoading) return <div>查询中...</div>;
return <div>地址 → {ensName || '未设置 ENS'}</div>;
}
Hook 名称 | 功能描述 | 核心参数/使用场景 |
---|---|---|
useEnsAvatar |
获取 ENS 头像 URL | name ;用户资料页显示头像 |
useEnsResolver |
获取 ENS 解析器地址 | name ;高级 ENS 操作(如自定义文本记录) |
useEnsText |
读取 ENS 文本记录(如推特、网站) | name 、key (如'com.twitter' );展示社交链接 |
useEstimateFeesPerGas
估算当前 EIP-1559 交易的 Gas 费用(maxFeePerGas
和 maxPriorityFeePerGas
)。
无。
import { useEstimateFeesPerGas } from 'wagmi';
import { formatGwei } from 'viem'; // 转换为 Gwei 单位
function GasFees() {
const { data: fees, isLoading } = useEstimateFeesPerGas();
if (isLoading || !fees) return <div>估算中...</div>;
return (
<div>
<p>Max Fee: {formatGwei(fees.maxFeePerGas)} Gwei</p>
<p>Max Priority Fee: {formatGwei(fees.maxPriorityFeePerGas)} Gwei</p>
</div>
);
}
useEstimateGas
估算交易所需 Gas 量(单位:gas)。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
to |
Address |
接收地址 | 是 |
value |
bigint |
转账金额(可选,合约调用时可不填) | 否 |
data |
Hex |
交易数据(合约调用时必填) | 否 |
import { useEstimateGas } from 'wagmi';
import { parseEther } from 'viem';
function EstimateTxGas() {
const { data: gas, isLoading } = useEstimateGas({
to: '0xBbBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as const,
value: parseEther('1.0'), // 转账 1 ETH
});
if (isLoading) return <div>估算中...</div>;
return <div>预估 Gas 量: {gas?.toString()} gas</div>;
}
Hook 名称 | 功能描述 | 核心参数/使用场景 |
---|---|---|
useEstimateMaxPriorityFeePerGas |
单独估算优先 Gas 费(maxPriorityFeePerGas ) |
无;优化交易确认速度(高优先级转账) |
useFeeHistory |
获取历史 Gas 费用数据 | blockCount 、rewardPercentiles ;绘制 Gas 趋势图 |
useGasPrice |
获取传统交易(非 EIP-1559)的 Gas 价格 | 无;Legacy 交易估算费用 |
useBalance
获取指定地址的原生代币或 ERC20 代币余额(简化版,无需手动写 ABI)。
参数名 | 类型 | 说明 | 是否必填 |
---|---|---|---|
address |
Address |
目标地址 | 是 |
token |
Address |
ERC20 代币地址(可选,默认查原生代币) | 否 |
watch |
boolean |
是否实时监听(默认false ) |
否 |
import { useBalance } from 'wagmi';
function UserBalance() {
const { data: ethBalance } = useBalance({
address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e' as const,
watch: true, // 实时更新 ETH 余额
});
const { data: daiBalance } = useBalance({
address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e' as const,
token: '0x6B175474E89094C44Da98b954EedeAC495271d0F' as const, // DAI 地址
watch: true,
});
return (
<div>
<p>ETH 余额: {ethBalance?.formatted} {ethBalance?.symbol}</p>
<p>DAI 余额: {daiBalance?.formatted} {daiBalance?.symbol}</p>
</div>
);
}
useChainId
获取当前连接的链 ID。
无。
import { useChainId } from 'wagmi';
function NetworkIndicator() {
const chainId = useChainId();
const chainMap = {
1: '以太坊主网',
11155111: 'Sepolia 测试网',
137: 'Polygon 主网',
};
const chainName = chainMap[chainId] || '未知网络';
return <div>当前网络: {chainName} (ID: {chainId})</div>;
}
Hook 名称 | 功能描述 | 核心参数/使用场景 |
---|---|---|
useChains |
获取所有配置的支持链信息 | 无;生成网络切换下拉菜单 |
useClient |
获取 Wagmi 客户端实例 | 无;直接调用客户端方法(如sendTransaction ) |
useConfig |
获取 Wagmi 配置实例(链、连接器等) | 无;自定义 Hook 中复用配置 |
usePublicClient |
获取公共客户端(读取链上数据) | chainId ;直接调用 viem 方法(如getBlock ) |
useWalletClient |
获取钱包客户端(发送交易、签名) | 无;钱包专属交互 |
useWatchAsset |
请求钱包添加代币(如 MetaMask 添加代币) | address 、symbol 、decimals ;引导用户添加代币 |
注意:实验性 API 可能不稳定,文档不完善,需谨慎使用。
Hook 名称 | 功能描述 | 核心参数/使用场景 |
---|---|---|
useCapabilities |
检测钱包支持的高级功能(如批量交易) | 无;根据钱包能力调整 DApp 功能(如显示/隐藏批量按钮) |
useCallsStatus |
获取批量交易状态 | id (批次 ID);监控 useSendCalls 交易状态 |
useSendCalls |
批量发送交易 | calls (交易数组);一次发多笔转账 |
useSendCallsSync |
同步发送批量交易(等待所有完成) | 同 useSendCalls ;需等待所有交易确认 |
useShowCallsStatus |
显示批量交易状态(进度/结果) | id ;展示批量交易 UI |
useWaitForCallsStatus |
等待批量交易完成 | id ;批量交易后的异步处理 |
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!