From 6fcb8985f1605b92cf55201e060b5eecb4db7af1 Mon Sep 17 00:00:00 2001 From: thunderbiscuit Date: Mon, 19 Dec 2022 13:42:17 -0500 Subject: [PATCH] Refactor: separate descriptor from lib.rs --- bdk-ffi/src/blockchain.rs | 3 +- bdk-ffi/src/descriptor.rs | 194 ++++++++++++++++++++++++++++++++++++++ bdk-ffi/src/lib.rs | 190 +------------------------------------ bdk-ffi/src/psbt.rs | 3 +- bdk-ffi/src/wallet.rs | 7 +- 5 files changed, 203 insertions(+), 194 deletions(-) create mode 100644 bdk-ffi/src/descriptor.rs diff --git a/bdk-ffi/src/blockchain.rs b/bdk-ffi/src/blockchain.rs index c32e98d..19389ab 100644 --- a/bdk-ffi/src/blockchain.rs +++ b/bdk-ffi/src/blockchain.rs @@ -1,5 +1,5 @@ // use crate::BlockchainConfig; -use crate::PartiallySignedTransaction; +use crate::{PartiallySignedTransaction, BdkError}; use bdk::bitcoin::Network; use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig}; use bdk::blockchain::rpc::Auth as BdkAuth; @@ -11,7 +11,6 @@ use bdk::blockchain::{ electrum::ElectrumBlockchainConfig, esplora::EsploraBlockchainConfig, rpc::RpcConfig as BdkRpcConfig, ConfigurableBlockchain, }; -use bdk::Error as BdkError; use std::convert::{From, TryFrom}; use std::path::PathBuf; use std::sync::{Mutex, MutexGuard}; diff --git a/bdk-ffi/src/descriptor.rs b/bdk-ffi/src/descriptor.rs new file mode 100644 index 0000000..92fe787 --- /dev/null +++ b/bdk-ffi/src/descriptor.rs @@ -0,0 +1,194 @@ +use std::ops::Deref; +use std::str::FromStr; +use std::sync::Arc; +use bdk::bitcoin::Network; +use bdk::bitcoin::secp256k1::Secp256k1; +use bdk::bitcoin::util::bip32::Fingerprint; +use bdk::descriptor::{ExtendedDescriptor, IntoWalletDescriptor, KeyMap}; +use bdk::KeychainKind; +use bdk::template::{Bip44, Bip44Public, Bip49, Bip49Public, Bip84, Bip84Public, DescriptorTemplate}; +use bdk::keys::{ + DescriptorPublicKey as BdkDescriptorPublicKey, + DescriptorSecretKey as BdkDescriptorSecretKey, +}; +use crate::{DescriptorPublicKey, DescriptorSecretKey, BdkError}; + +#[derive(Debug)] +pub(crate) struct Descriptor { + pub(crate) extended_descriptor: ExtendedDescriptor, + pub(crate) key_map: KeyMap, +} + +impl Descriptor { + pub(crate) fn new(descriptor: String, network: Network) -> Result { + let secp = Secp256k1::new(); + let (extended_descriptor, key_map) = descriptor.into_wallet_descriptor(&secp, network)?; + Ok(Self { + extended_descriptor, + key_map, + }) + } + + pub(crate) fn new_bip44( + secret_key: Arc, + keychain_kind: KeychainKind, + network: Network, + ) -> Self { + let derivable_key = secret_key.descriptor_secret_key_mutex.lock().unwrap(); + + match derivable_key.deref() { + BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { + let derivable_key = descriptor_x_key.xkey; + let (extended_descriptor, key_map, _) = + Bip44(derivable_key, keychain_kind).build(network).unwrap(); + Self { + extended_descriptor, + key_map, + } + } + BdkDescriptorSecretKey::Single(_) => { + unreachable!() + } + } + } + + pub(crate) fn new_bip44_public( + public_key: Arc, + fingerprint: String, + keychain_kind: KeychainKind, + network: Network, + ) -> Self { + let fingerprint = Fingerprint::from_str(fingerprint.as_str()).unwrap(); + let derivable_key = public_key.descriptor_public_key_mutex.lock().unwrap(); + + match derivable_key.deref() { + BdkDescriptorPublicKey::XPub(descriptor_x_key) => { + let derivable_key = descriptor_x_key.xkey; + let (extended_descriptor, key_map, _) = + Bip44Public(derivable_key, fingerprint, keychain_kind) + .build(network) + .unwrap(); + + Self { + extended_descriptor, + key_map, + } + } + BdkDescriptorPublicKey::Single(_) => { + unreachable!() + } + } + } + + pub(crate) fn new_bip49( + secret_key: Arc, + keychain_kind: KeychainKind, + network: Network, + ) -> Self { + let derivable_key = secret_key.descriptor_secret_key_mutex.lock().unwrap(); + + match derivable_key.deref() { + BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { + let derivable_key = descriptor_x_key.xkey; + let (extended_descriptor, key_map, _) = + Bip49(derivable_key, keychain_kind).build(network).unwrap(); + Self { + extended_descriptor, + key_map, + } + } + BdkDescriptorSecretKey::Single(_) => { + unreachable!() + } + } + } + + pub(crate) fn new_bip49_public( + public_key: Arc, + fingerprint: String, + keychain_kind: KeychainKind, + network: Network, + ) -> Self { + let fingerprint = Fingerprint::from_str(fingerprint.as_str()).unwrap(); + let derivable_key = public_key.descriptor_public_key_mutex.lock().unwrap(); + + match derivable_key.deref() { + BdkDescriptorPublicKey::XPub(descriptor_x_key) => { + let derivable_key = descriptor_x_key.xkey; + let (extended_descriptor, key_map, _) = + Bip49Public(derivable_key, fingerprint, keychain_kind) + .build(network) + .unwrap(); + + Self { + extended_descriptor, + key_map, + } + } + BdkDescriptorPublicKey::Single(_) => { + unreachable!() + } + } + } + + pub(crate) fn new_bip84( + secret_key: Arc, + keychain_kind: KeychainKind, + network: Network, + ) -> Self { + let derivable_key = secret_key.descriptor_secret_key_mutex.lock().unwrap(); + + match derivable_key.deref() { + BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { + let derivable_key = descriptor_x_key.xkey; + let (extended_descriptor, key_map, _) = + Bip84(derivable_key, keychain_kind).build(network).unwrap(); + Self { + extended_descriptor, + key_map, + } + } + BdkDescriptorSecretKey::Single(_) => { + unreachable!() + } + } + } + + pub(crate) fn new_bip84_public( + public_key: Arc, + fingerprint: String, + keychain_kind: KeychainKind, + network: Network, + ) -> Self { + let fingerprint = Fingerprint::from_str(fingerprint.as_str()).unwrap(); + let derivable_key = public_key.descriptor_public_key_mutex.lock().unwrap(); + + match derivable_key.deref() { + BdkDescriptorPublicKey::XPub(descriptor_x_key) => { + let derivable_key = descriptor_x_key.xkey; + let (extended_descriptor, key_map, _) = + Bip84Public(derivable_key, fingerprint, keychain_kind) + .build(network) + .unwrap(); + + Self { + extended_descriptor, + key_map, + } + } + BdkDescriptorPublicKey::Single(_) => { + unreachable!() + } + } + } + + pub(crate) fn as_string_private(&self) -> String { + let descriptor = &self.extended_descriptor; + let key_map = &self.key_map; + descriptor.to_string_with_secret(key_map) + } + + pub(crate) fn as_string(&self) -> String { + self.extended_descriptor.to_string() + } +} diff --git a/bdk-ffi/src/lib.rs b/bdk-ffi/src/lib.rs index 99d66bf..0e6f66b 100644 --- a/bdk-ffi/src/lib.rs +++ b/bdk-ffi/src/lib.rs @@ -7,24 +7,20 @@ use crate::blockchain::{ }; use crate::psbt::PartiallySignedTransaction; use crate::wallet::{BumpFeeTxBuilder, TxBuilder, Wallet}; - +use crate::descriptor::Descriptor; use bdk::bitcoin::blockdata::script::Script as BdkScript; use bdk::bitcoin::secp256k1::Secp256k1; -use bdk::bitcoin::util::bip32::{DerivationPath as BdkDerivationPath, Fingerprint}; +use bdk::bitcoin::util::bip32::{DerivationPath as BdkDerivationPath}; use bdk::bitcoin::{Address as BdkAddress, Network, OutPoint as BdkOutPoint, Txid}; use bdk::blockchain::Progress as BdkProgress; use bdk::database::any::{SledDbConfiguration, SqliteDbConfiguration}; -use bdk::descriptor::{DescriptorXKey, ExtendedDescriptor, IntoWalletDescriptor}; +use bdk::descriptor::{DescriptorXKey}; use bdk::keys::bip39::{Language, Mnemonic as BdkMnemonic, WordCount}; use bdk::keys::{ DerivableKey, DescriptorPublicKey as BdkDescriptorPublicKey, DescriptorSecretKey as BdkDescriptorSecretKey, ExtendedKey, GeneratableKey, GeneratedKey, - KeyMap, }; use bdk::miniscript::BareCtx; -use bdk::template::{ - Bip44, Bip44Public, Bip49, Bip49Public, Bip84, Bip84Public, DescriptorTemplate, -}; use bdk::wallet::AddressIndex as BdkAddressIndex; use bdk::wallet::AddressInfo as BdkAddressInfo; use bdk::{Balance as BdkBalance, BlockTime, Error as BdkError, FeeRate, KeychainKind}; @@ -578,186 +574,6 @@ impl DescriptorPublicKey { } } -#[derive(Debug)] -struct Descriptor { - pub extended_descriptor: ExtendedDescriptor, - pub key_map: KeyMap, -} - -impl Descriptor { - fn new(descriptor: String, network: Network) -> Result { - let secp = Secp256k1::new(); - let (extended_descriptor, key_map) = descriptor.into_wallet_descriptor(&secp, network)?; - Ok(Self { - extended_descriptor, - key_map, - }) - } - - fn new_bip44( - secret_key: Arc, - keychain_kind: KeychainKind, - network: Network, - ) -> Self { - let derivable_key = secret_key.descriptor_secret_key_mutex.lock().unwrap(); - - match derivable_key.deref() { - BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { - let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip44(derivable_key, keychain_kind).build(network).unwrap(); - Self { - extended_descriptor, - key_map, - } - } - BdkDescriptorSecretKey::Single(_) => { - unreachable!() - } - } - } - - fn new_bip44_public( - public_key: Arc, - fingerprint: String, - keychain_kind: KeychainKind, - network: Network, - ) -> Self { - let fingerprint = Fingerprint::from_str(fingerprint.as_str()).unwrap(); - let derivable_key = public_key.descriptor_public_key_mutex.lock().unwrap(); - - match derivable_key.deref() { - BdkDescriptorPublicKey::XPub(descriptor_x_key) => { - let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip44Public(derivable_key, fingerprint, keychain_kind) - .build(network) - .unwrap(); - - Self { - extended_descriptor, - key_map, - } - } - BdkDescriptorPublicKey::Single(_) => { - unreachable!() - } - } - } - - fn new_bip49( - secret_key: Arc, - keychain_kind: KeychainKind, - network: Network, - ) -> Self { - let derivable_key = secret_key.descriptor_secret_key_mutex.lock().unwrap(); - - match derivable_key.deref() { - BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { - let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip49(derivable_key, keychain_kind).build(network).unwrap(); - Self { - extended_descriptor, - key_map, - } - } - BdkDescriptorSecretKey::Single(_) => { - unreachable!() - } - } - } - - fn new_bip49_public( - public_key: Arc, - fingerprint: String, - keychain_kind: KeychainKind, - network: Network, - ) -> Self { - let fingerprint = Fingerprint::from_str(fingerprint.as_str()).unwrap(); - let derivable_key = public_key.descriptor_public_key_mutex.lock().unwrap(); - - match derivable_key.deref() { - BdkDescriptorPublicKey::XPub(descriptor_x_key) => { - let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip49Public(derivable_key, fingerprint, keychain_kind) - .build(network) - .unwrap(); - - Self { - extended_descriptor, - key_map, - } - } - BdkDescriptorPublicKey::Single(_) => { - unreachable!() - } - } - } - - fn new_bip84( - secret_key: Arc, - keychain_kind: KeychainKind, - network: Network, - ) -> Self { - let derivable_key = secret_key.descriptor_secret_key_mutex.lock().unwrap(); - - match derivable_key.deref() { - BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { - let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip84(derivable_key, keychain_kind).build(network).unwrap(); - Self { - extended_descriptor, - key_map, - } - } - BdkDescriptorSecretKey::Single(_) => { - unreachable!() - } - } - } - - fn new_bip84_public( - public_key: Arc, - fingerprint: String, - keychain_kind: KeychainKind, - network: Network, - ) -> Self { - let fingerprint = Fingerprint::from_str(fingerprint.as_str()).unwrap(); - let derivable_key = public_key.descriptor_public_key_mutex.lock().unwrap(); - - match derivable_key.deref() { - BdkDescriptorPublicKey::XPub(descriptor_x_key) => { - let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip84Public(derivable_key, fingerprint, keychain_kind) - .build(network) - .unwrap(); - - Self { - extended_descriptor, - key_map, - } - } - BdkDescriptorPublicKey::Single(_) => { - unreachable!() - } - } - } - - fn as_string_private(&self) -> String { - let descriptor = &self.extended_descriptor; - let key_map = &self.key_map; - descriptor.to_string_with_secret(key_map) - } - - fn as_string(&self) -> String { - self.extended_descriptor.to_string() - } -} - uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send); // The goal of these tests to to ensure `bdk-ffi` intermediate code correctly calls `bdk` APIs. diff --git a/bdk-ffi/src/psbt.rs b/bdk-ffi/src/psbt.rs index 403f92d..337d592 100644 --- a/bdk-ffi/src/psbt.rs +++ b/bdk-ffi/src/psbt.rs @@ -2,11 +2,10 @@ use bdk::bitcoin::hashes::hex::ToHex; use bdk::bitcoin::psbt::serialize::Serialize; use bdk::bitcoin::util::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction; use bdk::psbt::PsbtUtils; -use bdk::Error as BdkError; use std::str::FromStr; use std::sync::{Arc, Mutex}; -use crate::FeeRate; +use crate::{FeeRate, BdkError}; #[derive(Debug)] pub(crate) struct PartiallySignedTransaction { diff --git a/bdk-ffi/src/wallet.rs b/bdk-ffi/src/wallet.rs index 78ea384..ef18d53 100644 --- a/bdk-ffi/src/wallet.rs +++ b/bdk-ffi/src/wallet.rs @@ -4,7 +4,7 @@ use bdk::database::any::AnyDatabase; use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase}; use bdk::wallet::tx_builder::ChangeSpendPolicy; use bdk::{ - Error as BdkError, FeeRate, SignOptions, SyncOptions as BdkSyncOptions, Wallet as BdkWallet, + FeeRate, SignOptions, SyncOptions as BdkSyncOptions, Wallet as BdkWallet, }; use std::collections::HashSet; use std::ops::Deref; @@ -13,10 +13,11 @@ use std::sync::{Arc, Mutex, MutexGuard}; use crate::blockchain::Blockchain; use crate::psbt::PartiallySignedTransaction; +use crate::descriptor::Descriptor; use crate::{ - AddressIndex, AddressInfo, Balance, DatabaseConfig, Descriptor, LocalUtxo, NetworkLocalUtxo, + AddressIndex, AddressInfo, Balance, DatabaseConfig, LocalUtxo, NetworkLocalUtxo, OutPoint, Progress, ProgressHolder, RbfValue, Script, ScriptAmount, TransactionDetails, - TxBuilderResult, + TxBuilderResult, BdkError, }; #[derive(Debug)]