From e1a93379cefad4a6b659364a88a779028022bfb5 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sat, 20 Apr 2024 16:41:04 -0500 Subject: [PATCH] feat: add descriptor key related error --- bdk-ffi/src/bdk.udl | 19 +++++++++++----- bdk-ffi/src/error.rs | 29 ++++++++++++++++++++++++ bdk-ffi/src/keys.rs | 54 ++++++++++++++++++++++++-------------------- bdk-ffi/src/lib.rs | 1 + 4 files changed, 73 insertions(+), 30 deletions(-) diff --git a/bdk-ffi/src/bdk.udl b/bdk-ffi/src/bdk.udl index c5966f2..c614818 100644 --- a/bdk-ffi/src/bdk.udl +++ b/bdk-ffi/src/bdk.udl @@ -33,6 +33,13 @@ interface Bip32Error { UnknownError(string e); }; +[Error] +interface DescriptorKeyError { + Parse(string e); + InvalidKeyType(); + Bip32(string e); +}; + [Error] interface CalculateFeeError { MissingTxOut(sequence out_points); @@ -369,13 +376,13 @@ interface DerivationPath { interface DescriptorSecretKey { constructor(Network network, [ByRef] Mnemonic mnemonic, string? password); - [Name=from_string, Throws=Alpha3Error] + [Name=from_string, Throws=DescriptorKeyError] constructor(string secret_key); - [Throws=Alpha3Error] + [Throws=DescriptorKeyError] DescriptorSecretKey derive([ByRef] DerivationPath path); - [Throws=Alpha3Error] + [Throws=DescriptorKeyError] DescriptorSecretKey extend([ByRef] DerivationPath path); DescriptorPublicKey as_public(); @@ -386,13 +393,13 @@ interface DescriptorSecretKey { }; interface DescriptorPublicKey { - [Name=from_string, Throws=Alpha3Error] + [Name=from_string, Throws=DescriptorKeyError] constructor(string public_key); - [Throws=Alpha3Error] + [Throws=DescriptorKeyError] DescriptorPublicKey derive([ByRef] DerivationPath path); - [Throws=Alpha3Error] + [Throws=DescriptorKeyError] DescriptorPublicKey extend([ByRef] DerivationPath path); string as_string(); diff --git a/bdk-ffi/src/error.rs b/bdk-ffi/src/error.rs index 9bd6409..7f0e125 100644 --- a/bdk-ffi/src/error.rs +++ b/bdk-ffi/src/error.rs @@ -16,6 +16,7 @@ use bitcoin_internals::hex::display::DisplayHex; use crate::error::bip32::Error as BdkBip32Error; use bdk::bitcoin::address::ParseError; use bdk::keys::bip39::Error as BdkBip39Error; +use bdk::miniscript::descriptor::DescriptorKeyParseError as BdkDescriptorKeyParseError; use bdk::bitcoin::bip32; @@ -133,6 +134,18 @@ pub enum CreateTxError { MiniscriptPsbt { e: String }, } +#[derive(Debug, thiserror::Error)] +pub enum DescriptorKeyError { + #[error("error parsing descriptor key: {e}")] + Parse { e: String }, + + #[error("error invalid key type")] + InvalidKeyType, + + #[error("error bip 32 related: {e}")] + Bip32 { e: String }, +} + #[derive(Debug, thiserror::Error)] pub enum CalculateFeeError { #[error("missing transaction output: {out_points:?}")] @@ -545,6 +558,22 @@ impl From for SignerError { } } +impl From for DescriptorKeyError { + fn from(err: BdkDescriptorKeyParseError) -> DescriptorKeyError { + DescriptorKeyError::Parse { + e: format!("DescriptorKeyError error: {:?}", err), + } + } +} + +impl From for DescriptorKeyError { + fn from(err: bdk::bitcoin::bip32::Error) -> DescriptorKeyError { + DescriptorKeyError::Bip32 { + e: format!("BIP32 derivation error: {:?}", err), + } + } +} + impl From for PsbtParseError { fn from(error: BdkPsbtParseError) -> Self { match error { diff --git a/bdk-ffi/src/keys.rs b/bdk-ffi/src/keys.rs index 864554d..40a940e 100644 --- a/bdk-ffi/src/keys.rs +++ b/bdk-ffi/src/keys.rs @@ -1,4 +1,4 @@ -use crate::error::{Alpha3Error, Bip32Error, Bip39Error}; +use crate::error::{Bip32Error, Bip39Error, DescriptorKeyError}; use bdk::bitcoin::bip32::DerivationPath as BdkDerivationPath; use bdk::bitcoin::key::Secp256k1; @@ -86,22 +86,25 @@ impl DescriptorSecretKey { } } - pub(crate) fn from_string(private_key: String) -> Result { + pub(crate) fn from_string(private_key: String) -> Result { let descriptor_secret_key = BdkDescriptorSecretKey::from_str(private_key.as_str()) - .map_err(|_| Alpha3Error::Generic)?; + .map_err(DescriptorKeyError::from)?; Ok(Self { inner: descriptor_secret_key, }) } - pub(crate) fn derive(&self, path: &DerivationPath) -> Result, Alpha3Error> { + pub(crate) fn derive(&self, path: &DerivationPath) -> Result, DescriptorKeyError> { let secp = Secp256k1::new(); let descriptor_secret_key = &self.inner; let path = path.inner_mutex.lock().unwrap().deref().clone(); match descriptor_secret_key { - BdkDescriptorSecretKey::Single(_) => Err(Alpha3Error::Generic), + BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType), BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { - let derived_xprv = descriptor_x_key.xkey.derive_priv(&secp, &path)?; + let derived_xprv = descriptor_x_key + .xkey + .derive_priv(&secp, &path) + .map_err(DescriptorKeyError::from)?; let key_source = match descriptor_x_key.origin.clone() { Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)), None => (descriptor_x_key.xkey.fingerprint(&secp), path), @@ -116,15 +119,15 @@ impl DescriptorSecretKey { inner: derived_descriptor_secret_key, })) } - BdkDescriptorSecretKey::MultiXPrv(_) => Err(Alpha3Error::Generic), + BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType), } } - pub(crate) fn extend(&self, path: &DerivationPath) -> Result, Alpha3Error> { + pub(crate) fn extend(&self, path: &DerivationPath) -> Result, DescriptorKeyError> { let descriptor_secret_key = &self.inner; let path = path.inner_mutex.lock().unwrap().deref().clone(); match descriptor_secret_key { - BdkDescriptorSecretKey::Single(_) => Err(Alpha3Error::Generic), + BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType), BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { let extended_path = descriptor_x_key.derivation_path.extend(path); let extended_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey { @@ -137,7 +140,7 @@ impl DescriptorSecretKey { inner: extended_descriptor_secret_key, })) } - BdkDescriptorSecretKey::MultiXPrv(_) => Err(Alpha3Error::Generic), + BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType), } } @@ -177,23 +180,26 @@ pub struct DescriptorPublicKey { } impl DescriptorPublicKey { - pub(crate) fn from_string(public_key: String) -> Result { + pub(crate) fn from_string(public_key: String) -> Result { let descriptor_public_key = BdkDescriptorPublicKey::from_str(public_key.as_str()) - .map_err(|_| Alpha3Error::Generic)?; + .map_err(DescriptorKeyError::from)?; Ok(Self { inner: descriptor_public_key, }) } - pub(crate) fn derive(&self, path: &DerivationPath) -> Result, Alpha3Error> { + pub(crate) fn derive(&self, path: &DerivationPath) -> Result, DescriptorKeyError> { let secp = Secp256k1::new(); let descriptor_public_key = &self.inner; let path = path.inner_mutex.lock().unwrap().deref().clone(); match descriptor_public_key { - BdkDescriptorPublicKey::Single(_) => Err(Alpha3Error::Generic), + BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType), BdkDescriptorPublicKey::XPub(descriptor_x_key) => { - let derived_xpub = descriptor_x_key.xkey.derive_pub(&secp, &path)?; + let derived_xpub = descriptor_x_key + .xkey + .derive_pub(&secp, &path) + .map_err(DescriptorKeyError::from)?; let key_source = match descriptor_x_key.origin.clone() { Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)), None => (descriptor_x_key.xkey.fingerprint(), path), @@ -208,15 +214,15 @@ impl DescriptorPublicKey { inner: derived_descriptor_public_key, })) } - BdkDescriptorPublicKey::MultiXPub(_) => Err(Alpha3Error::Generic), + BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType), } } - pub(crate) fn extend(&self, path: &DerivationPath) -> Result, Alpha3Error> { + pub(crate) fn extend(&self, path: &DerivationPath) -> Result, DescriptorKeyError> { let descriptor_public_key = &self.inner; let path = path.inner_mutex.lock().unwrap().deref().clone(); match descriptor_public_key { - BdkDescriptorPublicKey::Single(_) => Err(Alpha3Error::Generic), + BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType), BdkDescriptorPublicKey::XPub(descriptor_x_key) => { let extended_path = descriptor_x_key.derivation_path.extend(path); let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey { @@ -229,7 +235,7 @@ impl DescriptorPublicKey { inner: extended_descriptor_public_key, })) } - BdkDescriptorPublicKey::MultiXPub(_) => Err(Alpha3Error::Generic), + BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType), } } @@ -242,7 +248,7 @@ impl DescriptorPublicKey { mod test { use crate::keys::{DerivationPath, DescriptorPublicKey, DescriptorSecretKey, Mnemonic}; // use bdk::bitcoin::hashes::hex::ToHex; - use crate::error::Alpha3Error; + use crate::error::DescriptorKeyError; use bdk::bitcoin::Network; use std::sync::Arc; @@ -254,7 +260,7 @@ mod test { fn derive_dsk( key: &DescriptorSecretKey, path: &str, - ) -> Result, Alpha3Error> { + ) -> Result, DescriptorKeyError> { let path = DerivationPath::new(path.to_string()).unwrap(); key.derive(&path) } @@ -262,7 +268,7 @@ mod test { fn extend_dsk( key: &DescriptorSecretKey, path: &str, - ) -> Result, Alpha3Error> { + ) -> Result, DescriptorKeyError> { let path = DerivationPath::new(path.to_string()).unwrap(); key.extend(&path) } @@ -270,7 +276,7 @@ mod test { fn derive_dpk( key: &DescriptorPublicKey, path: &str, - ) -> Result, Alpha3Error> { + ) -> Result, DescriptorKeyError> { let path = DerivationPath::new(path.to_string()).unwrap(); key.derive(&path) } @@ -278,7 +284,7 @@ mod test { fn extend_dpk( key: &DescriptorPublicKey, path: &str, - ) -> Result, Alpha3Error> { + ) -> Result, DescriptorKeyError> { let path = DerivationPath::new(path.to_string()).unwrap(); key.extend(&path) } diff --git a/bdk-ffi/src/lib.rs b/bdk-ffi/src/lib.rs index 4dd7e12..9c01453 100644 --- a/bdk-ffi/src/lib.rs +++ b/bdk-ffi/src/lib.rs @@ -22,6 +22,7 @@ use crate::error::CalculateFeeError; use crate::error::CannotConnectError; use crate::error::CreateTxError; use crate::error::DescriptorError; +use crate::error::DescriptorKeyError; use crate::error::EsploraError; use crate::error::ExtractTxError; use crate::error::FeeRateError;