跳转到主要内容
钱包所有权小组件是一个托管页面,用于证明您的某位客户控制特定的加密钱包地址。根据欧盟 TFR,VASP 在向自托管(非托管)钱包转入或从中转出超过 sunrise 阈值的资金之前,必须验证该钱包的所有权。小组件让 Didit 为您收集这一证明,您无需自行构建签名流程。 验证通过的证明会将匹配的钱包地址簿条目标记为 is_ownership_verified: true,从而使关联的 Travel Rule 转账能够从 UNCONFIRMED_OWNERSHIP 状态继续推进。

何时由 Didit 为您创建

您很少需要自行创建会话。 当您的 Travel Rule 设置中的 auto_wallet_verification 开启时(默认开启),只要转账需要终端用户证明其钱包控制权,Didit 就会在创建交易时自动创建小组件会话:
  • 转账处于 UNCONFIRMED_OWNERSHIP 状态,即对手方钱包在提交时已被声明为自托管。
  • 转账为转出,并处于 COUNTERPARTY_VASP_NOT_FOUND 状态,即无法识别对手方 VASP,因此所有权证明是完成转账的剩余途径。
自动创建的会话会在交易的 action_required 块中返回(type: "wallet_ownership",并包含要打开的 url),SDK 会在客户端提交时自动启动该会话。 Didit 为您创建的入账转账(sunrise 登记、入账 TRP 查询,或 INTERNAL 通道的入账段)即使进入 UNCONFIRMED_OWNERSHIP 状态,也永远不会自动创建会话。 如需在任何转账存在之前预先验证某个钱包,如已关闭 auto_wallet_verification,或针对上述某笔入账转账,请使用 POST /v3/travel-rule/widget-session/ 手动创建会话。

证明内容

该小部件最多提供四种证明方式。显示哪些方式取决于您创建会话的方式以及您的 Travel Rule 设置:

消息签名验证合约

提交签名后,一旦证明您控制该钱包,将返回 200 和 status: "VERIFIED"。 如果返回 400,证明保持开启状态,客户可以重新签名,同时返回以下 code 值之一:

Satoshi 测试验证合约

验证 Satoshi 测试充值是异步的,因为交易必须先在链上被看到,然后再被确认。 提交充值的 txid 后,若充值尚未在链上确认,将返回 200 和 status: "PENDING";txid 会被保留,而非丢弃。 充值确认后,将返回 200 和 status: "VERIFIED"。 对于确实错误的充值,将返回 400 和 status: "REJECTED":例如来自其他钱包、金额与充值地址不符、早于挑战时间,或该交易已证明过其他钱包。此时证明关闭,只要会话仍有剩余尝试次数,客户即可发起新的证明。 如果充值尚未被索引,同样返回 200 和 status: "PENDING";如果 Didit 端查询失败,则返回 400 和代码 DEPOSIT_LOOKUP_FAILED。两种情况下证明均保持开启,Didit 会继续检查。 如果在看到有效充值之前测试窗口已过期,将返回 410。 提交 txid 后,后台任务每五分钟重新检查一次待处理的充值,并在交易确认后完成证明,因此客户无需重新提交 txid。 当您传入 satoshi_deposit_address 时,小部件会话自身的 expires_at 会延长至至少 24 小时的 Satoshi 测试窗口,以便充值有时间完成确认,避免会话先于充值过期。

流程

1

创建小组件会话

调用 POST /v3/travel-rule/widget-session/,并传入需要验证的钱包。您可以选择将其关联到一笔转账,这样在钱包所有权得到证明后,该转账会自动推进。
2

打开返回的 URL

将客户引导至响应中的 url。客户在该页面完成证明,无需 Didit 账户或 API 密钥,URL 中的令牌即为身份认证凭据。
3

检测完成情况

证明验证通过后,小组件会将地址簿条目标记为已验证;如果会话关联了转账,还会推进该转账。请关注 travel_rule.status.updated 事件(针对关联转账),或轮询小组件上下文。

创建小组件会话

本示例将会话关联到 Travel Rule 指南中声明的自托管转账,因此 wallet_address 即为该转账的目标钱包。 关联了转账的会话只接受该转账交易对手钱包的证明。
请始终原样打开响应中返回的 url,切勿自行构造。

打开返回的 URL

本版本中小组件仅支持网页端。请在系统浏览器或自定义标签页中打开 url,切勿在 Didit 移动端 SDK 的 WebView 中打开。消息签名适用于客户浏览器中已安装的钱包,小组件通过 EIP-6963 和 Wallet Standard 协议发现这些钱包。 目前不支持配对独立的移动钱包应用(例如通过二维码配对),因此小组件不会跳转至其他应用。 应用内 WebView(例如 Didit Web/Flutter/React Native/iOS/Android SDK 的 WebView)无法访问客户浏览器中的钱包,因此在其中打开的小组件会使客户无法完成签名。在移动端,请使用操作系统浏览器(SFSafariViewController / Chrome Custom Tabs,或默认浏览器)打开 url,而不要在 WebView 中渲染。在网页端,普通标签页或弹出窗口均可。

检测完成情况

小组件提供一个以令牌为键的公开只读接口。您可以轮询该接口查看进度,或在会话关联转账时依赖 Webhook:
  • completed_at 在证明验证通过后变为非空值。
  • proofs 中的每一项都带有其方法所需的字段:SATOSHI_TEST 证明会额外返回 deposit_address、expected_amount 及其自身的 expires_at;MESSAGE_SIGNING 证明会额外返回 challenge,即客户需要签名的字符串。
  • SATOSHI_TEST 证明在其存款已在链上检测到但尚未确认时,可能处于 status: "PENDING",此时您和客户均无需采取任何操作。详见上文的 Satoshi 测试验证合约。
  • 创建会话时若带有 transaction_id,证明验证通过后将推进关联的转账;在生产环境的应用中,还会触发 travel_rule.status.updated Webhook。 建议优先使用 Webhook 而非轮询。 入站 TRP 询问在批准结果回传给发送方并送达后,将转为 COMPLETED。 其他处于 UNCONFIRMED_OWNERSHIP 的转账(或处于 ON_HOLD 的入站转账)会转为 COMPLETED;若收款人姓名与钱包持有人不匹配,则转为 COUNTERPARTY_MISMATCHED_DATA;已结算的 sunrise 存款完成后会继续转为 FINISHED。 处于 COUNTERPARTY_VASP_NOT_FOUND 的出站转账会转为 COMPLETED。
  • SCREENSHOT 证明在此场景下即使您确认了所有权,仍保持 status: "PENDING"。 您需通过 POST .../travel-rule/ownership/ 批准该证明,该接口仅接受处于等待所有权确认状态的转账。 因此,未关联转账的会话,或关联了处于 COUNTERPARTY_VASP_NOT_FOUND 的出站转账的会话,都无法批准截图证明。如果这些会话不应提供该方式,请关闭 allow_screenshot_proof。
  • 证明被拒绝后,只要仍有剩余次数,会话即可再次尝试。max_attempts、attempts_used 和 attempts_remaining 反映尝试次数,被拒绝的证明会携带 rejection_reason。当 attempts_remaining 为 0 时,再次提交证明将返回 409,此时您需要创建新会话。
  • 对于未知令牌,上下文接口返回 404;会话过期且未完成后,返回 410。
这里不存在一次性依赖:小组件与您的后端最终会收敛到同一份持久状态(已验证的地址簿条目和转账状态)。因此,无论 Webhook 丢失还是标签页被关闭,都可以通过重新读取转账或小组件上下文来恢复。

本地化与品牌定制

该组件以 54 种语言 呈现,语言随链接中的语言路径决定(未指定时使用浏览器默认语言)。 为您的应用启用白标后,该组件会自动继承您的验证流程品牌设置:Logo、品牌色、按钮和面板样式、自定义字体、favicon,以及标题中的应用公开名称。 无需单独配置,您为 KYC 会话设置的定制同样适用于此处。 用户返回已完成的链接时,会再次看到完成页面;如果您传递了 callback_url,组件会将用户带回该地址。 已过期的链接会显示带品牌标识的过期页面,提示用户申请新链接。请为其调用 POST /v3/travel-rule/widget-session/ 创建新会话:使用 action: "resend" 重新发送转账并不会创建会话。

后续步骤

Travel Rule

完整的交换生命周期、渠道、设置以及接收流程。

钱包地址簿

登记您控制的钱包,以便入站转账与这些钱包匹配。

Webhook

订阅 travel_rule.status.updated,以便在证明促使转账进入下一阶段时作出响应。

原生 SDK

请使用系统浏览器打开组件 URL,而不是 SDK 的 webview。
最后修改于 2026年11月7日