+×+
Technical Documentation

Privacy Technologies

Zero-knowledge proofs, multi-party computation, and post-quantum cryptography — delivering true financial privacy on Solana.

10 ZK Circuits
14 Programs
17 SDKs
14 Modules

System Architecture

+×+

System Architecture

Protocol Stack

Client Layer
MOBILE APP
React Native / Expo 54
EXTENSION
Chrome MV3 (beta)
WEB APP
Next.js 16
AI AGENT
56 Tools / On-Device LLM
Privacy Layer
AUTO-SHIELD
Stealth Receive + Auto Pool
PRIVACY ROUTER
Multi-Hop / 5 Levels
META-ADDRESSES
st:01 / st:02 P01-to-P01
SDK Layer
@protocol-01/specter-sdk
Stealth & Wallets
@protocol-01/zk-sdk
STARK Prover (post-quantum)
@protocol-01/zkspl-sdk
Confidential Balances
@protocol-01/arcium-sdk
MPC Compute
@protocol-01/p01-js
Merchant SDK
@protocol-01/privacy-toolkit
Merkle + Poseidon
@protocol-01/auth-sdk
Auth Integration
@protocol-01/rpc-config
RPC Fallback Chain
Protocol Layer
STEALTH
ECDH + ML-KEM-768
SHIELDED
ZK Pool + Merkle Tree
DENOMINATED
Fixed-Denom Pools
NOTE SPLIT
Cross-Pool Splitting
zkSPL
Confidential Balances
PAYMENTS
Streams & Subscriptions
VAULTS
Subscription Vaults
MPC
Arcium Cerberus
Verification Layer
ON-CHAIN RELAYER
Trustless ZK Relay
STARK VERIFIER
FRI + Goldilocks
QUANTUM VAULT
WOTS+ / Hash-Timelock
BUNDLER
Atomic Batch Shield
CRANK
Auto Subscription Payments
Solana Blockchain
14 PROGRAMS
Anchor 0.32.1 / Rust
SPL Tokens
Token Standard
alt_bn128 + FRI
ZK Verification
End-to-end encrypted
|
From client to settlement

Core Technologies

23 modules — click to expand technical details and code examples.

Stealth addresses allow recipients to receive funds without revealing their public address. Each payment creates a unique one-time address using Elliptic Curve Diffie-Hellman key exchange.

Key Features

  • Sender generates ephemeral keypair for each transaction
  • Shared secret computed using ECDH between sender ephemeral key and recipient's public key
  • One-time address derived: P = H(shared_secret) * G + recipient_pubkey
  • Only the recipient can detect and spend funds using their private key
  • v1: X25519 (Curve25519) for efficiency on Solana
  • v2: X25519 + ML-KEM-768 (FIPS 203) hybrid ECDH — quantum-resistant
  • View tags: 1-byte filter enables O(1) scanning without full decryption
  • On-chain registry (EIP-5564 for Solana) via p01_registry program

Code Example

// v1: Generate stealth address (X25519 ECDH)
const ephemeral = Keypair.generate();
const sharedSecret = x25519(ephemeral.secretKey, recipientPubkey);
const stealthKey = deriveStealthKey(sharedSecret, recipientPubkey);

// v2: Hybrid quantum-resistant (X25519 + ML-KEM-768)
const { ciphertext, sharedSecret: hybridSecret } =
  mlKem768.encapsulate(recipientMlKemPubkey);
const combinedSecret = hkdf(x25519Secret, hybridSecret);

Quantum-resistant STARK proof system over the Goldilocks field, powered by Winterfell. Hash-based — immune to Shor's algorithm — and the only proof system in use across mobile, extension, and on-chain verifier. Groth16/BN254 was retired in April 2026 (see Legacy / Migration History below).

Key Features

  • 6 STARK AIRs: subscriber_ownership, pool_commitment, balance_proof, merkle_path, confidential_balance, transfer
  • Winterfell prover, Goldilocks field (2^64 - 2^32 + 1), Poseidon AIR (x^7 S-box, 30 rounds)
  • Compact proofs (9-15KB) with Blake3 Merkle trees, 16 FRI queries, 124-bit soundness with DEEP-ALI
  • Custom on-chain FRI verifier (no Winterfell dep — fits 4KB stack), ~889K CU per verification
  • Mobile WASM prover via WebView (82KB module, all 6 circuits)
  • No trusted setup required — STARKs are transparent (unlike Groth16's .ptau ceremony)
  • Quantum-safe: hash-based construction immune to both Shor's and Grover's algorithms
  • Multi-circuit on-chain verifier with circuit_id routing (subscribe, pause, resume, unshield, split)
  • Legacy notes (Groth16/BN254 commitments) auto-detected on load and dropped — users re-shield to STARK format

Code Example

// STARK proof (quantum-resistant, hash-based, no trusted setup)
const starkProof = await starkProver.generateProof(secret);

// Upload proof buffer → on-chain FRI verifier → ~889K CU
await submitStarkProof(program, proofBuffer, commitment, circuitId);
// 6 AIRs over Goldilocks field, 124-bit soundness with DEEP-ALI
// Replaces legacy Groth16/BN254 (see "Legacy / Migration History")

Private transfers go through the relayer. The user generates a ZK proof client-side, funds the relayer, and the relayer executes the transfer to a stealth address. On-chain, only the relayer-to-stealth-address link is visible — the original sender is completely hidden.

Key Features

  • User generates STARK proof locally on device (sender never revealed)
  • User funds relayer with amount + 0.5% fee + gas
  • Relayer verifies proof off-chain, then sends to stealth address
  • On-chain visibility: Relayer → Stealth Address only
  • Sparse Merkle tree with depth 20 for commitment tracking
  • Instant shield/unshield (~3s) via filledSubtrees optimization — no full tree sync
  • Supports SOL and any SPL token

Code Example

// Shielded pool flow (v1.0.0 — STARK V3, quantum-safe)
// 1. User generates a STARK proof locally (no remote prover)
const starkProof = await starkProver.generateProof(noteInputs);

// 2. Optional: instant path via p01_liquidity prefund so the user
//    doesn't have to front ~0.85 SOL of proof-buffer rent
await liquidity.prefund({ ephemeralSigner, proofBuffer, amount });

// 3. Buffer verifies on-chain → funds release to a one-time
//    ECDH + ML-KEM-768 stealth recipient. Observer sees only
//    "ephemeral signer → stealth recipient" — never the user's wallet.
const tx = await unshieldDenominatedStark({ proofBuffer, stealthRecipient });

Poseidon is a ZK-friendly hash function designed specifically for use inside arithmetic circuits. It's significantly more efficient than traditional hashes like SHA-256 or Keccak in ZK contexts.

Key Features

  • Operates natively over the Goldilocks prime field (2^64 − 2^32 + 1)
  • Used inside STARK AIRs for commitments, nullifiers, and Merkle tree hashing
  • Parameters: x^7 S-box, 30 full rounds, t=3 and t=5 widths, circulant MDS matrix
  • Custom on-chain verifier round implementation: MDS × sbox(state + RC)
  • Hash-based and quantum-resistant — immune to Shor and Grover

Code Example

// Poseidon commitment in circuit
template Commitment() {
    signal input amount;
    signal input ownerPubkey;
    signal input randomness;
    signal output commitment;

    component hash = Poseidon(4);
    hash.inputs[0] <== amount;
    hash.inputs[1] <== ownerPubkey;
    hash.inputs[2] <== randomness;
    hash.inputs[3] <== tokenMint;
    commitment <== hash.out;
}

A Merkle tree stores all commitments, allowing users to prove they have funds in the shielded pool without revealing which commitment they own. The root is stored on-chain and updated with each deposit.

Key Features

  • Binary tree with Poseidon hash at each node
  • Depth 20 = 2^20 = ~1 million commitments capacity
  • Proof size: 20 siblings + 20 path indices
  • Incremental insertions for gas efficiency
  • Precomputed zero values for empty subtrees

Code Example

// Merkle proof verification in circuit
for (var i = 0; i < TREE_DEPTH; i++) {
    left = pathIndices[i] == 0 ? current : siblings[i];
    right = pathIndices[i] == 0 ? siblings[i] : current;
    current = Poseidon(left, right);
}
root === computedRoot; // Must match on-chain root

Nullifiers are unique identifiers that prevent double-spending without revealing which commitment was spent. Each commitment can only produce one valid nullifier.

Key Features

  • Nullifier = Poseidon(commitment, spending_key_hash)
  • Stored on-chain in a set (prevents reuse)
  • Cannot be linked back to the original commitment
  • Spending key proves ownership without revealing identity
  • Tracked by the relayer to prevent replay attacks

Code Example

// Nullifier computation
const spendingKeyHash = Poseidon([spendingKey]);
const nullifier = Poseidon([commitment, spendingKeyHash]);
// On-chain: require(!nullifierSet.contains(nullifier))

Protocol 01 leverages Solana's native cryptographic syscalls for efficient on-chain ZK proof verification, achieving verification in under 200K compute units.

Key Features

  • Custom FRI verifier for STARK proofs — Goldilocks field (~889K CU per verification)
  • sha256 syscall for Merkle path hashing (post-Groth16 migration)
  • 13 Anchor programs: zk_shielded, zkSPL, specter, subscriptions, streams, quantum_vault, STARK_verifier, registry, relayer, trustless, fee_splitter, whitelist, arcium
  • Quantum vault: WOTS+ signatures, hash-timelock, commit-then-reveal (SHA-256 based)
  • Cross-program invocations for token transfers and proof verification
  • 370+ automated tests: stress tests, E2E flows, SDK unit tests, Rust STARK tests

Code Example

// v1.0.0 — Every spend verifies through the custom on-chain
// FRI verifier (no Winterfell dep, Goldilocks + Blake3, ~889K CU).
let positions = fiat_shamir_positions(trace_root, commitment);
for pos in positions {
    verify_merkle_path(proof, pos, trace_root)?;
    verify_poseidon_round(trace_row, round_constants)?;
}

// LEGACY (pre-April 2026, now retired from every spend path) —
// BN254 Groth16 pairing via the sol_alt_bn128 syscall. Kept here
// only for historical reference; the code still exists in the
// repo history but no instruction dispatches to it in v1.0.0+.
//
//   let pairing_result = sol_alt_bn128_pairing(&[...]);
//   require!(pairing_result == 1, "Invalid Groth16 proof");

Fully on-chain relayer program (p01_relayer) that verifies ZK proofs and executes private transfers to stealth addresses. No backend server — the relayer is a Solana program, eliminating trust in any third party.

Key Features

  • On-chain Solana program — no backend server, fully trustless
  • User generates ZK proof client-side (spending key never leaves device)
  • Relayer PDA escrows transfer amount + fee (0.5%) + gas + rent
  • On-chain verification: proof checked by the program before executing transfer
  • Sends to stealth address — no on-chain link to the original sender
  • Local-only proving: Winterfell STARK WASM in WebView (mobile) or browser (extension)

Code Example

// Trustless on-chain relay flow (v1.0.0 — STARK V3 + relayer-routed)
// 1. Client generates a STARK proof locally via the WASM prover
//    (spending key stays on device; no remote prover fallback)
const starkProof = await starkProver.generateProof({
  secret, nullifierPreimage, merklePath, pathIndices,
});

// 2. Upload the proof to a buffer account (~120 KB, ~9–15 KB compact)
//    then call the on-chain FRI verifier (no Winterfell dep,
//    custom Goldilocks + Blake3 implementation, ~889K CU)
await submitStarkProof(program, proofBuffer, circuitId);

// 3. Instruction reads the verified buffer and releases funds
//    to a one-time stealth recipient (ECDH + ML-KEM-768 hybrid)
await program.methods.unshieldDenominatedStark(...)
  .accounts({ pool, recipient: stealthAddress, nullifierPda })
  .rpc();
// Legacy snarkjs.groth16 path fully retired — see Migration History

ZK proofs hide amounts and break the sender-receiver link. But some metadata remains: the relayer sees your transaction, nullifiers are posted in the clear, and registry lookups are observable. Arcium MPC eliminates these residual leaks by distributing every sensitive operation across a decentralized network of nodes — no single node ever sees the plaintext. It is an optional layer that users toggle on for maximum privacy.

Key Features

  • Nullifier hiding: MPC nodes jointly compute SHA3(nullifier) — only the hash goes on-chain, the actual nullifier stays encrypted
  • Confidential relay: your transaction is encrypted and split across MPC nodes (Rescue-CTR). They reconstruct and execute it together — no single relayer sees the content
  • Anonymous registry lookup: query a stealth meta-address through MPC — nobody knows who you looked up
  • Confidential balance audit: prove solvency to an auditor without revealing individual balances
  • Threshold stealth scan: your viewing key is sharded across nodes — no single node can scan your payments
  • Private governance: encrypted ballots tallied inside MPC — only the final result is revealed
  • Cerberus protocol: 1-of-N honest node guarantees correctness. 9 circuits deployed on Solana devnet
  • Graceful fallback: every MPC operation degrades to the standard (non-MPC) path when disabled — zero overhead

Code Example

// @protocol-01/arcium-sdk — MPC confidential compute
import { ArciumClient } from '@protocol-01/arcium-sdk';

const mpc = new ArciumClient({ connection, wallet, programId });
await mpc.initialize(); // X25519 key exchange + Rescue cipher setup

// Without MPC: nullifier posted in the clear on-chain
// With MPC:    nodes compute SHA3(nullifier) together, only hash goes on-chain
await mpc.commitNullifier(nullifierPreimage, secret);

// Without MPC: relayer sees full transaction content
// With MPC:    transaction split across nodes, nobody sees the plaintext
await mpc.confidentialRelay(encryptedTransaction);

// Without MPC: RPC lookup reveals who you searched for
// With MPC:    query goes through MPC, target stays anonymous
const metaAddress = await mpc.privateLookup(targetHash);

Trustless blind auctions combining Arcium MPC encrypted bid accumulation with a Groth16 ZK shielded pool escrow (legacy, scheduled for STARK migration). Bids are hidden, settlement is automatic, and no party can cheat — the circuit, the MPC, and the on-chain program enforce outcomes independently.

Key Features

  • Escrow before auction: bidders lock funds via escrow_shield (Groth16 proof — legacy, scheduled for STARK migration). The proof pre-authorizes two outcomes — pay the seller OR refund the bidder. Neither party chooses.
  • Encrypted bid accumulation: sealed_bid_auction MPC circuit runs on Arcium ARX nodes. Constant-time comparison prevents timing side-channels. No single node sees any bid.
  • MPC result revelation: finalize_auction reveals only the winning nullifier and bid amount. All losing bid amounts remain permanently hidden.
  • Nullifier-based identity: bidders are identified by their escrow nullifier, not their wallet address. Nullifiers are cryptographically unlinkable to identity.
  • Permissionless settlement: write_escrow_outcome reads the Auction PDA, escrow_release inserts the correct commitment into the Merkle tree. Anyone can crank — no cooperation needed.
  • Anti-replay: auction_id is a public input in the ZK proof, binding each escrow to a specific auction. Proofs cannot be reused across auctions.
  • Circuit: escrow_bid.circom — 4,954 constraints, 7 public inputs, Groth16 over BN254 (legacy, scheduled for STARK migration). Proves note ownership, Merkle membership, maturity, and dual commitment correctness.
  • Deployed on devnet: p01_arcium (FH1Ji...) + zk_shielded (GbVM5...) with comp defs initialized and VK uploaded. Ready for integration.

Code Example

// Sealed-Bid Auction — Arcium MPC + ZK Escrow
import { createAuction, submitSealedBid, finalizeAuction } from '@protocol-01/arcium-sdk';

// 1. Seller creates auction
await createAuction(client, program, { auctionId, pool, deadline });

// 2. Bidder locks funds in escrow (Groth16 proof pre-authorizes both outcomes)
//    Note: escrow surface still uses Groth16 — STARK migration scheduled.
await escrowShield(proof, nullifier, merkleRoot, auctionId, payCommit, refundCommit);

// 3. Bidder submits encrypted bid (MPC — no one sees the amount)
await submitSealedBid(client, program, auctionId, bidAmount, escrowNullifier);

// 4. After deadline: MPC reveals winner, escrow auto-settles
const result = await finalizeAuction(client, program, auctionId);
// Winner's funds → seller | Losers' funds → refunded. No trust needed.

Streams and subscriptions do NOT use ZK proofs. They are separate modules with their own privacy model based on obscurement. Users can add noise to amounts and timing to make payments harder to analyze, but they are not fully hidden like ZK transfers.

Key Features

  • Streams: time-locked escrow payments (P2P or P2B) — visible on-chain
  • Subscriptions: delegated recurring payments via crank — visible on-chain
  • Amount noise: 0-20% random variation on each payment
  • Timing noise: 0-24 hours random delay on payment execution
  • Optional stealth address for recipient obscurement
  • Privacy level: obscurement (not full anonymity like ZK transfers)

Code Example

// Subscription with privacy noise (not ZK)
await p01.createSubscription({
  amount: 9.99,
  interval: 'monthly',
  privacyOptions: {
    amountNoise: 10,    // ±10% random variation
    timingNoise: 12,    // ±12 hours random delay
    useStealth: true    // Pay to ephemeral address
  }
});
// On-chain: payment is visible but harder to correlate

Tornado Cash-style fixed-denomination pools for SOL and USDC. All deposits in a pool are the same value, making them indistinguishable. Epoch-based time delays prevent timing correlation attacks.

Key Features

  • Fixed denominations: 0.1/1/10/100 SOL or 1/10/100/1000 USDC
  • Commitment = Poseidon(nullifier_preimage, secret, deposit_epoch, token_mint)
  • PDA-per-nullifier for atomic double-spend prevention (not Bloom filter)
  • Epoch-based maturity: deposit_epoch <= min_epoch enforced in circuit and on-chain
  • Merkle tree depth 15 = 32,768 notes per pool
  • Circuit: denominated_pool.circom (4,273 non-linear constraints)
  • P2P note sharing via BLE and NFC for offline transfers (zero on-chain trace)
  • v0.9.5: Full stealth unshield — ephemeral signer (fee payer) + ECDH one-time recipient. User wallet never appears on-chain.

Code Example

// Shield: stealth intermediary hides wallet origin
const stealthKp = deriveStealthSigner(wallet, timestamp);
await fundStealth(wallet, stealthKp, 0.1); // small fee fund
await program.methods.shieldDenominated(commitment, epoch)
  .accounts({ pool, depositor: stealthKp.publicKey })
  .signers([stealthKp]).rpc();

// Unshield: stealth signer + stealth ECDH recipient
// Wallet NEVER appears as signer, fee payer, or recipient
const signer = deriveEphemeralSigner();
const recipient = generateStealthAddress(metaAddress); // ECDH one-time
await program.methods.unshieldDenominatedStark(starkProof)
  .accounts({ pool, recipient: recipient.address, nullifierPda })
  .signers([signer]).rpc();
// Auto-sweep: recipient → wallet (delayed 3-7s for decorrelation)

Account-model confidential tokens using Poseidon hash commitments. Unlike UTXO-based shielded pools, zkSPL maintains a single balance commitment per account that updates with each operation. Quantum-resistant by design.

Key Features

  • Balance commitment = Poseidon(balance, salt, owner_pubkey, token_mint)
  • Amount commitment = Poseidon(amount, amount_salt) links sender and recipient
  • Single circuit handles deposit, withdraw, send, and receive operations
  • Conservation law: old_balance + credits === new_balance + debits
  • Balance proof: proves balance >= threshold via Num2Bits(64) range check
  • Circuit: confidential_balance.circom (1,382 constraints)
  • SDK: @protocol-01/zkspl-sdk with ZkSplClient, ZkSplProver, LocalStateManager

Code Example

// Confidential deposit — public tokens become hidden balance
const oldCommitment = poseidon([0, salt, owner, mint]);
const newCommitment = poseidon([amount, newSalt, owner, mint]);
const { proof } = await prover.prove({
  old_balance: 0, new_balance: amount,
  public_credit: amount, public_debit: 0,
  private_credit: 0, private_debit: 0,
  old_salt: salt, new_salt: newSalt
});

// Confidential transfer — sender and recipient balances stay hidden
// Amount commitment links the two operations cryptographically
const amountCommitment = poseidon([transferAmount, amountSalt]);

On-chain recurring payment vaults with configurable intervals. Retailers create vaults, subscribers deposit funds, and a crank claims payments each period. Supports both normal (public) and ZK-private subscriber modes.

Key Features

  • Vault PDA stores: retailer, amount, interval, token mint, subscriber count
  • Normal mode: subscriber identity visible, straightforward recurring payments
  • Private mode: ZK proof of subscription ownership without revealing identity
  • Auto-pause on insufficient funds, resume when topped up
  • Retailer claim periods with on-chain settlement
  • Circuit: subscriber_ownership.circom for private subscriber proofs

Code Example

// Retailer creates a subscription vault
await program.methods.initSubscriptionVault(
  amount,       // per-period amount (lamports or token units)
  interval,     // seconds between payments
  tokenMint     // SOL (system_program::ID) or SPL token
).accounts({ vault, retailer }).rpc();

// Subscriber joins (normal mode)
await program.methods.subscribeNormal()
  .accounts({ vault, subscriber, subscriberRecord })
  .rpc();

// Retailer claims a payment period
await program.methods.claimPeriod()
  .accounts({ vault, subscriberRecord, retailer })
  .rpc();

Share denominated pool notes between devices offline using Bluetooth Low Energy or NFC. Notes are encrypted end-to-end and can be transferred without internet connectivity.

Key Features

  • BLE: X25519 ECDH key exchange with nacl.box encryption
  • NFC: Host Card Emulation (HCE) with PIN-derived nacl.secretbox
  • Anti-MITM fingerprint verification for BLE connections
  • Fragmentation protocol for large payloads over BLE characteristics
  • Native Android modules: BluetoothGattServer + HostApduService
  • Works offline — no internet or blockchain access needed for transfer

Code Example

// BLE: Sender (central) connects to receiver (peripheral)
// 1. ECDH key exchange
const sharedKey = x25519(senderPrivateKey, receiverPublicKey);

// 2. Encrypt note data
const encrypted = nacl.box(noteJSON, nonce, sharedKey);

// 3. Fragment and send over BLE characteristics
await bleTransport.sendFragmented(encrypted, characteristicUUID);

// NFC: Sender emulates tag via HCE
// Receiver taps phone → APDU commands: SELECT → GET LENGTH → GET DATA
// Data encrypted with nacl.secretbox(noteJSON, nonce, pinDerivedKey)

Seventeen TypeScript SDKs covering every use case: stealth wallets, ZK proofs, confidential tokens, MPC compute, merchant integration, Merkle trees, authentication, RPC infrastructure, privacy toolkit, and unified privacy SDK. All run client-side for maximum privacy.

Key Features

  • @protocol-01/specter-sdk — Core privacy: stealth wallets, transfers, quantum vault, registry, indexer
  • @protocol-01/zk-sdk — ZK primitives: ShieldedClient, Note, MerkleTree, ZkProver, viewing keys
  • @protocol-01/zkspl-sdk — Confidential tokens: deposit, withdraw, transfer, balance proof
  • @protocol-01/arcium-sdk — MPC compute: ArciumClient, 6 use-case modules, Rescue cipher
  • @protocol-01/p01-js — Merchant SDK: Protocol01 client, subscriptions, payments, React components
  • @protocol-01/privacy-toolkit — Incremental Merkle tree, Poseidon, amount hash, proof format
  • @protocol-01/auth-sdk — Auth integration: P01AuthClient, P01AuthServer, session management
  • @protocol-01/rpc-config — RPC infrastructure: connection manager, priority fallback chain, URL sanitization

Code Example

// === @protocol-01/specter-sdk — Core Privacy SDK ===
import { P01Client, createWallet, sendPrivate } from '@protocol-01/specter-sdk';
const client = new P01Client({ cluster: 'devnet' });
await sendPrivate({ amount: 1.5, recipient: stealthMetaAddress });

// === @protocol-01/zk-sdk — ZK Shielded Pool ===
import { ShieldedClient } from '@protocol-01/zk-sdk';
const zkClient = new ShieldedClient({ rpcUrl, programId });
await zkClient.shield(1_000_000_000n, notes);

// === @protocol-01/zkspl-sdk — Confidential Balances ===
import { ZkSplClient } from '@protocol-01/zkspl-sdk';
await zkspl.deposit(amount, proof);   // Public → confidential
await zkspl.send(amount, recipient);  // Confidential transfer

// === @protocol-01/arcium-sdk — MPC Compute ===
import { ArciumClient } from '@protocol-01/arcium-sdk';
await mpc.commitNullifier(preimage);  // SHA3 via MPC nodes

// === @protocol-01/p01-js — Merchant Integration ===
import { Protocol01 } from '@protocol-01/p01-js';
await p01.createSubscription({ amount: 9.99, interval: 'monthly' });

// === @protocol-01/privacy-toolkit — Merkle + Poseidon ===
import { IncrementalMerkleTree, poseidon2 } from '@protocol-01/privacy-toolkit';

// === @protocol-01/auth-sdk — Auth Integration ===
import { P01AuthClient } from '@protocol-01/auth-sdk';

// === @protocol-01/rpc-config — RPC Infrastructure ===
import { RpcConnectionManager } from '@protocol-01/rpc-config';
const conn = RpcConnectionManager.getConnection(); // Auto-fallback chain

When receiving funds, the app generates a one-time stealth address instead of exposing the main wallet. Incoming funds are automatically detected and shielded into the privacy pool — the main wallet is never visible to senders.

Key Features

  • Receive screen generates fresh stealth addresses (HMAC-derived from viewing secret key)
  • Autonomous runner polls every 5 minutes for incoming funds on stealth addresses
  • When balance detected (>0.05 SOL), auto-shields to the best matching denomination pool
  • Main wallet NEVER appears on-chain for incoming transfers
  • Stealth receive addresses tracked in SecureStore with cleanup after 7 days
  • Settings toggle in Privacy Settings to enable/disable auto-shielding
  • Compatible with any Solana wallet sender — no Protocol 01 required on sender side

Code Example

// Auto-Shield flow (autonomous runner)
// 1. User opens Receive → stealth address generated
const seed = hmac(sha256, viewingSecretKey, "p01_auto_receive_42");
const keypair = Keypair.fromSeed(seed);
// Display keypair.publicKey as QR code

// 2. Sender sends SOL to the stealth address (any wallet)
// 3. Runner detects funds → auto-shields
const balance = await connection.getBalance(stealthAddress);
if (balance > MIN_THRESHOLD) {
  await shield(pool, progressCb, undefined, keypair);
  // Main wallet never visible on-chain
}

For P01-to-P01 transfers, users share a persistent stealth meta-address (st:01...). The sender's Private Send auto-derives a fresh one-time stealth destination — both sender AND receiver are fully hidden on-chain.

Key Features

  • Meta-address format: st:01<base58(spending_ed25519_pub + viewing_x25519_pub)>
  • v2 hybrid: st:02<base58(spending + viewing + ML-KEM-768 pub)> — quantum-resistant
  • Persistent stealth keys (Ed25519 + X25519) stored in SecureStore
  • Private Send detects meta-addresses and auto-derives stealth destination
  • QR scanner auto-detects st:01/st:02 and routes to Private Send
  • On-chain trail: stealth_sender → pool → stealth_receiver (no real wallet visible)
  • Receive screen shows compact 'Copy P01 ID' for easy sharing

Code Example

// Receiver: share meta-address
const keys = await getOrCreateStealthKeys();
const metaAddress = createMetaAddress(keys);
// → "st:012u2trSt1XytE271..."

// Sender: Private Send auto-derives stealth destination
if (isMetaAddress(destination)) {
  const stealth = deriveStealthForRecipient(destination);
  finalDestination = stealth.address;
  // Both sender + receiver hidden on-chain
}

Split a high-denomination note into multiple lower-denomination notes across pools. Enables the Privacy Router to break large amounts into smaller, harder-to-trace pieces with a single ZK proof.

Key Features

  • On-chain instruction: split_note in zk_shielded program (deployed on devnet)
  • Circuit: note_split.circom (~10K constraints, max 20 outputs)
  • Denomination conservation enforced: source = numOutputs × target
  • Same nullifier PDA pattern as unshield (atomic double-spend prevention)
  • Protocol fee: 0.3% of source denomination
  • STARK proof verifies ownership + output commitment correctness
  • Mobile SDK: splitNote() function with proofGenerator callback

Code Example

// Split 1 SOL into 10 × 0.1 SOL
const result = await splitNote(
  sourcePool,  // 1 SOL pool
  targetPool,  // 0.1 SOL pool
  receipt,     // Source note receipt
  10,          // Number of outputs
  outputSecrets,
  proofGenerator,
);
// → 10 new notes in 0.1 SOL pool

The Privacy Router plans and executes multi-hop routes through the privacy pool system. Routes include shield, unshield, reshield, and split operations with configurable timing delays to maximize anonymity.

Key Features

  • 5 privacy levels: Minimal (1 hop) → Paranoid (14+ hops, 20 splits)
  • Autonomous runner executes hops in background (60s polling, Android foreground service)
  • Timing jitter: random delays between hops (hours) prevent correlation
  • Note locking: notes in active routes are locked (cannot withdraw or re-send)
  • Consent popup: irreversibility warning before route starts
  • Route progress: locked notes show hop X/Y, progress bar, next hop ETA
  • Routes encrypted in SecureStore, survive app restarts
  • In-app notification on each hop completion

Code Example

// Start a Paranoid-level private send
const route = await startPrivateRoute({
  amount: 0.1,
  destination: "7gWpzSZA...",
  privacyLevel: 5, // Paranoid
  spendingKeyHash,
});
// → 14 hops over ~2 days
// → Shield → Unshield → Reshield → ... → Final delivery
// → Each hop uses a different stealth address

On-device AI agent with 56 tools covering wallet operations, privacy actions, Solana network queries, DeFi analytics, and device features. Runs locally (Gemma 3 via llama.rn) — no data leaves the device.

Key Features

  • Wallet (6): balance, address, send, history, airdrop, stealth receive
  • Privacy (5): shield, notes list, private send, route status, privacy level
  • Solana (6): slot, epoch, TPS, tx lookup, account info, rent calculator
  • Token/DeFi (6): token balance, swap quote, swap execute, TVL, lending rates, portfolio
  • Analytics (3): gas tracker, whale watch, market dominance
  • Staking (3): stake info, APY, validators
  • NFT (2): list NFTs, floor price
  • Social (2): protocol info, trending tokens
  • Conversion (3): SOL/USD, SOL/lamports, epoch/date
  • Device (3): share, haptic, notification
  • Alerts (3): set price alert, list alerts, clear alerts
  • Utility (4): calculate, validate address, base58 encode, generate keypair
  • Memory (3): save, read, list persistent agent memory
  • Tool-use loop: up to 3 rounds of tool execution per message

Code Example

// User: "What's my balance and shield 0.1 SOL"
// Agent calls tools:
const balance = await executeTool("wallet_balance", {});
// → { sol: "3.69", usd: "$520.13" }

// Agent responds and calls shield tool:
await executeTool("privacy_shield", { amount: 0.1 });
// → Redirects to Privacy → Shield screen

STARK-authorized smart-contract wallet replacing Ed25519 fund custody. Funds spent via Poseidon preimage knowledge proof (Goldilocks, post-quantum), not signature. Same UX as a regular Solana wallet — your address looks the same, friends send to it the same way — but Shor cannot move your funds. Design doc shipped 2026-05-09, ~9-11 weeks solo execution gated on V3 audit close.

Key Features

  • Custody: ed25519 → STARK proof of preimage knowledge of Poseidon(seed_secret, salt) over Goldilocks
  • Wallet address = PDA owned by p01_quantum_wallet program (32 bytes, indistinguishable from a regular pubkey to senders)
  • Receive: any wallet (Phantom, exchange, friend) sends to your PDA via SystemProgram.transfer — no special integration required from sender
  • Send: STARK proof of preimage authorizes withdraw ix. ~20-30s per send (proof gen + buffer upload + verify + execute). Cost of post-quantum security
  • Threat model after ship: when Shor breaks Ed25519 (≥ 2030), an attacker who steals your Solana keypair can pay gas in your name but cannot move funds. Custody = preimage knowledge, not signature
  • Migration: auto-drain Ed25519 → quantum wallet at first launch post-update (1 silent tx, ~3s). User sees their existing wallet upgrade in place — no new seed, no manual transfer
  • Recovery: optional SPHINCS+ recovery key for "even if seed lost" emergency. MVP ships without it (seed phrase suffices)
  • Reuses V3 STARK verifier (DGY37k…) with new circuit_id = 7 for wallet-auth. Same Goldilocks Poseidon, same chunked buffer upload, same multi-relayer rotation. Zero new infrastructure

Code Example

// Quantum Wallet — STARK-authorized fund custody (coming Q3 2026)
// Funds spent via Poseidon preimage proof, not Ed25519 signature.

// 1. Init at first launch — silent, transparent migration
const seedSecret = hkdf(seedPhrase, "p01_quantum_v1");
const commitment = poseidonGl(seedSecret, salt);  // Goldilocks
const ownerId = poseidonGl(seedSecret, "id_v1");
const pda = derivePda(["qw", ownerId], P01_QUANTUM_WALLET_ID);
await initQuantumWallet({ commitment, recoveryPubkey: null });

// 2. Receive — your address is the PDA. Senders use SystemProgram.transfer
// like any other wallet. They don't know it's quantum-protected.

// 3. Send — STARK proves "I know the preimage of commitment"
const proof = await starkProver.generateProof({
  seedSecret, salt, recipient, amount, nonce, circuitId: 7,
});
await uploadProofBuffer(proof);
await withdraw({ amount, recipient, proofBuffer });

// Threat: Shor breaks Ed25519 ≥ 2030. Attacker steals your gas keypair
// → can pay fees in your name, CANNOT move your funds.
// Custody = preimage knowledge (Grover-resistant), not signature.

What we removed and what replaced it. Protocol 01 is post-quantum-first by default — every Groth16/BN254 path was retired in April 2026 in favor of STARKs over the Goldilocks field. This entry documents the migration so SDK consumers and auditors can see exactly what changed and why.

Key Features

  • April 2026 — Groth16 → STARK migration completed across mobile, extension, on-chain verifier, and all 7 circuits
  • Why retired: Groth16 uses BN254 elliptic-curve pairings; Shor's algorithm breaks discrete-log on elliptic curves once a CRQC exists. Also required a multi-party trusted setup ceremony (.ptau) that can never be fully verified
  • What replaced it: Winterfell-based STARKs over the Goldilocks field (2^64 − 2^32 + 1). Hash-based (Blake3 + Poseidon), no elliptic curves, no trusted setup, transparent and quantum-resistant
  • On-chain verifier: custom FRI implementation (no Winterfell dep — fits the 4KB SBF stack), 6 AIRs, ~889K CU per verification, 124-bit soundness with DEEP-ALI on every circuit
  • Removed dependencies: snarkjs, circomlib, ark-circom, alt_bn128 syscalls, .ptau trusted setup files (~30 MB), all compiled .zkey/.wasm circuit artifacts. Mobile bundle dropped 19 MB
  • Backwards compatibility: legacy notes (BN254 commitments) auto-detected on load and dropped from active state — users re-shield once to migrate to the STARK note format. No on-chain migration required

Code Example

// BEFORE — Groth16 / BN254 (retired April 2026)
// const { proof } = await snarkjs.groth16.fullProve(
//   inputs, "transfer.wasm", "transfer.zkey"
// );
// → BN254 pairings (Shor-vulnerable), 30 MB .ptau trusted setup,
//   snarkjs + circomlib runtime, alt_bn128 syscalls

// AFTER — Winterfell STARKs over Goldilocks (current)
const proof = await starkProver.generateProof(secret);
// → Hash-based (Blake3 + Poseidon), no trusted setup,
//   custom on-chain FRI verifier, 6 AIRs, ~9-15 KB proofs

Security Model

Threat Model

  • Blockchain observers cannot link senders and recipients
  • Transaction amounts are hidden in shielded transfers
  • Spending patterns cannot be analyzed
  • Balance tracking is impossible for third parties

Guarantees

  • Sound: Invalid proofs cannot be generated
  • Complete: Valid spends always produce valid proofs
  • Zero-knowledge: Proofs reveal nothing beyond validity
  • No double-spending: Nullifiers are unique per commitment
  • MPC threshold: 1-of-N honest node via Arcium Cerberus protocol

Security Hardening (Mobile)

  • Spending key never leaves device — no remote prover fallback
  • PIN: SHA-256 hashed with per-device salt, constant-time compare
  • Progressive lockout: 5→30s, 8→60s, 10→300s
  • All secrets in hardware-backed SecureStore (not AsyncStorage)
  • Clipboard auto-clear after 60s on all sensitive copies
  • App switcher blur prevents screenshot leaks
  • android:allowBackup="false" (prevents adb backup)
  • Biometric auth: device fallback when hardware unavailable
  • Lock screen enforced even when security_method="none"

Privacy: With & Without MPC

Protocol 01 is private by default — ZK proofs hide amounts and break the sender-receiver link. Arcium MPC is an optional upgrade that eliminates the remaining metadata leaks. Toggle it on in the app for maximum privacy, or leave it off for fast, already-private transactions.

OperationWithout MPCWith MPC (Arcium)
AmountsHidden by ZK proofHidden by ZK proof
Sender → Receiver linkBroken by stealth addressesBroken by stealth addresses
NullifierPosted in the clear on-chainMPC nodes compute SHA3 jointly — only hash on-chain
RelayOn-chain relayer sees TX contentTX split & encrypted — no single node sees plaintext
Registry lookupRPC query reveals search targetQuery goes through MPC — target stays anonymous
Balance audit Not availableProve solvency without revealing individual balances
Governance vote Not availableEncrypted ballots — only final tally revealed
Trust assumptionRelayer is honest (can't steal, can observe)1-of-N honest node (Cerberus protocol)

MPC Off — Already Private

  • STARK proofs hide amounts and ownership (quantum-resistant)
  • Stealth addresses make every payment unlinkable
  • Denominated pools prevent amount-based correlation
  • Some metadata visible: nullifiers, relay content, lookup targets

MPC On — Maximum Privacy

  • Everything above, plus all metadata leaks eliminated
  • Nullifiers encrypted — only SHA3 hash reaches the chain
  • Relay is threshold-decrypted — no single point of observation
  • Unlocks balance audits, private voting, threshold stealth scan

MPC adds ~1-2s per operation · Zero overhead when disabled · Toggle on/off in Privacy Zone

PROGRESSIVELY UPDATED · LAST REVISION MARCH 2026

Beta·Devnet Only

© 2026 PROTOCOL 01 | Built from scratch for privacy

This software is in active development. Not audited. Use at your own risk.