FAQ
Direct answers about what Privé does today on Robinhood Chain testnet (chain id 46630), and what is still in development. Anything not shipped is marked Planned.
Privacy
Is Privé a mixer?
Not in the usual sense. There is no pooled custody and no operator moving funds. You deposit USDG into a shielded pool contract and keep a secret note. Later you prove with a Groth16 proof that you own some unspent note in the pool, without revealing which one. The design follows the Privacy Pools model, whose point is to let honest users prove separation from illicit funds. That part (the association set) is not live yet. See below.
Can anyone see how much I hold?
No. The pool stores Poseidon commitments in a Merkle tree, where a commitment is Poseidon(value, label, Poseidon(nullifier, secret)). Amounts and owners are hidden inside a hash. Public: the pool’s total balance, each deposit (the Deposited event names the depositor and the value), and each withdrawal amount and recipient. Your balance inside the pool is not public.
Who can link my deposit to my withdrawal?
Nobody, from on-chain data. A withdrawal reveals a nullifier hash and a state root, never the commitment being spent, so neither the contract nor an observer learns which leaf you used.
The honest caveat: statistics still leak. Deposit 1,000 USDG and withdraw exactly 1,000 USDG a minute later into a near-empty pool, and the correlation is obvious. Privacy depends on the anonymity set, on timing, and on amounts. Partial withdrawals help, because what you take out need not match what you put in.
What exactly is a “note”?
A local secret, not an on-chain object. Four numbers: a random nullifier, a random secret, the value, and the label the contract assigns at deposit. Your browser derives the public commitment from them, plus the nullifierHash = Poseidon(nullifier) revealed when you spend. The note never leaves your browser, and anyone holding it can spend it. It is a bearer instrument.
What happens if I lose my note or clear my browser?
The funds are gone, permanently. No recovery path, no support desk, no admin key. That is what non-custodial means. Use the encrypted backup: notes are exported as a JSON envelope encrypted with AES-GCM 256, keyed by PBKDF2 (200,000 iterations, SHA-256) from your passphrase. Store the file somewhere you will still have next month.
How big is the anonymity set?
Small. Assume it is small. This is a testnet with a modest number of deposits, and your anonymity set is the set of commitments you could plausibly be spending. Treat testnet privacy as a demonstration of the cryptography, not as unlinkability at scale.
Compliance
Is the compliance / proof-of-innocence feature working right now?
Partly Screening is live, as an attestation. Deposits are screened against a public policy, an approved-set root is published that anyone can recompute from public chain data (no signing key), each note shows a clean status, and you can export a receipt a third party can verify. What is NOT live is enforcement: the withdrawal circuit still proves membership in the pool state tree only, and its own source comment still says NO ASP. So a withdrawal on its own does not prove your funds are screened. What proves it is the receipt, attached deliberately. In-protocol enforcement lands with the audit. The compliance model draws the exact line.
Chain and asset
Which chain is this on, and why?
Robinhood Chain testnet: an EVM chain (Arbitrum Orbit L2), chain id 46630, gas token ETH. That is where USDG lives natively. Nothing in the protocol is chain-specific: the pool is token-agnostic and the contracts are plain Solidity.
Why USDG and not USDC?
USDG (the Global Dollar, issued by Paxos) is Robinhood Chain’s native stablecoin, so it is the asset users on that chain actually hold. Shielding a bridged USDC nobody uses there would be pointless. On testnet the token is MockUSDG, a 6-decimal ERC-20 with an open mint anyone can call through the faucet. It is worthless by design. It is not real USDG.
Gas, fees, and the relayer
Do I need ETH to withdraw?
No. Privé runs a gasless relayer at /api/relay. Your browser builds the proof, the relayer broadcasts the transaction and pays the ETH gas, and it is repaid in USDG out of the amount withdrawn: the recipient receives withdrawnValue - feeAmount and the relayer receives feeAmount. That is what lets a claim link work for someone who has never touched the chain. You do need a little ETH to deposit, since that transaction comes from your own wallet. If the relayer is unavailable, the app falls back to self-submission, which needs ETH.
Can the relayer steal my funds or see who I am?
It cannot steal. The recipient, the fee recipient, and the fee amount are hashed into the proof’s context public signal (keccak256(abi.encode(withdrawal, SCOPE))). Change any of the three and the contract reverts with ContextMismatch. It cannot redirect your payout, inflate its fee, or replay the proof elsewhere.
It also cannot tell which deposit you are spending, because the proof hides that. What it does see: the recipient address and your IP, since you made an HTTP request to it. If that matters to your threat model, self-submit from an independently funded address.
What are the fees?
The protocol takes zero. PrivacyPool has no fee switch, no owner, and no treasury cut. The only cost beyond gas is the optional relayer fee.
| Action | Protocol fee | You pay |
|---|---|---|
| Deposit | 0 | ETH gas (approve + deposit) |
| Withdraw, self-submitted | 0 | ETH gas |
| Withdraw or claim, gasless | 0 | Relayer fee in USDG, floor 0.05 USDG |
The relayer quotes its fee and fee address from GET /api/relay and refuses anything under the floor. The contract separately rejects a fee greater than or equal to the amount withdrawn (FeeExceedsValue).
Status, code, and integration
Is the code audited?
No. Zero audits. The contracts, the circuit, and the trusted setup have had no third-party review. Assume bugs exist that could cause total loss. That is why the deployment is testnet-only.
Can I use this on mainnet today?
No. Privé is not deployed to any mainnet. The only live deployment is Robinhood Chain testnet:
PrivacyPool 0xd62C837a70b9552637C8ee1681fb09b459648181
WithdrawVerifier 0xBAFE6434C40e5582b11bA90cFd6cA1f5ebd904BF
MockUSDG 0xF47593cac046C3a4C15B495eDAd59DE5868B6BbB
chainId 46630Mainnet is gated on the ASP landing in-protocol and on an audit. Start with the testnet guide, and read security and risk first.
Is there an SDK, and can I integrate it?
Planned A TypeScript SDK exists in the repository (@pp/sdk): notes, Merkle sync from chain events, in-browser Groth16 proving via snarkjs, encrypted backup, claim-link encoding, and a viem pool client. It is not published to npm yet, so integrating today means building from source. The API is not stable.
Is there a token?
Live $PRIVE is live on Robinhood Chain mainnet, launched on Pons. Note the asymmetry, because we are not going to blur it: the token is on mainnet, the payment rail is still on testnet. The only official contract address is:
0x9a347d2C997D6D046A6118A2e8D05aB9b3fa498fAny other address, presale, airdrop or “official” $PRIVE is a scam, without exception. Check the address against this page and @privepayapp before you buy anything. Buy $PRIVE.
What the token does not do yet. $PRIVE is designed as the bond behind the relayer network and the screening provider, and as the vote over the screening policy. Those contracts are not deployed yet, so none of that utility is live today. Holding $PRIVE today is a claim on that future, not a live bond. See the token page and the roadmap for exactly what ships when.
What stops someone from spending a note twice?
Each withdrawal reveals the note’s nullifierHash and the contract records it in a spent set. A second attempt reverts with NullifierAlreadySpent. The hash is one-way, so publishing it reveals nothing about the note.
Can I withdraw part of a note?
Yes. The circuit spends one note and mints one change note, range-checking withdrawnValue and existingValue - withdrawnValue to 128 bits. The remainder re-enters the tree as a fresh commitment you own. One send is bounded by one note’s value, since the circuit is one-note-in, one-change-out.