-
Notifications
You must be signed in to change notification settings - Fork 90
feat: hdwallet-ledger zcash support #765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
56 commits
Select commit
Hold shift + click to select a range
a658fbe
fix: bs58check v4 compatibility for Tron and UTXO derivation
gomesalexandre 50dbb83
feat: add ledger support for zcash transparent addresses
gomesalexandre 1a16460
chore: version packages to 1.62.24-ledger-zcash.0
gomesalexandre aa0c4bf
docs: add zcash ledger implementation tracking document
gomesalexandre fdfa8b0
chore: version packages to 1.62.24-ledger-zcash.15
gomesalexandre f9f1792
chore: version to .16 - add input hex logging
gomesalexandre a58c8bd
fix: pass blockHeight per input for Zcash
gomesalexandre f92482a
fix: add blockHeight to BTCSignTxInputLedger type and logging
gomesalexandre 422a7ce
chore: downgrade hw-app-btc to 10.12.0
gomesalexandre 00f3fae
fix: manually construct Zcash v5 unsigned transaction
gomesalexandre 2301d6a
feat: use @bitgo/utxo-lib for Zcash Ledger v5 transactions
gomesalexandre bb56a2f
chore: version .22
gomesalexandre ff430e0
fix: use script format for Zcash PSBT outputs, not address
gomesalexandre 7461d8b
[skip ci] wip: cancel ci
gomesalexandre 2789a97
fix: use script format for Zcash outputs
gomesalexandre 6de79ca
docs: update implementation status
gomesalexandre ddc2e2f
chore: version .25
gomesalexandre b3608eb
[skip ci] chore: cancel CI
gomesalexandre 774cdbe
feat: more logs
gomesalexandre 64d6f05
fix: add inputs to Zcash PSBT before extracting unsigned transaction
gomesalexandre bd0433f
fix: use psbt.data.globalMap.unsignedTx.toBuffer() for Zcash like Swa…
gomesalexandre 4fa60f6
fix: try VERSION5_BRANCH_NU6_1 instead of VERSION4
gomesalexandre 3731b2c
fix: manually set versionGroupId for VERSION4_BRANCH_NU6_1
gomesalexandre c0ea27d
debug: log split tx consensusBranchId
gomesalexandre bb33565
fix: pre-set consensusBranchId on split input transaction
gomesalexandre d3dbd54
fix: remove blockHeight from inputs array since consensusBranchId is …
gomesalexandre 9170e4d
fix: remove psbt.addInput() - Ledger handles inputs via splitTransact…
gomesalexandre b2f347f
fix: use input blockHeight instead of hardcoded 3200000
gomesalexandre 1b1fd35
fix: pass Zcash params when splitting unsigned transaction
gomesalexandre ba7598f
fix: progress maybe
gomesalexandre 08e2c6d
feat: attempt more fix
gomesalexandre 9481c05
feat: versioning
gomesalexandre 5182720
feat: more debuggy
gomesalexandre 7babff7
feat: versioning
gomesalexandre b32bc69
feat: at this point i have no idea what im doing
gomesalexandre 23b53c5
fix: it works jfc
gomesalexandre c3cf796
feat: cleanup
gomesalexandre 076663e
[skip ci] chore: cancel CI
gomesalexandre f3c0f2f
feat: cleanup
gomesalexandre 7132cfe
feat: and more
gomesalexandre f0a41a1
[skip ci] chore: cancel CI
gomesalexandre c89cb36
[skip ci] fix: more lint fix
gomesalexandre b6ea580
[skip ci] feat: cleanup
gomesalexandre 22b9b61
Merge origin/master, preserving local version bumps and dependencies
gomesalexandre c429aaa
[skip ci] feat: bump and cleanup
gomesalexandre 801b398
feat: cleanup
gomesalexandre a734254
feat: cleanup
gomesalexandre 639a63d
feat: ready
gomesalexandre 4addc67
fix: align @ledgerhq/hw-app-btc to v10.13.0 and fix docs
gomesalexandre 2116cf6
fix: add Zcash to btcSupportsScriptType in Ledger wallet
gomesalexandre b87db14
fix: upstream yarn
gomesalexandre 6063fdc
fix: regen yarn.lock with upstream yarn
gomesalexandre f82a981
fix: hey siri how to get a job as a shepherd fast tyvm
gomesalexandre edadf99
fix: add Jest moduleNameMapper for @brandonblack/musig subpath exports
gomesalexandre 9964e15
fix: the actual fix
gomesalexandre 7268cb5
chore(release): publish 1.62.26
gomesalexandre File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| # Zcash Ledger Implementation Guide | ||
|
|
||
| This document outlines the changes required to support Zcash (ZEC) on Ledger devices within `hdwallet`. | ||
|
|
||
| ## Overview | ||
| Zcash support on Ledger requires specific handling due to its unique transaction format (ZIP-244, v4/v5 versions) and consensus branch IDs. The standard Bitcoin app on Ledger does not natively support these features without specific flags and updated libraries. | ||
|
|
||
| --- | ||
|
|
||
| ## Technical Specifications | ||
|
|
||
| ### BIP44 Derivation Path | ||
| - **SLIP44 Code**: 133 | ||
| - **Standard Path**: `m/44'/133'/0'/0/x` | ||
| - **Account Type**: P2PKH (Legacy) only - no SegWit support | ||
|
|
||
| ### Transaction Format | ||
| - **Versions**: v4 (Sapling), v5 (NU5+) | ||
| - **Version Encoding**: Little-endian with Overwinter flag | ||
| - v4: `0x80000004` | ||
| - v5: `0x80000005` | ||
| - **Version Group IDs**: | ||
| - v4 (Sapling): `0x892F2085` | ||
| - v5 (NU5+): `0x26A7270A` | ||
|
|
||
| ### Consensus Branch IDs | ||
| - **NU5**: `0xC2D6D0B4` (block 1,687,104) | ||
| - **NU6**: `0xC8E71055` (block 2,726,400 - Nov 2024) | ||
| - **NU6.1**: `0x4DEC4DF0` (block 3,146,400 - Nov 2025) | ||
|
|
||
| ### Address Format | ||
| - **Transparent addresses** (t-addresses): Start with "t1" (mainnet) | ||
| - **No shielded support**: z-addresses not supported in this implementation | ||
|
|
||
| --- | ||
|
|
||
| ## Issues & Solutions Discovered | ||
|
|
||
| ### Issue 1: `getVarint called with unexpected parameters` | ||
| **Error**: `splitTransaction` failed with varint parsing error | ||
| **Root Cause**: Missing `additionals` parameter when calling `splitTransaction` | ||
| **Solution**: Pass `["zcash", "sapling"]` as 4th parameter | ||
| **Reference**: [Ledger splitTransaction tests](https://github.com/LedgerHQ/ledger-live/blob/develop/libs/ledgerjs/packages/hw-app-btc/tests/splitTransaction.test.ts) | ||
|
|
||
| ### Issue 2: Ledger App Quits / USB Transfer Cancelled | ||
| **Error**: `AbortError: Failed to execute 'transferIn' on 'USBDevice'` | ||
| **Root Cause**: Wrong `isSegwit` parameter value (was `false`, should be `true`) | ||
| **Solution**: Set 2nd parameter to `true` for Zcash in `splitTransaction` | ||
| **Reference**: Ledger test file shows `splitTransaction(hex, true, true, ["zcash", "sapling"])` | ||
|
|
||
| ### Issue 3: Consensus Branch ID Mismatch (NU6 vs NU6.1) | ||
| **Error**: `transaction uses an incorrect consensus branch id` | ||
| **Root Cause**: Zcash network upgraded to NU6.1 (0x4DEC4DF0), but older Ledger libraries defaulted to NU6. | ||
| **Solution**: | ||
| - Use `@ledgerhq/hw-app-btc` version `10.13.0` (strictly pinned across all packages) | ||
| - Explicitly set `consensusBranchId` in the adapter if necessary. | ||
|
|
||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ### Issue 4: Invalid Trusted Input Hash (Zcash v5) | ||
| **Error**: "Missing inputs" error or invalid signature verification on broadcast. | ||
| **Root Cause**: `@ledgerhq/hw-app-btc` uses Double-SHA256 (SHA256d) to calculate the transaction hash for trusted inputs. However, Zcash v5 transactions use ZIP-244 transaction digests (Tree Hash) for the TXID. The library fails to handle this correctly for Zcash inputs, resulting in a mismatch between the trusted input's TXID and the actual input being signed. | ||
| **Solution**: **Monkey Patch** implemented in `packages/hdwallet-ledger/src/bitcoin.ts`. | ||
| - **Mechanism**: We patch `getTrustedInputBIP143` to intercept Zcash transactions. | ||
| - **Fix**: The patch injects the correct ZIP-244 TXID (provided by the adapter via `_customZcashTxId`) and Amount, bypassing the library's faulty re-hashing logic. | ||
| - **Safety**: The patch is strictly guarded to only affect Zcash transactions with the custom properties attached. Trusted input security is maintained as the Ledger device still verifies the signature. | ||
| - **Implementation**: Uses `require` to modify the CommonJS exports of the library, as ES6 imports are immutable. | ||
|
|
||
| --- | ||
|
|
||
| ## Known Limitations | ||
|
|
||
| ### 1. Transparent Addresses Only | ||
| - Only supports t-addresses (transparent UTXO transactions) | ||
| - Does **not** support z-addresses (shielded transactions) | ||
|
|
||
| ### 2. Expiry Height Management | ||
| - **Current**: Hardcoded to 0 (no expiry) using `Buffer.alloc(4)` in the implementation. | ||
| - **Requirement**: Zcash transactions require `expiryHeight`. If 0, it means no expiry (valid per ZIP-203). | ||
| - **Note**: The current implementation does not derive expiry from input block height. | ||
|
|
||
| --- | ||
|
|
||
| ## Files Modified | ||
|
|
||
| | File | Changes | | ||
| |------|---------| | ||
| | `packages/hdwallet-ledger/src/bitcoin.ts` | **Major Update**: Added Monkey Patch for `getTrustedInputBIP143`. Logic for Zcash inputs (using `ZcashPsbt`, `splitTransaction` params). Constants for Version/Branch IDs. | | ||
| | `packages/hdwallet-ledger/src/utils.ts` | Configured `isSegwitSupported: true` and `areTransactionTimestamped: true` for Zcash (SLIP-133). | | ||
| | `packages/hdwallet-ledger/src/currencies.ts` | Added Zcash currency with xpub version. | | ||
|
|
||
| --- | ||
|
|
||
| ## Testing Checklist | ||
|
|
||
| - [x] Address derivation works (t-address format) | ||
| - [x] Transaction signing initiates | ||
| - [x] Ledger app stays open during signing | ||
| - [x] splitTransaction parses input transactions correctly | ||
| - [x] **Consensus Branch ID** matches NU6.1 (0x4DEC4DF0) | ||
| - [x] **Trusted Input Hashing** matches ZIP-244 (via Monkey Patch) | ||
| - [x] Broadcast succeeds (Simulated/Verified) | ||
| - [ ] Swap works end-to-end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.