Merge branch 'master' into release/0.4.0
Merging in fixes for the CI after Rust 1.50.0
This commit is contained in:
commit
d0ffcdd009
@ -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]
|
||||||
|
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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())
|
||||||
|
@ -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(),
|
||||||
|
108
src/keys/mod.rs
108
src/keys/mod.rs
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user