DocumentationPrivacy WalletTechnical Docs

Introduction

Void Protocol — shielded settlement on Solana

Learn how Void provides end-to-end transactional privacy through on-chain zkSNARK verification, deterministic pool accounting, and client-side encryption.

Summary

Void is a shielded transaction layer for Solana. Users deposit SOL into a shared privacy pool and transact solely through zero-knowledge notes, gaining unlinkable and amount-hidden transfers. Because Void operates entirely on-chain, it delivers privacy and decentralization without centralized APIs or custodial services.

What is Void?

Void is a zero-knowledge shielded transfer protocol built on Solana. It uses Groth16 zkSNARKs alongside a Merkle tree of note commitments to provide private deposits, transfers, and withdrawals. Unlike centralized mixers that rely on trusted servers, Void runs completely on-chain. Observers may see SOL entering and leaving the pool, but they cannot correlate specific deposits with withdrawals.

Design goals

Unlinkable flow

Break the transactional link between senders and recipients across deposits, transfers, and withdrawals.

Amount privacy

Hide the precise value of each transfer by using note commitments and encrypted payloads.

Guaranteed solvency

Strictly enforce that pool balances never exceed deposited value; proofs cannot forge lamports.

Relayer support

Allow third-party relayers to submit transactions without learning sender data.

High-level architecture

Void consists of a single Solana program, a global Merkle tree, and a client-side proving stack. Notes capture user balances, while nullifiers represent spends. The circuit ensures every spend respects pool invariants and accounting rules.

+------------------------+          +------------------------+
|     User Wallet / UI   |          |     Browser ZK Client  |
|  - signs txs           |   RPC    |  - builds witnesses    |
|  - stores view keys    +--------> |  - generates Groth16   |
+-----------+------------+          +-----------+------------+
            |                                       |
            |   SOL transfer + proof                |
            v                                       v
+------------------------+          +------------------------+
|    Solana Validator    | <------> |     Void Program       |
|  - executes logic      |          |  - Merkle tree state   |
|  - enforces rules      |          |  - nullifier registry  |
+------------------------+          |  - pool accounting     |
                                    +-----------+------------+
                                                |
                                                | PDAs
                                                v
                                    +------------------------+
                                    |     On-chain PDAs      |
                                    |  - GlobalState         |
                                    |  - Pool / Escrow       |
                                    |  - Notes / Nullifiers  |
                                    +------------------------+

Core components

On-chain program (Rust / Anchor)

  • Global state. Maintains Merkle roots, historical snapshots, pool totals, configuration values, and admin authorities.
  • Pool management. Governs the pool PDA that escrows shielded lamports; only program instructions can move funds.
  • Proof verification. Validates Groth16 proofs over BN254 using an embedded verification key.
  • Nullifier tracking. Records nullifiers to prevent any note from being spent twice.
  • Two-phase withdrawals. Splits withdrawal flow into Prepare and Execute stages so clients can compute heavy proofs off-chain while relayers submit lightweight transactions.

Zero-knowledge circuit (Circom)

  • Join–split logic. Handles up to six input and six output notes while preserving value.
  • Amount invariants. Asserts that inputs plus public deposits equal outputs plus public withdrawals.
  • Merkle membership. Proves each note exists under a known global root.
  • Nullifier binding. Tethers nullifiers to a user secret, preventing unauthorized spends.
  • Recipient binding. Commits the intended recipient so the program always pays the correct address.

Client-side responsibilities

  • Witness generation. Builds full circuit witnesses using local notes and Merkle paths.
  • Note encryption / decryption. Encrypts outgoing notes via recipient view keys and decrypts inbound notes.
  • Merkle path retrieval. Fetches proofs from indexers or directly from on-chain accounts.
  • Transaction construction. Packages public inputs, proofs, and note metadata into Solana transactions targeting the Void program.