Skip to main content
Cloak is a UTXO privacy system on Solana with five active runtime surfaces:
  • Web app wallet UX, encrypted local cache, and scan/export flows
  • SDK proof generation, transaction orchestration, and chain-note scan/decrypt
  • Relay API for submit/status/viewing-key registration and chain indexing
  • Shield Pool on-chain proof verifier + state machine
  • Circuit layer constraints (2-in/2-out transaction circuit)

End-to-end flow

Core transaction model

  • The canonical path is UTXO transact / transact_swap (2 inputs, 2 outputs, tree height 32).
  • Public inputs are 264 bytes: root[32] + publicAmount[8] + extDataHash[32] + mint[32] + nullifiers[64] + commitments[64] + chainNoteHash[32].
  • publicAmount meaning:
    • > 0: deposit into pool
    • < 0: withdrawal from pool
    • = 0: shield-to-shield transfer
  • The same proof/public-input shape is consumed by relay and on-chain program.

Fee model (gross, fee, net)

  • Fixed fee: 5_000_000 lamports
  • Variable fee: gross * 3 / 1000
  • Total fee: fixed + variable
  • Net recipient amount: gross - fee
  • Minimum deposit: 10_000_000 lamports
These constants are aligned across program, relay, and SDK.

On-chain state

Shield Pool maintains:
  • Merkle tree (MERKLE_TREE_HEIGHT = 32)
  • Root history ring (ROOT_HISTORY_SIZE = 100)
  • Nullifier PDAs (["nullifier", nullifier_hash]) for spent checks
  • Pool PDA (["pool"]) and Treasury PDA (["treasury"])
  • SwapState PDA (["swap_state", pool_pubkey, nullifier]) for two-phase swaps

Relay responsibilities

  • Accept submit requests (/transact, /transact_swap, legacy /withdraw)
  • Validate payload size/shape and queue status tracking (/status/:id)
  • Provide chain-index data (/commitments, /merkle-root)
  • Run background commitment sync into Postgres for fast Merkle reconstruction
  • Verify and store viewing keys (/viewing-key/register)
  • Offer admin compliance endpoints (/admin/compliance/*)
GET /risk-quote intentionally returns 501 in relay; deposits that require risk oracle quotes must use an external quote service or getRiskQuoteInstruction in SDK options.

Viewing keys and history scanning

  • Viewing-key registration is required for normal SDK/web flows before transact/deposit/withdraw/swap.
  • User signs a fixed sign-in message; relay verifies signature and stores the 32-byte viewing key with an identifier hash.
  • Scanner path is chain-native: SDK reads program transactions from RPC, decrypts compact chain notes with nk, verifies chainNoteHash integrity, and computes running balance/fees.
  • Web history uses encrypted local cache (cloak_compliance_*) and supports explicit Clear cache & rescan.

Program IDs

Current deployment program ID:
  • c1oak6tetxYnNfvXKFkpn1d98FxtK7B68vBQLYQpWKp (default)
If you deploy a local/dev build with a different address, pass that programId explicitly to SDK/web.