]> Untitled Git - bdk/commitdiff
Update bdk to bitcoin 0.30.0
authorDaniela Brozzoni <danielabrozzoni@protonmail.com>
Wed, 19 Jul 2023 13:27:48 +0000 (15:27 +0200)
committerDaniela Brozzoni <danielabrozzoni@protonmail.com>
Thu, 3 Aug 2023 08:59:02 +0000 (10:59 +0200)
23 files changed:
crates/bdk/Cargo.toml
crates/bdk/README.md
crates/bdk/examples/mnemonic_to_descriptors.rs
crates/bdk/src/descriptor/dsl.rs
crates/bdk/src/descriptor/error.rs
crates/bdk/src/descriptor/mod.rs
crates/bdk/src/descriptor/policy.rs
crates/bdk/src/descriptor/template.rs
crates/bdk/src/error.rs
crates/bdk/src/keys/bip39.rs
crates/bdk/src/keys/mod.rs
crates/bdk/src/psbt/mod.rs
crates/bdk/src/types.rs
crates/bdk/src/wallet/coin_selection.rs
crates/bdk/src/wallet/export.rs
crates/bdk/src/wallet/hardwaresigner.rs
crates/bdk/src/wallet/mod.rs
crates/bdk/src/wallet/signer.rs
crates/bdk/src/wallet/tx_builder.rs
crates/bdk/src/wallet/utils.rs
crates/bdk/tests/common.rs
crates/bdk/tests/psbt.rs
crates/bdk/tests/wallet.rs

index 344fb3e55ac7703ca56587f2313388bc6f79e6b3..dc38fdd63fdbde16093ea95880188093d663bdba 100644 (file)
@@ -15,14 +15,14 @@ rust-version = "1.57"
 [dependencies]
 log = "0.4"
 rand = "^0.8"
-miniscript = { version = "9", features = ["serde"], default-features = false }
-bitcoin = { version = "0.29", features = ["serde", "base64", "rand"], default-features = false }
+miniscript = { version = "10.0.0", features = ["serde"], default-features = false }
+bitcoin = { version = "0.30.0", features = ["serde", "base64", "rand-std"], default-features = false }
 serde = { version = "^1.0", features = ["derive"] }
 serde_json = { version = "^1.0" }
 bdk_chain = { path = "../chain", version = "0.5.0", features = ["miniscript", "serde"], default-features = false }
 
 # Optional dependencies
-hwi = { version = "0.5", optional = true, features = [ "use-miniscript"] }
+hwi = { version = "0.7.0", optional = true, features = [ "miniscript"] }
 bip39 = { version = "1.0.1", optional = true }
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
@@ -46,8 +46,6 @@ dev-getrandom-wasm = ["getrandom/js"]
 [dev-dependencies]
 lazy_static = "1.4"
 env_logger = "0.7"
-# Move back to importing from rust-bitcoin once https://github.com/rust-bitcoin/rust-bitcoin/pull/1342 is released
-base64 = "^0.13"
 assert_matches = "1.5.0"
 
 [package.metadata.docs.rs]
index 9a5bd9986b2414d8c67f462a3546421f8681a9e4..ddd67df17a734bf89c4105ebadb8c561bd0f7871 100644 (file)
@@ -137,7 +137,7 @@ fn main() {
 <!-- use bdk::electrum_client::Client; -->
 <!-- use bdk::wallet::AddressIndex::New; -->
 
-<!-- use base64; -->
+<!-- use bitcoin::base64; -->
 <!-- use bdk::bitcoin::consensus::serialize; -->
 <!-- use bdk::bitcoin::Network; -->
 
@@ -174,7 +174,7 @@ fn main() {
 <!-- ```rust,no_run -->
 <!-- use bdk::{Wallet, SignOptions}; -->
 
-<!-- use base64; -->
+<!-- use bitcoin::base64; -->
 <!-- use bdk::bitcoin::consensus::deserialize; -->
 <!-- use bdk::bitcoin::Network; -->
 
index 0a560a528d4449ec376cf25688cfd9b7fbdd2a7a..7d2dd6013ffba96c769e2c4167603c301c6e9937 100644 (file)
@@ -6,8 +6,8 @@
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
+use bdk::bitcoin::bip32::DerivationPath;
 use bdk::bitcoin::secp256k1::Secp256k1;
-use bdk::bitcoin::util::bip32::DerivationPath;
 use bdk::bitcoin::Network;
 use bdk::descriptor;
 use bdk::descriptor::IntoWalletDescriptor;
index 60fac19e5bd16ac416cc24f9f4eb2825195d5c48..50cd978f7dff943656fccdbd169606be61cb19dc 100644 (file)
@@ -516,13 +516,14 @@ macro_rules! descriptor {
         use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
 
         $crate::impl_top_level_pk!(Pkh, $crate::miniscript::Legacy, $key)
+            .and_then(|(a, b, c)| Ok((a.map_err(|e| miniscript::Error::from(e))?, b, c)))
             .map(|(a, b, c)| (Descriptor::<DescriptorPublicKey>::Pkh(a), b, c))
     });
     ( wpkh ( $key:expr ) ) => ({
         use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
 
         $crate::impl_top_level_pk!(Wpkh, $crate::miniscript::Segwitv0, $key)
-            .and_then(|(a, b, c)| Ok((a?, b, c)))
+            .and_then(|(a, b, c)| Ok((a.map_err(|e| miniscript::Error::from(e))?, b, c)))
             .map(|(a, b, c)| (Descriptor::<DescriptorPublicKey>::Wpkh(a), b, c))
     });
     ( sh ( wpkh ( $key:expr ) ) ) => ({
@@ -532,7 +533,7 @@ macro_rules! descriptor {
         use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey, Sh};
 
         $crate::impl_top_level_pk!(Wpkh, $crate::miniscript::Segwitv0, $key)
-            .and_then(|(a, b, c)| Ok((a?, b, c)))
+            .and_then(|(a, b, c)| Ok((a.map_err(|e| miniscript::Error::from(e))?, b, c)))
             .and_then(|(a, b, c)| Ok((Descriptor::<DescriptorPublicKey>::Sh(Sh::new_wpkh(a.into_inner())?), b, c)))
     });
     ( sh ( $( $minisc:tt )* ) ) => ({
@@ -702,7 +703,7 @@ macro_rules! fragment {
         $crate::keys::make_pkh($key, &secp)
     });
     ( after ( $value:expr ) ) => ({
-        $crate::impl_leaf_opcode_value!(After, $crate::bitcoin::PackedLockTime($value)) // TODO!! https://github.com/rust-bitcoin/rust-bitcoin/issues/1302
+        $crate::impl_leaf_opcode_value!(After, $crate::miniscript::AbsLockTime::from_consensus($value))
     });
     ( older ( $value:expr ) ) => ({
         $crate::impl_leaf_opcode_value!(Older, $crate::bitcoin::Sequence($value)) // TODO!!
@@ -796,7 +797,6 @@ macro_rules! fragment {
 #[cfg(test)]
 mod test {
     use alloc::string::ToString;
-    use bitcoin::hashes::hex::ToHex;
     use bitcoin::secp256k1::Secp256k1;
     use miniscript::descriptor::{DescriptorPublicKey, KeyMap};
     use miniscript::{Descriptor, Legacy, Segwitv0};
@@ -805,8 +805,8 @@ mod test {
 
     use crate::descriptor::{DescriptorError, DescriptorMeta};
     use crate::keys::{DescriptorKey, IntoDescriptorKey, ValidNetworks};
+    use bitcoin::bip32;
     use bitcoin::network::constants::Network::{Bitcoin, Regtest, Signet, Testnet};
-    use bitcoin::util::bip32;
     use bitcoin::PrivateKey;
 
     // test the descriptor!() macro
@@ -822,18 +822,15 @@ mod test {
         assert_eq!(desc.is_witness(), is_witness);
         assert_eq!(!desc.has_wildcard(), is_fixed);
         for i in 0..expected.len() {
-            let index = i as u32;
-            let child_desc = if !desc.has_wildcard() {
-                desc.at_derivation_index(0)
-            } else {
-                desc.at_derivation_index(index)
-            };
+            let child_desc = desc
+                .at_derivation_index(i as u32)
+                .expect("i is not hardened");
             let address = child_desc.address(Regtest);
             if let Ok(address) = address {
                 assert_eq!(address.to_string(), *expected.get(i).unwrap());
             } else {
                 let script = child_desc.script_pubkey();
-                assert_eq!(script.to_hex().as_str(), *expected.get(i).unwrap());
+                assert_eq!(script.to_hex_string(), *expected.get(i).unwrap());
             }
         }
     }
@@ -1178,9 +1175,7 @@ mod test {
     }
 
     #[test]
-    #[should_panic(
-        expected = "Miniscript(ContextError(CompressedOnly(\"04b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a87378ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4\")))"
-    )]
+    #[should_panic(expected = "Miniscript(ContextError(UncompressedKeysNotAllowed))")]
     fn test_dsl_miniscript_checks() {
         let mut uncompressed_pk =
             PrivateKey::from_wif("L5EZftvrYaSudiozVRzTqLcHLNDoVn7H5HSfM9BAN6tMJX8oTWz6").unwrap();
index 5b0f1930dc1fa045dfe42dfc2a9125a77a1f7d2c..8731b5bfda270b022a2b0e24f99492b07e40d5e1 100644 (file)
@@ -32,11 +32,11 @@ pub enum Error {
     InvalidDescriptorCharacter(u8),
 
     /// BIP32 error
-    Bip32(bitcoin::util::bip32::Error),
+    Bip32(bitcoin::bip32::Error),
     /// Error during base58 decoding
-    Base58(bitcoin::util::base58::Error),
+    Base58(bitcoin::base58::Error),
     /// Key-related error
-    Pk(bitcoin::util::key::Error),
+    Pk(bitcoin::key::Error),
     /// Miniscript error
     Miniscript(miniscript::Error),
     /// Hex decoding error
@@ -81,9 +81,9 @@ impl fmt::Display for Error {
 #[cfg(feature = "std")]
 impl std::error::Error for Error {}
 
-impl_error!(bitcoin::util::bip32::Error, Bip32);
-impl_error!(bitcoin::util::base58::Error, Base58);
-impl_error!(bitcoin::util::key::Error, Pk);
+impl_error!(bitcoin::bip32::Error, Bip32);
+impl_error!(bitcoin::base58::Error, Base58);
+impl_error!(bitcoin::key::Error, Pk);
 impl_error!(miniscript::Error, Miniscript);
 impl_error!(bitcoin::hashes::hex::Error, Hex);
 impl_error!(crate::descriptor::policy::PolicyError, Policy);
index 9a6dc2b0c3a225f62974149f55fbf5ad8bea1d96..e139f7bd8b477644cf5bb4d0bb1708a7385b868c 100644 (file)
@@ -18,17 +18,17 @@ use crate::collections::BTreeMap;
 use alloc::string::String;
 use alloc::vec::Vec;
 
-use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint, KeySource};
-use bitcoin::util::{psbt, taproot};
-use bitcoin::{secp256k1, PublicKey, XOnlyPublicKey};
+use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint, KeySource};
+use bitcoin::{key::XOnlyPublicKey, secp256k1, PublicKey};
+use bitcoin::{psbt, taproot};
 use bitcoin::{Network, TxOut};
 
 use miniscript::descriptor::{
-    DefiniteDescriptorKey, DescriptorSecretKey, DescriptorType, InnerXKey, SinglePubKey,
+    DefiniteDescriptorKey, DescriptorMultiXKey, DescriptorSecretKey, DescriptorType,
+    DescriptorXKey, InnerXKey, KeyMap, SinglePubKey, Wildcard,
 };
 pub use miniscript::{
-    descriptor::DescriptorXKey, descriptor::KeyMap, descriptor::Wildcard, Descriptor,
-    DescriptorPublicKey, Legacy, Miniscript, ScriptContext, Segwitv0,
+    Descriptor, DescriptorPublicKey, Legacy, Miniscript, ScriptContext, Segwitv0,
 };
 use miniscript::{ForEachKey, MiniscriptKey, TranslatePk};
 
@@ -59,16 +59,16 @@ pub type DerivedDescriptor = Descriptor<DefiniteDescriptorKey>;
 /// Alias for the type of maps that represent derivation paths in a [`psbt::Input`] or
 /// [`psbt::Output`]
 ///
-/// [`psbt::Input`]: bitcoin::util::psbt::Input
-/// [`psbt::Output`]: bitcoin::util::psbt::Output
+/// [`psbt::Input`]: bitcoin::psbt::Input
+/// [`psbt::Output`]: bitcoin::psbt::Output
 pub type HdKeyPaths = BTreeMap<secp256k1::PublicKey, KeySource>;
 
 /// Alias for the type of maps that represent taproot key origins in a [`psbt::Input`] or
 /// [`psbt::Output`]
 ///
-/// [`psbt::Input`]: bitcoin::util::psbt::Input
-/// [`psbt::Output`]: bitcoin::util::psbt::Output
-pub type TapKeyOrigins = BTreeMap<bitcoin::XOnlyPublicKey, (Vec<taproot::TapLeafHash>, KeySource)>;
+/// [`psbt::Input`]: bitcoin::psbt::Input
+/// [`psbt::Output`]: bitcoin::psbt::Output
+pub type TapKeyOrigins = BTreeMap<XOnlyPublicKey, (Vec<taproot::TapLeafHash>, KeySource)>;
 
 /// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`]
 pub trait IntoWalletDescriptor {
@@ -136,14 +136,10 @@ impl IntoWalletDescriptor for (ExtendedDescriptor, KeyMap) {
             network: Network,
         }
 
-        impl<'s, 'd>
-            miniscript::Translator<DescriptorPublicKey, miniscript::DummyKey, DescriptorError>
+        impl<'s, 'd> miniscript::Translator<DescriptorPublicKey, String, DescriptorError>
             for Translator<'s, 'd>
         {
-            fn pk(
-                &mut self,
-                pk: &DescriptorPublicKey,
-            ) -> Result<miniscript::DummyKey, DescriptorError> {
+            fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<String, DescriptorError> {
                 let secp = &self.secp;
 
                 let (_, _, networks) = if self.descriptor.is_taproot() {
@@ -161,7 +157,7 @@ impl IntoWalletDescriptor for (ExtendedDescriptor, KeyMap) {
                 };
 
                 if networks.contains(&self.network) {
-                    Ok(miniscript::DummyKey)
+                    Ok(Default::default())
                 } else {
                     Err(DescriptorError::Key(KeyError::InvalidNetwork))
                 }
@@ -169,35 +165,40 @@ impl IntoWalletDescriptor for (ExtendedDescriptor, KeyMap) {
             fn sha256(
                 &mut self,
                 _sha256: &<DescriptorPublicKey as MiniscriptKey>::Sha256,
-            ) -> Result<miniscript::DummySha256Hash, DescriptorError> {
+            ) -> Result<String, DescriptorError> {
                 Ok(Default::default())
             }
             fn hash256(
                 &mut self,
                 _hash256: &<DescriptorPublicKey as MiniscriptKey>::Hash256,
-            ) -> Result<miniscript::DummyHash256Hash, DescriptorError> {
+            ) -> Result<String, DescriptorError> {
                 Ok(Default::default())
             }
             fn ripemd160(
                 &mut self,
                 _ripemd160: &<DescriptorPublicKey as MiniscriptKey>::Ripemd160,
-            ) -> Result<miniscript::DummyRipemd160Hash, DescriptorError> {
+            ) -> Result<String, DescriptorError> {
                 Ok(Default::default())
             }
             fn hash160(
                 &mut self,
                 _hash160: &<DescriptorPublicKey as MiniscriptKey>::Hash160,
-            ) -> Result<miniscript::DummyHash160Hash, DescriptorError> {
+            ) -> Result<String, DescriptorError> {
                 Ok(Default::default())
             }
         }
 
         // check the network for the keys
-        self.0.translate_pk(&mut Translator {
+        use miniscript::TranslateErr;
+        match self.0.translate_pk(&mut Translator {
             secp,
             network,
             descriptor: &self.0,
-        })?;
+        }) {
+            Ok(_) => {}
+            Err(TranslateErr::TranslatorErr(e)) => return Err(e),
+            Err(TranslateErr::OuterError(e)) => return Err(e.into()),
+        }
 
         Ok(self)
     }
@@ -251,7 +252,12 @@ impl IntoWalletDescriptor for DescriptorTemplateOut {
         }
 
         // fixup the network for keys that need it in the descriptor
-        let translated = desc.translate_pk(&mut Translator { network })?;
+        use miniscript::TranslateErr;
+        let translated = match desc.translate_pk(&mut Translator { network }) {
+            Ok(descriptor) => descriptor,
+            Err(TranslateErr::TranslatorErr(e)) => return Err(e),
+            Err(TranslateErr::OuterError(e)) => return Err(e.into()),
+        };
         // ...and in the key map
         let fixed_keymap = keymap
             .into_iter()
@@ -340,6 +346,18 @@ pub(crate) trait XKeyUtils {
     fn root_fingerprint(&self, secp: &SecpCtx) -> Fingerprint;
 }
 
+impl<T> XKeyUtils for DescriptorMultiXKey<T>
+where
+    T: InnerXKey,
+{
+    fn root_fingerprint(&self, secp: &SecpCtx) -> Fingerprint {
+        match self.origin {
+            Some((fingerprint, _)) => fingerprint,
+            None => self.xkey.xkey_fingerprint(secp),
+        }
+    }
+}
+
 impl<T> XKeyUtils for DescriptorXKey<T>
 where
     T: InnerXKey,
@@ -494,7 +512,10 @@ impl DescriptorMeta for ExtendedDescriptor {
             false
         });
 
-        path_found.map(|path| self.at_derivation_index(path))
+        path_found.map(|path| {
+            self.at_derivation_index(path)
+                .expect("We ignore hardened wildcards")
+        })
     }
 
     fn derive_from_hd_keypaths(
@@ -545,7 +566,7 @@ impl DescriptorMeta for ExtendedDescriptor {
             return None;
         }
 
-        let descriptor = self.at_derivation_index(0);
+        let descriptor = self.at_derivation_index(0).expect("0 is not hardened");
         match descriptor.desc_type() {
             // TODO: add pk() here
             DescriptorType::Pkh
@@ -585,11 +606,10 @@ mod test {
     use core::str::FromStr;
 
     use assert_matches::assert_matches;
-    use bitcoin::consensus::encode::deserialize;
     use bitcoin::hashes::hex::FromHex;
     use bitcoin::secp256k1::Secp256k1;
-    use bitcoin::util::{bip32, psbt};
-    use bitcoin::Script;
+    use bitcoin::ScriptBuf;
+    use bitcoin::{bip32, psbt::Psbt};
 
     use super::*;
     use crate::psbt::PsbtUtils;
@@ -600,7 +620,7 @@ mod test {
             "wpkh(02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737)",
         )
         .unwrap();
-        let psbt: psbt::PartiallySignedTransaction = deserialize(
+        let psbt = Psbt::deserialize(
             &Vec::<u8>::from_hex(
                 "70736274ff010052010000000162307be8e431fbaff807cdf9cdc3fde44d7402\
                  11bc8342c31ffd6ec11fe35bcc0100000000ffffffff01328601000000000016\
@@ -623,7 +643,7 @@ mod test {
             "pkh([0f056943/44h/0h/0h]tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd/10/*)",
         )
         .unwrap();
-        let psbt: psbt::PartiallySignedTransaction = deserialize(
+        let psbt = Psbt::deserialize(
             &Vec::<u8>::from_hex(
                 "70736274ff010053010000000145843b86be54a3cd8c9e38444e1162676c00df\
                  e7964122a70df491ea12fd67090100000000ffffffff01c19598000000000017\
@@ -654,7 +674,7 @@ mod test {
             "wsh(and_v(v:pk(03b6633fef2397a0a9de9d7b6f23aef8368a6e362b0581f0f0af70d5ecfd254b14),older(6)))",
         )
         .unwrap();
-        let psbt: psbt::PartiallySignedTransaction = deserialize(
+        let psbt = Psbt::deserialize(
             &Vec::<u8>::from_hex(
                 "70736274ff01005302000000011c8116eea34408ab6529223c9a176606742207\
                  67a1ff1d46a6e3c4a88243ea6e01000000000600000001109698000000000017\
@@ -678,7 +698,7 @@ mod test {
             "sh(and_v(v:pk(021403881a5587297818fcaf17d239cefca22fce84a45b3b1d23e836c4af671dbb),after(630000)))",
         )
         .unwrap();
-        let psbt: psbt::PartiallySignedTransaction = deserialize(
+        let psbt = Psbt::deserialize(
             &Vec::<u8>::from_hex(
                 "70736274ff0100530100000001bc8c13df445dfadcc42afa6dc841f85d22b01d\
                  a6270ebf981740f4b7b1d800390000000000feffffff01ba9598000000000017\
@@ -861,9 +881,9 @@ mod test {
         let (descriptor, _) =
             into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet).unwrap();
 
-        let descriptor = descriptor.at_derivation_index(0);
+        let descriptor = descriptor.at_derivation_index(0).unwrap();
 
-        let script = Script::from_str("5321022f533b667e2ea3b36e21961c9fe9dca340fbe0af5210173a83ae0337ab20a57621026bb53a98e810bd0ee61a0ed1164ba6c024786d76554e793e202dc6ce9c78c4ea2102d5b8a7d66a41ffdb6f4c53d61994022e886b4f45001fb158b95c9164d45f8ca3210324b75eead2c1f9c60e8adeb5e7009fec7a29afcdb30d829d82d09562fe8bae8521032d34f8932200833487bd294aa219dcbe000b9f9b3d824799541430009f0fa55121037468f8ea99b6c64788398b5ad25480cad08f4b0d65be54ce3a55fd206b5ae4722103f72d3d96663b0ea99b0aeb0d7f273cab11a8de37885f1dddc8d9112adb87169357ae").unwrap();
+        let script = ScriptBuf::from_hex("5321022f533b667e2ea3b36e21961c9fe9dca340fbe0af5210173a83ae0337ab20a57621026bb53a98e810bd0ee61a0ed1164ba6c024786d76554e793e202dc6ce9c78c4ea2102d5b8a7d66a41ffdb6f4c53d61994022e886b4f45001fb158b95c9164d45f8ca3210324b75eead2c1f9c60e8adeb5e7009fec7a29afcdb30d829d82d09562fe8bae8521032d34f8932200833487bd294aa219dcbe000b9f9b3d824799541430009f0fa55121037468f8ea99b6c64788398b5ad25480cad08f4b0d65be54ce3a55fd206b5ae4722103f72d3d96663b0ea99b0aeb0d7f273cab11a8de37885f1dddc8d9112adb87169357ae").unwrap();
 
         let mut psbt_input = psbt::Input::default();
         psbt_input
index 5de20ae7a3304404348d131cfa0496642a22ee75..14b2459ebe17b9594a03fee8442779fd9d9730ed 100644 (file)
@@ -45,9 +45,9 @@ use core::fmt;
 use serde::ser::SerializeMap;
 use serde::{Serialize, Serializer};
 
+use bitcoin::bip32::Fingerprint;
 use bitcoin::hashes::{hash160, ripemd160, sha256};
-use bitcoin::util::bip32::Fingerprint;
-use bitcoin::{LockTime, PublicKey, Sequence, XOnlyPublicKey};
+use bitcoin::{absolute, key::XOnlyPublicKey, PublicKey, Sequence};
 
 use miniscript::descriptor::{
     DescriptorPublicKey, ShInner, SinglePub, SinglePubKey, SortedMultiVec, WshInner,
@@ -68,7 +68,7 @@ use crate::wallet::utils::{After, Older, SecpCtx};
 use super::checksum::calc_checksum;
 use super::error::Error;
 use super::XKeyUtils;
-use bitcoin::util::psbt::{Input as PsbtInput, PartiallySignedTransaction as Psbt};
+use bitcoin::psbt::{self, Psbt};
 use miniscript::psbt::PsbtInputSatisfier;
 
 /// A unique identifier for a key
@@ -95,6 +95,9 @@ impl PkOrF {
                 ..
             }) => PkOrF::XOnlyPubkey(*pk),
             DescriptorPublicKey::XPub(xpub) => PkOrF::Fingerprint(xpub.root_fingerprint(secp)),
+            DescriptorPublicKey::MultiXPub(multi) => {
+                PkOrF::Fingerprint(multi.root_fingerprint(secp))
+            }
         }
     }
 }
@@ -131,7 +134,7 @@ pub enum SatisfiableItem {
     /// Absolute timeclock timestamp
     AbsoluteTimelock {
         /// The timelock value
-        value: LockTime,
+        value: absolute::LockTime,
     },
     /// Relative timelock locktime
     RelativeTimelock {
@@ -451,11 +454,14 @@ pub struct Condition {
     pub csv: Option<Sequence>,
     /// Optional timelock condition
     #[serde(skip_serializing_if = "Option::is_none")]
-    pub timelock: Option<LockTime>,
+    pub timelock: Option<absolute::LockTime>,
 }
 
 impl Condition {
-    fn merge_nlocktime(a: LockTime, b: LockTime) -> Result<LockTime, PolicyError> {
+    fn merge_nlocktime(
+        a: absolute::LockTime,
+        b: absolute::LockTime,
+    ) -> Result<absolute::LockTime, PolicyError> {
         if !a.is_same_unit(b) {
             Err(PolicyError::MixedTimelockUnits)
         } else if a > b {
@@ -749,6 +755,7 @@ fn signer_id(key: &DescriptorPublicKey, secp: &SecpCtx) -> SignerId {
             ..
         }) => pk.to_pubkeyhash(SigType::Ecdsa).into(),
         DescriptorPublicKey::XPub(xpub) => xpub.root_fingerprint(secp).into(),
+        DescriptorPublicKey::MultiXPub(xpub) => xpub.root_fingerprint(secp).into(),
     }
 }
 
@@ -786,9 +793,9 @@ fn make_generic_signature<M: Fn() -> SatisfiableItem, F: Fn(&Psbt) -> bool>(
 fn generic_sig_in_psbt<
     // C is for "check", it's a closure we use to *check* if a psbt input contains the signature
     // for a specific key
-    C: Fn(&PsbtInput, &SinglePubKey) -> bool,
+    C: Fn(&psbt::Input, &SinglePubKey) -> bool,
     // E is for "extract", it extracts a key from the bip32 derivations found in the psbt input
-    E: Fn(&PsbtInput, Fingerprint) -> Option<SinglePubKey>,
+    E: Fn(&psbt::Input, Fingerprint) -> Option<SinglePubKey>,
 >(
     psbt: &Psbt,
     key: &DescriptorPublicKey,
@@ -806,6 +813,13 @@ fn generic_sig_in_psbt<
                 None => false,
             }
         }
+        DescriptorPublicKey::MultiXPub(xpub) => {
+            //TODO check actual derivation matches
+            match extract(input, xpub.root_fingerprint(secp)) {
+                Some(pubkey) => check(input, &pubkey),
+                None => false,
+            }
+        }
     })
 }
 
@@ -911,12 +925,12 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
             }
             Terminal::After(value) => {
                 let mut policy: Policy = SatisfiableItem::AbsoluteTimelock {
-                    value: value.into(),
+                    value: (*value).into(),
                 }
                 .into();
                 policy.contribution = Satisfaction::Complete {
                     condition: Condition {
-                        timelock: Some(value.into()),
+                        timelock: Some((*value).into()),
                         csv: None,
                     },
                 };
@@ -928,9 +942,9 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
                 {
                     let after = After::new(Some(current_height), false);
                     let after_sat =
-                        Satisfier::<bitcoin::PublicKey>::check_after(&after, value.into());
+                        Satisfier::<bitcoin::PublicKey>::check_after(&after, (*value).into());
                     let inputs_sat = psbt_inputs_sat(psbt).all(|sat| {
-                        Satisfier::<bitcoin::PublicKey>::check_after(&sat, value.into())
+                        Satisfier::<bitcoin::PublicKey>::check_after(&sat, (*value).into())
                     });
                     if after_sat && inputs_sat {
                         policy.satisfaction = policy.contribution.clone();
@@ -1156,8 +1170,8 @@ mod test {
     use crate::wallet::signer::SignersContainer;
     use alloc::{string::ToString, sync::Arc};
     use assert_matches::assert_matches;
+    use bitcoin::bip32;
     use bitcoin::secp256k1::Secp256k1;
-    use bitcoin::util::bip32;
     use bitcoin::Network;
     use core::str::FromStr;
 
@@ -1575,6 +1589,7 @@ mod test {
 
         let addr = wallet_desc
             .at_derivation_index(0)
+            .unwrap()
             .address(Network::Testnet)
             .unwrap();
         assert_eq!(
@@ -1641,6 +1656,7 @@ mod test {
 
         let addr = wallet_desc
             .at_derivation_index(0)
+            .unwrap()
             .address(Network::Testnet)
             .unwrap();
         assert_eq!(
index 599cf69ec35c584df1fbe15a7b97a549f1d41ec7..c5e8b31c507bb51057bee702d65f42eb089f8f26 100644 (file)
@@ -14,7 +14,7 @@
 //! This module contains the definition of various common script templates that are ready to be
 //! used. See the documentation of each template for an example.
 
-use bitcoin::util::bip32;
+use bitcoin::bip32;
 use bitcoin::Network;
 
 use miniscript::{Legacy, Segwitv0, Tap};
@@ -195,7 +195,7 @@ impl<K: IntoDescriptorKey<Tap>> DescriptorTemplate for P2TR<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip44;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
+/// let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
 /// let mut wallet = Wallet::new_no_persist(
 ///     Bip44(key.clone(), KeychainKind::External),
 ///     Some(Bip44(key, KeychainKind::Internal)),
@@ -232,8 +232,8 @@ impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip44Public;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU")?;
-/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
+/// let key = bitcoin::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU")?;
+/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
 /// let mut wallet = Wallet::new_no_persist(
 ///     Bip44Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip44Public(key, fingerprint, KeychainKind::Internal)),
@@ -270,7 +270,7 @@ impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44Public<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip49;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
+/// let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
 /// let mut wallet = Wallet::new_no_persist(
 ///     Bip49(key.clone(), KeychainKind::External),
 ///     Some(Bip49(key, KeychainKind::Internal)),
@@ -307,8 +307,8 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip49Public;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L")?;
-/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
+/// let key = bitcoin::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L")?;
+/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
 /// let mut wallet = Wallet::new_no_persist(
 ///     Bip49Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip49Public(key, fingerprint, KeychainKind::Internal)),
@@ -345,7 +345,7 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49Public<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip84;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
+/// let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
 /// let mut wallet = Wallet::new_no_persist(
 ///     Bip84(key.clone(), KeychainKind::External),
 ///     Some(Bip84(key, KeychainKind::Internal)),
@@ -382,8 +382,8 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip84Public;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
-/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
+/// let key = bitcoin::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
+/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
 /// let mut wallet = Wallet::new_no_persist(
 ///     Bip84Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip84Public(key, fingerprint, KeychainKind::Internal)),
@@ -420,7 +420,7 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84Public<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip86;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
+/// let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
 /// let mut wallet = Wallet::new_no_persist(
 ///     Bip86(key.clone(), KeychainKind::External),
 ///     Some(Bip86(key, KeychainKind::Internal)),
@@ -457,8 +457,8 @@ impl<K: DerivableKey<Tap>> DescriptorTemplate for Bip86<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip86Public;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
-/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
+/// let key = bitcoin::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
+/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
 /// let mut wallet = Wallet::new_no_persist(
 ///     Bip86Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip86Public(key, fingerprint, KeychainKind::Internal)),
@@ -565,30 +565,30 @@ mod test {
     // BIP44 `pkh(key/44'/{0,1}'/0'/{0,1}/*)`
     #[test]
     fn test_bip44_template_cointype() {
-        use bitcoin::util::bip32::ChildNumber::{self, Hardened};
+        use bitcoin::bip32::ChildNumber::{self, Hardened};
 
-        let xprvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K2fpbqApQL69a4oKdGVnVN52R82Ft7d1pSqgKmajF62acJo3aMszZb6qQ22QsVECSFxvf9uyxFUvFYQMq3QbtwtRSMjLAhMf").unwrap();
+        let xprvkey = bitcoin::bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K2fpbqApQL69a4oKdGVnVN52R82Ft7d1pSqgKmajF62acJo3aMszZb6qQ22QsVECSFxvf9uyxFUvFYQMq3QbtwtRSMjLAhMf").unwrap();
         assert_eq!(Network::Bitcoin, xprvkey.network);
         let xdesc = Bip44(xprvkey, KeychainKind::Internal)
             .build(Network::Bitcoin)
             .unwrap();
 
         if let ExtendedDescriptor::Pkh(pkh) = xdesc.0 {
-            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().into();
+            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().unwrap().into();
             let purpose = path.get(0).unwrap();
             assert_matches!(purpose, Hardened { index: 44 });
             let coin_type = path.get(1).unwrap();
             assert_matches!(coin_type, Hardened { index: 0 });
         }
 
-        let tprvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+        let tprvkey = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
         assert_eq!(Network::Testnet, tprvkey.network);
         let tdesc = Bip44(tprvkey, KeychainKind::Internal)
             .build(Network::Testnet)
             .unwrap();
 
         if let ExtendedDescriptor::Pkh(pkh) = tdesc.0 {
-            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().into();
+            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().unwrap().into();
             let purpose = path.get(0).unwrap();
             assert_matches!(purpose, Hardened { index: 44 });
             let coin_type = path.get(1).unwrap();
@@ -612,9 +612,9 @@ mod test {
         for i in 0..expected.len() {
             let index = i as u32;
             let child_desc = if !desc.has_wildcard() {
-                desc.at_derivation_index(0)
+                desc.at_derivation_index(0).unwrap()
             } else {
-                desc.at_derivation_index(index)
+                desc.at_derivation_index(index).unwrap()
             };
             let address = child_desc.address(network).unwrap();
             assert_eq!(address.to_string(), *expected.get(i).unwrap());
@@ -740,7 +740,7 @@ mod test {
     // BIP44 `pkh(key/44'/0'/0'/{0,1}/*)`
     #[test]
     fn test_bip44_template() {
-        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+        let prvkey = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
         check(
             Bip44(prvkey, KeychainKind::External).build(Network::Bitcoin),
             false,
@@ -770,8 +770,8 @@ mod test {
     // BIP44 public `pkh(key/{0,1}/*)`
     #[test]
     fn test_bip44_public_template() {
-        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU").unwrap();
-        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
+        let pubkey = bitcoin::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU").unwrap();
+        let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f").unwrap();
         check(
             Bip44Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
             false,
@@ -801,7 +801,7 @@ mod test {
     // BIP49 `sh(wpkh(key/49'/0'/0'/{0,1}/*))`
     #[test]
     fn test_bip49_template() {
-        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+        let prvkey = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
         check(
             Bip49(prvkey, KeychainKind::External).build(Network::Bitcoin),
             true,
@@ -831,8 +831,8 @@ mod test {
     // BIP49 public `sh(wpkh(key/{0,1}/*))`
     #[test]
     fn test_bip49_public_template() {
-        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L").unwrap();
-        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
+        let pubkey = bitcoin::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L").unwrap();
+        let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f").unwrap();
         check(
             Bip49Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
             true,
@@ -862,7 +862,7 @@ mod test {
     // BIP84 `wpkh(key/84'/0'/0'/{0,1}/*)`
     #[test]
     fn test_bip84_template() {
-        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+        let prvkey = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
         check(
             Bip84(prvkey, KeychainKind::External).build(Network::Bitcoin),
             true,
@@ -892,8 +892,8 @@ mod test {
     // BIP84 public `wpkh(key/{0,1}/*)`
     #[test]
     fn test_bip84_public_template() {
-        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q").unwrap();
-        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
+        let pubkey = bitcoin::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q").unwrap();
+        let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f").unwrap();
         check(
             Bip84Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
             true,
@@ -924,7 +924,7 @@ mod test {
     // Used addresses in test vector in https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki
     #[test]
     fn test_bip86_template() {
-        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLisriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu").unwrap();
+        let prvkey = bitcoin::bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLisriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu").unwrap();
         check(
             Bip86(prvkey, KeychainKind::External).build(Network::Bitcoin),
             false,
@@ -955,8 +955,8 @@ mod test {
     // Used addresses in test vector in https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki
     #[test]
     fn test_bip86_public_template() {
-        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ").unwrap();
-        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("73c5da0a").unwrap();
+        let pubkey = bitcoin::bip32::ExtendedPubKey::from_str("xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ").unwrap();
+        let fingerprint = bitcoin::bip32::Fingerprint::from_str("73c5da0a").unwrap();
         check(
             Bip86Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
             false,
index 22817a3ef7f62030fcd3fe4a273ea9127ecad84b..fcb5a6f7b17ba159e15cedb46c3ae38e9aee18f8 100644 (file)
@@ -84,9 +84,9 @@ pub enum Error {
     /// Miniscript PSBT error
     MiniscriptPsbt(MiniscriptPsbtError),
     /// BIP32 error
-    Bip32(bitcoin::util::bip32::Error),
+    Bip32(bitcoin::bip32::Error),
     /// Partially signed bitcoin transaction error
-    Psbt(bitcoin::util::psbt::Error),
+    Psbt(bitcoin::psbt::Error),
 }
 
 /// Errors returned by miniscript when updating inconsistent PSBTs
@@ -197,5 +197,5 @@ impl From<crate::keys::KeyError> for Error {
 
 impl_error!(miniscript::Error, Miniscript);
 impl_error!(MiniscriptPsbtError, MiniscriptPsbt);
-impl_error!(bitcoin::util::bip32::Error, Bip32);
-impl_error!(bitcoin::util::psbt::Error, Psbt);
+impl_error!(bitcoin::bip32::Error, Bip32);
+impl_error!(bitcoin::psbt::Error, Psbt);
index 78f544934ffe035d8b7759cbfa87f58f69747af2..8b09ac287edb6d453c008e3950b8b598c1752f57 100644 (file)
@@ -15,7 +15,7 @@
 // something that should be fairly simple to re-implement.
 
 use alloc::string::String;
-use bitcoin::util::bip32;
+use bitcoin::bip32;
 use bitcoin::Network;
 
 use miniscript::ScriptContext;
@@ -142,7 +142,7 @@ impl<Ctx: ScriptContext> GeneratableKey<Ctx> for Mnemonic {
         (word_count, language): Self::Options,
         entropy: Self::Entropy,
     ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
-        let entropy = &entropy.as_ref()[..(word_count as usize / 8)];
+        let entropy = &entropy[..(word_count as usize / 8)];
         let mnemonic = Mnemonic::from_entropy_in(language, entropy)?;
 
         Ok(GeneratedKey::new(mnemonic, any_network()))
@@ -154,7 +154,7 @@ mod test {
     use alloc::string::ToString;
     use core::str::FromStr;
 
-    use bitcoin::util::bip32;
+    use bitcoin::bip32;
 
     use bip39::{Language, Mnemonic};
 
index b4cfb6dee347b81bf1231d9581c196537abf51a7..c91625932b70de7006332e56835f7be0b423244c 100644 (file)
@@ -22,8 +22,8 @@ use core::str::FromStr;
 
 use bitcoin::secp256k1::{self, Secp256k1, Signing};
 
-use bitcoin::util::bip32;
-use bitcoin::{Network, PrivateKey, PublicKey, XOnlyPublicKey};
+use bitcoin::bip32;
+use bitcoin::{key::XOnlyPublicKey, Network, PrivateKey, PublicKey};
 
 use miniscript::descriptor::{Descriptor, DescriptorXKey, Wildcard};
 pub use miniscript::descriptor::{
@@ -388,12 +388,12 @@ impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
 ///
 /// ```
 /// use bdk::bitcoin;
-/// use bdk::bitcoin::util::bip32;
+/// use bdk::bitcoin::bip32;
 /// use bdk::keys::{DerivableKey, ExtendedKey, KeyError, ScriptContext};
 ///
 /// struct MyCustomKeyType {
 ///     key_data: bitcoin::PrivateKey,
-///     chain_code: Vec<u8>,
+///     chain_code: [u8; 32],
 ///     network: bitcoin::Network,
 /// }
 ///
@@ -404,7 +404,7 @@ impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
 ///             depth: 0,
 ///             parent_fingerprint: bip32::Fingerprint::default(),
 ///             private_key: self.key_data.inner,
-///             chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
+///             chain_code: bip32::ChainCode::from(&self.chain_code),
 ///             child_number: bip32::ChildNumber::Normal { index: 0 },
 ///         };
 ///
@@ -419,14 +419,14 @@ impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
 ///
 /// ```
 /// use bdk::bitcoin;
-/// use bdk::bitcoin::util::bip32;
+/// use bdk::bitcoin::bip32;
 /// use bdk::keys::{
 ///     any_network, DerivableKey, DescriptorKey, ExtendedKey, KeyError, ScriptContext,
 /// };
 ///
 /// struct MyCustomKeyType {
 ///     key_data: bitcoin::PrivateKey,
-///     chain_code: Vec<u8>,
+///     chain_code: [u8; 32],
 /// }
 ///
 /// impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
@@ -436,7 +436,7 @@ impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
 ///             depth: 0,
 ///             parent_fingerprint: bip32::Fingerprint::default(),
 ///             private_key: self.key_data.inner,
-///             chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
+///             chain_code: bip32::ChainCode::from(&self.chain_code),
 ///             child_number: bip32::ChildNumber::Normal { index: 0 },
 ///         };
 ///
@@ -927,13 +927,13 @@ pub enum KeyError {
     Message(String),
 
     /// BIP32 error
-    Bip32(bitcoin::util::bip32::Error),
+    Bip32(bitcoin::bip32::Error),
     /// Miniscript error
     Miniscript(miniscript::Error),
 }
 
 impl_error!(miniscript::Error, Miniscript, KeyError);
-impl_error!(bitcoin::util::bip32::Error, Bip32, KeyError);
+impl_error!(bitcoin::bip32::Error, Bip32, KeyError);
 
 impl fmt::Display for KeyError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -953,7 +953,7 @@ impl std::error::Error for KeyError {}
 
 #[cfg(test)]
 pub mod test {
-    use bitcoin::util::bip32;
+    use bitcoin::bip32;
 
     use super::*;
 
index 8724323679c4797eb72cfa1e6085a730fe465127..bc6ce8589703e3fcab838b08bd577463d36bcfec 100644 (file)
@@ -13,7 +13,7 @@
 
 use crate::FeeRate;
 use alloc::vec::Vec;
-use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
+use bitcoin::psbt::PartiallySignedTransaction as Psbt;
 use bitcoin::TxOut;
 
 // TODO upstream the functions here to `rust-bitcoin`?
index e21bef90660c41dc6a8bb4734f8474628f437544..1b96ef0fff0d6496efc6f1effb99f46966c9476e 100644 (file)
@@ -15,7 +15,7 @@ use core::ops::Sub;
 
 use bdk_chain::ConfirmationTime;
 use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
-use bitcoin::{hash_types::Txid, util::psbt};
+use bitcoin::{hash_types::Txid, psbt, Weight};
 
 use serde::{Deserialize, Serialize};
 
@@ -99,8 +99,8 @@ impl FeeRate {
     }
 
     /// Calculate fee rate from `fee` and weight units (`wu`).
-    pub fn from_wu(fee: u64, wu: usize) -> FeeRate {
-        Self::from_vb(fee, wu.vbytes())
+    pub fn from_wu(fee: u64, wu: Weight) -> FeeRate {
+        Self::from_vb(fee, wu.to_vbytes_ceil() as usize)
     }
 
     /// Calculate fee rate from `fee` and `vbytes`.
@@ -120,8 +120,8 @@ impl FeeRate {
     }
 
     /// Calculate absolute fee in Satoshis using size in weight units.
-    pub fn fee_wu(&self, wu: usize) -> u64 {
-        self.fee_vb(wu.vbytes())
+    pub fn fee_wu(&self, wu: Weight) -> u64 {
+        self.fee_vb(wu.to_vbytes_ceil() as usize)
     }
 
     /// Calculate absolute fee in Satoshis using size in virtual bytes.
index e7927cabb3e2eb41e4bf6d6635196612dea6075b..6f30fd14ff30a1e0d1804245b2b0078d12b001f2 100644 (file)
 //!         &self,
 //!         required_utxos: Vec<WeightedUtxo>,
 //!         optional_utxos: Vec<WeightedUtxo>,
-//!         fee_rate: FeeRate,
+//!         fee_rate: bdk::FeeRate,
 //!         target_amount: u64,
 //!         drain_script: &Script,
 //!     ) -> Result<CoinSelectionResult, bdk::Error> {
 //!         let mut selected_amount = 0;
-//!         let mut additional_weight = 0;
+//!         let mut additional_weight = Weight::ZERO;
 //!         let all_utxos_selected = required_utxos
 //!             .into_iter()
 //!             .chain(optional_utxos)
@@ -51,7 +51,9 @@
 //!                 (&mut selected_amount, &mut additional_weight),
 //!                 |(selected_amount, additional_weight), weighted_utxo| {
 //!                     **selected_amount += weighted_utxo.utxo.txout().value;
-//!                     **additional_weight += TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight;
+//!                     **additional_weight += Weight::from_wu(
+//!                         (TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight) as u64,
+//!                     );
 //!                     Some(weighted_utxo.utxo)
 //!                 },
 //!             )
 //! # let mut wallet = doctest_wallet!();
 //! // create wallet, sync, ...
 //!
-//! let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+//! let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
+//!     .unwrap()
+//!     .require_network(Network::Testnet)
+//!     .unwrap();
 //! let (psbt, details) = {
 //!     let mut builder = wallet.build_tx().coin_selection(AlwaysSpendEverything);
 //!     builder.add_recipient(to_address.script_pubkey(), 50_000);
@@ -99,7 +104,7 @@ use crate::{error::Error, Utxo};
 
 use alloc::vec::Vec;
 use bitcoin::consensus::encode::serialize;
-use bitcoin::Script;
+use bitcoin::{Script, Weight};
 
 use core::convert::TryInto;
 use rand::seq::SliceRandom;
@@ -302,8 +307,9 @@ fn select_sorted_utxos(
             (&mut selected_amount, &mut fee_amount),
             |(selected_amount, fee_amount), (must_use, weighted_utxo)| {
                 if must_use || **selected_amount < target_amount + **fee_amount {
-                    **fee_amount +=
-                        fee_rate.fee_wu(TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight);
+                    **fee_amount += fee_rate.fee_wu(Weight::from_wu(
+                        (TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight) as u64,
+                    ));
                     **selected_amount += weighted_utxo.utxo.txout().value;
 
                     log::debug!(
@@ -351,7 +357,9 @@ struct OutputGroup {
 
 impl OutputGroup {
     fn new(weighted_utxo: WeightedUtxo, fee_rate: FeeRate) -> Self {
-        let fee = fee_rate.fee_wu(TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight);
+        let fee = fee_rate.fee_wu(Weight::from_wu(
+            (TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight) as u64,
+        ));
         let effective_value = weighted_utxo.utxo.txout().value as i64 - fee as i64;
         OutputGroup {
             weighted_utxo,
@@ -681,7 +689,7 @@ mod test {
     use core::str::FromStr;
 
     use bdk_chain::ConfirmationTime;
-    use bitcoin::{OutPoint, Script, TxOut};
+    use bitcoin::{OutPoint, ScriptBuf, TxOut};
 
     use super::*;
     use crate::types::*;
@@ -710,7 +718,7 @@ mod test {
                 outpoint,
                 txout: TxOut {
                     value,
-                    script_pubkey: Script::new(),
+                    script_pubkey: ScriptBuf::new(),
                 },
                 keychain: KeychainKind::External,
                 is_spent: false,
@@ -773,7 +781,7 @@ mod test {
                     .unwrap(),
                     txout: TxOut {
                         value: rng.gen_range(0..200000000),
-                        script_pubkey: Script::new(),
+                        script_pubkey: ScriptBuf::new(),
                     },
                     keychain: KeychainKind::External,
                     is_spent: false,
@@ -802,7 +810,7 @@ mod test {
                 .unwrap(),
                 txout: TxOut {
                     value: utxos_value,
-                    script_pubkey: Script::new(),
+                    script_pubkey: ScriptBuf::new(),
                 },
                 keychain: KeychainKind::External,
                 is_spent: false,
@@ -825,7 +833,7 @@ mod test {
     #[test]
     fn test_largest_first_coin_selection_success() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 250_000 + FEE_AMOUNT;
 
         let result = LargestFirstCoinSelection::default()
@@ -846,7 +854,7 @@ mod test {
     #[test]
     fn test_largest_first_coin_selection_use_all() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let result = LargestFirstCoinSelection::default()
@@ -867,7 +875,7 @@ mod test {
     #[test]
     fn test_largest_first_coin_selection_use_only_necessary() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let result = LargestFirstCoinSelection::default()
@@ -889,7 +897,7 @@ mod test {
     #[should_panic(expected = "InsufficientFunds")]
     fn test_largest_first_coin_selection_insufficient_funds() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 500_000 + FEE_AMOUNT;
 
         LargestFirstCoinSelection::default()
@@ -907,7 +915,7 @@ mod test {
     #[should_panic(expected = "InsufficientFunds")]
     fn test_largest_first_coin_selection_insufficient_funds_high_fees() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 250_000 + FEE_AMOUNT;
 
         LargestFirstCoinSelection::default()
@@ -924,7 +932,7 @@ mod test {
     #[test]
     fn test_oldest_first_coin_selection_success() {
         let utxos = get_oldest_first_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 180_000 + FEE_AMOUNT;
 
         let result = OldestFirstCoinSelection::default()
@@ -945,7 +953,7 @@ mod test {
     #[test]
     fn test_oldest_first_coin_selection_use_all() {
         let utxos = get_oldest_first_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let result = OldestFirstCoinSelection::default()
@@ -966,7 +974,7 @@ mod test {
     #[test]
     fn test_oldest_first_coin_selection_use_only_necessary() {
         let utxos = get_oldest_first_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let result = OldestFirstCoinSelection::default()
@@ -988,7 +996,7 @@ mod test {
     #[should_panic(expected = "InsufficientFunds")]
     fn test_oldest_first_coin_selection_insufficient_funds() {
         let utxos = get_oldest_first_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 600_000 + FEE_AMOUNT;
 
         OldestFirstCoinSelection::default()
@@ -1008,7 +1016,7 @@ mod test {
         let utxos = get_oldest_first_test_utxos();
 
         let target_amount: u64 = utxos.iter().map(|wu| wu.utxo.txout().value).sum::<u64>() - 50;
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         OldestFirstCoinSelection::default()
             .coin_select(
@@ -1027,7 +1035,7 @@ mod test {
         // select three outputs
         let utxos = generate_same_value_utxos(100_000, 20);
 
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let target_amount = 250_000 + FEE_AMOUNT;
 
@@ -1049,7 +1057,7 @@ mod test {
     #[test]
     fn test_bnb_coin_selection_required_are_enough() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let result = BranchAndBoundCoinSelection::default()
@@ -1070,7 +1078,7 @@ mod test {
     #[test]
     fn test_bnb_coin_selection_optional_are_enough() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 299756 + FEE_AMOUNT;
 
         let result = BranchAndBoundCoinSelection::default()
@@ -1106,7 +1114,7 @@ mod test {
         assert_eq!(amount, 100_000);
         let amount: u64 = optional.iter().map(|u| u.utxo.txout().value).sum();
         assert!(amount > 150_000);
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let target_amount = 150_000 + FEE_AMOUNT;
 
@@ -1129,7 +1137,7 @@ mod test {
     #[should_panic(expected = "InsufficientFunds")]
     fn test_bnb_coin_selection_insufficient_funds() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 500_000 + FEE_AMOUNT;
 
         BranchAndBoundCoinSelection::default()
@@ -1147,7 +1155,7 @@ mod test {
     #[should_panic(expected = "InsufficientFunds")]
     fn test_bnb_coin_selection_insufficient_funds_high_fees() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 250_000 + FEE_AMOUNT;
 
         BranchAndBoundCoinSelection::default()
@@ -1164,7 +1172,7 @@ mod test {
     #[test]
     fn test_bnb_coin_selection_check_fee_rate() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 99932; // first utxo's effective value
 
         let result = BranchAndBoundCoinSelection::new(0)
@@ -1192,7 +1200,7 @@ mod test {
         for _i in 0..200 {
             let mut optional_utxos = generate_random_utxos(&mut rng, 16);
             let target_amount = sum_random_utxos(&mut rng, &mut optional_utxos);
-            let drain_script = Script::default();
+            let drain_script = ScriptBuf::default();
             let result = BranchAndBoundCoinSelection::new(0)
                 .coin_select(
                     vec![],
@@ -1220,7 +1228,7 @@ mod test {
         let size_of_change = 31;
         let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
 
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
         BranchAndBoundCoinSelection::new(size_of_change)
             .bnb(
@@ -1251,7 +1259,7 @@ mod test {
         let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
         let target_amount = 20_000 + FEE_AMOUNT;
 
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         BranchAndBoundCoinSelection::new(size_of_change)
             .bnb(
@@ -1287,7 +1295,7 @@ mod test {
         // cost_of_change + 5.
         let target_amount = 2 * 50_000 - 2 * 67 - cost_of_change.ceil() as i64 + 5;
 
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let result = BranchAndBoundCoinSelection::new(size_of_change)
             .bnb(
@@ -1327,7 +1335,7 @@ mod test {
             let target_amount =
                 optional_utxos[3].effective_value + optional_utxos[23].effective_value;
 
-            let drain_script = Script::default();
+            let drain_script = ScriptBuf::default();
 
             let result = BranchAndBoundCoinSelection::new(0)
                 .bnb(
@@ -1358,7 +1366,7 @@ mod test {
             .map(|u| OutputGroup::new(u, fee_rate))
             .collect();
 
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let result = BranchAndBoundCoinSelection::default().single_random_draw(
             vec![],
@@ -1376,7 +1384,7 @@ mod test {
     #[test]
     fn test_bnb_exclude_negative_effective_value() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let selection = BranchAndBoundCoinSelection::default().coin_select(
             vec![],
@@ -1398,7 +1406,7 @@ mod test {
     #[test]
     fn test_bnb_include_negative_effective_value_when_required() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let (required, optional) = utxos
             .into_iter()
@@ -1424,7 +1432,7 @@ mod test {
     #[test]
     fn test_bnb_sum_of_effective_value_negative() {
         let utxos = get_test_utxos();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let selection = BranchAndBoundCoinSelection::default().coin_select(
             utxos,
index a4d93976c9f3b868de20364ec2460acc82029dbb..270d7340134d03b9b7f3be347498b8c751b3a109 100644 (file)
@@ -232,7 +232,7 @@ mod test {
             input: vec![],
             output: vec![],
             version: 0,
-            lock_time: bitcoin::PackedLockTime::ZERO,
+            lock_time: bitcoin::absolute::LockTime::ZERO,
         };
         wallet
             .insert_checkpoint(BlockId {
index dce1da8b8ed3619e2efb3cd2b4530a65b789f3a8..aec49297c28be6890cab39fb5b85045bd2c15089 100644 (file)
@@ -19,7 +19,7 @@
 //! # use bdk::wallet::hardwaresigner::HWISigner;
 //! # use bdk::wallet::AddressIndex::New;
 //! # use bdk::{FeeRate, KeychainKind, SignOptions, Wallet};
-//! # use hwi::{types::HWIChain, HWIClient};
+//! # use hwi::HWIClient;
 //! # use std::sync::Arc;
 //! #
 //! # fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -28,7 +28,7 @@
 //!     panic!("No devices found!");
 //! }
 //! let first_device = devices.remove(0)?;
-//! let custom_signer = HWISigner::from_device(&first_device, HWIChain::Test)?;
+//! let custom_signer = HWISigner::from_device(&first_device, Network::Testnet.into())?;
 //!
 //! # let mut wallet = Wallet::new_no_persist(
 //! #     "",
@@ -47,9 +47,9 @@
 //! # }
 //! ```
 
+use bitcoin::bip32::Fingerprint;
 use bitcoin::psbt::PartiallySignedTransaction;
 use bitcoin::secp256k1::{All, Secp256k1};
-use bitcoin::util::bip32::Fingerprint;
 
 use hwi::error::Error;
 use hwi::types::{HWIChain, HWIDevice};
index 5eeea45af1c183ce15a7183e4207e981e5df0c5a..2ef69f317ff7d997a6173dad6101ef5e394bc5d7 100644 (file)
@@ -29,11 +29,12 @@ use bdk_chain::{
     IndexedTxGraph, Persist, PersistBackend,
 };
 use bitcoin::consensus::encode::serialize;
+use bitcoin::psbt;
 use bitcoin::secp256k1::Secp256k1;
-use bitcoin::util::psbt;
+use bitcoin::sighash::{EcdsaSighashType, TapSighashType};
 use bitcoin::{
-    Address, EcdsaSighashType, LockTime, Network, OutPoint, SchnorrSighashType, Script, Sequence,
-    Transaction, TxOut, Txid, Witness,
+    absolute, Address, Network, OutPoint, Script, ScriptBuf, Sequence, Transaction, TxOut, Txid,
+    Weight, Witness,
 };
 use core::fmt;
 use core::ops::Deref;
@@ -322,11 +323,11 @@ impl<D> Wallet<D> {
         let (index, spk, additions) = match address_index {
             AddressIndex::New => {
                 let ((index, spk), index_additions) = txout_index.reveal_next_spk(&keychain);
-                (index, spk.clone(), Some(index_additions))
+                (index, spk.into(), Some(index_additions))
             }
             AddressIndex::LastUnused => {
                 let ((index, spk), index_additions) = txout_index.next_unused_spk(&keychain);
-                (index, spk.clone(), Some(index_additions))
+                (index, spk.into(), Some(index_additions))
             }
             AddressIndex::Peek(index) => {
                 let (index, spk) = txout_index
@@ -396,7 +397,7 @@ impl<D> Wallet<D> {
     /// script pubkeys the wallet is storing internally).
     pub fn spks_of_all_keychains(
         &self,
-    ) -> BTreeMap<KeychainKind, impl Iterator<Item = (u32, Script)> + Clone> {
+    ) -> BTreeMap<KeychainKind, impl Iterator<Item = (u32, ScriptBuf)> + Clone> {
         self.indexed_graph.index.spks_of_all_keychains()
     }
 
@@ -408,7 +409,7 @@ impl<D> Wallet<D> {
     pub fn spks_of_keychain(
         &self,
         keychain: KeychainKind,
-    ) -> impl Iterator<Item = (u32, Script)> + Clone {
+    ) -> impl Iterator<Item = (u32, ScriptBuf)> + Clone {
         self.indexed_graph.index.spks_of_keychain(&keychain)
     }
 
@@ -599,7 +600,7 @@ impl<D> Wallet<D> {
     /// # use bdk::*;
     /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
     /// # let mut wallet = doctest_wallet!();
-    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
     /// let (psbt, details) = {
     ///    let mut builder =  wallet.build_tx();
     ///    builder
@@ -716,7 +717,7 @@ impl<D> Wallet<D> {
             None => self
                 .chain
                 .tip()
-                .map(|cp| LockTime::from_height(cp.height()).expect("Invalid height")),
+                .map(|cp| absolute::LockTime::from_height(cp.height()).expect("Invalid height")),
             h => h,
         };
 
@@ -726,7 +727,7 @@ impl<D> Wallet<D> {
                 // Fee sniping can be partially prevented by setting the timelock
                 // to current_height. If we don't know the current_height,
                 // we default to 0.
-                let fee_sniping_height = current_height.unwrap_or(LockTime::ZERO);
+                let fee_sniping_height = current_height.unwrap_or(absolute::LockTime::ZERO);
 
                 // We choose the biggest between the required nlocktime and the fee sniping
                 // height
@@ -734,7 +735,7 @@ impl<D> Wallet<D> {
                     // No requirement, just use the fee_sniping_height
                     None => fee_sniping_height,
                     // There's a block-based requirement, but the value is lower than the fee_sniping_height
-                    Some(value @ LockTime::Blocks(_)) if value < fee_sniping_height => fee_sniping_height,
+                    Some(value @ absolute::LockTime::Blocks(_)) if value < fee_sniping_height => fee_sniping_height,
                     // There's a time-based requirement or a block-based requirement greater
                     // than the fee_sniping_height use that value
                     Some(value) => value,
@@ -750,7 +751,9 @@ impl<D> Wallet<D> {
 
         let n_sequence = match (params.rbf, requirements.csv) {
             // No RBF or CSV but there's an nLockTime, so the nSequence cannot be final
-            (None, None) if lock_time != LockTime::ZERO => Sequence::ENABLE_LOCKTIME_NO_RBF,
+            (None, None) if lock_time != absolute::LockTime::ZERO => {
+                Sequence::ENABLE_LOCKTIME_NO_RBF
+            }
             // No RBF, CSV or nLockTime, make the transaction final
             (None, None) => Sequence::MAX,
 
@@ -813,7 +816,7 @@ impl<D> Wallet<D> {
 
         let mut tx = Transaction {
             version,
-            lock_time: lock_time.into(),
+            lock_time,
             input: vec![],
             output: vec![],
         };
@@ -861,7 +864,7 @@ impl<D> Wallet<D> {
         // end up with a transaction with a slightly higher fee rate than the requested one.
         // If, instead, we undershoot, we may end up with a feerate lower than the requested one
         // - we might come up with non broadcastable txs!
-        fee_amount += fee_rate.fee_wu(2);
+        fee_amount += fee_rate.fee_wu(Weight::from_wu(2));
 
         if params.change_policy != tx_builder::ChangeSpendPolicy::ChangeAllowed
             && internal_descriptor.is_none()
@@ -878,7 +881,7 @@ impl<D> Wallet<D> {
             params.drain_wallet,
             params.manually_selected_only,
             params.bumping_fee.is_some(), // we mandate confirmed transactions if we're bumping the fee
-            current_height.map(LockTime::to_consensus_u32),
+            current_height.map(absolute::LockTime::to_consensus_u32),
         );
 
         // get drain script
@@ -888,7 +891,7 @@ impl<D> Wallet<D> {
                 let change_keychain = self.map_keychain(KeychainKind::Internal);
                 let ((index, spk), index_additions) =
                     self.indexed_graph.index.next_unused_spk(&change_keychain);
-                let spk = spk.clone();
+                let spk = spk.into();
                 self.indexed_graph.index.mark_used(&change_keychain, index);
                 self.persist
                     .stage(ChangeSet::from(IndexedAdditions::from(index_additions)));
@@ -912,7 +915,7 @@ impl<D> Wallet<D> {
             .iter()
             .map(|u| bitcoin::TxIn {
                 previous_output: u.outpoint(),
-                script_sig: Script::default(),
+                script_sig: ScriptBuf::default(),
                 sequence: n_sequence,
                 witness: Witness::new(),
             })
@@ -1000,7 +1003,7 @@ impl<D> Wallet<D> {
     /// # use bdk::*;
     /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
     /// # let mut wallet = doctest_wallet!();
-    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
     /// let (mut psbt, _) = {
     ///     let mut builder = wallet.build_tx();
     ///     builder
@@ -1014,7 +1017,7 @@ impl<D> Wallet<D> {
     /// let (mut psbt, _) =  {
     ///     let mut builder = wallet.build_fee_bump(tx.txid())?;
     ///     builder
-    ///         .fee_rate(FeeRate::from_sat_per_vb(5.0));
+    ///         .fee_rate(bdk::FeeRate::from_sat_per_vb(5.0));
     ///     builder.finish()?
     /// };
     ///
@@ -1078,6 +1081,7 @@ impl<D> Wallet<D> {
 
                 let weighted_utxo = match txout_index.index_of_spk(&txout.script_pubkey) {
                     Some(&(keychain, derivation_index)) => {
+                        #[allow(deprecated)]
                         let satisfaction_weight = self
                             .get_descriptor_for_keychain(keychain)
                             .max_satisfaction_weight()
@@ -1170,7 +1174,7 @@ impl<D> Wallet<D> {
     /// # use bdk::*;
     /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
     /// # let mut wallet = doctest_wallet!();
-    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
     /// let (mut psbt, _) = {
     ///     let mut builder = wallet.build_tx();
     ///     builder.add_recipient(to_address.script_pubkey(), 50_000);
@@ -1207,8 +1211,8 @@ impl<D> Wallet<D> {
             && !psbt.inputs.iter().all(|i| {
                 i.sighash_type.is_none()
                     || i.sighash_type == Some(EcdsaSighashType::All.into())
-                    || i.sighash_type == Some(SchnorrSighashType::All.into())
-                    || i.sighash_type == Some(SchnorrSighashType::Default.into())
+                    || i.sighash_type == Some(TapSighashType::All.into())
+                    || i.sighash_type == Some(TapSighashType::Default.into())
             })
         {
             return Err(Error::Signer(signer::SignerError::NonStandardSighash));
@@ -1403,13 +1407,14 @@ impl<D> Wallet<D> {
             .index
             .index_of_spk(&txout.script_pubkey)?;
         let descriptor = self.get_descriptor_for_keychain(keychain);
-        Some(descriptor.at_derivation_index(child))
+        descriptor.at_derivation_index(child).ok()
     }
 
     fn get_available_utxos(&self) -> Vec<(LocalUtxo, usize)> {
         self.list_unspent()
             .map(|utxo| {
                 let keychain = utxo.keychain;
+                #[allow(deprecated)]
                 (
                     utxo,
                     self.get_descriptor_for_keychain(keychain)
@@ -1620,7 +1625,9 @@ impl<D> Wallet<D> {
         };
 
         let desc = self.get_descriptor_for_keychain(keychain);
-        let derived_descriptor = desc.at_derivation_index(child);
+        let derived_descriptor = desc
+            .at_derivation_index(child)
+            .expect("child can't be hardened");
 
         psbt_input
             .update_with_descriptor_unchecked(&derived_descriptor)
@@ -1669,7 +1676,9 @@ impl<D> Wallet<D> {
                 );
 
                 let desc = self.get_descriptor_for_keychain(keychain);
-                let desc = desc.at_derivation_index(child);
+                let desc = desc
+                    .at_derivation_index(child)
+                    .expect("child can't be hardened");
 
                 if is_input {
                     psbt.update_input_with_descriptor(index, &desc)
@@ -1871,7 +1880,7 @@ fn new_tx_details(
 /// Macro for getting a wallet for use in a doctest
 macro_rules! doctest_wallet {
     () => {{
-        use $crate::bitcoin::{BlockHash, Transaction, PackedLockTime, TxOut, Network, hashes::Hash};
+        use $crate::bitcoin::{BlockHash, Transaction, absolute, TxOut, Network, hashes::Hash};
         use $crate::chain::{ConfirmationTime, BlockId};
         use $crate::wallet::{AddressIndex, Wallet};
         let descriptor = "tr([73c5da0a/86'/0'/0']tprv8fMn4hSKPRC1oaCPqxDb1JWtgkpeiQvZhsr8W2xuy3GEMkzoArcAWTfJxYb6Wj8XNNDWEjfYKK4wGQXh3ZUXhDF2NcnsALpWTeSwarJt7Vc/0/*)";
@@ -1886,7 +1895,7 @@ macro_rules! doctest_wallet {
         let address = wallet.get_address(AddressIndex::New).address;
         let tx = Transaction {
             version: 1,
-            lock_time: PackedLockTime(0),
+            lock_time: absolute::LockTime::ZERO,
             input: vec![],
             output: vec![TxOut {
                 value: 500_000,
index 68dc464509fb0d8e1bcc363fe4e4f06004e27982..68b2ecb154a08d017fca2cbfd1145d9b8e08f8cc 100644 (file)
@@ -19,7 +19,7 @@
 //! # use core::str::FromStr;
 //! # use bitcoin::secp256k1::{Secp256k1, All};
 //! # use bitcoin::*;
-//! # use bitcoin::util::psbt;
+//! # use bitcoin::psbt;
 //! # use bdk::signer::*;
 //! # use bdk::*;
 //! # #[derive(Debug)]
@@ -86,18 +86,17 @@ use core::cmp::Ordering;
 use core::fmt;
 use core::ops::{Bound::Included, Deref};
 
-use bitcoin::blockdata::opcodes;
-use bitcoin::blockdata::script::Builder as ScriptBuilder;
-use bitcoin::hashes::{hash160, Hash};
+use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, Fingerprint};
+use bitcoin::hashes::hash160;
 use bitcoin::secp256k1::Message;
-use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, Fingerprint};
-use bitcoin::util::{ecdsa, psbt, schnorr, sighash, taproot};
-use bitcoin::{secp256k1, XOnlyPublicKey};
-use bitcoin::{EcdsaSighashType, PrivateKey, PublicKey, SchnorrSighashType, Script};
+use bitcoin::sighash::{EcdsaSighashType, TapSighash, TapSighashType};
+use bitcoin::{ecdsa, psbt, sighash, taproot};
+use bitcoin::{key::TapTweak, key::XOnlyPublicKey, secp256k1};
+use bitcoin::{PrivateKey, PublicKey};
 
 use miniscript::descriptor::{
-    Descriptor, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, KeyMap, SinglePriv,
-    SinglePubKey,
+    Descriptor, DescriptorMultiXKey, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey,
+    InnerXKey, KeyMap, SinglePriv, SinglePubKey,
 };
 use miniscript::{Legacy, Segwitv0, SigType, Tap, ToPublicKey};
 
@@ -130,7 +129,7 @@ impl From<Fingerprint> for SignerId {
 }
 
 /// Signing error
-#[derive(Debug, PartialEq, Eq, Clone)]
+#[derive(Debug)]
 pub enum SignerError {
     /// The private key is missing for the required public key
     MissingKey,
@@ -383,6 +382,48 @@ impl InputSigner for SignerWrapper<DescriptorXKey<ExtendedPrivKey>> {
     }
 }
 
+fn multikey_to_xkeys<K: InnerXKey + Clone>(
+    multikey: DescriptorMultiXKey<K>,
+) -> Vec<DescriptorXKey<K>> {
+    multikey
+        .derivation_paths
+        .into_paths()
+        .into_iter()
+        .map(|derivation_path| DescriptorXKey {
+            origin: multikey.origin.clone(),
+            xkey: multikey.xkey.clone(),
+            derivation_path,
+            wildcard: multikey.wildcard,
+        })
+        .collect()
+}
+
+impl SignerCommon for SignerWrapper<DescriptorMultiXKey<ExtendedPrivKey>> {
+    fn id(&self, secp: &SecpCtx) -> SignerId {
+        SignerId::from(self.root_fingerprint(secp))
+    }
+
+    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
+        Some(DescriptorSecretKey::MultiXPrv(self.signer.clone()))
+    }
+}
+
+impl InputSigner for SignerWrapper<DescriptorMultiXKey<ExtendedPrivKey>> {
+    fn sign_input(
+        &self,
+        psbt: &mut psbt::PartiallySignedTransaction,
+        input_index: usize,
+        sign_options: &SignOptions,
+        secp: &SecpCtx,
+    ) -> Result<(), SignerError> {
+        let xkeys = multikey_to_xkeys(self.signer.clone());
+        for xkey in xkeys {
+            SignerWrapper::new(xkey, self.ctx).sign_input(psbt, input_index, sign_options, secp)?
+        }
+        Ok(())
+    }
+}
+
 impl SignerCommon for SignerWrapper<PrivateKey> {
     fn id(&self, secp: &SecpCtx) -> SignerId {
         SignerId::from(self.public_key(secp).to_pubkeyhash(SigType::Ecdsa))
@@ -477,8 +518,16 @@ impl InputSigner for SignerWrapper<PrivateKey> {
         }
 
         let (hash, hash_ty) = match self.ctx {
-            SignerContext::Segwitv0 => Segwitv0::sighash(psbt, input_index, ())?,
-            SignerContext::Legacy => Legacy::sighash(psbt, input_index, ())?,
+            SignerContext::Segwitv0 => {
+                let (h, t) = Segwitv0::sighash(psbt, input_index, ())?;
+                let h = h.to_raw_hash();
+                (h, t)
+            }
+            SignerContext::Legacy => {
+                let (h, t) = Legacy::sighash(psbt, input_index, ())?;
+                let h = h.to_raw_hash();
+                (h, t)
+            }
             _ => return Ok(()), // handled above
         };
         sign_psbt_ecdsa(
@@ -499,12 +548,12 @@ fn sign_psbt_ecdsa(
     secret_key: &secp256k1::SecretKey,
     pubkey: PublicKey,
     psbt_input: &mut psbt::Input,
-    hash: bitcoin::Sighash,
+    hash: impl bitcoin::hashes::Hash + bitcoin::secp256k1::ThirtyTwoByteHash,
     hash_ty: EcdsaSighashType,
     secp: &SecpCtx,
     allow_grinding: bool,
 ) {
-    let msg = &Message::from_slice(&hash.into_inner()[..]).unwrap();
+    let msg = &Message::from(hash);
     let sig = if allow_grinding {
         secp.sign_ecdsa_low_r(msg, secret_key)
     } else {
@@ -513,7 +562,7 @@ fn sign_psbt_ecdsa(
     secp.verify_ecdsa(msg, &sig, &pubkey.inner)
         .expect("invalid or corrupted ecdsa signature");
 
-    let final_signature = ecdsa::EcdsaSig { sig, hash_ty };
+    let final_signature = ecdsa::Signature { sig, hash_ty };
     psbt_input.partial_sigs.insert(pubkey, final_signature);
 }
 
@@ -523,12 +572,10 @@ fn sign_psbt_schnorr(
     pubkey: XOnlyPublicKey,
     leaf_hash: Option<taproot::TapLeafHash>,
     psbt_input: &mut psbt::Input,
-    hash: taproot::TapSighashHash,
-    hash_ty: SchnorrSighashType,
+    hash: TapSighash,
+    hash_ty: TapSighashType,
     secp: &SecpCtx,
 ) {
-    use schnorr::TapTweak;
-
     let keypair = secp256k1::KeyPair::from_seckey_slice(secp, secret_key.as_ref()).unwrap();
     let keypair = match leaf_hash {
         None => keypair
@@ -537,12 +584,12 @@ fn sign_psbt_schnorr(
         Some(_) => keypair, // no tweak for script spend
     };
 
-    let msg = &Message::from_slice(&hash.into_inner()[..]).unwrap();
+    let msg = &Message::from(hash);
     let sig = secp.sign_schnorr(msg, &keypair);
     secp.verify_schnorr(&sig, msg, &XOnlyPublicKey::from_keypair(&keypair).0)
         .expect("invalid or corrupted schnorr signature");
 
-    let final_signature = schnorr::SchnorrSig { sig, hash_ty };
+    let final_signature = taproot::Signature { sig, hash_ty };
 
     if let Some(lh) = leaf_hash {
         psbt_input
@@ -632,6 +679,11 @@ impl SignersContainer {
                     SignerOrdering::default(),
                     Arc::new(SignerWrapper::new(xprv, ctx)),
                 ),
+                DescriptorSecretKey::MultiXPrv(xprv) => container.add_external(
+                    SignerId::from(xprv.root_fingerprint(secp)),
+                    SignerOrdering::default(),
+                    Arc::new(SignerWrapper::new(xprv, ctx)),
+                ),
             };
         }
 
@@ -802,7 +854,7 @@ pub(crate) trait ComputeSighash {
 
 impl ComputeSighash for Legacy {
     type Extra = ();
-    type Sighash = bitcoin::Sighash;
+    type Sighash = sighash::LegacySighash;
     type SighashType = EcdsaSighashType;
 
     fn sighash(
@@ -849,19 +901,9 @@ impl ComputeSighash for Legacy {
     }
 }
 
-fn p2wpkh_script_code(script: &Script) -> Script {
-    ScriptBuilder::new()
-        .push_opcode(opcodes::all::OP_DUP)
-        .push_opcode(opcodes::all::OP_HASH160)
-        .push_slice(&script[2..])
-        .push_opcode(opcodes::all::OP_EQUALVERIFY)
-        .push_opcode(opcodes::all::OP_CHECKSIG)
-        .into_script()
-}
-
 impl ComputeSighash for Segwitv0 {
     type Extra = ();
-    type Sighash = bitcoin::Sighash;
+    type Sighash = sighash::SegwitV0Sighash;
     type SighashType = EcdsaSighashType;
 
     fn sighash(
@@ -908,14 +950,21 @@ impl ComputeSighash for Segwitv0 {
             Some(ref witness_script) => witness_script.clone(),
             None => {
                 if utxo.script_pubkey.is_v0_p2wpkh() {
-                    p2wpkh_script_code(&utxo.script_pubkey)
+                    utxo.script_pubkey
+                        .p2wpkh_script_code()
+                        .expect("We check above that the spk is a p2wpkh")
                 } else if psbt_input
                     .redeem_script
                     .as_ref()
-                    .map(Script::is_v0_p2wpkh)
+                    .map(|s| s.is_v0_p2wpkh())
                     .unwrap_or(false)
                 {
-                    p2wpkh_script_code(psbt_input.redeem_script.as_ref().unwrap())
+                    psbt_input
+                        .redeem_script
+                        .as_ref()
+                        .unwrap()
+                        .p2wpkh_script_code()
+                        .expect("We check above that the spk is a p2wpkh")
                 } else {
                     return Err(SignerError::MissingWitnessScript);
                 }
@@ -936,14 +985,14 @@ impl ComputeSighash for Segwitv0 {
 
 impl ComputeSighash for Tap {
     type Extra = Option<taproot::TapLeafHash>;
-    type Sighash = taproot::TapSighashHash;
-    type SighashType = SchnorrSighashType;
+    type Sighash = TapSighash;
+    type SighashType = TapSighashType;
 
     fn sighash(
         psbt: &psbt::PartiallySignedTransaction,
         input_index: usize,
         extra: Self::Extra,
-    ) -> Result<(Self::Sighash, SchnorrSighashType), SignerError> {
+    ) -> Result<(Self::Sighash, TapSighashType), SignerError> {
         if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
             return Err(SignerError::InputIndexOutOfRange);
         }
@@ -952,8 +1001,8 @@ impl ComputeSighash for Tap {
 
         let sighash_type = psbt_input
             .sighash_type
-            .unwrap_or_else(|| SchnorrSighashType::Default.into())
-            .schnorr_hash_ty()
+            .unwrap_or_else(|| TapSighashType::Default.into())
+            .taproot_hash_ty()
             .map_err(|_| SignerError::InvalidSighash)?;
         let witness_utxos = (0..psbt.inputs.len())
             .map(|i| psbt.get_utxo_for(i))
@@ -1015,8 +1064,8 @@ mod signers_container_tests {
     use crate::descriptor::IntoWalletDescriptor;
     use crate::keys::{DescriptorKey, IntoDescriptorKey};
     use assert_matches::assert_matches;
+    use bitcoin::bip32;
     use bitcoin::secp256k1::{All, Secp256k1};
-    use bitcoin::util::bip32;
     use bitcoin::Network;
     use core::str::FromStr;
     use miniscript::ScriptContext;
index 165f01f25f1cbb53da1858d7d93a1ac2125958f3..d7bcd711328976133143050b612985351a14bc4a 100644 (file)
@@ -18,7 +18,7 @@
 //! # use bitcoin::*;
 //! # use bdk::*;
 //! # use bdk::wallet::tx_builder::CreateTx;
-//! # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+//! # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
 //! # let mut wallet = doctest_wallet!();
 //! // create a TxBuilder from a wallet
 //! let mut tx_builder = wallet.build_tx();
@@ -27,7 +27,7 @@
 //!     // Create a transaction with one output to `to_address` of 50_000 satoshi
 //!     .add_recipient(to_address.script_pubkey(), 50_000)
 //!     // With a custom fee rate of 5.0 satoshi/vbyte
-//!     .fee_rate(FeeRate::from_sat_per_vb(5.0))
+//!     .fee_rate(bdk::FeeRate::from_sat_per_vb(5.0))
 //!     // Only spend non-change outputs
 //!     .do_not_spend_change()
 //!     // Turn on RBF signaling
@@ -43,8 +43,8 @@ use bdk_chain::PersistBackend;
 use core::cell::RefCell;
 use core::marker::PhantomData;
 
-use bitcoin::util::psbt::{self, PartiallySignedTransaction as Psbt};
-use bitcoin::{LockTime, OutPoint, Script, Sequence, Transaction};
+use bitcoin::psbt::{self, PartiallySignedTransaction as Psbt};
+use bitcoin::{absolute, script::PushBytes, OutPoint, ScriptBuf, Sequence, Transaction};
 
 use super::coin_selection::{CoinSelectionAlgorithm, DefaultCoinSelectionAlgorithm};
 use super::ChangeSet;
@@ -82,7 +82,7 @@ impl TxBuilderContext for BumpFee {}
 /// # use bitcoin::*;
 /// # use core::str::FromStr;
 /// # let mut wallet = doctest_wallet!();
-/// # let addr1 = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+/// # let addr1 = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
 /// # let addr2 = addr1.clone();
 /// // chaining
 /// let (psbt1, details) = {
@@ -129,9 +129,9 @@ pub struct TxBuilder<'a, D, Cs, Ctx> {
 //TODO: TxParams should eventually be exposed publicly.
 #[derive(Default, Debug, Clone)]
 pub(crate) struct TxParams {
-    pub(crate) recipients: Vec<(Script, u64)>,
+    pub(crate) recipients: Vec<(ScriptBuf, u64)>,
     pub(crate) drain_wallet: bool,
-    pub(crate) drain_to: Option<Script>,
+    pub(crate) drain_to: Option<ScriptBuf>,
     pub(crate) fee_policy: Option<FeePolicy>,
     pub(crate) internal_policy_path: Option<BTreeMap<String, Vec<usize>>>,
     pub(crate) external_policy_path: Option<BTreeMap<String, Vec<usize>>>,
@@ -140,7 +140,7 @@ pub(crate) struct TxParams {
     pub(crate) manually_selected_only: bool,
     pub(crate) sighash: Option<psbt::PsbtSighashType>,
     pub(crate) ordering: TxOrdering,
-    pub(crate) locktime: Option<LockTime>,
+    pub(crate) locktime: Option<absolute::LockTime>,
     pub(crate) rbf: Option<RbfValue>,
     pub(crate) version: Option<Version>,
     pub(crate) change_policy: ChangeSpendPolicy,
@@ -148,7 +148,7 @@ pub(crate) struct TxParams {
     pub(crate) add_global_xpubs: bool,
     pub(crate) include_output_redeem_witness_script: bool,
     pub(crate) bumping_fee: Option<PreviousFee>,
-    pub(crate) current_height: Option<LockTime>,
+    pub(crate) current_height: Option<absolute::LockTime>,
     pub(crate) allow_dust: bool,
 }
 
@@ -245,7 +245,10 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
     /// # use std::collections::BTreeMap;
     /// # use bitcoin::*;
     /// # use bdk::*;
-    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    /// # let to_address =
+    /// Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
+    ///     .unwrap()
+    ///     .assume_checked();
     /// # let mut wallet = doctest_wallet!();
     /// let mut path = BTreeMap::new();
     /// path.insert("aabbccdd".to_string(), vec![0, 1]);
@@ -287,6 +290,7 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
 
             for utxo in utxos {
                 let descriptor = wallet.get_descriptor_for_keychain(utxo.keychain);
+                #[allow(deprecated)]
                 let satisfaction_weight = descriptor.max_satisfaction_weight().unwrap();
                 self.params.utxos.push(WeightedUtxo {
                     satisfaction_weight,
@@ -431,7 +435,7 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
     /// Use a specific nLockTime while creating the transaction
     ///
     /// This can cause conflicts if the wallet's descriptors contain an "after" (OP_CLTV) operator.
-    pub fn nlocktime(&mut self, locktime: LockTime) -> &mut Self {
+    pub fn nlocktime(&mut self, locktime: absolute::LockTime) -> &mut Self {
         self.params.locktime = Some(locktime);
         self
     }
@@ -470,7 +474,7 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
         self
     }
 
-    /// Only Fill-in the [`psbt::Input::witness_utxo`](bitcoin::util::psbt::Input::witness_utxo) field when spending from
+    /// Only Fill-in the [`psbt::Input::witness_utxo`](bitcoin::psbt::Input::witness_utxo) field when spending from
     /// SegWit descriptors.
     ///
     /// This reduces the size of the PSBT, but some signers might reject them due to the lack of
@@ -480,8 +484,8 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
         self
     }
 
-    /// Fill-in the [`psbt::Output::redeem_script`](bitcoin::util::psbt::Output::redeem_script) and
-    /// [`psbt::Output::witness_script`](bitcoin::util::psbt::Output::witness_script) fields.
+    /// Fill-in the [`psbt::Output::redeem_script`](bitcoin::psbt::Output::redeem_script) and
+    /// [`psbt::Output::witness_script`](bitcoin::psbt::Output::witness_script) fields.
     ///
     /// This is useful for signers which always require it, like ColdCard hardware wallets.
     pub fn include_output_redeem_witness_script(&mut self) -> &mut Self {
@@ -568,7 +572,8 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
     ///
     /// In both cases, if you don't provide a current height, we use the last sync height.
     pub fn current_height(&mut self, height: u32) -> &mut Self {
-        self.params.current_height = Some(LockTime::from_height(height).expect("Invalid height"));
+        self.params.current_height =
+            Some(absolute::LockTime::from_height(height).expect("Invalid height"));
         self
     }
 
@@ -583,20 +588,20 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
 
 impl<'a, D, Cs: CoinSelectionAlgorithm> TxBuilder<'a, D, Cs, CreateTx> {
     /// Replace the recipients already added with a new list
-    pub fn set_recipients(&mut self, recipients: Vec<(Script, u64)>) -> &mut Self {
+    pub fn set_recipients(&mut self, recipients: Vec<(ScriptBuf, u64)>) -> &mut Self {
         self.params.recipients = recipients;
         self
     }
 
     /// Add a recipient to the internal list
-    pub fn add_recipient(&mut self, script_pubkey: Script, amount: u64) -> &mut Self {
+    pub fn add_recipient(&mut self, script_pubkey: ScriptBuf, amount: u64) -> &mut Self {
         self.params.recipients.push((script_pubkey, amount));
         self
     }
 
     /// Add data as an output, using OP_RETURN
-    pub fn add_data(&mut self, data: &[u8]) -> &mut Self {
-        let script = Script::new_op_return(data);
+    pub fn add_data<T: AsRef<PushBytes>>(&mut self, data: &T) -> &mut Self {
+        let script = ScriptBuf::new_op_return(data);
         self.add_recipient(script, 0u64);
         self
     }
@@ -626,7 +631,10 @@ impl<'a, D, Cs: CoinSelectionAlgorithm> TxBuilder<'a, D, Cs, CreateTx> {
     /// # use bitcoin::*;
     /// # use bdk::*;
     /// # use bdk::wallet::tx_builder::CreateTx;
-    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    /// # let to_address =
+    /// Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
+    ///     .unwrap()
+    ///     .assume_checked();
     /// # let mut wallet = doctest_wallet!();
     /// let mut tx_builder = wallet.build_tx();
     ///
@@ -635,7 +643,7 @@ impl<'a, D, Cs: CoinSelectionAlgorithm> TxBuilder<'a, D, Cs, CreateTx> {
     ///     .drain_wallet()
     ///     // Send the excess (which is all the coins minus the fee) to this address.
     ///     .drain_to(to_address.script_pubkey())
-    ///     .fee_rate(FeeRate::from_sat_per_vb(5.0))
+    ///     .fee_rate(bdk::FeeRate::from_sat_per_vb(5.0))
     ///     .enable_rbf();
     /// let (psbt, tx_details) = tx_builder.finish()?;
     /// # Ok::<(), bdk::Error>(())
@@ -645,7 +653,7 @@ impl<'a, D, Cs: CoinSelectionAlgorithm> TxBuilder<'a, D, Cs, CreateTx> {
     /// [`add_recipient`]: Self::add_recipient
     /// [`add_utxos`]: Self::add_utxos
     /// [`drain_wallet`]: Self::drain_wallet
-    pub fn drain_to(&mut self, script_pubkey: Script) -> &mut Self {
+    pub fn drain_to(&mut self, script_pubkey: ScriptBuf) -> &mut Self {
         self.params.drain_to = Some(script_pubkey);
         self
     }
@@ -663,7 +671,7 @@ impl<'a, D> TxBuilder<'a, D, DefaultCoinSelectionAlgorithm, BumpFee> {
     ///
     /// Returns an `Err` if `script_pubkey` can't be found among the recipients of the
     /// transaction we are bumping.
-    pub fn allow_shrinking(&mut self, script_pubkey: Script) -> Result<&mut Self, Error> {
+    pub fn allow_shrinking(&mut self, script_pubkey: ScriptBuf) -> Result<&mut Self, Error> {
         match self
             .params
             .recipients
@@ -868,8 +876,11 @@ mod test {
         );
 
         assert_eq!(tx.output[0].value, 800);
-        assert_eq!(tx.output[1].script_pubkey, From::from(vec![0xAA]));
-        assert_eq!(tx.output[2].script_pubkey, From::from(vec![0xAA, 0xEE]));
+        assert_eq!(tx.output[1].script_pubkey, ScriptBuf::from(vec![0xAA]));
+        assert_eq!(
+            tx.output[2].script_pubkey,
+            ScriptBuf::from(vec![0xAA, 0xEE])
+        );
     }
 
     fn get_test_utxos() -> Vec<LocalUtxo> {
@@ -878,7 +889,7 @@ mod test {
         vec![
             LocalUtxo {
                 outpoint: OutPoint {
-                    txid: bitcoin::Txid::from_inner([0; 32]),
+                    txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(),
                     vout: 0,
                 },
                 txout: Default::default(),
@@ -889,7 +900,7 @@ mod test {
             },
             LocalUtxo {
                 outpoint: OutPoint {
-                    txid: bitcoin::Txid::from_inner([0; 32]),
+                    txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(),
                     vout: 1,
                 },
                 txout: Default::default(),
index 86f7d2fe42bb23999ebaad4c0c5e178ac0186a24..71e24950bcf285c3ddc1b5c22ccfc14b7b36af59 100644 (file)
@@ -10,7 +10,7 @@
 // licenses.
 
 use bitcoin::secp256k1::{All, Secp256k1};
-use bitcoin::{LockTime, Script, Sequence};
+use bitcoin::{absolute, Script, Sequence};
 
 use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};
 
@@ -65,7 +65,7 @@ pub(crate) fn check_nsequence_rbf(rbf: Sequence, csv: Sequence) -> bool {
 }
 
 impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for After {
-    fn check_after(&self, n: LockTime) -> bool {
+    fn check_after(&self, n: absolute::LockTime) -> bool {
         if let Some(current_height) = self.current_height {
             current_height >= n.to_consensus_u32()
         } else {
@@ -119,12 +119,14 @@ mod test {
     pub(crate) const SEQUENCE_LOCKTIME_TYPE_FLAG: u32 = 1 << 22;
 
     use super::{check_nsequence_rbf, IsDust};
-    use crate::bitcoin::{Address, Sequence};
+    use crate::bitcoin::{Address, Network, Sequence};
     use core::str::FromStr;
 
     #[test]
     fn test_is_dust() {
         let script_p2pkh = Address::from_str("1GNgwA8JfG7Kc8akJ8opdNWJUihqUztfPe")
+            .unwrap()
+            .require_network(Network::Bitcoin)
             .unwrap()
             .script_pubkey();
         assert!(script_p2pkh.is_p2pkh());
@@ -132,6 +134,8 @@ mod test {
         assert!(!546.is_dust(&script_p2pkh));
 
         let script_p2wpkh = Address::from_str("bc1qxlh2mnc0yqwas76gqq665qkggee5m98t8yskd8")
+            .unwrap()
+            .require_network(Network::Bitcoin)
             .unwrap()
             .script_pubkey();
         assert!(script_p2wpkh.is_v0_p2wpkh());
index de94670321465d8372dd3557cb1ad63f5e6981eb..002724d7f9a11ec55247566c87175824b72ab17d 100644 (file)
@@ -14,7 +14,7 @@ pub fn get_funded_wallet_with_change(
 
     let tx = Transaction {
         version: 1,
-        lock_time: bitcoin::PackedLockTime(0),
+        lock_time: bitcoin::absolute::LockTime::ZERO,
         input: vec![],
         output: vec![TxOut {
             value: 50_000,
index 8d399f5feab42618ea49d210ca7bb82c707af671..22e34f9def3b9c81ba7d096a8edbcf82f1599a1f 100644 (file)
@@ -2,7 +2,7 @@ use bdk::bitcoin::TxIn;
 use bdk::wallet::AddressIndex;
 use bdk::wallet::AddressIndex::New;
 use bdk::{psbt, FeeRate, SignOptions};
-use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
+use bitcoin::psbt::PartiallySignedTransaction as Psbt;
 use core::str::FromStr;
 mod common;
 use common::*;
index e8ded3146eafdc8fb1ab572c72a4c1a49a6ea2f4..396b727e584ee0f466ec2cf5db64ce8149ecce06 100644 (file)
@@ -11,13 +11,14 @@ use bdk_chain::BlockId;
 use bdk_chain::ConfirmationTime;
 use bdk_chain::COINBASE_MATURITY;
 use bitcoin::hashes::Hash;
+use bitcoin::sighash::{EcdsaSighashType, TapSighashType};
 use bitcoin::BlockHash;
-use bitcoin::Script;
-use bitcoin::{util::psbt, Network};
+use bitcoin::ScriptBuf;
 use bitcoin::{
-    Address, EcdsaSighashType, LockTime, OutPoint, PackedLockTime, SchnorrSighashType, Sequence,
-    Transaction, TxIn, TxOut,
+    absolute, script::PushBytesBuf, taproot::TapNodeHash, Address, OutPoint, Sequence, Transaction,
+    TxIn, TxOut, Weight,
 };
+use bitcoin::{psbt, Network};
 use core::str::FromStr;
 
 mod common;
@@ -26,7 +27,7 @@ use common::*;
 fn receive_output(wallet: &mut Wallet, value: u64, height: ConfirmationTime) -> OutPoint {
     let tx = Transaction {
         version: 1,
-        lock_time: PackedLockTime(0),
+        lock_time: absolute::LockTime::ZERO,
         input: vec![],
         output: vec![TxOut {
             script_pubkey: wallet.get_address(LastUnused).script_pubkey(),
@@ -210,7 +211,7 @@ fn test_create_tx_default_locktime_is_last_sync_height() {
 
     // Since we never synced the wallet we don't have a last_sync_height
     // we could use to try to prevent fee sniping. We default to 0.
-    assert_eq!(psbt.unsigned_tx.lock_time.0, 1_000);
+    assert_eq!(psbt.unsigned_tx.lock_time.to_consensus_u32(), 1_000);
 }
 
 #[test]
@@ -224,7 +225,7 @@ fn test_create_tx_fee_sniping_locktime_last_sync() {
 
     // If there's no current_height we're left with using the last sync height
     assert_eq!(
-        psbt.unsigned_tx.lock_time.0,
+        psbt.unsigned_tx.lock_time.to_consensus_u32(),
         wallet.latest_checkpoint().unwrap().height()
     );
 }
@@ -237,7 +238,7 @@ fn test_create_tx_default_locktime_cltv() {
     builder.add_recipient(addr.script_pubkey(), 25_000);
     let (psbt, _) = builder.finish().unwrap();
 
-    assert_eq!(psbt.unsigned_tx.lock_time.0, 100_000);
+    assert_eq!(psbt.unsigned_tx.lock_time.to_consensus_u32(), 100_000);
 }
 
 #[test]
@@ -248,13 +249,13 @@ fn test_create_tx_custom_locktime() {
     builder
         .add_recipient(addr.script_pubkey(), 25_000)
         .current_height(630_001)
-        .nlocktime(LockTime::from_height(630_000).unwrap());
+        .nlocktime(absolute::LockTime::from_height(630_000).unwrap());
     let (psbt, _) = builder.finish().unwrap();
 
     // When we explicitly specify a nlocktime
     // we don't try any fee sniping prevention trick
     // (we ignore the current_height)
-    assert_eq!(psbt.unsigned_tx.lock_time.0, 630_000);
+    assert_eq!(psbt.unsigned_tx.lock_time.to_consensus_u32(), 630_000);
 }
 
 #[test]
@@ -264,10 +265,10 @@ fn test_create_tx_custom_locktime_compatible_with_cltv() {
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 25_000)
-        .nlocktime(LockTime::from_height(630_000).unwrap());
+        .nlocktime(absolute::LockTime::from_height(630_000).unwrap());
     let (psbt, _) = builder.finish().unwrap();
 
-    assert_eq!(psbt.unsigned_tx.lock_time.0, 630_000);
+    assert_eq!(psbt.unsigned_tx.lock_time.to_consensus_u32(), 630_000);
 }
 
 #[test]
@@ -280,7 +281,7 @@ fn test_create_tx_custom_locktime_incompatible_with_cltv() {
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 25_000)
-        .nlocktime(LockTime::from_height(50000).unwrap());
+        .nlocktime(absolute::LockTime::from_height(50000).unwrap());
     builder.finish().unwrap();
 }
 
@@ -402,7 +403,9 @@ fn test_create_tx_drain_wallet_and_drain_to() {
 #[test]
 fn test_create_tx_drain_wallet_and_drain_to_and_with_recipient() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
-    let addr = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    let addr = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
+        .unwrap()
+        .assume_checked();
     let drain_addr = wallet.get_address(New);
     let mut builder = wallet.build_tx();
     builder
@@ -614,18 +617,18 @@ fn test_create_tx_custom_sighash() {
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 30_000)
-        .sighash(bitcoin::EcdsaSighashType::Single.into());
+        .sighash(EcdsaSighashType::Single.into());
     let (psbt, _) = builder.finish().unwrap();
 
     assert_eq!(
         psbt.inputs[0].sighash_type,
-        Some(bitcoin::EcdsaSighashType::Single.into())
+        Some(EcdsaSighashType::Single.into())
     );
 }
 
 #[test]
 fn test_create_tx_input_hd_keypaths() {
-    use bitcoin::util::bip32::{DerivationPath, Fingerprint};
+    use bitcoin::bip32::{DerivationPath, Fingerprint};
     use core::str::FromStr;
 
     let (mut wallet, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
@@ -646,7 +649,7 @@ fn test_create_tx_input_hd_keypaths() {
 
 #[test]
 fn test_create_tx_output_hd_keypaths() {
-    use bitcoin::util::bip32::{DerivationPath, Fingerprint};
+    use bitcoin::bip32::{DerivationPath, Fingerprint};
     use core::str::FromStr;
 
     let (mut wallet, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
@@ -680,7 +683,7 @@ fn test_create_tx_set_redeem_script_p2sh() {
 
     assert_eq!(
         psbt.inputs[0].redeem_script,
-        Some(Script::from(
+        Some(ScriptBuf::from(
             Vec::<u8>::from_hex(
                 "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac"
             )
@@ -704,7 +707,7 @@ fn test_create_tx_set_witness_script_p2wsh() {
     assert_eq!(psbt.inputs[0].redeem_script, None);
     assert_eq!(
         psbt.inputs[0].witness_script,
-        Some(Script::from(
+        Some(ScriptBuf::from(
             Vec::<u8>::from_hex(
                 "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac"
             )
@@ -715,8 +718,6 @@ fn test_create_tx_set_witness_script_p2wsh() {
 
 #[test]
 fn test_create_tx_set_redeem_witness_script_p2wsh_p2sh() {
-    use bitcoin::hashes::hex::FromHex;
-
     let (mut wallet, _) =
         get_funded_wallet("sh(wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)))");
     let addr = wallet.get_address(New);
@@ -724,12 +725,10 @@ fn test_create_tx_set_redeem_witness_script_p2wsh_p2sh() {
     builder.drain_to(addr.script_pubkey()).drain_wallet();
     let (psbt, _) = builder.finish().unwrap();
 
-    let script = Script::from(
-        Vec::<u8>::from_hex(
-            "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac",
-        )
-        .unwrap(),
-    );
+    let script = ScriptBuf::from_hex(
+        "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac",
+    )
+    .unwrap();
 
     assert_eq!(psbt.inputs[0].redeem_script, Some(script.to_v0_p2wsh()));
     assert_eq!(psbt.inputs[0].witness_script, Some(script));
@@ -799,7 +798,7 @@ fn test_create_tx_add_utxo() {
             script_pubkey: wallet.get_address(New).address.script_pubkey(),
         }],
         version: 0,
-        lock_time: PackedLockTime(0),
+        lock_time: absolute::LockTime::ZERO,
     };
     wallet
         .insert_tx(
@@ -808,7 +807,9 @@ fn test_create_tx_add_utxo() {
         )
         .unwrap();
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 30_000)
@@ -838,7 +839,7 @@ fn test_create_tx_manually_selected_insufficient() {
             script_pubkey: wallet.get_address(New).address.script_pubkey(),
         }],
         version: 0,
-        lock_time: PackedLockTime(0),
+        lock_time: absolute::LockTime::ZERO,
     };
 
     wallet
@@ -848,7 +849,9 @@ fn test_create_tx_manually_selected_insufficient() {
         )
         .unwrap();
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 30_000)
@@ -866,7 +869,9 @@ fn test_create_tx_manually_selected_insufficient() {
 fn test_create_tx_policy_path_required() {
     let (mut wallet, _) = get_funded_wallet(get_test_a_or_b_plus_csv());
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder.add_recipient(addr.script_pubkey(), 30_000);
     builder.finish().unwrap();
@@ -879,7 +884,7 @@ fn test_create_tx_policy_path_no_csv() {
 
     let tx = Transaction {
         version: 0,
-        lock_time: PackedLockTime(0),
+        lock_time: absolute::LockTime::ZERO,
         input: vec![],
         output: vec![TxOut {
             value: 50_000,
@@ -895,7 +900,9 @@ fn test_create_tx_policy_path_no_csv() {
     // child #0 is just the key "A"
     let path = vec![(root_id, vec![0])].into_iter().collect();
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 30_000)
@@ -914,7 +921,9 @@ fn test_create_tx_policy_path_use_csv() {
     // child #1 is or(pk(B),older(144))
     let path = vec![(root_id, vec![1])].into_iter().collect();
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 30_000)
@@ -933,7 +942,9 @@ fn test_create_tx_policy_path_ignored_subtree_with_csv() {
     // child #0 is pk(cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu)
     let path = vec![(root_id, vec![0])].into_iter().collect();
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 30_000)
@@ -945,8 +956,8 @@ fn test_create_tx_policy_path_ignored_subtree_with_csv() {
 
 #[test]
 fn test_create_tx_global_xpubs_with_origin() {
+    use bitcoin::bip32;
     use bitcoin::hashes::hex::FromHex;
-    use bitcoin::util::bip32;
 
     let (mut wallet, _) = get_funded_wallet("wpkh([73756c7f/48'/0'/0'/2']tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
     let addr = wallet.get_address(New);
@@ -970,8 +981,11 @@ fn test_add_foreign_utxo() {
     let (wallet2, _) =
         get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let utxo = wallet2.list_unspent().next().expect("must take!");
+    #[allow(deprecated)]
     let foreign_utxo_satisfaction = wallet2
         .get_descriptor_for_keychain(KeychainKind::External)
         .max_satisfaction_weight()
@@ -1036,6 +1050,7 @@ fn test_add_foreign_utxo() {
 fn test_add_foreign_utxo_invalid_psbt_input() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
     let outpoint = wallet.list_unspent().next().expect("must exist").outpoint;
+    #[allow(deprecated)]
     let foreign_utxo_satisfaction = wallet
         .get_descriptor_for_keychain(KeychainKind::External)
         .max_satisfaction_weight()
@@ -1057,6 +1072,7 @@ fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
     let tx1 = wallet1.get_tx(txid1, true).unwrap().transaction.unwrap();
     let tx2 = wallet2.get_tx(txid2, true).unwrap().transaction.unwrap();
 
+    #[allow(deprecated)]
     let satisfaction_weight = wallet2
         .get_descriptor_for_keychain(KeychainKind::External)
         .max_satisfaction_weight()
@@ -1096,9 +1112,12 @@ fn test_add_foreign_utxo_only_witness_utxo() {
     let (mut wallet1, _) = get_funded_wallet(get_test_wpkh());
     let (wallet2, txid2) =
         get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let utxo2 = wallet2.list_unspent().next().unwrap();
 
+    #[allow(deprecated)]
     let satisfaction_weight = wallet2
         .get_descriptor_for_keychain(KeychainKind::External)
         .max_satisfaction_weight()
@@ -1181,8 +1200,8 @@ fn test_create_tx_global_xpubs_origin_missing() {
 
 #[test]
 fn test_create_tx_global_xpubs_master_without_origin() {
+    use bitcoin::bip32;
     use bitcoin::hashes::hex::FromHex;
-    use bitcoin::util::bip32;
 
     let (mut wallet, _) = get_funded_wallet("wpkh(tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL/0/*)");
     let addr = wallet.get_address(New);
@@ -1315,7 +1334,9 @@ fn test_bump_fee_zero_abs() {
 #[test]
 fn test_bump_fee_reduce_change() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 25_000)
@@ -1401,7 +1422,9 @@ fn test_bump_fee_reduce_change() {
 #[test]
 fn test_bump_fee_reduce_single_recipient() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .drain_to(addr.script_pubkey())
@@ -1434,7 +1457,9 @@ fn test_bump_fee_reduce_single_recipient() {
 #[test]
 fn test_bump_fee_absolute_reduce_single_recipient() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .drain_to(addr.script_pubkey())
@@ -1470,7 +1495,7 @@ fn test_bump_fee_drain_wallet() {
     // receive an extra tx so that our wallet has two utxos.
     let tx = Transaction {
         version: 1,
-        lock_time: PackedLockTime(0),
+        lock_time: absolute::LockTime::ZERO,
         input: vec![],
         output: vec![TxOut {
             value: 25_000,
@@ -1486,7 +1511,9 @@ fn test_bump_fee_drain_wallet() {
             },
         )
         .unwrap();
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
 
     let mut builder = wallet.build_tx();
     builder
@@ -1530,7 +1557,7 @@ fn test_bump_fee_remove_output_manually_selected_only() {
     // unless you've also set "allow_shrinking" OR there is a change output.
     let init_tx = Transaction {
         version: 1,
-        lock_time: PackedLockTime(0),
+        lock_time: absolute::LockTime::ZERO,
         input: vec![],
         output: vec![TxOut {
             script_pubkey: wallet.get_address(New).script_pubkey(),
@@ -1553,7 +1580,9 @@ fn test_bump_fee_remove_output_manually_selected_only() {
         txid: init_tx.txid(),
         vout: 0,
     };
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .drain_to(addr.script_pubkey())
@@ -1581,7 +1610,7 @@ fn test_bump_fee_add_input() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
     let init_tx = Transaction {
         version: 1,
-        lock_time: PackedLockTime(0),
+        lock_time: absolute::LockTime::ZERO,
         input: vec![],
         output: vec![TxOut {
             script_pubkey: wallet.get_address(New).script_pubkey(),
@@ -1597,7 +1626,9 @@ fn test_bump_fee_add_input() {
         .into();
     wallet.insert_tx(init_tx, pos).unwrap();
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx().coin_selection(LargestFirstCoinSelection);
     builder
         .add_recipient(addr.script_pubkey(), 45_000)
@@ -1643,7 +1674,9 @@ fn test_bump_fee_add_input() {
 fn test_bump_fee_absolute_add_input() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
     receive_output_in_latest_block(&mut wallet, 25_000);
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx().coin_selection(LargestFirstCoinSelection);
     builder
         .add_recipient(addr.script_pubkey(), 45_000)
@@ -1691,7 +1724,9 @@ fn test_bump_fee_no_change_add_input_and_change() {
     let op = receive_output_in_latest_block(&mut wallet, 25_000);
 
     // initially make a tx without change by using `drain_to`
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .drain_to(addr.script_pubkey())
@@ -1747,7 +1782,9 @@ fn test_bump_fee_no_change_add_input_and_change() {
 fn test_bump_fee_add_input_change_dust() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
     receive_output_in_latest_block(&mut wallet, 25_000);
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx().coin_selection(LargestFirstCoinSelection);
     builder
         .add_recipient(addr.script_pubkey(), 45_000)
@@ -1775,7 +1812,8 @@ fn test_bump_fee_add_input_change_dust() {
     // + extra input weight: 160 WU = (32 (prevout) + 4 (vout) + 4 (nsequence)) * 4
     // + input satisfaction weight: 112 WU = 106 (witness) + 2 (witness len) + (1 (script len)) * 4
     // - change output weight: 124 WU = (8 (value) + 1 (script len) + 22 (script)) * 4
-    let new_tx_weight = original_tx_weight + 160 + 112 - 124;
+    let new_tx_weight =
+        original_tx_weight + Weight::from_wu(160) + Weight::from_wu(112) - Weight::from_wu(124);
     // two inputs (50k, 25k) and one output (45k) - epsilon
     // We use epsilon here to avoid asking for a slightly too high feerate
     let fee_abs = 50_000 + 25_000 - 45_000 - 10;
@@ -1811,7 +1849,9 @@ fn test_bump_fee_force_add_input() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
     let incoming_op = receive_output_in_latest_block(&mut wallet, 25_000);
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx().coin_selection(LargestFirstCoinSelection);
     builder
         .add_recipient(addr.script_pubkey(), 45_000)
@@ -1865,7 +1905,9 @@ fn test_bump_fee_absolute_force_add_input() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
     let incoming_op = receive_output_in_latest_block(&mut wallet, 25_000);
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx().coin_selection(LargestFirstCoinSelection);
     builder
         .add_recipient(addr.script_pubkey(), 45_000)
@@ -1923,7 +1965,9 @@ fn test_bump_fee_unconfirmed_inputs_only() {
     // The replacement transaction may only include an unconfirmed input
     // if that input was included in one of the original transactions.
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .drain_wallet()
@@ -1958,7 +2002,9 @@ fn test_bump_fee_unconfirmed_input() {
     // always fee bump with an unconfirmed input if it was included in the
     // original transaction)
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     // We receive a tx with 0 confirmations, which will be used as an input
     // in the drain tx.
     receive_output(&mut wallet, 25_000, ConfirmationTime::unconfirmed(0));
@@ -1996,7 +2042,9 @@ fn test_fee_amount_negative_drain_val() {
     // for a transaction.
     // See https://github.com/bitcoindevkit/bdk/issues/660
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
-    let send_to = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt").unwrap();
+    let send_to = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")
+        .unwrap()
+        .assume_checked();
     let fee_rate = FeeRate::from_sat_per_vb(2.01);
     let incoming_op = receive_output_in_latest_block(&mut wallet, 8859);
 
@@ -2110,7 +2158,9 @@ fn test_sign_single_xprv_no_hd_keypaths() {
 #[test]
 fn test_include_output_redeem_witness_script() {
     let (mut wallet, _) = get_funded_wallet("sh(wsh(multi(1,cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW,cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu)))");
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 45_000)
@@ -2127,7 +2177,9 @@ fn test_include_output_redeem_witness_script() {
 #[test]
 fn test_signing_only_one_of_multiple_inputs() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), 45_000)
@@ -2135,7 +2187,7 @@ fn test_signing_only_one_of_multiple_inputs() {
     let (mut psbt, _) = builder.finish().unwrap();
 
     // add another input to the psbt that is at least passable.
-    let dud_input = bitcoin::util::psbt::Input {
+    let dud_input = bitcoin::psbt::Input {
         witness_utxo: Some(TxOut {
             value: 100_000,
             script_pubkey: miniscript::Descriptor::<bitcoin::PublicKey>::from_str(
@@ -2383,7 +2435,9 @@ fn test_returns_index_and_address() {
         wallet.get_address(New),
         AddressInfo {
             index: 0,
-            address: Address::from_str("tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a").unwrap(),
+            address: Address::from_str("tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a")
+                .unwrap()
+                .assume_checked(),
             keychain: KeychainKind::External,
         }
     );
@@ -2393,7 +2447,9 @@ fn test_returns_index_and_address() {
         wallet.get_address(New),
         AddressInfo {
             index: 1,
-            address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7").unwrap(),
+            address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7")
+                .unwrap()
+                .assume_checked(),
             keychain: KeychainKind::External,
         }
     );
@@ -2403,7 +2459,9 @@ fn test_returns_index_and_address() {
         wallet.get_address(Peek(25)),
         AddressInfo {
             index: 25,
-            address: Address::from_str("tb1qsp7qu0knx3sl6536dzs0703u2w2ag6ppl9d0c2").unwrap(),
+            address: Address::from_str("tb1qsp7qu0knx3sl6536dzs0703u2w2ag6ppl9d0c2")
+                .unwrap()
+                .assume_checked(),
             keychain: KeychainKind::External,
         }
     );
@@ -2413,7 +2471,9 @@ fn test_returns_index_and_address() {
         wallet.get_address(New),
         AddressInfo {
             index: 2,
-            address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2").unwrap(),
+            address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2")
+                .unwrap()
+                .assume_checked(),
             keychain: KeychainKind::External,
         }
     );
@@ -2423,7 +2483,8 @@ fn test_returns_index_and_address() {
 fn test_sending_to_bip350_bech32m_address() {
     let (mut wallet, _) = get_funded_wallet(get_test_wpkh());
     let addr = Address::from_str("tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c")
-        .unwrap();
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder.add_recipient(addr.script_pubkey(), 45_000);
     builder.finish().unwrap();
@@ -2432,7 +2493,7 @@ fn test_sending_to_bip350_bech32m_address() {
 #[test]
 fn test_get_address() {
     use bdk::descriptor::template::Bip84;
-    let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+    let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
     let mut wallet = Wallet::new_no_persist(
         Bip84(key, KeychainKind::External),
         Some(Bip84(key, KeychainKind::Internal)),
@@ -2444,7 +2505,9 @@ fn test_get_address() {
         wallet.get_address(AddressIndex::New),
         AddressInfo {
             index: 0,
-            address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w").unwrap(),
+            address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w")
+                .unwrap()
+                .assume_checked(),
             keychain: KeychainKind::External,
         }
     );
@@ -2453,7 +2516,9 @@ fn test_get_address() {
         wallet.get_internal_address(AddressIndex::New),
         AddressInfo {
             index: 0,
-            address: Address::from_str("bcrt1q0ue3s5y935tw7v3gmnh36c5zzsaw4n9c9smq79").unwrap(),
+            address: Address::from_str("bcrt1q0ue3s5y935tw7v3gmnh36c5zzsaw4n9c9smq79")
+                .unwrap()
+                .assume_checked(),
             keychain: KeychainKind::Internal,
         }
     );
@@ -2465,7 +2530,9 @@ fn test_get_address() {
         wallet.get_internal_address(AddressIndex::New),
         AddressInfo {
             index: 0,
-            address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w").unwrap(),
+            address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w")
+                .unwrap()
+                .assume_checked(),
             keychain: KeychainKind::External,
         },
         "when there's no internal descriptor it should just use external"
@@ -2477,7 +2544,7 @@ fn test_get_address_no_reuse_single_descriptor() {
     use bdk::descriptor::template::Bip84;
     use std::collections::HashSet;
 
-    let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+    let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
     let mut wallet =
         Wallet::new_no_persist(Bip84(key, KeychainKind::External), None, Network::Regtest).unwrap();
 
@@ -2532,7 +2599,7 @@ fn test_taproot_psbt_populate_tap_key_origins_repeated_key() {
     let (mut wallet, _) = get_funded_wallet(get_test_tr_repeated_key());
     let addr = wallet.get_address(AddressIndex::New);
 
-    let path = vec![("e5mmg3xh".to_string(), vec![0])]
+    let path = vec![("rn4nre9c".to_string(), vec![0])]
         .into_iter()
         .collect();
 
@@ -2552,13 +2619,6 @@ fn test_taproot_psbt_populate_tap_key_origins_repeated_key() {
     assert_eq!(
         input_key_origins,
         vec![
-            (
-                from_str!("b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55"),
-                (
-                    vec![],
-                    (FromStr::from_str("871fd295").unwrap(), vec![].into())
-                )
-            ),
             (
                 from_str!("2b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3"),
                 (
@@ -2572,6 +2632,13 @@ fn test_taproot_psbt_populate_tap_key_origins_repeated_key() {
                     ],
                     (FromStr::from_str("ece52657").unwrap(), vec![].into())
                 )
+            ),
+            (
+                from_str!("b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55"),
+                (
+                    vec![],
+                    (FromStr::from_str("871fd295").unwrap(), vec![].into())
+                )
             )
         ],
         "Wrong input tap_key_origins"
@@ -2592,10 +2659,8 @@ fn test_taproot_psbt_populate_tap_key_origins_repeated_key() {
 
 #[test]
 fn test_taproot_psbt_input_tap_tree() {
-    use bdk::bitcoin::psbt::serialize::Deserialize;
-    use bdk::bitcoin::psbt::TapTree;
     use bitcoin::hashes::hex::FromHex;
-    use bitcoin::util::taproot;
+    use bitcoin::taproot;
 
     let (mut wallet, _) = get_funded_wallet(get_test_tr_with_taptree());
     let addr = wallet.get_address(AddressIndex::Peek(0));
@@ -2607,15 +2672,17 @@ fn test_taproot_psbt_input_tap_tree() {
     assert_eq!(
         psbt.inputs[0].tap_merkle_root,
         Some(
-            FromHex::from_hex("61f81509635053e52d9d1217545916167394490da2287aca4693606e43851986")
-                .unwrap()
+            TapNodeHash::from_str(
+                "61f81509635053e52d9d1217545916167394490da2287aca4693606e43851986"
+            )
+            .unwrap()
         ),
     );
     assert_eq!(
         psbt.inputs[0].tap_scripts.clone().into_iter().collect::<Vec<_>>(),
         vec![
-            (taproot::ControlBlock::from_slice(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b7ef769a745e625ed4b9a4982a4dc08274c59187e73e6f07171108f455081cb2").unwrap()).unwrap(), (from_str!("208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac"), taproot::LeafVersion::TapScript)),
-            (taproot::ControlBlock::from_slice(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b9a515f7be31a70186e3c5937ee4a70cc4b4e1efe876c1d38e408222ffc64834").unwrap()).unwrap(), (from_str!("2051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac"), taproot::LeafVersion::TapScript)),
+            (taproot::ControlBlock::decode(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b7ef769a745e625ed4b9a4982a4dc08274c59187e73e6f07171108f455081cb2").unwrap()).unwrap(), (ScriptBuf::from_hex("208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac").unwrap(), taproot::LeafVersion::TapScript)),
+            (taproot::ControlBlock::decode(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b9a515f7be31a70186e3c5937ee4a70cc4b4e1efe876c1d38e408222ffc64834").unwrap()).unwrap(), (ScriptBuf::from_hex("2051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac").unwrap(), taproot::LeafVersion::TapScript)),
         ],
     );
     assert_eq!(
@@ -2632,10 +2699,8 @@ fn test_taproot_psbt_input_tap_tree() {
         psbt.outputs[0].tap_internal_key
     );
 
-    assert_eq!(
-        psbt.outputs[0].tap_tree,
-        Some(TapTree::deserialize(&Vec::<u8>::from_hex("01c022208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac01c0222051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac",).unwrap()).unwrap())
-    );
+    let tap_tree: bitcoin::taproot::TapTree = serde_json::from_str(r#"[1,{"Script":["2051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac",192]},1,{"Script":["208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac",192]}]"#).unwrap();
+    assert_eq!(psbt.outputs[0].tap_tree, Some(tap_tree));
 }
 
 #[test]
@@ -2706,9 +2771,12 @@ fn test_taproot_foreign_utxo() {
     let (mut wallet1, _) = get_funded_wallet(get_test_wpkh());
     let (wallet2, _) = get_funded_wallet(get_test_tr_single_sig());
 
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let utxo = wallet2.list_unspent().next().unwrap();
     let psbt_input = wallet2.get_psbt_input(utxo.clone(), None, false).unwrap();
+    #[allow(deprecated)]
     let foreign_utxo_satisfaction = wallet2
         .get_descriptor_for_keychain(KeychainKind::External)
         .max_satisfaction_weight()
@@ -2829,7 +2897,7 @@ fn test_taproot_script_spend_sign_all_leaves() {
 #[test]
 fn test_taproot_script_spend_sign_include_some_leaves() {
     use bdk::signer::TapLeavesOptions;
-    use bitcoin::util::taproot::TapLeafHash;
+    use bitcoin::taproot::TapLeafHash;
 
     let (mut wallet, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
     let addr = wallet.get_address(AddressIndex::New);
@@ -2869,7 +2937,7 @@ fn test_taproot_script_spend_sign_include_some_leaves() {
 #[test]
 fn test_taproot_script_spend_sign_exclude_some_leaves() {
     use bdk::signer::TapLeavesOptions;
-    use bitcoin::util::taproot::TapLeafHash;
+    use bitcoin::taproot::TapLeafHash;
 
     let (mut wallet, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
     let addr = wallet.get_address(AddressIndex::New);
@@ -2958,7 +3026,7 @@ fn test_taproot_sign_explicit_sighash_all() {
     let mut builder = wallet.build_tx();
     builder
         .drain_to(addr.script_pubkey())
-        .sighash(SchnorrSighashType::All.into())
+        .sighash(TapSighashType::All.into())
         .drain_wallet();
     let (mut psbt, _) = builder.finish().unwrap();
 
@@ -2971,7 +3039,7 @@ fn test_taproot_sign_explicit_sighash_all() {
 
 #[test]
 fn test_taproot_sign_non_default_sighash() {
-    let sighash = SchnorrSighashType::NonePlusAnyoneCanPay;
+    let sighash = TapSighashType::NonePlusAnyoneCanPay;
 
     let (mut wallet, _) = get_funded_wallet(get_test_tr_single_sig());
     let addr = wallet.get_address(New);
@@ -3052,7 +3120,7 @@ fn test_spend_coinbase() {
         .unwrap();
     let coinbase_tx = Transaction {
         version: 1,
-        lock_time: bitcoin::PackedLockTime(0),
+        lock_time: absolute::LockTime::ZERO,
         input: vec![TxIn {
             previous_output: OutPoint::null(),
             ..Default::default()
@@ -3088,7 +3156,9 @@ fn test_spend_coinbase() {
 
     // We try to create a transaction, only to notice that all
     // our funds are unspendable
-    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+    let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+        .unwrap()
+        .assume_checked();
     let mut builder = wallet.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), balance.immature / 2)
@@ -3167,7 +3237,7 @@ fn test_fee_rate_sign_no_grinding_high_r() {
     let addr = wallet.get_address(New);
     let fee_rate = FeeRate::from_sat_per_vb(1.0);
     let mut builder = wallet.build_tx();
-    let mut data = vec![0];
+    let mut data = PushBytesBuf::try_from(vec![0]).unwrap();
     builder
         .drain_to(addr.script_pubkey())
         .drain_wallet()
@@ -3187,8 +3257,8 @@ fn test_fee_rate_sign_no_grinding_high_r() {
     while sig_len < 71 {
         // Changing the OP_RETURN data will make the signature change (but not the fee, until
         // data[0] is small enough)
-        data[0] += 1;
-        psbt.unsigned_tx.output[op_return_vout].script_pubkey = Script::new_op_return(&data);
+        data.as_mut_bytes()[0] += 1;
+        psbt.unsigned_tx.output[op_return_vout].script_pubkey = ScriptBuf::new_op_return(&data);
         // Clearing the previous signature
         psbt.inputs[0].partial_sigs.clear();
         // Signing
@@ -3310,7 +3380,9 @@ fn test_taproot_load_descriptor_duplicated_keys() {
 fn test_tx_cancellation() {
     macro_rules! new_tx {
         ($wallet:expr) => {{
-            let addr = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+            let addr = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
+                .unwrap()
+                .assume_checked();
             let mut builder = $wallet.build_tx();
             builder.add_recipient(addr.script_pubkey(), 10_000);