Check it yourself.
The vintage command checks any Zcash mainnet transaction from your own machine, against the public chain. It needs no account, no key and no server of ours. It also makes Vintage payments from a wallet.
Build it.
Rust 1.89 or newer. The first build compiles the Zcash libraries, so it takes a while; later builds are quick.
Checking transactions needs nothing else. Sending (vintage send) also needs zcash-devtool with the two small patches in patches/, next to the vintage binary. Vintage never reads your seed: zcash-devtool signs.
$ git clone https://github.com/Samuel-Chuku/vintage $ cd vintage $ cargo build --release $ ./target/release/vintage --help
Three commands, no wallet.
Did every coin this transaction spends exist before an event, or before any block you name? Exit code 0 PASS, 1 FAIL, 2 not provable.
$ vintage verify <txid> --before bitget-2026-09 $ vintage verify <txid> --before 3501240 --json
PASS: These coins existed before block 3,525,709 (Vintage demo, a staged event, not a real hack). evidence: the anchor matched none of the 2890 distinct Ironwood roots at heights 3525709..=3530376; consensus requires it to be the root of an earlier block
No event needed: the block by which every coin was in the pool, and which registered events that predates.
$ vintage age d3252057850259c86ffae437d0df207ff8b500e4d83dfe4409f585dcd6b441e4
age: in the pool by block 3499995 (2026-09-29 06:15 UTC)
✓ bitget-2026-09 block 3501240 Bitget hot-wallet exploit: first shielding into Ironwood
✓ vintage-demo-2026-10 block 3525709 Vintage demo, a staged event, not a real hack
Lists real Ironwood transactions to try: from the last N blocks, or from any block with --from.
$ vintage sample --blocks 20 $ vintage sample --from 3500000 --blocks 1
3500000 d3252057850259c86ffae437d0df207ff8b500e4d83dfe4409f585dcd6b441e4 3500000 13ab80b092baae27d3c053bff2367d06e8a9e61e99f13eb907bd8c92825c78b8 3500000 eb9f4285d97744bc67409247ee7cb2d4cc50ac9ebb75c09c588e35224d3395b4
A transaction's Ironwood details: mined height and time, anchor, and what it spends.
$ vintage tx da9017e0fca0d8bd87def8e3faa7956067f2bd2234cfee91ca7ad4e67095e3a7
mined: 3527813 (2026-10-23 12:17:14 UTC) ironwood: 3 action(s), spends enabled, outputs enabled anchor: 855ccc99a779159d9d98664d1a09737814b930cc782b149660a94a3881d98502
Make a deposit that proves its age.
For each registered event: how much of a wallet's ZEC a Vintage send can prove predates it.
$ vintage status --wallet <wallet-dir> --sync
Sends with an anchor before the event, so the transaction proves its inputs predate it. Always --dry-run first: it shows which notes qualify and stops before signing.
$ vintage send --wallet <wallet-dir> -i <age-identity> \
--to <address> --value <zatoshis> --before bitget-2026-09 --dry-run
Ask, pay, link.
Ask a payer for a Vintage payment. Prints a payment link (ZIP 321) whose memo names the event; the payer pays it with vintage send --uri.
$ vintage request --to <your address> --amount 0.5 --before bitget-2026-09 $ vintage send --wallet <payer-wallet> -i <age-identity> --uri '<URI>' --dry-run
Link a deposit from a single-use receipt account to the Vintage payment that funded it. Discloses that one account's viewing key, nothing else. The rail can run link verify itself.
$ vintage link prove --deposit <D> --funding <T1> --wallet <receipt-wallet> --out bundle.json $ vintage link verify bundle.json --before bitget-2026-09
input 0: 0.00300000 ZEC from da9017e0fca0d8bd… output 1 input 1: 0.00300000 ZEC from da9017e0fca0d8bd… output 2 PASS: Every coin this deposit spends came from 1 payment whose coins existed before block 3,525,709 (Vintage demo, a staged event, not a real hack).
Signed dates.
The registry in registry/ is a list of dated events, signed with ed25519. check verifies the signature; the other two are for whoever maintains a registry.
$ vintage registry check $ vintage registry keygen # once: writes the private key and pubkey.hex $ vintage registry sign # after any edit to events.json
Every command.
| Command | What it does | Needs |
|---|---|---|
| verify <txid> --before <H> | PASS, FAIL or not provable against an event or block. --json, --received-by (a viewing key, checked locally). | Nothing |
| age <txid> | The coins' proven age, and every registered event it predates. --json. | Nothing |
| tx <txid> | A transaction's Ironwood details. | Nothing |
| sample | Real Ironwood transactions to try. --blocks N, --from H. | Nothing |
| status --wallet | How much of a wallet's ZEC predates each event. --sync. | A wallet |
| send --wallet | Send with an anchor before the event. --to, --value, --uri, --dry-run. | A wallet, zcash-devtool |
| request | A payment link asking for a Vintage payment. | Nothing |
| link prove / verify | The receipt-account link for coins received after an event. | Prove: the receipt wallet |
| witness --wallet | Read-only: which of a wallet's notes have a witness at a height. | A wallet |
| registry check / keygen / sign | Verify or maintain the signed event registry. | Sign: the private key |
Options on every command: --network main|test (default main), --server host:port (any lightwalletd or Zaino server over TLS; default zec.rocks), --registry dir. Point --server at your own node and nobody else is involved. The same checks over HTTP: the API.