From 8a7a61f0d1db7c0fd51fd50f3b71e04311707815 Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Fri, 24 Oct 2025 13:45:50 +0200 Subject: [PATCH 1/9] feat(wasm-utxo): export address module contents Export all public items from the address module instead of just the utxolib_compat namespace. Issue: BTC-2652 Co-authored-by: llm-git --- packages/wasm-utxo/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/wasm-utxo/src/lib.rs b/packages/wasm-utxo/src/lib.rs index dd4d610..420309a 100644 --- a/packages/wasm-utxo/src/lib.rs +++ b/packages/wasm-utxo/src/lib.rs @@ -12,6 +12,7 @@ mod try_into_js_value; pub use ::miniscript::bitcoin; pub use address::utxolib_compat; +pub use address::*; pub use descriptor::WrapDescriptor; pub use miniscript::WrapMiniscript; pub use psbt::WrapPsbt; From ed1d57ee4ea7784ea87323ab107788ff3d6e9322 Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Fri, 24 Oct 2025 13:46:27 +0200 Subject: [PATCH 2/9] feat(wasm-utxo): use rust idiomatic style for boolean expressions Replace boolean equality comparisons with direct assertions and other idiomatic patterns throughout the codebase. Improve function parameter handling by removing unnecessary references and dereferences. Issue: BTC-2652 Co-authored-by: llm-git --- packages/wasm-utxo/src/address/cashaddr.rs | 10 +++--- packages/wasm-utxo/src/descriptor.rs | 11 +++---- .../wallet_scripts/checkmultisig.rs | 32 +++++++++---------- .../wallet_scripts/checksigverify.rs | 8 ++--- .../fixed_script_wallet/wallet_scripts/mod.rs | 18 +++++------ .../wallet_scripts/singlesig.rs | 4 +-- packages/wasm-utxo/src/psbt.rs | 20 ++++++------ packages/wasm-utxo/src/try_into_js_value.rs | 8 ++--- 8 files changed, 53 insertions(+), 58 deletions(-) diff --git a/packages/wasm-utxo/src/address/cashaddr.rs b/packages/wasm-utxo/src/address/cashaddr.rs index 4865339..51b0087 100644 --- a/packages/wasm-utxo/src/address/cashaddr.rs +++ b/packages/wasm-utxo/src/address/cashaddr.rs @@ -474,7 +474,7 @@ mod tests { // Test roundtrip let (decoded_hash, is_p2sh) = decode_cashaddr(&address, "bitcoincash").unwrap(); assert_eq!(decoded_hash, hash); - assert_eq!(is_p2sh, false); + assert!(!is_p2sh); } #[test] @@ -490,7 +490,7 @@ mod tests { // Test roundtrip let (decoded_hash, is_p2sh) = decode_cashaddr(&address, "bchtest").unwrap(); assert_eq!(decoded_hash, hash); - assert_eq!(is_p2sh, true); + assert!(is_p2sh); } #[test] @@ -503,7 +503,7 @@ mod tests { // Test roundtrip let (decoded_hash, is_p2sh) = decode_cashaddr(&address, "pref").unwrap(); assert_eq!(decoded_hash, hash); - assert_eq!(is_p2sh, true); + assert!(is_p2sh); } #[test] @@ -585,7 +585,7 @@ mod tests { let (hash, is_p2sh) = decode_cashaddr(uppercase, "bitcoincash").unwrap(); assert_eq!(hex::encode(hash).to_uppercase(), TEST_HASH_20); - assert_eq!(is_p2sh, false); + assert!(!is_p2sh); } #[test] @@ -628,7 +628,7 @@ mod tests { // Test roundtrip let (decoded_hash, is_p2sh) = decode_cashaddr(&address, "ecash").unwrap(); assert_eq!(decoded_hash, hash); - assert_eq!(is_p2sh, false); + assert!(!is_p2sh); } #[test] diff --git a/packages/wasm-utxo/src/descriptor.rs b/packages/wasm-utxo/src/descriptor.rs index a08ab22..a0765bd 100644 --- a/packages/wasm-utxo/src/descriptor.rs +++ b/packages/wasm-utxo/src/descriptor.rs @@ -1,6 +1,6 @@ use crate::error::WasmMiniscriptError; use crate::try_into_js_value::TryIntoJsValue; -use miniscript::bitcoin::secp256k1::{Context, Secp256k1, Signing}; +use miniscript::bitcoin::secp256k1::{Secp256k1, Signing}; use miniscript::bitcoin::ScriptBuf; use miniscript::descriptor::KeyMap; use miniscript::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey}; @@ -115,7 +115,7 @@ impl WrapDescriptor { secp: &Secp256k1, descriptor: &str, ) -> Result { - let (desc, keys) = Descriptor::parse_descriptor(&secp, descriptor)?; + let (desc, keys) = Descriptor::parse_descriptor(secp, descriptor)?; Ok(WrapDescriptor(WrapDescriptorEnum::Derivable(desc, keys))) } @@ -217,15 +217,14 @@ mod tests { ) .unwrap(); - assert_eq!(desc.has_wildcard(), false); - assert_eq!( + assert!(!desc.has_wildcard()); + assert!( match desc { WrapDescriptor { 0: crate::descriptor::WrapDescriptorEnum::Definite(_), } => true, _ => false, - }, - true + } ); } } diff --git a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checkmultisig.rs b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checkmultisig.rs index e65aee8..20baa88 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checkmultisig.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checkmultisig.rs @@ -9,7 +9,7 @@ pub fn build_multisig_script_2_of_3(keys: &PubTriple) -> ScriptBuf { let total_count = 3; let mut builder = Builder::default().push_int(quorum as i64); for key in keys { - builder = builder.push_slice(&key.to_bytes()) + builder = builder.push_slice(key.to_bytes()) } builder .push_int(total_count as i64) @@ -150,7 +150,7 @@ mod tests { // Test script with wrong number of instructions let script = Builder::new() .push_opcode(OP_PUSHNUM_2) - .push_slice(&[0x02; 33]) // Only one key instead of three + .push_slice([0x02; 33]) // Only one key instead of three .push_opcode(OP_PUSHNUM_3) .push_opcode(OP_CHECKMULTISIG) .into_script(); @@ -173,9 +173,9 @@ mod tests { // Build script with wrong quorum (OP_1 instead of OP_2) let script = Builder::new() .push_opcode(OP_PUSHNUM_1) - .push_slice(&pub_triple[0].to_bytes()) - .push_slice(&pub_triple[1].to_bytes()) - .push_slice(&pub_triple[2].to_bytes()) + .push_slice(pub_triple[0].to_bytes()) + .push_slice(pub_triple[1].to_bytes()) + .push_slice(pub_triple[2].to_bytes()) .push_opcode(OP_PUSHNUM_3) .push_opcode(OP_CHECKMULTISIG) .into_script(); @@ -198,9 +198,9 @@ mod tests { // Build script with wrong total (OP_4 instead of OP_3) let script = Builder::new() .push_opcode(OP_PUSHNUM_2) - .push_slice(&pub_triple[0].to_bytes()) - .push_slice(&pub_triple[1].to_bytes()) - .push_slice(&pub_triple[2].to_bytes()) + .push_slice(pub_triple[0].to_bytes()) + .push_slice(pub_triple[1].to_bytes()) + .push_slice(pub_triple[2].to_bytes()) .push_opcode(OP_PUSHNUM_4) .push_opcode(OP_CHECKMULTISIG) .into_script(); @@ -223,9 +223,9 @@ mod tests { // Build script without OP_CHECKMULTISIG let script = Builder::new() .push_opcode(OP_PUSHNUM_2) - .push_slice(&pub_triple[0].to_bytes()) - .push_slice(&pub_triple[1].to_bytes()) - .push_slice(&pub_triple[2].to_bytes()) + .push_slice(pub_triple[0].to_bytes()) + .push_slice(pub_triple[1].to_bytes()) + .push_slice(pub_triple[2].to_bytes()) .push_opcode(OP_PUSHNUM_3) .push_opcode(OP_PUSHNUM_1) // Wrong opcode instead of OP_CHECKMULTISIG .into_script(); @@ -242,9 +242,9 @@ mod tests { // Build script with invalid public key data let script = Builder::new() .push_opcode(OP_PUSHNUM_2) - .push_slice(&[0x00; 10]) // Invalid public key (too short) - .push_slice(&[0x02; 33]) // Valid compressed pubkey format - .push_slice(&[0x03; 33]) // Valid compressed pubkey format + .push_slice([0x00; 10]) // Invalid public key (too short) + .push_slice([0x02; 33]) // Valid compressed pubkey format + .push_slice([0x03; 33]) // Valid compressed pubkey format .push_opcode(OP_PUSHNUM_3) .push_opcode(OP_CHECKMULTISIG) .into_script(); @@ -262,8 +262,8 @@ mod tests { let script = Builder::new() .push_opcode(OP_PUSHNUM_2) .push_opcode(OP_PUSHNUM_1) // Wrong: should be pubkey bytes - .push_slice(&[0x02; 33]) - .push_slice(&[0x03; 33]) + .push_slice([0x02; 33]) + .push_slice([0x03; 33]) .push_opcode(OP_PUSHNUM_3) .push_opcode(OP_CHECKMULTISIG) .into_script(); diff --git a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checksigverify.rs b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checksigverify.rs index 3bf81cd..f9e03c5 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checksigverify.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checksigverify.rs @@ -20,7 +20,7 @@ pub fn build_p2tr_ns_script(keys: &[CompressedPublicKey]) -> ScriptBuf { for (i, key) in keys.iter().enumerate() { // convert to xonly key let key_bytes = to_xonly_pubkey(*key); - builder = builder.push_slice(&key_bytes); + builder = builder.push_slice(key_bytes); if i == keys.len() - 1 { builder = builder.push_opcode(OP_CHECKSIG); } else { @@ -89,11 +89,11 @@ impl ScriptP2tr { pub fn output_script(&self) -> ScriptBuf { let output_key = self.spend_info.output_key().to_inner(); - let output_script = Builder::new() + + Builder::new() .push_int(1) .push_slice(output_key.serialize()) - .into_script(); - output_script + .into_script() } } diff --git a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/mod.rs b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/mod.rs index af27b72..4841683 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/mod.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/mod.rs @@ -39,11 +39,11 @@ impl std::fmt::Display for WalletScripts { f, "{}", match self { - WalletScripts::P2sh(_) => format!("P2sh"), - WalletScripts::P2shP2wsh(_) => format!("P2shP2wsh"), - WalletScripts::P2wsh(_) => format!("P2wsh"), - WalletScripts::P2trLegacy(_) => format!("P2trLegacy"), - WalletScripts::P2trMusig2(_) => format!("P2trMusig2"), + WalletScripts::P2sh(_) => "P2sh".to_string(), + WalletScripts::P2shP2wsh(_) => "P2shP2wsh".to_string(), + WalletScripts::P2wsh(_) => "P2wsh".to_string(), + WalletScripts::P2trLegacy(_) => "P2trLegacy".to_string(), + WalletScripts::P2trMusig2(_) => "P2trMusig2".to_string(), } ) } @@ -165,7 +165,7 @@ pub fn derive_xpubs_with_path( ) -> XpubTriple { let derived = xpubs .iter() - .map(|k| k.derive_pub(&ctx, &p).unwrap()) + .map(|k| k.derive_pub(ctx, &p).unwrap()) .collect::>(); derived.try_into().expect("could not convert vec to array") } @@ -182,7 +182,7 @@ pub fn derive_xpubs( index: chain as u32, }) .child(ChildNumber::Normal { index }); - derive_xpubs_with_path(&xpubs, ctx, p) + derive_xpubs_with_path(xpubs, ctx, p) } #[cfg(test)] @@ -383,14 +383,14 @@ mod tests { .expect("Failed to find input with script type"); let (chain, index) = - parse_fixture_paths(&input_fixture).expect("Failed to parse fixture paths"); + parse_fixture_paths(input_fixture).expect("Failed to parse fixture paths"); let scripts = WalletScripts::from_xpubs(&xpubs, chain, index); // Use the new helper methods for validation match (scripts, input_fixture) { (WalletScripts::P2sh(scripts), fixtures::PsbtInputFixture::P2sh(fixture_input)) => { let vout = fixture.inputs[input_index].index as usize; - let output_script = get_output_script_from_non_witness_utxo(&fixture_input, vout); + let output_script = get_output_script_from_non_witness_utxo(fixture_input, vout); fixture_input .assert_matches_wallet_scripts(&scripts, &output_script) .expect("P2sh validation failed"); diff --git a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/singlesig.rs b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/singlesig.rs index 062e249..21b8f04 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/singlesig.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/singlesig.rs @@ -7,7 +7,7 @@ use crate::bitcoin::{CompressedPublicKey, ScriptBuf}; /// Build bare p2pk script (used for p2sh-p2pk replay protection) pub fn build_p2pk_script(key: CompressedPublicKey) -> ScriptBuf { Builder::default() - .push_slice(&key.to_bytes()) + .push_slice(key.to_bytes()) .push_opcode(OP_CHECKSIG) .into_script() } @@ -58,7 +58,7 @@ mod tests { let expected_redeem_script = &p2shp2pk_input.redeem_script; let expected_pubkey = p2shp2pk_input .partial_sig - .get(0) + .first() .map(|sig| &sig.pubkey) .expect("No partial signature found"); diff --git a/packages/wasm-utxo/src/psbt.rs b/packages/wasm-utxo/src/psbt.rs index 3cd0841..83d66b4 100644 --- a/packages/wasm-utxo/src/psbt.rs +++ b/packages/wasm-utxo/src/psbt.rs @@ -3,8 +3,8 @@ use crate::error::WasmMiniscriptError; use crate::try_into_js_value::TryIntoJsValue; use crate::WrapDescriptor; use miniscript::bitcoin::bip32::Fingerprint; -use miniscript::bitcoin::secp256k1::{Context, Secp256k1, Signing}; -use miniscript::bitcoin::{bip32, psbt, secp256k1, PublicKey, XOnlyPublicKey}; +use miniscript::bitcoin::secp256k1::{Secp256k1, Signing}; +use miniscript::bitcoin::{bip32, psbt, PublicKey, XOnlyPublicKey}; use miniscript::bitcoin::{PrivateKey, Psbt}; use miniscript::descriptor::{SinglePub, SinglePubKey}; use miniscript::psbt::PsbtExt; @@ -46,7 +46,7 @@ impl psbt::GetKey for SingleKeySigner { fn get_key( &self, key_request: psbt::KeyRequest, - secp: &Secp256k1, + _secp: &Secp256k1, ) -> Result, Self::Error> { match key_request { // NOTE: this KeyRequest does not occur for taproot signatures @@ -54,15 +54,15 @@ impl psbt::GetKey for SingleKeySigner { // instead based on `DescriptorPublicKey::Single(SinglePub { origin: None, key, })` psbt::KeyRequest::Pubkey(req_pubkey) => { if req_pubkey == self.pubkey { - Ok(Some(self.privkey.clone())) + Ok(Some(self.privkey)) } else { Ok(None) } } - psbt::KeyRequest::Bip32((fingerprint, path)) => { + psbt::KeyRequest::Bip32((fingerprint, _path)) => { if fingerprint.eq(&self.fingerprint) || fingerprint.eq(&self.fingerprint_xonly) { - Ok(Some(self.privkey.clone())) + Ok(Some(self.privkey)) } else { Ok(None) } @@ -99,7 +99,7 @@ impl WrapPsbt { match &descriptor.0 { WrapDescriptorEnum::Definite(d) => self .0 - .update_input_with_descriptor(input_index, &d) + .update_input_with_descriptor(input_index, d) .map_err(JsError::from), WrapDescriptorEnum::Derivable(_, _) => Err(JsError::new( "Cannot update input with a derivable descriptor", @@ -119,7 +119,7 @@ impl WrapPsbt { match &descriptor.0 { WrapDescriptorEnum::Definite(d) => self .0 - .update_output_with_descriptor(output_index, &d) + .update_output_with_descriptor(output_index, d) .map_err(JsError::from), WrapDescriptorEnum::Derivable(_, _) => Err(JsError::new( "Cannot update output with a derivable descriptor", @@ -149,7 +149,7 @@ impl WrapPsbt { let secp = Secp256k1::new(); self.0 .sign(&SingleKeySigner::from_privkey(privkey, &secp), &secp) - .map_err(|(r, errors)| { + .map_err(|(_r, errors)| { WasmMiniscriptError::new(&format!("{} errors: {:?}", errors.len(), errors)) }) .and_then(|r| r.try_to_js_value()) @@ -200,7 +200,7 @@ mod tests { .values() .for_each(|key_source| { let key_source_ref: KeySource = ( - Fingerprint::from_hex(&"aeee1e6a").unwrap(), + Fingerprint::from_hex("aeee1e6a").unwrap(), DerivationPath::from(vec![]), ); assert_eq!(key_source.1, key_source_ref); diff --git a/packages/wasm-utxo/src/try_into_js_value.rs b/packages/wasm-utxo/src/try_into_js_value.rs index d189a0a..fde3fdd 100644 --- a/packages/wasm-utxo/src/try_into_js_value.rs +++ b/packages/wasm-utxo/src/try_into_js_value.rs @@ -283,12 +283,8 @@ impl TryIntoJsValue for SigningKeysMap { fn try_to_js_value(&self) -> Result { let obj = js_sys::Object::new(); for (key, value) in self.iter() { - js_sys::Reflect::set( - &obj, - &key.to_string().into(), - &value.try_to_js_value()?.into(), - ) - .map_err(|_| WasmMiniscriptError::new("Failed to set object property"))?; + js_sys::Reflect::set(&obj, &key.to_string().into(), &value.try_to_js_value()?) + .map_err(|_| WasmMiniscriptError::new("Failed to set object property"))?; } Ok(obj.into()) } From 413dcf911a2c8fe73b28373b0b745e550fe574b0 Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Fri, 24 Oct 2025 13:54:49 +0200 Subject: [PATCH 3/9] feat(wasm-utxo): refactor polymod function to use iterator for clarity Use enumerate() with iterator in cashaddr polymod calculation for improved readability. This eliminates manual indexing while maintaining the same functionality. Issue: BTC-2652 Co-authored-by: llm-git --- packages/wasm-utxo/src/address/cashaddr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/wasm-utxo/src/address/cashaddr.rs b/packages/wasm-utxo/src/address/cashaddr.rs index 51b0087..56ca138 100644 --- a/packages/wasm-utxo/src/address/cashaddr.rs +++ b/packages/wasm-utxo/src/address/cashaddr.rs @@ -265,9 +265,9 @@ fn polymod(values: &[u8]) -> u64 { let c0 = (c >> 35) as u8; c = ((c & 0x07ffffffff) << 5) ^ (d as u64); - for i in 0..5 { + for (i, &generator) in generators.iter().enumerate() { if (c0 & (1 << i)) != 0 { - c ^= generators[i]; + c ^= generator; } } } From 491675cee09ac0af7b2d40eb25a0c039cb21670b Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Fri, 24 Oct 2025 13:55:33 +0200 Subject: [PATCH 4/9] feat(wasm-utxo): update assertion to use matches! macro Improves code clarity by replacing the manual match statement with the more concise matches! macro for descriptor type checking. Issue: BTC-2652 Co-authored-by: llm-git --- packages/wasm-utxo/src/descriptor.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/wasm-utxo/src/descriptor.rs b/packages/wasm-utxo/src/descriptor.rs index a0765bd..ef40c6d 100644 --- a/packages/wasm-utxo/src/descriptor.rs +++ b/packages/wasm-utxo/src/descriptor.rs @@ -218,13 +218,11 @@ mod tests { .unwrap(); assert!(!desc.has_wildcard()); - assert!( - match desc { - WrapDescriptor { - 0: crate::descriptor::WrapDescriptorEnum::Definite(_), - } => true, - _ => false, + assert!(matches!( + desc, + WrapDescriptor { + 0: crate::descriptor::WrapDescriptorEnum::Definite(_), } - ); + )); } } From 4eec7a8cc0589d6baf5af14f03c688b42269586a Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Fri, 24 Oct 2025 13:55:11 +0200 Subject: [PATCH 5/9] feat(wasm-utxo): implement Display trait for WrapDescriptor Improve code quality by implementing the Display trait for WrapDescriptor and refactoring the to_string method to use it, following best practices. Added an allow annotation for clippy warning about shadowing Display trait. Issue: BTC-2652 Co-authored-by: llm-git --- packages/wasm-utxo/src/descriptor.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/wasm-utxo/src/descriptor.rs b/packages/wasm-utxo/src/descriptor.rs index ef40c6d..e1e9557 100644 --- a/packages/wasm-utxo/src/descriptor.rs +++ b/packages/wasm-utxo/src/descriptor.rs @@ -4,6 +4,7 @@ use miniscript::bitcoin::secp256k1::{Secp256k1, Signing}; use miniscript::bitcoin::ScriptBuf; use miniscript::descriptor::KeyMap; use miniscript::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey}; +use std::fmt; use std::str::FromStr; use wasm_bindgen::prelude::*; @@ -27,12 +28,9 @@ impl WrapDescriptor { } #[wasm_bindgen(js_name = toString)] + #[allow(clippy::inherent_to_string_shadow_display)] pub fn to_string(&self) -> String { - match &self.0 { - WrapDescriptorEnum::Derivable(desc, _) => desc.to_string(), - WrapDescriptorEnum::Definite(desc) => desc.to_string(), - WrapDescriptorEnum::String(desc) => desc.to_string(), - } + format!("{}", self) } #[wasm_bindgen(js_name = hasWildcard)] @@ -199,6 +197,16 @@ impl WrapDescriptor { } } +impl fmt::Display for WrapDescriptor { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.0 { + WrapDescriptorEnum::Derivable(desc, _) => write!(f, "{}", desc), + WrapDescriptorEnum::Definite(desc) => write!(f, "{}", desc), + WrapDescriptorEnum::String(desc) => write!(f, "{}", desc), + } + } +} + impl FromStr for WrapDescriptor { type Err = WasmMiniscriptError; fn from_str(s: &str) -> Result { From 88176a637e3010dbf0e37d3306e3fb188f660618 Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Fri, 24 Oct 2025 13:55:46 +0200 Subject: [PATCH 6/9] feat(wasm-utxo): implement Display for WrapMiniscript Adds proper Display trait implementation for WrapMiniscript and refactors toString to use it instead of directly calling the inner implementation. Adds necessary clippy allow attribute to handle shadow warning. Issue: BTC-2652 Co-authored-by: llm-git --- packages/wasm-utxo/src/miniscript.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/wasm-utxo/src/miniscript.rs b/packages/wasm-utxo/src/miniscript.rs index f068cd1..cacc0b3 100644 --- a/packages/wasm-utxo/src/miniscript.rs +++ b/packages/wasm-utxo/src/miniscript.rs @@ -2,6 +2,7 @@ use crate::error::WasmMiniscriptError; use crate::try_into_js_value::TryIntoJsValue; use miniscript::bitcoin::{PublicKey, XOnlyPublicKey}; use miniscript::{bitcoin, Legacy, Miniscript, Segwitv0, Tap}; +use std::fmt; use std::str::FromStr; use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsValue; @@ -35,8 +36,9 @@ impl WrapMiniscript { } #[wasm_bindgen(js_name = toString)] + #[allow(clippy::inherent_to_string_shadow_display)] pub fn to_string(&self) -> String { - unwrap_apply!(&self.0, |ms| ms.to_string()) + format!("{}", self) } #[wasm_bindgen(js_name = encode)] @@ -112,3 +114,9 @@ impl From> for WrapMiniscript { WrapMiniscript(WrapMiniscriptEnum::Legacy(miniscript)) } } + +impl fmt::Display for WrapMiniscript { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + unwrap_apply!(&self.0, |ms| write!(f, "{}", ms)) + } +} From 2c73c41e7457113927d793bb7c2b080c7a79b660 Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Fri, 24 Oct 2025 13:56:06 +0200 Subject: [PATCH 7/9] feat(wasm-utxo): enhance code readability and multisig iteration Remove unnecessary blank line in cashaddr module's test section and refactor multisig script parsing to use iterator methods instead of index-based loops for better readability and safer iteration. Issue: BTC-2652 Co-authored-by: llm-git --- packages/wasm-utxo/src/address/cashaddr.rs | 1 - .../fixed_script_wallet/wallet_scripts/checkmultisig.rs | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/wasm-utxo/src/address/cashaddr.rs b/packages/wasm-utxo/src/address/cashaddr.rs index 56ca138..5afa541 100644 --- a/packages/wasm-utxo/src/address/cashaddr.rs +++ b/packages/wasm-utxo/src/address/cashaddr.rs @@ -457,7 +457,6 @@ mod tests { /// /// Using bech32 crate's `ByteIterExt::bytes_to_fes()` or checksum functions would fail these tests /// because they implement Bech32/Bech32m logic, not CashAddr logic. - // Test vector: 20-byte P2PKH payload const TEST_HASH_20: &str = "F5BF48B397DAE70BE82B3CCA4793F8EB2B6CDAC9"; diff --git a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checkmultisig.rs b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checkmultisig.rs index 20baa88..1738d57 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checkmultisig.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/checkmultisig.rs @@ -51,13 +51,13 @@ pub fn parse_multisig_script_2_of_3(script: &ScriptBuf) -> Result { let key = CompressedPublicKey::from_slice(bytes.as_bytes()).map_err(|e| { format!( "Failed to parse compressed public key at position {}: {}", - i, e + idx, e ) })?; keys.push(key); @@ -65,7 +65,7 @@ pub fn parse_multisig_script_2_of_3(script: &ScriptBuf) -> Result { return Err(format!( "Instruction at position {} should be a push bytes instruction", - i + idx )); } } From 83fa37501f981f85b455edbbf0dac11979375012 Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Fri, 24 Oct 2025 13:56:19 +0200 Subject: [PATCH 8/9] feat(wasm-utxo): rename unused `pubkey_xonly` to `_pubkey_xonly` BTC-2652 Co-authored-by: llm-git --- packages/wasm-utxo/src/psbt.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/wasm-utxo/src/psbt.rs b/packages/wasm-utxo/src/psbt.rs index 83d66b4..ef9d3b2 100644 --- a/packages/wasm-utxo/src/psbt.rs +++ b/packages/wasm-utxo/src/psbt.rs @@ -17,7 +17,7 @@ use wasm_bindgen::{JsError, JsValue}; struct SingleKeySigner { privkey: PrivateKey, pubkey: PublicKey, - pubkey_xonly: XOnlyPublicKey, + _pubkey_xonly: XOnlyPublicKey, fingerprint: Fingerprint, fingerprint_xonly: Fingerprint, } @@ -33,7 +33,7 @@ impl SingleKeySigner { SingleKeySigner { privkey, pubkey, - pubkey_xonly, + _pubkey_xonly: pubkey_xonly, fingerprint: SingleKeySigner::fingerprint(SinglePubKey::FullKey(pubkey)), fingerprint_xonly: SingleKeySigner::fingerprint(SinglePubKey::XOnly(pubkey_xonly)), } From 6d5051c9ee194fad7f88f4012ba9fd57a69754d1 Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Fri, 24 Oct 2025 13:56:27 +0200 Subject: [PATCH 9/9] feat(wasm-utxo): implement Clone trait properly for WrapPsbt Implemented Clone trait for WrapPsbt to provide proper cloning functionality and addressed clippy lint warnings about manually implementing the trait method. Issue: BTC-2652 Co-authored-by: llm-git --- packages/wasm-utxo/src/psbt.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/wasm-utxo/src/psbt.rs b/packages/wasm-utxo/src/psbt.rs index ef9d3b2..f2312ef 100644 --- a/packages/wasm-utxo/src/psbt.rs +++ b/packages/wasm-utxo/src/psbt.rs @@ -86,8 +86,9 @@ impl WrapPsbt { self.0.serialize() } + #[allow(clippy::should_implement_trait)] pub fn clone(&self) -> WrapPsbt { - WrapPsbt(self.0.clone()) + Clone::clone(self) } #[wasm_bindgen(js_name = updateInputWithDescriptor)] @@ -165,6 +166,12 @@ impl WrapPsbt { } } +impl Clone for WrapPsbt { + fn clone(&self) -> Self { + WrapPsbt(self.0.clone()) + } +} + #[cfg(test)] mod tests { use crate::psbt::SingleKeySigner;