FEATURED · 精选文章

web3.js v4 迁移指南:web3.providers 全面升级(HttpProvider / WebSocketProvider / IpcProvider)

发布时间 / 2026/9/20 6:55:28
来源 / 创域科博编辑部
栏目 / 资讯中心
web3.js v4 迁移指南:web3.providers 全面升级(HttpProvider / WebSocketProvider / IpcProvider) 区块链Web3【免费下载链接】web3.jsCollection of comprehensive TypeScript libraries for Interaction with the Ethereum JSON RPC API and utility functions.项目地址https://gitcode.com/gh_mirrors/we/web3.js点击查看免费下载本指南以 web3.js 1.x 升级到 v4 为背景系统梳理web3.providers中 HttpProvider、WebSocketProvider、IpcProvider 三大 Provider 在构造参数、重连机制、事件模型与程序生命周期上的全部破坏性变更并提供逐项对照的 TypeScript 迁移示例与源码级原理佐证。读完本文你将能无痛地把 1.x 时代的 Provider 配置代码改写为 v4 风格并正确应对程序不再自动退出close 事件被废弃重连错误消息带 maxAttempts 后缀等关键行为差异。关于 Provider 的完整介绍、优先级与类型体系可先参阅仓库内的 web3.js Providers Guide。本文是 15_web3_upgrade_guide 系列 中专讲web3.providers的一篇。迁移总览1.x 与 v4 的 Provider 差异在哪里web3.js v4 对 Provider 体系做了三件大事构造选项类型全面更换1.x 中每个 Provider 自带一套专属 Options 接口HttpProviderOptions、WebsocketProviderOptionsv4 则统一对齐 Web 标准RequestInit、ClientOptions/ClientRequestArgs、SocketConstructorOpts并把重连抽离为独立的ReconnectOptions。事件模型对齐 EIP-1193废弃close事件改用disconnect事件Provider 内部通过Eip1193Provider抽象类实现chainChanged、accountsChanged、connect、disconnect等标准事件。包结构与生命周期变化IpcProvider不再默认随主包安装需单独引入web3-providers-ipcWebSocket 连接下程序不再因代码执行完而自动退出必须显式disconnect()。从源码结构看v4 的 Provider 分层为HttpProvider直接继承Web3BaseProvider见 packages/web3-providers-http/src/index.ts而WebSocketProvider与IpcProvider共同继承抽象类SocketProvider见 packages/web3-utils/src/socket_provider.ts后者再继承Eip1193Provider见 packages/web3-utils/src/web3_eip1193_provider.ts。重连、请求队列、订阅解析等通用能力都收口在SocketProvider里这正是两个 socket 类 Provider 行为高度一致的根本原因。在web3主包中Provider 通过 packages/web3/src/providers.exports.ts 导出http与ws两个命名空间直接导出export * as http from web3-providers-http、export * as ws from web3-providers-ws同时导出Eip1193Provider、SocketProvider等基类而IpcProvider不在其中需要自行安装web3-providers-ipc。HttpProvider 选项迁移HttpProviderOptions 改为 RequestInit1.x 的 HttpProviderOptions1.x 中构造HttpProvider时传入的是HttpProviderOptions由keepAlive、timeout、headers、withCredentials、agent五个字段构成其中agent用于配置 Node.js 的http/https代理interface HttpProviderOptions { keepAlive?: boolean; timeout?: number; headers?: HttpHeader[]; withCredentials?: boolean; agent?: HttpAgent; } interface HttpAgent { http?: http.Agent; https?: https.Agent; baseUrl?: string; } interface HttpHeader { name: string; value: string; }v4 的 HttpProviderOptionsv4 中选项类型同名但结构完全不同HttpProviderOptions现在只是一个包装对象唯一的键是providerOptions其值为标准 Fetch API 的RequestInit对象即fetch的第二个参数所对应的配置类型涵盖body、cache、credentials、headers、keepalive、method、mode、redirect、referrer、signal等字段。该接口在仓库中定义于 packages/web3-providers-http/src/types.tsexport interface HttpProviderOptions { providerOptions: RequestInit; }两种写法对比如下// in 1.x let httpOptions { keepAlive: true, withCredentials: false, timeout: 20000, // ms headers: [ { name: Access-Control-Allow-Origin, value: * }, ], agent: { http: http.Agent(...), baseUrl: } }; // in v4 let httpOptions { providerOptions: { body: undefined, cache: force-cache, credentials: same-origin, headers: { Content-Type: application/json, }, integrity: foo, keepalive: true, method: GET, mode: same-origin, redirect: error, referrer: foo, referrerPolicy: same-origin, signal: undefined, window: undefined, } as RequestInit, };源码层面的行为佐证从 packages/web3-providers-http/src/index.ts 的request()实现可以看到 v4 对providerOptions的实际处理方式const providerOptionsCombined { ...this.httpProviderOptions?.providerOptions, ...requestOptions, }; const response await fetch(this.clientUrl, { ...providerOptionsCombined, method: POST, headers: { ...providerOptionsCombined.headers, Content-Type: application/json, }, body: JSON.stringify(payload), });几个值得注意的实现事实构造时传入的providerOptions会与每次调用request(payload, requestOptions)时传入的RequestInit浅合并且单次请求的requestOptions优先。无论你如何配置method都会被强制为POSTContent-Type会被强制为application/jsonbody会被替换为JSON.stringify(payload)——这是 JSON-RPC over HTTP 的硬性要求。HttpProvider的构造器会先校验 URL必须匹配/^http(s)?:\/\//i否则抛出InvalidClientError同时它不支持订阅supportsSubscriptions()返回falseon/once/removeListener/connect/disconnect等 socket 类方法都会抛出MethodNotImplementedError。迁移时的常见注意点1.x 中timeout是一个独立字段v4 中你要在RequestInit层面自行实现超时例如配合signal使用AbortController因为标准fetch没有内置timeout选项。WebSocketProvider 选项迁移ClientOptions/ClientRequestArgs ReconnectOptions1.x 的 WebsocketProviderOptions1.x 中WebSocketProvider构造时传入的是WebsocketProviderOptions字段相当繁杂host、timeout、reconnectDelay、headers、protocol、clientConfig、requestOptions、origin以及内嵌的reconnect: ReconnectOptions注意 1.x 的字段名是auto、delay、maxAttempts、onTimeoutinterface WebsocketProviderOptions { host?: string; timeout?: number; reconnectDelay?: number; headers?: any; protocol?: string; clientConfig?: object; requestOptions?: any; origin?: string; reconnect?: ReconnectOptions; } interface ReconnectOptions { auto?: boolean; delay?: number; maxAttempts?: number; onTimeout?: boolean; }v4 的构造参数拆分为两个独立可选参数v4 中WebSocketProvider的构造函数签名变成三个参数socketPath、socketOptions、reconnectOptions见 packages/web3-providers-ws/src/index.tspublic constructor( socketPath: string, socketOptions?: ClientOptions | ClientRequestArgs, reconnectOptions?: PartialReconnectOptions, )socketOptions的类型为ClientOptionsisomorphic-ws/ws库的 WebSocket 客户端选项如headers、maxPayload或 Node.js 的ClientRequestArgs底层 HTTP 升级请求选项。reconnectOptions用来控制自动重连的开关、延迟与最大尝试次数其类型与原文档一致// this is the same options interface used for both WebSocketProvider and IpcProvider type ReconnectOptions { autoReconnect: boolean; // default: true delay: number; // default: 5000 maxAttempts: number; // default: 5 };这三个默认值并非文档虚构而是定义在 packages/web3-utils/src/socket_provider.ts 的DEFAULT_RECONNECTION_OPTIONS常量中并在SocketProvider构造器里通过展开合并注入this._reconnectOptions { ...DEFAULT_RECONNECTION_OPTIONS, ...(reconnectOptions ?? {}) }。因此即便你不传第三个参数Provider 也会默认启用自动重连autoReconnect: true、延迟 5 秒、最多 5 次。程序生命周期行为的变化重要1.x 中程序连接 WebSocket Provider 后执行完所有代码就会自动退出即使连接仍然存活const web3 new Web3(wsUrl); // The program will terminate after connecting since there are no more lines of code to run.v4 中行为已改变只要 WebSocket 连接还开着事件循环就会被活跃的连接保持住程序不会自动退出以便持续监听链上事件const web3 new Web3(wsUrl); // The program will keep running to listen for events.如何正确终止程序当你准备结束程序时需要手动调用disconnect()关闭连接进程才会正常退出const web3 new Web3(wsUrl); // When you are ready to terminate your program web3.currentProvider?.disconnect(); // The program will now terminatedisconnect(code?, data?)由SocketProvider实现见 packages/web3-utils/src/socket_provider.ts未传code时默认使用NORMAL_CLOSE_CODE 1000它会先移除 socket 监听器再关闭底层连接并触发_onDisconnect。如果你希望优雅等待所有在途请求完成后再断开还可以使用safeDisconnect(code, data, forceDisconnect, ms)——它会以setInterval轮询待发与已发请求队列直到两个队列均为空或forceDisconnect且重试 5 次后强制清空队列才真正断开详见 socket_provider.ts。选项示例1.x vs v4// in 1.x var options { timeout: 30000, // ms // Useful for credentialed urls, e.g: ws://username:passwordlocalhost:8546 headers: { authorization: Basic username:password, }, clientConfig: { // Useful if requests are large maxReceivedFrameSize: 100000000, // bytes - default: 1MiB maxReceivedMessageSize: 100000000, // bytes - default: 8MiB // Useful to keep a connection alive keepalive: true, keepaliveInterval: 60000, // ms }, // Enable auto reconnection reconnect: { auto: true, delay: 5000, // ms maxAttempts: 5, onTimeout: false, }, }; // in v4 let clientOptions: ClientOptions { // Useful for credentialed urls, e.g: ws://username:passwordlocalhost:8546 headers: { authorization: Basic username:password, }, maxPayload: 100000000, }; const reconnectOptions: ReconnectOptions { autoReconnect: true, delay: 5000, maxAttempts: 5, };对应的WebSocketProvider实例化示例socketOptions与reconnectOptions均为可选参数const provider new WebSocketProvider( ws://localhost:8545, { headers: { // to provide the API key if the Node requires the key to be inside the headers for example: x-api-key: Api key, }, }, { delay: 500, autoReconnect: true, maxAttempts: 10, }, );第二个参数可以为空对象或undefined只配置重连策略const provider new WebSocketProvider( ws://localhost:8545, {}, { delay: 500, autoReconnect: true, maxAttempts: 10, }, );注意WebSocketProvider构造时并不主动建立连接SocketProvider构造器中的this.connect()只是发起连接流程真正建立连接的时机在_openSocketConnection()它会以isomorphic-ws的WebSocket创建实例packages/web3-providers-ws/src/index.ts当socketOptions为空对象时会被显式转成undefined传给底层库。IpcProvider 迁移独立安装 SocketConstructorOpts使用场景与安装方式IPC Provider 用于 Node.js dApp 连接本地节点提供最安全的连接方式不经过网络层。1.x 中它随web3.providers一起可用构造时接受路径 net.Server实例import * as net from net; const ipcProvider new IpcProvider(/Users/myuser/Library/Ethereum/geth.ipc, new net.Server());v4 中由于它依赖的 Node.js 原生模块会影响 web3.js 在浏览器端的使用IPC Provider 不再随主包默认安装。你需要单独安装并显式创建实例由于它兼容 EIP-1193 Provider可以直接传给Web3实例使用import { IpcProvider } from web3-providers-ipc; const ipcProvider new IpcProvider(/Users/myuser/Library/Ethereum/geth.ipc);构造参数SocketConstructorOpts ReconnectOptionsv4 的IpcProvider构造签名为(socketPath, socketOptions?, reconnectOptions?)见 packages/web3-providers-ipc/src/index.ts第二个参数socketOptions的类型是 Node.jsnet.Socket的SocketConstructorOptsinterface SocketConstructorOpts { fd?: number | undefined; allowHalfOpen?: boolean | undefined; readable?: boolean | undefined; writable?: boolean | undefined; signal?: AbortSignal; }第三个参数reconnectOptions与WebSocketProvider共用同一ReconnectOptions类型默认值同样为autoReconnect: true、delay: 5000、maxAttempts: 5// this is the same options interface used for both WebSocketProvider and IpcProvider type ReconnectOptions { autoReconnect: boolean; // default: true delay: number; // default: 5000 maxAttempts: number; // default: 5 };选项与实例化示例// in 1.x var net require(net); new Web3.providers.IpcProvider(/Users/myuser/Library/Ethereum/geth.ipc, net); // mac os path // on windows the path is: \\\\.\\pipe\\geth.ipc // on linux the path is: /users/myuser/.ethereum/geth.ipc // in v4 let clientOptions: SocketConstructorOpts { allowHalfOpen: false, readable: true, writable: true, }; const reconnectOptions: ReconnectOptions { autoReconnect: true, delay: 5000, maxAttempts: 5, };IpcProvider的实例化示例第二、三参数均可选import { IpcProvider } from web3-providers-ipc; const provider new IpcProvider( path.ipc, { writable: false, }, { delay: 500, autoReconnect: true, maxAttempts: 10, }, );第二个参数同样可以为空对象或undefinedimport { IpcProvider } from web3-providers-ipc; const provider new IpcProvider( path.ipc, {}, { delay: 500, autoReconnect: true, maxAttempts: 10, }, );实现细节IpcProvider._openSocketConnection()在真正创建net.Socket之前会先调用existsSync(this._socketPath)校验 IPC 文件是否存在packages/web3-providers-ipc/src/index.ts路径不存在会直接抛出InvalidClientError——所以请先确认 geth/erigon 等本地节点的geth.ipc文件路径真实有效。重连机制与错误消息的变更重连逻辑WebSocketProvider 与 IpcProvider 通用socketOptions与reconnectOptions之外重连的核心逻辑收口在SocketProvider_reconnect()packages/web3-utils/src/socket_provider.ts在重连开始时把已发送队列中的请求以PendingRequestsOnReconnectingError拒绝若_reconnectAttempts maxAttempts则递增计数并延迟delay毫秒后重新connect()达到上限后清空队列并发出错误事件。WebSocket 侧_onCloseEventpackages/web3-providers-ws/src/index.ts只有满足autoReconnect (![1000, 1001].includes(event.code) || !event.wasClean)才触发重连——即关闭码 1000正常关闭与 1001节点离开且干净关闭时不重连。IPC 侧_onCloseEventpackages/web3-providers-ipc/src/index.ts在没有收到事件对象且autoReconnect为真时触发重连。错误消息变化与捕获方式本小节对IpcProvider与WebSocketProvider均适用。1.x 中重连次数耗尽时抛出的 Error 消息为Maximum number of reconnect attempts reached!v4 中消息不变但会附加maxAttempts的实际值Maximum number of reconnect attempts reached! (${maxAttempts})这并非临时文案而是由 packages/web3-errors/src/errors/connection_errors.ts 中的MaxAttemptsReachedOnReconnectingError类构造super(\Maximum number of reconnect attempts reached! (${numberOfAttempts}))并带有专属错误码ERR_CONN_MAX_ATTEMPTS。v4 中捕获该错误的推荐写法provider.on(error, error { if (error.message.startsWith(Maximum number of reconnect attempts reached!)) { // the error.message will be Maximum number of reconnect attempts reached! (${maxAttempts}) // the maxAttempts is equal to the provided value by the user, or the default value 5. } });由于消息以固定前缀开头、后接(数字)用startsWith判断前缀是兼容性最好的方式如需精确匹配也可按Maximum number of reconnect attempts reached! (5)全量比对。事件迁移close 已被废弃改用 disconnect遵循 EIP-1193 标准close事件已被废弃由disconnect取代。两者在WebSocketProvider与IpcProvider上行为一致。WebSocketProvider1.x 监听closeconst provider new WebSocketProvider(host port); // we would use close to listen to the disconnect function provider.on(close, function (err) { console.log(closed); resolve(); }); provider.disconnect(1012); // would eventually log closedv4 监听disconnectconst provider new WebSocketProvider(host port); // we would use disconnect to listen to the disconnect function provider.on(disconnect, function (err) { console.log(closed); resolve(); }); provider.disconnect(1012); // would eventually log closedIpcProvider1.x 监听closeconst provider new IpcProvider(host port); // we would use close to listen to the disconnect function provider.on(close, function (err) { console.log(closed); resolve(); }); provider.disconnect(1012); // would eventually log closedv4 监听disconnectconst provider new IpcProvider(host port); // we would use disconnect to listen to the disconnect function provider.on(disconnect, function (err) { console.log(closed); resolve(); }); provider.disconnect(1012); // would eventually log closed实现层面的说明SocketProvider的on/once/removeListener等事件 API 最终都落到内部EventEmitter上packages/web3-utils/src/socket_provider.ts当连接断开时Eip1193Provider._onDisconnect(code, data)会 emit 一个EIP1193ProviderRpcError类型的disconnect事件packages/web3-utils/src/web3_eip1193_provider.ts事件回调中拿到的err就是该错误对象携带code与data。同时 v4 在连接成功时还会按 EIP-1193 发射chainChanged、accountsChanged、connect等事件订阅这些标准事件是 v4 应用监听链与账户变更的推荐姿势。迁移检查清单把HttpProvider的构造选项从keepAlive/timeout/headers/withCredentials/agent改为{ providerOptions: RequestInit }并在RequestInit层面自行处理超时如AbortController。把WebSocketProvider的构造从单一 options 对象改为(socketPath, socketOptions?: ClientOptions | ClientRequestArgs, reconnectOptions?: PartialReconnectOptions)确认headers、maxPayload已迁移到ClientOptions。把 1.x 的reconnect: { auto, delay, maxAttempts, onTimeout }改为独立的reconnectOptions: { autoReconnect, delay, maxAttempts }注意 v4 默认已开启自动重连延迟 5s、最多 5 次。WebSocket 场景下若程序需要退出记得显式调用web3.currentProvider?.disconnect()或等待在途请求完成的safeDisconnect()否则进程会一直存活监听事件。把所有provider.on(close, ...)改为provider.on(disconnect, ...)并按 EIP-1193 标准事件connect、chainChanged、accountsChanged、message重构监听逻辑。IPC 场景安装web3-providers-ipc去掉 1.x 的new net.Server()第二个实参改用(path, socketOptions?: SocketConstructorOpts, reconnectOptions?)核实不同平台的 IPC 路径macOS~/Library/Ethereum/geth.ipc、Windows\\.\pipe\geth.ipc、Linux~/.ethereum/geth.ipc。重连失败错误处理改为兼容Maximum number of reconnect attempts reached! (N)的新格式用startsWith判断前缀。赞分享区块链Web3【免费下载链接】web3.jsCollection of comprehensive TypeScript libraries for Interaction with the Ethereum JSON RPC API and utility functions.项目地址https://gitcode.com/gh_mirrors/we/web3.js点击查看免费下载相关推荐5分钟快速上手免费Windows字体自定义终极指南5分钟快速上手免费Windows字体自定义终极指南 还在为Windows系统千篇一律的字体而烦恼吗微软从Windows 8.1开始取消了系统字体自定义功能区块链Web3深入 RustPython Notebook在浏览器中同时运行 Python、JavaScript、Markdown 与 TeX 的科学计算笔记本深入 RustPython Notebook在浏览器中同时运行 Python、JavaScript、Markdown 与 TeX 的科学计算笔记本 RustP区块链Web3Web3.js核心模块深度解析从Web3-Core到Web3-EthWeb3.js核心模块深度解析从Web3 Core到Web3 Eth 本文深度解析了Web3.js的四个核心模块Web3 Core作为基础架构提供请求管理和区块链Web3上一篇Rerun re_time_ruler 深度解析时间轴的时间↔屏幕分段线性映射与刻度渲染实现下一篇事件溯源查询优化Modular Monolith DDD物化视图设计创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻