Architecture
High-level overview of how Senddy works under the hood.
System Overview
Senddy is a privacy-preserving payment system built on zero-knowledge proofs, smart contracts, and a trusted execution environment. Here's how the pieces fit together.
Components
Client (Browser/Mobile)
The user's device handles:
- Key derivation — Senddy keys are derived from an EIP-712 signature, no seed phrase needed
- Note management — Tracking which private "notes" belong to you via the sync engine
- Proof generation — Zero-knowledge proofs are generated client-side in 2-5 seconds using WebAssembly
- Memo encryption — Encrypted using X25519 ECDH + XChaCha20-Poly1305
Smart Contracts (Base)
The on-chain contracts include:
- Pool Contract — The main contract that holds all funds and processes deposits, shields, spends, and withdrawals
- Verifier Contracts — Verify zero-knowledge proofs for shield and spend operations
- Yield Strategy — Manages yield generation by deploying funds to trusted DeFi lending protocols
Attestor Service
The attestor verifies ZK proofs off-chain in a hardware-isolated trusted execution environment (TEE):
- Runs in a secure enclave — isolated, tamper-proof, no persistent storage
- Verifies proofs using the UltraHonk verifier
- Signs attestations via a hardware security module (HSM) — the signing key never leaves the enclave
Data Indexer
Indexes on-chain events for efficient querying:
- Commitments, nullifiers, deposits, withdrawals
- Pool state and asset statistics
- Daily aggregated data
Relayer Network
Enables gasless transactions:
- Users never need ETH for gas
- Transaction fees are embedded in the ZK circuit
- Relayed via a third-party relayer network for reliable execution
Transaction Flow
Deposit and Shield
- User deposits USDC into the pool contract (public transaction)
- Client generates a shield proof — proves the deposit converts to valid private notes
- Attestor verifies the proof in the secure enclave
- Attestor signs an attestation
- The shield transaction is submitted on-chain with the attestation
- Private notes (commitments) are added to the Merkle tree
Private Transfer (Spend)
- Client selects notes to spend and constructs new output notes
- Client generates a spend proof — proves:
- The input notes exist in the Merkle tree
- The user knows the secret keys for those notes
- The input and output values balance (conservation)
- The nullifiers are correctly derived
- Attestor verifies the proof and signs an attestation
- The spend transaction is submitted on-chain
- Input note nullifiers are recorded (preventing double-spend)
- New output note commitments are added to the Merkle tree
Withdrawal
Same as a spend, but one of the output notes is a "withdrawal" that sends USDC to a public Ethereum address.
Key Design Decisions
- Universal setup — Our proving system uses a universal trusted setup, meaning the same setup ceremony works for any circuit. No per-circuit trusted setup required, and the system can be upgraded without new ceremonies.
- Attestation-based verification — Proofs are verified off-chain in a TEE rather than on-chain, reducing gas costs dramatically
- UTXO model — Like Bitcoin/Zcash, not account-based. Each "note" is a discrete value that can be spent atomically
- Client-side proving — Proofs are generated on the user's device, so no server ever sees transaction details
- Gasless transactions — Fees are embedded in the ZK circuit and paid from the user's private balance