Veilmainnet-betaOpen app →
Veil documentation

A privacy layer for everything you do on Solana

Veil gives your wallet a private balance. Shield any token into it, then send, trade, lend and withdraw without the chain linking any of it back to you. Your keys never leave your browser.

0.3%to shield
0%Veil fee on private transfers
0.3%to withdraw
—notes in the pool
Beta. Veil is in a guarded beta: deposits are capped per token, and the external audit and public key ceremony complete before caps are lifted. See Security for the current status.

How it works

Value enters through a public shield, lives as sealed notes, and leaves through a public exit. Everything in between is proven, not revealed. Tap a stage.

Visible on Solana

Phantom, Solflare or Backpack stays your public identity. It signs exactly one thing in Veil: a shield. Veil never holds or sees its private key.

The three pieces

Notes

Each note commits to a token, an amount and its owner. Only your viewing key can open it; only your spending key can spend it.

Proofs

Groth16 zero-knowledge proofs, built in your browser, convince the Veil program that balances add up and you own what you spend.

Relayers

A relayer submits your proof and pays the network fee. It can't change where funds go: the recipient and its fee are bound into the proof.

Quick start

Connect your walletPhantom, Solflare or Backpack. It stays your public entry and exit.
Create your vault and save the recovery keyA random key generated in your browser, encrypted with your passphrase. Write the recovery key down: it is the only way back if this browser is lost.
Shield a tokenOne wallet signature moves it behind the privacy wall.
Use it privatelySend to a veil1… address, trade, or lend. No wallet signatures, no public link.
WithdrawTo any address, by default a fresh one-time address only your vault controls.

Shield

Moves any registered SPL or Token-2022 token from your wallet into Veil. SOL is wrapped and unwrapped automatically. Your wallet pays the amount plus the 0.3% Veil fee and signs once; the note is sealed in your browser.

Any token can get a Veil vault: if it doesn't have one yet, anyone can open it for about 0.004 SOL of rent. Tokens with features that could put a shared vault at risk (permanent delegates, transfer hooks, pausable mints) are refused on-chain.

Crowd size matters. A token few people use is easier to trace from entry to exit. The app shows each token's crowd and warns when it's small.

Send privately

Pay any veil1… address in any token. There's no wallet signature and no Veil fee, only the relayer's network fee. When you hold private SOL, Veil pays that fee in SOL, and the transaction doesn't name the token you sent.

The recipient's app finds the payment by trying to open every new note with its viewing key, so nobody (not even the indexer) learns which notes are whose.

Trade

Swap inside your private balance through Jupiter. On-chain, Veil's vault is the trader. You set a minimum output; if the market can't meet it, nothing is traded and your input returns to your private balance automatically.

Each trade runs in two steps: your proof sets aside the input in an escrow of its own, then the route runs. The program checks the escrow paid out exactly the input and the vault received at least your minimum.

Earn

Lend from your private balance through Jupiter Lend. Your position is a private note of the market's share token (for example jlUSDC), and it grows as the share price rises with interest. Withdraw turns it back into the underlying token, privately.

Lending has its own risks: smart contracts, borrowers, and withdrawal limits when a market is busy. Veil hides who lends; it doesn't insure the market.

Withdraw & one-time addresses

Withdraw sends funds to any Solana address. By default it creates a one-time address derived from your vault, so nothing ties it to your wallet. Your recovery key restores every one of them.

Receive works the other way: give a payer a one-time address instead of your wallet. When funds land, shield them back with one tap. It's gasless: the relayer pays the network fee and takes its fee from the deposit, so even a token-only address works.

What is public, what is private

Pick an action to see exactly what the chain records and what stays sealed.

What Solana sees
  • That a private transfer happened
  • The relayer fee (in SOL when you hold private SOL)
  • How many notes were spent (1–4)
What stays private
  • Sender
  • Recipient
  • Amount
  • Which token, when the fee is paid in SOL
With no private SOL, the relayer is paid in the token itself, so that transfer shows which token moved. The app tells you before you confirm.

Good habits

  • Don't withdraw the exact amount you shielded to the same wallet right away.
  • Keep a little private SOL so transfers can hide their token.
  • Prefer tokens with a big crowd; wait a while between shielding and withdrawing.
  • Reach the relayer through a network-level privacy tool if your IP address matters to you.

Fees

Veil charges a protocol fee each time value crosses the privacy wall. The program enforces it, and no fee can ever exceed 1%. Current rates, read live from the chain:

ActionVeil feeRelayer fee
Shield0.3%, on topNone (your wallet pays the network fee)
SendNoneNetwork fee + rent for each note spent
Trade / Earn0.3% of the inputNetwork fee + rent
Withdraw0.3% of what you withdrawNetwork fee + rent (+ opening the recipient's token account if needed)

Try it

Action
Amount (any token)
Veil fee0.3% · 0.3
ResultYour wallet pays 100.3; 100 lands privately.

Keys & recovery

Your vault holds one random 32-byte root. From it your browser derives a spending key (to spend notes), a viewing key (to find and open them) and every one-time address. It's encrypted with your passphrase (PBKDF2, 600,000 rounds → AES-GCM) and stored only in this browser.

  • The recovery key (shown once at creation) restores everything on any device. Anyone who has it can spend your private balance.
  • It is not derived from your wallet, so a wallet compromise doesn't expose your Veil balance, and vice versa.
  • Lose both this browser and the recovery key and the funds are unrecoverable. Nobody, including Veil, can restore them.

Security model

  • Non-custodial: only proofs from your keys move your notes. The admin can pause, set fees (≤1%), caps and allowlisted programs, but cannot move anyone's funds.
  • Bound to the proof: recipient, fees and swap terms are hashed into the proof by the program itself; a relayer that changes anything gets an invalid proof.
  • Isolated swaps: each trade or lend has its own escrow and signer; an allowlisted protocol can only touch that one.
  • Guarded launch: per-token caps, a multisig admin with two-step handover, and a public key ceremony.

Testing, review status and live on-chain checks are on the Security page.

Limits & risks

  • Beta caps: each token has a per-deposit limit and a vault cap during the beta.
  • Anonymity set: privacy grows with the number of people using Veil, and per token for shields and exits.
  • Freezable tokens (like USDC) can have their vault frozen by the issuer. The app labels them.
  • Proving keys come from a ceremony that is secure if any one participant was honest. Until it completes, development keys are used.
  • Emergency pause: the multisig can pause the protocol, which also pauses withdrawals until it's lifted.

SDK

@veil/sdk does everything the app does: keys, sync, proofs, and talking to the relayer. Proofs are generated client-side; nothing secret is ever sent.

import { VeilClient } from '@veil/sdk'
import { deriveKeys, rand } from '@veil/crypto'

const veil = new VeilClient({
  connection, programId,
  indexerUrl: 'https://indexer.example', relayerUrl: 'https://relayer.example',
  circuit: { wasm: '/circuits/transaction.wasm', zkey: '/circuits/transaction.zkey' }
})
veil.unlock(deriveKeys(rand(32)))   // keep the 32-byte root safe: it is the vault
await veil.sync()                      // download notes, find yours by trial decryption

Relayer & indexer API

Both are plain HTTP and keep no logs of who asked what. Anyone can run their own.

EndpointWhat it does
GET /v1/infoRelayer key, allowlisted swap and lending programs, protocol fee rates
GET /v1/fee?mint&inputsRelayer fee for a token and number of notes spent, and the account it's paid to
POST /v1/relaySubmit a proof (transfer, withdrawal, trade, lend); the relayer pays the network fee
POST /v1/sponsorGasless shield: co-sign a deposit as fee payer after a strict check
GET /v1/quoteSwap or lending quote, after the Veil fee
GET /v1/positionsLending markets, rates and share prices
GET /v1/commitmentsIndexer: every note commitment and ciphertext, in order (everyone downloads all)
GET /v1/nullifiers · /v1/rootIndexer: spent markers and the current Merkle root

On-chain program

Program id (mainnet-beta)VeiL111111111111111111111111111111111111111
InstructionPurpose
transactShield, private transfer or withdrawal, with a Groth16 proof (up to 4 notes in, 3 out)
swap_prepare · swap_execute · swap_refundTwo-step private trade or lending position through an allowlisted program
register_assetOpen a vault for a token (anyone; screened on-chain)
collect_feesSweep protocol fees to the treasury (anyone; treasury only)
set_* · accept_adminMultisig governance: fees ≤ 1%, caps, pause, allowlist, two-step admin handover

Circuit: Transaction(26, 4, 3), Groth16 over BN254, 13 public inputs, verified with Solana's alt_bn128 syscalls. Notes live in a Poseidon Merkle tree of 226 leaves.

FAQ

Does Veil ever hold my keys?

No. Your vault is generated and encrypted in your browser. Proofs are built there too. The relayer and indexer only ever see public data and proofs.

Can the Veil team freeze or take my funds?

The program has no path for anyone to move notes without the owner’s proof. The multisig can pause the protocol in an emergency (which also pauses withdrawals until lifted) and set limits, but cannot move funds.

What if the relayer goes down?

Run your own or use another: the relayer only submits proofs and pays network fees. Anyone can be a relayer, and your proof works with any of them.

Is Veil anonymous?

Veil hides the link between your wallet and your private activity. How well depends on the crowd and your habits (amounts, timing, tokens). No tool makes you 100% anonymous, and we won’t claim it does.

Which tokens work?

Any SPL or Token-2022 token without features that are unsafe in a shared vault. Anyone can open a vault for a new token.

I lost my recovery key and browser data.

Then the funds can’t be recovered by anyone. Keep the recovery key offline and private.

Why does a send sometimes show the token?

When you have no private SOL, the relayer is paid in the token you’re sending, which names it. Shield a little SOL to keep sends fully hidden.

Glossary

NoteA sealed record of a token amount you own. Your private balance is your notes.
CommitmentThe public fingerprint of a note, added to the Merkle tree. Reveals nothing about the note.
NullifierPublished when a note is spent, so it can't be spent twice. Unlinkable to the note's commitment.
RelayerA server that submits proofs and pays network fees. It can't alter what the proof allows.
Anonymity setThe crowd your activity blends into: other users of the same pool and token.
One-time addressA fresh Solana address derived from your vault, used once for an exit or a payment.
CeremonyA public multi-party process that creates the proving keys; secure if any one participant is honest.