From a37a656d4a1c5f7f8e4a197c79d7551e929aa3e9 Mon Sep 17 00:00:00 2001 From: thunderbiscuit Date: Thu, 11 Jan 2024 13:13:28 -0500 Subject: [PATCH] feat: upgrade API to match bdk 0.29 --- bdk-ffi/src/bdk.udl | 11 ++- bdk-ffi/src/blockchain.rs | 4 +- bdk-ffi/src/descriptor.rs | 62 ++++++++++---- bdk-ffi/src/keys.rs | 44 +++++----- bdk-ffi/src/lib.rs | 170 ++++++++++++++++++++++---------------- bdk-ffi/src/psbt.rs | 10 +-- bdk-ffi/src/wallet.rs | 53 ++++++------ 7 files changed, 212 insertions(+), 142 deletions(-) diff --git a/bdk-ffi/src/bdk.udl b/bdk-ffi/src/bdk.udl index 5ca6458a..7347bb4e 100644 --- a/bdk-ffi/src/bdk.udl +++ b/bdk-ffi/src/bdk.udl @@ -46,6 +46,7 @@ enum BdkError { "Sled", "Rusqlite", "Rpc", + "HardenedIndex" }; dictionary AddressInfo { @@ -277,8 +278,6 @@ interface Transaction { u64 vsize(); - sequence serialize(); - boolean is_coin_base(); boolean is_explicitly_rbf(); @@ -361,7 +360,7 @@ interface TxBuilder { interface BumpFeeTxBuilder { constructor(string txid, float new_fee_rate); - BumpFeeTxBuilder allow_shrinking(string address); + BumpFeeTxBuilder allow_shrinking(Script script_pubkey); BumpFeeTxBuilder enable_rbf(); @@ -455,7 +454,7 @@ interface Descriptor { interface Address { [Throws=BdkError] - constructor(string address); + constructor(string address, Network network); [Name=from_script, Throws=BdkError] constructor(Script script, Network network); @@ -473,9 +472,9 @@ interface Address { [Enum] interface Payload { - PubkeyHash(sequence pubkey_hash); + PubkeyHash(string pubkey_hash); - ScriptHash(sequence script_hash); + ScriptHash(string script_hash); WitnessProgram(WitnessVersion version, sequence program); }; diff --git a/bdk-ffi/src/blockchain.rs b/bdk-ffi/src/blockchain.rs index ac418cc0..1106720f 100644 --- a/bdk-ffi/src/blockchain.rs +++ b/bdk-ffi/src/blockchain.rs @@ -1,6 +1,6 @@ // use crate::BlockchainConfig; +use crate::Network; use crate::{BdkError, Transaction}; -use bdk::bitcoin::Network; use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig}; use bdk::blockchain::rpc::Auth as BdkAuth; use bdk::blockchain::rpc::RpcSyncParams as BdkRpcSyncParams; @@ -45,7 +45,7 @@ impl Blockchain { BlockchainConfig::Rpc { config } => AnyBlockchainConfig::Rpc(BdkRpcConfig { url: config.url, auth: config.auth.into(), - network: config.network, + network: config.network.into(), wallet_name: config.wallet_name, sync_params: config.sync_params.map(|p| p.into()), }), diff --git a/bdk-ffi/src/descriptor.rs b/bdk-ffi/src/descriptor.rs index a8a37037..6f9c9d1e 100644 --- a/bdk-ffi/src/descriptor.rs +++ b/bdk-ffi/src/descriptor.rs @@ -1,10 +1,11 @@ +use crate::Network; use crate::{BdkError, DescriptorPublicKey, DescriptorSecretKey}; +use bdk::bitcoin::bip32::Fingerprint; use bdk::bitcoin::secp256k1::Secp256k1; -use bdk::bitcoin::util::bip32::Fingerprint; -use bdk::bitcoin::Network; -use bdk::descriptor::{ExtendedDescriptor, IntoWalletDescriptor, KeyMap}; +use bdk::descriptor::{ExtendedDescriptor, IntoWalletDescriptor}; use bdk::keys::{ DescriptorPublicKey as BdkDescriptorPublicKey, DescriptorSecretKey as BdkDescriptorSecretKey, + KeyMap, }; use bdk::template::{ Bip44, Bip44Public, Bip49, Bip49Public, Bip84, Bip84Public, Bip86, Bip86Public, @@ -23,7 +24,8 @@ pub(crate) struct Descriptor { 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)?; + let (extended_descriptor, key_map) = + descriptor.into_wallet_descriptor(&secp, network.into())?; Ok(Self { extended_descriptor, key_map, @@ -40,8 +42,9 @@ impl Descriptor { match derivable_key { 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(); + let (extended_descriptor, key_map, _) = Bip44(derivable_key, keychain_kind) + .build(network.into()) + .unwrap(); Self { extended_descriptor, key_map, @@ -50,6 +53,9 @@ impl Descriptor { BdkDescriptorSecretKey::Single(_) => { unreachable!() } + BdkDescriptorSecretKey::MultiXPrv(_) => { + unreachable!() + } } } @@ -67,7 +73,7 @@ impl Descriptor { let derivable_key = descriptor_x_key.xkey; let (extended_descriptor, key_map, _) = Bip44Public(derivable_key, fingerprint, keychain_kind) - .build(network) + .build(network.into()) .unwrap(); Self { @@ -78,6 +84,9 @@ impl Descriptor { BdkDescriptorPublicKey::Single(_) => { unreachable!() } + BdkDescriptorPublicKey::MultiXPub(_) => { + unreachable!() + } } } @@ -91,8 +100,9 @@ impl Descriptor { match derivable_key { 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(); + let (extended_descriptor, key_map, _) = Bip49(derivable_key, keychain_kind) + .build(network.into()) + .unwrap(); Self { extended_descriptor, key_map, @@ -101,6 +111,9 @@ impl Descriptor { BdkDescriptorSecretKey::Single(_) => { unreachable!() } + BdkDescriptorSecretKey::MultiXPrv(_) => { + unreachable!() + } } } @@ -118,7 +131,7 @@ impl Descriptor { let derivable_key = descriptor_x_key.xkey; let (extended_descriptor, key_map, _) = Bip49Public(derivable_key, fingerprint, keychain_kind) - .build(network) + .build(network.into()) .unwrap(); Self { @@ -129,6 +142,9 @@ impl Descriptor { BdkDescriptorPublicKey::Single(_) => { unreachable!() } + BdkDescriptorPublicKey::MultiXPub(_) => { + unreachable!() + } } } @@ -142,8 +158,9 @@ impl Descriptor { match derivable_key { 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(); + let (extended_descriptor, key_map, _) = Bip84(derivable_key, keychain_kind) + .build(network.into()) + .unwrap(); Self { extended_descriptor, key_map, @@ -152,6 +169,9 @@ impl Descriptor { BdkDescriptorSecretKey::Single(_) => { unreachable!() } + BdkDescriptorSecretKey::MultiXPrv(_) => { + unreachable!() + } } } @@ -169,7 +189,7 @@ impl Descriptor { let derivable_key = descriptor_x_key.xkey; let (extended_descriptor, key_map, _) = Bip84Public(derivable_key, fingerprint, keychain_kind) - .build(network) + .build(network.into()) .unwrap(); Self { @@ -180,6 +200,9 @@ impl Descriptor { BdkDescriptorPublicKey::Single(_) => { unreachable!() } + BdkDescriptorPublicKey::MultiXPub(_) => { + unreachable!() + } } } @@ -193,8 +216,9 @@ impl Descriptor { match derivable_key { BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip86(derivable_key, keychain_kind).build(network).unwrap(); + let (extended_descriptor, key_map, _) = Bip86(derivable_key, keychain_kind) + .build(network.into()) + .unwrap(); Self { extended_descriptor, key_map, @@ -203,6 +227,9 @@ impl Descriptor { BdkDescriptorSecretKey::Single(_) => { unreachable!() } + BdkDescriptorSecretKey::MultiXPrv(_) => { + unreachable!() + } } } @@ -220,7 +247,7 @@ impl Descriptor { let derivable_key = descriptor_x_key.xkey; let (extended_descriptor, key_map, _) = Bip86Public(derivable_key, fingerprint, keychain_kind) - .build(network) + .build(network.into()) .unwrap(); Self { @@ -231,6 +258,9 @@ impl Descriptor { BdkDescriptorPublicKey::Single(_) => { unreachable!() } + BdkDescriptorPublicKey::MultiXPub(_) => { + unreachable!() + } } } diff --git a/bdk-ffi/src/keys.rs b/bdk-ffi/src/keys.rs index e1eb1e5f..44a3f5d5 100644 --- a/bdk-ffi/src/keys.rs +++ b/bdk-ffi/src/keys.rs @@ -1,14 +1,14 @@ use crate::BdkError; +use crate::Network; +use bdk::bitcoin::bip32::DerivationPath as BdkDerivationPath; use bdk::bitcoin::secp256k1::Secp256k1; -use bdk::bitcoin::util::bip32::DerivationPath as BdkDerivationPath; -use bdk::bitcoin::Network; -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, }; +use bdk::miniscript::descriptor::{DescriptorXKey, Wildcard}; use bdk::miniscript::BareCtx; use std::ops::Deref; use std::str::FromStr; @@ -75,9 +75,9 @@ impl DescriptorSecretKey { let xkey: ExtendedKey = (mnemonic, password).into_extended_key().unwrap(); let descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey { origin: None, - xkey: xkey.into_xprv(network).unwrap(), + xkey: xkey.into_xprv(network.into()).unwrap(), derivation_path: BdkDerivationPath::master(), - wildcard: bdk::descriptor::Wildcard::Unhardened, + wildcard: Wildcard::Unhardened, }); Self { inner: descriptor_secret_key, @@ -116,6 +116,9 @@ impl DescriptorSecretKey { BdkDescriptorSecretKey::Single(_) => Err(BdkError::Generic( "Cannot derive from a single key".to_string(), )), + BdkDescriptorSecretKey::MultiXPrv(_) => Err(BdkError::Generic( + "Cannot derive from a multi key".to_string(), + )), } } @@ -138,6 +141,9 @@ impl DescriptorSecretKey { BdkDescriptorSecretKey::Single(_) => Err(BdkError::Generic( "Cannot extend from a single key".to_string(), )), + BdkDescriptorSecretKey::MultiXPrv(_) => Err(BdkError::Generic( + "Cannot extend from a multi key".to_string(), + )), } } @@ -152,13 +158,16 @@ impl DescriptorSecretKey { /// Get the private key as bytes. pub(crate) fn secret_bytes(&self) -> Vec { let inner = &self.inner; - let secret_bytes: Vec = match inner.deref() { + let secret_bytes: Vec = match inner { BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { descriptor_x_key.xkey.private_key.secret_bytes().to_vec() } BdkDescriptorSecretKey::Single(_) => { unreachable!() } + BdkDescriptorSecretKey::MultiXPrv(_) => { + unreachable!() + } }; secret_bytes @@ -188,7 +197,7 @@ impl DescriptorPublicKey { let descriptor_public_key = &self.inner; let path = path.inner_mutex.lock().unwrap().deref().clone(); - match descriptor_public_key.deref() { + match descriptor_public_key { BdkDescriptorPublicKey::XPub(descriptor_x_key) => { let derived_xpub = descriptor_x_key.xkey.derive_pub(&secp, &path)?; let key_source = match descriptor_x_key.origin.clone() { @@ -208,13 +217,16 @@ impl DescriptorPublicKey { BdkDescriptorPublicKey::Single(_) => Err(BdkError::Generic( "Cannot derive from a single key".to_string(), )), + BdkDescriptorPublicKey::MultiXPub(_) => Err(BdkError::Generic( + "Cannot derive from a multi key".to_string(), + )), } } pub(crate) fn extend(&self, path: Arc) -> Result, BdkError> { let descriptor_public_key = &self.inner; let path = path.inner_mutex.lock().unwrap().deref().clone(); - match descriptor_public_key.deref() { + match descriptor_public_key { BdkDescriptorPublicKey::XPub(descriptor_x_key) => { let extended_path = descriptor_x_key.derivation_path.extend(path); let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey { @@ -230,6 +242,9 @@ impl DescriptorPublicKey { BdkDescriptorPublicKey::Single(_) => Err(BdkError::Generic( "Cannot extend from a single key".to_string(), )), + BdkDescriptorPublicKey::MultiXPub(_) => Err(BdkError::Generic( + "Cannot extend from a multi key".to_string(), + )), } } @@ -245,8 +260,7 @@ impl DescriptorPublicKey { mod test { use crate::keys::{DerivationPath, DescriptorPublicKey, DescriptorSecretKey, Mnemonic}; use crate::BdkError; - use bdk::bitcoin::hashes::hex::ToHex; - use bdk::bitcoin::Network; + use crate::Network; use std::sync::Arc; fn get_inner() -> DescriptorSecretKey { @@ -358,14 +372,4 @@ mod test { let derived_dpk = &derive_dpk(&master_dpk, "m/84h/1h/0h"); assert!(derived_dpk.is_err()); } - - #[test] - fn test_retrieve_master_secret_key() { - let master_dpk = get_inner(); - let master_private_key = master_dpk.secret_bytes().to_hex(); - assert_eq!( - master_private_key, - "e93315d6ce401eb4db803a56232f0ed3e69b053774e6047df54f1bd00e5ea936" - ) - } } diff --git a/bdk-ffi/src/lib.rs b/bdk-ffi/src/lib.rs index 032597ac..2f09dee6 100644 --- a/bdk-ffi/src/lib.rs +++ b/bdk-ffi/src/lib.rs @@ -15,14 +15,14 @@ use crate::keys::{DescriptorPublicKey, DescriptorSecretKey, Mnemonic}; use crate::psbt::PartiallySignedTransaction; use crate::wallet::SignOptions; use crate::wallet::{BumpFeeTxBuilder, TxBuilder, Wallet}; -use bdk::bitcoin::blockdata::script::Script as BdkScript; +use bdk::bitcoin::address::{NetworkUnchecked, Payload as BdkPayload, WitnessVersion}; +use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf; use bdk::bitcoin::blockdata::transaction::TxIn as BdkTxIn; use bdk::bitcoin::blockdata::transaction::TxOut as BdkTxOut; use bdk::bitcoin::consensus::Decodable; -use bdk::bitcoin::psbt::serialize::Serialize; -use bdk::bitcoin::util::address::{Payload as BdkPayload, WitnessVersion}; +use bdk::bitcoin::network::constants::Network as BdkNetwork; use bdk::bitcoin::{ - Address as BdkAddress, Network, OutPoint as BdkOutPoint, Transaction as BdkTransaction, Txid, + Address as BdkAddress, OutPoint as BdkOutPoint, Transaction as BdkTransaction, Txid, }; use bdk::blockchain::Progress as BdkProgress; use bdk::database::any::{SledDbConfiguration, SqliteDbConfiguration}; @@ -41,6 +41,26 @@ use std::sync::Arc; uniffi::include_scaffolding!("bdk"); +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Script(pub(crate) BdkScriptBuf); + +impl Script { + pub fn new(raw_output_script: Vec) -> Self { + let script: BdkScriptBuf = raw_output_script.into(); + Script(script) + } + + pub fn to_bytes(&self) -> Vec { + self.0.to_bytes() + } +} + +impl From for Script { + fn from(script: BdkScriptBuf) -> Self { + Script(script) + } +} + /// A output script and an amount of satoshis. pub struct ScriptAmount { pub script: Arc