diff --git a/packages/wasm-utxo/src/descriptor.rs b/packages/wasm-utxo/src/descriptor.rs index e1e95576..903c12d8 100644 --- a/packages/wasm-utxo/src/descriptor.rs +++ b/packages/wasm-utxo/src/descriptor.rs @@ -1,4 +1,4 @@ -use crate::error::WasmMiniscriptError; +use crate::error::WasmUtxoError; use crate::try_into_js_value::TryIntoJsValue; use miniscript::bitcoin::secp256k1::{Secp256k1, Signing}; use miniscript::bitcoin::ScriptBuf; @@ -19,7 +19,7 @@ pub struct WrapDescriptor(pub(crate) WrapDescriptorEnum); #[wasm_bindgen] impl WrapDescriptor { - pub fn node(&self) -> Result { + pub fn node(&self) -> Result { Ok(match &self.0 { WrapDescriptorEnum::Derivable(desc, _) => desc.try_to_js_value()?, WrapDescriptorEnum::Definite(desc) => desc.try_to_js_value()?, @@ -43,20 +43,20 @@ impl WrapDescriptor { } #[wasm_bindgen(js_name = atDerivationIndex)] - pub fn at_derivation_index(&self, index: u32) -> Result { + pub fn at_derivation_index(&self, index: u32) -> Result { match &self.0 { WrapDescriptorEnum::Derivable(desc, _keys) => { let d = desc.at_derivation_index(index)?; Ok(WrapDescriptor(WrapDescriptorEnum::Definite(d))) } - _ => Err(WasmMiniscriptError::new( + _ => Err(WasmUtxoError::new( "Cannot derive from a definite descriptor", )), } } #[wasm_bindgen(js_name = descType)] - pub fn desc_type(&self) -> Result { + pub fn desc_type(&self) -> Result { (match &self.0 { WrapDescriptorEnum::Derivable(desc, _) => desc.desc_type(), WrapDescriptorEnum::Definite(desc) => desc.desc_type(), @@ -66,38 +66,36 @@ impl WrapDescriptor { } #[wasm_bindgen(js_name = scriptPubkey)] - pub fn script_pubkey(&self) -> Result, WasmMiniscriptError> { + pub fn script_pubkey(&self) -> Result, WasmUtxoError> { match &self.0 { WrapDescriptorEnum::Definite(desc) => Ok(desc.script_pubkey().to_bytes()), - _ => Err(WasmMiniscriptError::new( - "Cannot encode a derivable descriptor", - )), + _ => Err(WasmUtxoError::new("Cannot encode a derivable descriptor")), } } - fn explicit_script(&self) -> Result { + fn explicit_script(&self) -> Result { match &self.0 { WrapDescriptorEnum::Definite(desc) => Ok(desc.explicit_script()?), - WrapDescriptorEnum::Derivable(_, _) => Err(WasmMiniscriptError::new( - "Cannot encode a derivable descriptor", - )), - WrapDescriptorEnum::String(_) => Err(WasmMiniscriptError::new( - "Cannot encode a string descriptor", - )), + WrapDescriptorEnum::Derivable(_, _) => { + Err(WasmUtxoError::new("Cannot encode a derivable descriptor")) + } + WrapDescriptorEnum::String(_) => { + Err(WasmUtxoError::new("Cannot encode a string descriptor")) + } } } - pub fn encode(&self) -> Result, WasmMiniscriptError> { + pub fn encode(&self) -> Result, WasmUtxoError> { Ok(self.explicit_script()?.to_bytes()) } #[wasm_bindgen(js_name = toAsmString)] - pub fn to_asm_string(&self) -> Result { + pub fn to_asm_string(&self) -> Result { Ok(self.explicit_script()?.to_asm_string()) } #[wasm_bindgen(js_name = maxWeightToSatisfy)] - pub fn max_weight_to_satisfy(&self) -> Result { + pub fn max_weight_to_satisfy(&self) -> Result { let weight = (match &self.0 { WrapDescriptorEnum::Derivable(desc, _) => desc.max_weight_to_satisfy(), WrapDescriptorEnum::Definite(desc) => desc.max_weight_to_satisfy(), @@ -106,18 +104,18 @@ impl WrapDescriptor { weight .to_wu() .try_into() - .map_err(|_| WasmMiniscriptError::new("Weight exceeds u32")) + .map_err(|_| WasmUtxoError::new("Weight exceeds u32")) } fn from_string_derivable( secp: &Secp256k1, descriptor: &str, - ) -> Result { + ) -> Result { let (desc, keys) = Descriptor::parse_descriptor(secp, descriptor)?; Ok(WrapDescriptor(WrapDescriptorEnum::Derivable(desc, keys))) } - fn from_string_definite(descriptor: &str) -> Result { + fn from_string_definite(descriptor: &str) -> Result { let desc = Descriptor::::from_str(descriptor)?; Ok(WrapDescriptor(WrapDescriptorEnum::Definite(desc))) } @@ -135,7 +133,7 @@ impl WrapDescriptor { /// - "string": For descriptors with string placeholders /// /// # Returns - /// * `Result` - The parsed descriptor or an error + /// * `Result` - The parsed descriptor or an error /// /// # Example /// ``` @@ -145,10 +143,7 @@ impl WrapDescriptor { /// ); /// ``` #[wasm_bindgen(js_name = fromString, skip_typescript)] - pub fn from_string( - descriptor: &str, - pk_type: &str, - ) -> Result { + pub fn from_string(descriptor: &str, pk_type: &str) -> Result { match pk_type { "derivable" => WrapDescriptor::from_string_derivable(&Secp256k1::new(), descriptor), "definite" => WrapDescriptor::from_string_definite(descriptor), @@ -156,7 +151,7 @@ impl WrapDescriptor { let desc = Descriptor::::from_str(descriptor)?; Ok(WrapDescriptor(WrapDescriptorEnum::String(desc))) } - _ => Err(WasmMiniscriptError::new("Invalid descriptor type")), + _ => Err(WasmUtxoError::new("Invalid descriptor type")), } } @@ -168,7 +163,7 @@ impl WrapDescriptor { /// * `descriptor` - A string containing the descriptor to parse /// /// # Returns - /// * `Result` - The parsed descriptor or an error + /// * `Result` - The parsed descriptor or an error /// /// # Example /// ``` @@ -183,12 +178,10 @@ impl WrapDescriptor { /// ); /// ``` #[wasm_bindgen(js_name = fromStringDetectType, skip_typescript)] - pub fn from_string_detect_type( - descriptor: &str, - ) -> Result { + pub fn from_string_detect_type(descriptor: &str) -> Result { let secp = Secp256k1::new(); let (descriptor, _key_map) = Descriptor::parse_descriptor(&secp, descriptor) - .map_err(|_| WasmMiniscriptError::new("Invalid descriptor"))?; + .map_err(|_| WasmUtxoError::new("Invalid descriptor"))?; if descriptor.has_wildcard() { WrapDescriptor::from_string_derivable(&secp, &descriptor.to_string()) } else { @@ -208,7 +201,7 @@ impl fmt::Display for WrapDescriptor { } impl FromStr for WrapDescriptor { - type Err = WasmMiniscriptError; + type Err = WasmUtxoError; fn from_str(s: &str) -> Result { WrapDescriptor::from_string_detect_type(s) } diff --git a/packages/wasm-utxo/src/error.rs b/packages/wasm-utxo/src/error.rs index 3315a8cd..5ba110b9 100644 --- a/packages/wasm-utxo/src/error.rs +++ b/packages/wasm-utxo/src/error.rs @@ -1,51 +1,51 @@ use core::fmt; #[derive(Debug, Clone)] -pub enum WasmMiniscriptError { +pub enum WasmUtxoError { StringError(String), } -impl std::error::Error for WasmMiniscriptError {} -impl fmt::Display for WasmMiniscriptError { +impl std::error::Error for WasmUtxoError {} +impl fmt::Display for WasmUtxoError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - WasmMiniscriptError::StringError(s) => write!(f, "{}", s), + WasmUtxoError::StringError(s) => write!(f, "{}", s), } } } -impl From<&str> for WasmMiniscriptError { +impl From<&str> for WasmUtxoError { fn from(s: &str) -> Self { - WasmMiniscriptError::StringError(s.to_string()) + WasmUtxoError::StringError(s.to_string()) } } -impl From for WasmMiniscriptError { +impl From for WasmUtxoError { fn from(s: String) -> Self { - WasmMiniscriptError::StringError(s) + WasmUtxoError::StringError(s) } } -impl From for WasmMiniscriptError { +impl From for WasmUtxoError { fn from(err: miniscript::Error) -> Self { - WasmMiniscriptError::StringError(err.to_string()) + WasmUtxoError::StringError(err.to_string()) } } -impl From for WasmMiniscriptError { +impl From for WasmUtxoError { fn from(err: miniscript::descriptor::ConversionError) -> Self { - WasmMiniscriptError::StringError(err.to_string()) + WasmUtxoError::StringError(err.to_string()) } } -impl WasmMiniscriptError { - pub fn new(s: &str) -> WasmMiniscriptError { - WasmMiniscriptError::StringError(s.to_string()) +impl WasmUtxoError { + pub fn new(s: &str) -> WasmUtxoError { + WasmUtxoError::StringError(s.to_string()) } } -impl From for WasmMiniscriptError { +impl From for WasmUtxoError { fn from(err: crate::address::AddressError) -> Self { - WasmMiniscriptError::StringError(err.to_string()) + WasmUtxoError::StringError(err.to_string()) } } diff --git a/packages/wasm-utxo/src/fixed_script_wallet/bip32interface.rs b/packages/wasm-utxo/src/fixed_script_wallet/bip32interface.rs index 01b393d5..ef217704 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/bip32interface.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/bip32interface.rs @@ -1,11 +1,11 @@ use std::str::FromStr; use crate::bitcoin::bip32::Xpub; -use crate::error::WasmMiniscriptError; +use crate::error::WasmUtxoError; use crate::try_from_js_value::{get_buffer_field, get_field, get_nested_field}; use wasm_bindgen::JsValue; -fn try_xpub_from_bip32_properties(bip32_key: &JsValue) -> Result { +fn try_xpub_from_bip32_properties(bip32_key: &JsValue) -> Result { // Extract properties using helper functions let version: u32 = get_nested_field(bip32_key, "network.bip32.public")?; let depth: u8 = get_field(bip32_key, "depth")?; @@ -24,33 +24,32 @@ fn try_xpub_from_bip32_properties(bip32_key: &JsValue) -> Result Result { +fn xpub_from_base58_method(bip32_key: &JsValue) -> Result { // Fallback: Call toBase58() method on BIP32Interface let to_base58 = js_sys::Reflect::get(bip32_key, &JsValue::from_str("toBase58")) - .map_err(|_| WasmMiniscriptError::new("Failed to get 'toBase58' method"))?; + .map_err(|_| WasmUtxoError::new("Failed to get 'toBase58' method"))?; if !to_base58.is_function() { - return Err(WasmMiniscriptError::new("'toBase58' is not a function")); + return Err(WasmUtxoError::new("'toBase58' is not a function")); } let to_base58_fn = js_sys::Function::from(to_base58); let xpub_str = to_base58_fn .call0(bip32_key) - .map_err(|_| WasmMiniscriptError::new("Failed to call 'toBase58'"))?; + .map_err(|_| WasmUtxoError::new("Failed to call 'toBase58'"))?; let xpub_string = xpub_str .as_string() - .ok_or_else(|| WasmMiniscriptError::new("'toBase58' did not return a string"))?; + .ok_or_else(|| WasmUtxoError::new("'toBase58' did not return a string"))?; Xpub::from_str(&xpub_string) - .map_err(|e| WasmMiniscriptError::new(&format!("Failed to parse xpub: {}", e))) + .map_err(|e| WasmUtxoError::new(&format!("Failed to parse xpub: {}", e))) } -pub fn xpub_from_bip32interface(bip32_key: &JsValue) -> Result { +pub fn xpub_from_bip32interface(bip32_key: &JsValue) -> Result { // Try to construct from properties first, fall back to toBase58() if that fails try_xpub_from_bip32_properties(bip32_key).or_else(|_| xpub_from_base58_method(bip32_key)) } diff --git a/packages/wasm-utxo/src/fixed_script_wallet/mod.rs b/packages/wasm-utxo/src/fixed_script_wallet/mod.rs index 852cc5e3..c85630d1 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/mod.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/mod.rs @@ -13,7 +13,7 @@ pub use wallet_scripts::*; use wasm_bindgen::prelude::*; use crate::address::networks::AddressFormat; -use crate::error::WasmMiniscriptError; +use crate::error::WasmUtxoError; use crate::try_from_js_value::TryFromJsValue; use crate::utxolib_compat::UtxolibNetwork; @@ -28,10 +28,10 @@ impl FixedScriptWalletNamespace { chain: u32, index: u32, network: JsValue, - ) -> Result, WasmMiniscriptError> { + ) -> Result, WasmUtxoError> { let network = UtxolibNetwork::try_from_js_value(&network)?; let chain = Chain::try_from(chain) - .map_err(|e| WasmMiniscriptError::new(&format!("Invalid chain: {}", e)))?; + .map_err(|e| WasmUtxoError::new(&format!("Invalid chain: {}", e)))?; let wallet_keys = RootWalletKeys::from_jsvalue(&keys)?; let scripts = WalletScripts::from_wallet_keys( @@ -50,11 +50,11 @@ impl FixedScriptWalletNamespace { index: u32, network: JsValue, address_format: Option, - ) -> Result { + ) -> Result { let network = UtxolibNetwork::try_from_js_value(&network)?; let wallet_keys = RootWalletKeys::from_jsvalue(&keys)?; let chain = Chain::try_from(chain) - .map_err(|e| WasmMiniscriptError::new(&format!("Invalid chain: {}", e)))?; + .map_err(|e| WasmUtxoError::new(&format!("Invalid chain: {}", e)))?; let scripts = WalletScripts::from_wallet_keys( &wallet_keys, chain, @@ -63,13 +63,13 @@ impl FixedScriptWalletNamespace { )?; let script = scripts.output_script(); let address_format = AddressFormat::from_optional_str(address_format.as_deref()) - .map_err(|e| WasmMiniscriptError::new(&format!("Invalid address format: {}", e)))?; + .map_err(|e| WasmUtxoError::new(&format!("Invalid address format: {}", e)))?; let address = crate::address::utxolib_compat::from_output_script_with_network( &script, &network, address_format, ) - .map_err(|e| WasmMiniscriptError::new(&format!("Failed to generate address: {}", e)))?; + .map_err(|e| WasmUtxoError::new(&format!("Failed to generate address: {}", e)))?; Ok(address.to_string()) } } diff --git a/packages/wasm-utxo/src/fixed_script_wallet/wallet_keys.rs b/packages/wasm-utxo/src/fixed_script_wallet/wallet_keys.rs index a1586f01..82461d5c 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/wallet_keys.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/wallet_keys.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use crate::bitcoin::bip32::{ChildNumber, DerivationPath}; use crate::bitcoin::{bip32::Xpub, secp256k1::Secp256k1, CompressedPublicKey}; -use crate::error::WasmMiniscriptError; +use crate::error::WasmUtxoError; use wasm_bindgen::JsValue; use super::bip32interface::xpub_from_bip32interface; @@ -12,41 +12,40 @@ pub type XpubTriple = [Xpub; 3]; pub type PubTriple = [CompressedPublicKey; 3]; -pub fn xpub_triple_from_jsvalue(keys: &JsValue) -> Result { +pub fn xpub_triple_from_jsvalue(keys: &JsValue) -> Result { let keys_array = js_sys::Array::from(keys); if keys_array.length() != 3 { - return Err(WasmMiniscriptError::new("Expected exactly 3 xpub keys")); + return Err(WasmUtxoError::new("Expected exactly 3 xpub keys")); } let key_strings: Result<[String; 3], _> = (0..3) .map(|i| { - keys_array.get(i).as_string().ok_or_else(|| { - WasmMiniscriptError::new(&format!("Key at index {} is not a string", i)) - }) + keys_array + .get(i) + .as_string() + .ok_or_else(|| WasmUtxoError::new(&format!("Key at index {} is not a string", i))) }) .collect::, _>>() .and_then(|v| { v.try_into() - .map_err(|_| WasmMiniscriptError::new("Failed to convert to array")) + .map_err(|_| WasmUtxoError::new("Failed to convert to array")) }); xpub_triple_from_strings(&key_strings?) } -pub fn xpub_triple_from_strings( - xpub_strings: &[String; 3], -) -> Result { +pub fn xpub_triple_from_strings(xpub_strings: &[String; 3]) -> Result { let xpubs: Result, _> = xpub_strings .iter() .map(|s| { Xpub::from_str(s) - .map_err(|e| WasmMiniscriptError::new(&format!("Failed to parse xpub: {}", e))) + .map_err(|e| WasmUtxoError::new(&format!("Failed to parse xpub: {}", e))) }) .collect(); xpubs? .try_into() - .map_err(|_| WasmMiniscriptError::new("Expected exactly 3 xpubs")) + .map_err(|_| WasmUtxoError::new("Expected exactly 3 xpubs")) } pub fn to_pub_triple(xpubs: &XpubTriple) -> PubTriple { @@ -90,7 +89,7 @@ impl RootWalletKeys { &self, chain: u32, index: u32, - ) -> Result { + ) -> Result { let paths: Vec = self .derivation_prefixes .iter() @@ -102,20 +101,20 @@ impl RootWalletKeys { let ctx = Secp256k1::new(); - // zip xpubs and paths, and return a Result + // zip xpubs and paths, and return a Result self.xpubs .iter() .zip(paths.iter()) .map(|(x, p)| { x.derive_pub(&ctx, p) - .map_err(|e| WasmMiniscriptError::new(&format!("Error deriving xpub: {}", e))) + .map_err(|e| WasmUtxoError::new(&format!("Error deriving xpub: {}", e))) }) .collect::, _>>()? .try_into() - .map_err(|_| WasmMiniscriptError::new("Expected exactly 3 derived xpubs")) + .map_err(|_| WasmUtxoError::new("Expected exactly 3 derived xpubs")) } - pub(crate) fn from_jsvalue(keys: &JsValue) -> Result { + pub(crate) fn from_jsvalue(keys: &JsValue) -> Result { // Check if keys is an array (xpub strings) or an object (WalletKeys/RootWalletKeys) if js_sys::Array::is_array(keys) { // Handle array of xpub strings @@ -134,19 +133,15 @@ impl RootWalletKeys { // Get the triple property let triple = js_sys::Reflect::get(&obj, &JsValue::from_str("triple")) - .map_err(|_| WasmMiniscriptError::new("Failed to get 'triple' property"))?; + .map_err(|_| WasmUtxoError::new("Failed to get 'triple' property"))?; if !js_sys::Array::is_array(&triple) { - return Err(WasmMiniscriptError::new( - "'triple' property must be an array", - )); + return Err(WasmUtxoError::new("'triple' property must be an array")); } let triple_array = js_sys::Array::from(&triple); if triple_array.length() != 3 { - return Err(WasmMiniscriptError::new( - "'triple' must contain exactly 3 keys", - )); + return Err(WasmUtxoError::new("'triple' must contain exactly 3 keys")); } // Extract xpubs from BIP32Interface objects @@ -157,7 +152,7 @@ impl RootWalletKeys { }) .collect::, _>>()? .try_into() - .map_err(|_| WasmMiniscriptError::new("Failed to convert to array"))?; + .map_err(|_| WasmUtxoError::new("Failed to convert to array"))?; // Try to get derivationPrefixes if present (for RootWalletKeys) let derivation_prefixes = @@ -179,15 +174,15 @@ impl RootWalletKeys { let prefix_strings: Result<[String; 3], _> = (0..3) .map(|i| { - prefixes_array.get(i).as_string().ok_or_else(|| { - WasmMiniscriptError::new("Prefix is not a string") - }) + prefixes_array + .get(i) + .as_string() + .ok_or_else(|| WasmUtxoError::new("Prefix is not a string")) }) .collect::, _>>() .and_then(|v| { - v.try_into().map_err(|_| { - WasmMiniscriptError::new("Failed to convert to array") - }) + v.try_into() + .map_err(|_| WasmUtxoError::new("Failed to convert to array")) }); prefix_strings.ok() @@ -201,12 +196,12 @@ impl RootWalletKeys { // Remove leading 'm/' if present and add it back let p = p.strip_prefix("m/").unwrap_or(p); DerivationPath::from_str(&format!("m/{}", p)).map_err(|e| { - WasmMiniscriptError::new(&format!("Invalid derivation prefix: {}", e)) + WasmUtxoError::new(&format!("Invalid derivation prefix: {}", e)) }) }) .collect::, _>>()? .try_into() - .map_err(|_| WasmMiniscriptError::new("Failed to convert derivation paths"))? + .map_err(|_| WasmUtxoError::new("Failed to convert derivation paths"))? } else { [ DerivationPath::from_str("m/0/0").unwrap(), @@ -220,7 +215,7 @@ impl RootWalletKeys { derivation_paths, )) } else { - Err(WasmMiniscriptError::new( + Err(WasmUtxoError::new( "Expected array of xpub strings or WalletKeys object", )) } 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 1a5c816a..432d4960 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 @@ -15,7 +15,7 @@ pub use singlesig::{build_p2pk_script, ScriptP2shP2pk}; use crate::address::networks::OutputScriptSupport; use crate::bitcoin::bip32::{ChildNumber, DerivationPath}; use crate::bitcoin::ScriptBuf; -use crate::error::WasmMiniscriptError; +use crate::error::WasmUtxoError; use crate::fixed_script_wallet::wallet_keys::{to_pub_triple, PubTriple, XpubTriple}; use crate::RootWalletKeys; use std::convert::TryFrom; @@ -57,7 +57,7 @@ impl WalletScripts { keys: &PubTriple, chain: Chain, script_support: &OutputScriptSupport, - ) -> Result { + ) -> Result { match chain { Chain::P2shExternal | Chain::P2shInternal => { script_support.assert_legacy()?; @@ -97,7 +97,7 @@ impl WalletScripts { chain: Chain, index: u32, script_support: &OutputScriptSupport, - ) -> Result { + ) -> Result { let derived_keys = wallet_keys .derive_for_chain_and_index(chain as u32, index) .unwrap(); diff --git a/packages/wasm-utxo/src/miniscript.rs b/packages/wasm-utxo/src/miniscript.rs index cacc0b3b..c427a22a 100644 --- a/packages/wasm-utxo/src/miniscript.rs +++ b/packages/wasm-utxo/src/miniscript.rs @@ -1,4 +1,4 @@ -use crate::error::WasmMiniscriptError; +use crate::error::WasmUtxoError; use crate::try_into_js_value::TryIntoJsValue; use miniscript::bitcoin::{PublicKey, XOnlyPublicKey}; use miniscript::{bitcoin, Legacy, Miniscript, Segwitv0, Tap}; @@ -31,7 +31,7 @@ pub struct WrapMiniscript(WrapMiniscriptEnum); #[wasm_bindgen] impl WrapMiniscript { #[wasm_bindgen(js_name = node)] - pub fn node(&self) -> Result { + pub fn node(&self) -> Result { unwrap_apply!(&self.0, |ms| ms.try_to_js_value()) } @@ -47,29 +47,23 @@ impl WrapMiniscript { } #[wasm_bindgen(js_name = toAsmString)] - pub fn to_asm_string(&self) -> Result { + pub fn to_asm_string(&self) -> Result { unwrap_apply!(&self.0, |ms| Ok(ms.encode().to_asm_string())) } #[wasm_bindgen(js_name = fromString, skip_typescript)] - pub fn from_string( - script: &str, - context_type: &str, - ) -> Result { + pub fn from_string(script: &str, context_type: &str) -> Result { match context_type { "tap" => Ok(WrapMiniscript::from( - Miniscript::::from_str(script) - .map_err(WasmMiniscriptError::from)?, + Miniscript::::from_str(script).map_err(WasmUtxoError::from)?, )), "segwitv0" => Ok(WrapMiniscript::from( - Miniscript::::from_str(script) - .map_err(WasmMiniscriptError::from)?, + Miniscript::::from_str(script).map_err(WasmUtxoError::from)?, )), "legacy" => Ok(WrapMiniscript::from( - Miniscript::::from_str(script) - .map_err(WasmMiniscriptError::from)?, + Miniscript::::from_str(script).map_err(WasmUtxoError::from)?, )), - _ => Err(WasmMiniscriptError::new("Invalid context type")), + _ => Err(WasmUtxoError::new("Invalid context type")), } } @@ -77,22 +71,19 @@ impl WrapMiniscript { pub fn from_bitcoin_script( script: &[u8], context_type: &str, - ) -> Result { + ) -> Result { let script = bitcoin::Script::from_bytes(script); match context_type { "tap" => Ok(WrapMiniscript::from( - Miniscript::::parse(script) - .map_err(WasmMiniscriptError::from)?, + Miniscript::::parse(script).map_err(WasmUtxoError::from)?, )), "segwitv0" => Ok(WrapMiniscript::from( - Miniscript::::parse(script) - .map_err(WasmMiniscriptError::from)?, + Miniscript::::parse(script).map_err(WasmUtxoError::from)?, )), "legacy" => Ok(WrapMiniscript::from( - Miniscript::::parse(script) - .map_err(WasmMiniscriptError::from)?, + Miniscript::::parse(script).map_err(WasmUtxoError::from)?, )), - _ => Err(WasmMiniscriptError::new("Invalid context type")), + _ => Err(WasmUtxoError::new("Invalid context type")), } } } diff --git a/packages/wasm-utxo/src/psbt.rs b/packages/wasm-utxo/src/psbt.rs index f2312eff..a44ed9e4 100644 --- a/packages/wasm-utxo/src/psbt.rs +++ b/packages/wasm-utxo/src/psbt.rs @@ -1,5 +1,5 @@ use crate::descriptor::WrapDescriptorEnum; -use crate::error::WasmMiniscriptError; +use crate::error::WasmUtxoError; use crate::try_into_js_value::TryIntoJsValue; use crate::WrapDescriptor; use miniscript::bitcoin::bip32::Fingerprint; @@ -132,36 +132,35 @@ impl WrapPsbt { } #[wasm_bindgen(js_name = signWithXprv)] - pub fn sign_with_xprv(&mut self, xprv: String) -> Result { - let key = - bip32::Xpriv::from_str(&xprv).map_err(|_| WasmMiniscriptError::new("Invalid xprv"))?; + pub fn sign_with_xprv(&mut self, xprv: String) -> Result { + let key = bip32::Xpriv::from_str(&xprv).map_err(|_| WasmUtxoError::new("Invalid xprv"))?; self.0 .sign(&key, &Secp256k1::new()) .map_err(|(_, errors)| { - WasmMiniscriptError::new(&format!("{} errors: {:?}", errors.len(), errors)) + WasmUtxoError::new(&format!("{} errors: {:?}", errors.len(), errors)) }) .and_then(|r| r.try_to_js_value()) } #[wasm_bindgen(js_name = signWithPrv)] - pub fn sign_with_prv(&mut self, prv: Vec) -> Result { + pub fn sign_with_prv(&mut self, prv: Vec) -> Result { let privkey = PrivateKey::from_slice(&prv, miniscript::bitcoin::network::Network::Bitcoin) - .map_err(|_| WasmMiniscriptError::new("Invalid private key"))?; + .map_err(|_| WasmUtxoError::new("Invalid private key"))?; let secp = Secp256k1::new(); self.0 .sign(&SingleKeySigner::from_privkey(privkey, &secp), &secp) .map_err(|(_r, errors)| { - WasmMiniscriptError::new(&format!("{} errors: {:?}", errors.len(), errors)) + WasmUtxoError::new(&format!("{} errors: {:?}", errors.len(), errors)) }) .and_then(|r| r.try_to_js_value()) } #[wasm_bindgen(js_name = finalize)] - pub fn finalize_mut(&mut self) -> Result<(), WasmMiniscriptError> { + pub fn finalize_mut(&mut self) -> Result<(), WasmUtxoError> { self.0 .finalize_mut(&Secp256k1::verification_only()) .map_err(|vec_err| { - WasmMiniscriptError::new(&format!("{} errors: {:?}", vec_err.len(), vec_err)) + WasmUtxoError::new(&format!("{} errors: {:?}", vec_err.len(), vec_err)) }) } } diff --git a/packages/wasm-utxo/src/try_from_js_value.rs b/packages/wasm-utxo/src/try_from_js_value.rs index ac4a0416..be53cb91 100644 --- a/packages/wasm-utxo/src/try_from_js_value.rs +++ b/packages/wasm-utxo/src/try_from_js_value.rs @@ -1,9 +1,9 @@ use crate::address::utxolib_compat::{CashAddr, UtxolibNetwork}; -use crate::error::WasmMiniscriptError; +use crate::error::WasmUtxoError; use wasm_bindgen::JsValue; pub(crate) trait TryFromJsValue { - fn try_from_js_value(value: &JsValue) -> Result + fn try_from_js_value(value: &JsValue) -> Result where Self: Sized; } @@ -11,33 +11,33 @@ pub(crate) trait TryFromJsValue { // Implement TryFromJsValue for primitive types impl TryFromJsValue for String { - fn try_from_js_value(value: &JsValue) -> Result { + fn try_from_js_value(value: &JsValue) -> Result { value .as_string() - .ok_or_else(|| WasmMiniscriptError::new("Expected a string")) + .ok_or_else(|| WasmUtxoError::new("Expected a string")) } } impl TryFromJsValue for u8 { - fn try_from_js_value(value: &JsValue) -> Result { + fn try_from_js_value(value: &JsValue) -> Result { value .as_f64() - .ok_or_else(|| WasmMiniscriptError::new("Expected a number")) + .ok_or_else(|| WasmUtxoError::new("Expected a number")) .map(|n| n as u8) } } impl TryFromJsValue for u32 { - fn try_from_js_value(value: &JsValue) -> Result { + fn try_from_js_value(value: &JsValue) -> Result { value .as_f64() - .ok_or_else(|| WasmMiniscriptError::new("Expected a number")) + .ok_or_else(|| WasmUtxoError::new("Expected a number")) .map(|n| n as u32) } } impl TryFromJsValue for Option { - fn try_from_js_value(value: &JsValue) -> Result { + fn try_from_js_value(value: &JsValue) -> Result { if value.is_undefined() || value.is_null() { Ok(None) } else { @@ -47,22 +47,19 @@ impl TryFromJsValue for Option { } // Helper function to get a field from an object and convert it using TryFromJsValue -pub(crate) fn get_field( - obj: &JsValue, - key: &str, -) -> Result { +pub(crate) fn get_field(obj: &JsValue, key: &str) -> Result { let field_value = js_sys::Reflect::get(obj, &JsValue::from_str(key)) - .map_err(|_| WasmMiniscriptError::new(&format!("Failed to read {} from object", key)))?; + .map_err(|_| WasmUtxoError::new(&format!("Failed to read {} from object", key)))?; T::try_from_js_value(&field_value) - .map_err(|e| WasmMiniscriptError::new(&format!("{} (field: {})", e, key))) + .map_err(|e| WasmUtxoError::new(&format!("{} (field: {})", e, key))) } // Helper function to get a nested field using dot notation (e.g., "network.bip32.public") pub(crate) fn get_nested_field( obj: &JsValue, path: &str, -) -> Result { +) -> Result { let parts: Vec<&str> = path.split('.').collect(); let mut current = obj.clone(); @@ -72,26 +69,25 @@ pub(crate) fn get_nested_field( return get_field(¤t, part); } else { // Intermediate part - just get the object - current = js_sys::Reflect::get(¤t, &JsValue::from_str(part)).map_err(|_| { - WasmMiniscriptError::new(&format!("Failed to read {} from object", part)) - })?; + current = js_sys::Reflect::get(¤t, &JsValue::from_str(part)) + .map_err(|_| WasmUtxoError::new(&format!("Failed to read {} from object", part)))?; } } - Err(WasmMiniscriptError::new("Empty path")) + Err(WasmUtxoError::new("Empty path")) } // Helper function to get a buffer field as a fixed-size byte array pub(crate) fn get_buffer_field( obj: &JsValue, key: &str, -) -> Result<[u8; N], WasmMiniscriptError> { +) -> Result<[u8; N], WasmUtxoError> { let field_value = js_sys::Reflect::get(obj, &JsValue::from_str(key)) - .map_err(|_| WasmMiniscriptError::new(&format!("Failed to read {} from object", key)))?; + .map_err(|_| WasmUtxoError::new(&format!("Failed to read {} from object", key)))?; let buffer = js_sys::Uint8Array::new(&field_value); if buffer.length() as usize != N { - return Err(WasmMiniscriptError::new(&format!( + return Err(WasmUtxoError::new(&format!( "{} must be {} bytes, got {}", key, N, @@ -106,12 +102,9 @@ pub(crate) fn get_buffer_field( // Helper function to get a buffer field as a Vec #[allow(dead_code)] -pub(crate) fn get_buffer_field_vec( - obj: &JsValue, - key: &str, -) -> Result, WasmMiniscriptError> { +pub(crate) fn get_buffer_field_vec(obj: &JsValue, key: &str) -> Result, WasmUtxoError> { let field_value = js_sys::Reflect::get(obj, &JsValue::from_str(key)) - .map_err(|_| WasmMiniscriptError::new(&format!("Failed to read {} from object", key)))?; + .map_err(|_| WasmUtxoError::new(&format!("Failed to read {} from object", key)))?; let buffer = js_sys::Uint8Array::new(&field_value); let mut bytes = vec![0u8; buffer.length() as usize]; @@ -120,7 +113,7 @@ pub(crate) fn get_buffer_field_vec( } impl TryFromJsValue for UtxolibNetwork { - fn try_from_js_value(value: &JsValue) -> Result { + fn try_from_js_value(value: &JsValue) -> Result { let pub_key_hash = get_field(value, "pubKeyHash")?; let script_hash = get_field(value, "scriptHash")?; let bech32 = get_field(value, "bech32")?; @@ -136,7 +129,7 @@ impl TryFromJsValue for UtxolibNetwork { } impl TryFromJsValue for CashAddr { - fn try_from_js_value(value: &JsValue) -> Result { + fn try_from_js_value(value: &JsValue) -> Result { let prefix = get_field(value, "prefix")?; let pub_key_hash = get_field(value, "pubKeyHash")?; let script_hash = get_field(value, "scriptHash")?; diff --git a/packages/wasm-utxo/src/try_into_js_value.rs b/packages/wasm-utxo/src/try_into_js_value.rs index fde3fdda..fe54f142 100644 --- a/packages/wasm-utxo/src/try_into_js_value.rs +++ b/packages/wasm-utxo/src/try_into_js_value.rs @@ -1,4 +1,4 @@ -use crate::error::WasmMiniscriptError; +use crate::error::WasmUtxoError; use js_sys::Array; use miniscript::bitcoin::hashes::{hash160, ripemd160}; use miniscript::bitcoin::psbt::{SigningKeys, SigningKeysMap}; @@ -12,7 +12,7 @@ use std::sync::Arc; use wasm_bindgen::JsValue; pub(crate) trait TryIntoJsValue { - fn try_to_js_value(&self) -> Result; + fn try_to_js_value(&self) -> Result; } macro_rules! js_obj { @@ -20,9 +20,9 @@ macro_rules! js_obj { let obj = js_sys::Object::new(); $( js_sys::Reflect::set(&obj, &$key.into(), &$value.try_to_js_value()?.into()) - .map_err(|_| WasmMiniscriptError::new("Failed to set object property"))?; + .map_err(|_| WasmUtxoError::new("Failed to set object property"))?; )* - Ok(Into::::into(obj)) as Result + Ok(Into::::into(obj)) as Result }}; } @@ -36,33 +36,33 @@ macro_rules! js_arr { }}; } -impl From for JsValue { - fn from(err: WasmMiniscriptError) -> Self { +impl From for JsValue { + fn from(err: WasmUtxoError) -> Self { js_sys::Error::new(&err.to_string()).into() } } impl TryIntoJsValue for JsValue { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(self.clone()) } } impl TryIntoJsValue for Arc { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { self.as_ref().try_to_js_value() } } impl TryIntoJsValue for String { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(JsValue::from_str(self)) } } // array of TryToJsValue impl TryIntoJsValue for Vec { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { let arr = Array::new(); for item in self.iter() { arr.push(&item.try_to_js_value()?); @@ -72,7 +72,7 @@ impl TryIntoJsValue for Vec { } impl TryIntoJsValue for Option { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { match self { Some(v) => v.try_to_js_value(), None => Ok(JsValue::NULL), @@ -81,55 +81,55 @@ impl TryIntoJsValue for Option { } impl TryIntoJsValue for XOnlyPublicKey { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(JsValue::from_str(&self.to_string())) } } impl TryIntoJsValue for PublicKey { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(JsValue::from_str(&self.to_string())) } } impl TryIntoJsValue for AbsLockTime { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(JsValue::from_f64(self.to_consensus_u32() as f64)) } } impl TryIntoJsValue for RelLockTime { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(JsValue::from_f64(self.to_consensus_u32() as f64)) } } impl TryIntoJsValue for ripemd160::Hash { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(JsValue::from_str(&self.to_string())) } } impl TryIntoJsValue for hash160::Hash { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(JsValue::from_str(&self.to_string())) } } impl TryIntoJsValue for hash256::Hash { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(JsValue::from_str(&self.to_string())) } } impl TryIntoJsValue for usize { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(JsValue::from_f64(*self as f64)) } } impl TryIntoJsValue for Threshold { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { let arr = Array::new(); arr.push(&self.k().try_to_js_value()?); for v in self.iter() { @@ -142,13 +142,13 @@ impl TryIntoJsValue for Threshold { impl TryIntoJsValue for Miniscript { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { self.node.try_to_js_value() } } impl TryIntoJsValue for Terminal { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { match self { Terminal::True => Ok(JsValue::TRUE), Terminal::False => Ok(JsValue::FALSE), @@ -186,7 +186,7 @@ impl TryIntoJsValue for impl TryIntoJsValue for SortedMultiVec { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { js_obj!( "k" => self.k(), "n" => self.n(), @@ -196,7 +196,7 @@ impl TryIntoJsValue } impl TryIntoJsValue for ShInner { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { match self { ShInner::Wsh(v) => js_obj!("Wsh" => v.as_inner()), ShInner::Wpkh(v) => js_obj!("Wpkh" => v.as_inner()), @@ -207,7 +207,7 @@ impl TryIntoJsValue for ShInner { } impl TryIntoJsValue for WshInner { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { match self { WshInner::SortedMulti(v) => js_obj!("SortedMulti" => v), WshInner::Ms(v) => js_obj!("Ms" => v), @@ -216,13 +216,13 @@ impl TryIntoJsValue for WshInner { } impl TryIntoJsValue for Tr { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { Ok(js_arr!(self.internal_key(), self.tap_tree())) } } impl TryIntoJsValue for TapTree { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { match self { TapTree::Tree { left, right, .. } => js_obj!("Tree" => js_arr!(left, right)), TapTree::Leaf(ms) => ms.try_to_js_value(), @@ -231,7 +231,7 @@ impl TryIntoJsValue for TapTree { } impl TryIntoJsValue for DescriptorPublicKey { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { match self { DescriptorPublicKey::Single(_v) => js_obj!("Single" => self.to_string()), DescriptorPublicKey::XPub(_v) => js_obj!("XPub" => self.to_string()), @@ -241,13 +241,13 @@ impl TryIntoJsValue for DescriptorPublicKey { } impl TryIntoJsValue for DefiniteDescriptorKey { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { self.as_descriptor_public_key().try_to_js_value() } } impl TryIntoJsValue for Descriptor { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { match self { Descriptor::Bare(v) => js_obj!("Bare" => v.as_inner()), Descriptor::Pkh(v) => js_obj!("Pkh" => v.as_inner()), @@ -260,14 +260,14 @@ impl TryIntoJsValue for Descriptor { } impl TryIntoJsValue for DescriptorType { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { let str_from_enum = format!("{:?}", self); Ok(JsValue::from_str(&str_from_enum)) } } impl TryIntoJsValue for SigningKeys { - fn try_to_js_value(&self) -> Result { + fn try_to_js_value(&self) -> Result { match self { SigningKeys::Ecdsa(v) => { js_obj!("Ecdsa" => v) @@ -280,11 +280,11 @@ impl TryIntoJsValue for SigningKeys { } impl TryIntoJsValue for SigningKeysMap { - fn try_to_js_value(&self) -> Result { + 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()?) - .map_err(|_| WasmMiniscriptError::new("Failed to set object property"))?; + .map_err(|_| WasmUtxoError::new("Failed to set object property"))?; } Ok(obj.into()) }