钱包事件的骨架只有两个方法:EIP-2700 定义的 on 与 removeListener 图 1
钱包事件的骨架只有两个方法:EIP-2700 定义的 on 与 removeListener · 图 1

先有插座,再有电器

2020 年 6 月 5 日,两位开发者提交了 EIP-2700:定义一个最小事件骨架,让网页与钱包之间”一个对象、两个方法”就能完成订阅——on(eventName, listener) 挂监听,removeListener(eventName, listener) 摘监听。有意思的是它的规范范围:这份 Final 提案只规定插座形状,既不定义有哪些事件、也不定义事件携带什么数据,连”这个对象挂在哪里”都留给后续标准。事件清单与语义由起草更早(2018 年 6 月 30 日)且如今同为 Final 的 EIP-1193 填充,也就是网页请钱包签名前那份英文名单:EIP-1193 的 Provider 接口与事件那套 chainChangedaccountsChanged 名单。分层切割是这份提案的全部方法论:接口形状一次定稳,内容各自演进。

钱包事件的骨架只有两个方法:EIP-2700 定义的 on 与 removeListener 图 2
钱包事件的骨架只有两个方法:EIP-2700 定义的 on 与 removeListener · 图 2

规范原文其实只有三条义务

剥去套话,2700 对钱包实现者提了三条可测试的要求。第一,如果钱包认识这个事件名,当事件发生时必须调用登记的回调。第二,同一个监听函数被 on 注册两次,钱包可以选择只调一次、也可以按注册次数回调——这条”二选一”是刻意留白,为的是不强推引用计数语义。第三,removeListener 必须让回调次数精确减一。注意用词:规范没说”移除登记”,而是”减少一次调用”,这个 Node.js EventEmitter 式的表述让重复注册的处理变得可预测。对照自家产品测试钱包或开发网页时,这三条就是验收清单。

为什么骨架值得单独立标准

把”事件有哪些”与”怎么监听”拆开的收益在工程史里反复出现。事件清单天然会膨胀——换链要通知、断连要通知、账户列表变化要通知,每加一种就得改协议;而订阅接口十年不变。后来的连接状态事件之争就是活例:钱包掉线了,网页还在傻等:EIP-2786 与连接状态事件的两次尝试记录了专门提案为钱包补上 connectdisconnect 的两次尝试,最终事件被 1193 吸收,但没有一个钱包需要更换 onremoveListener 的调用形状。对新标准作者,这也是一个现成的接口治理模板:先立不变的机制层,再让语义层各自认领。

用户端的感知在哪里

普通用户不会直接接触这两个方法,但它们决定的行为你天天遇到。换链弹窗出现后网页余额没刷新,多半是站点只订阅了账户事件、漏订链切换事件;断开钱包扩展后网页卡在加载态,多半是站点根本没监听断连通知。这类问题的诊断语言正是从事件模型来的:不是”钱包坏了”,而是”站点没处理某类事件”。对网页开发者,最小正确姿势是一组对称的订阅与取消——组件卸载时记得 removeListener,否则监听器在单页应用里越积越多,换一次链触发一叠重复请求。

对普通用户意味着什么

这套骨架与你钱包里那些”看起来理所当然”的行为直接相关。你在钱包里切换账户,网页余额跟着变,是因为钱包派发了 accountsChanged 事件、网页订阅了这个事件名——但”事件怎么到达网页”的通道形状,正是 2700 规定的。反过来说,如果某个站点在你换链后什么都不刷新,责任划分也可以用这套语言讲清楚:钱包有义务对认识的事件名调用回调,网页有义务监听并处理;两边都有代码时,这类刷新失灵大多是网页侧漏订,而不是钱包坏了。给排障一个新视角:先确认钱包版本日志里是否声明了相关事件支持,再看站点是否有已知的事件处理缺陷报告,比笼统地说”连不上”精确得多。

边界与易误读

第一,2700 不定义事件可靠性:事件是尽力而为的通知,网络断开期间的变化不会补发,站点必须保留轮询或重连后全量对账的兜底逻辑,这一点和你点了加速,网页还在等旧交易:EIP-2831 想给替换补上三个事件讲的替换事件教训一脉相承。第二,事件本身没有安全属性:任何能拿到 provider 的脚本都能监听,事件内容不含授权含义,看到 accountsChanged 不等于账户被攻击,也可能只是你刚切换了账户。第三,removeListeneroff 类便利方法不等价——规范只保证前者,看到扩展库提供其他写法时,回溯它最终映射到哪条义务才是可靠读法。风险提示:本文解释接口机制,不构成投资建议;钱包功能以官方当期文档为准。