Guides
Answering a request
For holders: from a request link to a proof in the verifier’s hands, without your keys, your balance or your history leaving your machine.
On this page
#What happens
The prover is a single binary. It reads three things: the request, a public chain snapshot, and your seed. It writes one file. It never connects to anything while proving; the only command that touches the network is pof-prove revoke, and only when you run it.
#Read the request
A request is a link to /prove?r=…. The r value is base64url JSON, and the whole request is in it; nothing is stored on a server. Open the link at /prove to read, in plain sentences, what the verifier will and will not learn.
| Field | Meaning | Rule |
|---|---|---|
v | Request format version | must be 1 |
id | Request id; the default deposit intent for an exit | hex |
claim · zatoshi | The threshold, as a decimal string | HoldsAtLeast; a multiple of 0.125 ZEC |
audience | The verifier’s identifier | printable ASCII |
expiryDays | How long the proof stays valid | 1–365 days |
respondBy | Optional deadline for an answer | unix seconds |
bind | solana: bind the proof to your Solana account | optional |
kind | exit (an exit certificate) or reserves (a batch) | optional |
epoch | The verifier’s period: reuse within it is visible to them | optional |
dormantSince | The block your notes must be unmoved since | a multiple of 1,000 |
The same rules are implemented in Rust and TypeScript and checked against one shared vector file in CI.
#1 · Install the prover
Each release has pof-prove, pof-verify and pof-anchor for macOS (Apple silicon), Linux and Windows, with a SHA-256 beside every archive.
curl -fL https://github.com/SATISH-JALAN/Vouch/releases/latest/download/vouch-linux-x86_64.tar.gz | tar xz # or vouch-macos-arm64.tar.gz, vouch-windows-x86_64.zip
# or with Rust 1.91 or newer
cargo install --git https://github.com/SATISH-JALAN/Vouch pof-prove --locked
# or from source
git clone https://github.com/SATISH-JALAN/Vouch && cd Vouch/backend && cargo build --release -p pof-prove#2 · Get the chain snapshot
The prover needs the public Ironwood data up to a published anchor: every note commitment and nullifier, and the encrypted outputs your wallet finds its notes in. Build it yourself from any lightwalletd:
cargo install --git https://github.com/SATISH-JALAN/Vouch pof-anchor --locked
pof-anchor scan --server https://zec.rocks:443 --to 3493000
# ✓ nc_root matches lightwalletd's Ironwood tree state at 3493000It writes target/snapshots/mainnet-<height>.vsnp. The anchor it prints must match one in the verifier’s table, or the verifier answers AnchorNotFound. On testnet add --network testnet: the server, the start height and the table switch, and pof-prove takes the network (ZIP 32 coin type 1) from the snapshot.
#3 · Review, then prove
pof-prove prove --request <encoded> --snapshot target/snapshots/mainnet-3493000.vsnp \
--seed-file ~/.vouch/seed.txt --out proof.pof
✓ account 0 on mainnet
✓ 565,704 Ironwood actions to block 3493000
✓ 2 notes found
✓ anchor at block 3493000
✓ 1 note used; balance not revealed
wrote proof.pof (11,886 bytes). Nothing was broadcast.The seed file holds a BIP 39 mnemonic or a hex seed. The prover prints the same sentence as /prove and asks before doing anything. It picks the fewest notes that clear the bar, largest first, up to five, and fails fast if the best five cannot.
Variants
| You want | Add |
|---|---|
| A proof a Solana program can use | --bind-solana <your pubkey> |
| “Unmoved since block H” | --since <H> |
| An exit certificate | --exit [--intent <deposit id>] |
| A reserves batch (more than five notes) | --batch-size 5 --out reserves.pofb |
Exits: send from exactly the certified notes
An exit certificate names its notes. Send the deposit from those notes in a transaction with no dummy spends, or the rail will see a nullifier the certificate never named and answer mismatch. Make the certificate only when you are ready to send.
#4 · Check it, hand it over
Drop proof.pof on /prove or /verify: you see exactly the verdict the other side will see. Then send the file, or the verify link, which carries the proof after the # so it never reaches a server log.
#5 · Revoke it
pof-prove history # your proofs: claim, audience, expiry, status
pof-prove revoke <id> --endpoint https://vouch-zcash.vercel.app/api/revocationsRevoking publishes the proof’s 32-byte revocation secret. Every verifier that checks the list answers Revoked from then on. History is saved with owner-only permissions; if saving fails, the secret is printed so it is never lost.
#No ZEC? The demo ledger
pof-prove demo prove --world fixtures/demo-world.json --request … answers any request as the demo holder: 4,018.2 ZEC in five real Ironwood notes under a real key, in a published demo tree. The proofs are real; the anchor is labelled demo everywhere it appears.