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.
Warning
PhantomPool is experimental and unaudited. It targets Stellar testnet. Do not use it with real funds. See Status and known limitations.
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.
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
The full design (data flows, encodings, trust model) is in docs/ARCHITECTURE.md.
| 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 |
| 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 |
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 devThe 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.
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 buildCI runs the same checks on every pull request.
| 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.
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/circuitsgenerate 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
ownerfield 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).
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.