The first ZK-proof shielded pool on Stellar Soroban — powered by Protocol 25's native BN254 and Poseidon cryptographic primitives.
PrivacyLayer enables compliance-forward private transactions on Stellar. Users deposit fixed-denomination XLM or USDC into a shielded pool, then withdraw to any address using a zero-knowledge proof — with no on-chain link between deposit and withdrawal.
Inspired by Penumbra (Cosmos) and Aztec Network (Ethereum), adapted natively for the Stellar/Soroban ecosystem.
Stellar Protocol 25 (X-Ray, January 2026) added:
- ✅ BN254 elliptic curve operations (
G1/G2add, scalar mul, pairing) - ✅ Poseidon / Poseidon2 hash functions
- ✅ Both are native Soroban host functions — no external libraries needed
No Soroban dApp has used these yet. PrivacyLayer is the first.
User PrivacyLayer SDK Soroban Contract
│ │ │
│── deposit(amount) ──────►│ │
│ │── generateNote() ────────────►│
│ │ (nullifier, secret) │
│ │── Poseidon(nullifier,secret) │
│ │ = commitment │
│ │── deposit(commitment) ───────►│
│ │ insert into│
│◄── noteBackup ───────────│ MerkleTree │
│ │ │
│── withdraw(note) ────────►│ │
│ │── syncMerkleTree() ──────────►│
│ │◄── leaves[] ─────────────────│
│ │── generateMerkleProof() │
│ │── generateZKProof() [WASM] │
│ │ Groth16 via Noir prover │
│ │── withdraw(proof) ───────────►│
│ │ verifyG16 │
│ │ BN254 pair │
│◄── funds at new addr ────│◄── transfer() ───────────────│
| Step | Operation | Protocol 25 Primitive |
|---|---|---|
| Deposit | commitment = Poseidon(nullifier ∥ secret) |
poseidon2_hash host fn |
| Store | Insert commitment into on-chain Merkle tree | Soroban storage |
| Withdraw (prove) | ZK proof: know preimage of a commitment in the tree | Noir circuit (BN254) |
| Withdraw (verify) | Groth16 pairing check on-chain | bn254_pairing host fn |
PrivacyLayer/
├── circuits/ # ZK circuits written in Noir
│ ├── commitment/ # Commitment scheme (Poseidon)
│ │ └── src/main.nr
│ ├── withdraw/ # Withdrawal proof (Merkle + nullifier)
│ │ └── src/main.nr
│ ├── merkle/ # Merkle tree circuit library
│ │ └── src/lib.nr
│ ├── lib/ # Shared circuit utilities
│ │ └── src/
│ │ ├── hash/ # Hash functions
│ │ ├── merkle/ # Merkle utilities
│ │ └── validation/# Input validation
│ └── integration_test.nr
├── contracts/ # Soroban smart contracts (Rust)
│ └── privacy_pool/
│ └── src/
│ ├── contract.rs # Main contract interface
│ ├── lib.rs # Library entry point
│ ├── core/ # Core business logic
│ │ ├── deposit.rs # Deposit operations
│ │ ├── withdraw.rs # Withdrawal operations
│ │ ├── admin.rs # Admin functions
│ │ ├── initialize.rs # Contract initialization
│ │ └── view.rs # View/query functions
│ ├── crypto/ # Cryptographic operations
│ │ ├── merkle.rs # Incremental Merkle tree (depth=20)
│ │ └── verifier.rs # Groth16 verifier via BN254 host fns
│ ├── storage/ # State management
│ │ ├── config.rs # Configuration storage
│ │ └── nullifier.rs # Nullifier tracking
│ ├── types/ # Type definitions
│ │ ├── state.rs # Contract state types
│ │ ├── events.rs # Contract events
│ │ └── errors.rs # Error types
│ ├── utils/ # Utility functions
│ │ ├── validation.rs # Input validation
│ │ └── address_decoder.rs
│ ├── test.rs # Unit tests
│ └── integration_test.rs# Integration tests
├── sdk/ # TypeScript client SDK (planned)
│ └── src/
│ ├── note.ts # Note generation
│ ├── deposit.ts # Deposit flow
│ ├── withdraw.ts # Withdraw flow (proof generation)
│ ├── merkle.ts # Client-side Merkle sync
│ └── __tests__/ # Jest tests
├── frontend/ # Next.js dApp (planned)
├── scripts/ # Deploy + key setup (planned)
├── contracts/privacy_pool/ARCHITECTURE.md # Contract architecture docs
└── docs/ # Documentation (planned)
# Rust (for Soroban contracts)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown
# Stellar CLI
cargo install --locked stellar-cli
# Noir toolchain (nargo)
curl -L https://raw.githubusercontent.com/noir-lang/noirup/refs/heads/main/install | bash
noirup
# Node.js 18+ (for SDK and frontend)
# Use nvm: https://github.com/nvm-sh/nvmcd circuits/commitment
nargo build # Compile commitment circuit
nargo test # Run circuit tests
cd ../withdraw
nargo build # Compile withdrawal circuit
nargo test
cd ../merkle
nargo build # Compile merkle librarycd contracts
cargo build --target wasm32-unknown-unknown --release
cargo test # Run unit and integration tests✅ Circuits: Commitment, withdrawal, and merkle circuits implemented
✅ Contracts: Full privacy pool contract with deposit/withdraw/admin functions
🚧 SDK: TypeScript client SDK (planned)
🚧 Frontend: Next.js dApp (planned)
🚧 Scripts: Deployment automation (planned)
We're tracking development through GitHub Issues. Key areas:
- Circuits: Optimization, additional proof types, circuit auditing
- Contracts: Gas optimization, additional admin features, testnet deployment
- SDK: TypeScript/JavaScript client library for note generation and proof creation
- Frontend: Web interface with Freighter wallet integration
- Documentation: Architecture docs, API references, tutorials
- Testing: Comprehensive test coverage, fuzzing, security audits
Check the Issues tab for specific tasks and bounties.
⚠️ AUDIT STATUS: Unaudited. Do not use in production.
This project uses zero-knowledge cryptography. While the mathematical primitives (BN254, Poseidon) are battle-tested, the circuit logic and contract integration require a formal security audit before mainnet deployment.
See docs/threat-model.md for known risks.
We welcome contributions! Here's how to get started:
- Check the Issues tab for open tasks
- Comment on an issue to claim it
- Fork the repo and create a feature branch
- Submit a PR referencing the issue number
See CONTRIBUTING.md for detailed guidelines.
This project is funded via Drips Wave — contributors earn USDC for completing issues.
MIT — see LICENSE