用 DID 登录打通收付款(收款地址)
今天可离线自测登录通过校验后,你可以在服务端 resolve 该 DID,并从 canonical 记录里读出收款地址。这段逻辑今天就能写完并离线自测;在生产环境读取真实地址则随生产登录一起被阻塞。pay:address 是一句用户在批准页看到并同意的声明,不是权限。
动线总体状态今天可离线自测
步骤
1收款地址究竟从哪里来
今天可用一次登录响应只带 did、规范化消息与签名——没有账户地址。要拿到地址,你必须在服务端 resolve 该 DID 并读取 canonical 记录。
记录里的 owner 就是那个 44 字符的 MSG 账户地址(msg + 40 位十六进制 + 1 位校验)。文档里的 controller 字段不一样:它列的是 controller DID,不是地址,所以绝不要把 MSG 转给 did:msg:... 字符串。使用地址之前先检查 deactivated,并且缓存不要超过你的 resolve TTL(5 到 15 秒);DID 更新之间,名字到地址的映射是可能变化的。
js // After a verified login you have `did` (result.did) — never an address. import { createAgentApiResolver, createCachedResolver } from '@aidid/login'; const resolve = createCachedResolver({ resolver: createAgentApiResolver({ agentApiEndpoint: process.env.AGENT_API }), }); const record = await resolve.resolve(result.did); // canonical record, 10 s TTL by default if (record.deactivated) throw new Error('did_deactivated'); // refuse a retired identity first const payoutAddress = record.owner; // 'msg' + 40 hex + 1 checksum = 44 chars, an ACCOUNT address // record.document.controller is a list of controller DIDs — NOT a payment address.2resources: ['pay:address'] 是一句声明,不是授权
今天可用把 pay:address 加进 resources,只是把一句话放进用户签名的规范化消息里,钱包会在批准页显示它:「该站点将获得你的收款地址」。这是一句声明,规范也明确如此定性。
它不是权限、不授予任何链上权利,也不代表用户已完成支付授权。响应里仍然不会有地址,所以你必须自己 resolve 该 DID。如果你没有请求 pay:address,就完全不要推导、展示或把它用于收款。
js import { createSignInRequest } from '@aidid/login'; const request = createSignInRequest({ domain: 'shop.example', chainId: 'msg-chain-1', uri: 'https://shop.example/aidid/callback', statement: 'Sign in to shop.example.', // A declaration the user sees and approves. It is NOT a permission and the // response carries no address, so you still resolve the DID yourself. resources: ['did:auth', 'pay:address'], }); // result of the callback: { ok: true, did: 'did:msg:...' } — no address field, by design.3地址与 DID 的绑定:换设备、换密钥、子 DID
今天可离线自测地址属于 DID,所以真正要紧的问题是「DID 本身,以及它此刻在哪里」。
换设备或恢复备份:恢复带回的是同一份 DID 文档,所以同一个 owner 地址依然适用。新建的 DID 会得到新地址,所以绝不要把地址硬编码到用户账号上。
密钥轮换或 DID 更新:每次打款前都重新 resolve;记录带有单调递增的 version 与 updated 区块时间,owner 可能随更新变化。
子 DID:子 DID 是它自己的 did:msg,有自己的 resolve 记录。只有当这个子 DID 就是你接受的身份时,才把款项付给它的 owner;同时记住,子 DID 授权今天没有链上吊销通道——在文档更新之前,已撤销的授权仍可能 resolve 出来。
已停用的 DID:先用 did_deactivated 拒绝,再读地址;并且维护你自己的 deny list,因为链上没有黑名单。
4今天:可以离线自测,不能在生产取地址
今天不可用以上这些今天都能写完并离线自测,用 fixture resolver 代替 canonical resolve:请求、批准页声明、回调、resolve 这一步以及读取地址。
今天做不到的是在生产环境读取真实地址。公网上 resolve 未获授权,所以对任何 DID,取地址这一步都会以 endpoint_unavailable 失败关闭。不要上线任何依赖它的结账或打款流程;在链侧授权 endpoint、且普通用户确实能持有 DID 之前,诚实的状态就是失败关闭。
今天为什么被阻塞
didLoginProductionThe chain-side DID resolve endpoint (`GET {agent_api}/agent/v1/aidid/resolve`) is not authorized yet, so an RP cannot resolve any DID in production.
原因取自 status.json#capabilities —— 不是为这个页面手写的。