Core Features

Shield & Send

Deposit B20 tokens into the privacy pool and send them privately using zero-knowledge proofs.

How Shielding Works

Shielding deposits public B20 tokens into the vault. You receive a shielded note — a cryptographic commitment that proves ownership without revealing amount or identity.

  1. Generate random nullifier and secret locally in browser.
  2. Compute Poseidon(nullifier, secret, amount).
  3. Approve vault, call vault.shield(token, amount, commitment).
  4. Vault transfers B20 and inserts commitment into Merkle tree.
  5. Store nullifier, secret, amount locally.
Your nullifier and secret never leave your browser. The on-chain commitment reveals nothing.

Shielding Example

javascript
// Alice shields 1,000 B20
const nullifier = randomFieldElement();
const secret = randomFieldElement();
const amount = parseEther("1000");

// Compute commitment
const commitment = poseidon([nullifier, secret, amount]);

// Approve + shield
await b20.approve(vault.address, amount);
await vault.shield(b20.address, amount, commitment);

// Store locally
wallet.saveNote({ nullifier, secret, amount, token: b20.address });

How Private Sending Works

A PLONK zero-knowledge proof proves:

Transfer Flow

  1. Input note — Alice's existing note (e.g., 1,000 B20)
  2. Output notes — Bob (600 B20) + Alice change (400 B20)
  3. ZK proof — valid without revealing amounts/addresses
  4. Broadcaster — submits proof, pays gas, collects B20 fee
  5. Vault — verifies, marks nullifier spent, inserts new commitments
javascript
// Alice sends 600 B20 to Bob
const proof = await generateProof({
  inputNote: aliceNote,
  outputNotes: [
    { amount: 600, recipient: bobAddress },
    { amount: 400, recipient: aliceAddress }, // change
  ],
  merkleRoot: await getMerkleRoot(),
  merkleProof: await getMerkleProof(aliceNote.index),
});
await broadcaster.submitTransfer(proof);

Privacy Model

Privacy strength = anonymity set size. Every shielded note is a 32-byte commitment — indistinguishable on-chain.

What's visible on-chain

DataVisible?Details
Shield deposit amountYesPublic ERC-20 transfer
Commitment hashesYes32-byte hashes — reveal nothing
Nullifier hashesYesProves spent, not which note
Transfer amountsNoHidden by ZK proof
Sender identityNoBroadcaster submits
Recipient identityNoRecipient sees note locally

Best practices