Project Summary
TxGuard is a small CLI and GitHub Action that checks a Zcash v5 transaction’s embedded consensus branch ID against what a target node expects in the current upgrade context, and fails CI (or pre-broadcast) on mismatch. It prevents a recurring “can’t send” failure mode seen across wallets during 2024–2025 upgrade events by catching branch-ID mistakes before release.
Project Description
TxGuard is a small, focused developer tool meant to reduce a specific and recurring class of Zcash send failures: broadcasting a Zcash v5 transaction with an incorrect embedded consensus branch ID, which can cause the transaction to be rejected, particularly around network upgrade boundaries. When this happens, wallet/service teams typically need to ship a fix before users can send again.
The project will deliver an open-source command-line tool and a GitHub Action that external wallet and service teams can run in CI or as a pre-broadcast check. TxGuard takes a raw v5 transaction hex produced by the team’s code and verifies branch-ID alignment in one of two ways:
-
Online mode (recommended): TxGuard queries a target node via RPC and derives the expected branch ID from the node’s reported upgrade context. If the required fields are missing or ambiguous, it fails closed with an “insufficient context” error rather than guessing.
-
Offline mode: Teams can supply an explicit expected branch ID when CI cannot reach a node, and TxGuard performs the same comparison deterministically.
TxGuard is CI-friendly: it returns stable exit codes and can emit a machine-readable JSON report so teams can gate releases and diagnose mismatches quickly. An optional wrapper mode is included for broadcast services: it runs the same check before calling sendrawtransaction, so mismatched transactions can be blocked before a broadcast attempt.
The goals of the project are:
-
Reduce the chance of user-facing send failures caused by branch-ID mismatches by catching them before release or broadcast.
-
Make the check easy to adopt by shipping a standalone CLI, a copy/paste GitHub Action example, clear documentation, and deterministic outputs.
-
Avoid false confidence by keeping scope narrow (branch-ID alignment only), failing closed on unknowns, and clearly stating what the tool does not validate.
-
Make the work reusable by including a minimal vector pack (good/bad fixtures) and an optional upstream-ready patch bundle, without depending on any upstream merge for TxGuard itself to be useful.
Proposed Problem
A recurring and user-blocking problem in the Zcash ecosystem is wallets and services producing Zcash v5 transactions with an incorrect embedded consensus branch ID, especially around network upgrade boundaries. When this happens, the transaction is rejected at broadcast time and users cannot send funds until the wallet/service software is updated and redeployed. This is not a theoretical edge case; it has surfaced repeatedly across different wallet contexts and implementations.
In practice, this failure mode is painful for both users and developers:
-
Users experience “can’t send” failures with confusing errors (for example, branch ID mismatch) and often assume Zcash itself is broken.
-
Wallet and service teams face urgent support load and must ship fixes quickly, because the issue blocks normal funds movement.
-
The same class of failure repeats at upgrades because branch ID correctness is an upgrade-edge requirement, and it is easy for external stacks (especially those built on custom or forked transaction logic) to miss an update.
This recurring breakage is visible in public 2024–2025 reports and upstream work:
-
Ledger Live users reporting
bad-tx-consensus-branch-id-mismatchwhen trying to move ZEC (Nov 2024):
https://forum.zcashcommunity.com/t/trying-to-move-zec-from-ledger-live/49337 -
“Zcash stuck in a wallet” FAQ explaining NU6 changed the consensus branch ID and some wallets were not prepared (Dec 2024):
https://forum.zcashcommunity.com/t/zcash-stuck-in-a-wallet-check-here/49752 -
Zebra issue showing sendrawtransaction failing because a tx “uses an incorrect consensus branch id” (Dec 2024):
bug: Coinbase funds are not spendable in zebra regtest mode. ZcashFoundation/zebra#9082 -
Zebra 2.1.0 release note describing verification of correct branch ID for v5 mempool transactions (Dec 2024):
https://zfnd.org/zebra-2-1-0-release/ -
Zebra 2.2.0 release note adding an additional consensus check on branch ID of NU6 transactions (Feb 2025):
https://zfnd.org/zebra-2-2-0-release/ -
NU 6.1 activation “issues thread,” which anticipates software issues and points developers to node-level checks like
getblockchaininfo(Nov 2025):
https://forum.zcashcommunity.com/t/nu-6-1-activation-is-here/53386 -
Transparent key sweep/import issue reporting “transaction uses an incorrect consensus branch id” right after NU 6.1 activation (Nov 2025):
https://forum.zcashcommunity.com/t/trouble-importing-transparent-private-key-any-suggestions/53450 -
YWallet support thread showing users unable to transfer funds after NU 6.1 with branch-ID related errors (Nov 2025):
https://forum.zcashcommunity.com/t/ywallet-technical-support/45569?page=4
Even though documentation exists, these incidents show that documentation alone does not reliably prevent implementations from shipping the wrong branch ID. What is missing is a small, CI-friendly enforcement step that checks the actual transaction bytes produced by a wallet/service before release or broadcast. This proposal directly targets that gap.
Proposed Solution
This project will deliver TxGuard, a small CI-first tool that helps wallet and service teams catch a specific upgrade-edge mistake before release or broadcast: producing a Zcash v5 transaction with an incorrect embedded consensus branch ID, which can cause the node to reject the transaction.
TxGuard performs one narrow check:
Does the transaction’s embedded consensus branch ID match the expected branch ID for the target node’s current upgrade state?
What TxGuard provides (v1)
1) Standalone CLI (runs locally or in CI)
TxGuard takes a raw v5 transaction hex produced by the team’s code and compares the transaction’s embedded branch ID against an expected value:
-
Online mode (recommended):
txguard check --rawtx <hex> --rpc <node_rpc_url>
TxGuard queries the target node via RPC and derives an expected branch ID from the node’s reported upgrade context. If the node response does not provide enough information to derive an expected value, TxGuard fails with an “insufficient context” error rather than guessing. -
Offline mode:
txguard check --rawtx <hex> --expected-branchid <hex>
For environments where CI cannot reach a node, teams can supply the expected branch ID explicitly and the check remains deterministic.
TxGuard outputs:
-
a clear pass/fail result,
-
an optional machine-readable JSON report (
--json report.json), and -
a CI-friendly exit code (
0pass
Solution Format
-
A small command-line tool (TxGuard) distributed as release binaries (and optionally a container image).
-
A GitHub Action wrapper that runs TxGuard in CI and can upload a JSON report artifact on failure.
-
A machine-readable JSON report format plus stable exit codes so teams can gate releases and troubleshoot mismatches quickly.
-
A minimal fixture/vector pack (good/bad examples) used for TxGuard’s own tests, plus an optional upstream-ready patch bundle (not required for TxGuard to work).
-
Documentation: quickstart, CI integration snippet, wrap/broadcast usage, and a short troubleshooting guide.
Dependencies
Technical dependencies
-
A standard development environment for building a small CLI tool (open-source toolchain and libraries for parsing hex/bytes and producing JSON output).
-
For online mode, access to a Zcash node RPC endpoint (in test/staging) that supports
getblockchaininfo. TxGuard also supports an offline mode where the expected branch ID is provided explicitly. -
Release tooling for security hygiene: signing for release tags/artifacts, SBOM generation, and reproducible build steps (verified in CI).
Resources
-
Developer time for implementation, tests (including basic fuzz/property tests), documentation, release packaging, and a 90-day maintenance window.
-
CI to run tests and publish artifacts (e.g., GitHub Actions or equivalent).
Collaborations
-
No formal collaborations is required.
-
Optional community feedback via public issues/threads.
Technical Approach
1) Implementation and packaging
-
Implement TxGuard as a single CLI (Rust is a good fit for safe, deterministic parsing and distributing stable binaries).
-
Publish versioned release binaries. A minimal container image is optional and only for easier CI usage (the tool must work without Docker).
**2) v5 transaction parsing **
-
Parse only what is required from the raw transaction bytes to:
-
confirm the transaction is v5, and
-
extract the embedded consensus branch ID field.
-
-
Use bounded parsing with explicit error returns (no panics on malformed inputs).
3)Expected branch ID derivation
-
Online mode: call a target node RPC endpoint and derive an expected branch ID from the node’s reported upgrade context. If the expected value cannot be derived from the RPC response, TxGuard returns a clear “insufficient context” failure rather than guessing.
-
Offline mode: accept
--expected-branchid <hex>so teams can run the check deterministically in CI environments where RPC access is not available.
Note: TxGuard does not depend on any deprecated node stack. Online mode works with any node implementation that exposes the required RPC fields; offline mode works even without node access.
4)Check + reporting
-
txguard checkcompares:-
tx embedded branch ID, vs
-
expected branch ID ,
and returns: -
stable exit codes,
-
a short human-readable summary, and
-
optional JSON output (
--json) for CI artifacts.
-
-
txguard inspectprints only the parsed tx version and embedded branch ID to support debugging.
5) Testing and correctness safeguards
-
Unit tests for parsing and mismatch detection using a minimal fixture pack (good/bad examples).
-
Mocked-RPC tests for online mode, so behavior is reproducible and does not rely on live infrastructure.
-
Basic fuzz/property tests focused on parser safety and report serialization (ensuring malformed inputs cannot crash the tool).
6) Release hygiene
-
Signed tags and/or signed release artifacts.
-
SBOM generation for releases.
-
Documented build steps that CI can reproduce (pinned toolchain/dependencies and repeatable release workflow).
Upstream Merge Opportunities
TxGuard does not fork or modify any upstream Zcash repositories. It will ship as a standalone tool and does not depend on upstream merges.
Hardware/Software Costs (USD)
0
Hardware/Software Justification
n/a
Service Costs (USD)
0
Service Costs Justification
n/a
Compensation Costs (USD)
$21,000
Compensation Costs Justification
-
Core development, tests, docs, CI/Action, and release hygiene: ~175 hours × $100/hr = $17,500
-
90-day light maintenance (bug fixes, minor compatibility adjustments, support): ~40 hours × $100/hr = $4,000
Total: 215 hours × $100/hr = $21,500
Total Budget (USD)
$21,000
Previous Funding
No
Previous Funding Details
No response
Other Funding Sources
No
Other Funding Sources Details
No response
Implementation Risks
-
RPC field variability: Online mode relies on extracting the expected branch ID from
getblockchaininfo. If required fields are missing or differ across nodes, TxGuard must fail closed and direct users to offline mode. -
Scope control: There is a risk of expanding beyond the intended v1 (v5 branch-ID alignment). v1 must stay limited to that single check to remain feasible.
-
Input handling: TxGuard must handle malformed tx hex or missing parameters safely, returning clear errors without crashing.
-
Maintenance: If relevant RPC response fields change, the online extraction logic may need small updates during the 90-day maintenance window.
Potential Side Effects
-
False sense of full validity: Teams might treat a “pass” as meaning the transaction is fully valid. TxGuard will mitigate this by clearly stating in output and documentation that it only checks branch-ID alignment, not full transaction validity.
-
Extra CI friction: Adding a new CI step can block releases if the tool can’t verify (e.g., RPC unavailable) or detects mismatches. This is intentional for safety, but it may require teams to adjust workflows (using offline mode where needed).
-
Misconfiguration risk: If a team supplies the wrong expected branch ID in offline mode, TxGuard will still behave deterministically, but they could block themselves unnecessarily. Documentation will emphasize correct parameter handling and when to prefer online mode.
Success Metrics
Adoption in real projects:
-
Within ~90 days of v1.0, at least 10 external repositories (not owned by us) using TxGuard in CI (via the Action or CLI).
- Within ~180 days, at least 25 external repositories using it.
-
Evidence it prevents real failures:
- At least 2 public examples (issue/PR/forum post) within 180 days where TxGuard output is referenced as catching a branch-ID mismatch before release or broadcast.
-
Basic usage volume:
- At least 300 downloads/pulls (release binaries and/or container pulls) within 90 days, and 1,000 within 180 days.
-
Maintenance performance:
- During the 90-day maintenance window, confirmed bugs reported by users are either fixed in a patch release or documented with a workaround within the window.
Startup Funding (USD)
n/a
Startup Funding Justification
n/a
Milestone Details
-
Milestone: M1 — Core CLI (v5 parse + inspect + offline check)
Amount (USD): 5,500
Expected Completion Date: 2026-01-20
User Stories:- “As a wallet/service developer, I want to inspect a raw Zcash v5 transaction and see its embedded consensus branch ID, so that I can debug branch-ID mismatch failures faster.”
- “As a CI engineer, I want an offline branch-ID check with stable exit codes, so that I can run the check even when CI cannot reach a node RPC endpoint.”
Deliverables: txguard inspect --rawtx <hex> [--json](prints tx version and embedded branch ID)txguard check --rawtx <hex> --expected-branchid <hex> [--json report.json](offline mode)- Minimal fixtures for TxGuard self-tests:
good_v5.hexandbad_wrong_branchid.hex - Unit tests for v5 parsing and mismatch detection
Acceptance Criteria: - Running
txguard inspectongood_v5.hexprintstx_version=5and a branch ID value. - Running
txguard checkpasses ongood_v5.hexand fails onbad_wrong_branchid.hexwith a non-zero exit code and a mismatch message. - All unit tests pass in CI.
-
Milestone: M2 — Online mode (RPC-derived expected branch ID, fail-closed)
Amount (USD): 6,000
Expected Completion Date: 2026-02-03
User Stories:- “As a developer, I want TxGuard to derive an expected branch ID from my target node’s RPC output, so that I don’t have to hardcode upgrade constants.”
- “As a release engineer, I want the tool to fail when it cannot determine an expected value from RPC, so that CI does not report a false pass.”
Deliverables: txguard check --rawtx <hex> --rpc <node_rpc_url> [--json report.json](online mode)- Mocked-RPC fixtures and tests covering: pass, mismatch fail, and “insufficient context” fail
- JSON report includes
tx_branch_id,expected_branch_id(when available), andverification_mode(online/offline)
Acceptance Criteria: - With mocked RPC fixtures,
txguard checkreturns the expected exit codes for pass/mismatch/insufficient-context cases. - If required RPC fields are missing/ambiguous, TxGuard fails with “insufficient context” and a non-zero exit code.
-
Milestone: M3 — GitHub Action + optional wrap-sendrawtransaction mode
Amount (USD): 5,000
Expected Completion Date: 2026-02-17
User Stories:- “As a CI engineer, I want a copy/paste GitHub Action step, so that I can add TxGuard to CI quickly.”
- “As a service operator, I want an optional pre-broadcast wrapper, so that I can block branch-ID mismatched transactions before attempting to broadcast.”
Deliverables: - GitHub Action wrapper that runs
txguard checkand can upload the JSON report artifact on failure - Example workflow in the TxGuard repo demonstrating both a passing and failing fixture
- Optional
txguard wrap-sendrawtransaction --rpc <url> --rawtx <hex>command with documented behavior - Short documentation: “Add to CI” and “Use wrap mode”
Acceptance Criteria: - The example workflow fails on
bad_wrong_branchid.hex, passes ongood_v5.hex, and uploadsreport.jsonon failure. - Wrap mode blocks a mismatch and returns a clear error without broadcasting (validated via a stubbed RPC test).
-
Milestone: M4 — Release hardening + vector pack + upstream-ready patch bundle
Amount (USD): 3,000
Expected Completion Date: 2026-03-03
User Stories:- “As an integrator, I want verifiable releases (signing + SBOM), so that I can trust TxGuard in CI.”
- “As a maintainer, I want a small fixture/vector pack that can be proposed upstream, so that this failure class is easier to test elsewhere if maintainers choose.”
Deliverables: - Signed release tag and/or signed artifacts for v1.0.0
- SBOM generated and published with the release
- Reproducible build instructions verified in CI
- Minimal vector pack under
vectors/branchid/and an optionalformat-patch/bundle - Basic fuzz/property tests for parser safety (bounded runtime in CI)
Acceptance Criteria: - v1.0.0 release exists with verification instructions and an SBOM artifact.
- CI includes a documented build path that produces the release artifacts.
- Fuzz/property tests run in CI for a bounded duration without crashes.
-
Milestone: M5 — 90-day maintenance window
Amount (USD): 2,500
Expected Completion Date: 2026-06-03
User Stories:- “As an adopter, I want early bugs addressed promptly, so that the tool remains usable during initial adoption.”
Deliverables: - Up to ~40 hours of maintenance: bug fixes, minor compatibility adjustments (e.g., RPC-shape handling), documentation clarifications
- One patch release if needed during the window
Acceptance Criteria: - Issues filed during the window receive an initial response within 7 days.
- Confirmed bugs are fixed in a patch release or documented with a workaround during the maintenance period.
- “As an adopter, I want early bugs addressed promptly, so that the tool remains usable during initial adoption.”