Skip to content

Instantly share code, notes, and snippets.

@jonaprieto
Created February 16, 2026 14:39
Show Gist options
  • Select an option

  • Save jonaprieto/3881b2af8c6c3e84de9d291b4707f9ee to your computer and use it in GitHub Desktop.

Select an option

Save jonaprieto/3881b2af8c6c3e84de9d291b4707f9ee to your computer and use it in GitHub Desktop.
Swap Settlement: Current Implementation (two-party signing, server-orchestrated)

Swap Settlement: Current Implementation

Variant: Two-party signing, server-orchestrated single action

Diagram

sequenceDiagram
    participant M as Maker
    participant S as Server
    participant T as Taker

    T->>S: POST /match/:id/initiate (taker NK + counter-resource)
    S-->>T: match_id (status: WaitingForMaker)

    M->>S: POST /match/:id/maker-respond (maker NK)
    Note over S: Computes action_tree_root<br/>from both NKs
    S-->>M: action_tree_root

    M->>S: POST /match/:id/sign (maker signature)
    T->>S: POST /match/:id/sign (taker signature)

    Note over S: Assembles IntentSettlementRequest<br/>Generates ZK proofs (Bonsai)<br/>Submits transaction on-chain

    S-->>M: status: Completed
    S-->>T: status: Completed
Loading

Action tree structure

The swap is a single Anoma action with 2 consumed and 2 created resources:

Action tree = [nf_a, cm_b, nf_b, cm_a]
               ───────────  ───────────
               pair 0       pair 1

nf_a = nullifier of maker's resource    (consumes it)
cm_b = commitment for taker             (maker's tokens → taker)
nf_b = nullifier of taker's resource    (consumes it)
cm_a = commitment for maker             (taker's tokens → maker)

One action tree root. Both parties sign it. Server collects signatures, generates proofs, submits.

Proofs generated

Proof Count Purpose
Compliance 2 One per consumed/created pair — proves resource validity
Logic (consumed) 2 Proves authorization to consume each resource (verifies auth signature inside circuit)
Logic (created) 2 Proves created resources satisfy transfer logic
Delta 1 Proves value conservation (no tokens created from nothing)
Aggregation 1 Combines all proofs into one verifiable transaction
Total 8

Pros

  • Simple: one action, one root, one transaction — minimal protocol rounds
  • Atomic: both sides of the swap settle in a single on-chain transaction — no partial settlement possible
  • Minimal trust surface: server never holds signing keys; signatures are verified inside the ZK circuit, not by the server
  • No operator key management: server has no key to protect, rotate, or back up
  • Permissionless in principle: anyone could run the orchestrator since it adds no cryptographic material

Cons

  • Blind signing: parties sign a root computed by the server without being able to independently verify it (neither has the other's NK to recompute)
  • Server can manipulate: a compromised server could compute a different action tree root (e.g., one that sends maker's tokens to an attacker address) and parties would sign it unknowingly
  • No censorship resistance: server can silently drop matches or refuse to generate proofs — no cryptographic evidence of misbehavior
  • No accountability: since the server doesn't sign, there's no on-chain proof that the server authorized or participated in a settlement
  • Single point of failure: if the server goes down, no settlements proceed — parties can't complete the protocol peer-to-peer
  • NK exposure to server: both parties reveal their nullifier keys to the server, which must be trusted not to front-run or leak them
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment