wagmi 自定义 Transport(custom)接入指南:为 Ethereum 应用配置任意 JSON-RPC Provider
2026/9/17 15:54:00 网站建设 项目流程

wagmi 自定义 Transport(custom)接入指南:为 Ethereum 应用配置任意 JSON-RPC Provider

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

customTransport 允许在 wagmi 中绕过固定 URL 的 RPC 端点,直接传入一个符合 EIP-1193 规范的request函数来与任意 JSON-RPC API 通信,是实现钱包 Provider 适配、自定义 RPC 网关、测试替身与跨框架复用的关键入口。本文以 site/react/api/transports/custom.md(其正文来自共享文档 site/shared/transports/custom.md)为核心,结合 wagmi 源码与测试,完整讲解它的导入方式、配置参数、重试机制与在 React 环境下的实际用法。

Transport 在 wagmi 中的地位

在 wagmi 中,Transport 是连接链与客户端之间的桥梁。createConfig通过transports对象把每个chain.id映射到一个 Transport,从而决定该链上的读取、写入与合约调用请求走哪条网络通道:

export const config = createConfig({ chains: [mainnet], connectors: [injected()], transports: { [mainnet.id]: custom({ /* ... */ }), }, })

wagmi 原生导出了三类 Transport,全部通过viem转发(见 packages/core/src/exports/index.ts 的export { custom, http, webSocket } from 'viem'):

  • http:通过固定的 HTTP URL 连接 RPC 端点;
  • webSocket:通过 WebSocket 连接 RPC 端点;
  • custom:通过自定义的 EIP-1193request函数连接,是本文主题。

同时 wagmi 还提供了fallback(packages/core/src/transports/fallback.ts)与unstable_connector(packages/core/src/transports/connector.ts)两个组合型 Transport,可与custom组合使用。在 React 包中,custom同样从@wagmi/core被重新导出(见 packages/react/src/exports/index.ts),因此 React、Core 用户使用完全一致的 API。

导入 custom Transport

在所有框架(React、Vue、Solid 或纯 Core)中,custom都可以直接从包顶层导入:

import { custom } from 'wagmi'

对于仅使用 core 的场景,则从@wagmi/core导入:

import { custom } from '@wagmi/core'

基本用法:在 createConfig 中注册自定义 RPC

最典型的用法是在createConfigtransports中,将某个链的 Transport 指定为custom,并传入一个request函数:

import { createConfig, custom, } from 'wagmi' import { mainnet } from 'wagmi/chains' import { customRpc } from './rpc' export const config = createConfig({ chains: [mainnet], connectors: [injected()], transports: { [mainnet.id]: custom({ async request({ method, params }) { const response = await customRpc.request(method, params) return response }, }), }, })

其中./rpc中的customRpc可以是任意实现了request方法的 JSON-RPC 客户端,例如 ethers 的JsonRpcProvider、MetaMask 等注入式钱包的window.ethereum、测试网络的 stub,或经过包装的网关客户端。从源码结构看,custom本身不负责链的校验、连接管理或地址解析,它只负责把{ method, params }转发给你提供的request实现,因此它具有极强的通用性。

参数详解

provider(必填)

{ request({ method: string, params: unknown[] }): Promise<unknown> }

custom的第一个参数是一个 EIP-1193 规范的request函数。EIP-1193 定义了 Ethereum Provider 的标准接口,其核心就是request方法:接收一个 JSON-RPC 请求对象(method与可选的params),返回一个 Promise。任何符合该规范的 Provider(注入式钱包、钱包 SDK、本地节点封装等)都可以直接传入:

import { customRpc } from './rpc' const transport = custom({ async request({ method, params }) { const response = await customRpc.request(method, params) return response }, })

key(可选)

string

Transport 的键,默认为"custom"key在客户端创建时用于标识与查找对应的 Transport:

const transport = custom( provider, { key: 'windowProvider', }, )

name(可选)

string

Transport 的名称,默认为"Ethereum Provider"。该名称主要用于日志与调试信息展示:

const transport = custom( provider, { name: 'Window Ethereum Provider', }, )

retryCount(可选)

number

请求失败时的最大重试次数,默认为3。注意该参数是“最大重试次数”,即最多额外重试 3 次,总共最多发出 4 次请求:

const transport = custom(provider, { retryCount: 5, })

retryDelay(可选)

number

重试之间的基础延迟(毫秒)。默认情况下 Transport 会采用指数退避策略,计算公式为~~(1 << count) * retryDelay,意味着重试间隔并非恒定值,而是随重试次数指数增长:

const transport = custom(provider, { retryDelay: 100, })

结合源码理解:Transport 配置如何在链上落地

custom在 wagmi 中是一个透明转发自 viem 的 API,但理解它如何与 wagmi 的客户端体系协作,有助于在实际项目中排错与调优。

wagmi 自身实现的两个组合型 Transport 与custom遵循完全一致的配置协议,可作为对照参考。以 packages/core/src/transports/connector.ts 中的ConnectorTransportConfig为例,它定义了与custom相同的四个可选配置项:

export type ConnectorTransportConfig = { /** The key of the transport. */ key?: TransportConfig['key'] | undefined /** The name of the transport. */ name?: TransportConfig['name'] | undefined /** The max number of times to retry. */ retryCount?: TransportConfig['retryCount'] | undefined /** The base delay (in ms) between retries. */ retryDelay?: TransportConfig['retryDelay'] | undefined }

其实现unstable_connector(packages/core/src/transports/connector.ts)展示了 Transport 的完整生命周期:

  1. 设置默认值:key默认为'connector'name默认为'Connector'
  2. 当客户端实际发起请求时,Transport 函数被调用,接收chainconnectors等参数;
  3. 通过connectors.getState().find(...)找到目标连接器,调用其getProvider({ chainId })取得 Provider;
  4. eth_chainId进行带重试与超时(100ms)的探测,校验当前链与目标链一致,不一致则抛出ChainDisconnectedError
  5. 最终通过createTransport组装出标准 Transport 对象,将keynameretryCountretryDelay一并下发。

可以推断,custom传入的request函数最终也会被 viem 的createTransport包装为同样的 Transport 结构,并应用相同的重试与超时策略。这意味着你为custom设置的retryCount/retryDelay会作用于其内部的每一次 JSON-RPC 请求,因此:

  • 当你的自定义 Provider 偶发网络抖动时,retryCount: 3(默认值)能提供基本的容错;
  • 若你的 Provider 对高并发请求敏感,可适当增大retryDelay以拉长退避间隔,降低瞬时压力;
  • 若你的 Provider 自身已实现完整重试,可将retryCount设为0关闭 wagmi 侧的重试,避免双重重试造成请求堆积。

常见应用场景

1. 适配注入式钱包 / 自定义 Provider

custom最常见的用途是把window.ethereum之类的 EIP-1193 Provider 包装为可用的 Transport,从而让应用既能使用 wagmi 的 connectors,又能直接通过底层 Provider 发起 JSON-RPC 调用。

2. 接入非标准 RPC 网关

当你的 RPC 端点需要签名、鉴权、限流等自定义逻辑时,http无法表达这些行为,此时用customrequest内部完成包装即可。

3. 测试替身与模拟

在单元测试中,可以传入一个返回固定响应或按方法分发的 mockrequest函数,从而在不依赖真实网络的情况下验证应用逻辑(可参考 packages/core/src/transports/fallback.test.ts 与 packages/core/src/transports/connector.test.ts 了解 wagmi 对 Transport 行为的测试方式)。

4. 与 fallback 组合实现多通道容灾

fallbackTransport 接受一组 Transport 并依次尝试,因此可以把customhttpwebSocket组合,形成“自定义通道优先、公共 RPC 兜底”的策略:

import { createConfig, custom, fallback, http } from 'wagmi' import { mainnet } from 'wagmi/chains' export const config = createConfig({ chains: [mainnet], transports: { [mainnet.id]: fallback([ custom({ /* 自定义网关 */ }), http('https://cloudflare-eth.com'), ]), }, })

相关参考

  • Transport 参考文档:site/shared/transports/custom.md、site/react/api/transports/custom.md、site/react/api/transports/http.md
  • Core 源码导出:packages/core/src/exports/index.ts
  • React 源码导出:packages/react/src/exports/index.ts
  • 组合型 Transport 实现:packages/core/src/transports/fallback.ts、packages/core/src/transports/connector.ts
  • 链与 Transport 配置示例:playgrounds/vite-react/wagmi.config.ts

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

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

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

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

立即咨询