Skip to main content

System Architecture

End-to-end view of how Bitcoin, the SPV Relayer, the four Soroban contracts, and the browser interact. Writz System Architecture Key layers:
  • Bitcoin — P2WSH locks collateral; two spending paths (cooperative co-sign or CLTV timelock)
  • SPV Relayer — watches Bitcoin, produces Merkle inclusion proofs on demand
  • Soroban contractsbitcoin-spv, zk-verifier, commitment-tree, private-lend verify proofs and manage positions
  • Browser — generates all ZK proofs locally; private witness values never leave the device

Deposit Flow

Step-by-step path from connecting a Bitcoin wallet to having an active position on Stellar. Deposit Flow
  1. Connect Bitcoin wallet (Xverse) and Stellar wallet (Freighter)
  2. Derive unique P2WSH address from protocol key + user key + timelock height
  3. Send BTC to that address on-chain
  4. Relayer produces SPV proof (block headers + Merkle path)
  5. Browser generates Groth16 ZK proof binding commitment to the Bitcoin txid
  6. commitment-tree.deposit() verifies SPV proof + ZK proof on Soroban
  7. Admin calls insert_commitment() — position becomes active

Borrow & Repay Flow

How the protocol updates the Merkle commitment on every borrow or repay, preserving privacy throughout. Borrow and Repay Flow
  • Borrow: delta = amount_stroops, is_borrow = 1
  • Repay: delta = (FIELD_PRIME − amount) mod FIELD_PRIME, is_borrow = 0
  • The nonce rotates on every action; the commitment Poseidon(collateral, debt, secret, nonce) is replaced in the tree

BTC Release Flow (Path A)

Cooperative co-signed release after full repayment. BTC Release Flow
  • The server (/api/cosign) verifies the commitment is no longer pending before signing
  • PROTOCOL_SIGNING_KEY is server-only — never exposed to the browser
  • Final witness: [user_sig, protocol_sig, 0x01, redeemScript]

ZK Circuits

All three Groth16 circuits (Circom / BN254), their private inputs, public inputs, and public outputs. ZK Circuits
CircuitPurpose
deposit.circomBinds a Poseidon commitment to a Bitcoin txid
borrow_repay.circomProves Merkle inclusion + valid collateral ratio after state change
liquidation.circomProves position is under-collateralized

Commitment State Machine

Complete lifecycle of a position from pending to BTC release (or liquidation). Commitment State Machine
StateDescription
Pendingdeposit() verified, waiting for insert_commitment()
Active · debt=0Commitment in Merkle tree, no outstanding debt
Active · debt>0USDC borrowed; nonce rotates on every partial repay
ClosedFull repayment done; old nullifier spent
ReleasedPath A PSBT finalized; BTC returned on Bitcoin
LiquidatedRatio below 120%; keeper repaid debt

Soroban Contract Interactions

How the four live testnet contracts call each other. Contract Interactions
ContractRole
bitcoin-spvVerifies Bitcoin SPV proofs (block headers + Merkle path)
zk-verifierGroth16 verification via Protocol X-Ray host functions
commitment-treeMerkle tree of commitments; orchestrates all flows
private-lendUSDC liquidity pool; lender deposits + borrower drawdowns

Regenerating Diagrams

pip3 install graphviz
python3 scripts/diagrams/render-all.py
Output: docs/diagrams/output/*.svg and *.png