Nocta Pay

x402 payments nobody can trace back

Deposit USDC once. Every payment after that comes from a wallet made for that one request, and settles through the merchant's own unmodified x402 stack.

What happens when a server answers 402

Only the first step ever touches your wallet.

01

Deposit once

USDC goes into the pool as a note only your key can open.

Public: your deposit
02

Get a price

An x402 endpoint answers with the amount and who to pay.

Nothing on chain
03

Prove and withdraw

A proof moves exactly the price to a brand new wallet. A relayer submits it.

Public: pool to a stranger
04

Pay with stock x402

The new wallet pays. The facilitator covers the network fee.

Public: a stranger paid
05

Sweep

The empty account closes and its rent goes back.

Public: account closed

What an observer can piece together

Three payments to three merchants. Plain x402 ties them to one address. Through Nocta each comes from a wallet with no history.

Plain x402Linked
…news.site0.05 USDC
…api.dev2.40 USDC
…shop.xyz18.00 USDC
NoctaUnlinkable
…news.site0.05 USDC
…api.dev2.40 USDC
…shop.xyz18.00 USDC

Costs and limits

Detail
Relayer fee0.50 USDC per payment, from your private balance. It covers about 0.0036 SOL of storage the relayer can't recover.
Network feePaid by the merchant's facilitator, as with any x402 payment on Solana.
ProofOne Groth16 proof, 146,835 compute units to verify. Withdrawal and token account fit in one 1,087-byte transaction.
AmountsPublic, as in plain x402. What's hidden is who paid.
TimingA watcher can match the withdrawal to the payment seconds later. Matching either to your wallet is what's hidden.
Anonymity setEveryone who has deposited into the pool.

Two lines on top of your x402 client

Register the private scheme for Solana and wrap fetch. Anything that comes back 402 is paid from the pool.

const scheme = new PrivateSvmScheme({ rpcUrl, keypair, relayer });
const pay = wrapFetchWithPayment(fetch,
  new x402Client().register("solana:*", scheme));

await pay("https://api.dev/report");  // paid by a stranger
await scheme.sweep();