Skip to content

About

Zero-knowledge private trading on Stellar.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

PhantomPool

Zero-knowledge private trading on Stellar. Balances live as shielded notes, orders are posted as commitments, and trades settle on Soroban only after Groth16 proofs show they are valid. Nobody, including the operator, learns order sizes, prices or balances.

CI License: MIT Built on Stellar Contributors welcome

Warning

PhantomPool is experimental and unaudited. It targets Stellar testnet. Do not use it with real funds. See Status and known limitations.

Why

On a public order book every order, size and balance is visible, which invites front-running, copy-trading and targeted liquidation. PhantomPool keeps all of that private and still lets anyone verify that the system is correct:

Property How
Private balances Funds are held as notes, Pedersen(asset, amount, salt, owner), in an on-chain Poseidon Merkle tree
Hidden orders Only Poseidon(order terms) is published, with a proof that the order is well-formed
Verifiable settlement Settlement verifies matching, value-conservation and note-membership proofs on-chain
No double spends Spending a note reveals only its nullifier, which the vault records
Selective disclosure Owners can grant auditors expiring, revocable viewing keys
Non-custodial Withdrawals need only a proof; no operator can move user funds

Stellar suits this well. Soroban has native BN254 pairing and Poseidon host functions (Protocol 25), so Groth16 proofs from standard Circom circuits verify directly on-chain. Fees are fractions of a cent, and the Stellar Asset Contract makes any Stellar asset (XLM, USDC, EURC, …) usable through one interface.

Architecture

flowchart LR
  subgraph Browser
    UI[Next.js frontend] --> SDK[TS SDK + snarkjs<br/>notes, proofs]
    UI --> W[Freighter wallet]
  end
  subgraph Soroban["Stellar / Soroban (Rust)"]
    V[shielded-vault<br/>notes, nullifiers, Poseidon tree]
    R[order-registry<br/>order commitments]
    S[settlement]
    A[audit-gateway<br/>viewing keys]
    G[groth16-verifier ×5<br/>BN254 pairing check]
  end
  B[Rust backend<br/>matching engine, indexer, API]

  W -- signed txs --> V & R & A
  V & R & S -- verify --> G
  S -- mark filled --> R
  S -- spend / insert notes --> V
  B -- getEvents --> Soroban
  B -- settle_execution --> S
  UI -- REST / WebSocket --> B
Loading

The full design (data flows, encodings, trust model) is in docs/ARCHITECTURE.md.

Repository layout

Path What it is Stack
contracts/ Soroban smart contracts: vault, order registry, settlement, audit gateway, Groth16 verifier Rust, soroban-sdk 28
backend/ Matching engine, chain indexer, commitment-tree mirror, REST + WebSocket API Rust, axum, tokio
frontend/ Trading UI with Freighter wallet support Next.js 16, React 19, @stellar/stellar-sdk
packages/circuits/ Zero-knowledge circuits and trusted-setup scripts Circom 2, Groth16
packages/sdk/ Client SDK for notes, commitments and proofs TypeScript, snarkjs
packages/integration/ Property-based end-to-end tests TypeScript, fast-check
docs/ Architecture, deployment guide, roadmap

Quick start

Prerequisites

Tool Version Needed for
Rust 1.91+ with the wasm32v1-none target contracts, backend
Stellar CLI 25.2+ building and deploying contracts
Node.js 20+ frontend, SDK
pnpm 10+ SDK, circuits, integration tests
Circom 2.1.6+ only when changing circuits

Run the stack locally

git clone https://github.com/The-Engineer-Network/phantompool.git
cd phantompool

# 1. Contracts: run the test suite (includes a real BN254 Groth16 verification)
cd contracts && cargo test && cd ..

# 2. Backend: http://localhost:3001 (connects to Stellar testnet RPC by default)
cd backend && cp .env.example .env && cargo run && cd ..

# 3. Frontend: http://localhost:3000 (in a second terminal)
cd frontend && cp .env.example .env.local && npm install && npm run dev

The frontend has no mock mode: every action is a real Soroban transaction signed with Freighter, with proofs generated in the browser. Deposits, withdrawals, orders and viewing keys need deployed contracts and compiled circuits; follow docs/DEPLOYMENT.md. Until then those actions show a clear error saying what is missing.

Checks to run before a pull request

cd contracts && cargo fmt --all --check && cargo clippy --all-targets -- -D warnings && cargo test
cd backend   && cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo test
cd frontend  && npm run typecheck && npm run build

CI runs the same checks on every pull request.

Contracts at a glance

Contract Key entry points
groth16-verifier verify(proof, public_inputs). One instance per circuit, holding its verifying key
shielded-vault deposit, withdraw, apply_settlement (settlement only), current_root, is_known_root, is_nullifier_spent
order-registry submit_order, cancel_order, mark_expired, mark_filled (settlement only), get_active_orders
settlement settle_execution, settle_batch (operator only, proofs always enforced)
audit-gateway register_viewing_key, revoke_viewing_key, is_key_valid, get_user_keys

Measured CPU cost against Soroban's 100M-instruction transaction limit: one Groth16 verification ≈ 26M, a deposit's tree insertion (20 Poseidon hashes) ≈ 22M.

Status and known limitations

This is a working foundation, not a finished product. These are the open problems, and each is a tracked roadmap item:

  • Circuits are not yet compiled in CI, and keys have not gone through a multi-party trusted setup. The scripts in packages/circuits generate development keys only.
  • Settlement exceeds a single transaction's CPU budget. It verifies four Groth16 proofs (about 4 × 26M instructions). Merging the settlement circuits into one proof is the planned fix.
  • Settlement needs both traders' secrets for the conservation proof. A two-party proving flow (or per-trader proofs) is still to be designed.
  • Equal-size matching only. The matching circuit requires the buy and sell amounts to be equal; partial fills need change notes.
  • Withdrawals consume a whole note. There are no change notes yet.
  • The backend keeps state in memory and trusts the owner field on owner-only endpoints. Persistence and wallet-signed requests (SEP-53) are planned.
  • The TypeScript SDK does not build yet. Several modules predate the Stellar port (for example, the Pedersen commitment needs a circomlib-compatible implementation).

Contributing

Contributions are welcome, from typo fixes to cryptography. Start with CONTRIBUTING.md, then pick an issue labelled good first issue or check the roadmap. The project takes part in Drips Wave, so eligible issues carry a Wave label and complexity rating, and resolving them earns rewards.

Please read the Code of Conduct. To report a vulnerability, follow SECURITY.md. Do not open a public issue.

License

MIT

About

Zero-knowledge private trading on Stellar.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages