Skip to content

feat: Zcash Orchard shielded transaction support#11

Draft
BitHighlander wants to merge 12 commits intodevelopfrom
feature-zcash
Draft

feat: Zcash Orchard shielded transaction support#11
BitHighlander wants to merge 12 commits intodevelopfrom
feature-zcash

Conversation

@BitHighlander
Copy link
Collaborator

@BitHighlander BitHighlander commented Mar 8, 2026

Summary

  • Zcash transparent (t-addr) support with BIP-44 derivation
  • Orchard shielded privacy: sidecar architecture (Rust CLI + NDJSON IPC), chain scanning, PCZT construction, device signing via RedPallas, Halo2 proof finalization, and lightwalletd broadcast
  • Frontend ZcashPrivacyTab: shielded balance, QR receive address, scan controls, and send form with memo field
  • REST API endpoints for all shielded operations (status, init, scan, balance, build, finalize, broadcast)
  • Full memo field support wired through TypeScript → sidecar IPC → Rust Orchard note encryption

Hardening (code review fixes)

  • Removed dev-only startHeight hardcode from scan
  • Added enc_ciphertext length validation before buffer slicing (panic guard)
  • Added sendCommand timeout (300s) to prevent hung sidecar requests
  • Fixed JSON parse error handling to reject pending requests instead of hanging
  • Added REST API input validation: seed_hex format, amount bounds, signature format
  • Redacted FVK key material from debug logs
  • Fixed init failure status reporting
  • Cleaned all 6 Rust compiler warnings

Won't Do (this PR)

  • Sapling pool support (Orchard-only)
  • Testnet support

Test plan

  • Build zcash-cli: cd zcash-cli && cargo build --release
  • Verify zero Rust warnings
  • Tab appears for ZEC asset with sidecar status indicator
  • Auto-init fetches FVK from device, displays Orchard UA
  • Scan finds notes from chain
  • Send with memo field produces valid shielded tx
  • REST API endpoints respond with proper validation errors for invalid input

@BitHighlander BitHighlander marked this pull request as draft March 8, 2026 23:39
BitHighlander and others added 11 commits March 9, 2026 00:34
…s access in watch-only

- Engine: auto-trigger promptPin() on needs_passphrase so device sends PASSPHRASE_REQUEST
- Engine: route applySettings through updateState so passphrase toggle triggers full flow
- PassphraseEntry: show "Confirm on your KeepKey" spinner after submit instead of dismissing
- App: auto-dismiss passphrase overlay when device transitions away from needs_passphrase
- App: show needs_pin/needs_passphrase as splash (not ready) to prevent dashboard flash
- App: enable settings gear + drawer in watch-only/claimed mode
- TopNav: remove watchOnly disable on settings button
- i18n: add passphrase.confirmOnDevice strings (10 languages)
- i18n: enable partialBundledLanguages for graceful fallback
- Bump version to 1.1.2
- Rename build folder to _build (electrobun.config, collect-externals, build-windows-production.ps1)
- Add cross-platform window drag to TopNav (useWindowDrag on Windows, CSS class on Mac)
- Update Makefile verify/clean targets to match _build rename

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
xcrun stapler staple fails with relative paths — it can't resolve
the file. Using $(pwd) ensures all tools (hdiutil, codesign, stapler)
get a consistent absolute path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- engine-controller: updatePhase = 'idle' (not null) on reboot poll timeout,
  emit disconnected state so UI recovers; reduce poll log frequency to every 30s
- reports: add safeRoundSats() guard for satoshi values near MAX_SAFE_INTEGER,
  validate Pioneer API response shapes, export SECTION_TITLES constants
- tax-export: use shared SECTION_TITLES constants, add row bounds checking
  to prevent silent data corruption on schema changes
- PassphraseEntry: catch onSubmit errors to reset spinner (device disconnect
  during confirm no longer leaves overlay stuck)
- App: suppress PIN auto-show during all firmware phases (not just rebooting)
- index: post-decode firmware size validation (7.5MB binary limit)
release: v1.1.2 — passphrase flow, Windows drag, build fixes
Add ZEC chain config, UTXO tx builder with Zcash v4 overwintered params
(NU6.1 branchId), t1/t3 address encoding, fee defaults, and REST API
passthrough for Zcash-specific fields. Fix dangling symlink cleanup in
collect-externals build script.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Complete shielded (Orchard) transaction support for KeepKey Vault v11:

- Rust sidecar (zcash-cli): NDJSON IPC process handling chain scanning,
  PCZT construction, Halo2 proving, ZIP-244 sighash, and tx finalization.
  Communicates via stdin/stdout, never opens USB device.

- Privacy tab UI: new "Privacy" pill on Zcash AssetPage with shielded
  balance display, Orchard Unified Address (u1...) with QR code, chain
  scan controls, and shielded send form with device signing flow.

- Device FVK export: wallet.zcashGetOrchardFVK() retrieves the Full
  Viewing Key (ak, nk, rivk) from device firmware — seed never leaves
  the device. Sidecar reconstructs FVK and derives Unified Address.

- Sidecar lifecycle: auto-starts on app boot, graceful shutdown on quit,
  multi-path binary resolution for dev/production builds.

- Hidden chain support: zcash-shielded chain hidden from Dashboard grid
  but accessible internally via Privacy tab.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sidecar improvements:
- Enhanced startup lifecycle with health check retries
- Better error handling for binary path resolution
- Improved NDJSON IPC robustness

Scanner improvements:
- Subtree root fetching for ShardTree construction
- Improved compact block trial decryption
- Better nullifier tracking for spend detection
- GetTreeState and GetSubtreeRoots gRPC integration

PCZT builder improvements:
- Real Merkle witness computation from ShardTree
- Halo2 proof generation for Orchard actions
- v5 transaction serialization with proper padding
- RedPallas signature application

Frontend:
- Enhanced ZcashPrivacyTab with better status display
- Improved scanning progress and error feedback

Update submodule refs:
- device-protocol: feature-zcash (messages-zcash.proto)
- hdwallet: feature-zcash (zcash.ts + wallet wiring)
- Remove dev-only startHeight:3260068 from ZcashPrivacyTab scan
- Wire memo through full stack: buildShieldedTx → sidecar IPC → Rust build_pczt → Orchard note encryption
- Add enc_ciphertext length validation before buffer slicing (panic guard)
- Add sendCommand timeout (300s default) to prevent hung sidecar requests
- Fix JSON parse error to reject pending request instead of leaving it hanging
- Add REST API input validation: seed_hex format, amount bounds, signature format
- Redact FVK key material from debug logs, move signature diagnostics to debug level
- Fix init failure status: show not_running instead of masking as ready
- Suppress 6 Rust compiler warnings (dead_code on reference implementations)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
H1-1: Fix witness ordering — iterate sorted_by_pos for checkpoint ID alignment
H1-2: Replace FIFO queue with request-ID Map in sidecar IPC (TS + Rust)
H2-1: Validate signature count matches action count in finalize_pczt
H2-2: Replace .unwrap() with .ok()? in scanner for untrusted gRPC data
H2-3: Disable seed_hex REST endpoint (dev-only path removed)
H2-4: Add concurrency guard to prevent concurrent sendShielded calls
H2-5: Validate device signature array length matches n_actions
M1: Promote verify_result log to hard error on signature failure
M2: Use full 32-byte ak hash for FVK fingerprint comparison
M3: String-based decimal→zatoshi conversion (no float precision loss)
M4: Validate memo byte-length (512 max) before send
L1: Extract hardcoded English strings to i18n keys

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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