Zero-knowledge settlement for x402
zk402 authorizes an x402 transfer with a cryptographic proof instead of a recovered signature. Verified against a circuit, settled on-chain.
How a payment settles
Client proves
The payer runs a prover locally over their private inputs and produces a
PaymentPayload carrying a proof and its public inputs —
amount, asset, recipient, and a replay nonce.
Facilitator verifies
The facilitator checks the public inputs against what was requested, confirms it trusts the declared circuit, and verifies the proof — rejecting anything it can't independently confirm.
Chain settles
The facilitator submits the proof on-chain. One transaction re-verifies it, consumes the nonce, and transfers funds — atomically, with no partial state.
Why a proof instead of a signature
A different trust primitive
x402's existing schemes authorize a transfer by recovering a signer from a signature, or by simulating a trusted delegation. zk402 checks a proof against a circuit-specific verifying key instead — a boundary that extends to predicates a signature can't express.
No facilitator discretion
Amount, asset, and recipient are bound into the proof's public inputs. A facilitator can broadcast the transaction, but it cannot alter where funds go without invalidating the proof.
Honest about scope
This is a minimal reference implementation — verify and settle only, no policy or budget logic. Public inputs are not hidden in this version; identity-hiding variants are a larger, separate design.
The zk402 crate family
Scheme trait, and the
ProofSystem trait every other crate builds on. No crypto
dependencies.
docs.rscrates.io
PaymentPayload.
docs.rscrates.io