Skip to content

Architecture Overview ​

Veilix is four pieces that stay in separate roles: a client that holds secrets and builds proofs, an on-chain program that holds funds and verifies proofs, a relayer that submits withdrawals, and an indexer that serves tree data and quotes.

On-chain program ​

The program is the custody boundary. Deposits move SOL or tokens into a treasury. Withdrawals move them out. Nothing in between depends on an operator co-signing.

For each asset the program keeps:

AccountRole
TreeOne Merkle tree. SOL uses the seed tree. A token uses tree plus the mint. Height 26. The latest 100 roots are accepted.
TreasuryHolds the asset. Token treasuries are associated token accounts.
Nullifier accountsOne account per spent nullifier, seeded by nullifier plus the nullifier bytes. A second spend fails.
Network stateThe configuration authority and the platform-fee wallets. Seed config.

A tree also stores maxDepositAmount. A deposit larger than that cap is rejected. The configuration authority can change the cap and can replace the fee-wallet list.

Each shielded transaction has two inputs and two outputs. Unused slots are zero-amount notes. A fresh deposit spends two empty inputs and creates one real output (the new note) plus an empty output. A full withdrawal spends one real note and creates no change. A partial withdrawal spends one real note and creates one change note.

The program emits:

  • NewCommitment for every leaf, including the encrypted output bytes
  • Deposit with the public amount that entered
  • Withdrawal with the public amount, recipient, relayer, and fee

Client ​

The user’s device:

  1. Samples the note secrets.
  2. Rebuilds the Merkle tree from indexed leaves when spending.
  3. Builds a Groth16 proof over the withdraw circuit.
  4. Either signs a deposit transaction, or hands a withdrawal payload to a relayer.

The note string and the spending key stay on the client. The payload that leaves the device is the proof plus public fields: root, nullifiers, output commitments, amount, fee, recipient, relayer, and the encrypted outputs.

Indexer ​

The indexer is how clients read the trees without walking the whole chain themselves.

ClusterBase URL
Devnethttps://api3.veilixprotocol.com

It serves the current root and leaves, checks whether a commitment or nullifier is already known, quotes a withdrawal fee, lists relayers, and accepts a queue of withdrawal proofs (POST /submit) for Private Send.

The indexer is not the source of truth for balances. The program is. A quote can go stale. A missing leaf means the client must wait until the indexer has caught up. A proof still has to match a root the program currently accepts.

Relayers ​

Relayers are separate operators. The indexer lists active ones. Each relayer advertises a reward account and a fee. The client picks one, binds that account and that fee into the proof, and the relayer signs the withdrawal. Details are in Relayer Network.

Address-risk service ​

Before a withdrawal proof is built, the client asks https://api3.veilixprotocol.com whether the recipient is flagged. A flagged recipient is refused. This check sits in front of the proof. It is described in Address Screening.

What is deliberately not a second system ​

There is no separate contract for payments. Private Send uses the same deposit and the same withdrawal. There is no swap pool. There is no fixed list of denominations.