DOME Docs

Architecture

Contracts, circuits, indexer, and relayer in the Dome stack.

High-level flow

User wallet  →  deposit (proof + ETH)  →  EtherPool on Base

         Indexer scans events  →  wallet decrypts notes

User wallet  →  withdraw proof  →  Relayer  →  EtherPool  →  recipient

On-chain

Deposits and withdrawals both call transact() on the pool. The contract verifies Groth16 proofs, updates the Merkle tree, and records nullifiers to prevent double-spends.

Notes are Poseidon-hashed and committed without revealing plaintext on-chain. Encrypted note payloads are emitted in events for clients that hold the viewing key.

Off-chain services

Indexer (@dome/backend)

  • Scans NewCommitment logs from the deployment block
  • Serves Merkle paths, encrypted outputs, and pool config
  • Persists state in SQLite (local) or Postgres (testnet/production)

Relayer

  • Accepts signed withdraw payloads from clients
  • Pays gas and submits transact() on behalf of users
  • Protected with DOME_RELAYER_SECRET on public deployments

Circuits

PrimitiveUsage
Groth16Deposit and withdraw proofs
PoseidonNote commitments and Merkle tree
26 levelsMerkle depth (~67M leaves)

Circuit artifacts are hosted for browser proving; SDK env DOME_CIRCUIT_KEY_BASE_PATH points at the WASM/zkey base URL.

Client stack

  • @dome/sdk-evm — Deposit, sync, withdraw in Node or bundlers
  • dome-web / dome-mobile — Wallets using the SDK + hosted backend

On this page