Merge branch 'master' into release/0.4.0

Merging in fixes for the CI after Rust 1.50.0
This commit is contained in:
Alekos Filini 2021-02-13 11:08:03 -05:00
commit d0ffcdd009
No known key found for this signature in database
GPG Key ID: 431401E4A4530061
9 changed files with 205 additions and 177 deletions

View File

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Keys ### Keys
#### Changed #### Changed
- Renamed `DerivableKey::add_metadata()` to `DerivableKey::into_descriptor_key()` - Renamed `DerivableKey::add_metadata()` to `DerivableKey::into_descriptor_key()`
- Renamed `ToDescriptorKey::to_descriptor_key()` to `IntoDescriptorKey::into_descriptor_key()`
#### Added #### Added
- Added an `ExtendedKey` type that is an enum of `bip32::ExtendedPubKey` and `bip32::ExtendedPrivKey` - Added an `ExtendedKey` type that is an enum of `bip32::ExtendedPubKey` and `bip32::ExtendedPrivKey`
- Added `DerivableKey::into_extended_key()` as the only method that needs to be implemented - Added `DerivableKey::into_extended_key()` as the only method that needs to be implemented
@ -29,6 +30,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Wallet ### Wallet
#### Changed #### Changed
- Removed the explicit `id` argument from `Wallet::add_signer()` since that's now part of `Signer` itself - Removed the explicit `id` argument from `Wallet::add_signer()` since that's now part of `Signer` itself
- Renamed `ToWalletDescriptor::to_wallet_descriptor()` to `IntoWalletDescriptor::into_wallet_descriptor()`
### Policy
#### Changed
- Removed unneeded `Result<(), PolicyError>` return type for `Satisfaction::finalize()`
## [v0.3.0] - [v0.2.0] ## [v0.3.0] - [v0.2.0]

View File

@ -223,14 +223,14 @@ impl Peer {
)), )),
)?; )?;
let version = if let NetworkMessage::Version(version) = let version = if let NetworkMessage::Version(version) =
Self::_recv(&responses, "version", None)?.unwrap() Self::_recv(&responses, "version", None).unwrap()
{ {
version version
} else { } else {
return Err(CompactFiltersError::InvalidResponse); return Err(CompactFiltersError::InvalidResponse);
}; };
if let NetworkMessage::Verack = Self::_recv(&responses, "verack", None)?.unwrap() { if let NetworkMessage::Verack = Self::_recv(&responses, "verack", None).unwrap() {
Self::_send(&mut locked_writer, network.magic(), NetworkMessage::Verack)?; Self::_send(&mut locked_writer, network.magic(), NetworkMessage::Verack)?;
} else { } else {
return Err(CompactFiltersError::InvalidResponse); return Err(CompactFiltersError::InvalidResponse);
@ -271,7 +271,7 @@ impl Peer {
responses: &Arc<RwLock<ResponsesMap>>, responses: &Arc<RwLock<ResponsesMap>>,
wait_for: &'static str, wait_for: &'static str,
timeout: Option<Duration>, timeout: Option<Duration>,
) -> Result<Option<NetworkMessage>, CompactFiltersError> { ) -> Option<NetworkMessage> {
let message_resp = { let message_resp = {
let mut lock = responses.write().unwrap(); let mut lock = responses.write().unwrap();
let message_resp = lock.entry(wait_for).or_default(); let message_resp = lock.entry(wait_for).or_default();
@ -287,15 +287,14 @@ impl Peer {
Some(t) => { Some(t) => {
let result = cvar.wait_timeout(messages, t).unwrap(); let result = cvar.wait_timeout(messages, t).unwrap();
if result.1.timed_out() { if result.1.timed_out() {
return Ok(None); return None;
} }
messages = result.0; messages = result.0;
} }
} }
} }
Ok(messages.pop()) messages.pop()
} }
/// Return the [`VersionMessage`] sent by the peer /// Return the [`VersionMessage`] sent by the peer
@ -415,7 +414,7 @@ impl Peer {
wait_for: &'static str, wait_for: &'static str,
timeout: Option<Duration>, timeout: Option<Duration>,
) -> Result<Option<NetworkMessage>, CompactFiltersError> { ) -> Result<Option<NetworkMessage>, CompactFiltersError> {
Self::_recv(&self.responses, wait_for, timeout) Ok(Self::_recv(&self.responses, wait_for, timeout))
} }
} }

View File

@ -76,10 +76,10 @@ macro_rules! impl_top_level_pk {
use $crate::miniscript::descriptor::$inner_type; use $crate::miniscript::descriptor::$inner_type;
#[allow(unused_imports)] #[allow(unused_imports)]
use $crate::keys::{DescriptorKey, ToDescriptorKey}; use $crate::keys::{DescriptorKey, IntoDescriptorKey};
let secp = $crate::bitcoin::secp256k1::Secp256k1::new(); let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
$key.to_descriptor_key() $key.into_descriptor_key()
.and_then(|key: DescriptorKey<$ctx>| key.extract(&secp)) .and_then(|key: DescriptorKey<$ctx>| key.extract(&secp))
.map_err($crate::descriptor::DescriptorError::Key) .map_err($crate::descriptor::DescriptorError::Key)
.map(|(pk, key_map, valid_networks)| ($inner_type::new(pk), key_map, valid_networks)) .map(|(pk, key_map, valid_networks)| ($inner_type::new(pk), key_map, valid_networks))
@ -225,12 +225,12 @@ macro_rules! impl_sortedmulti {
$crate::keys::make_sortedmulti($thresh, $keys, $build_desc, &secp) $crate::keys::make_sortedmulti($thresh, $keys, $build_desc, &secp)
}); });
( $build_desc:expr, sortedmulti ( $thresh:expr $(, $key:expr )+ ) ) => ({ ( $build_desc:expr, sortedmulti ( $thresh:expr $(, $key:expr )+ ) ) => ({
use $crate::keys::ToDescriptorKey; use $crate::keys::IntoDescriptorKey;
let secp = $crate::bitcoin::secp256k1::Secp256k1::new(); let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
let mut keys = vec![]; let mut keys = vec![];
$( $(
keys.push($key.to_descriptor_key()); keys.push($key.into_descriptor_key());
)* )*
keys.into_iter().collect::<Result<Vec<_>, _>>() keys.into_iter().collect::<Result<Vec<_>, _>>()
@ -326,11 +326,11 @@ macro_rules! apply_modifier {
/// broken up to `s:d:v:older(144)`. /// broken up to `s:d:v:older(144)`.
/// ///
/// The `pk()`, `pk_k()` and `pk_h()` operands can take as argument any type that implements /// The `pk()`, `pk_k()` and `pk_h()` operands can take as argument any type that implements
/// [`ToDescriptorKey`]. This means that keys can also be written inline as strings, but in that /// [`IntoDescriptorKey`]. This means that keys can also be written inline as strings, but in that
/// case they must be wrapped in quotes, which is another difference compared to the standard /// case they must be wrapped in quotes, which is another difference compared to the standard
/// descriptor syntax. /// descriptor syntax.
/// ///
/// [`ToDescriptorKey`]: crate::keys::ToDescriptorKey /// [`IntoDescriptorKey`]: crate::keys::IntoDescriptorKey
/// ///
/// ## Example /// ## Example
/// ///
@ -653,12 +653,12 @@ macro_rules! fragment {
$crate::keys::make_multi($thresh, $keys) $crate::keys::make_multi($thresh, $keys)
}); });
( multi ( $thresh:expr $(, $key:expr )+ ) ) => ({ ( multi ( $thresh:expr $(, $key:expr )+ ) ) => ({
use $crate::keys::ToDescriptorKey; use $crate::keys::IntoDescriptorKey;
let secp = $crate::bitcoin::secp256k1::Secp256k1::new(); let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
let mut keys = vec![]; let mut keys = vec![];
$( $(
keys.push($key.to_descriptor_key()); keys.push($key.into_descriptor_key());
)* )*
keys.into_iter().collect::<Result<Vec<_>, _>>() keys.into_iter().collect::<Result<Vec<_>, _>>()
@ -685,7 +685,7 @@ mod test {
use std::str::FromStr; use std::str::FromStr;
use crate::descriptor::{DescriptorError, DescriptorMeta}; use crate::descriptor::{DescriptorError, DescriptorMeta};
use crate::keys::{DescriptorKey, ToDescriptorKey, ValidNetworks}; use crate::keys::{DescriptorKey, IntoDescriptorKey, ValidNetworks};
use bitcoin::network::constants::Network::{Bitcoin, Regtest, Signet, Testnet}; use bitcoin::network::constants::Network::{Bitcoin, Regtest, Signet, Testnet};
use bitcoin::util::bip32; use bitcoin::util::bip32;
use bitcoin::PrivateKey; use bitcoin::PrivateKey;
@ -724,7 +724,7 @@ mod test {
} }
// - at least one of each "type" of operator; ie. one modifier, one leaf_opcode, one leaf_opcode_value, etc. // - at least one of each "type" of operator; ie. one modifier, one leaf_opcode, one leaf_opcode_value, etc.
// - mixing up key types that implement ToDescriptorKey in multi() or thresh() // - mixing up key types that implement IntoDescriptorKey in multi() or thresh()
// expected script for pk and bare manually created // expected script for pk and bare manually created
// expected addresses created with `bitcoin-cli getdescriptorinfo` (for hash) and `bitcoin-cli deriveaddresses` // expected addresses created with `bitcoin-cli getdescriptorinfo` (for hash) and `bitcoin-cli deriveaddresses`
@ -808,7 +808,7 @@ mod test {
let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap(); let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let path = bip32::DerivationPath::from_str("m/0").unwrap(); let path = bip32::DerivationPath::from_str("m/0").unwrap();
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap(); let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
check( check(
descriptor!(pk(desc_key)), descriptor!(pk(desc_key)),
false, false,
@ -820,7 +820,7 @@ mod test {
], ],
); );
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap(); let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
check( check(
descriptor!(pkh(desc_key)), descriptor!(pkh(desc_key)),
false, false,
@ -833,8 +833,8 @@ mod test {
); );
let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap(); let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
let desc_key1 = (xprv, path).to_descriptor_key().unwrap(); let desc_key1 = (xprv, path).into_descriptor_key().unwrap();
let desc_key2 = (xprv, path2).to_descriptor_key().unwrap(); let desc_key2 = (xprv, path2).into_descriptor_key().unwrap();
check( check(
descriptor!(sh(multi(1, desc_key1, desc_key2))), descriptor!(sh(multi(1, desc_key1, desc_key2))),
@ -853,7 +853,7 @@ mod test {
let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap(); let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let path = bip32::DerivationPath::from_str("m/0").unwrap(); let path = bip32::DerivationPath::from_str("m/0").unwrap();
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap(); let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
check( check(
descriptor!(wpkh(desc_key)), descriptor!(wpkh(desc_key)),
true, true,
@ -865,7 +865,7 @@ mod test {
], ],
); );
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap(); let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
check( check(
descriptor!(sh(wpkh(desc_key))), descriptor!(sh(wpkh(desc_key))),
true, true,
@ -878,8 +878,8 @@ mod test {
); );
let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap(); let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
let desc_key1 = (xprv, path.clone()).to_descriptor_key().unwrap(); let desc_key1 = (xprv, path.clone()).into_descriptor_key().unwrap();
let desc_key2 = (xprv, path2.clone()).to_descriptor_key().unwrap(); let desc_key2 = (xprv, path2.clone()).into_descriptor_key().unwrap();
check( check(
descriptor!(wsh(multi(1, desc_key1, desc_key2))), descriptor!(wsh(multi(1, desc_key1, desc_key2))),
true, true,
@ -891,8 +891,8 @@ mod test {
], ],
); );
let desc_key1 = (xprv, path).to_descriptor_key().unwrap(); let desc_key1 = (xprv, path).into_descriptor_key().unwrap();
let desc_key2 = (xprv, path2).to_descriptor_key().unwrap(); let desc_key2 = (xprv, path2).into_descriptor_key().unwrap();
check( check(
descriptor!(sh(wsh(multi(1, desc_key1, desc_key2)))), descriptor!(sh(wsh(multi(1, desc_key1, desc_key2)))),
true, true,
@ -968,7 +968,7 @@ mod test {
fn test_valid_networks() { fn test_valid_networks() {
let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap(); let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let path = bip32::DerivationPath::from_str("m/0").unwrap(); let path = bip32::DerivationPath::from_str("m/0").unwrap();
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap(); let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
let (_desc, _key_map, valid_networks) = descriptor!(pkh(desc_key)).unwrap(); let (_desc, _key_map, valid_networks) = descriptor!(pkh(desc_key)).unwrap();
assert_eq!( assert_eq!(
@ -978,7 +978,7 @@ mod test {
let xprv = bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi").unwrap(); let xprv = bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi").unwrap();
let path = bip32::DerivationPath::from_str("m/10/20/30/40").unwrap(); let path = bip32::DerivationPath::from_str("m/10/20/30/40").unwrap();
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap(); let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
let (_desc, _key_map, valid_networks) = descriptor!(wpkh(desc_key)).unwrap(); let (_desc, _key_map, valid_networks) = descriptor!(wpkh(desc_key)).unwrap();
assert_eq!(valid_networks, [Bitcoin].iter().cloned().collect()); assert_eq!(valid_networks, [Bitcoin].iter().cloned().collect());
@ -991,26 +991,26 @@ mod test {
let xprv1 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap(); let xprv1 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let path1 = bip32::DerivationPath::from_str("m/0").unwrap(); let path1 = bip32::DerivationPath::from_str("m/0").unwrap();
let desc_key1 = (xprv1, path1.clone()).to_descriptor_key().unwrap(); let desc_key1 = (xprv1, path1.clone()).into_descriptor_key().unwrap();
let xprv2 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPegBHHnq7YEgM815dG24M2Jk5RVqipgDxF1HJ1tsnT815X5Fd5FRfMVUs8NZs9XCb6y9an8hRPThnhfwfXJ36intaekySHGF").unwrap(); let xprv2 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPegBHHnq7YEgM815dG24M2Jk5RVqipgDxF1HJ1tsnT815X5Fd5FRfMVUs8NZs9XCb6y9an8hRPThnhfwfXJ36intaekySHGF").unwrap();
let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap(); let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
let desc_key2 = (xprv2, path2.clone()).to_descriptor_key().unwrap(); let desc_key2 = (xprv2, path2.clone()).into_descriptor_key().unwrap();
let xprv3 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf").unwrap(); let xprv3 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf").unwrap();
let path3 = bip32::DerivationPath::from_str("m/10/20/30/40").unwrap(); let path3 = bip32::DerivationPath::from_str("m/10/20/30/40").unwrap();
let desc_key3 = (xprv3, path3.clone()).to_descriptor_key().unwrap(); let desc_key3 = (xprv3, path3.clone()).into_descriptor_key().unwrap();
let (_desc, key_map, _valid_networks) = let (_desc, key_map, _valid_networks) =
descriptor!(sh(wsh(multi(2, desc_key1, desc_key2, desc_key3)))).unwrap(); descriptor!(sh(wsh(multi(2, desc_key1, desc_key2, desc_key3)))).unwrap();
assert_eq!(key_map.len(), 3); assert_eq!(key_map.len(), 3);
let desc_key1: DescriptorKey<Segwitv0> = let desc_key1: DescriptorKey<Segwitv0> =
(xprv1, path1.clone()).to_descriptor_key().unwrap(); (xprv1, path1.clone()).into_descriptor_key().unwrap();
let desc_key2: DescriptorKey<Segwitv0> = let desc_key2: DescriptorKey<Segwitv0> =
(xprv2, path2.clone()).to_descriptor_key().unwrap(); (xprv2, path2.clone()).into_descriptor_key().unwrap();
let desc_key3: DescriptorKey<Segwitv0> = let desc_key3: DescriptorKey<Segwitv0> =
(xprv3, path3.clone()).to_descriptor_key().unwrap(); (xprv3, path3.clone()).into_descriptor_key().unwrap();
let (key1, _key_map, _valid_networks) = desc_key1.extract(&secp).unwrap(); let (key1, _key_map, _valid_networks) = desc_key1.extract(&secp).unwrap();
let (key2, _key_map, _valid_networks) = desc_key2.extract(&secp).unwrap(); let (key2, _key_map, _valid_networks) = desc_key2.extract(&secp).unwrap();
@ -1020,19 +1020,19 @@ mod test {
assert_eq!(key_map.get(&key3).unwrap().to_string(), "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf/10/20/30/40/*"); assert_eq!(key_map.get(&key3).unwrap().to_string(), "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf/10/20/30/40/*");
} }
// - verify the ScriptContext is correctly validated (i.e. passing a type that only impl ToDescriptorKey<Segwitv0> to a pkh() descriptor should throw a compilation error // - verify the ScriptContext is correctly validated (i.e. passing a type that only impl IntoDescriptorKey<Segwitv0> to a pkh() descriptor should throw a compilation error
#[test] #[test]
fn test_script_context_validation() { fn test_script_context_validation() {
// this compiles // this compiles
let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap(); let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let path = bip32::DerivationPath::from_str("m/0").unwrap(); let path = bip32::DerivationPath::from_str("m/0").unwrap();
let desc_key: DescriptorKey<Legacy> = (xprv, path.clone()).to_descriptor_key().unwrap(); let desc_key: DescriptorKey<Legacy> = (xprv, path.clone()).into_descriptor_key().unwrap();
let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap(); let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap();
assert_eq!(desc.to_string(), "pkh(tpubD6NzVbkrYhZ4WR7a4vY1VT3khMJMeAxVsfq9TBJyJWrNk247zCJtV7AWf6UJP7rAVsn8NNKdJi3gFyKPTmWZS9iukb91xbn2HbFSMQm2igY/0/*)#yrnz9pp2"); assert_eq!(desc.to_string(), "pkh(tpubD6NzVbkrYhZ4WR7a4vY1VT3khMJMeAxVsfq9TBJyJWrNk247zCJtV7AWf6UJP7rAVsn8NNKdJi3gFyKPTmWZS9iukb91xbn2HbFSMQm2igY/0/*)#yrnz9pp2");
// as expected this does not compile due to invalid context // as expected this does not compile due to invalid context
//let desc_key:DescriptorKey<Segwitv0> = (xprv, path.clone()).to_descriptor_key().unwrap(); //let desc_key:DescriptorKey<Segwitv0> = (xprv, path.clone()).into_descriptor_key().unwrap();
//let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap(); //let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap();
} }

View File

@ -54,7 +54,7 @@ pub use self::derived::DerivedDescriptorKey;
pub use self::error::Error as DescriptorError; pub use self::error::Error as DescriptorError;
pub use self::policy::Policy; pub use self::policy::Policy;
use self::template::DescriptorTemplateOut; use self::template::DescriptorTemplateOut;
use crate::keys::{KeyError, ToDescriptorKey}; use crate::keys::{IntoDescriptorKey, KeyError};
use crate::wallet::signer::SignersContainer; use crate::wallet::signer::SignersContainer;
use crate::wallet::utils::SecpCtx; use crate::wallet::utils::SecpCtx;
@ -72,17 +72,17 @@ pub type DerivedDescriptor<'s> = Descriptor<DerivedDescriptorKey<'s>>;
pub type HDKeyPaths = BTreeMap<PublicKey, KeySource>; pub type HDKeyPaths = BTreeMap<PublicKey, KeySource>;
/// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`] /// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`]
pub trait ToWalletDescriptor { pub trait IntoWalletDescriptor {
/// Convert to wallet descriptor /// Convert to wallet descriptor
fn to_wallet_descriptor( fn into_wallet_descriptor(
self, self,
secp: &SecpCtx, secp: &SecpCtx,
network: Network, network: Network,
) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError>; ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError>;
} }
impl ToWalletDescriptor for &str { impl IntoWalletDescriptor for &str {
fn to_wallet_descriptor( fn into_wallet_descriptor(
self, self,
secp: &SecpCtx, secp: &SecpCtx,
network: Network, network: Network,
@ -102,32 +102,33 @@ impl ToWalletDescriptor for &str {
self self
}; };
ExtendedDescriptor::parse_descriptor(secp, descriptor)?.to_wallet_descriptor(secp, network) ExtendedDescriptor::parse_descriptor(secp, descriptor)?
.into_wallet_descriptor(secp, network)
} }
} }
impl ToWalletDescriptor for &String { impl IntoWalletDescriptor for &String {
fn to_wallet_descriptor( fn into_wallet_descriptor(
self, self,
secp: &SecpCtx, secp: &SecpCtx,
network: Network, network: Network,
) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> { ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
self.as_str().to_wallet_descriptor(secp, network) self.as_str().into_wallet_descriptor(secp, network)
} }
} }
impl ToWalletDescriptor for ExtendedDescriptor { impl IntoWalletDescriptor for ExtendedDescriptor {
fn to_wallet_descriptor( fn into_wallet_descriptor(
self, self,
secp: &SecpCtx, secp: &SecpCtx,
network: Network, network: Network,
) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> { ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
(self, KeyMap::default()).to_wallet_descriptor(secp, network) (self, KeyMap::default()).into_wallet_descriptor(secp, network)
} }
} }
impl ToWalletDescriptor for (ExtendedDescriptor, KeyMap) { impl IntoWalletDescriptor for (ExtendedDescriptor, KeyMap) {
fn to_wallet_descriptor( fn into_wallet_descriptor(
self, self,
secp: &SecpCtx, secp: &SecpCtx,
network: Network, network: Network,
@ -137,11 +138,11 @@ impl ToWalletDescriptor for (ExtendedDescriptor, KeyMap) {
let check_key = |pk: &DescriptorPublicKey| { let check_key = |pk: &DescriptorPublicKey| {
let (pk, _, networks) = if self.0.is_witness() { let (pk, _, networks) = if self.0.is_witness() {
let desciptor_key: DescriptorKey<miniscript::Segwitv0> = let desciptor_key: DescriptorKey<miniscript::Segwitv0> =
pk.clone().to_descriptor_key()?; pk.clone().into_descriptor_key()?;
desciptor_key.extract(&secp)? desciptor_key.extract(&secp)?
} else { } else {
let desciptor_key: DescriptorKey<miniscript::Legacy> = let desciptor_key: DescriptorKey<miniscript::Legacy> =
pk.clone().to_descriptor_key()?; pk.clone().into_descriptor_key()?;
desciptor_key.extract(&secp)? desciptor_key.extract(&secp)?
}; };
@ -159,8 +160,8 @@ impl ToWalletDescriptor for (ExtendedDescriptor, KeyMap) {
} }
} }
impl ToWalletDescriptor for DescriptorTemplateOut { impl IntoWalletDescriptor for DescriptorTemplateOut {
fn to_wallet_descriptor( fn into_wallet_descriptor(
self, self,
_secp: &SecpCtx, _secp: &SecpCtx,
network: Network, network: Network,
@ -613,7 +614,7 @@ mod test {
#[test] #[test]
fn test_to_wallet_descriptor_fixup_networks() { fn test_to_wallet_descriptor_fixup_networks() {
use crate::keys::{any_network, ToDescriptorKey}; use crate::keys::{any_network, IntoDescriptorKey};
let secp = Secp256k1::new(); let secp = Secp256k1::new();
@ -622,116 +623,120 @@ mod test {
// here `to_descriptor_key` will set the valid networks for the key to only mainnet, since // here `to_descriptor_key` will set the valid networks for the key to only mainnet, since
// we are using an "xpub" // we are using an "xpub"
let key = (xpub, path).to_descriptor_key().unwrap(); let key = (xpub, path).into_descriptor_key().unwrap();
// override it with any. this happens in some key conversions, like bip39 // override it with any. this happens in some key conversions, like bip39
let key = key.override_valid_networks(any_network()); let key = key.override_valid_networks(any_network());
// make a descriptor out of it // make a descriptor out of it
let desc = crate::descriptor!(wpkh(key)).unwrap(); let desc = crate::descriptor!(wpkh(key)).unwrap();
// this should conver the key that supports "any_network" to the right network (testnet) // this should conver the key that supports "any_network" to the right network (testnet)
let (wallet_desc, _) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (wallet_desc, _) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
assert_eq!(wallet_desc.to_string(), "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)#y8p7e8kk"); assert_eq!(wallet_desc.to_string(), "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)#y8p7e8kk");
} }
// test ToWalletDescriptor trait from &str with and without checksum appended // test IntoWalletDescriptor trait from &str with and without checksum appended
#[test] #[test]
fn test_descriptor_from_str_with_checksum() { fn test_descriptor_from_str_with_checksum() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#tqz0nc62" let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#tqz0nc62"
.to_wallet_descriptor(&secp, Network::Testnet); .into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok()); assert!(desc.is_ok());
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)" let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
.to_wallet_descriptor(&secp, Network::Testnet); .into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok()); assert!(desc.is_ok());
let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)#67ju93jw" let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)#67ju93jw"
.to_wallet_descriptor(&secp, Network::Testnet); .into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok()); assert!(desc.is_ok());
let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)" let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
.to_wallet_descriptor(&secp, Network::Testnet); .into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok()); assert!(desc.is_ok());
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw" let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw"
.to_wallet_descriptor(&secp, Network::Testnet); .into_wallet_descriptor(&secp, Network::Testnet);
assert!(matches!( assert!(matches!(
desc.err(), desc.err(),
Some(DescriptorError::InvalidDescriptorChecksum) Some(DescriptorError::InvalidDescriptorChecksum)
)); ));
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw" let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw"
.to_wallet_descriptor(&secp, Network::Testnet); .into_wallet_descriptor(&secp, Network::Testnet);
assert!(matches!( assert!(matches!(
desc.err(), desc.err(),
Some(DescriptorError::InvalidDescriptorChecksum) Some(DescriptorError::InvalidDescriptorChecksum)
)); ));
} }
// test ToWalletDescriptor trait from &str with keys from right and wrong network // test IntoWalletDescriptor trait from &str with keys from right and wrong network
#[test] #[test]
fn test_descriptor_from_str_with_keys_network() { fn test_descriptor_from_str_with_keys_network() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)" let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
.to_wallet_descriptor(&secp, Network::Testnet); .into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok()); assert!(desc.is_ok());
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)" let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
.to_wallet_descriptor(&secp, Network::Regtest); .into_wallet_descriptor(&secp, Network::Regtest);
assert!(desc.is_ok()); assert!(desc.is_ok());
let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)" let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
.to_wallet_descriptor(&secp, Network::Testnet); .into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok()); assert!(desc.is_ok());
let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)" let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
.to_wallet_descriptor(&secp, Network::Regtest); .into_wallet_descriptor(&secp, Network::Regtest);
assert!(desc.is_ok()); assert!(desc.is_ok());
let desc = "sh(wpkh(02864bb4ad00cefa806098a69e192bbda937494e69eb452b87bb3f20f6283baedb))" let desc = "sh(wpkh(02864bb4ad00cefa806098a69e192bbda937494e69eb452b87bb3f20f6283baedb))"
.to_wallet_descriptor(&secp, Network::Testnet); .into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok()); assert!(desc.is_ok());
let desc = "sh(wpkh(02864bb4ad00cefa806098a69e192bbda937494e69eb452b87bb3f20f6283baedb))" let desc = "sh(wpkh(02864bb4ad00cefa806098a69e192bbda937494e69eb452b87bb3f20f6283baedb))"
.to_wallet_descriptor(&secp, Network::Bitcoin); .into_wallet_descriptor(&secp, Network::Bitcoin);
assert!(desc.is_ok()); assert!(desc.is_ok());
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)" let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
.to_wallet_descriptor(&secp, Network::Bitcoin); .into_wallet_descriptor(&secp, Network::Bitcoin);
assert!(matches!( assert!(matches!(
desc.err(), desc.err(),
Some(DescriptorError::Key(KeyError::InvalidNetwork)) Some(DescriptorError::Key(KeyError::InvalidNetwork))
)); ));
let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)" let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
.to_wallet_descriptor(&secp, Network::Bitcoin); .into_wallet_descriptor(&secp, Network::Bitcoin);
assert!(matches!( assert!(matches!(
desc.err(), desc.err(),
Some(DescriptorError::Key(KeyError::InvalidNetwork)) Some(DescriptorError::Key(KeyError::InvalidNetwork))
)); ));
} }
// test ToWalletDescriptor trait from the output of the descriptor!() macro // test IntoWalletDescriptor trait from the output of the descriptor!() macro
#[test] #[test]
fn test_descriptor_from_str_from_output_of_macro() { fn test_descriptor_from_str_from_output_of_macro() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let tpub = bip32::ExtendedPubKey::from_str("tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK").unwrap(); let tpub = bip32::ExtendedPubKey::from_str("tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK").unwrap();
let path = bip32::DerivationPath::from_str("m/1/2").unwrap(); let path = bip32::DerivationPath::from_str("m/1/2").unwrap();
let key = (tpub, path).to_descriptor_key().unwrap(); let key = (tpub, path).into_descriptor_key().unwrap();
// make a descriptor out of it // make a descriptor out of it
let desc = crate::descriptor!(wpkh(key)).unwrap(); let desc = crate::descriptor!(wpkh(key)).unwrap();
let (wallet_desc, _) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (wallet_desc, _) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let wallet_desc_str = wallet_desc.to_string(); let wallet_desc_str = wallet_desc.to_string();
assert_eq!(wallet_desc_str, "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)#67ju93jw"); assert_eq!(wallet_desc_str, "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)#67ju93jw");
let (wallet_desc2, _) = wallet_desc_str let (wallet_desc2, _) = wallet_desc_str
.to_wallet_descriptor(&secp, Network::Testnet) .into_wallet_descriptor(&secp, Network::Testnet)
.unwrap(); .unwrap();
assert_eq!(wallet_desc, wallet_desc2) assert_eq!(wallet_desc, wallet_desc2)
} }

View File

@ -354,7 +354,7 @@ impl Satisfaction {
} }
} }
fn finalize(&mut self) -> Result<(), PolicyError> { fn finalize(&mut self) {
// if partial try to bump it to a partialcomplete // if partial try to bump it to a partialcomplete
if let Satisfaction::Partial { if let Satisfaction::Partial {
n, n,
@ -420,8 +420,6 @@ impl Satisfaction {
}; };
} }
} }
Ok(())
} }
} }
@ -575,7 +573,7 @@ impl Policy {
for (index, item) in items.iter().enumerate() { for (index, item) in items.iter().enumerate() {
contribution.add(&item.contribution, index)?; contribution.add(&item.contribution, index)?;
} }
contribution.finalize()?; contribution.finalize();
let mut policy: Policy = SatisfiableItem::Thresh { items, threshold }.into(); let mut policy: Policy = SatisfiableItem::Thresh { items, threshold }.into();
policy.contribution = contribution; policy.contribution = contribution;
@ -613,7 +611,7 @@ impl Policy {
)?; )?;
} }
} }
contribution.finalize()?; contribution.finalize();
let mut policy: Policy = SatisfiableItem::Multisig { let mut policy: Policy = SatisfiableItem::Multisig {
keys: parsed_keys, keys: parsed_keys,
@ -890,11 +888,11 @@ impl ExtractPolicy for Descriptor<DescriptorPublicKey> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::descriptor; use crate::descriptor;
use crate::descriptor::{ExtractPolicy, ToWalletDescriptor}; use crate::descriptor::{ExtractPolicy, IntoWalletDescriptor};
use super::*; use super::*;
use crate::descriptor::policy::SatisfiableItem::{Multisig, Signature, Thresh}; use crate::descriptor::policy::SatisfiableItem::{Multisig, Signature, Thresh};
use crate::keys::{DescriptorKey, ToDescriptorKey}; use crate::keys::{DescriptorKey, IntoDescriptorKey};
use crate::wallet::signer::SignersContainer; use crate::wallet::signer::SignersContainer;
use bitcoin::secp256k1::{All, Secp256k1}; use bitcoin::secp256k1::{All, Secp256k1};
use bitcoin::util::bip32; use bitcoin::util::bip32;
@ -915,8 +913,8 @@ mod test {
let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap(); let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap();
let tpub = bip32::ExtendedPubKey::from_private(&secp, &tprv); let tpub = bip32::ExtendedPubKey::from_private(&secp, &tprv);
let fingerprint = tprv.fingerprint(&secp); let fingerprint = tprv.fingerprint(&secp);
let prvkey = (tprv, path.clone()).to_descriptor_key().unwrap(); let prvkey = (tprv, path.clone()).into_descriptor_key().unwrap();
let pubkey = (tpub, path).to_descriptor_key().unwrap(); let pubkey = (tpub, path).into_descriptor_key().unwrap();
(prvkey, pubkey, fingerprint) (prvkey, pubkey, fingerprint)
} }
@ -929,7 +927,9 @@ mod test {
let (prvkey, pubkey, fingerprint) = setup_keys(TPRV0_STR); let (prvkey, pubkey, fingerprint) = setup_keys(TPRV0_STR);
let desc = descriptor!(wpkh(pubkey)).unwrap(); let desc = descriptor!(wpkh(pubkey)).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers_container = Arc::new(SignersContainer::from(keymap)); let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = wallet_desc let policy = wallet_desc
.extract_policy(&signers_container, &Secp256k1::new()) .extract_policy(&signers_container, &Secp256k1::new())
@ -942,7 +942,9 @@ mod test {
assert!(matches!(&policy.contribution, Satisfaction::None)); assert!(matches!(&policy.contribution, Satisfaction::None));
let desc = descriptor!(wpkh(prvkey)).unwrap(); let desc = descriptor!(wpkh(prvkey)).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers_container = Arc::new(SignersContainer::from(keymap)); let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = wallet_desc let policy = wallet_desc
.extract_policy(&signers_container, &Secp256k1::new()) .extract_policy(&signers_container, &Secp256k1::new())
@ -1025,7 +1027,9 @@ mod test {
let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR); let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR);
let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR); let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR);
let desc = descriptor!(sh(multi(1, pubkey0, prvkey1))).unwrap(); let desc = descriptor!(sh(multi(1, pubkey0, prvkey1))).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers_container = Arc::new(SignersContainer::from(keymap)); let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = wallet_desc let policy = wallet_desc
.extract_policy(&signers_container, &Secp256k1::new()) .extract_policy(&signers_container, &Secp256k1::new())
@ -1055,7 +1059,9 @@ mod test {
let (prvkey0, _pubkey0, fingerprint0) = setup_keys(TPRV0_STR); let (prvkey0, _pubkey0, fingerprint0) = setup_keys(TPRV0_STR);
let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR); let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR);
let desc = descriptor!(sh(multi(2, prvkey0, prvkey1))).unwrap(); let desc = descriptor!(sh(multi(2, prvkey0, prvkey1))).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers_container = Arc::new(SignersContainer::from(keymap)); let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = wallet_desc let policy = wallet_desc
.extract_policy(&signers_container, &Secp256k1::new()) .extract_policy(&signers_container, &Secp256k1::new())
@ -1085,7 +1091,9 @@ mod test {
let (prvkey, pubkey, fingerprint) = setup_keys(TPRV0_STR); let (prvkey, pubkey, fingerprint) = setup_keys(TPRV0_STR);
let desc = descriptor!(wpkh(pubkey)).unwrap(); let desc = descriptor!(wpkh(pubkey)).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let single_key = wallet_desc.derive(0); let single_key = wallet_desc.derive(0);
let signers_container = Arc::new(SignersContainer::from(keymap)); let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = single_key let policy = single_key
@ -1099,7 +1107,9 @@ mod test {
assert!(matches!(&policy.contribution, Satisfaction::None)); assert!(matches!(&policy.contribution, Satisfaction::None));
let desc = descriptor!(wpkh(prvkey)).unwrap(); let desc = descriptor!(wpkh(prvkey)).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let single_key = wallet_desc.derive(0); let single_key = wallet_desc.derive(0);
let signers_container = Arc::new(SignersContainer::from(keymap)); let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = single_key let policy = single_key
@ -1124,7 +1134,9 @@ mod test {
let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR); let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR);
let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR); let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR);
let desc = descriptor!(sh(multi(1, pubkey0, prvkey1))).unwrap(); let desc = descriptor!(sh(multi(1, pubkey0, prvkey1))).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let single_key = wallet_desc.derive(0); let single_key = wallet_desc.derive(0);
let signers_container = Arc::new(SignersContainer::from(keymap)); let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = single_key let policy = single_key
@ -1166,7 +1178,9 @@ mod test {
))) )))
.unwrap(); .unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers_container = Arc::new(SignersContainer::from(keymap)); let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = wallet_desc let policy = wallet_desc
.extract_policy(&signers_container, &Secp256k1::new()) .extract_policy(&signers_container, &Secp256k1::new())

View File

@ -32,9 +32,9 @@ use bitcoin::Network;
use miniscript::{Legacy, Segwitv0}; use miniscript::{Legacy, Segwitv0};
use super::{ExtendedDescriptor, KeyMap, ToWalletDescriptor}; use super::{ExtendedDescriptor, IntoWalletDescriptor, KeyMap};
use crate::descriptor::DescriptorError; use crate::descriptor::DescriptorError;
use crate::keys::{DerivableKey, ToDescriptorKey, ValidNetworks}; use crate::keys::{DerivableKey, IntoDescriptorKey, ValidNetworks};
use crate::wallet::utils::SecpCtx; use crate::wallet::utils::SecpCtx;
use crate::{descriptor, KeychainKind}; use crate::{descriptor, KeychainKind};
@ -43,20 +43,20 @@ pub type DescriptorTemplateOut = (ExtendedDescriptor, KeyMap, ValidNetworks);
/// Trait for descriptor templates that can be built into a full descriptor /// Trait for descriptor templates that can be built into a full descriptor
/// ///
/// Since [`ToWalletDescriptor`] is implemented for any [`DescriptorTemplate`], they can also be /// Since [`IntoWalletDescriptor`] is implemented for any [`DescriptorTemplate`], they can also be
/// passed directly to the [`Wallet`](crate::Wallet) constructor. /// passed directly to the [`Wallet`](crate::Wallet) constructor.
/// ///
/// ## Example /// ## Example
/// ///
/// ``` /// ```
/// use bdk::descriptor::error::Error as DescriptorError; /// use bdk::descriptor::error::Error as DescriptorError;
/// use bdk::keys::{KeyError, ToDescriptorKey}; /// use bdk::keys::{KeyError, IntoDescriptorKey};
/// use bdk::miniscript::Legacy; /// use bdk::miniscript::Legacy;
/// use bdk::template::{DescriptorTemplate, DescriptorTemplateOut}; /// use bdk::template::{DescriptorTemplate, DescriptorTemplateOut};
/// ///
/// struct MyP2PKH<K: ToDescriptorKey<Legacy>>(K); /// struct MyP2PKH<K: IntoDescriptorKey<Legacy>>(K);
/// ///
/// impl<K: ToDescriptorKey<Legacy>> DescriptorTemplate for MyP2PKH<K> { /// impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for MyP2PKH<K> {
/// fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> { /// fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> {
/// Ok(bdk::descriptor!(pkh(self.0))?) /// Ok(bdk::descriptor!(pkh(self.0))?)
/// } /// }
@ -69,13 +69,13 @@ pub trait DescriptorTemplate {
/// Turns a [`DescriptorTemplate`] into a valid wallet descriptor by calling its /// Turns a [`DescriptorTemplate`] into a valid wallet descriptor by calling its
/// [`build`](DescriptorTemplate::build) method /// [`build`](DescriptorTemplate::build) method
impl<T: DescriptorTemplate> ToWalletDescriptor for T { impl<T: DescriptorTemplate> IntoWalletDescriptor for T {
fn to_wallet_descriptor( fn into_wallet_descriptor(
self, self,
secp: &SecpCtx, secp: &SecpCtx,
network: Network, network: Network,
) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> { ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
Ok(self.build()?.to_wallet_descriptor(secp, network)?) Ok(self.build()?.into_wallet_descriptor(secp, network)?)
} }
} }
@ -104,9 +104,9 @@ impl<T: DescriptorTemplate> ToWalletDescriptor for T {
/// ); /// );
/// # Ok::<_, Box<dyn std::error::Error>>(()) /// # Ok::<_, Box<dyn std::error::Error>>(())
/// ``` /// ```
pub struct P2PKH<K: ToDescriptorKey<Legacy>>(pub K); pub struct P2PKH<K: IntoDescriptorKey<Legacy>>(pub K);
impl<K: ToDescriptorKey<Legacy>> DescriptorTemplate for P2PKH<K> { impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for P2PKH<K> {
fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> { fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> {
Ok(descriptor!(pkh(self.0))?) Ok(descriptor!(pkh(self.0))?)
} }
@ -138,9 +138,9 @@ impl<K: ToDescriptorKey<Legacy>> DescriptorTemplate for P2PKH<K> {
/// # Ok::<_, Box<dyn std::error::Error>>(()) /// # Ok::<_, Box<dyn std::error::Error>>(())
/// ``` /// ```
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct P2WPKH_P2SH<K: ToDescriptorKey<Segwitv0>>(pub K); pub struct P2WPKH_P2SH<K: IntoDescriptorKey<Segwitv0>>(pub K);
impl<K: ToDescriptorKey<Segwitv0>> DescriptorTemplate for P2WPKH_P2SH<K> { impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2WPKH_P2SH<K> {
fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> { fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> {
Ok(descriptor!(sh(wpkh(self.0)))?) Ok(descriptor!(sh(wpkh(self.0)))?)
} }
@ -171,9 +171,9 @@ impl<K: ToDescriptorKey<Segwitv0>> DescriptorTemplate for P2WPKH_P2SH<K> {
/// ); /// );
/// # Ok::<_, Box<dyn std::error::Error>>(()) /// # Ok::<_, Box<dyn std::error::Error>>(())
/// ``` /// ```
pub struct P2WPKH<K: ToDescriptorKey<Segwitv0>>(pub K); pub struct P2WPKH<K: IntoDescriptorKey<Segwitv0>>(pub K);
impl<K: ToDescriptorKey<Segwitv0>> DescriptorTemplate for P2WPKH<K> { impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2WPKH<K> {
fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> { fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> {
Ok(descriptor!(wpkh(self.0))?) Ok(descriptor!(wpkh(self.0))?)
} }
@ -410,7 +410,7 @@ macro_rules! expand_make_bipxx {
bip: u32, bip: u32,
key: K, key: K,
keychain: KeychainKind, keychain: KeychainKind,
) -> Result<impl ToDescriptorKey<$ctx>, DescriptorError> { ) -> Result<impl IntoDescriptorKey<$ctx>, DescriptorError> {
let mut derivation_path = Vec::with_capacity(4); let mut derivation_path = Vec::with_capacity(4);
derivation_path.push(bip32::ChildNumber::from_hardened_idx(bip)?); derivation_path.push(bip32::ChildNumber::from_hardened_idx(bip)?);
derivation_path.push(bip32::ChildNumber::from_hardened_idx(0)?); derivation_path.push(bip32::ChildNumber::from_hardened_idx(0)?);
@ -434,7 +434,7 @@ macro_rules! expand_make_bipxx {
key: K, key: K,
parent_fingerprint: bip32::Fingerprint, parent_fingerprint: bip32::Fingerprint,
keychain: KeychainKind, keychain: KeychainKind,
) -> Result<impl ToDescriptorKey<$ctx>, DescriptorError> { ) -> Result<impl IntoDescriptorKey<$ctx>, DescriptorError> {
let derivation_path: bip32::DerivationPath = match keychain { let derivation_path: bip32::DerivationPath = match keychain {
KeychainKind::External => vec![bip32::ChildNumber::from_normal_idx(0)?].into(), KeychainKind::External => vec![bip32::ChildNumber::from_normal_idx(0)?].into(),
KeychainKind::Internal => vec![bip32::ChildNumber::from_normal_idx(1)?].into(), KeychainKind::Internal => vec![bip32::ChildNumber::from_normal_idx(1)?].into(),

View File

@ -205,15 +205,15 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// ``` /// ```
/// use bdk::bitcoin::PublicKey; /// use bdk::bitcoin::PublicKey;
/// ///
/// use bdk::keys::{DescriptorKey, KeyError, ScriptContext, ToDescriptorKey}; /// use bdk::keys::{DescriptorKey, KeyError, ScriptContext, IntoDescriptorKey};
/// ///
/// pub struct MyKeyType { /// pub struct MyKeyType {
/// pubkey: PublicKey, /// pubkey: PublicKey,
/// } /// }
/// ///
/// impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for MyKeyType { /// impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
/// fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { /// fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
/// self.pubkey.to_descriptor_key() /// self.pubkey.into_descriptor_key()
/// } /// }
/// } /// }
/// ``` /// ```
@ -225,15 +225,15 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// ///
/// use bdk::keys::{ /// use bdk::keys::{
/// mainnet_network, DescriptorKey, DescriptorPublicKey, DescriptorSinglePub, KeyError, /// mainnet_network, DescriptorKey, DescriptorPublicKey, DescriptorSinglePub, KeyError,
/// ScriptContext, ToDescriptorKey, /// ScriptContext, IntoDescriptorKey,
/// }; /// };
/// ///
/// pub struct MyKeyType { /// pub struct MyKeyType {
/// pubkey: PublicKey, /// pubkey: PublicKey,
/// } /// }
/// ///
/// impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for MyKeyType { /// impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
/// fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { /// fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
/// Ok(DescriptorKey::from_public( /// Ok(DescriptorKey::from_public(
/// DescriptorPublicKey::SinglePub(DescriptorSinglePub { /// DescriptorPublicKey::SinglePub(DescriptorSinglePub {
/// origin: None, /// origin: None,
@ -250,17 +250,17 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// ``` /// ```
/// use bdk::bitcoin::PublicKey; /// use bdk::bitcoin::PublicKey;
/// ///
/// use bdk::keys::{DescriptorKey, ExtScriptContext, KeyError, ScriptContext, ToDescriptorKey}; /// use bdk::keys::{DescriptorKey, ExtScriptContext, KeyError, ScriptContext, IntoDescriptorKey};
/// ///
/// pub struct MyKeyType { /// pub struct MyKeyType {
/// is_legacy: bool, /// is_legacy: bool,
/// pubkey: PublicKey, /// pubkey: PublicKey,
/// } /// }
/// ///
/// impl<Ctx: ScriptContext + 'static> ToDescriptorKey<Ctx> for MyKeyType { /// impl<Ctx: ScriptContext + 'static> IntoDescriptorKey<Ctx> for MyKeyType {
/// fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { /// fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
/// if Ctx::is_legacy() == self.is_legacy { /// if Ctx::is_legacy() == self.is_legacy {
/// self.pubkey.to_descriptor_key() /// self.pubkey.into_descriptor_key()
/// } else { /// } else {
/// Err(KeyError::InvalidScriptContext) /// Err(KeyError::InvalidScriptContext)
/// } /// }
@ -279,15 +279,15 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// use bdk::bitcoin::PublicKey; /// use bdk::bitcoin::PublicKey;
/// use std::str::FromStr; /// use std::str::FromStr;
/// ///
/// use bdk::keys::{DescriptorKey, KeyError, ToDescriptorKey}; /// use bdk::keys::{DescriptorKey, KeyError, IntoDescriptorKey};
/// ///
/// pub struct MySegwitOnlyKeyType { /// pub struct MySegwitOnlyKeyType {
/// pubkey: PublicKey, /// pubkey: PublicKey,
/// } /// }
/// ///
/// impl ToDescriptorKey<bdk::miniscript::Segwitv0> for MySegwitOnlyKeyType { /// impl IntoDescriptorKey<bdk::miniscript::Segwitv0> for MySegwitOnlyKeyType {
/// fn to_descriptor_key(self) -> Result<DescriptorKey<bdk::miniscript::Segwitv0>, KeyError> { /// fn into_descriptor_key(self) -> Result<DescriptorKey<bdk::miniscript::Segwitv0>, KeyError> {
/// self.pubkey.to_descriptor_key() /// self.pubkey.into_descriptor_key()
/// } /// }
/// } /// }
/// ///
@ -299,9 +299,9 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// ///
/// # Ok::<_, Box<dyn std::error::Error>>(()) /// # Ok::<_, Box<dyn std::error::Error>>(())
/// ``` /// ```
pub trait ToDescriptorKey<Ctx: ScriptContext>: Sized { pub trait IntoDescriptorKey<Ctx: ScriptContext>: Sized {
/// Turn the key into a [`DescriptorKey`] within the requested [`ScriptContext`] /// Turn the key into a [`DescriptorKey`] within the requested [`ScriptContext`]
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>; fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>;
} }
/// Enum for extended keys that can be either `xprv` or `xpub` /// Enum for extended keys that can be either `xprv` or `xpub`
@ -370,12 +370,12 @@ impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
/// Trait for keys that can be derived. /// Trait for keys that can be derived.
/// ///
/// When extra metadata are provided, a [`DerivableKey`] can be transofrmed into a /// When extra metadata are provided, a [`DerivableKey`] can be transofrmed into a
/// [`DescriptorKey`]: the trait [`ToDescriptorKey`] is automatically implemented /// [`DescriptorKey`]: the trait [`IntoDescriptorKey`] is automatically implemented
/// for `(DerivableKey, DerivationPath)` and /// for `(DerivableKey, DerivationPath)` and
/// `(DerivableKey, KeySource, DerivationPath)` tuples. /// `(DerivableKey, KeySource, DerivationPath)` tuples.
/// ///
/// For key types that don't encode any indication about the path to use (like bip39), it's /// For key types that don't encode any indication about the path to use (like bip39), it's
/// generally recommended to implemented this trait instead of [`ToDescriptorKey`]. The same /// generally recommended to implemented this trait instead of [`IntoDescriptorKey`]. The same
/// rules regarding script context and valid networks apply. /// rules regarding script context and valid networks apply.
/// ///
/// ## Examples /// ## Examples
@ -499,14 +499,14 @@ let xprv = xkey.into_xprv(Network::Bitcoin).unwrap();
derivation_path, derivation_path,
wildcard: Wildcard::Unhardened, wildcard: Wildcard::Unhardened,
}) })
.to_descriptor_key(), .into_descriptor_key(),
ExtendedKey::Public((xpub, _)) => DescriptorPublicKey::XPub(DescriptorXKey { ExtendedKey::Public((xpub, _)) => DescriptorPublicKey::XPub(DescriptorXKey {
origin, origin,
xkey: xpub, xkey: xpub,
derivation_path, derivation_path,
wildcard: Wildcard::Unhardened, wildcard: Wildcard::Unhardened,
}) })
.to_descriptor_key(), .into_descriptor_key(),
} }
} }
} }
@ -583,25 +583,25 @@ where
// Make generated keys directly usable in descriptors, and make sure they get assigned the right // Make generated keys directly usable in descriptors, and make sure they get assigned the right
// `valid_networks`. // `valid_networks`.
impl<Ctx, K> ToDescriptorKey<Ctx> for GeneratedKey<K, Ctx> impl<Ctx, K> IntoDescriptorKey<Ctx> for GeneratedKey<K, Ctx>
where where
Ctx: ScriptContext, Ctx: ScriptContext,
K: ToDescriptorKey<Ctx>, K: IntoDescriptorKey<Ctx>,
{ {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
let desc_key = self.key.to_descriptor_key()?; let desc_key = self.key.into_descriptor_key()?;
Ok(desc_key.override_valid_networks(self.valid_networks)) Ok(desc_key.override_valid_networks(self.valid_networks))
} }
} }
/// Trait for keys that can be generated /// Trait for keys that can be generated
/// ///
/// The same rules about [`ScriptContext`] and [`ValidNetworks`] from [`ToDescriptorKey`] apply. /// The same rules about [`ScriptContext`] and [`ValidNetworks`] from [`IntoDescriptorKey`] apply.
/// ///
/// This trait is particularly useful when combined with [`DerivableKey`]: if `Self` /// This trait is particularly useful when combined with [`DerivableKey`]: if `Self`
/// implements it, the returned [`GeneratedKey`] will also implement it. The same is true for /// implements it, the returned [`GeneratedKey`] will also implement it. The same is true for
/// [`ToDescriptorKey`]: the generated keys can be directly used in descriptors if `Self` is also /// [`IntoDescriptorKey`]: the generated keys can be directly used in descriptors if `Self` is also
/// [`ToDescriptorKey`]. /// [`IntoDescriptorKey`].
pub trait GeneratableKey<Ctx: ScriptContext>: Sized { pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
/// Type specifying the amount of entropy required e.g. `[u8;32]` /// Type specifying the amount of entropy required e.g. `[u8;32]`
type Entropy: AsMut<[u8]> + Default; type Entropy: AsMut<[u8]> + Default;
@ -711,27 +711,29 @@ impl<Ctx: ScriptContext> GeneratableKey<Ctx> for PrivateKey {
} }
} }
impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> ToDescriptorKey<Ctx> for (T, bip32::DerivationPath) { impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx>
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { for (T, bip32::DerivationPath)
{
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
self.0.into_descriptor_key(None, self.1) self.0.into_descriptor_key(None, self.1)
} }
} }
impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> ToDescriptorKey<Ctx> impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx>
for (T, bip32::KeySource, bip32::DerivationPath) for (T, bip32::KeySource, bip32::DerivationPath)
{ {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
self.0.into_descriptor_key(Some(self.1), self.2) self.0.into_descriptor_key(Some(self.1), self.2)
} }
} }
fn expand_multi_keys<Pk: ToDescriptorKey<Ctx>, Ctx: ScriptContext>( fn expand_multi_keys<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
pks: Vec<Pk>, pks: Vec<Pk>,
secp: &SecpCtx, secp: &SecpCtx,
) -> Result<(Vec<DescriptorPublicKey>, KeyMap, ValidNetworks), KeyError> { ) -> Result<(Vec<DescriptorPublicKey>, KeyMap, ValidNetworks), KeyError> {
let (pks, key_maps_networks): (Vec<_>, Vec<_>) = pks let (pks, key_maps_networks): (Vec<_>, Vec<_>) = pks
.into_iter() .into_iter()
.map(|key| Ok::<_, KeyError>(key.to_descriptor_key()?.extract(secp)?)) .map(|key| Ok::<_, KeyError>(key.into_descriptor_key()?.extract(secp)?))
.collect::<Result<Vec<_>, _>>()? .collect::<Result<Vec<_>, _>>()?
.into_iter() .into_iter()
.map(|(a, b, c)| (a, (b, c))) .map(|(a, b, c)| (a, (b, c)))
@ -752,11 +754,11 @@ fn expand_multi_keys<Pk: ToDescriptorKey<Ctx>, Ctx: ScriptContext>(
// Used internally by `bdk::fragment!` to build `pk_k()` fragments // Used internally by `bdk::fragment!` to build `pk_k()` fragments
#[doc(hidden)] #[doc(hidden)]
pub fn make_pk<Pk: ToDescriptorKey<Ctx>, Ctx: ScriptContext>( pub fn make_pk<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
descriptor_key: Pk, descriptor_key: Pk,
secp: &SecpCtx, secp: &SecpCtx,
) -> Result<(Miniscript<DescriptorPublicKey, Ctx>, KeyMap, ValidNetworks), DescriptorError> { ) -> Result<(Miniscript<DescriptorPublicKey, Ctx>, KeyMap, ValidNetworks), DescriptorError> {
let (key, key_map, valid_networks) = descriptor_key.to_descriptor_key()?.extract(secp)?; let (key, key_map, valid_networks) = descriptor_key.into_descriptor_key()?.extract(secp)?;
let minisc = Miniscript::from_ast(Terminal::PkK(key))?; let minisc = Miniscript::from_ast(Terminal::PkK(key))?;
minisc.check_minsicript()?; minisc.check_minsicript()?;
@ -766,7 +768,7 @@ pub fn make_pk<Pk: ToDescriptorKey<Ctx>, Ctx: ScriptContext>(
// Used internally by `bdk::fragment!` to build `multi()` fragments // Used internally by `bdk::fragment!` to build `multi()` fragments
#[doc(hidden)] #[doc(hidden)]
pub fn make_multi<Pk: ToDescriptorKey<Ctx>, Ctx: ScriptContext>( pub fn make_multi<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
thresh: usize, thresh: usize,
pks: Vec<Pk>, pks: Vec<Pk>,
secp: &SecpCtx, secp: &SecpCtx,
@ -788,7 +790,7 @@ pub fn make_sortedmulti<Pk, Ctx, F>(
secp: &SecpCtx, secp: &SecpCtx,
) -> Result<(Descriptor<DescriptorPublicKey>, KeyMap, ValidNetworks), DescriptorError> ) -> Result<(Descriptor<DescriptorPublicKey>, KeyMap, ValidNetworks), DescriptorError>
where where
Pk: ToDescriptorKey<Ctx>, Pk: IntoDescriptorKey<Ctx>,
Ctx: ScriptContext, Ctx: ScriptContext,
F: Fn( F: Fn(
usize, usize,
@ -802,14 +804,14 @@ where
} }
/// The "identity" conversion is used internally by some `bdk::fragment`s /// The "identity" conversion is used internally by some `bdk::fragment`s
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for DescriptorKey<Ctx> { impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorKey<Ctx> {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
Ok(self) Ok(self)
} }
} }
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for DescriptorPublicKey { impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
let networks = match self { let networks = match self {
DescriptorPublicKey::SinglePub(_) => any_network(), DescriptorPublicKey::SinglePub(_) => any_network(),
DescriptorPublicKey::XPub(DescriptorXKey { xkey, .. }) DescriptorPublicKey::XPub(DescriptorXKey { xkey, .. })
@ -824,18 +826,18 @@ impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for DescriptorPublicKey {
} }
} }
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for PublicKey { impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PublicKey {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
DescriptorPublicKey::SinglePub(DescriptorSinglePub { DescriptorPublicKey::SinglePub(DescriptorSinglePub {
key: self, key: self,
origin: None, origin: None,
}) })
.to_descriptor_key() .into_descriptor_key()
} }
} }
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for DescriptorSecretKey { impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
let networks = match &self { let networks = match &self {
DescriptorSecretKey::SinglePriv(sk) if sk.key.network == Network::Bitcoin => { DescriptorSecretKey::SinglePriv(sk) if sk.key.network == Network::Bitcoin => {
mainnet_network() mainnet_network()
@ -852,21 +854,21 @@ impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for DescriptorSecretKey {
} }
} }
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for &'_ str { impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for &'_ str {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
DescriptorSecretKey::from_str(self) DescriptorSecretKey::from_str(self)
.map_err(|e| KeyError::Message(e.to_string()))? .map_err(|e| KeyError::Message(e.to_string()))?
.to_descriptor_key() .into_descriptor_key()
} }
} }
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for PrivateKey { impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PrivateKey {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> { fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
DescriptorSecretKey::SinglePriv(DescriptorSinglePriv { DescriptorSecretKey::SinglePriv(DescriptorSinglePriv {
key: self, key: self,
origin: None, origin: None,
}) })
.to_descriptor_key() .into_descriptor_key()
} }
} }

View File

@ -67,7 +67,7 @@ use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
use crate::descriptor::derived::AsDerived; use crate::descriptor::derived::AsDerived;
use crate::descriptor::{ use crate::descriptor::{
get_checksum, DerivedDescriptor, DerivedDescriptorMeta, DescriptorMeta, DescriptorScripts, get_checksum, DerivedDescriptor, DerivedDescriptorMeta, DescriptorMeta, DescriptorScripts,
ExtendedDescriptor, ExtractPolicy, Policy, ToWalletDescriptor, XKeyUtils, ExtendedDescriptor, ExtractPolicy, IntoWalletDescriptor, Policy, XKeyUtils,
}; };
use crate::error::Error; use crate::error::Error;
use crate::psbt::PSBTUtils; use crate::psbt::PSBTUtils;
@ -110,7 +110,7 @@ where
D: BatchDatabase, D: BatchDatabase,
{ {
/// Create a new "offline" wallet /// Create a new "offline" wallet
pub fn new_offline<E: ToWalletDescriptor>( pub fn new_offline<E: IntoWalletDescriptor>(
descriptor: E, descriptor: E,
change_descriptor: Option<E>, change_descriptor: Option<E>,
network: Network, network: Network,
@ -124,7 +124,7 @@ impl<B, D> Wallet<B, D>
where where
D: BatchDatabase, D: BatchDatabase,
{ {
fn _new<E: ToWalletDescriptor>( fn _new<E: IntoWalletDescriptor>(
descriptor: E, descriptor: E,
change_descriptor: Option<E>, change_descriptor: Option<E>,
network: Network, network: Network,
@ -134,7 +134,7 @@ where
) -> Result<Self, Error> { ) -> Result<Self, Error> {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let (descriptor, keymap) = descriptor.to_wallet_descriptor(&secp, network)?; let (descriptor, keymap) = descriptor.into_wallet_descriptor(&secp, network)?;
database.check_descriptor_checksum( database.check_descriptor_checksum(
KeychainKind::External, KeychainKind::External,
get_checksum(&descriptor.to_string())?.as_bytes(), get_checksum(&descriptor.to_string())?.as_bytes(),
@ -143,7 +143,7 @@ where
let (change_descriptor, change_signers) = match change_descriptor { let (change_descriptor, change_signers) = match change_descriptor {
Some(desc) => { Some(desc) => {
let (change_descriptor, change_keymap) = let (change_descriptor, change_keymap) =
desc.to_wallet_descriptor(&secp, network)?; desc.into_wallet_descriptor(&secp, network)?;
database.check_descriptor_checksum( database.check_descriptor_checksum(
KeychainKind::Internal, KeychainKind::Internal,
get_checksum(&change_descriptor.to_string())?.as_bytes(), get_checksum(&change_descriptor.to_string())?.as_bytes(),
@ -1247,7 +1247,7 @@ where
{ {
/// Create a new "online" wallet /// Create a new "online" wallet
#[maybe_async] #[maybe_async]
pub fn new<E: ToWalletDescriptor>( pub fn new<E: IntoWalletDescriptor>(
descriptor: E, descriptor: E,
change_descriptor: Option<E>, change_descriptor: Option<E>,
network: Network, network: Network,

View File

@ -560,8 +560,8 @@ impl Eq for SignersContainerKey {}
mod signers_container_tests { mod signers_container_tests {
use super::*; use super::*;
use crate::descriptor; use crate::descriptor;
use crate::descriptor::ToWalletDescriptor; use crate::descriptor::IntoWalletDescriptor;
use crate::keys::{DescriptorKey, ToDescriptorKey}; use crate::keys::{DescriptorKey, IntoDescriptorKey};
use bitcoin::secp256k1::{All, Secp256k1}; use bitcoin::secp256k1::{All, Secp256k1};
use bitcoin::util::bip32; use bitcoin::util::bip32;
use bitcoin::util::psbt::PartiallySignedTransaction; use bitcoin::util::psbt::PartiallySignedTransaction;
@ -579,7 +579,9 @@ mod signers_container_tests {
let (prvkey1, _, _) = setup_keys(TPRV0_STR); let (prvkey1, _, _) = setup_keys(TPRV0_STR);
let (prvkey2, _, _) = setup_keys(TPRV1_STR); let (prvkey2, _, _) = setup_keys(TPRV1_STR);
let desc = descriptor!(sh(multi(2, prvkey1, prvkey2))).unwrap(); let desc = descriptor!(sh(multi(2, prvkey1, prvkey2))).unwrap();
let (_, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap(); let (_, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers = SignersContainer::from(keymap); let signers = SignersContainer::from(keymap);
assert_eq!(signers.ids().len(), 2); assert_eq!(signers.ids().len(), 2);
@ -690,8 +692,8 @@ mod signers_container_tests {
let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap(); let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap();
let tpub = bip32::ExtendedPubKey::from_private(&secp, &tprv); let tpub = bip32::ExtendedPubKey::from_private(&secp, &tprv);
let fingerprint = tprv.fingerprint(&secp); let fingerprint = tprv.fingerprint(&secp);
let prvkey = (tprv, path.clone()).to_descriptor_key().unwrap(); let prvkey = (tprv, path.clone()).into_descriptor_key().unwrap();
let pubkey = (tpub, path).to_descriptor_key().unwrap(); let pubkey = (tpub, path).into_descriptor_key().unwrap();
(prvkey, pubkey, fingerprint) (prvkey, pubkey, fingerprint)
} }