feat: add descriptor key related error

This commit is contained in:
Matthew 2024-04-20 16:41:04 -05:00
parent e609b57bff
commit e1a93379ce
No known key found for this signature in database
GPG Key ID: 8D4FCD82DD54DDD2
4 changed files with 73 additions and 30 deletions

View File

@ -33,6 +33,13 @@ interface Bip32Error {
UnknownError(string e); UnknownError(string e);
}; };
[Error]
interface DescriptorKeyError {
Parse(string e);
InvalidKeyType();
Bip32(string e);
};
[Error] [Error]
interface CalculateFeeError { interface CalculateFeeError {
MissingTxOut(sequence<OutPoint> out_points); MissingTxOut(sequence<OutPoint> out_points);
@ -369,13 +376,13 @@ interface DerivationPath {
interface DescriptorSecretKey { interface DescriptorSecretKey {
constructor(Network network, [ByRef] Mnemonic mnemonic, string? password); constructor(Network network, [ByRef] Mnemonic mnemonic, string? password);
[Name=from_string, Throws=Alpha3Error] [Name=from_string, Throws=DescriptorKeyError]
constructor(string secret_key); constructor(string secret_key);
[Throws=Alpha3Error] [Throws=DescriptorKeyError]
DescriptorSecretKey derive([ByRef] DerivationPath path); DescriptorSecretKey derive([ByRef] DerivationPath path);
[Throws=Alpha3Error] [Throws=DescriptorKeyError]
DescriptorSecretKey extend([ByRef] DerivationPath path); DescriptorSecretKey extend([ByRef] DerivationPath path);
DescriptorPublicKey as_public(); DescriptorPublicKey as_public();
@ -386,13 +393,13 @@ interface DescriptorSecretKey {
}; };
interface DescriptorPublicKey { interface DescriptorPublicKey {
[Name=from_string, Throws=Alpha3Error] [Name=from_string, Throws=DescriptorKeyError]
constructor(string public_key); constructor(string public_key);
[Throws=Alpha3Error] [Throws=DescriptorKeyError]
DescriptorPublicKey derive([ByRef] DerivationPath path); DescriptorPublicKey derive([ByRef] DerivationPath path);
[Throws=Alpha3Error] [Throws=DescriptorKeyError]
DescriptorPublicKey extend([ByRef] DerivationPath path); DescriptorPublicKey extend([ByRef] DerivationPath path);
string as_string(); string as_string();

View File

@ -16,6 +16,7 @@ use bitcoin_internals::hex::display::DisplayHex;
use crate::error::bip32::Error as BdkBip32Error; use crate::error::bip32::Error as BdkBip32Error;
use bdk::bitcoin::address::ParseError; use bdk::bitcoin::address::ParseError;
use bdk::keys::bip39::Error as BdkBip39Error; use bdk::keys::bip39::Error as BdkBip39Error;
use bdk::miniscript::descriptor::DescriptorKeyParseError as BdkDescriptorKeyParseError;
use bdk::bitcoin::bip32; use bdk::bitcoin::bip32;
@ -133,6 +134,18 @@ pub enum CreateTxError {
MiniscriptPsbt { e: String }, 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)] #[derive(Debug, thiserror::Error)]
pub enum CalculateFeeError { pub enum CalculateFeeError {
#[error("missing transaction output: {out_points:?}")] #[error("missing transaction output: {out_points:?}")]
@ -545,6 +558,22 @@ impl From<BdkSignerError> for SignerError {
} }
} }
impl From<BdkDescriptorKeyParseError> for DescriptorKeyError {
fn from(err: BdkDescriptorKeyParseError) -> DescriptorKeyError {
DescriptorKeyError::Parse {
e: format!("DescriptorKeyError error: {:?}", err),
}
}
}
impl From<bdk::bitcoin::bip32::Error> for DescriptorKeyError {
fn from(err: bdk::bitcoin::bip32::Error) -> DescriptorKeyError {
DescriptorKeyError::Bip32 {
e: format!("BIP32 derivation error: {:?}", err),
}
}
}
impl From<BdkPsbtParseError> for PsbtParseError { impl From<BdkPsbtParseError> for PsbtParseError {
fn from(error: BdkPsbtParseError) -> Self { fn from(error: BdkPsbtParseError) -> Self {
match error { match error {

View File

@ -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::bip32::DerivationPath as BdkDerivationPath;
use bdk::bitcoin::key::Secp256k1; use bdk::bitcoin::key::Secp256k1;
@ -86,22 +86,25 @@ impl DescriptorSecretKey {
} }
} }
pub(crate) fn from_string(private_key: String) -> Result<Self, Alpha3Error> { pub(crate) fn from_string(private_key: String) -> Result<Self, DescriptorKeyError> {
let descriptor_secret_key = BdkDescriptorSecretKey::from_str(private_key.as_str()) let descriptor_secret_key = BdkDescriptorSecretKey::from_str(private_key.as_str())
.map_err(|_| Alpha3Error::Generic)?; .map_err(DescriptorKeyError::from)?;
Ok(Self { Ok(Self {
inner: descriptor_secret_key, inner: descriptor_secret_key,
}) })
} }
pub(crate) fn derive(&self, path: &DerivationPath) -> Result<Arc<Self>, Alpha3Error> { pub(crate) fn derive(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let descriptor_secret_key = &self.inner; let descriptor_secret_key = &self.inner;
let path = path.inner_mutex.lock().unwrap().deref().clone(); let path = path.inner_mutex.lock().unwrap().deref().clone();
match descriptor_secret_key { match descriptor_secret_key {
BdkDescriptorSecretKey::Single(_) => Err(Alpha3Error::Generic), BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { 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() { let key_source = match descriptor_x_key.origin.clone() {
Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)), Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)),
None => (descriptor_x_key.xkey.fingerprint(&secp), path), None => (descriptor_x_key.xkey.fingerprint(&secp), path),
@ -116,15 +119,15 @@ impl DescriptorSecretKey {
inner: derived_descriptor_secret_key, inner: derived_descriptor_secret_key,
})) }))
} }
BdkDescriptorSecretKey::MultiXPrv(_) => Err(Alpha3Error::Generic), BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
} }
} }
pub(crate) fn extend(&self, path: &DerivationPath) -> Result<Arc<Self>, Alpha3Error> { pub(crate) fn extend(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
let descriptor_secret_key = &self.inner; let descriptor_secret_key = &self.inner;
let path = path.inner_mutex.lock().unwrap().deref().clone(); let path = path.inner_mutex.lock().unwrap().deref().clone();
match descriptor_secret_key { match descriptor_secret_key {
BdkDescriptorSecretKey::Single(_) => Err(Alpha3Error::Generic), BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
let extended_path = descriptor_x_key.derivation_path.extend(path); let extended_path = descriptor_x_key.derivation_path.extend(path);
let extended_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey { let extended_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
@ -137,7 +140,7 @@ impl DescriptorSecretKey {
inner: extended_descriptor_secret_key, inner: extended_descriptor_secret_key,
})) }))
} }
BdkDescriptorSecretKey::MultiXPrv(_) => Err(Alpha3Error::Generic), BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
} }
} }
@ -177,23 +180,26 @@ pub struct DescriptorPublicKey {
} }
impl DescriptorPublicKey { impl DescriptorPublicKey {
pub(crate) fn from_string(public_key: String) -> Result<Self, Alpha3Error> { pub(crate) fn from_string(public_key: String) -> Result<Self, DescriptorKeyError> {
let descriptor_public_key = BdkDescriptorPublicKey::from_str(public_key.as_str()) let descriptor_public_key = BdkDescriptorPublicKey::from_str(public_key.as_str())
.map_err(|_| Alpha3Error::Generic)?; .map_err(DescriptorKeyError::from)?;
Ok(Self { Ok(Self {
inner: descriptor_public_key, inner: descriptor_public_key,
}) })
} }
pub(crate) fn derive(&self, path: &DerivationPath) -> Result<Arc<Self>, Alpha3Error> { pub(crate) fn derive(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let descriptor_public_key = &self.inner; let descriptor_public_key = &self.inner;
let path = path.inner_mutex.lock().unwrap().deref().clone(); let path = path.inner_mutex.lock().unwrap().deref().clone();
match descriptor_public_key { match descriptor_public_key {
BdkDescriptorPublicKey::Single(_) => Err(Alpha3Error::Generic), BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
BdkDescriptorPublicKey::XPub(descriptor_x_key) => { 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() { let key_source = match descriptor_x_key.origin.clone() {
Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)), Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)),
None => (descriptor_x_key.xkey.fingerprint(), path), None => (descriptor_x_key.xkey.fingerprint(), path),
@ -208,15 +214,15 @@ impl DescriptorPublicKey {
inner: derived_descriptor_public_key, inner: derived_descriptor_public_key,
})) }))
} }
BdkDescriptorPublicKey::MultiXPub(_) => Err(Alpha3Error::Generic), BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
} }
} }
pub(crate) fn extend(&self, path: &DerivationPath) -> Result<Arc<Self>, Alpha3Error> { pub(crate) fn extend(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
let descriptor_public_key = &self.inner; let descriptor_public_key = &self.inner;
let path = path.inner_mutex.lock().unwrap().deref().clone(); let path = path.inner_mutex.lock().unwrap().deref().clone();
match descriptor_public_key { match descriptor_public_key {
BdkDescriptorPublicKey::Single(_) => Err(Alpha3Error::Generic), BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
BdkDescriptorPublicKey::XPub(descriptor_x_key) => { BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
let extended_path = descriptor_x_key.derivation_path.extend(path); let extended_path = descriptor_x_key.derivation_path.extend(path);
let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey { let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
@ -229,7 +235,7 @@ impl DescriptorPublicKey {
inner: extended_descriptor_public_key, inner: extended_descriptor_public_key,
})) }))
} }
BdkDescriptorPublicKey::MultiXPub(_) => Err(Alpha3Error::Generic), BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
} }
} }
@ -242,7 +248,7 @@ impl DescriptorPublicKey {
mod test { mod test {
use crate::keys::{DerivationPath, DescriptorPublicKey, DescriptorSecretKey, Mnemonic}; use crate::keys::{DerivationPath, DescriptorPublicKey, DescriptorSecretKey, Mnemonic};
// use bdk::bitcoin::hashes::hex::ToHex; // use bdk::bitcoin::hashes::hex::ToHex;
use crate::error::Alpha3Error; use crate::error::DescriptorKeyError;
use bdk::bitcoin::Network; use bdk::bitcoin::Network;
use std::sync::Arc; use std::sync::Arc;
@ -254,7 +260,7 @@ mod test {
fn derive_dsk( fn derive_dsk(
key: &DescriptorSecretKey, key: &DescriptorSecretKey,
path: &str, path: &str,
) -> Result<Arc<DescriptorSecretKey>, Alpha3Error> { ) -> Result<Arc<DescriptorSecretKey>, DescriptorKeyError> {
let path = DerivationPath::new(path.to_string()).unwrap(); let path = DerivationPath::new(path.to_string()).unwrap();
key.derive(&path) key.derive(&path)
} }
@ -262,7 +268,7 @@ mod test {
fn extend_dsk( fn extend_dsk(
key: &DescriptorSecretKey, key: &DescriptorSecretKey,
path: &str, path: &str,
) -> Result<Arc<DescriptorSecretKey>, Alpha3Error> { ) -> Result<Arc<DescriptorSecretKey>, DescriptorKeyError> {
let path = DerivationPath::new(path.to_string()).unwrap(); let path = DerivationPath::new(path.to_string()).unwrap();
key.extend(&path) key.extend(&path)
} }
@ -270,7 +276,7 @@ mod test {
fn derive_dpk( fn derive_dpk(
key: &DescriptorPublicKey, key: &DescriptorPublicKey,
path: &str, path: &str,
) -> Result<Arc<DescriptorPublicKey>, Alpha3Error> { ) -> Result<Arc<DescriptorPublicKey>, DescriptorKeyError> {
let path = DerivationPath::new(path.to_string()).unwrap(); let path = DerivationPath::new(path.to_string()).unwrap();
key.derive(&path) key.derive(&path)
} }
@ -278,7 +284,7 @@ mod test {
fn extend_dpk( fn extend_dpk(
key: &DescriptorPublicKey, key: &DescriptorPublicKey,
path: &str, path: &str,
) -> Result<Arc<DescriptorPublicKey>, Alpha3Error> { ) -> Result<Arc<DescriptorPublicKey>, DescriptorKeyError> {
let path = DerivationPath::new(path.to_string()).unwrap(); let path = DerivationPath::new(path.to_string()).unwrap();
key.extend(&path) key.extend(&path)
} }

View File

@ -22,6 +22,7 @@ use crate::error::CalculateFeeError;
use crate::error::CannotConnectError; use crate::error::CannotConnectError;
use crate::error::CreateTxError; use crate::error::CreateTxError;
use crate::error::DescriptorError; use crate::error::DescriptorError;
use crate::error::DescriptorKeyError;
use crate::error::EsploraError; use crate::error::EsploraError;
use crate::error::ExtractTxError; use crate::error::ExtractTxError;
use crate::error::FeeRateError; use crate::error::FeeRateError;