Skip to content

Add Zcash forwarding via zecd - #2

Merged
sethforprivacy merged 1 commit into
mainfrom
cake/zcash
Oct 20, 2026
Merged

sethforprivacy merged 1 commit into
mainfrom
cake/zcash

Conversation

@sethforprivacy

Copy link
Copy Markdown

Zcash autoforwarding, redesigned from MAGICGrants#51 against the current codebase and zecd 0.8.2:

  • Sweep: z_mergetoaddress per pool (ANY_ORCHARD, which covers Orchard and Ironwood, then ANY_SAPLING) to Kraken's Zcash (Transparent) address, with AllowRevealedRecipients. That sends the inputs minus the ZIP-317 fee, so there's no fixed buffer and no change, and a backlog batches across passes.
  • Readiness: every pass first requires zecd's /readyz.
  • Container: zecd runs as published (distroless) with a mounted config pointing at our own lightwalletd. A one-shot zcash-wallet-init is the only container that ever sees the seed.
  • Dry run: stops after the readiness, balance and address checks, because zecd can't build a send without broadcasting it.
  • Opt-in: zec is not in the default coin list.

Tests are in tests/test_dry_run.py (11 pass; each new guard is mutation-checked). Not yet run against a real wallet: that happens on btcpay-stg with the staging store's ZEC seed.

🤖 Generated with Claude Code

zecd 0.8.2 (zecrocks; Zellic-audited, Ironwood-capable, bitcoind-dialect
JSON-RPC) holds the seed and sweeps to Kraken's only ZEC deposit method,
a t-address. Re-designed from MAGICGrants#51:

- Sweep with z_mergetoaddress per pool (ANY_ORCHARD - Orchard + Ironwood
  - then ANY_SAPLING): inputs minus the ZIP-317 fee to one output, so no
  fixed fee buffer and no change; its note limits batch a backlog across
  passes. AllowRevealedRecipients explicitly for the t-address payout. An
  empty pool ('Could not find any funds to merge.') is skipped. The async
  operation is awaited in slices up to SEND_TIMEOUT and a failure raises.
- Every pass requires zecd's /readyz (scanned to the tip): a wallet still
  scanning reports a partial balance.
- No Dockerfile: zecd's image is distroless and run as published, with
  docker/zcash-wallet/zecd.toml mounted read-only (our own lightwalletd
  backend, sapling+orchard receivers, fetch_memos off, auto_unlock). A
  one-shot zcash-wallet-init (compose profile) restores from the seed and
  is the only container that ever sees it. No at-rest passphrase: an
  unattended forwarder would unlock it automatically anyway.
- Dry run stops after readiness, balance and Kraken address validation:
  zecd has no way to build a send without broadcasting it.
- Opt-in: zec is not in the AUTOFORWARD_COINS default.

Tests: a ZEC dry run never merges (own address and Kraken); a wallet that
is not ready is never swept; each pool is swept to the Kraken t-address
with AllowRevealedRecipients and an empty pool is skipped. Each fails
when its rule is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sethforprivacy
sethforprivacy merged commit f8b83a0 into main Oct 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant