wagmi React Hooks 版本演进全解析:从 0.x 到 3.7 的核心 API 变化与迁移要点
【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi
wagmi 是面向以太坊应用的 React Hooks 集合(packages/react,包名为wagmi,npm 描述为 "React Hooks for Ethereum"),它把钱包连接、链上数据读取、交易发送、签名等能力封装成声明式的 Hook,同时以 @wagmi/core 为底层状态与动作核心。本文以 packages/react/CHANGELOG.md(记录了自 0.0.2 至 3.7.6 的全部版本变更)为骨架,结合 package.json、exports 入口、Provider 与 Hydrate 实现 等源码,梳理 wagmi React 包从早期试探到 v2 重构、再到 v3 Tempo 原生集成的完整演进路径。读完本文,你将理解每个大版本"为什么变"、关键 Hook 与配置参数的来源与去向,以及升级时最容易踩到的破坏性变更点。
一、包定位与工程形态:一个"薄壳 + 核心"的 React 适配层
在进入版本史之前,先看当前仓库中wagmi包的物理结构。它不是一个自包含库,而是建立在@wagmi/core之上的 React 适配层:
- 依赖:
@wagmi/connectors、@wagmi/core(均以workspace:*指向仓库内同名单包)、use-sync-external-store@1.4.0(用于在 React 18+ 中安全订阅外部 store); - 对等依赖:
@tanstack/react-query >=5.0.0、react >=18、viem 2.x,以及可选的typescript >=5.9.3(见 packages/react/package.json)。也就是说,查询缓存层交给 TanStack Query,链的客户端与 ABI 类型系统交给 viem,wagmi 自身只负责"把 core 的动作变成 Hook"。
exports字段声明了多个子路径入口(./actions、./chains、./codegen、./connectors、./query、./tempo),这直接对应 CHANGELOG 中两个标志性变化:3.6.19 为连接器(connector)增加独立子路径导出以适配 Turbopack 解析,以及3.2.0 引入一等公民的/tempo入口。./tempo在typesVersions中同样有对应映射,说明它是从类型到运行时的完整导出面。
入口文件 packages/react/src/exports/index.ts 集中 re-export 了三大块:
- Context:
WagmiContext、WagmiProvider; - Hooks:从
useBalance、useReadContract、useWriteContract、useSendTransaction到useSignTransaction、useContractEvents、useBlobBaseFee等近百个 Hook,每个都同时导出UseXxxParameters/UseXxxReturnType类型; - @wagmi/core 全量透传:
createConfig、createConnector、createStorage、cookieToInitialState、http/webSocket/custom/fallback等传输层工具,以及Connection、Connector、State、Storage等核心类型。
该文件还保留了 v2 时代的命名痕迹:useAccount与useAccountEffect被标注@deprecated,推荐使用useConnection/useConnectionEffect;useSwitchAccount亦被useSwitchConnection取代。这与 CHANGELOG 中 v3 对连接(Connection)概念的收敛是一致的。
Provider 的实现(packages/react/src/context.ts)也很简洁:WagmiProviderProps仅含config、initialState?、reconnectOnMount?三个字段,内部把config通过WagmiContext.Provider注入,并外包一层 Hydrate。Hydrate 会调用@wagmi/core的hydrate(config, { initialState, reconnectOnMount }),并且按 SSR 与否区分挂载时机:非 SSR 时同步onMount(),SSR 时放入useEffect异步执行——这正是 CHANGELOG 中反复出现的 "SSR hydration" 相关修复(如 2.5.11 "Fixed SSR hydration issues"、2.1.1 "SSR cookie support")在源码层面的落点。
二、3.x 时代:稳定化、连接器解耦与 Tempo 原生集成
2.1 v3.0.0:连接器依赖全部改为可选 peer dependency
3.0.0 是一个影响安装方式的重大变更(Major Changes):所有连接器依赖从硬依赖变为可选 peer 依赖——"if you want to use a specific connector, you need to install its required dependencies"。CHANGELOG 给出了每个连接器需要手工安装的清单:
| 连接器 | 需安装的依赖(CHANGELOG 记录的建议版本) |
|---|---|
baseAccount | @base-org/account@~2.4.0 |
coinbaseWallet | @coinbase/wallet-sdk@~4.3.6 |
gemini | @gemini-wallet/core@~0.3.1 |
metaMask | @metamask/sdk@~0.33.1 |
porto | porto@~0.2.35 |
safe | @safe-global/safe-apps-provider@~0.18.6与@safe-global/safe-apps-sdk@~9.1.0 |
walletConnect | @walletconnect/ethereum-provider@~2.21.1 |
这一设计的意义在于:应用不再为未使用的钱包 SDK 支付 bundle 成本,也降低了 SDK 版本冲突的可能。作为配套,3.6.19 又"Added connector-specific subpath exports and marked optional connector dependency imports as optional for Turbopack resolution",即用条件导入让打包器(尤其 Turbopack)在未安装对应 SDK 时也能正常解析。
注意:上表中的版本号来自 CHANGELOG 撰写当时的建议,实际安装时应以连接器当前要求的版本为准(如 3.6.0 中 MetaMask 连接器已从
@metamask/sdk迁移到@metamask/connect-evm,见下文)。
2.2 v3.1.0:统一mutate/mutateAsync,终结解构改名疲劳
3.1.0 是对开发体验的一次重要修订:废弃各 Hook 的自定义 mutate 函数名,统一为mutate/mutateAsync,与 TanStack Query 术语对齐。CHANGELOG 给出了动机与前后对比:
- 之前:同时使用多个同款 Hook 时不得不反复重命名解构键,例如
useWriteContract()解构出writeContract后再手动改名transfer/approve,还要处理connect.connect这类别扭的嵌套调用; - 之后:直接给 Hook 返回值命名即可,属性名无需二次改名:
// 之前 const { writeContract: transfer, error: transferError, isPending: transferIsPending } = useWriteContract() const { writeContract: approve, error: approveError } = useWriteContract() // 之后 const transfer = useWriteContract() // transfer.mutate, transfer.error, transfer.isPending const approve = useWriteContract() // approve.mutate, approve.error2.3 v3.2 ~ v3.3:Tempo 一等支持与 viem 2.44.0 Moderato
- 3.2.0:通过
/tempo入口为 Tempo 提供"first-class support and extension",这是 wagmi 走向"非纯 EVM"的重要一步; - 3.3.0:升级到
viem@2.44.0并支持Tempo Moderato,伴随一批 Tempo Hook 的破坏性重命名:reward.useStart→reward.useDistribute、reward.useStartSync→reward.useDistributeSync、reward.useGetTotalPerSecond→reward.useGetGlobalRewardPerToken、reward.useWatchRewardScheduled→reward.useWatchRewardDistributed;同时移除nonce.useNonceKeyCount、nonce.useWatchActiveKeyCountChanged、amm.useWatchFeeSwap,新增dex.useCancelStale与dex.useCancelStaleSync。
同一时期 3.4.4 修复了 "wagmi/tempo hooks were not propagatingUseQueryOptions" 的问题,表明 Tempo Hook 同样基于 TanStack Query 构建,参数透传需要与普通 Hook 保持一致。
2.4 v3.4 ~ v3.6:新 Hook 井喷与连接器换血
3.x 中段是 Hook 生态快速扩张的阶段,CHANGELOG 记录的 Minor 级新增包括:
- 3.4.0:新增
useContractEvents、useBlobBaseFee、useWriteContractSync;并修复useWatchBlockNumber、useWatchBlocks、useWatchContractEvent、useWatchPendingTransactions每次渲染都重新订阅的问题; - 3.5.0:新增
useSignTransaction(在交易发送前对交易结构签名); - 3.6.0:MetaMask 连接器底层从
@metamask/sdk切换到全新的@metamask/connect-evm,升级命令为:
npm install @metamask/connect-evm npm uninstall @metamask/sdk- 3.6.1:修复 Tempo 链上
useSendTransaction/useSendTransactionSync/useWriteContract/useWriteContractSync的feePayer类型;修复createUseReadContract在多个 view 函数共享同一参数形状时的返回类型推断; - 3.6.2:新增
tempoWallet连接器(对应@wagmi/connectors8.0.2); - 3.6.3:新增Tempo Zones支持;
- 3.6.10:为
viem/tempo#wallet动作补齐 Actions 与 Hooks; - 3.6.13:
useReadContracts优先采用显式传入的chainId,而非推断或已连接链的 chain id; - 3.6.15:
cookieToInitialState处理畸形 cookie 状态不再崩溃。
2.5 v3.7:Tempo API 收敛与Amount对象
v3.7 主要是 Tempo 侧 API 的收口,也是本文中"当前最新"的一批变更:
- 3.7.0:Tempo 的 token 余额与授权读取开始返回
Amount对象(配合 viem 2.54.0 的 API 变化); - 3.7.2:修复 Tempo Zone Hook 与 Viem 2.55.2 的兼容性;
- 3.7.4:移除
Hooks.zone.useDepositStatus,以对齐当前 Tempo Zone API——需要等待区块导入时用Hooks.zone.useWaitForTempoBlock,需要一次性读取时用Hooks.zone.useZoneInfo并检查tempoBlockNumber字段; - 3.7.5 / 3.7.6:跟随
@wagmi/connectors8.0.26 / 8.1.0 的常规升级。
在 3.6.15 中还有一次值得关注的 Tempo 命名统一:Actions.wallet.send更名为Actions.wallet.transfer,Hooks.wallet.useSend更名为Hooks.wallet.useTransfer,参数从value改为amount:
- await Actions.wallet.send(config, { - to: '0x...', - token: '0x...', - value: '1.5', - }) + await Actions.wallet.transfer(config, { + amount: '1.5', + to: '0x...', + token: '0x...', + }) - const send = Hooks.wallet.useSend() + const transfer = Hooks.wallet.useTransfer()这组"重命名式破坏变更"贯穿 Tempo 演进始终,升级 Tempo 相关代码时务必以最新 CHANGELOG 为准做全局搜索替换。
三、2.x 时代:Wagmi 2.0 的架构级重构
2.0.0是 CHANGELOG 中仅次于 3.0.0 的里程碑,官方列出的特性清单为:
- 完整 TanStack Query 支持 +
queryKeys; - 支持同时连接多个连接器(connect multiple connectors);
- 未连接时也能切换链(switch chains while disconnected);
- 启用 EIP-6963(多钱包注入发现标准);
- 强类型的
chainId与链属性; - 更小的 bundle 体积。
迁移指南见仓库内 site/react/guides/migrate-from-v1-to-v2.md。2.x 阶段还沉淀了大量今天仍在使用的 Hook 与配置:
- 2.1.0新增
useCall; - 2.2.0新增
useBytecode、useStorageAt、useProof、useTransactionReceipt; - 2.3.0新增
useEnsText,并"Modified persist strategy to only store critical properties that are needed before hydration"(只为水合前所需的关键属性做持久化); - 2.4.0新增
usePrepareTransactionRequest; - 2.5.0新增
useTransactionConfirmations; - 2.8.0引入实验性 EIP-5792 Actions & Hooks(
sendCalls系列),2.15.0 将其稳定化; - 2.10.0新增
useDeployContract; - 2.11.0新增
useWatchAsset;2.12.10 修复useReadContract的"未部署合约读取"(deployless reads)支持; - 2.12.15稳定化
useAccount返回值对象引用(减少不必要的重渲染); - 2.14.0支持
useConnect传入自定义connector.connect参数; - 2.16.0新增
baseAccount连接器;2.17.0为connect增加withCapabilities选项以暴露响应能力; - 2.18.0新增
useSendTransactionSync与useSendCallsSync(同步式发送,便于在事件回调中直接调用); - 2.19.4优化
useReadContracts内部chainId计算以减少无谓的 query 失效。
值得单独一提的是 2.12.0:"Added functionality for consumer-defined RPC URLs (config.transports) to be propagated to the WalletConnect & MetaMask Connectors"——即用户在createConfig里自定义的 transports 会被下发给 WalletConnect 与 MetaMask 连接器,这是 RPC 配置"单一来源"原则的落地。
四、1.x 与 0.x 时代:从createClient到createConfig的奠基史
4.1 0.x:早期 Hook 与configureChains的出现
0.x 阶段完成了 wagmi 最基本 Hook 形态的定型,其中几处关键变更至今仍影响 API 设计:
- 0.4.0引入
configureChains(chains, providers, config?),把"为每个链推导 RPC URL、实例化 Provider"的工作集中收口,替代了此前在createClient里手工connectors({ chainId })拼接 RPC 的做法; - 0.5.0将
useContractWrite/useContractEvent/useContractRead的参数合并为单一 config 对象(此前为(config, functionName, args?)多参数形式); - 0.5.0重构
useAccount:返回值改为顶层address/connector+ 全局连接状态(isConnecting/isReconnecting/isConnected/isDisconnected与status),并新增onConnect/onDisconnect回调,同时删除其异步查询相关的isLoading、refetch等字段;切换链能力被拆到新的useSwitchNetwork; - 0.7.0强化 ABI 类型推断:对
abi使用as const断言后,functionName、args、返回值可端到端自动推断(要求 TypeScript >= 4.7.4,利用了 TS 4.7 的 extends 约束推断特性); - 0.8.0移除
ropsten、rinkeby、kovan、optimismKovan、arbitrumRinkeby等废弃测试链,并移除 CommonJS 支持; - 0.9.0将链相关导出(
chain、allChains、defaultChains、chainId、etherscanBlockExplorers等)从主入口剥离到wagmi/chains子路径,Chain类型的rpcUrls改为{ http: string[]; webSocket: string[] }结构,multicall/ens移入contracts.multicall3/contracts.ensRegistry; - 0.10.0:
useSigner在无 signer 时返回undefined(而非null);WalletConnectConnector 开始支持 v2(需在 WalletConnect Cloud 申请projectId); - 0.12.0:WalletConnect 默认使用 v2,v1 拆分为独立的
WalletConnectLegacyConnector,并移除了version配置项。
4.2 1.x:createConfig与WagmiProvider的正式化
1.0.0-next.2发生了两处影响至今的命名定型:
createClient重命名为createConfig;useClient重命名为useConfig。
1.0.0正式发布 v1(对应@wagmi/core@1.0.0)。1.x 期间的 1.4.12 记录了一次安全相关的移除:"Removed LedgerConnector due to security vulnerability",可见 CHANGELOG 也承载了安全事件的追踪。1.x 末尾的2.0.0即前述架构级重构,而 v2 → v3 的迁移说明见 site/react/guides/migrate-from-v2-to-v3.md。
4.3 由 CHANGELOG 可以确认的 Hook 全貌
将 CHANGELOG 的 Minor 变更与 hooks 目录 对照,可以确认当前wagmi包提供的 Hook 能力版图,大致分为五类:
- 连接与账户:
useConnect/useDisconnect/useReconnect/useConnection(原useAccount)/useConnections/useConnectors/useSwitchConnection(原useSwitchAccount)/useConnectionEffect/useConnectorClient/useWalletClient; - 链与客户端:
useChainId/useChains/useClient/useConfig/usePublicClient/useSwitchChain; - 合约读写与事件:
useReadContract/useReadContracts/useInfiniteReadContracts/useWriteContract/useWriteContractSync/useSimulateContract/useContractEvents/useWatchContractEvent/useDeployContract; - 交易与签名:
useSendTransaction/useSendTransactionSync/usePrepareTransactionRequest/useWaitForTransactionReceipt/useTransaction/useTransactionReceipt/useTransactionConfirmations/useTransactionCount/useSignMessage/useSignTypedData/useSignTransaction/useVerifyMessage/useVerifyTypedData;EIP-5792 系列:useSendCalls/useSendCallsSync/useCallsStatus/useShowCallsStatus/useWaitForCallsStatus/useCapabilities; - 链上数据与订阅:
useBalance/useBlock/useBlockNumber/useBlockTransactionCount/useFeeHistory/useGasPrice/useEstimateFeesPerGas/useEstimateMaxPriorityFeePerGas/useEstimateGas/useBytecode/useStorageAt/useProof/useCall/useWatchBlocks/useWatchBlockNumber/useWatchPendingTransactions/useWatchAsset,以及 ENS 一族useEnsAddress/useEnsAvatar/useEnsName/useEnsResolver/useEnsText。
以上清单为"当前仓库 hooks 目录 + CHANGELOG 曾记录的新增"的并集,具体导入方式(主入口 vs 子路径)以 exports/index.ts 为准。
五、源码印证:CHANGELOG 关键条目在仓库中的落点
为便于读者进一步核对,下面把本文提到的几条重要结论映射到具体源码文件:
| CHANGELOG 条目 | 仓库中的印证 |
|---|---|
| 3.6.19 连接器子路径导出 / Turbopack 适配 | package.json 的exports与typesVersions中的./connectors等映射 |
| 3.2.0 Tempo 一等支持 | package.json 的./tempo入口;packages/react/src/tempo/目录 |
3.6.2tempoWallet连接器 | packages/connectors/src/tempoWallet.ts(连接器实现) |
v2 时代useAccount别名保留 | exports/index.ts 中useAccount的@deprecated标注 |
| WagmiProvider 与 SSR 水合行为 | context.ts + hydrate.ts |
| 全量 Hook 与类型导出 | exports/index.ts 中每个useXxx的Parameters/ReturnType导出 |
| peer 依赖边界(TanStack Query / viem / React 版本) | package.json 的peerDependencies |
六、升级与迁移要点小结
综合整份 CHANGELOG,可以将升级到当前版本(3.7.x)时最需要关注的破坏性变更归纳为以下几点:
- 依赖安装方式已变(3.0.0):连接器所需 SDK 一律手工安装;使用 MetaMask 连接器还需从
@metamask/sdk切换到@metamask/connect-evm(3.6.0); - 命名统一(3.1.0):所有 mutate 型 Hook 统一使用
mutate/mutateAsync,不要再依赖writeContract、sendTransaction等旧键名; - 连接概念(v3):
useAccount→useConnection、useSwitchAccount→useSwitchConnection,旧名仍可用但已废弃; - Tempo 专属变更密集(3.2 ~ 3.7):Reward/Dex/Wallet/Zone 相关 Hook 经历过多次重命名、移除与返回类型升级(如
Amount对象),升级时需逐条对照 CHANGELOG 的 diff 示例; - v1 → v2 → v3 的迁移指南分别维护在 site/react/guides/migrate-from-v1-to-v2.md 与 site/react/guides/migrate-from-v2-to-v3.md,跨大版本升级时优先阅读这两份文档。
总体来看,wagmi React 包的演进脉络非常清晰:0.x 完成 Hook 形态与链配置的奠基,1.x 定型createConfig/WagmiProvider心智模型,2.x 以 TanStack Query 与 EIP-6963 完成架构重构,3.x 在稳定化的同时向 Tempo 等新执行环境纵深扩展。对使用者而言,CHANGELOG 本身既是"发生了什么"的记录,也是"升级要改什么"的操作手册;结合 packages/react 下的源码阅读,可以更准确地理解每个 Hook 背后的参数透传与状态管理机制。
【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考