资讯详情

wagmi 中 createConfig 完全指南:配置项详解、Config 状态模型与源码级原理

📅 2026/9/17 13:51:48 | 华诺云谱 👁 阅读
wagmi 中 createConfig 完全指南:配置项详解、Config 状态模型与源码级原理
wagmi 中 createConfig 完全指南配置项详解、Config 状态模型与源码级原理【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmicreateConfig是 wagmi 的核心入口函数用于创建应用级的Config对象。它是整个 wagmi 运行时的“心脏”负责管理链与 transport 的映射、连接器Connector的注册与 EIP-6963 钱包发现、状态的持久化与订阅以及按需创建链感知的 Viem Client。读完本文你将掌握createConfig的全部参数语义与默认值、返回的Config对象的方法与内部State结构并能结合仓库源码理解其底层实现在实际项目中正确初始化与使用 wagmi。本文基于仓库 site/shared/createConfig.md由 site/react/api/createConfig.md 通过 include 引入编写并辅以 packages/core/src/createConfig.ts 等源码作为实现佐证。导入与基本用法createConfig从 wagmi 主入口直接导出见 packages/react/src/exports/index.ts 中export { createConfig } from wagmi/coreReact 用户可按如下方式导入import { createConfig } from wagmi最基础的用法是传入一组链以及一个“链 ID → Transport”的映射import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })其中http()是内置 transport 工厂除http外还支持webSocket、fallback、custom等详见 Transports 文档。createConfig的完整类型定义位于 packages/core/src/createConfig.ts 的CreateConfigParameters。提示集成自定义 Viem Client如果不使用transports也可以通过client属性提供一个返回 ViemClient的函数从而对 wagmi 内部的 Client 创建逻辑做更细粒度的控制import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains import { createClient } from viem const config createConfig({ chains: [mainnet, sepolia], client({ chain }) { return createClient({ chain, transport: http() }) }, })注意使用client选项时建议把回调收到的parameters.chain原样透传给createClient以保证 Viem Client 与当前活跃连接所指向的链保持一致。参数详解参数类型可通过CreateConfigParameters引入import { type CreateConfigParameters } from wagmichains类型readonly [Chain, ...Chain[]]用途Config 所使用的链列表。chains至少需要包含一条链非空元组。内置链与Chain类型的完整说明见 Chains 文档。源码中chains会被存入独立的 zustand storecreateStore(() rest.chains)初始chainId即取自chains[0].id见 createConfig.ts。import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], // [!code focus] transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })connectors类型CreateConnectorFn[] | undefined用途Config 使用的连接器Connector列表。连接器的完整说明见 Connectors 文档。常见的连接器工厂包括injected()见 injected 连接器、metaMask()、walletConnect()、coinbaseWallet()等均从wagmi/connectors导入import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains import { injected } from wagmi/connectors // [!code focus] const config createConfig({ chains: [mainnet, sepolia], connectors: [injected()], // [!code focus] transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })从源码看每个 connector 工厂都会被setup()包裹为它创建带uid的事件发射器createEmitter传入chains、storage、transports以及一个按rdns过滤的providersgetter并立即监听其connect事件——这使得钱包可以在无用户交互的情况下自行建立连接例如 MetaMask 的“手动连接当前站点”见 createConfig.ts。multiInjectedProviderDiscovery类型boolean | undefined默认值true用途是否通过 EIP-6963 自动发现注入式钱包 Provider并使用mipd库将其转换为injected连接器。import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], multiInjectedProviderDiscovery: false, // [!code focus] transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })源码中的实现细节当typeof window ! undefined multiInjectedProviderDiscovery为真时会调用createMipd()创建 mipd store并在初始化时把mipd.getProviders()返回的每个 ProviderproviderDetailToConnector将其包装为injected({ target: { ...info, id: info.rdns, provider } })追加为连接器同时按rdns去重避免与显式配置的 connector 重复见 createConfig.ts。此外 mipd store 的subscribe会持续监听新出现的钱包 Provider 并动态注册见 createConfig.ts。createConfig.test.ts中的eip 6963 providers用例验证了通过announceProvider广播的钱包会被依次加入config.connectors见 createConfig.test.ts。ssr类型boolean | undefined默认值false用途标识 Config 是否运行在服务端渲染环境中。import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], ssr: true, // [!code focus] transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })开启ssr后有两个关键行为变化其一跳过显式 connectors 与 mipd 发现到的连接器的rdns收集见 createConfig.ts其二zustandpersist中间件启用skipHydration: ssr避免在服务端直接读取/写入持久化存储见 createConfig.ts。storage类型Storage | null | undefined默认值createStorage({ storage: typeof window ! undefined window.localStorage ? window.localStorage : noopStorage })用途Config 使用的存储用于在会话之间持久化Config的State。Storage类型的完整说明见 createStorage 文档。默认实现中浏览器环境使用window.localStorage非浏览器环境如 Node/SSR退化为空操作存储noopStoragecreateStorage还会对写入异常做静默处理见 createStorage.ts。持久化的 key 以wagmi为前缀写入前会经过serialize、读取后经deserialize处理见 createStorage.ts。import { createConfig, createStorage, http } from wagmi import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], storage: createStorage({ storage: window.localStorage }), // [!code focus] transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })createConfig内部会把该storage接入 zustand 的persist中间件名为store并通过partialize只持久化关键字段connections、chainId、current以控制存储体积status不会被持久化因为它会影响重连逻辑见 createConfig.ts。syncConnectedChain类型boolean | undefined默认值true用途是否让State[chainId]与当前连接保持同步。import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], syncConnectedChain: false, // [!code focus] transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })实现上该选项通过store.subscribe监听“当前连接对应的 chainId”并在链已配置的前提下把chainId状态同步过去未配置的链不会被切换见 createConfig.ts。createConfig.test.ts的behavior: syncConnectedChain用例完整验证了默认取第一条链、switchChain后跟随切换、连接指定链后跟随连接、断开连接后保持最后链的完整链路见 createConfig.test.ts。batch类型{ multicall?: boolean | { batchSize?: number | undefined; wait?: number | undefined } | undefined } | { [_ in chains[number][id]]?: ... } | undefined默认值{ multicall: true }用途批量请求相关设置multicall 批处理详见 Viem 文档。import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], batch: { multicall: true }, // [!code focus] transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })该配置也支持按链覆盖例如batch: { [mainnet.id]: { multicall: { batchSize: 1024 } } }。源码中当未显式提供batch时Viem Client 会默认使用{ multicall: true }见 [createConfig.ts](https://link.gitcode.com/i/e1389845fd21b728ab26baf6e3fd122f#L182-L188。测试behavior: properties passed through to Viem Client via getClient验证了全局与按链配置两种写法未配置的链回退到{ multicall: true }见 createConfig.test.ts。cacheTime类型number | { [_ in chains[number][id]]?: number | undefined } | undefined默认值pollingInterval的值或4_000毫秒用途启用轮询polling功能的缓存频率详见 Viem 文档。import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], cacheTime: 4_000, // [!code focus] transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })pollingInterval类型number | { [_ in chains[number][id]]?: number | undefined } | undefined默认值4_000毫秒用途启用轮询功能的轮询频率详见 Viem 文档。import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], pollingInterval: 4_000, // [!code focus] transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })值得说明的是cacheTime、pollingInterval、batch等 Viem Client 相关属性均支持“全局值”与“按链 ID 覆盖”两种写法。源码在创建 Client 时会逐个解析这些属性若某个值以 chainId 为键的对象则取当前链对应的值若对象键是其它链的 ID 但当前链没有对应值则该属性被跳过见 createConfig.ts。transports类型Recordchains[number][id], Transport用途链 ID 到Transport的映射用于内部创建链感知的 ViemClient。Transport的完整说明见 Transports 文档。可以为同一条链配置多个 transport 并通过fallback组合实现高可用import { createConfig, fallback, http } from wagmi // [!code focus] import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], transports: { // [!code focus] [mainnet.id]: fallback([ // [!code focus] http(https://...), // [!code focus] http(https://...), // [!code focus] ]), // [!code focus] [sepolia.id]: http(https://...), // [!code focus] }, // [!code focus] })client类型(parameters: { chain: chains[number] }) ClientTransport, chains[number]用途用于创建内部 ViemClient的函数比transports提供更多控制力。import { createClient, http } from viem // [!code focus] import { createConfig } from wagmi import { mainnet, sepolia } from wagmi/chains const config createConfig({ chains: [mainnet, sepolia], client({ chain }) { // [!code focus] return createClient({ chain, transport: http(https://...) }) // [!code focus] }, // [!code focus] })警告使用client时建议将回调参数parameters.chain原样传给createClient以确保 Viem Client 与活跃连接保持同步。返回类型Config 对象createConfig返回Config它是一个负责管理 wagmi 状态与内部机制的对象。类型通过以下方式引入import { type Config } from wagmichains类型readonly [Chain, ...Chain[]]说明即传给createConfig的chains。通过 getter 暴露get chains()返回内部 chains store 的状态见 createConfig.ts。connectors类型readonly Connector[]说明由传入的connectors与multiInjectedProviderDiscovery共同组装而成的连接器集合。同样通过 getter 暴露见 createConfig.ts。state类型Statechains说明Config对象的内部状态结构与State一致见下文。通过get state()读取见 createConfig.ts。storage类型Storage | null说明传给createConfig的storage。getClient类型(parameters?: { chainId?: chainId | chains[number][id] | undefined }): Clienttransports[chainId], Extractchains[number], { id: chainId }说明创建新的 ViemClient对象。不传chainId时使用当前state.chainId对应的链chainId指定但未配置时会抛出ChainNotConfiguredError已创建过的 Client 会按链 ID 记忆化复用见 createConfig.ts。// index.ts import { config } from ./config const client config.getClient({ chainId: 1 })// config.ts import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains export const config createConfig({ chains: [mainnet, sepolia], transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })测试getClient验证了默认链、指定链以及“未配置 chainId 抛错”三种情形见 createConfig.test.ts。setState类型(value: Statechains | ((state: Statechains) Statechains)) void说明更新Config对象的内部状态。与 zustand 的setState语义一致接受直接值或函数式更新若传入的状态与基础状态结构不符缺失关键字段或非对象会被重置为初始状态见 createConfig.ts。// index.ts import { mainnet } from wagmi/chains import { config } from ./config config.setState((x) ({ ...x, chainId: x.current ? x.chainId : mainnet.id, }))// config.ts import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains export const config createConfig({ chains: [mainnet, sepolia], transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })警告使用setState需格外谨慎它仅面向内部与高级场景。手动设置状态可能导致意外行为。subscribe类型(selector: (state: Statechains) state, listener: (selectedState: state, previousSelectedState: state) void, options?: { emitImmediately?: boolean | undefined; equalityFn?: ((a: state, b: state) boolean) | undefined } | undefined) (() void)说明监听与selector匹配的状态变化返回一个可用于取消订阅的函数。底层基于 zustand 的subscribeWithSelector中间件实现见 createConfig.ts。// index.ts import { config } from ./config const unsubscribe config.subscribe( (state) state.chainId, (chainId) console.log(Chain ID changed to ${chainId}), ) unsubscribe()// config.ts import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains export const config createConfig({ chains: [mainnet, sepolia], transports: { [mainnet.id]: http(https://mainnet.example.com), [sepolia.id]: http(https://sepolia.example.com), }, })StateConfig 的内部状态模型类型引入方式import { type State } from wagmiStatechains的定义见 createConfig.ts包含四个字段chainId类型chains[number][id]说明当前链 ID。当syncConnectedChain为true时与当前连接保持同步默认取chains中的第一条链。connections类型Mapstring, Connection说明从“唯一连接器标识符connector uid”到Connection对象的映射。current类型string | undefined说明当前活跃连接的唯一标识符。status类型connected | connecting | disconnected | reconnecting说明当前连接状态四种取值的语义为connecting正在尝试建立连接reconnecting正在尝试与一个或多个连接器重新建立连接connected至少有一个连接器已连接disconnected未与任何连接器建立连接。状态的流转由内部事件处理函数驱动connector 发出connect事件时写入connections、current并置status: connectedchange事件更新账号与链 IDdisconnect事件在无剩余连接时重置为disconnected否则切换到剩余连接中的下一个见 createConfig.ts。另外持久化恢复时会校验被持久化的chainId是否仍在当前chains中若已被移除则回退到第一条链的 IDvalidatePersistedChainId见 createConfig.ts。测试behavior: restore unconfigured chainId验证了该行为见 createConfig.test.ts。Connection连接的数据结构类型引入方式import { type Connection } from wagmiConnection的类型定义见 createConfig.ts包含三个字段accounts类型readonly [Address, ...Address[]]说明与该连接关联的地址数组非空。chainId类型number说明与该连接关联的链 ID。connector类型Connector说明与该连接关联的连接器对象。源码级原理createConfig 到底做了什么综合 packages/core/src/createConfig.ts 的实现createConfig的核心工作可以归纳为四步解析默认值multiInjectedProviderDiscovery true、storage createStorage({ storage: getDefaultStorage() })、syncConnectedChain true、ssr false均为解构默认值见 createConfig.ts组装 connectors为每个 connector 工厂创建带uid的 emitter 并注入chains、storage、transports与 mipd providers随后在浏览器且开启发现时合并 EIP-6963 钱包见 createConfig.ts构建状态 store使用 zustand 的createStoresubscribeWithSelectorpersist中间件将初始状态chainId为首链、空connections、current: null、status: disconnected接入持久化与迁移见 createConfig.ts挂载订阅与事件syncConnectedChain同步链、mipd 监听新钱包、emitter 处理connect/change/disconnect最终返回对外暴露的Config对象含_internal内部 API见 createConfig.ts。在 React 应用中消费 Config在 React 中创建好的config需要传给WagmiProvider由 packages/react/src/context.ts 导出它会通过 React Context 把 config 提供给整棵组件树并在挂载时执行Hydrate组件内再通过useConfig见 packages/react/src/hooks/useConfig.ts读取未包裹 Provider 时会抛出WagmiProviderNotFoundError。例如import { WagmiProvider, useConfig } from wagmi function App() { return ( WagmiProvider config{config} WalletButton / /WagmiProvider ) } function WalletButton() { const config useConfig() // config.chains / config.state / config.getClient() ... }SSR 场景下配合ssr: true的 config 与cookieToInitialState可在服务端预取状态、客户端水合相关指引可参考 SSR 指南。总结createConfig是 wagmi 一切能力的起点chains与transports定义了网络拓扑connectors与multiInjectedProviderDiscovery定义了钱包接入方式storage、ssr、syncConnectedChain定义了状态生命周期而返回的Config对象state、getClient、setState、subscribe则是连接 hooks、actions 与底层 Viem Client 的桥梁。理解这些参数与内部State/Connection结构是排查连接状态问题、定制 Client 行为以及实现 SSR 水合的前提。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。