Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,043 changes: 1,957 additions & 86 deletions packages/wasm-utxo/Cargo.lock

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion packages/wasm-utxo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ all = "warn"
[dependencies]
wasm-bindgen = "0.2"
js-sys = "0.3"
miniscript = { git = "https://github.com/BitGo/rust-miniscript", tag = "miniscript-13.0.0-opdrop-forkid" }
miniscript = { git = "https://github.com/BitGo/rust-miniscript", tag = "miniscript-13.0.0-bitgo.1" }
bech32 = "0.11"
musig2 = { version = "0.3.1", default-features = false, features = ["k256"] }
getrandom = { version = "0.2", features = ["js"] }
Expand All @@ -31,6 +31,9 @@ wasm-bindgen-test = "0.3"
rstest = "0.26.1"
pastey = "0.1"

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
zebra-chain = { version = "3.1", default-features = false }

[profile.release]
# this is required to make webpack happy
# https://github.com/webpack/webpack/issues/15566#issuecomment-2558347645
Expand Down
11 changes: 10 additions & 1 deletion packages/wasm-utxo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,16 @@ This project is under active development.
| Descriptor Wallet: Address Support | ✅ Complete | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
| Descriptor Wallet: Transaction Support | ✅ Complete | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
| FixedScript Wallet: Address Generation | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete |
| FixedScript Wallet: Transaction Support | ✅ Complete | ✅ Complete | ✅ Complete | ⏳ TODO | ⏳ TODO | ✅ Complete | ⏳ TODO |
| FixedScript Wallet: Transaction Support | ✅ Complete | ✅ Complete | ✅ Complete | ⏳ TODO | ⏳ TODO | ✅ Complete | ✅ Complete |

### Zcash Features

Zcash support includes:

- **Network Upgrade Awareness**: Automatic consensus branch ID determination based on block height
- **All Network Upgrades**: Support for Overwinter, Sapling, Blossom, Heartwood, Canopy, Nu5, Nu6, and Nu6_1
- **Height-Based API**: Preferred `createEmpty()` method automatically selects correct consensus rules
- **Parity Testing**: Validated against `zebra-chain` for accuracy across all network upgrades

## Building

Expand Down
1 change: 0 additions & 1 deletion packages/wasm-utxo/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@ base64 = "0.21"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
num-bigint = "0.4"
bitcoin = { git = "https://github.com/BitGo/rust-bitcoin", tag = "bitcoin-0.32.8-forkid" }
colored = "2.1"
ptree = "0.5"
49 changes: 33 additions & 16 deletions packages/wasm-utxo/cli/src/parse/node.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/// This contains low-level parsing of PSBT into a node structure suitable for display
use bitcoin::consensus::Decodable;
use bitcoin::hashes::Hash;
use bitcoin::psbt::Psbt;
use bitcoin::{Network, ScriptBuf, Transaction};
use wasm_utxo::bitcoin::consensus::Decodable;
use wasm_utxo::bitcoin::hashes::Hash;
use wasm_utxo::bitcoin::psbt::Psbt;
use wasm_utxo::bitcoin::{Network, ScriptBuf, Transaction};
use wasm_utxo::fixed_script_wallet::bitgo_psbt::{
p2tr_musig2_input::{Musig2PartialSig, Musig2Participants, Musig2PubNonce},
BitGoKeyValue, ProprietaryKeySubtype, BITGO,
Expand All @@ -21,8 +21,11 @@ fn script_buf_to_node(label: &str, script_buf: &ScriptBuf) -> Node {

fn bip32_derivations_to_nodes(
bip32_derivation: &std::collections::BTreeMap<
bitcoin::secp256k1::PublicKey,
(bitcoin::bip32::Fingerprint, bitcoin::bip32::DerivationPath),
wasm_utxo::bitcoin::secp256k1::PublicKey,
(
wasm_utxo::bitcoin::bip32::Fingerprint,
wasm_utxo::bitcoin::bip32::DerivationPath,
),
>,
) -> Vec<Node> {
bip32_derivation
Expand Down Expand Up @@ -100,7 +103,10 @@ fn musig2_partial_sig_to_node(sig: &Musig2PartialSig) -> Node {
node
}

fn bitgo_proprietary_to_node(prop_key: &bitcoin::psbt::raw::ProprietaryKey, v: &[u8]) -> Node {
fn bitgo_proprietary_to_node(
prop_key: &wasm_utxo::bitcoin::psbt::raw::ProprietaryKey,
v: &[u8],
) -> Node {
// Try to parse as BitGo key-value
let v_vec = v.to_vec();
let bitgo_kv_result = BitGoKeyValue::from_key_value(prop_key, &v_vec);
Expand Down Expand Up @@ -159,7 +165,7 @@ fn bitgo_proprietary_to_node(prop_key: &bitcoin::psbt::raw::ProprietaryKey, v: &

fn raw_proprietary_to_node(
label: &str,
prop_key: &bitcoin::psbt::raw::ProprietaryKey,
prop_key: &wasm_utxo::bitcoin::psbt::raw::ProprietaryKey,
v: &[u8],
) -> Node {
let mut prop_node = Node::new(label, Primitive::None);
Expand All @@ -177,7 +183,10 @@ fn raw_proprietary_to_node(
}

fn proprietary_to_nodes(
proprietary: &std::collections::BTreeMap<bitcoin::psbt::raw::ProprietaryKey, Vec<u8>>,
proprietary: &std::collections::BTreeMap<
wasm_utxo::bitcoin::psbt::raw::ProprietaryKey,
Vec<u8>,
>,
) -> Vec<Node> {
proprietary
.iter()
Expand All @@ -194,8 +203,11 @@ fn proprietary_to_nodes(

fn xpubs_to_nodes(
xpubs: &std::collections::BTreeMap<
bitcoin::bip32::Xpub,
(bitcoin::bip32::Fingerprint, bitcoin::bip32::DerivationPath),
wasm_utxo::bitcoin::bip32::Xpub,
(
wasm_utxo::bitcoin::bip32::Fingerprint,
wasm_utxo::bitcoin::bip32::DerivationPath,
),
>,
) -> Vec<Node> {
xpubs
Expand All @@ -215,8 +227,11 @@ fn xpubs_to_nodes(

pub fn xpubs_to_node(
xpubs: &std::collections::BTreeMap<
bitcoin::bip32::Xpub,
(bitcoin::bip32::Fingerprint, bitcoin::bip32::DerivationPath),
wasm_utxo::bitcoin::bip32::Xpub,
(
wasm_utxo::bitcoin::bip32::Fingerprint,
wasm_utxo::bitcoin::bip32::DerivationPath,
),
>,
) -> Node {
let mut xpubs_node = Node::new("xpubs", Primitive::U64(xpubs.len() as u64));
Expand Down Expand Up @@ -267,7 +282,7 @@ pub fn psbt_to_node(psbt: &Psbt, network: Network) -> Node {
witness_node.add_child(Node::new(
"address",
Primitive::String(
bitcoin::Address::from_script(&witness_utxo.script_pubkey, network)
wasm_utxo::bitcoin::Address::from_script(&witness_utxo.script_pubkey, network)
.map(|a| a.to_string())
.unwrap_or_else(|_| "<invalid address>".to_string()),
),
Expand Down Expand Up @@ -353,7 +368,7 @@ pub fn psbt_to_node(psbt: &Psbt, network: Network) -> Node {
psbt_node
}

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

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

if let Ok(address) = bitcoin::Address::from_script(&output.script_pubkey, network) {
if let Ok(address) =
wasm_utxo::bitcoin::Address::from_script(&output.script_pubkey, network)
{
output_node.add_child(Node::new("address", Primitive::String(address.to_string())));
}

Expand Down
6 changes: 3 additions & 3 deletions packages/wasm-utxo/cli/src/parse/node_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
///
/// - [BIP-174: PSBT Format](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki)
/// - [bitcoin::psbt::raw](https://docs.rs/bitcoin/latest/bitcoin/psbt/raw/index.html)
use bitcoin::consensus::Decodable;
use bitcoin::psbt::raw::{Key, Pair};
use bitcoin::{Network, Transaction, VarInt};
use wasm_utxo::bitcoin::consensus::Decodable;
use wasm_utxo::bitcoin::psbt::raw::{Key, Pair};
use wasm_utxo::bitcoin::{Network, Transaction, VarInt};

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

Expand Down
30 changes: 15 additions & 15 deletions packages/wasm-utxo/cli/test/fixtures/psbt_bitcoin_fullsigned.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ psbt: None
├─ tx: None
│ ├─ version: 1i32
│ ├─ lock_time: 0u32
│ ├─ txid: a8f0a1efb5a77f4fe2e40c379d3e122d3b30ac0b88aa80c6e70d3fd72a6cf736 (32 bytes)
│ ├─ ntxid: a8f0a1efb5a77f4fe2e40c379d3e122d3b30ac0b88aa80c6e70d3fd72a6cf736 (32 bytes)
│ ├─ wtxid: a8f0a1efb5a77f4fe2e40c379d3e122d3b30ac0b88aa80c6e70d3fd72a6cf736 (32 bytes)
│ ├─ txid: 5e9a93a20ef076d902be4e361a633c35eec975633036e35e3890ba2d3daa78ae (32 bytes)
│ ├─ ntxid: 5e9a93a20ef076d902be4e361a633c35eec975633036e35e3890ba2d3daa78ae (32 bytes)
│ ├─ wtxid: 5e9a93a20ef076d902be4e361a633c35eec975633036e35e3890ba2d3daa78ae (32 bytes)
│ ├─ inputs: 7u64
│ │ ├─ input_0: None
│ │ │ ├─ prev_txid: 7cce12effc2ea564c4227333fd305447e0de7b3ae7a5fcc751effff3ea1377e1 (32 bytes)
Expand Down Expand Up @@ -71,7 +71,7 @@ psbt: None
│ │ ├─ script_pubkey: a914954288203f9697e25eaecb48d85b8a8608c385cf87 (23 bytes)
│ │ └─ address: 3FJEJqGMWCA8XUnK1jypEy7bu74YMCT8eE
│ └─ output_7: None
│ ├─ value: 900u64
│ ├─ value: 0u64
│ └─ script_pubkey: 6a0f736574656320617374726f6e6f6d79 (17 bytes)
├─ xpubs: 3u64
│ ├─ xpub: None
Expand All @@ -95,10 +95,10 @@ psbt: None
│ │ ├─ signatures: 2u64
│ │ │ ├─ 0: None
│ │ │ │ ├─ pubkey: 03e1524d7f6fc57ab3eacbb659b787106780a475d1db483952c2310b7e9a38975b (33 bytes)
│ │ │ │ └─ signature: 3044022068576594f32f0196dce83d0a2fadde3e3670ae4cee22295337c406374a14496602205858f9cbf54285930c2004045440956db1953a67d305ca3db0206ffd7e7d534301 (71 bytes)
│ │ │ │ └─ signature: 304402201720c319f1acfc962998bec10d8e1c918cd96f02d5f1b5ebf41c39ff1c627cba02206f7941de25ed468bf2e6ad1678d32d4a4ac2c19b74ea1c9a8089c7a2ba933cde01 (71 bytes)
│ │ │ └─ 1: None
│ │ │ ├─ pubkey: 03f6f40764bd5d63f200a2778883acf75e96f15095c998263c087270d0c97e7e7f (33 bytes)
│ │ │ └─ signature: 3044022063f7d77b3e78d916fef10e0e3249730b0b364a07bd4d1de482e7dc3a6910e13402204925ac2db7e1e6a51970f288a12d88d8abfec4fc3b44686664f5a6d707e6b27101 (71 bytes)
│ │ │ └─ signature: 304402204ed1631487b06c29f7e586998de96acd42ceec747e33dc52a455efd0059da14a0220615d8d2f159314c45ef79dd831419dc5cab1c21987d0fa14d0dbfba4113e216401 (71 bytes)
│ │ ├─ sighash_type: 1u32
│ │ ├─ sighash_type: SIGHASH_ALL
│ │ ├─ bip32_derivation: None
Expand All @@ -125,10 +125,10 @@ psbt: None
│ │ ├─ signatures: 2u64
│ │ │ ├─ 0: None
│ │ │ │ ├─ pubkey: 02234531bc9119a36a7946e95aeb74915dd087c7b44f517b8eeeb73f89a0ff1a99 (33 bytes)
│ │ │ │ └─ signature: 304402204f46d55ab3c78be2dd7b2df1a04aa929478c32445ea948923dc36f13eea30d23022054db1d0f3e7922e1ee1e7c3610b73c0297050c37cc4ac12e8ac63cb71dc314a501 (71 bytes)
│ │ │ │ └─ signature: 304402206a7b992610f302ac7320a999aa42531e8b623b0492768daf032c39d6d52ec7c60220670939f9ecd102ce69e98750060646db5e1fb162b1891350b95a8ff21378f83c01 (71 bytes)
│ │ │ └─ 1: None
│ │ │ ├─ pubkey: 02a585f3fab49b5ef95346d932221a221bd55ec191f15533e0f270b3582574f035 (33 bytes)
│ │ │ └─ signature: 3045022100c3dddbc8b20f4aac003165182fb72357486da8a1538d151b06aca94f7894e169022050756f3949e780fd15e3a25baf7b3b3f674422c7ee8aff1d2f77a0f4d7f42ada01 (72 bytes)
│ │ │ └─ signature: 304402200a2d971c408317038596ad6ab0ef17282fd3d8b368d599026bc4ef2dbe0d7ea40220415624b6b92e9846566cab7a828d22017d494064b72aa2620fd13225b54938d301 (71 bytes)
│ │ ├─ sighash_type: 1u32
│ │ ├─ sighash_type: SIGHASH_ALL
│ │ ├─ bip32_derivation: None
Expand All @@ -153,10 +153,10 @@ psbt: None
│ │ ├─ signatures: 2u64
│ │ │ ├─ 0: None
│ │ │ │ ├─ pubkey: 02e80a08885c353676b820cdc290e6d81a0ac95a03e8abbf4bb7aeebfb70feb418 (33 bytes)
│ │ │ │ └─ signature: 3045022100a9a571f171172962c80bf97099c0f1a809bec183af83dabe65bfc51ff1084548022047376a83e5d8bd5bfb07c5720bf90535d9a0ba5837172235132530387618b95901 (72 bytes)
│ │ │ │ └─ signature: 30440220162101914f7fadf5ca92de401acaf9f4e9995acfa222fc7bb09d692650290d81022020004b2656dda5efd0f8a48cdc5e362b092f53bc0a12bf32cbb96a00525bf27601 (71 bytes)
│ │ │ └─ 1: None
│ │ │ ├─ pubkey: 03519e572ab468560d1f8d0f87699d098308e166905f5dcae4390f060faa8f1ce3 (33 bytes)
│ │ │ └─ signature: 304402207017fae20521ac634cfaf259714d370efcd196f83fb8d7c3133207900f27355902201e9b7f217987da96f77b3ba33e868987d13257cc03a05af959e34be2719fe1b501 (71 bytes)
│ │ │ └─ signature: 3045022100e57d42ff5e19de633312bcdeea3a8d298c2f0b7da59b80af50570d7bb9f6678a022013488e7e86183467c4430fe88536f1e40ddd4eb1b64fdbf00d0d5195ccb757a001 (72 bytes)
│ │ ├─ sighash_type: 1u32
│ │ ├─ sighash_type: SIGHASH_ALL
│ │ ├─ bip32_derivation: None
Expand Down Expand Up @@ -202,27 +202,27 @@ psbt: None
│ │ ├─ musig2_pub_nonce: None
│ │ │ ├─ participant_pub_key: 020fdea69e40a3adef3cdc7fa6f3af02f4c9d9e3254503c96a6a2b4aa66e778171 (33 bytes)
│ │ │ ├─ tap_output_key: 15c5815026f6a54b10194fc6980f1866a02d9ec128533c7997cdb4289bf3ef16 (32 bytes)
│ │ │ └─ pub_nonce: 02b4881cc04cf3173c6e8b15d00628725a2c13e7f4be2c1a282267a5ad99d75adf032439eda8b735b1c76cbcce28e6e38ff0296bf8fc49697e4139e69b618b91c317 (66 bytes)
│ │ │ └─ pub_nonce: 023b5df91ceaf9fd5494814cce7dd2edc8e7a1bb69100f6a805863da356fa8df8703dab0d93005f3b0cd39b73693d7d7692ba0a6b15daf4c28151c576f1f0e6215b5 (66 bytes)
│ │ ├─ musig2_pub_nonce: None
│ │ │ ├─ participant_pub_key: 021d978a17486ff9e47c82990269e531fc63981419d4ce73ee8bd2c99661c53953 (33 bytes)
│ │ │ ├─ tap_output_key: 15c5815026f6a54b10194fc6980f1866a02d9ec128533c7997cdb4289bf3ef16 (32 bytes)
│ │ │ └─ pub_nonce: 02c5e3e6b77561cf40b98223232d555e5036e7cc6dff331b2ac56dbe88ac4596dd034e1a2caab3b4564c9edbd5cd9c3c9d9329b2aa0a1c10b95085429a4a5b5ce601 (66 bytes)
│ │ │ └─ pub_nonce: 023c524ddd0036a37e547009bfc9e937146f6d34012b65f9164ddfb9b085fece76020adc083deed55f820a950fb7af097cad224a929a46e3257e75768eb4339a08b0 (66 bytes)
│ │ ├─ musig2_partial_sig: None
│ │ │ ├─ participant_pub_key: 020fdea69e40a3adef3cdc7fa6f3af02f4c9d9e3254503c96a6a2b4aa66e778171 (33 bytes)
│ │ │ ├─ tap_output_key: 15c5815026f6a54b10194fc6980f1866a02d9ec128533c7997cdb4289bf3ef16 (32 bytes)
│ │ │ └─ partial_sig: 195d81caf2f957fb640de13e9490b065b54f0bd6a659f6144f88a635870ab68e (32 bytes)
│ │ │ └─ partial_sig: bc1cc048a82394ceffcbc93a1724ed8e524b1707f15b412ee97a50b80a54fe30 (32 bytes)
│ │ └─ musig2_partial_sig: None
│ │ ├─ participant_pub_key: 021d978a17486ff9e47c82990269e531fc63981419d4ce73ee8bd2c99661c53953 (33 bytes)
│ │ ├─ tap_output_key: 15c5815026f6a54b10194fc6980f1866a02d9ec128533c7997cdb4289bf3ef16 (32 bytes)
│ │ └─ partial_sig: f1a4a1d7baece98c0d2c11aa5e31728b6456062824e961a59fcbc3831dd181e5 (32 bytes)
│ │ └─ partial_sig: ea3135bfda975a100ff472637e798d12f9e3b288e73147ab3a18fc9c67d6e822 (32 bytes)
│ └─ input_6: None
│ ├─ non_witness_utxo: 200d021345d40b204cc22a07ebad78da17159f34c2c656a2f4a51d68c6ca7754 (32 bytes)
│ ├─ redeem_script: 210336ef228ffe9b8efffba052c32d334660dd1f8366cf8fe44ae5aa672b6b629095ac (35 bytes)
│ │ └─ asm: OP_PUSHBYTES_33 0336ef228ffe9b8efffba052c32d334660dd1f8366cf8fe44ae5aa672b6b629095 OP_CHECKSIG
│ ├─ signatures: 1u64
│ │ └─ 0: None
│ │ ├─ pubkey: 0336ef228ffe9b8efffba052c32d334660dd1f8366cf8fe44ae5aa672b6b629095 (33 bytes)
│ │ └─ signature: 3044022066ba18beb6d351e087fe1203f4a0e47ddcc035882f9cd30a83e2d92febe9eff90220664396d8ebdcd04bef62a0781c1261279493b2ad88dc79eddc55f11e3ebcdb9d01 (71 bytes)
│ │ └─ signature: 304402204890fd617b33ecf9f56f5a53fadbcaa447701b219f107c39a1aceff88bea446102202ef154cd23b17e79a235767e568490149baae698628082664db2d9e629c53e6e01 (71 bytes)
│ ├─ sighash_type: 1u32
│ └─ sighash_type: SIGHASH_ALL
└─ outputs: 8u64
Expand Down
Loading