Wagmi Core 与 Viem 集成实战:Actions、多链 Client 与本地账户的完整指南
发布时间:2026/9/17 14:36:32来源:尧图网络
Wagmi Core 与 Viem 集成实战Actions、多链 Client 与本地账户的完整指南【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmiWagmi Core 本质上是对 Viem 的一层封装它通过 createConfig 提供多链能力通过 Connectors 提供自动化的账户管理而底层所有链上交互都落在 Viem 之上。本篇指南以 Wagmi 官方文档 site/core/guides/viem.md 为骨架结合仓库源码系统讲解如何直接调用 Viem Actions、如何用 Wagmi 构造多链 Viem Client、以及如何在 Wagmi 中搭配 Viem 的私钥/助记词本地账户读完即可在真实项目中灵活组合两者。Viem 与 Wagmi Core 的关系Viem 是一个面向以太坊的低层级 TypeScript 接口库提供 JSON-RPC API 抽象、智能合约交互、钱包与签名实现、编码/解析工具等能力。Wagmi Core 本质上是 Viem 之上的一个封装层核心职责有两个多链支持通过 Wagmi Config即createConfig管理一组链与对应的 transports自动账户管理通过 Connectors 管理钱包连接、账户切换与断开。也就是说Wagmi 把单链、需要手动管理 provider的 Viem 使用方式升级为多链、连接器感知的开发体验但当你需要更底层的能力时Viem 始终唾手可得。直接调用 Viem Actions 的两种方式Wagmi 提供的全部 Core Actions 都是对 Viem Actions 的友好封装——它们会注入一个多链且连接器感知的 Wagmi Config。但在某些场景下你可能希望绕过封装直接使用 Viem Actions例如某个 Viem 已有、而 Wagmi 尚未封装的新 Action。此时可以直接从viem/actions导入 Viem Actions并将由getClientAction 返回的 Viem Client 作为参数传入。官方给出了两种用法Tree-shakable Actions推荐公共类操作使用getClient钱包类操作使用getConnectorClientClient Actions公共类操作使用getPublicClient钱包类操作使用getWalletClient。提示强烈建议使用 tree-shakable 方式确保只打包你用到的模块控制最终 bundle 体积。Tree-shakable Actions 示例// 1. Import modules. import { http, createConfig, getClient, getConnectorClient } from wagmi/core import { base, mainnet, optimism, zora } from wagmi/core/chains import { getLogs, watchAsset } from viem/actions // 2. Set up a Wagmi Config export const config createConfig({ chains: [base, mainnet, optimism, zora], transports: { [base.id]: http(), [mainnet.id]: http(), [optimism.id]: http(), [zora.id]: http(), }, }) // 3. Extract a Viem Client for the current active chain. const publicClient getClient(config) const logs await getLogs(publicClient, /* ... */) // 4. Extract a Viem Client for the current active chain account. const walletClient getConnectorClient(config) const success await watchAsset(walletClient, /* ... */)Client Actions 示例// 1. Import modules. import { http, createConfig, getPublicClient, getWalletClient } from wagmi/core import { base, mainnet, optimism, zora } from wagmi/core/chains // 2. Set up a Wagmi Config export const config createConfig({ chains: [base, mainnet, optimism, zora], transports: { [base.id]: http(), [mainnet.id]: http(), [optimism.id]: http(), [zora.id]: http(), }, }) // 3. Extract a Viem Public Client for the current active chain. const publicClient getPublicClient(config) const logs await publicClient.getLogs(publicClient, /* ... */) // 4. Extract a Viem Wallet Client for the current active chain account. const walletClient getWalletClient(config) const success await walletClient.watchAsset(walletClient, /* ... */)源码级原理四个 Client 获取 Action 的关系从源码结构看这组 API 有清晰的继承关系全部位于 packages/core/src/actions/getClient核心入口直接调用config.getClient(parameters)并用try/catch包裹——当请求的chainId未被配置时如链 ID123456不存在于 config.chains会静默返回undefined而不是抛错。这一行为在 getClient.test.ts 中有对应测试behavior: unconfigured chain用例断言未配置链返回undefined。getPublicClient内部先调用getClient再通过client.extend(publicActions)挂载 Viem 的publicActions得到带完整公共读方法集的PublicClient。getConnectorClient从config.state.connections或显式传入的connector参数中取出当前连接校验链 ID 与账户后用连接器提供的 EIP-1193 provider 构造customtransport最终createClient出一个Connector Client。它还支持account: null允许未指定账户、由钱包内选择账户与assertChainId默认true链不匹配时抛ConnectorChainMismatchError等参数。getWalletClient内部先调用getConnectorClient再client.extend(walletActions)得到带签名、发交易等钱包方法集的WalletClient。而 Wagmi 自身 Action 的封装方式可以从sendTransaction看出端倪它根据account类型选择客户端——若传入的是type local的本地账户如私钥账户走config.getClient({ chainId })否则走getConnectorClient。随后通过getAction解析出最终的 Viem Action优先使用 client 上可能被覆写的方法否则回退到 tree-shakable 的viem_sendTransaction函数。这正是Wagmi Action 多链配置 连接器账户 Viem Action这一架构的微观体现。多链 Viem Client用 Wagmi 消除样板代码Viem Client 提供与 JSON-RPC Provider 交互的接口。由于 JSON-RPC Provider 天生是单链的Viem Client 在实例化时必须指定单一chain这导致用纯 Viem 搭建多链环境会相当冗长。好消息是通过createConfig加getClient你可以用 Wagmi 直接得到一个**多链 Viem Client**。Wagmi 方式推荐// 1. Import modules. import { http, createConfig, getClient, getConnectorClient } from wagmi/core import { base, mainnet, optimism, zora } from wagmi/core/chains import { getBlockNumber, sendTransaction } from viem/actions // 2. Set up a Wagmi Config export const config createConfig({ chains: [base, mainnet, optimism, zora], transports: { [base.id]: http(), [mainnet.id]: http(), [optimism.id]: http(), [zora.id]: http(), }, }) // 3. Extract a Viem Client for the current active chain. const publicClient getClient(config) const blockNumber await getBlockNumber(publicClient) // 4. Extract a Viem Client for the current active chain account. const walletClient getConnectorClient(config) const hash await sendTransaction(walletClient, /* ... */)纯 Viem 方式仅作对比请勿照做// Manually set up Viem Clients without wagmi. Dont do this, its only here // to demonstrate the amount of boilerplate required. import { createPublicClient, createWalletClient, http } from viem import { base, mainnet, optimism, zora } from viem/chains const publicClient { base: createPublicClient({ chain: base, transport: http() }), mainnet: createPublicClient({ chain: mainnet, transport: http() }), optimism: createPublicClient({ chain: optimism, transport: http() }), zora: createPublicClient({ chain: zora, transport: http() }) } as const const walletClient { base: createWalletClient({ chain: base, transport: custom(window.ethereum) }), mainnet: createWalletClient({ chain: mainnet, transport: custom(window.ethereum) }), optimism: createWalletClient({ chain: optimism, transport: custom(window.ethereum) }), zora: createWalletClient({ chain: zora, transport: custom(window.ethereum) }) } as const const blockNumber await publicClient.mainnet.getBlockNumber() const hash await walletClient.mainnet.sendTransaction(/* ... */)对比可见纯 Viem 需要为每条链手动创建 Public/Wallet Client还要各自指定window.ethereum与链配置而 Wagmi 只需一份createConfiggetClient/getConnectorClient会基于 config 中当前激活的链自动返回对应 Client链切换如用户在钱包中切换网络时无需重写任何代码。从实现细节看这一多链感知来自Config内部的getClient方法见 packages/core/src/createConfig.ts#L587-L589它接收可选的chainId参数从chains中匹配对应的链与transports返回Clienttransports[chainId], Extractchains[number], { id: chainId }类型。也就是说当前链默认取自连接器/配置状态也可以显式指定chainId覆盖这正是多链 Client 的底层支撑。在 Wagmi 中使用私钥与助记词账户你还可以将 Viem 的 Private Key Mnemonic Accounts 与 Wagmi 搭配使用只需在 Wagmi Action 上显式传入account参数即可。import { http, createConfig, sendTransaction } from wagmi/core import { base, mainnet, optimism, zora } from wagmi/core/chains import { parseEther } from viem import { privateKeyToAccount } from viem/accounts export const config createConfig({ chains: [base, mainnet, optimism, zora], transports: { [base.id]: http(), [mainnet.id]: http(), [optimism.id]: http(), [zora.id]: http(), }, }) const account privateKeyToAccount(0x...) const hash await sendTransaction({ account, to: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC, value: parseEther(0.001) })这段代码的后端路径同样可以落到源码在 packages/core/src/actions/sendTransaction.ts#L67-L78 中当传入的account是type local的本地账户privateKeyToAccount创建的对象即满足该特征时Wagmi 会直接使用config.getClient({ chainId })得到的公共 Client 发起交易而不经过连接器——因为本地账户自带签名能力无需依赖浏览器钱包。注意Wagmi 目前不支持将 Private Key Mnemonic Accounts 提升到顶层 Wagmi Config——也就是说你必须在每个 Action 上显式传入account。如果你认为这应当作为一个特性加入可以在 Wagmi 的 GitHub Discussions 中发起讨论。结语与延伸阅读总结来说Wagmi Core 与 Viem 的分工非常清晰常规场景优先使用 Wagmi 封装的 Core Actions它们自动处理多链与连接器账户进阶场景从viem/actions导入 tree-shakable Action配合getClient/getConnectorClient直接驱动底层 Client多链场景用一份createConfig覆盖多条链通过getClient系列 Action 按需取用避免手写大量样板本地账户场景用 Viem 的privateKeyToAccount等工具创建本地账户在 Wagmi Action 中显式传入account。如需继续深入可查阅本仓库中的相关文档createConfig 详解、getClient Action、getPublicClient Action、getWalletClient Action 以及 Actions 总览源码层面可重点阅读 packages/core/src/actions/ 目录下的对应实现与测试文件它们共同构成了理解 Wagmi 底层运作的最佳入口。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网