Prover (Groth16 via Noir + sunspot)

Blind sends need a Groth16 proof of the transfer circuit. There is no browser prover (see spike/noir/REPORT.md): sunspot generates proofs via a Go CLI, so the dApp's RemoteProver POSTs the witness to a server route that shells out to nargo + sunspot.

Topology

code
dApp (RemoteProver) --POST /api/prove--> CliProver --> nargo execute + sunspot prove
  • RemoteProver (packages/blind-mode/src/noir/prover.ts) — dApp path. POSTs { circuit, inputs }; the witness carries amounts/blindings but NOT the ed25519 spend scalar, so funds stay non-custodial (documented devnet trust assumption).
  • CliProver (same file) — Node path: writes Prover.toml, runs nargo execute then sunspot prove, reads <circuit>.proof + <circuit>.pw.
  • /api/prove (dapp/app/api/prove/route.ts) — runtime: nodejs, maxDuration: 60. Widens PATH with ~/.nargo/bin and ~/sunspot/go. Single-flight (shared Prover.toml); behind the access gate in production.

Self-host vs dApp route

By default the dApp uses its own /api/prove. To run the prover elsewhere (dedicated host with the toolchain + circuit artifacts), set PROVER_URL and point RemoteProver at it. The contract is the same POST { circuit, inputs } -> { proof, publicWitness } (both base64).

Health

GET /api/prove/health (no proving; cheap, pollable) reports:

JSON
{
  "ok": true,
  "toolchain": { "ok": true, "nargo": "nargo version ...", "sunspot": "..." },
  "circuits": { "transfer": { "compiled": true, "mtime": "..." }, "swap-auth": { ... } }
}

Returns 503 when the toolchain isn't on PATH or no circuit is compiled. Use it to verify a prover host is ready before routing blind sends to it.

Toolchain

See docs/toolchain.md. In short: nargo (via noirup, ~/.nargo/bin) and sunspot (~/sunspot/go). Circuit artifacts live under packages/blind-mode/circuits/<name>/target/<name>.json.

Compute budget

Every verifier-CPI tx raises its compute-unit limit above the 200k default. The dApp does this at one chokepoint — withComputeBudget(instructions, units?) in dapp/lib/client.ts (default CU_LIMIT = 800_000) — applied by both sendWithSigner and sendWithKeypair. A heavier route (e.g. a Jupiter swap group) passes a larger units rather than hand-rolling its own ComputeBudget ix.

v2 (deferred)

A browser WASM prover would remove the server round-trip for blind sends. Spike only; not built (packages/blind-mode).