feat!: improve wallet building methods
Remove returning `Result` for builder methods on `CreateParams` and `LoadParams`.
This commit is contained in:
parent
eb73f0659e
commit
22d02ed3d1
@ -7,7 +7,7 @@
|
||||
//! # use bdk_wallet::descriptor::Descriptor;
|
||||
//! # use bdk_wallet::signer::SignerOrdering;
|
||||
//! # use bdk_hwi::HWISigner;
|
||||
//! # use bdk_wallet::{KeychainKind, SignOptions};
|
||||
//! # use bdk_wallet::{KeychainKind, SignOptions, Wallet};
|
||||
//! # use hwi::HWIClient;
|
||||
//! # use std::sync::Arc;
|
||||
//! # use std::str::FromStr;
|
||||
@ -20,8 +20,7 @@
|
||||
//! let first_device = devices.remove(0)?;
|
||||
//! let custom_signer = HWISigner::from_device(&first_device, Network::Testnet.into())?;
|
||||
//!
|
||||
//! # let mut wallet = bdk_wallet::CreateParams::new("", "", Network::Testnet)?
|
||||
//! # .create_wallet_no_persist()?;
|
||||
//! # let mut wallet = Wallet::create("", "").network(Network::Testnet).create_wallet_no_persist()?;
|
||||
//! #
|
||||
//! // Adding the hardware signer to the BDK wallet
|
||||
//! wallet.add_signer(
|
||||
|
@ -67,7 +67,7 @@ To persist `Wallet` state data use a data store crate that reads and writes [`Ch
|
||||
|
||||
<!-- compile_fail because outpoint and txout are fake variables -->
|
||||
```rust,no_run
|
||||
use bdk_wallet::{bitcoin::Network, CreateParams, LoadParams, KeychainKind, ChangeSet};
|
||||
use bdk_wallet::{bitcoin::Network, KeychainKind, ChangeSet, Wallet};
|
||||
|
||||
// Open or create a new file store for wallet data.
|
||||
let mut db =
|
||||
@ -78,13 +78,17 @@ let mut db =
|
||||
let network = Network::Testnet;
|
||||
let descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/0/*)";
|
||||
let change_descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/1/*)";
|
||||
let load_params = LoadParams::with_descriptors(descriptor, change_descriptor, network)
|
||||
.expect("must parse descriptors");
|
||||
let create_params = CreateParams::new(descriptor, change_descriptor, network)
|
||||
.expect("must parse descriptors");
|
||||
let mut wallet = match load_params.load_wallet(&mut db).expect("wallet") {
|
||||
let wallet_opt = Wallet::load()
|
||||
.descriptors(descriptor, change_descriptor)
|
||||
.network(network)
|
||||
.load_wallet(&mut db)
|
||||
.expect("wallet");
|
||||
let mut wallet = match wallet_opt {
|
||||
Some(wallet) => wallet,
|
||||
None => create_params.create_wallet(&mut db).expect("wallet"),
|
||||
None => Wallet::create(descriptor, change_descriptor)
|
||||
.network(network)
|
||||
.create_wallet(&mut db)
|
||||
.expect("wallet"),
|
||||
};
|
||||
|
||||
// Get a new address to receive bitcoin.
|
||||
|
@ -21,7 +21,7 @@ use bitcoin::Network;
|
||||
use miniscript::policy::Concrete;
|
||||
use miniscript::Descriptor;
|
||||
|
||||
use bdk_wallet::{CreateParams, KeychainKind};
|
||||
use bdk_wallet::{KeychainKind, Wallet};
|
||||
|
||||
/// Miniscript policy is a high level abstraction of spending conditions. Defined in the
|
||||
/// rust-miniscript library here https://docs.rs/miniscript/7.0.0/miniscript/policy/index.html
|
||||
@ -77,7 +77,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
);
|
||||
|
||||
// Create a new wallet from descriptors
|
||||
let mut wallet = CreateParams::new(&descriptor, &internal_descriptor, Network::Regtest)?
|
||||
let mut wallet = Wallet::create(descriptor, internal_descriptor)
|
||||
.network(Network::Regtest)
|
||||
.create_wallet_no_persist()?;
|
||||
|
||||
println!(
|
||||
|
@ -112,6 +112,16 @@ impl IntoWalletDescriptor for &String {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoWalletDescriptor for String {
|
||||
fn into_wallet_descriptor(
|
||||
self,
|
||||
secp: &SecpCtx,
|
||||
network: Network,
|
||||
) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
|
||||
self.as_str().into_wallet_descriptor(secp, network)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoWalletDescriptor for ExtendedDescriptor {
|
||||
fn into_wallet_descriptor(
|
||||
self,
|
||||
|
@ -73,7 +73,7 @@ impl<T: DescriptorTemplate> IntoWalletDescriptor for T {
|
||||
///
|
||||
/// ```
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::CreateParams;
|
||||
/// # use bdk_wallet::Wallet;
|
||||
/// # use bdk_wallet::KeychainKind;
|
||||
/// use bdk_wallet::template::P2Pkh;
|
||||
///
|
||||
@ -81,7 +81,8 @@ impl<T: DescriptorTemplate> IntoWalletDescriptor for T {
|
||||
/// bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
|
||||
/// let key_internal =
|
||||
/// bitcoin::PrivateKey::from_wif("cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW")?;
|
||||
/// let mut wallet = CreateParams::new(P2Pkh(key_external), P2Pkh(key_internal), Network::Testnet)?
|
||||
/// let mut wallet = Wallet::create(P2Pkh(key_external), P2Pkh(key_internal))
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
@ -92,6 +93,7 @@ impl<T: DescriptorTemplate> IntoWalletDescriptor for T {
|
||||
/// );
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct P2Pkh<K: IntoDescriptorKey<Legacy>>(pub K);
|
||||
|
||||
impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for P2Pkh<K> {
|
||||
@ -106,7 +108,7 @@ impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for P2Pkh<K> {
|
||||
///
|
||||
/// ```
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::CreateParams;
|
||||
/// # use bdk_wallet::Wallet;
|
||||
/// # use bdk_wallet::KeychainKind;
|
||||
/// use bdk_wallet::template::P2Wpkh_P2Sh;
|
||||
///
|
||||
@ -114,12 +116,9 @@ impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for P2Pkh<K> {
|
||||
/// bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
|
||||
/// let key_internal =
|
||||
/// bitcoin::PrivateKey::from_wif("cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW")?;
|
||||
/// let mut wallet = CreateParams::new(
|
||||
/// P2Wpkh_P2Sh(key_external),
|
||||
/// P2Wpkh_P2Sh(key_internal),
|
||||
/// Network::Testnet,
|
||||
/// )?
|
||||
/// .create_wallet_no_persist()?;
|
||||
/// let mut wallet = Wallet::create(P2Wpkh_P2Sh(key_external), P2Wpkh_P2Sh(key_internal))
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// wallet
|
||||
@ -130,6 +129,7 @@ impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for P2Pkh<K> {
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct P2Wpkh_P2Sh<K: IntoDescriptorKey<Segwitv0>>(pub K);
|
||||
|
||||
impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh_P2Sh<K> {
|
||||
@ -144,7 +144,7 @@ impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh_P2Sh<K> {
|
||||
///
|
||||
/// ```
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::CreateParams;
|
||||
/// # use bdk_wallet::Wallet;
|
||||
/// # use bdk_wallet::KeychainKind;
|
||||
/// use bdk_wallet::template::P2Wpkh;
|
||||
///
|
||||
@ -152,9 +152,9 @@ impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh_P2Sh<K> {
|
||||
/// bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
|
||||
/// let key_internal =
|
||||
/// bitcoin::PrivateKey::from_wif("cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW")?;
|
||||
/// let mut wallet =
|
||||
/// CreateParams::new(P2Wpkh(key_external), P2Wpkh(key_internal), Network::Testnet)?
|
||||
/// .create_wallet_no_persist()?;
|
||||
/// let mut wallet = Wallet::create(P2Wpkh(key_external), P2Wpkh(key_internal))
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// wallet
|
||||
@ -164,6 +164,7 @@ impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh_P2Sh<K> {
|
||||
/// );
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct P2Wpkh<K: IntoDescriptorKey<Segwitv0>>(pub K);
|
||||
|
||||
impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh<K> {
|
||||
@ -178,7 +179,7 @@ impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh<K> {
|
||||
///
|
||||
/// ```
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::CreateParams;
|
||||
/// # use bdk_wallet::Wallet;
|
||||
/// # use bdk_wallet::KeychainKind;
|
||||
/// use bdk_wallet::template::P2TR;
|
||||
///
|
||||
@ -186,7 +187,8 @@ impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh<K> {
|
||||
/// bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
|
||||
/// let key_internal =
|
||||
/// bitcoin::PrivateKey::from_wif("cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW")?;
|
||||
/// let mut wallet = CreateParams::new(P2TR(key_external), P2TR(key_internal), Network::Testnet)?
|
||||
/// let mut wallet = Wallet::create(P2TR(key_external), P2TR(key_internal))
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
@ -197,6 +199,7 @@ impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh<K> {
|
||||
/// );
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct P2TR<K: IntoDescriptorKey<Tap>>(pub K);
|
||||
|
||||
impl<K: IntoDescriptorKey<Tap>> DescriptorTemplate for P2TR<K> {
|
||||
@ -213,24 +216,22 @@ impl<K: IntoDescriptorKey<Tap>> DescriptorTemplate for P2TR<K> {
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// # use std::str::FromStr;
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::{CreateParams, KeychainKind};
|
||||
/// # use bdk_wallet::{Wallet, KeychainKind};
|
||||
/// use bdk_wallet::template::Bip44;
|
||||
///
|
||||
/// let key = bitcoin::bip32::Xpriv::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
|
||||
/// let mut wallet = CreateParams::new(
|
||||
/// Bip44(key.clone(), KeychainKind::External),
|
||||
/// Bip44(key, KeychainKind::Internal),
|
||||
/// Network::Testnet,
|
||||
/// )?
|
||||
/// .create_wallet_no_persist()?;
|
||||
/// let mut wallet = Wallet::create(Bip44(key.clone(), KeychainKind::External), Bip44(key, KeychainKind::Internal))
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(wallet.next_unused_address(KeychainKind::External).to_string(), "mmogjc7HJEZkrLqyQYqJmxUqFaC7i4uf89");
|
||||
/// assert_eq!(wallet.public_descriptor(KeychainKind::External).to_string(), "pkh([c55b303f/44'/1'/0']tpubDCuorCpzvYS2LCD75BR46KHE8GdDeg1wsAgNZeNr6DaB5gQK1o14uErKwKLuFmeemkQ6N2m3rNgvctdJLyr7nwu2yia7413Hhg8WWE44cgT/0/*)#5wrnv0xt");
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bip44<K: DerivableKey<Legacy>>(pub K, pub KeychainKind);
|
||||
|
||||
impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44<K> {
|
||||
@ -253,22 +254,23 @@ impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44<K> {
|
||||
/// ```
|
||||
/// # use std::str::FromStr;
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::{CreateParams, KeychainKind};
|
||||
/// # use bdk_wallet::{KeychainKind, Wallet};
|
||||
/// use bdk_wallet::template::Bip44Public;
|
||||
///
|
||||
/// let key = bitcoin::bip32::Xpub::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU")?;
|
||||
/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
|
||||
/// let mut wallet = CreateParams::new(
|
||||
/// let mut wallet = Wallet::create(
|
||||
/// Bip44Public(key.clone(), fingerprint, KeychainKind::External),
|
||||
/// Bip44Public(key, fingerprint, KeychainKind::Internal),
|
||||
/// Network::Testnet,
|
||||
/// )?
|
||||
/// )
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(wallet.next_unused_address(KeychainKind::External).to_string(), "miNG7dJTzJqNbFS19svRdTCisC65dsubtR");
|
||||
/// assert_eq!(wallet.public_descriptor(KeychainKind::External).to_string(), "pkh([c55b303f/44'/1'/0']tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU/0/*)#cfhumdqz");
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bip44Public<K: DerivableKey<Legacy>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
|
||||
|
||||
impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44Public<K> {
|
||||
@ -291,21 +293,22 @@ impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44Public<K> {
|
||||
/// ```
|
||||
/// # use std::str::FromStr;
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::{CreateParams, KeychainKind};
|
||||
/// # use bdk_wallet::{Wallet, KeychainKind};
|
||||
/// use bdk_wallet::template::Bip49;
|
||||
///
|
||||
/// let key = bitcoin::bip32::Xpriv::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
|
||||
/// let mut wallet = CreateParams::new(
|
||||
/// let mut wallet = Wallet::create(
|
||||
/// Bip49(key.clone(), KeychainKind::External),
|
||||
/// Bip49(key, KeychainKind::Internal),
|
||||
/// Network::Testnet,
|
||||
/// )?
|
||||
/// )
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(wallet.next_unused_address(KeychainKind::External).to_string(), "2N4zkWAoGdUv4NXhSsU8DvS5MB36T8nKHEB");
|
||||
/// assert_eq!(wallet.public_descriptor(KeychainKind::External).to_string(), "sh(wpkh([c55b303f/49'/1'/0']tpubDDYr4kdnZgjjShzYNjZUZXUUtpXaofdkMaipyS8ThEh45qFmhT4hKYways7UXmg6V7het1QiFo9kf4kYUXyDvV4rHEyvSpys9pjCB3pukxi/0/*))#s9vxlc8e");
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bip49<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
|
||||
|
||||
impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49<K> {
|
||||
@ -328,22 +331,23 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49<K> {
|
||||
/// ```
|
||||
/// # use std::str::FromStr;
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::{CreateParams, KeychainKind};
|
||||
/// # use bdk_wallet::{Wallet, KeychainKind};
|
||||
/// use bdk_wallet::template::Bip49Public;
|
||||
///
|
||||
/// let key = bitcoin::bip32::Xpub::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L")?;
|
||||
/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
|
||||
/// let mut wallet = CreateParams::new(
|
||||
/// let mut wallet = Wallet::create(
|
||||
/// Bip49Public(key.clone(), fingerprint, KeychainKind::External),
|
||||
/// Bip49Public(key, fingerprint, KeychainKind::Internal),
|
||||
/// Network::Testnet,
|
||||
/// )?
|
||||
/// )
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(wallet.next_unused_address(KeychainKind::External).to_string(), "2N3K4xbVAHoiTQSwxkZjWDfKoNC27pLkYnt");
|
||||
/// assert_eq!(wallet.public_descriptor(KeychainKind::External).to_string(), "sh(wpkh([c55b303f/49'/1'/0']tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L/0/*))#3tka9g0q");
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bip49Public<K: DerivableKey<Segwitv0>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
|
||||
|
||||
impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49Public<K> {
|
||||
@ -366,21 +370,22 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49Public<K> {
|
||||
/// ```
|
||||
/// # use std::str::FromStr;
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::{CreateParams, KeychainKind};
|
||||
/// # use bdk_wallet::{Wallet, KeychainKind};
|
||||
/// use bdk_wallet::template::Bip84;
|
||||
///
|
||||
/// let key = bitcoin::bip32::Xpriv::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
|
||||
/// let mut wallet = CreateParams::new(
|
||||
/// let mut wallet = Wallet::create(
|
||||
/// Bip84(key.clone(), KeychainKind::External),
|
||||
/// Bip84(key, KeychainKind::Internal),
|
||||
/// Network::Testnet,
|
||||
/// )?
|
||||
/// )
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(wallet.next_unused_address(KeychainKind::External).to_string(), "tb1qhl85z42h7r4su5u37rvvw0gk8j2t3n9y7zsg4n");
|
||||
/// assert_eq!(wallet.public_descriptor(KeychainKind::External).to_string(), "wpkh([c55b303f/84'/1'/0']tpubDDc5mum24DekpNw92t6fHGp8Gr2JjF9J7i4TZBtN6Vp8xpAULG5CFaKsfugWa5imhrQQUZKXe261asP5koDHo5bs3qNTmf3U3o4v9SaB8gg/0/*)#6kfecsmr");
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bip84<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
|
||||
|
||||
impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84<K> {
|
||||
@ -403,21 +408,23 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84<K> {
|
||||
/// ```
|
||||
/// # use std::str::FromStr;
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::{CreateParams, KeychainKind};
|
||||
/// # use bdk_wallet::{Wallet, KeychainKind};
|
||||
/// use bdk_wallet::template::Bip84Public;
|
||||
///
|
||||
/// let key = bitcoin::bip32::Xpub::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
|
||||
/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
|
||||
/// let mut wallet = CreateParams::new(
|
||||
/// let mut wallet = Wallet::create(
|
||||
/// Bip84Public(key.clone(), fingerprint, KeychainKind::External),
|
||||
/// Bip84Public(key, fingerprint, KeychainKind::Internal),
|
||||
/// Network::Testnet,
|
||||
/// )?.create_wallet_no_persist()?;
|
||||
/// )
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(wallet.next_unused_address(KeychainKind::External).to_string(), "tb1qedg9fdlf8cnnqfd5mks6uz5w4kgpk2pr6y4qc7");
|
||||
/// assert_eq!(wallet.public_descriptor(KeychainKind::External).to_string(), "wpkh([c55b303f/84'/1'/0']tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q/0/*)#dhu402yv");
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bip84Public<K: DerivableKey<Segwitv0>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
|
||||
|
||||
impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84Public<K> {
|
||||
@ -440,21 +447,22 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84Public<K> {
|
||||
/// ```
|
||||
/// # use std::str::FromStr;
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::{CreateParams, KeychainKind};
|
||||
/// # use bdk_wallet::{Wallet, KeychainKind};
|
||||
/// use bdk_wallet::template::Bip86;
|
||||
///
|
||||
/// let key = bitcoin::bip32::Xpriv::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
|
||||
/// let mut wallet = CreateParams::new(
|
||||
/// let mut wallet = Wallet::create(
|
||||
/// Bip86(key.clone(), KeychainKind::External),
|
||||
/// Bip86(key, KeychainKind::Internal),
|
||||
/// Network::Testnet,
|
||||
/// )?
|
||||
/// )
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(wallet.next_unused_address(KeychainKind::External).to_string(), "tb1p5unlj09djx8xsjwe97269kqtxqpwpu2epeskgqjfk4lnf69v4tnqpp35qu");
|
||||
/// assert_eq!(wallet.public_descriptor(KeychainKind::External).to_string(), "tr([c55b303f/86'/1'/0']tpubDCiHofpEs47kx358bPdJmTZHmCDqQ8qw32upCSxHrSEdeeBs2T5Mq6QMB2ukeMqhNBiyhosBvJErteVhfURPGXPv3qLJPw5MVpHUewsbP2m/0/*)#dkgvr5hm");
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bip86<K: DerivableKey<Tap>>(pub K, pub KeychainKind);
|
||||
|
||||
impl<K: DerivableKey<Tap>> DescriptorTemplate for Bip86<K> {
|
||||
@ -477,22 +485,23 @@ impl<K: DerivableKey<Tap>> DescriptorTemplate for Bip86<K> {
|
||||
/// ```
|
||||
/// # use std::str::FromStr;
|
||||
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
|
||||
/// # use bdk_wallet::{CreateParams, KeychainKind};
|
||||
/// # use bdk_wallet::{Wallet, KeychainKind};
|
||||
/// use bdk_wallet::template::Bip86Public;
|
||||
///
|
||||
/// let key = bitcoin::bip32::Xpub::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
|
||||
/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
|
||||
/// let mut wallet = CreateParams::new(
|
||||
/// let mut wallet = Wallet::create(
|
||||
/// Bip86Public(key.clone(), fingerprint, KeychainKind::External),
|
||||
/// Bip86Public(key, fingerprint, KeychainKind::Internal),
|
||||
/// Network::Testnet,
|
||||
/// )?
|
||||
/// )
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// assert_eq!(wallet.next_unused_address(KeychainKind::External).to_string(), "tb1pwjp9f2k5n0xq73ecuu0c5njvgqr3vkh7yaylmpqvsuuaafymh0msvcmh37");
|
||||
/// assert_eq!(wallet.public_descriptor(KeychainKind::External).to_string(), "tr([c55b303f/86'/1'/0']tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q/0/*)#2p65srku");
|
||||
/// # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bip86Public<K: DerivableKey<Tap>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
|
||||
|
||||
impl<K: DerivableKey<Tap>> DescriptorTemplate for Bip86Public<K> {
|
||||
|
@ -29,11 +29,11 @@
|
||||
//! }"#;
|
||||
//!
|
||||
//! let import = FullyNodedExport::from_str(import)?;
|
||||
//! let wallet = CreateParams::new(
|
||||
//! &import.descriptor(),
|
||||
//! &import.change_descriptor().expect("change descriptor"),
|
||||
//! Network::Testnet,
|
||||
//! )?
|
||||
//! let wallet = Wallet::create(
|
||||
//! import.descriptor(),
|
||||
//! import.change_descriptor().expect("change descriptor"),
|
||||
//! )
|
||||
//! .network(Network::Testnet)
|
||||
//! .create_wallet_no_persist()?;
|
||||
//! # Ok::<_, Box<dyn std::error::Error>>(())
|
||||
//! ```
|
||||
@ -43,11 +43,11 @@
|
||||
//! # use bitcoin::*;
|
||||
//! # use bdk_wallet::export::*;
|
||||
//! # use bdk_wallet::*;
|
||||
//! let wallet = CreateParams::new(
|
||||
//! let wallet = Wallet::create(
|
||||
//! "wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/0/*)",
|
||||
//! "wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/1/*)",
|
||||
//! Network::Testnet,
|
||||
//! )?
|
||||
//! )
|
||||
//! .network(Network::Testnet)
|
||||
//! .create_wallet_no_persist()?;
|
||||
//! let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true).unwrap();
|
||||
//!
|
||||
@ -221,13 +221,13 @@ mod test {
|
||||
use bitcoin::{transaction, BlockHash, Network, Transaction};
|
||||
|
||||
use super::*;
|
||||
use crate::wallet::{CreateParams, Wallet};
|
||||
use crate::Wallet;
|
||||
|
||||
fn get_test_wallet(descriptor: &str, change_descriptor: &str, network: Network) -> Wallet {
|
||||
use crate::wallet::Update;
|
||||
use bdk_chain::TxGraph;
|
||||
let mut wallet = CreateParams::new(descriptor, change_descriptor, network)
|
||||
.expect("must parse descriptors")
|
||||
let mut wallet = Wallet::create(descriptor.to_string(), change_descriptor.to_string())
|
||||
.network(network)
|
||||
.create_wallet_no_persist()
|
||||
.expect("must create wallet");
|
||||
let transaction = Transaction {
|
||||
|
@ -290,7 +290,8 @@ impl Wallet {
|
||||
/// # const EXTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/0/*)";
|
||||
/// # const INTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)";
|
||||
/// // Create a non-persisted wallet.
|
||||
/// let wallet = Wallet::create(EXTERNAL_DESC, INTERNAL_DESC, Network::Testnet)?
|
||||
/// let wallet = Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
///
|
||||
/// // Create a wallet that is persisted to SQLite database.
|
||||
@ -298,48 +299,48 @@ impl Wallet {
|
||||
/// # let file_path = temp_dir.path().join("store.db");
|
||||
/// use bdk_wallet::rusqlite::Connection;
|
||||
/// let mut conn = Connection::open(file_path)?;
|
||||
/// let wallet = Wallet::create(EXTERNAL_DESC, INTERNAL_DESC, Network::Testnet)?
|
||||
/// let wallet = Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet(&mut conn)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn create<E: IntoWalletDescriptor>(
|
||||
descriptor: E,
|
||||
change_descriptor: E,
|
||||
network: Network,
|
||||
) -> Result<CreateParams, DescriptorError> {
|
||||
CreateParams::new(descriptor, change_descriptor, network)
|
||||
pub fn create<D>(descriptor: D, change_descriptor: D) -> CreateParams
|
||||
where
|
||||
D: IntoWalletDescriptor + Clone + 'static,
|
||||
{
|
||||
CreateParams::new(descriptor, change_descriptor)
|
||||
}
|
||||
|
||||
/// Create a new [`Wallet`] with given `params`.
|
||||
///
|
||||
/// If you have previously created a wallet, use [`load`](Self::load) instead.
|
||||
/// Refer to [`Wallet::create`] for more.
|
||||
pub fn create_with_params(params: CreateParams) -> Result<Self, DescriptorError> {
|
||||
let secp = params.secp;
|
||||
let secp = SecpCtx::new();
|
||||
let network = params.network;
|
||||
let genesis_hash = params
|
||||
.genesis_hash
|
||||
.unwrap_or(genesis_block(network).block_hash());
|
||||
|
||||
let (chain, chain_changeset) = LocalChain::from_genesis_hash(genesis_hash);
|
||||
|
||||
check_wallet_descriptor(¶ms.descriptor)?;
|
||||
check_wallet_descriptor(¶ms.change_descriptor)?;
|
||||
let (descriptor, mut descriptor_keymap) = (params.descriptor)(&secp, network)?;
|
||||
descriptor_keymap.extend(params.descriptor_keymap);
|
||||
|
||||
let (change_descriptor, mut change_descriptor_keymap) =
|
||||
(params.change_descriptor)(&secp, network)?;
|
||||
change_descriptor_keymap.extend(params.change_descriptor_keymap);
|
||||
|
||||
let signers = Arc::new(SignersContainer::build(
|
||||
params.descriptor_keymap,
|
||||
¶ms.descriptor,
|
||||
descriptor_keymap,
|
||||
&descriptor,
|
||||
&secp,
|
||||
));
|
||||
let change_signers = Arc::new(SignersContainer::build(
|
||||
params.change_descriptor_keymap,
|
||||
¶ms.change_descriptor,
|
||||
change_descriptor_keymap,
|
||||
&change_descriptor,
|
||||
&secp,
|
||||
));
|
||||
let index = create_indexer(
|
||||
params.descriptor,
|
||||
params.change_descriptor,
|
||||
params.lookahead,
|
||||
)?;
|
||||
let index = create_indexer(descriptor, change_descriptor, params.lookahead)?;
|
||||
|
||||
let descriptor = index.get_descriptor(&KeychainKind::External).cloned();
|
||||
let change_descriptor = index.get_descriptor(&KeychainKind::Internal).cloned();
|
||||
@ -370,7 +371,8 @@ impl Wallet {
|
||||
///
|
||||
/// Note that the descriptor secret keys are not persisted to the db. You can either add
|
||||
/// signers after-the-fact with [`Wallet::add_signer`] or [`Wallet::set_keymap`]. Or you can
|
||||
/// construct wallet using [`Wallet::load_with_descriptors`].
|
||||
/// add keys when building the wallet using [`LoadParams::keymap`] and/or
|
||||
/// [`LoadParams::descriptors`].
|
||||
///
|
||||
/// # Synopsis
|
||||
///
|
||||
@ -394,14 +396,15 @@ impl Wallet {
|
||||
/// # let genesis_hash = BlockHash::all_zeros();
|
||||
/// let mut conn = bdk_wallet::rusqlite::Connection::open(file_path)?;
|
||||
/// let mut wallet = Wallet::load()
|
||||
/// // manually include private keys
|
||||
/// // the alternative is to use `Wallet::load_with_descriptors`
|
||||
/// // check loaded descriptors matches these values and extract private keys
|
||||
/// .descriptors(EXTERNAL_DESC, INTERNAL_DESC)
|
||||
/// // you can also manually add private keys
|
||||
/// .keymap(KeychainKind::External, external_keymap)
|
||||
/// .keymap(KeychainKind::Internal, internal_keymap)
|
||||
/// // set a lookahead for our indexer
|
||||
/// .lookahead(101)
|
||||
/// // ensure loaded wallet's genesis hash matches this value
|
||||
/// .genesis_hash(genesis_hash)
|
||||
/// // set a lookahead for our indexer
|
||||
/// .lookahead(101)
|
||||
/// .load_wallet(&mut conn)?
|
||||
/// .expect("must have data to load wallet");
|
||||
/// # Ok(())
|
||||
@ -411,59 +414,9 @@ impl Wallet {
|
||||
LoadParams::new()
|
||||
}
|
||||
|
||||
/// Build [`Wallet`] by loading from persistence or [`ChangeSet`]. This fails if the loaded
|
||||
/// wallet has a different `network`.
|
||||
/// Load [`Wallet`] from the given previously persisted [`ChangeSet`] and `params`.
|
||||
///
|
||||
/// Note that the descriptor secret keys are not persisted to the db. You can either add
|
||||
/// signers after-the-fact with [`Wallet::add_signer`] or [`Wallet::set_keymap`]. Or you can
|
||||
/// construct wallet using [`Wallet::load_with_descriptors`].
|
||||
pub fn load_with_network(network: Network) -> LoadParams {
|
||||
LoadParams::with_network(network)
|
||||
}
|
||||
|
||||
/// Build [`Wallet`] by loading from persistence or [`ChangeSet`]. This fails if the loaded
|
||||
/// wallet has a different `network`, `descriptor` or `change_descriptor`.
|
||||
///
|
||||
/// If the passed-in descriptors contains secret keys, the keys will be included in the
|
||||
/// constructed wallet (which means you can sign transactions).
|
||||
pub fn load_with_descriptors<E: IntoWalletDescriptor>(
|
||||
descriptor: E,
|
||||
change_descriptor: E,
|
||||
network: Network,
|
||||
) -> Result<LoadParams, DescriptorError> {
|
||||
LoadParams::with_descriptors(descriptor, change_descriptor, network)
|
||||
}
|
||||
|
||||
/// Load [`Wallet`] from the given previously persisted [`ChangeSet`].
|
||||
///
|
||||
/// Note that the descriptor secret keys are not persisted to the db; this means that after
|
||||
/// calling this method the [`Wallet`] **won't** know the secret keys, and as such, won't be
|
||||
/// able to sign transactions.
|
||||
///
|
||||
/// If you wish to use the wallet to sign transactions, you need to add the secret keys
|
||||
/// manually to the [`Wallet`]:
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # use bdk_wallet::Wallet;
|
||||
/// # use bitcoin::Network;
|
||||
/// # use bdk_wallet::{LoadParams, KeychainKind, PersistedWallet};
|
||||
/// use bdk_chain::sqlite::Connection;
|
||||
/// #
|
||||
/// # fn main() -> anyhow::Result<()> {
|
||||
/// # let temp_dir = tempfile::tempdir().expect("must create tempdir");
|
||||
/// # let file_path = temp_dir.path().join("store.db");
|
||||
/// const EXTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/0/*)";
|
||||
/// const INTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)";
|
||||
///
|
||||
/// let mut conn = Connection::open(file_path)?;
|
||||
/// let mut wallet: PersistedWallet =
|
||||
/// LoadParams::with_descriptors(EXTERNAL_DESC, INTERNAL_DESC, Network::Testnet)?
|
||||
/// .load_wallet(&mut conn)?
|
||||
/// .expect("db should have data to load wallet");
|
||||
///
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
/// Refer to [`Wallet::load`] for more.
|
||||
pub fn load_with_params(
|
||||
changeset: ChangeSet,
|
||||
params: LoadParams,
|
||||
@ -476,13 +429,16 @@ impl Wallet {
|
||||
let chain = LocalChain::from_changeset(changeset.local_chain)
|
||||
.map_err(|_| LoadError::MissingGenesis)?;
|
||||
|
||||
let mut descriptor_keymap = params.descriptor_keymap;
|
||||
let descriptor = changeset
|
||||
.descriptor
|
||||
.ok_or(LoadError::MissingDescriptor(KeychainKind::External))?;
|
||||
check_wallet_descriptor(&descriptor).map_err(LoadError::Descriptor)?;
|
||||
|
||||
let mut change_descriptor_keymap = params.change_descriptor_keymap;
|
||||
let change_descriptor = changeset
|
||||
.change_descriptor
|
||||
.ok_or(LoadError::MissingDescriptor(KeychainKind::Internal))?;
|
||||
check_wallet_descriptor(&descriptor).map_err(LoadError::Descriptor)?;
|
||||
check_wallet_descriptor(&change_descriptor).map_err(LoadError::Descriptor)?;
|
||||
|
||||
// checks
|
||||
@ -503,6 +459,10 @@ impl Wallet {
|
||||
}
|
||||
}
|
||||
if let Some(exp_descriptor) = params.check_descriptor {
|
||||
let (exp_descriptor, keymap) =
|
||||
(exp_descriptor)(&secp, network).map_err(LoadError::Descriptor)?;
|
||||
descriptor_keymap.extend(keymap);
|
||||
|
||||
if descriptor.descriptor_id() != exp_descriptor.descriptor_id() {
|
||||
return Err(LoadError::Mismatch(LoadMismatch::Descriptor {
|
||||
keychain: KeychainKind::External,
|
||||
@ -512,6 +472,10 @@ impl Wallet {
|
||||
}
|
||||
}
|
||||
if let Some(exp_change_descriptor) = params.check_change_descriptor {
|
||||
let (exp_change_descriptor, keymap) =
|
||||
(exp_change_descriptor)(&secp, network).map_err(LoadError::Descriptor)?;
|
||||
change_descriptor_keymap.extend(keymap);
|
||||
|
||||
if change_descriptor.descriptor_id() != exp_change_descriptor.descriptor_id() {
|
||||
return Err(LoadError::Mismatch(LoadMismatch::Descriptor {
|
||||
keychain: KeychainKind::External,
|
||||
@ -522,12 +486,12 @@ impl Wallet {
|
||||
}
|
||||
|
||||
let signers = Arc::new(SignersContainer::build(
|
||||
params.descriptor_keymap,
|
||||
descriptor_keymap,
|
||||
&descriptor,
|
||||
&secp,
|
||||
));
|
||||
let change_signers = Arc::new(SignersContainer::build(
|
||||
params.change_descriptor_keymap,
|
||||
change_descriptor_keymap,
|
||||
&change_descriptor,
|
||||
&secp,
|
||||
));
|
||||
@ -1092,11 +1056,12 @@ impl Wallet {
|
||||
/// ## Example
|
||||
///
|
||||
/// ```
|
||||
/// # use bdk_wallet::{CreateParams, KeychainKind};
|
||||
/// # use bdk_wallet::{Wallet, KeychainKind};
|
||||
/// # use bdk_wallet::bitcoin::Network;
|
||||
/// let descriptor = "wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/1'/0'/0/*)";
|
||||
/// let change_descriptor = "wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/1'/0'/1/*)";
|
||||
/// let wallet = CreateParams::new(descriptor, change_descriptor, Network::Testnet)?
|
||||
/// let wallet = Wallet::create(descriptor, change_descriptor)
|
||||
/// .network(Network::Testnet)
|
||||
/// .create_wallet_no_persist()?;
|
||||
/// for secret_key in wallet.get_signers(KeychainKind::External).signers().iter().filter_map(|s| s.descriptor_secret_key()) {
|
||||
/// // secret_key: tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*
|
||||
@ -2452,18 +2417,14 @@ macro_rules! doctest_wallet {
|
||||
() => {{
|
||||
use $crate::bitcoin::{BlockHash, Transaction, absolute, TxOut, Network, hashes::Hash};
|
||||
use $crate::chain::{ConfirmationBlockTime, BlockId, TxGraph};
|
||||
use $crate::{Update, CreateParams, KeychainKind};
|
||||
use $crate::{Update, KeychainKind, Wallet};
|
||||
let descriptor = "tr([73c5da0a/86'/0'/0']tprv8fMn4hSKPRC1oaCPqxDb1JWtgkpeiQvZhsr8W2xuy3GEMkzoArcAWTfJxYb6Wj8XNNDWEjfYKK4wGQXh3ZUXhDF2NcnsALpWTeSwarJt7Vc/0/*)";
|
||||
let change_descriptor = "tr([73c5da0a/86'/0'/0']tprv8fMn4hSKPRC1oaCPqxDb1JWtgkpeiQvZhsr8W2xuy3GEMkzoArcAWTfJxYb6Wj8XNNDWEjfYKK4wGQXh3ZUXhDF2NcnsALpWTeSwarJt7Vc/1/*)";
|
||||
|
||||
let mut wallet = CreateParams::new(
|
||||
descriptor,
|
||||
change_descriptor,
|
||||
Network::Regtest,
|
||||
)
|
||||
.unwrap()
|
||||
.create_wallet_no_persist()
|
||||
.unwrap();
|
||||
let mut wallet = Wallet::create(descriptor, change_descriptor)
|
||||
.network(Network::Regtest)
|
||||
.create_wallet_no_persist()
|
||||
.unwrap();
|
||||
let address = wallet.peek_address(KeychainKind::External, 0).address;
|
||||
let tx = Transaction {
|
||||
version: transaction::Version::ONE,
|
||||
|
@ -1,53 +1,58 @@
|
||||
use alloc::boxed::Box;
|
||||
use bdk_chain::{keychain_txout::DEFAULT_LOOKAHEAD, PersistAsyncWith, PersistWith};
|
||||
use bitcoin::{BlockHash, Network};
|
||||
use miniscript::descriptor::KeyMap;
|
||||
|
||||
use crate::{
|
||||
descriptor::{DescriptorError, ExtendedDescriptor, IntoWalletDescriptor},
|
||||
utils::SecpCtx,
|
||||
KeychainKind, Wallet,
|
||||
};
|
||||
|
||||
use super::{utils::SecpCtx, ChangeSet, LoadError, PersistedWallet};
|
||||
use super::{ChangeSet, LoadError, PersistedWallet};
|
||||
|
||||
/// This atrocity is to avoid having type parameters on [`CreateParams`] and [`LoadParams`].
|
||||
///
|
||||
/// The better option would be to do `Box<dyn IntoWalletDescriptor>`, but we cannot due to Rust's
|
||||
/// [object safety rules](https://doc.rust-lang.org/reference/items/traits.html#object-safety).
|
||||
type DescriptorToExtract = Box<
|
||||
dyn FnOnce(&SecpCtx, Network) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError>
|
||||
+ 'static,
|
||||
>;
|
||||
|
||||
fn make_descriptor_to_extract<D>(descriptor: D) -> DescriptorToExtract
|
||||
where
|
||||
D: IntoWalletDescriptor + 'static,
|
||||
{
|
||||
Box::new(|secp, network| descriptor.into_wallet_descriptor(secp, network))
|
||||
}
|
||||
|
||||
/// Parameters for [`Wallet::create`] or [`PersistedWallet::create`].
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use]
|
||||
pub struct CreateParams {
|
||||
pub(crate) descriptor: ExtendedDescriptor,
|
||||
pub(crate) descriptor: DescriptorToExtract,
|
||||
pub(crate) descriptor_keymap: KeyMap,
|
||||
pub(crate) change_descriptor: ExtendedDescriptor,
|
||||
pub(crate) change_descriptor: DescriptorToExtract,
|
||||
pub(crate) change_descriptor_keymap: KeyMap,
|
||||
pub(crate) network: Network,
|
||||
pub(crate) genesis_hash: Option<BlockHash>,
|
||||
pub(crate) lookahead: u32,
|
||||
pub(crate) secp: SecpCtx,
|
||||
}
|
||||
|
||||
impl CreateParams {
|
||||
/// Construct parameters with provided `descriptor`, `change_descriptor` and `network`.
|
||||
///
|
||||
/// Default values: `genesis_hash` = `None`, `lookahead` = [`DEFAULT_LOOKAHEAD`]
|
||||
pub fn new<E: IntoWalletDescriptor>(
|
||||
descriptor: E,
|
||||
change_descriptor: E,
|
||||
network: Network,
|
||||
) -> Result<Self, DescriptorError> {
|
||||
let secp = SecpCtx::default();
|
||||
|
||||
let (descriptor, descriptor_keymap) = descriptor.into_wallet_descriptor(&secp, network)?;
|
||||
let (change_descriptor, change_descriptor_keymap) =
|
||||
change_descriptor.into_wallet_descriptor(&secp, network)?;
|
||||
|
||||
Ok(Self {
|
||||
descriptor,
|
||||
descriptor_keymap,
|
||||
change_descriptor,
|
||||
change_descriptor_keymap,
|
||||
network,
|
||||
pub fn new<D: IntoWalletDescriptor + 'static>(descriptor: D, change_descriptor: D) -> Self {
|
||||
Self {
|
||||
descriptor: make_descriptor_to_extract(descriptor),
|
||||
descriptor_keymap: KeyMap::default(),
|
||||
change_descriptor: make_descriptor_to_extract(change_descriptor),
|
||||
change_descriptor_keymap: KeyMap::default(),
|
||||
network: Network::Bitcoin,
|
||||
genesis_hash: None,
|
||||
lookahead: DEFAULT_LOOKAHEAD,
|
||||
secp,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Extend the given `keychain`'s `keymap`.
|
||||
@ -60,6 +65,12 @@ impl CreateParams {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set `network`.
|
||||
pub fn network(mut self, network: Network) -> Self {
|
||||
self.network = network;
|
||||
self
|
||||
}
|
||||
|
||||
/// Use a custom `genesis_hash`.
|
||||
pub fn genesis_hash(mut self, genesis_hash: BlockHash) -> Self {
|
||||
self.genesis_hash = Some(genesis_hash);
|
||||
@ -102,16 +113,14 @@ impl CreateParams {
|
||||
|
||||
/// Parameters for [`Wallet::load`] or [`PersistedWallet::load`].
|
||||
#[must_use]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LoadParams {
|
||||
pub(crate) descriptor_keymap: KeyMap,
|
||||
pub(crate) change_descriptor_keymap: KeyMap,
|
||||
pub(crate) lookahead: u32,
|
||||
pub(crate) check_network: Option<Network>,
|
||||
pub(crate) check_genesis_hash: Option<BlockHash>,
|
||||
pub(crate) check_descriptor: Option<ExtendedDescriptor>,
|
||||
pub(crate) check_change_descriptor: Option<ExtendedDescriptor>,
|
||||
pub(crate) secp: SecpCtx,
|
||||
pub(crate) check_descriptor: Option<DescriptorToExtract>,
|
||||
pub(crate) check_change_descriptor: Option<DescriptorToExtract>,
|
||||
}
|
||||
|
||||
impl LoadParams {
|
||||
@ -127,39 +136,9 @@ impl LoadParams {
|
||||
check_genesis_hash: None,
|
||||
check_descriptor: None,
|
||||
check_change_descriptor: None,
|
||||
secp: SecpCtx::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct parameters with `network` check.
|
||||
pub fn with_network(network: Network) -> Self {
|
||||
Self {
|
||||
check_network: Some(network),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct parameters with descriptor checks.
|
||||
pub fn with_descriptors<E: IntoWalletDescriptor>(
|
||||
descriptor: E,
|
||||
change_descriptor: E,
|
||||
network: Network,
|
||||
) -> Result<Self, DescriptorError> {
|
||||
let mut params = Self::with_network(network);
|
||||
let secp = ¶ms.secp;
|
||||
|
||||
let (descriptor, descriptor_keymap) = descriptor.into_wallet_descriptor(secp, network)?;
|
||||
params.check_descriptor = Some(descriptor);
|
||||
params.descriptor_keymap = descriptor_keymap;
|
||||
|
||||
let (change_descriptor, change_descriptor_keymap) =
|
||||
change_descriptor.into_wallet_descriptor(secp, network)?;
|
||||
params.check_change_descriptor = Some(change_descriptor);
|
||||
params.change_descriptor_keymap = change_descriptor_keymap;
|
||||
|
||||
Ok(params)
|
||||
}
|
||||
|
||||
/// Extend the given `keychain`'s `keymap`.
|
||||
pub fn keymap(mut self, keychain: KeychainKind, keymap: KeyMap) -> Self {
|
||||
match keychain {
|
||||
@ -170,6 +149,23 @@ impl LoadParams {
|
||||
self
|
||||
}
|
||||
|
||||
/// Checks that `descriptor` of `keychain` matches this, and extracts private keys (if
|
||||
/// avaliable).
|
||||
pub fn descriptors<D>(mut self, descriptor: D, change_descriptor: D) -> Self
|
||||
where
|
||||
D: IntoWalletDescriptor + 'static,
|
||||
{
|
||||
self.check_descriptor = Some(make_descriptor_to_extract(descriptor));
|
||||
self.check_change_descriptor = Some(make_descriptor_to_extract(change_descriptor));
|
||||
self
|
||||
}
|
||||
|
||||
/// Check for `network`.
|
||||
pub fn network(mut self, network: Network) -> Self {
|
||||
self.check_network = Some(network);
|
||||
self
|
||||
}
|
||||
|
||||
/// Check for a `genesis_hash`.
|
||||
pub fn genesis_hash(mut self, genesis_hash: BlockHash) -> Self {
|
||||
self.check_genesis_hash = Some(genesis_hash);
|
||||
|
@ -69,7 +69,8 @@
|
||||
//!
|
||||
//! let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/0/*)";
|
||||
//! let change_descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/1/*)";
|
||||
//! let mut wallet = CreateParams::new(descriptor, change_descriptor, Network::Testnet)?
|
||||
//! let mut wallet = Wallet::create(descriptor, change_descriptor)
|
||||
//! .network(Network::Testnet)
|
||||
//! .create_wallet_no_persist()?;
|
||||
//! wallet.add_signer(
|
||||
//! KeychainKind::External,
|
||||
|
@ -13,8 +13,8 @@ use std::str::FromStr;
|
||||
/// to a foreign address and one returning 50_000 back to the wallet. The remaining 1000
|
||||
/// sats are the transaction fee.
|
||||
pub fn get_funded_wallet_with_change(descriptor: &str, change: &str) -> (Wallet, bitcoin::Txid) {
|
||||
let mut wallet = CreateParams::new(descriptor, change, Network::Regtest)
|
||||
.expect("must parse descriptors")
|
||||
let mut wallet = Wallet::create(descriptor.to_string(), change.to_string())
|
||||
.network(Network::Regtest)
|
||||
.create_wallet_no_persist()
|
||||
.expect("descriptors must be valid");
|
||||
|
||||
|
@ -122,7 +122,8 @@ fn wallet_is_persisted() -> anyhow::Result<()> {
|
||||
// create new wallet
|
||||
let wallet_spk_index = {
|
||||
let mut db = create_db(&file_path)?;
|
||||
let mut wallet = CreateParams::new(external_desc, internal_desc, Network::Testnet)?
|
||||
let mut wallet = Wallet::create(external_desc, internal_desc)
|
||||
.network(Network::Testnet)
|
||||
.create_wallet(&mut db)?;
|
||||
wallet.reveal_next_address(KeychainKind::External);
|
||||
|
||||
@ -134,10 +135,11 @@ fn wallet_is_persisted() -> anyhow::Result<()> {
|
||||
// recover wallet
|
||||
{
|
||||
let mut db = open_db(&file_path).context("failed to recover db")?;
|
||||
let wallet =
|
||||
LoadParams::with_descriptors(external_desc, internal_desc, Network::Testnet)?
|
||||
.load_wallet(&mut db)?
|
||||
.expect("wallet must exist");
|
||||
let wallet = Wallet::load()
|
||||
.descriptors(external_desc, internal_desc)
|
||||
.network(Network::Testnet)
|
||||
.load_wallet(&mut db)?
|
||||
.expect("wallet must exist");
|
||||
|
||||
assert_eq!(wallet.network(), Network::Testnet);
|
||||
assert_eq!(
|
||||
@ -179,8 +181,8 @@ fn wallet_is_persisted() -> anyhow::Result<()> {
|
||||
fn test_error_external_and_internal_are_the_same() {
|
||||
// identical descriptors should fail to create wallet
|
||||
let desc = get_test_wpkh();
|
||||
let err = CreateParams::new(desc, desc, Network::Testnet)
|
||||
.unwrap()
|
||||
let err = Wallet::create(desc, desc)
|
||||
.network(Network::Testnet)
|
||||
.create_wallet_no_persist();
|
||||
assert!(
|
||||
matches!(&err, Err(DescriptorError::ExternalAndInternalAreTheSame)),
|
||||
@ -191,8 +193,8 @@ fn test_error_external_and_internal_are_the_same() {
|
||||
// public + private of same descriptor should fail to create wallet
|
||||
let desc = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/0/*)";
|
||||
let change_desc = "wpkh([3c31d632/84'/1'/0']tpubDCYwFkks2cg78N7eoYbBatsFEGje8vW8arSKW4rLwD1AU1s9KJMDRHE32JkvYERuiFjArrsH7qpWSpJATed5ShZbG9KsskA5Rmi6NSYgYN2/0/*)";
|
||||
let err = CreateParams::new(desc, change_desc, Network::Testnet)
|
||||
.unwrap()
|
||||
let err = Wallet::create(desc, change_desc)
|
||||
.network(Network::Testnet)
|
||||
.create_wallet_no_persist();
|
||||
assert!(
|
||||
matches!(err, Err(DescriptorError::ExternalAndInternalAreTheSame)),
|
||||
@ -1154,8 +1156,8 @@ fn test_create_tx_policy_path_required() {
|
||||
#[test]
|
||||
fn test_create_tx_policy_path_no_csv() {
|
||||
let (descriptor, change_descriptor) = get_test_wpkh_with_change_desc();
|
||||
let mut wallet = CreateParams::new(descriptor, change_descriptor, Network::Regtest)
|
||||
.expect("must parse")
|
||||
let mut wallet = Wallet::create(descriptor, change_descriptor)
|
||||
.network(Network::Regtest)
|
||||
.create_wallet_no_persist()
|
||||
.expect("wallet");
|
||||
|
||||
@ -2769,8 +2771,8 @@ fn test_sign_nonstandard_sighash() {
|
||||
fn test_unused_address() {
|
||||
let descriptor = "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)";
|
||||
let change_descriptor = get_test_wpkh();
|
||||
let mut wallet = CreateParams::new(descriptor, change_descriptor, Network::Testnet)
|
||||
.expect("must parse descriptors")
|
||||
let mut wallet = Wallet::create(descriptor, change_descriptor)
|
||||
.network(Network::Testnet)
|
||||
.create_wallet_no_persist()
|
||||
.expect("wallet");
|
||||
|
||||
@ -2800,8 +2802,8 @@ fn test_unused_address() {
|
||||
fn test_next_unused_address() {
|
||||
let descriptor = "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)";
|
||||
let change_descriptor = get_test_wpkh();
|
||||
let mut wallet = CreateParams::new(descriptor, change_descriptor, Network::Testnet)
|
||||
.expect("must parse descriptors")
|
||||
let mut wallet = Wallet::create(descriptor, change_descriptor)
|
||||
.network(Network::Testnet)
|
||||
.create_wallet_no_persist()
|
||||
.expect("wallet");
|
||||
assert_eq!(wallet.derivation_index(KeychainKind::External), None);
|
||||
@ -2850,8 +2852,8 @@ fn test_next_unused_address() {
|
||||
fn test_peek_address_at_index() {
|
||||
let descriptor = "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)";
|
||||
let change_descriptor = get_test_wpkh();
|
||||
let mut wallet = CreateParams::new(descriptor, change_descriptor, Network::Testnet)
|
||||
.expect("must parse descriptors")
|
||||
let mut wallet = Wallet::create(descriptor, change_descriptor)
|
||||
.network(Network::Testnet)
|
||||
.create_wallet_no_persist()
|
||||
.expect("wallet");
|
||||
|
||||
@ -2888,11 +2890,11 @@ fn test_peek_address_at_index() {
|
||||
|
||||
#[test]
|
||||
fn test_peek_address_at_index_not_derivable() {
|
||||
let wallet = CreateParams::new(
|
||||
"wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/1)",
|
||||
get_test_wpkh(),
|
||||
Network::Testnet,
|
||||
).unwrap().create_wallet_no_persist().unwrap();
|
||||
let descriptor = "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/1)";
|
||||
let wallet = Wallet::create(descriptor, get_test_wpkh())
|
||||
.network(Network::Testnet)
|
||||
.create_wallet_no_persist()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
wallet.peek_address(KeychainKind::External, 1).to_string(),
|
||||
@ -2912,11 +2914,12 @@ fn test_peek_address_at_index_not_derivable() {
|
||||
|
||||
#[test]
|
||||
fn test_returns_index_and_address() {
|
||||
let mut wallet = CreateParams::new(
|
||||
"wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
|
||||
get_test_wpkh(),
|
||||
Network::Testnet,
|
||||
).unwrap().create_wallet_no_persist().unwrap();
|
||||
let descriptor =
|
||||
"wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)";
|
||||
let mut wallet = Wallet::create(descriptor, get_test_wpkh())
|
||||
.network(Network::Testnet)
|
||||
.create_wallet_no_persist()
|
||||
.unwrap();
|
||||
|
||||
// new index 0
|
||||
assert_eq!(
|
||||
@ -2982,12 +2985,11 @@ fn test_sending_to_bip350_bech32m_address() {
|
||||
fn test_get_address() {
|
||||
use bdk_wallet::descriptor::template::Bip84;
|
||||
let key = bitcoin::bip32::Xpriv::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
|
||||
let wallet = CreateParams::new(
|
||||
let wallet = Wallet::create(
|
||||
Bip84(key, KeychainKind::External),
|
||||
Bip84(key, KeychainKind::Internal),
|
||||
Network::Regtest,
|
||||
)
|
||||
.unwrap()
|
||||
.network(Network::Regtest)
|
||||
.create_wallet_no_persist()
|
||||
.unwrap();
|
||||
|
||||
@ -3017,8 +3019,8 @@ fn test_get_address() {
|
||||
#[test]
|
||||
fn test_reveal_addresses() {
|
||||
let (desc, change_desc) = get_test_tr_single_sig_xprv_with_change_desc();
|
||||
let mut wallet = CreateParams::new(desc, change_desc, Network::Signet)
|
||||
.expect("must parse")
|
||||
let mut wallet = Wallet::create(desc, change_desc)
|
||||
.network(Network::Signet)
|
||||
.create_wallet_no_persist()
|
||||
.unwrap();
|
||||
let keychain = KeychainKind::External;
|
||||
@ -3041,12 +3043,11 @@ fn test_get_address_no_reuse() {
|
||||
use std::collections::HashSet;
|
||||
|
||||
let key = bitcoin::bip32::Xpriv::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
|
||||
let mut wallet = CreateParams::new(
|
||||
let mut wallet = Wallet::create(
|
||||
Bip84(key, KeychainKind::External),
|
||||
Bip84(key, KeychainKind::Internal),
|
||||
Network::Regtest,
|
||||
)
|
||||
.unwrap()
|
||||
.network(Network::Regtest)
|
||||
.create_wallet_no_persist()
|
||||
.unwrap();
|
||||
|
||||
@ -3517,14 +3518,10 @@ fn test_taproot_sign_derive_index_from_psbt() {
|
||||
let mut psbt = builder.finish().unwrap();
|
||||
|
||||
// re-create the wallet with an empty db
|
||||
let wallet_empty = CreateParams::new(
|
||||
get_test_tr_single_sig_xprv(),
|
||||
get_test_tr_single_sig(),
|
||||
Network::Regtest,
|
||||
)
|
||||
.unwrap()
|
||||
.create_wallet_no_persist()
|
||||
.unwrap();
|
||||
let wallet_empty = Wallet::create(get_test_tr_single_sig_xprv(), get_test_tr_single_sig())
|
||||
.network(Network::Regtest)
|
||||
.create_wallet_no_persist()
|
||||
.unwrap();
|
||||
|
||||
// signing with an empty db means that we will only look at the psbt to infer the
|
||||
// derivation index
|
||||
@ -3624,8 +3621,8 @@ fn test_taproot_sign_non_default_sighash() {
|
||||
#[test]
|
||||
fn test_spend_coinbase() {
|
||||
let (desc, change_desc) = get_test_wpkh_with_change_desc();
|
||||
let mut wallet = CreateParams::new(desc, change_desc, Network::Regtest)
|
||||
.unwrap()
|
||||
let mut wallet = Wallet::create(desc, change_desc)
|
||||
.network(Network::Regtest)
|
||||
.create_wallet_no_persist()
|
||||
.unwrap();
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
use bdk_wallet::file_store::Store;
|
||||
use bdk_wallet::CreateParams;
|
||||
use bdk_wallet::LoadParams;
|
||||
use bdk_wallet::Wallet;
|
||||
use std::io::Write;
|
||||
use std::str::FromStr;
|
||||
|
||||
@ -26,11 +25,15 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
|
||||
let mut db = Store::<bdk_wallet::ChangeSet>::open_or_create_new(DB_MAGIC.as_bytes(), db_path)?;
|
||||
|
||||
let load_params = LoadParams::with_descriptors(EXTERNAL_DESC, INTERNAL_DESC, NETWORK)?;
|
||||
let create_params = CreateParams::new(EXTERNAL_DESC, INTERNAL_DESC, NETWORK)?;
|
||||
let mut wallet = match load_params.load_wallet(&mut db)? {
|
||||
let wallet_opt = Wallet::load()
|
||||
.descriptors(EXTERNAL_DESC, INTERNAL_DESC)
|
||||
.network(NETWORK)
|
||||
.load_wallet(&mut db)?;
|
||||
let mut wallet = match wallet_opt {
|
||||
Some(wallet) => wallet,
|
||||
None => create_params.create_wallet(&mut db)?,
|
||||
None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
|
||||
.network(NETWORK)
|
||||
.create_wallet(&mut db)?,
|
||||
};
|
||||
|
||||
let address = wallet.next_unused_address(KeychainKind::External);
|
||||
|
@ -5,7 +5,7 @@ use bdk_esplora::{esplora_client, EsploraAsyncExt};
|
||||
use bdk_wallet::{
|
||||
bitcoin::{Amount, Network},
|
||||
rusqlite::Connection,
|
||||
CreateParams, KeychainKind, LoadParams, SignOptions,
|
||||
KeychainKind, SignOptions, Wallet,
|
||||
};
|
||||
|
||||
const SEND_AMOUNT: Amount = Amount::from_sat(5000);
|
||||
@ -22,11 +22,15 @@ const ESPLORA_URL: &str = "http://signet.bitcoindevkit.net";
|
||||
async fn main() -> Result<(), anyhow::Error> {
|
||||
let mut conn = Connection::open(DB_PATH)?;
|
||||
|
||||
let load_params = LoadParams::with_descriptors(EXTERNAL_DESC, INTERNAL_DESC, NETWORK)?;
|
||||
let create_params = CreateParams::new(EXTERNAL_DESC, INTERNAL_DESC, NETWORK)?;
|
||||
let mut wallet = match load_params.load_wallet(&mut conn)? {
|
||||
let wallet_opt = Wallet::load()
|
||||
.descriptors(EXTERNAL_DESC, INTERNAL_DESC)
|
||||
.network(NETWORK)
|
||||
.load_wallet(&mut conn)?;
|
||||
let mut wallet = match wallet_opt {
|
||||
Some(wallet) => wallet,
|
||||
None => create_params.create_wallet(&mut conn)?,
|
||||
None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
|
||||
.network(NETWORK)
|
||||
.create_wallet(&mut conn)?,
|
||||
};
|
||||
|
||||
let address = wallet.next_unused_address(KeychainKind::External);
|
||||
|
@ -4,7 +4,7 @@ use bdk_esplora::{esplora_client, EsploraExt};
|
||||
use bdk_wallet::{
|
||||
bitcoin::{Amount, Network},
|
||||
file_store::Store,
|
||||
CreateParams, KeychainKind, LoadParams, SignOptions,
|
||||
KeychainKind, SignOptions, Wallet,
|
||||
};
|
||||
|
||||
const DB_MAGIC: &str = "bdk_wallet_esplora_example";
|
||||
@ -21,12 +21,15 @@ const ESPLORA_URL: &str = "http://signet.bitcoindevkit.net";
|
||||
fn main() -> Result<(), anyhow::Error> {
|
||||
let mut db = Store::<bdk_wallet::ChangeSet>::open_or_create_new(DB_MAGIC.as_bytes(), DB_PATH)?;
|
||||
|
||||
let load_params = LoadParams::with_descriptors(EXTERNAL_DESC, INTERNAL_DESC, NETWORK)?;
|
||||
let create_params = CreateParams::new(EXTERNAL_DESC, INTERNAL_DESC, NETWORK)?;
|
||||
|
||||
let mut wallet = match load_params.load_wallet(&mut db)? {
|
||||
let wallet_opt = Wallet::load()
|
||||
.descriptors(EXTERNAL_DESC, INTERNAL_DESC)
|
||||
.network(NETWORK)
|
||||
.load_wallet(&mut db)?;
|
||||
let mut wallet = match wallet_opt {
|
||||
Some(wallet) => wallet,
|
||||
None => create_params.create_wallet(&mut db)?,
|
||||
None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
|
||||
.network(NETWORK)
|
||||
.create_wallet(&mut db)?,
|
||||
};
|
||||
|
||||
let address = wallet.next_unused_address(KeychainKind::External);
|
||||
|
@ -5,7 +5,7 @@ use bdk_bitcoind_rpc::{
|
||||
use bdk_wallet::{
|
||||
bitcoin::{Block, Network, Transaction},
|
||||
file_store::Store,
|
||||
CreateParams, LoadParams,
|
||||
Wallet,
|
||||
};
|
||||
use clap::{self, Parser};
|
||||
use std::{path::PathBuf, sync::mpsc::sync_channel, thread::spawn, time::Instant};
|
||||
@ -88,13 +88,15 @@ fn main() -> anyhow::Result<()> {
|
||||
let start_load_wallet = Instant::now();
|
||||
let mut db =
|
||||
Store::<bdk_wallet::ChangeSet>::open_or_create_new(DB_MAGIC.as_bytes(), args.db_path)?;
|
||||
|
||||
let load_params =
|
||||
LoadParams::with_descriptors(&args.descriptor, &args.change_descriptor, args.network)?;
|
||||
let create_params = CreateParams::new(&args.descriptor, &args.change_descriptor, args.network)?;
|
||||
let mut wallet = match load_params.load_wallet(&mut db)? {
|
||||
let wallet_opt = Wallet::load()
|
||||
.descriptors(args.descriptor.clone(), args.change_descriptor.clone())
|
||||
.network(args.network)
|
||||
.load_wallet(&mut db)?;
|
||||
let mut wallet = match wallet_opt {
|
||||
Some(wallet) => wallet,
|
||||
None => create_params.create_wallet(&mut db)?,
|
||||
None => Wallet::create(args.descriptor, args.change_descriptor)
|
||||
.network(args.network)
|
||||
.create_wallet(&mut db)?,
|
||||
};
|
||||
println!(
|
||||
"Loaded wallet in {}s",
|
||||
|
Loading…
x
Reference in New Issue
Block a user