Wagmi CLI 快速上手:从安装配置到 ABI 管理与 React Hooks 代码生成
2026/9/17 11:27:27 网站建设 项目流程

Wagmi CLI 快速上手:从安装配置到 ABI 管理与 React Hooks 代码生成

【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi

Wagmi CLI 是 wagmi 生态中用于管理以太坊合约 ABI 与生成代码的命令行工具,它可以自动从 Etherscan 等区块浏览器、Foundry/Hardhat 等项目解析 ABI,并为这些 ABI 生成类型安全的 React Hooks 等代码。本文以 site/cli/getting-started.md 为骨架,结合仓库内packages/cli的真实源码与测试,带你走完安装、初始化配置、添加合约与插件、运行代码生成、使用生成代码的完整流程,读完即可在自己的 wagmi 项目中落地 CLI 工作流。

Wagmi CLI 能做什么

Wagmi CLI 是一个专门面向以太坊开发者的命令行界面,其核心价值在于把大量重复劳动自动化:从区块浏览器(如 Etherscan)或本地区块链开发框架(如 Foundry、Hardhat)获取并管理 ABI,再基于这些 ABI 生成诸如 React Hooks 之类的类型安全代码。它的出发点与设计理念可参见仓库中的 Why Wagmi CLI 一节。

packages/cli/package.json可以看到,@wagmi/cli的定位是 “Manage and generate code from Ethereum ABIs”,当前版本为 2.10.0,通过bin.wagmi暴露wagmi命令(入口为dist/esm/cli.js),并以type: "module"的 ESM 形式发布。这意味着无论使用哪个包管理器,最终获得的能力都是同一套 CLI 命令与可编程 API。

安装 Wagmi CLI

Wagmi CLI 通常作为项目的开发依赖安装,因为它是构建期/开发期工具,生成的代码会提交或由构建流程产出。以下四种包管理器任选其一:

pnpm add -D @wagmi/cli
npm install --save-dev @wagmi/cli
yarn add -D @wagmi/cli
bun add -D @wagmi/cli

安装完成后,即可在项目中通过pnpm wagminpx wagmiyarn wagmibun wagmi调用 CLI。仓库中的packages/cli/package.jsontypescript声明为可选 peerDependency(>=5.9.3),即 TypeScript 不是强制依赖,但在生成 TypeScript 输出或使用.ts配置文件时推荐安装。

创建配置文件:wagmi init

CLI 的使用以配置文件为中心。运行init命令即可生成一份初始配置:

pnpm wagmi init
npx wagmi init
yarn wagmi init
bun wagmi init

init命令的行为在 init 命令源码 中有清晰体现,其决策逻辑值得展开:

  1. 检测已有配置:通过findConfig向上层目录查找配置文件。若已存在配置,命令会直接提示 “Config already exists at ..." 并退出,避免覆盖已有配置。
  2. 判断是否使用 TypeScript:调用getIsUsingTypeScript()(见 getIsUsingTypeScript.ts),其判定方式是向上查找tsconfig.jsontsconfig.base.jsontsconfig.lib.jsontsconfig.node.json,或查找wagmi.config.tswagmi.config.mts。只要命中其一即视为 TypeScript 项目。
  3. 决定文件名与内容:TypeScript 项目生成wagmi.config.ts,否则生成wagmi.config.js。你也可以用--config <path>显式指定配置文件名,此时init会按指定路径写入。
  4. 写入模板:TypeScript 版本使用import { defineConfig } from '@wagmi/cli'+export default defineConfig(...);JavaScript 版本则生成带// @ts-check@type {import('@wagmi/cli').Config}JSDoc 注解的 ESM 配置,文件写入前会经过 Prettier 格式化。

生成的配置文件内容大致如下:

import { defineConfig } from '@wagmi/cli' export default defineConfig({ out: 'src/generated.ts', contracts: [], plugins: [], })

注意initgenerate命令都支持-c, --config <path>-r, --root <path>两个选项(见 cli.ts 命令定义),前者指定配置文件路径,后者指定解析配置的根目录。

理解配置文件结构

init生成的空模板包含三个字段,它们正是 Config 类型定义 中的全部配置项:

配置项类型说明
outstring生成代码的输出文件路径,必填
contractsContractConfig[]直接声明的合约列表(名称、ABI、地址)
pluginsPlugin[]启用的插件列表(Etherscan、Foundry、React 等)

defineConfig是一个纯类型辅助函数,其签名接受单个配置对象、配置对象数组,或返回配置(数组)的函数。defaultConfig默认值为{ out: 'src/generated.ts', contracts: [], plugins: [] }

每个ContractConfig包含三个字段:

  • name:合约名称,用于生成标识符(如erc20会派生出erc20AbiuseReadErc20等)。
  • abi:合约 ABI。
  • address(可选):单个地址字符串,或多链地址对象{ [chainId]: address }。多链对象在生成代码时会附带地址文档注释,并额外导出${name}Address${name}Config常量。

如果使用 JavaScript 配置且想获得编辑器的类型提示,可以借助 JSDoc 或defineConfig,详见 Configuring CLI。配置还可以导出函数(支持条件配置与异步配置),例如按NODE_ENV返回不同配置,或通过loadEnv手动加载.env文件(CLI 默认不自动加载.env,因为需要先求值配置才能确定加载哪些文件)。

关于配置文件的查找,findConfig.ts 给出了明确的优先级顺序:wagmi.config.tswagmi.config.jswagmi.config.mjswagmi.config.mts,并使用escalade从当前目录向父目录逐层搜索。

添加合约与插件

配置就绪后,就可以向contractsplugins中添加内容了。下面的示例同时演示了三种典型用法:直接引用 viem 提供的erc20Abi、通过etherscan插件按链 ID 拉取链上合约 ABI、通过react插件生成 React Hooks。

import { defineConfig } from '@wagmi/cli' import { etherscan, react } from '@wagmi/cli/plugins' import { erc20Abi } from 'viem' import { mainnet, sepolia } from 'wagmi/chains' export default defineConfig({ out: 'src/generated.ts', contracts: [ { name: 'erc20', abi: erc20Abi, }, ], plugins: [ etherscan({ apiKey: process.env.ETHERSCAN_API_KEY!, chainId: mainnet.id, contracts: [ { name: 'EnsRegistry', address: { [mainnet.id]: '0x314159265dd8dbb310642f98f50c066173c1259b', [sepolia.id]: '0x112234455c3a32fd11230c42e7bccd4a84e02010', }, }, ], }), react(), ], })

直接声明合约

上例中contracts数组里的erc20合约直接复用了 viem 导出的erc20Abi,无需网络请求。这是最快的接入方式,适合在项目中内联使用常见标准合约 ABI。

Etherscan 插件:按链拉取 ABI

etherscan插件的完整配置项定义在 etherscan.ts 中,包括:

  • apiKey(必填):Etherscan API 密钥。
  • chainId(必填):用于拉取 ABI 的链 ID;当address是多链对象时,以此选择具体地址。
  • contracts(必填):待拉取 ABI 的合约列表(无需abi字段)。
  • cacheDuration(可选):ABI 缓存时长,默认1_800_000毫秒(30 分钟)。缓存逻辑由 fetch.ts 中的通用fetch助手承担,缓存键为etherscan:<address>或序列化后的多链地址对象。
  • tryFetchProxyImplementation(可选):是否尝试获取代理合约的实现地址(默认false),开启后会先调用getsourcecode动作。

拉取到的 ABI 会被序列化进生成的out文件,因此运行一次generate后,即使离线也可以继续使用这些 ABI。

React 插件:生成 Hooks

react()插件不依赖任何网络请求,它纯粹基于已解析的合约(来自配置contracts与其它插件的产出)生成 React Hooks。从 react.ts 插件实现 可以看到其核心逻辑:遍历每个合约的 ABI,按函数/事件类型分组,然后为每种能力生成对应的 Hooks:

  • 只读函数view/pure)→useRead${Contract}${Item},底层调用createUseReadContract
  • 写入函数nonpayable/payable)→useWrite${Contract}${Item}createUseWriteContract)与useSimulate${Contract}${Item}createUseSimulateContract)。
  • 事件useWatch${Contract}${Item}EventcreateUseWatchContractEvent)。

默认的命名模式为use${type}${ContractName}${ItemName}(watch 额外追加Event),例如合约erc20balanceOf读函数会生成useReadErc20BalanceOf。若同时存在合约级 Hook 与函数级 Hook 时,重载函数只生成一个 Hook 以避免冲突。你也可以通过react({ getHookName: ... })自定义命名函数,或通过abiItemHooks: false关闭逐函数 Hook 的生成。所有生成的 Hook 都带有基于合约地址的文档注释,方便 IDE 悬浮提示。

运行代码生成:wagmi generate

配置完成后,执行generate命令即可解析所有 ABI 并将生成代码写入out指向的文件:

pnpm wagmi generate
npx wagmi generate
yarn wagmi generate
bun wagmi generate

以上示例配置执行generate时,命令实际会依次完成以下工作(对应 generate.ts 主流程):

  1. 校验etherscanreact两个插件的配置(调用每个插件的validate钩子)。
  2. 收集插件提供的合约:从 Etherscan 拉取并缓存 ENS Registry 的 ABI(按 Mainnet/Sepolia 地址区分)。
  3. 将配置中的erc20Abi以名称'ERC20'纳入合约集合,并按名称排序去重;若合约名重复会直接报错。
  4. 依次运行每个插件的run钩子,react插件基于全部合约生成 React Hooks,产出以importsprependcontent三段式拼装。
  5. 将 ABI 常量、ENS Registry 的多链地址常量、合约配置常量以及所有 React Hooks 写入out文件(见writeContracts,写入前会自动创建输出目录并格式化)。

generate命令支持的选项与 generate 命令文档 一致:

选项类型说明
-c, --config <path>string指定配置文件路径
-r, --root <path>string解析配置的根目录
-w, --watchboolean监听文件变化(仅对支持 watch 的插件生效)
-h, --help-显示帮助信息

--watch模式是日常开发的利器:对于支持 watch 的插件(如 Foundry、Hardhat),generate --watch会通过 chokidar 监听源码文件变化,在文件新增/变更/删除时自动更新对应合约并防抖(100ms)重写输出文件;同时它还会监听配置文件本身的变更并提示重启进程。仓库中 generate.test.ts 覆盖了大量行为验证,包括无效 CLI 选项、配置文件缺失、out与合约名重复、ABI/地址非法、未配置合约时的提示,以及无 watch 插件时使用--watch的告警等。

使用生成的代码

generate完成后,out(如src/generated.ts)中会导出所有合约的 ABI 常量、地址常量与 React Hooks。在 React 应用中可以直接导入使用:

import { useReadErc20, useReadErc20BalanceOf } from './generated' // 使用生成的 ERC-20 合约级读 Hook const { data } = useReadErc20({ address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', functionName: 'balanceOf', args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], }) // 使用生成的 ERC-20 "balanceOf" 专属 Hook(函数名已内联) const { data } = useReadErc20BalanceOf({ address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], })

两种写法各有适用场景:合约级 Hook(如useReadErc20)需要在调用时手动指定functionName,灵活度更高;函数级 Hook(如useReadErc20BalanceOf)已把函数名固化在类型与实现中,参数列表更简洁、类型约束更严格。二者都基于wagmi/codegen中的createUseReadContract等工厂函数,因此与 React 组件、TanStack Query 的集成方式与手写 Hook 完全一致。

需要留意的是,生成的 Hooks 参数中地址与参数类型都源自 ABI 的类型推导(通过 abitype 完成),错误参数会在编译期被拦截,这是使用 CLI 生成代码相比手写裸调用最大的收益之一。

关于 out 文件的工程实践

官方建议(见原文档 tip)不要把out文件提交进版本库:更稳妥的做法是将其加入.gitignore,然后在构建流程或启动开发服务器前触发generate。例如在package.json中添加"predev": "wagmi generate"脚本,或在 CI 构建阶段先执行生成步骤,保证仓库中始终只保留配置与源码,生成的代码随构建即时产出。

进阶方向

完成上述流程后,可以按需深入以下主题:

  • Configuring CLI:掌握defineConfig的类型提示、条件配置、异步配置、数组配置与环境变量加载等进阶用法。
  • Commands:查阅全部 CLI 命令(含 generate 与 init)的完整选项说明。
  • Plugins:浏览插件全集,包括 etherscan、react、foundry、hardhat、sourcify、blockExplorer、fetch、actions 等,均可通过@wagmi/cli/plugins子路径导入。
  • Migrate from v1 to v2:如果你是旧版本用户,可参照此指南平滑迁移。

【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询