SenddySenddy Docs

Transaction Flow

End-to-end lifecycle of a private transaction in Senddy.

Overview

A private transaction in Senddy goes through six phases: note selection, proof generation, attestation, relay, on-chain execution, and sync. The diagram below shows the full flow.

Phase Breakdown

1. Note Selection

When the user initiates a send, the app fetches all unspent notes from local storage (IndexedDB). Notes are sorted by value and selected greedily — largest first — to cover the target amount. If the selected notes exceed the amount, a change note is created for the remainder.

For each selected note, the app fetches the current commitment tree from the subgraph and builds a Merkle path proving membership.

2. Proof Generation

The app generates a zero-knowledge proof using a Noir circuit compiled with UltraHonk. The proof attests to:

  • Ownership — the sender knows the secret key for each input note
  • Existence — each input note's commitment exists in the on-chain Merkle tree
  • Conservation — the sum of inputs equals the sum of outputs (no value created or destroyed)
  • Correctness — nullifiers and output commitments are correctly derived

The circuit supports up to 3 inputs (spend3) or 9 inputs (spend9) for note consolidation.

3. Attestation

The proof is sent to the attestor — a trusted enclave that verifies compliance requirements and signs the transaction. The attestor's signature is required by the pool contract before accepting any spend.

4. On-chain Execution

The signed transaction is submitted through Gelato Relay, so the user never needs to hold ETH for gas. The relay calls the pool contract, which:

  1. Verifies the ZK proof
  2. Checks the attestor signature
  3. Records each nullifier (preventing double-spend)
  4. Appends new output commitments to the Merkle tree

5. Sync

After the transaction is confirmed, the sync engine detects the new on-chain events via the subgraph. Both the sender and recipient's clients:

  • Fetch new commitments and nullifiers
  • Attempt to decrypt attached memos using their view keys
  • Store any decrypted notes locally and update balances

On this page