钱包掉线了,网页还在傻等:EIP-2786 与连接状态事件的两次尝试 图 1
钱包掉线了,网页还在傻等:EIP-2786 与连接状态事件的两次尝试 · 图 1

转圈的页面背后少了一个通知

钱包扩展与网页之间的通信模型建立在 EIP-1193 的 Provider 接口上:网页调用方法、钱包回应或报错,一切看似顺畅。但有一类状态长期无处安放——钱包自己”掉线”了。扩展后台与节点 RPC 的连接中断时,Provider 变成了哑巴:网页发出去的每个请求都石沉大海或连环失败,页面要么永远转圈,要么弹出含义模糊的错误。EIP-2786 在 2020 年 7 月 15 日提交,专门处理这个信息断层:让 Provider 在连接状态改变时主动广播事件。它的结局值得注意——提案被作者撤回(Withdrawn),因为它想立的标准最终被并进了 1193 正式规范,也就是说,你今天用的连接事件就是它概念的落地形态。

钱包掉线了,网页还在傻等:EIP-2786 与连接状态事件的两次尝试 图 2
钱包掉线了,网页还在傻等:EIP-2786 与连接状态事件的两次尝试 · 图 2

连接与断开的判定口径

2786 的定义完全以”能力”为准,不以界面为准:Provider 能对至少一条链处理 RPC 请求,就算 connected;对所有链都无能为力,才算 disconnected。注意这个口径有多严——只是当前网络不通、但换一条链还能服务,系统层面仍算连接着。事件方面,规范从”断开”状态进入”连接”状态时发 connect,携带一个十六进制的 chainId;反之发 disconnect。若 Provider 实现了 eth_chainId,事件里的链号必须与其返回值一致。它还有一句容易被忽略的话:这是一个”追溯性提案”,codify 的是当时各家钱包已经私下在发的事件——标准要做的只是把私有方言统一成普通话。

4900 与 4901:同是断开,含义差一层

1193 正式文本把断开状态细分进错误码表:4900 Disconnected 表示 Provider 与所有链都断开了;4901 Chain Disconnected 表示与当前请求的那条链断开、但仍连着其他链。这个分界对读日志和排障极其有用。4901 常出现在这样的场景:你切了一个刚添加、RPC 地址写错或已失效的网络,页面请求全部撞墙,但钱包本体完好,换个网络立刻恢复。4900 则指向更底层的问题:扩展断网、节点服务停摆、RPC 服务商故障。同一句”请检查连接”的界面提示,背后可能是这两层中完全不同的一层——分辨方法就是看钱包自己的状态区或直接用另一笔只读查询验证当前网络是否可达,机制与 eth_chainId 怎么确认你现在在正确的链上? 的链号核对是同一套动作。

事件监听缺失时,网页会怎样误报

规范约束的是 Provider 的义务,网页是否监听 connect/disconnect 完全自愿,于是出现两类典型误报。一类是掉线恢复后的旧数据:断连期间页面的缓存余额、交易列表停留在旧时点,重连后不刷新就继续展示,用户误以为交易丢失。另一类是竞态:disconnect 与 accountsChanged、chainChanged 等事件几乎同时到达(参见 监控工具怎么知道事件发生了:轮询与订阅推送的分工 讲的轮询与推送分工),实现粗糙的页面按到达顺序处理,出现余额与账户张冠李戴。因此把”页面显示的异常”当作链上事实之前,先做两件事:在钱包界面看账户真实余额,在区块浏览器按地址核对该笔交易的最终状态(参见 区块浏览器怎么读:确认数、失败原因和交易状态逐项解释),两边一致才算数。

与连接层相关的另一道分界

2786 管的是”能不能服务”,与”允不允许你调用”是两回事。后者是授权层:钱包是否把地址暴露给这个网站、网站能否发起签名请求,走的是连接授权流程,和 4900 这类传输层状态互不解释。实践中最常见的混淆是把”网站没被授权”误读成”钱包掉线”,进而去乱改 RPC 配置。正确的分诊顺序:先看钱包图标是否有断连标记或报错码,是传输层;钱包一切正常但页面拿不到地址,是授权层;两边都正常但数据不动,才轮到 RPC 质量与节点同步问题。

三点可带走的经验

第一,界面转圈和”链上有问题”之间永远隔着一层状态同步,任何钱包 UI 都不能替代浏览器上的按地址核对。第二,记住 4900 与 4901 的分界,能帮你把”换网络能救”和”换网络也没用”两类故障分开,省掉大量无效折腾。第三,标准演化的常态是”被吸收而非被否决”:2786 标记为 Withdrawn 不等于它失败了,而是它的条款住进了更完整的 1193 里——读任何提案的状态字段时,都要顺带查它的去向。本文为机制科普,不构成投资建议。