Skip to content

feat: CCH multi-asset swap#1257

Draft
doitian wants to merge 6 commits intonervosnetwork:developfrom
doitian:feat/cch-multi-asset-swap
Draft

feat: CCH multi-asset swap#1257
doitian wants to merge 6 commits intonervosnetwork:developfrom
doitian:feat/cch-multi-asset-swap

Conversation

@doitian
Copy link
Copy Markdown
Member

@doitian doitian commented Apr 8, 2026

Summary

This PR tracks CCH multi-asset swap work: a protocol specification plus the implementation that follows it.

Current branch state: the spec only (docs/specs/cch-multi-asset-swap.md). Implementation commits will be added here before merge.

Specification (done on branch)

  • Scope: HTLC flow unchanged; Fiber leg covers native CKB (shannons) and UDTs with type script; Lightning remains BTC-denominated.
  • Economics: swap rate from invoice pair + hub fees (BTC-side fee basis); no hard-coded 1:1 wrapped BTC mapping.
  • Hub policy: asset allowlist and per-UDT decimals/metadata.
  • Swap acceptor: WebSocket JSON-RPC subscription (subscribe_swap_proposals / respond_swap_proposal) with binary accept/reject only, configurable timeout, and recommended explicit RPC errors on reject/timeout.
  • Cross-links to docs/specs/payment-invoice.md and docs/specs/cch-expiry-dependency.md.

Implementation (planned)

To be added in follow-up commits on this branch, aligned with the spec—for example:

  • Generalize CCH config and actor beyond a single wrapped-BTC UDT; native CKB and allowlisted UDTs.
  • RPC: swap-acceptor subscription + response methods; order/API types as needed.
  • Tests and RPC docs updates.

@doitian doitian added this to Kanban Apr 8, 2026
@doitian doitian changed the title docs: add CCH multi-asset swap specification feat: CCH multi-asset swap Apr 8, 2026
@doitian doitian force-pushed the feat/cch-multi-asset-swap branch from d9ced30 to 75583f0 Compare April 21, 2026 03:41
This document specifies cross-chain hub behavior for atomic swaps
between Bitcoin on Lightning and arbitrary Fiber assets (native CKB or
UDTs).
@doitian doitian force-pushed the feat/cch-multi-asset-swap branch from 75583f0 to f55b11f Compare April 21, 2026 04:35
ian added 5 commits April 21, 2026 15:08
Step 1 of the cch-multi-asset-swap spec: drop the BTC-centric
`wrapped_btc_type_script[_args]` config fields in favor of a generic
`fiber_asset_allowlist` plus a `fixed_rate_assets` table. This is the
config-layer foundation for accepting swaps against arbitrary Fiber
assets (native CKB or any allowlisted UDT) instead of a single
hard-coded wrapped-BTC UDT.

- Introduce `CchAsset` (`Option<Script>`, where `None` = native CKB) and
  `FixedRateAsset { fiber_asset, sats_per_smallest_unit }` in
  `cch::config`, re-exported from `cch::mod`.
- `validate_standalone` now requires a non-empty allowlist; UDT type
  scripts are declared inline so no separate JSON-string parsing step
  is needed.
- Update the deployer yaml to declare the SimpleUDT entry with a zero
  `code_hash` placeholder; `tests/deploy/udt-init` recursively patches
  every cch `code_hash` placeholder to the real deployed
  SIMPLE_UDT data hash, so all CCH-enabled nodes (in-process and
  standalone) get a uniformly populated config.

Call sites in `cch/actor.rs`, `fiber-types::CchOrder`, the json-types
mirror, and the cch tests still reference the removed fields and will
be updated in Step 2 along with the order-type refactor; the tree
intentionally does not compile between this commit and Step 2.
Rename and extend the persisted CchOrder so a single record can describe
a swap between BTC and any allowlisted Fiber asset (native CKB or any
UDT), not just wrapped BTC.

Field changes:
  wrapped_btc_type_script: Script   -> fiber_type_script: Option<Script>
  amount_sats: u128                 -> btc_amount_msat: u128
  fee_sats: u128                    -> btc_fee_msat: u128
  (new)                             -> fiber_amount_smallest_unit: u128

The BTC leg is now denominated in millisatoshi (1 sat = 1000 msat) so
fee/exchange-rate math is rounding-free; the Fiber leg uses the smallest
unit of the target asset (shannon for native CKB, the UDT's smallest
denomination otherwise). `fiber_type_script = None` denotes native CKB.

Bincode migration mig_20260421_cch_multi_asset rewrites every existing
order at prefix 232: legacy single-asset records were 1:1 sat-to-UDT
smallest-unit, so fiber_amount_smallest_unit is set to the old
amount_sats and BTC amounts are scaled by 1000.

The fiber-lib tree intentionally does not compile after this commit;
call sites and tests are updated in the next commit.
Mechanically rewrites the CCH actor and JSON-types to use the new
CchOrder fields (btc_amount_msat, btc_fee_msat, fiber_amount_smallest_unit,
fiber_type_script) introduced in the previous commit. Behaviour is
unchanged: per-request asset selection, allowlist enforcement, and
fixed-rate computation are deferred to a follow-up; the actor uses a
placeholder asset resolver that returns the first allowlist entry.

- actor.rs: send_btc/receive_btc fee math now in msat throughout
- json-types: CchOrderResponse mirrors the new on-disk shape
- tests: update CchOrder/CchConfig literals to new fields; harness
  injects a default allowlist entry; rewrite the two fee-assertion
  tests to use msat-based expectations
- regenerate store schema
Step 3a of the multi-asset CCH refactor. Replaces the placeholder
single-asset resolver with real per-request asset selection:

- SendBTC / SendBTCParams gain a fiber_type_script: Option<Script>
  parameter (None = native CKB). The hub validates it against the
  configured fiber_asset_allowlist before creating the order, and the
  proxy Fiber invoice omits the UdtScript attribute for native CKB.
- ReceiveBTC reads the asset directly from the submitted Fiber invoice
  (UdtScript attribute, or None for native CKB) and validates it
  against the same allowlist.
- Replace CchError::WrappedBTCTypescriptMismatch with
  FiberAssetNotAllowlisted; update the existing rejection test and
  add coverage for (a) send_btc rejecting a non-allowlisted UDT and
  (b) send_btc accepting native CKB end-to-end when allowlisted.

Per-asset fixed-rate computation is still TODO (Step 3b); fee math
remains in msat with the current 1 sat \u2194 1 UDT smallest unit shortcut.
Replace the legacy hard-coded 1:1 sat-to-smallest-unit conversion with a
lookup against the configured `fixed_rate_assets` table, so the CCH can
quote orders for any allowlisted Fiber asset whose fixed rate is
published in config. Send/receive amounts are derived from the configured
`smallest_units_per_sat` (renamed from `sats_per_smallest_unit` to
match its actual semantics): on send_btc the Fiber-leg amount is
`btc_amount_msat * rate / 1000`, on receive_btc the BTC-leg is
`fiber * 1000 / rate` plus the BTC-denominated hub fee. Allowlisted
assets without a fixed-rate entry are rejected with the new
`NoFixedRateForAsset` error in lieu of the not-yet-implemented
proposal-driven path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant