//! # 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;
//! 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(
<!-- 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 =
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.
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
);
// 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!(
}
}
+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,
///
/// ```
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
-/// # use bdk_wallet::CreateParams;
+/// # use bdk_wallet::Wallet;
/// # use bdk_wallet::KeychainKind;
/// use bdk_wallet::template::P2Pkh;
///
/// 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!(
/// );
/// # 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> {
///
/// ```
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
-/// # use bdk_wallet::CreateParams;
+/// # use bdk_wallet::Wallet;
/// # use bdk_wallet::KeychainKind;
/// use bdk_wallet::template::P2Wpkh_P2Sh;
///
/// 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
/// # 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> {
///
/// ```
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
-/// # use bdk_wallet::CreateParams;
+/// # use bdk_wallet::Wallet;
/// # use bdk_wallet::KeychainKind;
/// use bdk_wallet::template::P2Wpkh;
///
/// 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
/// );
/// # 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> {
///
/// ```
/// # use bdk_wallet::bitcoin::{PrivateKey, Network};
-/// # use bdk_wallet::CreateParams;
+/// # use bdk_wallet::Wallet;
/// # use bdk_wallet::KeychainKind;
/// use bdk_wallet::template::P2TR;
///
/// 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!(
/// );
/// # 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> {
///
/// ## 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> {
/// ```
/// # 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> {
/// ```
/// # 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> {
/// ```
/// # 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> {
/// ```
/// # 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> {
/// ```
/// # 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> {
/// ```
/// # 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> {
/// ```
/// # 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> {
//! }"#;
//!
//! 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>>(())
//! ```
//! # 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();
//!
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 {
/// # 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.
/// # 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();
///
/// 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
///
/// # 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(())
LoadParams::new()
}
- /// Build [`Wallet`] by loading from persistence or [`ChangeSet`]. This fails if the loaded
- /// wallet has a different `network`.
- ///
- /// 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/*)";
+ /// Load [`Wallet`] from the given previously persisted [`ChangeSet`] and `params`.
///
- /// 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,
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
}
}
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,
}
}
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,
}
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,
));
/// ## 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/*
() => {{
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,
+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`.
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);
/// 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 {
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 {
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);
//!
//! 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,
/// 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");
// 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);
// 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!(
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)),
// 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)),
#[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");
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");
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);
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");
#[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(),
#[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!(
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();
#[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;
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();
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
#[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();
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;
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);
use bdk_wallet::{
bitcoin::{Amount, Network},
rusqlite::Connection,
- CreateParams, KeychainKind, LoadParams, SignOptions,
+ KeychainKind, SignOptions, Wallet,
};
const SEND_AMOUNT: Amount = Amount::from_sat(5000);
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);
use bdk_wallet::{
bitcoin::{Amount, Network},
file_store::Store,
- CreateParams, KeychainKind, LoadParams, SignOptions,
+ KeychainKind, SignOptions, Wallet,
};
const DB_MAGIC: &str = "bdk_wallet_esplora_example";
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);
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};
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",