Back to user guide

Technical docs

Privacy

Privacy payments

Operational vs cryptographic privacy, current PoolManager stack, Nethermind reference, and migration plan for opt-in ZK settlement.

Overview

Hypertron ships an opt-in private settlement path for B2B payment links. Merchants can offer checkout where the payer’s wallet is hidden from the business, and funds are tracked via commitments and nullifiers on a Soroban PoolManager contract. This page explains what that gives you today, what real cryptographic privacy looks like on Stellar, and how we plan to migrate from our Phase 1 stack to a full zero-knowledge pool.

Private settlement is enabled when NEXT_PUBLIC_POOLMANAGER_CONTRACT_ID is set (or NEXT_PUBLIC_ENABLE_PRIVATE_SETTLEMENT=true). It targets Stellar testnet only and is not audited.

Real vs operational privacy

Not all “private payments” are equal. Hypertron Phase 1 and a full ZK privacy pool solve different problems.

GuaranteePhase 1 (Hypertron today)ZK pool (Nethermind target)
Hide payer from merchantYes — relayer + hash memo + UIYes — shielded UTXO inside pool
Hide payer from chain analystNo — payer → relayer → pool is traceableYes — ZK proofs break on-chain links
Hide amountNo — visible on Horizon paymentYes — inside pool
Unlinkable withdrawalNo — direct pool → recipient payoutYes — nullifier spend via ZK proof
Server cannot spend user fundsNo — server derives secrets, signs commitsYes — client holds note keys
Trust modelTrust Hypertron backend + pool operatorTrustless on-chain verification

Operational privacy (Phase 1) is appropriate for “the merchant shouldn’t see who paid.” Cryptographic privacy (Phase 2) is required for unlinkable, trustless settlement — the standard set by Nethermind’s reference implementation.

  • Phase 1 solves a real merchant problem.
  • Phase 2 adds cryptographic privacy via Nethermind’s stack.

Nethermind reference implementation

The Stellar Privacy Engineering team at Nethermind maintains the canonical open-source privacy pool for Soroban. It is the intended upgrade path for Hypertron’s ZK layer and is explicitly referenced in our PoolManager source.

  • Repository: github.com/NethermindEth/stellar-private-payments ↗
  • Live demo: nethermindeth.github.io/stellar-private-payments ↗
  • Stack: Circom circuits, Groth16 proofs (browser WASM), Pool + CircomGroth16Verifier + ASP Membership + ASP Non-Membership Soroban contracts
  • Model: 2-in / 2-out UTXO transactions — deposit, private transfer, and withdraw inside the pool with balance conservation proved in zero knowledge
  • Compliance: Association Set Provider (ASP) membership and non-membership Merkle proofs enforced inside the circuit
  • Status: Work in progress, not audited — same caution as Hypertron testnet beta
We do not fork or reimplement Nethermind’s circuits from scratch. Phase 2 embeds their pool, verifier, and prover as the settlement layer while Hypertron remains the B2B orchestration layer (payment links, vaults, dashboard, KYB).

Current architecture (Phase 1)

Phase 1 splits settlement across classic Horizon payments (fund custody) and a Soroban commitment registry (double-spend bookkeeping). Privacy is achieved at the application layer, not inside a shielded pool.

Phase 1: operational private checkout
Customer opts in to private settlement

POST prepare-pay → SHA-256 memo hash

PendingPaymentMemo in DB

Relayer configured?

Yes

Payer → relayer (hash memo)

Relayer → pool G-address (same memo)

No

Payer → pool / vault (hash memo)

Horizon match + attribution

status poll / relayer inbox

Server derives secret + nullifier

hashToScalar(payer, businessId, amount)

PoolManager.commit (Soroban)

Poseidon leaf + nullifier reg

Virtual balance updated (Prisma)

Merchant sees Paid ✓ (no payer address)

Key components in the repo:

LayerFiles / contractsRole
Checkout UXpay/[id], privacy-features.tsOpt-in toggle, prepare-pay, Freighter signing
Hash memoprepare-payOne-time opaque memo; no link id on chain
Relayerrelayer.tsHide payer from pool observer; forward to pool
Attributionstatus/route.tsHorizon match → commit → update PaymentLink
Soroban clientsoroban-commit-server.ts, soroban-poolmanager.tsServer-side commit / withdraw invocations
PoolManager (PoC)contracts/poolmanagerPoseidon leaf, nullifier registry, ASP approve/block, stub ZK verifier
Virtual balancevirtual-balance.tsOff-chain ledger of unspent nullifiers per business
Withdrawal/api/withdraw, payout-server.tsMark nullifiers on Soroban + Horizon payout from pool account
PoolManager stores depositor and amount on chain, uses a rolling Poseidon accumulator (not a Merkle tree), and verify_proof_stub accepts any non-empty proof. These are intentional PoC shortcuts — not production privacy guarantees.

Where we are today

Opt-in private settlement on payment links (testnet beta)

Shipped

Hash-memo dark pool (prepare-pay + PendingPaymentMemo)

Shipped

Relayer: payer hidden from merchant / pool memo match

Shipped

Fee sponsorship (CAP-40) on private checkout

Shipped

PoolManager commit + nullifier registry on Soroban testnet

PoC contract; SDK call shape may lag contract ABI

Shipped

Virtual balance + /api/withdraw treasury flow

Shipped

Groth16 on-chain proof verification

Planned

Client-side WASM prover (Circom)

Planned

Merkle commitment tree + membership proofs

Planned

Single shielded pool custody (no split Horizon + Soroban)

Planned

Privacy relay (multi-hop ephemeral wallets)

Described in README; not implemented — superseded by ZK path for real unlinkability

Planned

Security audit before mainnet

Planned

Target architecture (Phase 2)

Phase 2 keeps Hypertron as the product layer and swaps the settlement engine for Nethermind’s shielded pool when the customer opts in. Standard checkout (direct vault payment) stays unchanged.

Phase 2: opt-in ZK private checkout
Customer selects Private (ZK) checkout

Browser loads WASM prover

Nethermind circuit artifacts

Client generates deposit proof + note

User holds secrets

Pool.transact(proof, ext_data)

Tokens locked in pool contract

Hypertron indexes pool events

Update merchant virtual balance

Merchant sees Paid ✓ (cryptographically private)

Nethermind contracts to deploy alongside (or instead of) stub PoolManager:

ContractPurpose
PoolMerkle UTXO pool — transact (deposit / transfer / withdraw)
CircomGroth16VerifierOn-chain Groth16 proof verification (BN254)
ASPMembershipMerkle tree of approved note public keys
ASPNonMembershipSparse Merkle exclusion list

What Hypertron keeps vs replaces:

Keep (Hypertron)Replace / embed (Nethermind)
Payment links, /pay checkout, fee sponsorshipPoolManager stub → Pool + Verifier
Business vaults, treasury UX, virtual balance displayServer hashToScalar secrets → client UTXO notes
Relayer (optional pre-pool obfuscation)Horizon-only custody → in-contract token lock
KYB / compliance dashboardInline approve/block maps → ASP Merkle + circuit proofs
Prisma attribution (link id ↔ payment)Event sync from pool NewCommitment / NewNullifier events

Migration plan

Migration is phased so merchants can ship confidential checkout now while ZK settlement is integrated without breaking standard payments.

Phase 1 — Shipped (operational privacy)

  • Hash-memo + relayer + PoolManager PoC commits
  • Market honestly as “payer hidden from merchant” — not ZK-shielded
  • Fix contract ↔ SDK ABI alignment if continuing PoC commits on testnet

Phase 2 — Nethermind integration (real privacy)

  • Deploy Nethermind contracts to testnet using their deployments/scripts/deploy.sh (pool levels, ASP levels, verification key)
  • Bundle Circom WASM prover + circuit keys in the private checkout path only
  • Replace executeCommit with client-side Pool.transact() deposit flow
  • Replace sendPayout + stub withdraw with ZK withdraw transact from pool
  • Sync virtual balances from pool contract events (replace server-derived nullifier tracking where possible)
  • Wire KYB-approved businesses into ASP membership tree (admin UI or CLI)

Phase 3 — Production hardening

  • Joint or independent security audit (Hypertron BFF + Nethermind pool path)
  • Trusted setup / verification key governance documented for deployers
  • Mainnet deploy only after Protocol 25 X-Ray verifier is stable on public network
  • Deprecate stub PoolManager; migrate open nullifiers or sunset testnet pool
Migration: dual settlement backends
Pay pageHypertron APIPhase 1 pathNethermind PoolMerchant
  1. 1
    Pay pagePay page

    User chooses Standard vs Private (ZK)

  2. 2
    Pay pagePhase 1 path

    Standard → Horizon payment to vault/pool G-address

  3. 3
    Pay pageNethermind Pool

    Private (ZK) → WASM proof + transact deposit

  4. 4
    Phase 1 pathHypertron API

    Memo match + optional commit

  5. 5
    Nethermind PoolHypertron API

    Pool events → virtual balance

  6. 6
    Hypertron APIMerchant

    Dashboard: Paid ✓

Opt-in dual-mode checkout

The product goal is a single payment link with two modes — defaulting to standard (simple, auditable) and offering private settlement as an explicit opt-in:

ModeUser experiencePrivacy levelBackend
StandardPay vault / pool directly; text or fixed memoPublic on-chain paymentCurrent Hypertron Horizon flow
Confidential (Phase 1)Hash memo; optional relayer; payer hidden from merchantOperationalrelayer.ts + PoolManager PoC + virtual balance
Private / ZK (Phase 2)Freighter signs ZK deposit; note stored client-sideCryptographicNethermind Pool + WASM prover + ASP

Environment flags today: NEXT_PUBLIC_ENABLE_PRIVATE_SETTLEMENT, NEXT_PUBLIC_POOLMANAGER_CONTRACT_ID, NEXT_PUBLIC_RELAYER_PUBLIC_KEY / RELAYER_SECRET_KEY, SOROBAN_COMMIT_SOURCE_SECRET. Phase 2 adds Nethermind contract IDs, circuit key paths, and prover bundle config (TBD).

Hypertron
Onboard
000