Skip to content

Commit 4b89ac9

Browse files
Merge pull request #78 from BitGo/BTC-2659.add-zcash-support
feat(wasm-utxo): add Zcash support
2 parents c953971 + 5df410a commit 4b89ac9

File tree

72 files changed

+4238
-728
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+4238
-728
lines changed

packages/wasm-utxo/Cargo.lock

Lines changed: 1957 additions & 86 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/wasm-utxo/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ all = "warn"
1616
[dependencies]
1717
wasm-bindgen = "0.2"
1818
js-sys = "0.3"
19-
miniscript = { git = "https://github.com/BitGo/rust-miniscript", tag = "miniscript-13.0.0-opdrop-forkid" }
19+
miniscript = { git = "https://github.com/BitGo/rust-miniscript", tag = "miniscript-13.0.0-bitgo.1" }
2020
bech32 = "0.11"
2121
musig2 = { version = "0.3.1", default-features = false, features = ["k256"] }
2222
getrandom = { version = "0.2", features = ["js"] }
@@ -31,6 +31,9 @@ wasm-bindgen-test = "0.3"
3131
rstest = "0.26.1"
3232
pastey = "0.1"
3333

34+
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
35+
zebra-chain = { version = "3.1", default-features = false }
36+
3437
[profile.release]
3538
# this is required to make webpack happy
3639
# https://github.com/webpack/webpack/issues/15566#issuecomment-2558347645

packages/wasm-utxo/README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,16 @@ This project is under active development.
2020
| Descriptor Wallet: Address Support | ✅ Complete | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
2121
| Descriptor Wallet: Transaction Support | ✅ Complete | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
2222
| FixedScript Wallet: Address Generation | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete |
23-
| FixedScript Wallet: Transaction Support | ✅ Complete | ✅ Complete | ✅ Complete | ⏳ TODO | ⏳ TODO | ✅ Complete | ⏳ TODO |
23+
| FixedScript Wallet: Transaction Support | ✅ Complete | ✅ Complete | ✅ Complete | ⏳ TODO | ⏳ TODO | ✅ Complete | ✅ Complete |
24+
25+
### Zcash Features
26+
27+
Zcash support includes:
28+
29+
- **Network Upgrade Awareness**: Automatic consensus branch ID determination based on block height
30+
- **All Network Upgrades**: Support for Overwinter, Sapling, Blossom, Heartwood, Canopy, Nu5, Nu6, and Nu6_1
31+
- **Height-Based API**: Preferred `createEmpty()` method automatically selects correct consensus rules
32+
- **Parity Testing**: Validated against `zebra-chain` for accuracy across all network upgrades
2433

2534
## Building
2635

packages/wasm-utxo/cli/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,5 @@ base64 = "0.21"
1616
serde = { version = "1.0", features = ["derive"] }
1717
serde_json = "1.0"
1818
num-bigint = "0.4"
19-
bitcoin = { git = "https://github.com/BitGo/rust-bitcoin", tag = "bitcoin-0.32.8-forkid" }
2019
colored = "2.1"
2120
ptree = "0.5"

packages/wasm-utxo/cli/src/parse/node.rs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/// This contains low-level parsing of PSBT into a node structure suitable for display
2-
use bitcoin::consensus::Decodable;
3-
use bitcoin::hashes::Hash;
4-
use bitcoin::psbt::Psbt;
5-
use bitcoin::{Network, ScriptBuf, Transaction};
2+
use wasm_utxo::bitcoin::consensus::Decodable;
3+
use wasm_utxo::bitcoin::hashes::Hash;
4+
use wasm_utxo::bitcoin::psbt::Psbt;
5+
use wasm_utxo::bitcoin::{Network, ScriptBuf, Transaction};
66
use wasm_utxo::fixed_script_wallet::bitgo_psbt::{
77
p2tr_musig2_input::{Musig2PartialSig, Musig2Participants, Musig2PubNonce},
88
BitGoKeyValue, ProprietaryKeySubtype, BITGO,
@@ -21,8 +21,11 @@ fn script_buf_to_node(label: &str, script_buf: &ScriptBuf) -> Node {
2121

2222
fn bip32_derivations_to_nodes(
2323
bip32_derivation: &std::collections::BTreeMap<
24-
bitcoin::secp256k1::PublicKey,
25-
(bitcoin::bip32::Fingerprint, bitcoin::bip32::DerivationPath),
24+
wasm_utxo::bitcoin::secp256k1::PublicKey,
25+
(
26+
wasm_utxo::bitcoin::bip32::Fingerprint,
27+
wasm_utxo::bitcoin::bip32::DerivationPath,
28+
),
2629
>,
2730
) -> Vec<Node> {
2831
bip32_derivation
@@ -100,7 +103,10 @@ fn musig2_partial_sig_to_node(sig: &Musig2PartialSig) -> Node {
100103
node
101104
}
102105

103-
fn bitgo_proprietary_to_node(prop_key: &bitcoin::psbt::raw::ProprietaryKey, v: &[u8]) -> Node {
106+
fn bitgo_proprietary_to_node(
107+
prop_key: &wasm_utxo::bitcoin::psbt::raw::ProprietaryKey,
108+
v: &[u8],
109+
) -> Node {
104110
// Try to parse as BitGo key-value
105111
let v_vec = v.to_vec();
106112
let bitgo_kv_result = BitGoKeyValue::from_key_value(prop_key, &v_vec);
@@ -159,7 +165,7 @@ fn bitgo_proprietary_to_node(prop_key: &bitcoin::psbt::raw::ProprietaryKey, v: &
159165

160166
fn raw_proprietary_to_node(
161167
label: &str,
162-
prop_key: &bitcoin::psbt::raw::ProprietaryKey,
168+
prop_key: &wasm_utxo::bitcoin::psbt::raw::ProprietaryKey,
163169
v: &[u8],
164170
) -> Node {
165171
let mut prop_node = Node::new(label, Primitive::None);
@@ -177,7 +183,10 @@ fn raw_proprietary_to_node(
177183
}
178184

179185
fn proprietary_to_nodes(
180-
proprietary: &std::collections::BTreeMap<bitcoin::psbt::raw::ProprietaryKey, Vec<u8>>,
186+
proprietary: &std::collections::BTreeMap<
187+
wasm_utxo::bitcoin::psbt::raw::ProprietaryKey,
188+
Vec<u8>,
189+
>,
181190
) -> Vec<Node> {
182191
proprietary
183192
.iter()
@@ -194,8 +203,11 @@ fn proprietary_to_nodes(
194203

195204
fn xpubs_to_nodes(
196205
xpubs: &std::collections::BTreeMap<
197-
bitcoin::bip32::Xpub,
198-
(bitcoin::bip32::Fingerprint, bitcoin::bip32::DerivationPath),
206+
wasm_utxo::bitcoin::bip32::Xpub,
207+
(
208+
wasm_utxo::bitcoin::bip32::Fingerprint,
209+
wasm_utxo::bitcoin::bip32::DerivationPath,
210+
),
199211
>,
200212
) -> Vec<Node> {
201213
xpubs
@@ -215,8 +227,11 @@ fn xpubs_to_nodes(
215227

216228
pub fn xpubs_to_node(
217229
xpubs: &std::collections::BTreeMap<
218-
bitcoin::bip32::Xpub,
219-
(bitcoin::bip32::Fingerprint, bitcoin::bip32::DerivationPath),
230+
wasm_utxo::bitcoin::bip32::Xpub,
231+
(
232+
wasm_utxo::bitcoin::bip32::Fingerprint,
233+
wasm_utxo::bitcoin::bip32::DerivationPath,
234+
),
220235
>,
221236
) -> Node {
222237
let mut xpubs_node = Node::new("xpubs", Primitive::U64(xpubs.len() as u64));
@@ -267,7 +282,7 @@ pub fn psbt_to_node(psbt: &Psbt, network: Network) -> Node {
267282
witness_node.add_child(Node::new(
268283
"address",
269284
Primitive::String(
270-
bitcoin::Address::from_script(&witness_utxo.script_pubkey, network)
285+
wasm_utxo::bitcoin::Address::from_script(&witness_utxo.script_pubkey, network)
271286
.map(|a| a.to_string())
272287
.unwrap_or_else(|_| "<invalid address>".to_string()),
273288
),
@@ -353,7 +368,7 @@ pub fn psbt_to_node(psbt: &Psbt, network: Network) -> Node {
353368
psbt_node
354369
}
355370

356-
pub fn tx_to_node(tx: &Transaction, network: bitcoin::Network) -> Node {
371+
pub fn tx_to_node(tx: &Transaction, network: wasm_utxo::bitcoin::Network) -> Node {
357372
let mut tx_node = Node::new("tx", Primitive::None);
358373

359374
tx_node.add_child(Node::new("version", Primitive::I32(tx.version.0)));
@@ -425,7 +440,9 @@ pub fn tx_to_node(tx: &Transaction, network: bitcoin::Network) -> Node {
425440
Primitive::Buffer(output.script_pubkey.as_bytes().to_vec()),
426441
));
427442

428-
if let Ok(address) = bitcoin::Address::from_script(&output.script_pubkey, network) {
443+
if let Ok(address) =
444+
wasm_utxo::bitcoin::Address::from_script(&output.script_pubkey, network)
445+
{
429446
output_node.add_child(Node::new("address", Primitive::String(address.to_string())));
430447
}
431448

packages/wasm-utxo/cli/src/parse/node_raw.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
///
2626
/// - [BIP-174: PSBT Format](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki)
2727
/// - [bitcoin::psbt::raw](https://docs.rs/bitcoin/latest/bitcoin/psbt/raw/index.html)
28-
use bitcoin::consensus::Decodable;
29-
use bitcoin::psbt::raw::{Key, Pair};
30-
use bitcoin::{Network, Transaction, VarInt};
28+
use wasm_utxo::bitcoin::consensus::Decodable;
29+
use wasm_utxo::bitcoin::psbt::raw::{Key, Pair};
30+
use wasm_utxo::bitcoin::{Network, Transaction, VarInt};
3131

3232
pub use crate::node::{Node, Primitive};
3333

packages/wasm-utxo/cli/test/fixtures/psbt_bitcoin_fullsigned.txt

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ psbt: None
22
├─ tx: None
33
│ ├─ version: 1i32
44
│ ├─ lock_time: 0u32
5-
│ ├─ txid: a8f0a1efb5a77f4fe2e40c379d3e122d3b30ac0b88aa80c6e70d3fd72a6cf736 (32 bytes)
6-
│ ├─ ntxid: a8f0a1efb5a77f4fe2e40c379d3e122d3b30ac0b88aa80c6e70d3fd72a6cf736 (32 bytes)
7-
│ ├─ wtxid: a8f0a1efb5a77f4fe2e40c379d3e122d3b30ac0b88aa80c6e70d3fd72a6cf736 (32 bytes)
5+
│ ├─ txid: 5e9a93a20ef076d902be4e361a633c35eec975633036e35e3890ba2d3daa78ae (32 bytes)
6+
│ ├─ ntxid: 5e9a93a20ef076d902be4e361a633c35eec975633036e35e3890ba2d3daa78ae (32 bytes)
7+
│ ├─ wtxid: 5e9a93a20ef076d902be4e361a633c35eec975633036e35e3890ba2d3daa78ae (32 bytes)
88
│ ├─ inputs: 7u64
99
│ │ ├─ input_0: None
1010
│ │ │ ├─ prev_txid: 7cce12effc2ea564c4227333fd305447e0de7b3ae7a5fcc751effff3ea1377e1 (32 bytes)
@@ -71,7 +71,7 @@ psbt: None
7171
│ │ ├─ script_pubkey: a914954288203f9697e25eaecb48d85b8a8608c385cf87 (23 bytes)
7272
│ │ └─ address: 3FJEJqGMWCA8XUnK1jypEy7bu74YMCT8eE
7373
│ └─ output_7: None
74-
│ ├─ value: 900u64
74+
│ ├─ value: 0u64
7575
│ └─ script_pubkey: 6a0f736574656320617374726f6e6f6d79 (17 bytes)
7676
├─ xpubs: 3u64
7777
│ ├─ xpub: None
@@ -95,10 +95,10 @@ psbt: None
9595
│ │ ├─ signatures: 2u64
9696
│ │ │ ├─ 0: None
9797
│ │ │ │ ├─ pubkey: 03e1524d7f6fc57ab3eacbb659b787106780a475d1db483952c2310b7e9a38975b (33 bytes)
98-
│ │ │ │ └─ signature: 3044022068576594f32f0196dce83d0a2fadde3e3670ae4cee22295337c406374a14496602205858f9cbf54285930c2004045440956db1953a67d305ca3db0206ffd7e7d534301 (71 bytes)
98+
│ │ │ │ └─ signature: 304402201720c319f1acfc962998bec10d8e1c918cd96f02d5f1b5ebf41c39ff1c627cba02206f7941de25ed468bf2e6ad1678d32d4a4ac2c19b74ea1c9a8089c7a2ba933cde01 (71 bytes)
9999
│ │ │ └─ 1: None
100100
│ │ │ ├─ pubkey: 03f6f40764bd5d63f200a2778883acf75e96f15095c998263c087270d0c97e7e7f (33 bytes)
101-
│ │ │ └─ signature: 3044022063f7d77b3e78d916fef10e0e3249730b0b364a07bd4d1de482e7dc3a6910e13402204925ac2db7e1e6a51970f288a12d88d8abfec4fc3b44686664f5a6d707e6b27101 (71 bytes)
101+
│ │ │ └─ signature: 304402204ed1631487b06c29f7e586998de96acd42ceec747e33dc52a455efd0059da14a0220615d8d2f159314c45ef79dd831419dc5cab1c21987d0fa14d0dbfba4113e216401 (71 bytes)
102102
│ │ ├─ sighash_type: 1u32
103103
│ │ ├─ sighash_type: SIGHASH_ALL
104104
│ │ ├─ bip32_derivation: None
@@ -125,10 +125,10 @@ psbt: None
125125
│ │ ├─ signatures: 2u64
126126
│ │ │ ├─ 0: None
127127
│ │ │ │ ├─ pubkey: 02234531bc9119a36a7946e95aeb74915dd087c7b44f517b8eeeb73f89a0ff1a99 (33 bytes)
128-
│ │ │ │ └─ signature: 304402204f46d55ab3c78be2dd7b2df1a04aa929478c32445ea948923dc36f13eea30d23022054db1d0f3e7922e1ee1e7c3610b73c0297050c37cc4ac12e8ac63cb71dc314a501 (71 bytes)
128+
│ │ │ │ └─ signature: 304402206a7b992610f302ac7320a999aa42531e8b623b0492768daf032c39d6d52ec7c60220670939f9ecd102ce69e98750060646db5e1fb162b1891350b95a8ff21378f83c01 (71 bytes)
129129
│ │ │ └─ 1: None
130130
│ │ │ ├─ pubkey: 02a585f3fab49b5ef95346d932221a221bd55ec191f15533e0f270b3582574f035 (33 bytes)
131-
│ │ │ └─ signature: 3045022100c3dddbc8b20f4aac003165182fb72357486da8a1538d151b06aca94f7894e169022050756f3949e780fd15e3a25baf7b3b3f674422c7ee8aff1d2f77a0f4d7f42ada01 (72 bytes)
131+
│ │ │ └─ signature: 304402200a2d971c408317038596ad6ab0ef17282fd3d8b368d599026bc4ef2dbe0d7ea40220415624b6b92e9846566cab7a828d22017d494064b72aa2620fd13225b54938d301 (71 bytes)
132132
│ │ ├─ sighash_type: 1u32
133133
│ │ ├─ sighash_type: SIGHASH_ALL
134134
│ │ ├─ bip32_derivation: None
@@ -153,10 +153,10 @@ psbt: None
153153
│ │ ├─ signatures: 2u64
154154
│ │ │ ├─ 0: None
155155
│ │ │ │ ├─ pubkey: 02e80a08885c353676b820cdc290e6d81a0ac95a03e8abbf4bb7aeebfb70feb418 (33 bytes)
156-
│ │ │ │ └─ signature: 3045022100a9a571f171172962c80bf97099c0f1a809bec183af83dabe65bfc51ff1084548022047376a83e5d8bd5bfb07c5720bf90535d9a0ba5837172235132530387618b95901 (72 bytes)
156+
│ │ │ │ └─ signature: 30440220162101914f7fadf5ca92de401acaf9f4e9995acfa222fc7bb09d692650290d81022020004b2656dda5efd0f8a48cdc5e362b092f53bc0a12bf32cbb96a00525bf27601 (71 bytes)
157157
│ │ │ └─ 1: None
158158
│ │ │ ├─ pubkey: 03519e572ab468560d1f8d0f87699d098308e166905f5dcae4390f060faa8f1ce3 (33 bytes)
159-
│ │ │ └─ signature: 304402207017fae20521ac634cfaf259714d370efcd196f83fb8d7c3133207900f27355902201e9b7f217987da96f77b3ba33e868987d13257cc03a05af959e34be2719fe1b501 (71 bytes)
159+
│ │ │ └─ signature: 3045022100e57d42ff5e19de633312bcdeea3a8d298c2f0b7da59b80af50570d7bb9f6678a022013488e7e86183467c4430fe88536f1e40ddd4eb1b64fdbf00d0d5195ccb757a001 (72 bytes)
160160
│ │ ├─ sighash_type: 1u32
161161
│ │ ├─ sighash_type: SIGHASH_ALL
162162
│ │ ├─ bip32_derivation: None
@@ -202,27 +202,27 @@ psbt: None
202202
│ │ ├─ musig2_pub_nonce: None
203203
│ │ │ ├─ participant_pub_key: 020fdea69e40a3adef3cdc7fa6f3af02f4c9d9e3254503c96a6a2b4aa66e778171 (33 bytes)
204204
│ │ │ ├─ tap_output_key: 15c5815026f6a54b10194fc6980f1866a02d9ec128533c7997cdb4289bf3ef16 (32 bytes)
205-
│ │ │ └─ pub_nonce: 02b4881cc04cf3173c6e8b15d00628725a2c13e7f4be2c1a282267a5ad99d75adf032439eda8b735b1c76cbcce28e6e38ff0296bf8fc49697e4139e69b618b91c317 (66 bytes)
205+
│ │ │ └─ pub_nonce: 023b5df91ceaf9fd5494814cce7dd2edc8e7a1bb69100f6a805863da356fa8df8703dab0d93005f3b0cd39b73693d7d7692ba0a6b15daf4c28151c576f1f0e6215b5 (66 bytes)
206206
│ │ ├─ musig2_pub_nonce: None
207207
│ │ │ ├─ participant_pub_key: 021d978a17486ff9e47c82990269e531fc63981419d4ce73ee8bd2c99661c53953 (33 bytes)
208208
│ │ │ ├─ tap_output_key: 15c5815026f6a54b10194fc6980f1866a02d9ec128533c7997cdb4289bf3ef16 (32 bytes)
209-
│ │ │ └─ pub_nonce: 02c5e3e6b77561cf40b98223232d555e5036e7cc6dff331b2ac56dbe88ac4596dd034e1a2caab3b4564c9edbd5cd9c3c9d9329b2aa0a1c10b95085429a4a5b5ce601 (66 bytes)
209+
│ │ │ └─ pub_nonce: 023c524ddd0036a37e547009bfc9e937146f6d34012b65f9164ddfb9b085fece76020adc083deed55f820a950fb7af097cad224a929a46e3257e75768eb4339a08b0 (66 bytes)
210210
│ │ ├─ musig2_partial_sig: None
211211
│ │ │ ├─ participant_pub_key: 020fdea69e40a3adef3cdc7fa6f3af02f4c9d9e3254503c96a6a2b4aa66e778171 (33 bytes)
212212
│ │ │ ├─ tap_output_key: 15c5815026f6a54b10194fc6980f1866a02d9ec128533c7997cdb4289bf3ef16 (32 bytes)
213-
│ │ │ └─ partial_sig: 195d81caf2f957fb640de13e9490b065b54f0bd6a659f6144f88a635870ab68e (32 bytes)
213+
│ │ │ └─ partial_sig: bc1cc048a82394ceffcbc93a1724ed8e524b1707f15b412ee97a50b80a54fe30 (32 bytes)
214214
│ │ └─ musig2_partial_sig: None
215215
│ │ ├─ participant_pub_key: 021d978a17486ff9e47c82990269e531fc63981419d4ce73ee8bd2c99661c53953 (33 bytes)
216216
│ │ ├─ tap_output_key: 15c5815026f6a54b10194fc6980f1866a02d9ec128533c7997cdb4289bf3ef16 (32 bytes)
217-
│ │ └─ partial_sig: f1a4a1d7baece98c0d2c11aa5e31728b6456062824e961a59fcbc3831dd181e5 (32 bytes)
217+
│ │ └─ partial_sig: ea3135bfda975a100ff472637e798d12f9e3b288e73147ab3a18fc9c67d6e822 (32 bytes)
218218
│ └─ input_6: None
219219
│ ├─ non_witness_utxo: 200d021345d40b204cc22a07ebad78da17159f34c2c656a2f4a51d68c6ca7754 (32 bytes)
220220
│ ├─ redeem_script: 210336ef228ffe9b8efffba052c32d334660dd1f8366cf8fe44ae5aa672b6b629095ac (35 bytes)
221221
│ │ └─ asm: OP_PUSHBYTES_33 0336ef228ffe9b8efffba052c32d334660dd1f8366cf8fe44ae5aa672b6b629095 OP_CHECKSIG
222222
│ ├─ signatures: 1u64
223223
│ │ └─ 0: None
224224
│ │ ├─ pubkey: 0336ef228ffe9b8efffba052c32d334660dd1f8366cf8fe44ae5aa672b6b629095 (33 bytes)
225-
│ │ └─ signature: 3044022066ba18beb6d351e087fe1203f4a0e47ddcc035882f9cd30a83e2d92febe9eff90220664396d8ebdcd04bef62a0781c1261279493b2ad88dc79eddc55f11e3ebcdb9d01 (71 bytes)
225+
│ │ └─ signature: 304402204890fd617b33ecf9f56f5a53fadbcaa447701b219f107c39a1aceff88bea446102202ef154cd23b17e79a235767e568490149baae698628082664db2d9e629c53e6e01 (71 bytes)
226226
│ ├─ sighash_type: 1u32
227227
│ └─ sighash_type: SIGHASH_ALL
228228
└─ outputs: 8u64

0 commit comments

Comments
 (0)