跳到主要内容

结算与接入

状态:规范(LP 协议 v1,2026-09-23 草案)。

链上模型​

RFQ swap 使用 Canton Token Standard allocation 工作流(CIP-0056)结算,与 Rocky 现货结算器 allocate-and-execute 路径所用原语相同。每一方把自己那条腿锁进一个以 Rocky 操作员 party 为 executor 的 Allocation。执行 registry 的 allocation 需要 executor、sender 和 receiver 三方授权,因此这一笔结算交易包在双方的 MemberAuth 合约里(rocky-clob-v8 ≥ 0.7.0,Auth_OpenAllocations → Auth_RunAllocationsWith):交易者钱包与 LP 都只在启用/接入时签一次 MemberAuth,与订单簿结算完全相同。没有 Rocky 专有的托管合约。

Choice签名方时机效果
AllocationFactory_Allocate交易者(钱包)POST /v1/swaps/rfq 之后锁定输入金额(receiver:LP party)与 taker 费(receiver:Rocky 手续费 party)
AllocationFactory_AllocateLP在 accept-and-allocate 中锁定输出金额(receiver:交易者 party),以及非零时的 maker 费
MemberAuth Auth_OpenAllocations → 对每一腿 Allocation_ExecuteTransferRocky 操作员,借双方 MemberAuth双方核验通过后在一笔 Canton 交易中原子转移全部腿
MemberAuth Auth_CancelAllocations → Allocation_CancelRocky 操作员,借发送方 MemberAuth任一终态失败时在 settleBefore 前释放该成员已锁定的 allocation
Allocation_Withdraw发送方(交易者或 LP)settleBefore 之后仍锁定时发送方无需 Rocky 即可释放自己的 allocation

同一笔 swap 的所有 allocation 共享同一个 SettlementInfo:

executor = Rocky 操作员 party
settlementRef = { id: <swapId>, cid: None }
requestedAt = swap 创建时间
allocateBefore = requestedAt + 60 s
settleBefore = requestedAt + 120 s
meta.values = { "rocky.swapId": <swapId>, "rocky.symbol": <symbol> }

settlementRef.id = swapId 把链上交易与你看到的这笔交易绑定,正如订单簿成交用 settlementRef.id = tradeId 一样。Rocky 在推进前会在账本上核验每个 allocation:资产、数量、发送方、收款方、executor 与完整的 SettlementInfo 必须与冻结的 swap 一致。Rocky 绝不会修改金额来迁就一笔 swap。

资产需通过其 registry 支持 Token Standard allocation(Canton Coin 与 Rocky 上线的 CC 封装资产都支持)。这条路径不需要收款方预授权。

失败处理​

失败由谁发现交易者输入LP 输出
交易者始终未 allocateallocateBefore 到期未锁—
交易者 allocation 不匹配Rocky 核验executor Allocation_Cancel;钱包也可在 settleBefore 后 Allocation_Withdraw—
LP 拒绝 / 超时accept-and-allocateexecutor 取消—
LP allocation 不匹配或迟到Rocky 核验 / allocateBeforeexecutor 取消executor 取消;LP 可在 settleBefore 后撤回
结算瞬时错误executor在 settleBefore 内重试期间保持锁定同左
结算终态错误executorexecutor 取消;settleBefore 后可撤回同左
swap 中途 Rocky 不可用—settleBefore 后可撤回settleBefore 后可撤回

窗口刻意设得很短,一笔卡住的 swap 锁定资金不会超过两分钟。由于执行是一笔交易,不存在一方已付、另一方未付的状态。

在 Canton 上核验一笔 swap​

  1. 从 GET /v1/lp/trades/{swapId}(LP)或 GET /v1/swaps/rfq/{swapId}(交易者)取 swapId 与 cantonUpdateId。
  2. 在托管你 party 的 participant 或 Canton Scan 中打开该 update。
  3. 交易根节点是某个 MemberAuth 上的 Auth_OpenAllocations(内嵌 Auth_RunAllocationsWith),其中每腿一个 Allocation_ExecuteTransfer(两条交易腿加一到两条手续费腿),别无其他;每个 exercise 的 settlementRef.id 等于 swapId,executor 等于 Rocky 操作员 party。
  4. 金额与交易对象的 legs 块一致。

SUCCEEDED 的 swap 也会纳入下一次 epoch 承诺;GET /v1/chain/proof?ref_id=<swapId> 返回其包含证明。

接入​

商务条款、交易对、规模与支持渠道记录在集成包中。技术步骤:

步骤你Rocky
1. Party提供将持有库存的 Canton party id 及其 validator/钱包类型把账户绑定到该 party(机构接入 §2)
2. API key登记 Ed25519 公钥(通过第二渠道复读指纹)以 ext-mm 限流档位登记该 key
2b. MemberAuth为你的 party 完成一次 MemberAuth(机构接入 §4);它只授权 Rocky 执行 executor 为 Rocky、腿在你与交易者之间的 allocation在向你路由第一笔询价前核实该合约存在
3. 服务提供 serviceUrl、出口 IP、TLS 细节(以及 mTLS 客户端证书要求,如有)登记 LP,向你发布 Rocky 签名密钥指纹
4. 交易对列出交易对及 minBaseQty / maxBaseQty配置广播;maxBaseQty 限制单笔 swap 上限
5. 测试保持服务在线,由 Rocky 发起测试 swap以 TESTING 状态登记你:只有 Rocky 的测试交易者、小额、在主网上询价,并跑下方上线清单
6. 上线确认清单中的人工项切换为 ACTIVE,公开询价开始到达

没有单独的测试网络:Rocky 上线的资产都在 Canton 主网上,因此上线测试在主网以 TESTING 状态、小额(通常每笔 0.00001 CBTC)进行。Rocky 把你切到 ACTIVE 之前,公众的询价不会到达你。

参考 LP 服务(签名校验、报价构造、经你的 JSON Ledger API 创建 allocation)见 Rocky API Maker Bot 仓库的 python/rocky_spot/rfq_lp.py 与 python/examples/rfq_lp.py。

服务水平​

Rocky 按 LP 度量:报价应答率与 p95 延迟、接受率、不匹配率、结算成功率。DEGRADED 健康状态(连续三次探测失败)会自动把你移出广播。其余指标用于 fanOutShare:近一小时接受率低于 80% 或不匹配率高于 1% 的 LP 会收到较少的询价,直至指标恢复。v1 中 fanOutShare 由 Rocky 运营复核后调整,尚未自动化。阈值发布在集成包中,只会在提前通知后收紧。

上线检查清单​

  • GET /health 在 500 ms 内返回你的生产 party 与交易对。
  • 30 分钟沙盒运行中报价 p95 在报价超时以内到达。
  • 连续十笔测试 swap 结算成功;每个 cantonUpdateId 按上述形状核验。
  • 一次强制拒绝返回 409 REJECTED,交易者的 allocation 被释放。
  • 一次强制超时在 GET /v1/lp/trades/{swapId} 显示 LP_ACCEPT_FAILED,你这边没有悬空的 allocation。
  • POST /v1/lp/pause 一秒内把你移出广播;resume 恢复。
  • 你的 validator 流量余额监控已就位(Canton 流量)。

RFQ swap 不是什么​

  • 不是订单簿成交:没有 @trade 打印,不影响 K 线或行情,不计入订单簿成交量的现货排行。
  • 不是托管:Rocky 在任何时刻都不持有任何一方的资产。
  • 不做净额:每笔 swap 是独立的一笔交易,双方都按笔承担 Canton 流量。