Appearance
Veilix’s Approach
Veilix is built so a deposit and a later withdrawal do not share a signer, and so the proof does not name the deposit. The user keeps a secret note. The chain keeps a commitment. A zero-knowledge proof spends the note later, and a relayer submits that proof. That removes the explicit on-chain pointer. The anonymity set, timing, user behavior, network metadata, amount patterns, relayer behavior, and other factors remain.
Design choices
| Choice | What it means |
|---|---|
| Non-custodial | The program releases funds only for a valid proof. The spending key is inside the user’s note. |
| Any amount | A note holds whatever you deposit, up to that asset’s cap. You can withdraw part of it. |
| One tree per asset | SOL, VEILIX, USDC, wBTC, and wETH each have a single shared tree. Every note of that asset is in the same set. |
| Client-side proofs | The secret never needs to leave the device that builds the proof. |
| Relayed withdrawals | The relayer signs the withdrawal. The recipient does not. |
| Split fee | A withdrawal pays a relayer fee and a platform fee. Both are taken from the withdrawn amount. The recipient receives the remainder. |
| Optional note backup | The note can be sealed on-chain under a key derived from the wallet, so the same wallet can find it later. |
How the link is broken
A deposit and a withdrawal are both ordinary Solana transactions, but they do not share a signer, and the proof does not name the deposit.
Commitments. A deposit creates a note: an amount, a spending key, and a random blinding factor. Those values are hashed into a commitment. The commitment is appended to the asset’s Merkle tree. The amount that entered the treasury is public. The spending key is not.
Proofs. To spend, the user proves knowledge of a note whose commitment sits in the tree, and proves that the public outputs (recipient, fee, change commitment) match that note. The verifier learns that some note in the tree was spent. It does not learn which leaf.
Nullifiers. Spending publishes a nullifier derived from the note and its position in the tree. The program stores that nullifier. A second spend of the same note fails. Observers see that a nullifier was used. They do not see which commitment produced it.
Change. If the withdrawal is smaller than the note, the proof inserts a new commitment for the remainder. That change note is a new secret. It stays in the pool until it is spent. The public payment does not have to equal the original deposit.
Variable amounts and the anonymity set
Amount randomization is designed to reduce deterministic amount-based correlation. Privacy is not automatic. It depends on the anonymity set, timing, user behavior, network metadata, asset denomination and amount patterns, relayer behavior, and other factors.
In a fixed-denomination pool, every note is the same size, so the amount itself is a shared label. Veilix uses variable amounts instead. Notes in one asset tree can have different amounts. That is more flexible, and it changes what an observer can try:
- The cryptographic proof still hides which note was spent. The public amounts stay visible.
- A distinctive amount can still narrow the candidates. A deposit of 7.3491 SOL followed by a withdrawal of 7.3491 SOL is easy to pair, because almost no other note has that size.
- Withdrawing a different amount, or leaving a change note in the pool, is amount randomization. It is aimed at that deterministic match. The change note is itself a new member of the tree. Timing, behavior, metadata, and relayer choice still sit beside it.
- The anonymity set is the unspent notes of that same asset, not a separate crowd for each denomination. More deposits of that asset make the set larger. SOL and USDC never share a set. Set size is one of the factors above.
Veilix does not compute a privacy score.
Public balance and shielded balance
Your Solana wallet remains a normal public balance. Tokens sitting in a Veilix tree are a second balance. That shielded balance is the sum of the unspent notes you can open. The chain shows commitments and, on withdrawal, a recipient and an amount. It does not show a token account whose balance is “your Veilix holdings.”
If you seal notes with your wallet’s encryption key, the same wallet can scan the tree and reconstruct that balance. Anyone without the key sees ciphertext.
One program for every product
A note created to hold funds and a note created for Private Send are the same kind of object in the same tree. Private Send deposits, then withdraws to the recipient you named. There is no second pool and no claim transaction for the recipient.
The on-chain program id shipped with the SDK is HbatG5gpfs2g3N4gc2Qkfmmeu4zaBEVxzrDdYtWNLyyA.