网页把钱包装进小框里怎么对话:CAIP-295 的 iframe 钱包消息通道 图 1
网页把钱包装进小框里怎么对话:CAIP-295 的 iframe 钱包消息通道 · 图 1

钱包不止扩展一种形态

多数人对钱包网页形态的印象是浏览器扩展:装在浏览器上、悬浮在所有页面之外。另一类钱包把界面做成网站页面里的一块内嵌框(iframe),你在同一个页面里选币、签名,不必跳走。两种形态的信任模型很不一样:扩展注入到页面的通信对象人人可见可抢,内嵌框则靠浏览器自带的页面内消息接口传话。顺带说明,内嵌框架也是钓鱼和注入高发的边界,哪些内嵌页面拿得到钱包接口,可见《有的网页里钱包入口根本不存在:EIP-5593 说的安全上下文与内嵌框架边界》所讲的上下文限制。

网页把钱包装进小框里怎么对话:CAIP-295 的 iframe 钱包消息通道 图 2
网页把钱包装进小框里怎么对话:CAIP-295 的 iframe 钱包消息通道 · 图 2

发现:两句话各自广播

编号 295 的链无关协议(CAIP-295)用 window.postMessagewindow.addEventListener 定义通道,第一步解决「互相发现」。规范给的理由很朴素:页面里各组件加载先后不确定,靠单方向的喊话不可靠,所以要求双向广播。钱包一侧,初始化时主动广播一条 wallet_announce,携带一份包含每页独立 uuid 的钱包数据;网站一侧,初始化时广播一条 wallet_prompt,意为「有需要登录/连接的钱包请报上来」。收到对方的 wallet_prompt 后,钱包要再 announce 一次,让晚到的一方也补上。此后网站按 uuid 把已知钱包记进一张表。

握手与签名:不发明新东西

用户选中某个钱包后,发现阶段让位给既有协议:连接握手直接走编号 25 的会话创建请求,签名与调用走编号 27 的方法调用,用会话建立后的 sessionIdchainId 分辨响应发给谁、打的哪条链。整份提案只新造发现层的两句话,握手、签名一律复用已有标准——这也是它 frontmatter 里 requires 25、27、282、372 的原因。这种「薄传输层」定位,与扩展形态的消息协议是同一族思路的 iframe 变体。

每页一个编号,不许复用

规范用一整小节强调 uuid 的生成纪律:钱包必须为每个加载的网页生成彼此不同的 uuid,在用户同意建立会话之前不得复用。这条约束针对跨站追踪:如果同一台机器上的钱包对所有站点喊出同一个标识,网站之间就能拿它把你的浏览行为连成一条线。每页一换之后,标识只在单个页面会话内有意义。对用户的含义是:这个 uuid 泄露与否直接影响隐私画像,但它也绝不是凭证——它只是「哪句话是接谁的话」的路牌号,不需要像 WalletConnect会话权限怎么读? 讲的会话权限那样逐条核对内容。

边界:草案、TODO 与核对清单

反过来说,当内嵌钱包区域迟迟不出现或点了没反应,按这份协议的对话模型可以分层排查:先确认页面本身处于受支持的浏览器与协议环境——若站点根本不在安全上下文里,钱包接口可能压根不会被暴露,这一步的判断逻辑与内嵌框架安全边界一致;再确认钱包扩展或客户端在运行、页面有权限向其发消息;最后才怀疑时序问题,刷新页面让双方的广播重新对齐——规范之所以要求网站初始化时主动广播询问,正是为了补救钱包先加载、网站后加载造成的错过。排查顺序的意义在于别把环境问题误判成钱包故障:连接失败先问「通道在不在」,再问「对方喊没喊话」,而不是反复重装钱包。

写作时该提案状态是 Draft,且规范自己挂着未完成项:「Target Origin」一节整段 TODO,即按来源地址限定收发对象的合法目标类型尚待另行提案。内嵌框能通到什么地址,目前实现自行掌握。把三节拼成一份核对清单,用户遇到内嵌钱包时依次问四点:内嵌框加载自哪个域名(点进框内查来源);钱包是否只在明确点过连接后才发会话请求;uuid 之外网站还拿到了什么持久标识;断开时是否走标准的会话撤销路径,可对照 点下「撤销连接」之后发生了什么:CAIP-285 与 wallet_revokeSession 的协议动作 讲的撤销动作。它解决的从来不是安全判断,而是把「谁在跟谁说话」写成了可以对账的明文。