Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zinc-scanner

A small, stateless, view-only Orchard utility for Zcash. It derives UFVKs, scans the shielded chain for memos (e.g. ZINC inscriptions) through a lightwalletd endpoint, decodes/validates addresses, and builds/inspects PCZTs for client-side signing. It holds no state and no spend keys — point it at your own node and viewing key and run it alongside zebrad/zcashd + lightwalletd.

It is the companion scanner for the ZINC inscription standard, but nothing here is ZINC-specific: it is a generic Orchard scanner/UFVK tool and works for any shielded-memo use case.

Why view-only?

The daemon only ever needs a Unified Full Viewing Key (UFVK). It can see incoming notes and their memos, but it cannot spend. Spending is done elsewhere (e.g. a wallet / FROST signers) against PCZTs this tool builds. Keep spend keys off the scanning host entirely.

Build

Requires a recent stable Rust toolchain. The committed Cargo.lock is format v4, so Rust ≥ 1.78 is needed (tested with 1.90).

cargo build --release --locked
# binary: ./target/release/zinc-scanner

The Zcash crates come from a librustzcash fork (branch public-pczt-api, pinned by commit in Cargo.toml + Cargo.lock) that exposes public PCZT struct fields for external construction — Cargo fetches it automatically, so there is no vendoring or submodule step. Build with --locked so the pinned dependency graph (one transitive crate, core2, is yanked upstream but pinned here) resolves reproducibly. The first build compiles the Zcash proving stack and takes a while.

Quick start

# 1. Generate a view-only sub-account seed (24 words). Keep it offline; only its
#    UFVK should ever touch the scanning host.
zinc-scanner generate-mnemonic --words 24

# 2. Derive the UFVK (read the secret from stdin so it stays out of `ps`/proc):
echo "<mnemonic>" | zinc-scanner derive-ufvk --mnemonic-stdin --network mainnet

# 3. Scan Orchard for notes + memos via your lightwalletd (UFVK from stdin):
echo "<ufvk>" | zinc-scanner scan-ufvk --ufvk-stdin \
  --server lightwalletd.example.com:9067 --tls --max-blocks 2000

All commands emit JSON on stdout, so they compose cleanly with jq and scripts.

Commands

Command Purpose
generate-mnemonic Generate a fresh BIP-39 mnemonic (12–24 words) for a listings/inbox-only sub-account.
derive-ufvk Derive a UFVK from a mnemonic via ZIP-32 (m/32'/133'/account'). Testing convenience — derive client-side in production.
scan-ufvk Scan Orchard with a UFVK via lightwalletd (view-only); returns notes + memos.
decode-address Decode a unified address into its Orchard/Sapling/transparent receivers (offline).
ufvk-address Derive the Orchard receiver a UFVK owns; with --match-ua, prove a UFVK owns a given UA.
latest Get the latest block height from lightwalletd.
dump-tree-state Dump the TreeState at a height (debug).
build-pczt Build an unsigned PCZT from provided Orchard notes (for client-side signing).
extract-tx Extract the final transaction from a signed PCZT.
inspect-pczt Inspect a PCZT's structure (debug).
apply-transparent-signatures Apply client-generated transparent signatures to a PCZT.
extract-orchard-sighash Extract the Orchard shielded sighash from a PCZT (for FROST co-signing).
apply-orchard-frost Apply FROST Orchard SpendAuth signatures, prove, and finalise.
extract-sapling-sighash Extract the Sapling shielded sighash from a PCZT (no Orchard actions).
apply-sapling-frost Apply FROST Sapling spend-auth signatures, prove Sapling, and finalise.

Run zinc-scanner <command> --help for the full flag list.

Connecting to lightwalletd

--server host:port selects the endpoint; add --tls for TLS and --tls-name to set the SNI/domain when it differs from host. You can run your own lightwalletd in front of zebrad/zcashd, or point at a public instance.

Security notes

  • Secrets via stdin. Pass mnemonics/UFVKs with the --*-stdin flags so they never appear in ps, shell history or /proc/<pid>/cmdline. A mnemonic is a spend secret; only ever move the derived UFVK to a scanning host.
  • No spend authority. This tool never signs spends. PCZTs it builds are signed by your wallet / FROST signers elsewhere.
  • Runtime caches are not source. Decrypted note/witness data derived from a viewing key is excluded by .gitignore; treat any such cache as sensitive.

Relationship to ZINC

ZINC inscriptions are ordinary ZIP-302 shielded memos; this scanner is one way to read them off-chain from a registry/inbox UFVK. See the ZINC standard for the memo format and profiles, and https://secresea.com for a live deployment.

License

MIT © FungeLLC

About

Stateless Orchard view-only scanner & UFVK/PCZT utility for Zcash — scan shielded memos (e.g. ZINC inscriptions) via lightwalletd; run alongside your node/zebrad.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages