Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ let change_descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfS
let mut wallet = match Wallet::load()
.descriptor(KeychainKind::External, Some(descriptor))
.descriptor(KeychainKind::Internal, Some(change_descriptor))
.extract_keys()
.check_network(network)
.load_wallet(&mut conn)?
{
Expand Down
1 change: 0 additions & 1 deletion examples/bitcoind_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ fn main() -> anyhow::Result<()> {
let wallet_opt = Wallet::load()
.descriptor(KeychainKind::External, Some(args.descriptor.clone()))
.descriptor(KeychainKind::Internal, args.change_descriptor.clone())
.extract_keys()
.check_network(args.network)
.load_wallet(&mut db)?;
let mut wallet = match wallet_opt {
Expand Down
13 changes: 11 additions & 2 deletions examples/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ use bitcoin::Network;
use miniscript::Descriptor;
use miniscript::policy::Concrete;

use bdk_wallet::descriptor::ExtractPolicy;
use bdk_wallet::descriptor::policy::BuildSatisfaction;
use bdk_wallet::signer::SignersContainer;
use bdk_wallet::{KeychainKind, Wallet};

/// Miniscript policy is a high level abstraction of spending conditions. Defined in the
Expand Down Expand Up @@ -66,9 +69,15 @@ fn main() -> Result<(), Box<dyn Error>> {
wallet.next_unused_address(KeychainKind::External),
);

// BDK also has it's own `Policy` structure to represent the spending condition in a more
// BDK also has its own `Policy` structure to represent the spending condition in a more
// human readable json format.
let spending_policy = wallet.policies(KeychainKind::External)?;
let spending_policy = wallet
.public_descriptor(KeychainKind::External)
.extract_policy(
&SignersContainer::default(),
BuildSatisfaction::None,
wallet.secp_ctx(),
)?;
println!(
"The BDK spending policy: \n{}",
serde_json::to_string_pretty(&spending_policy)?
Expand Down
26 changes: 20 additions & 6 deletions examples/electrum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use bdk_wallet::Wallet;
use bdk_wallet::bitcoin::Amount;
use bdk_wallet::bitcoin::FeeRate;
use bdk_wallet::bitcoin::Network;
use bdk_wallet::bitcoin::secp256k1::Secp256k1;
use bdk_wallet::chain::collections::HashSet;
use bdk_wallet::descriptor::IntoWalletDescriptor;
use bdk_wallet::miniscript::descriptor::KeyMapWrapper;
use bdk_wallet::psbt::PsbtUtils;
use bdk_wallet::rusqlite::Connection;
use bdk_wallet::{KeychainKind, SignOptions};
Expand All @@ -23,16 +26,22 @@ const INTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7
const ELECTRUM_URL: &str = "ssl://mempool.space:40002";

fn main() -> Result<(), anyhow::Error> {
let secp = Secp256k1::new();
let (external_descriptor, mut external_keymap) =
EXTERNAL_DESC.into_wallet_descriptor(&secp, NETWORK.into())?;
let (internal_descriptor, internal_keymap) =
INTERNAL_DESC.into_wallet_descriptor(&secp, NETWORK.into())?;
external_keymap.extend(internal_keymap);
let signer = KeyMapWrapper::from(external_keymap);
let mut db = Connection::open(DB_PATH)?;
let wallet_opt = Wallet::load()
.descriptor(KeychainKind::External, Some(EXTERNAL_DESC))
.descriptor(KeychainKind::Internal, Some(INTERNAL_DESC))
.extract_keys()
.descriptor(KeychainKind::External, Some(external_descriptor.clone()))
.descriptor(KeychainKind::Internal, Some(internal_descriptor.clone()))
.check_network(NETWORK)
.load_wallet(&mut db)?;
let mut wallet = match wallet_opt {
Some(wallet) => wallet,
None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
None => Wallet::create(external_descriptor, internal_descriptor)
.network(NETWORK)
.create_wallet(&mut db)?,
};
Expand Down Expand Up @@ -89,7 +98,9 @@ fn main() -> Result<(), anyhow::Error> {
tx_builder.fee_rate(target_fee_rate);

let mut psbt = tx_builder.finish()?;
let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
psbt.sign(&signer, wallet.secp_ctx())
Comment thread
noahjoeris marked this conversation as resolved.
.map_err(|(_, e)| anyhow::anyhow!("{e:?}"))?;
let finalized = wallet.finalize_psbt(&mut psbt, SignOptions::default())?;
assert!(finalized);
let original_fee = psbt.fee_amount().unwrap();
let tx_feerate = psbt.fee_rate().unwrap();
Expand Down Expand Up @@ -124,7 +135,10 @@ fn main() -> Result<(), anyhow::Error> {
let mut builder = wallet.build_fee_bump(txid).expect("failed to bump tx");
builder.fee_rate(feerate);
let mut bumped_psbt = builder.finish().unwrap();
let finalize_btx = wallet.sign(&mut bumped_psbt, SignOptions::default())?;
bumped_psbt
.sign(&signer, wallet.secp_ctx())
.map_err(|(_, e)| anyhow::anyhow!("{e:?}"))?;
let finalize_btx = wallet.finalize_psbt(&mut bumped_psbt, SignOptions::default())?;
assert!(finalize_btx);
let new_fee = bumped_psbt.fee_amount().unwrap();
let bumped_tx = bumped_psbt.extract_tx()?;
Expand Down
27 changes: 20 additions & 7 deletions examples/esplora_async.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use bdk_esplora::{EsploraAsyncExt, esplora_client};
use bdk_wallet::{
KeychainKind, SignOptions, Wallet,
bitcoin::{Amount, FeeRate, Network},
bitcoin::{Amount, FeeRate, Network, secp256k1::Secp256k1},
descriptor::IntoWalletDescriptor,
miniscript::descriptor::KeyMapWrapper,
psbt::PsbtUtils,
rusqlite::Connection,
};
Expand All @@ -20,16 +22,22 @@ const ESPLORA_URL: &str = "https://mempool.space/testnet4/api";

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
let secp = Secp256k1::new();
let (external_descriptor, mut external_keymap) =
EXTERNAL_DESC.into_wallet_descriptor(&secp, NETWORK.into())?;
let (internal_descriptor, internal_keymap) =
INTERNAL_DESC.into_wallet_descriptor(&secp, NETWORK.into())?;
external_keymap.extend(internal_keymap);
let signer = KeyMapWrapper::from(external_keymap);
let mut db = Connection::open(DB_PATH)?;
let wallet_opt = Wallet::load()
.descriptor(KeychainKind::External, Some(EXTERNAL_DESC))
.descriptor(KeychainKind::Internal, Some(INTERNAL_DESC))
.extract_keys()
.descriptor(KeychainKind::External, Some(external_descriptor.clone()))
.descriptor(KeychainKind::Internal, Some(internal_descriptor.clone()))
.check_network(NETWORK)
.load_wallet(&mut db)?;
let mut wallet = match wallet_opt {
Some(wallet) => wallet,
None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
None => Wallet::create(external_descriptor, internal_descriptor)
.network(NETWORK)
.create_wallet(&mut db)?,
};
Expand Down Expand Up @@ -83,7 +91,9 @@ async fn main() -> Result<(), anyhow::Error> {
tx_builder.fee_rate(target_fee_rate);

let mut psbt = tx_builder.finish()?;
let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
psbt.sign(&signer, wallet.secp_ctx())
.map_err(|(_, e)| anyhow::anyhow!("{e:?}"))?;
let finalized = wallet.finalize_psbt(&mut psbt, SignOptions::default())?;
assert!(finalized);
let original_fee = psbt.fee_amount().unwrap();
let tx_feerate = psbt.fee_rate().unwrap();
Expand Down Expand Up @@ -117,7 +127,10 @@ async fn main() -> Result<(), anyhow::Error> {
let mut builder = wallet.build_fee_bump(txid).expect("failed to bump tx");
builder.fee_rate(feerate);
let mut bumped_psbt = builder.finish().unwrap();
let finalize_btx = wallet.sign(&mut bumped_psbt, SignOptions::default())?;
bumped_psbt
.sign(&signer, wallet.secp_ctx())
.map_err(|(_, e)| anyhow::anyhow!("{e:?}"))?;
let finalize_btx = wallet.finalize_psbt(&mut bumped_psbt, SignOptions::default())?;
assert!(finalize_btx);
let new_fee = bumped_psbt.fee_amount().unwrap();
let bumped_tx = bumped_psbt.extract_tx()?;
Expand Down
27 changes: 20 additions & 7 deletions examples/esplora_blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use bdk_esplora::{EsploraExt, esplora_client};
use bdk_wallet::rusqlite::Connection;
use bdk_wallet::{
KeychainKind, SignOptions, Wallet,
bitcoin::{Amount, FeeRate, Network},
bitcoin::{Amount, FeeRate, Network, secp256k1::Secp256k1},
descriptor::IntoWalletDescriptor,
miniscript::descriptor::KeyMapWrapper,
psbt::PsbtUtils,
};
use std::thread::sleep;
Expand All @@ -20,16 +22,22 @@ const INTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7
const ESPLORA_URL: &str = "https://mempool.space/testnet4/api";

fn main() -> Result<(), anyhow::Error> {
let secp = Secp256k1::new();
let (external_descriptor, mut external_keymap) =
EXTERNAL_DESC.into_wallet_descriptor(&secp, NETWORK.into())?;
let (internal_descriptor, internal_keymap) =
INTERNAL_DESC.into_wallet_descriptor(&secp, NETWORK.into())?;
external_keymap.extend(internal_keymap);
let signer = KeyMapWrapper::from(external_keymap);
let mut db = Connection::open(DB_PATH)?;
let wallet_opt = Wallet::load()
.descriptor(KeychainKind::External, Some(EXTERNAL_DESC))
.descriptor(KeychainKind::Internal, Some(INTERNAL_DESC))
.extract_keys()
.descriptor(KeychainKind::External, Some(external_descriptor.clone()))
.descriptor(KeychainKind::Internal, Some(internal_descriptor.clone()))
.check_network(NETWORK)
.load_wallet(&mut db)?;
let mut wallet = match wallet_opt {
Some(wallet) => wallet,
None => Wallet::create(EXTERNAL_DESC, INTERNAL_DESC)
None => Wallet::create(external_descriptor, internal_descriptor)
.network(NETWORK)
.create_wallet(&mut db)?,
};
Expand Down Expand Up @@ -78,7 +86,9 @@ fn main() -> Result<(), anyhow::Error> {
tx_builder.fee_rate(target_fee_rate);

let mut psbt = tx_builder.finish()?;
let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
psbt.sign(&signer, wallet.secp_ctx())
.map_err(|(_, e)| anyhow::anyhow!("{e:?}"))?;
let finalized = wallet.finalize_psbt(&mut psbt, SignOptions::default())?;
assert!(finalized);
let original_fee = psbt.fee_amount().unwrap();
let tx_feerate = psbt.fee_rate().unwrap();
Expand Down Expand Up @@ -113,7 +123,10 @@ fn main() -> Result<(), anyhow::Error> {
let mut builder = wallet.build_fee_bump(txid).unwrap();
builder.fee_rate(feerate);
let mut new_psbt = builder.finish().unwrap();
let finalize_tx = wallet.sign(&mut new_psbt, SignOptions::default())?;
new_psbt
.sign(&signer, wallet.secp_ctx())
.map_err(|(_, e)| anyhow::anyhow!("{e:?}"))?;
let finalize_tx = wallet.finalize_psbt(&mut new_psbt, SignOptions::default())?;
assert!(finalize_tx);
let new_fee = new_psbt.fee_amount().unwrap();
let bumped_tx = new_psbt.extract_tx()?;
Expand Down
2 changes: 1 addition & 1 deletion src/descriptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub mod template;

pub use self::checksum::calc_checksum;
pub use self::error::Error as DescriptorError;
pub use self::policy::Policy;
pub use self::policy::{Condition, Policy};
use self::template::DescriptorTemplateOut;
use crate::keys::{IntoDescriptorKey, KeyError};
use crate::wallet::{signer::SignersContainer, utils::SecpCtx};
Expand Down
6 changes: 5 additions & 1 deletion src/descriptor/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,11 @@ impl Condition {
}
}

pub(crate) fn merge(mut self, other: &Condition) -> Result<Self, PolicyError> {
/// Merge two [`Condition`]s into the strictest combined CSV / CLTV requirements.
///
/// Useful when combining external and internal keychain requirements into one `Condition`
/// before passing it to the transaction builder.
pub fn merge(mut self, other: &Condition) -> Result<Self, PolicyError> {
match (self.csv, other.csv) {
(Some(a), Some(b)) => self.csv = Some(Self::merge_nsequence(a, b)?),
(None, any) => self.csv = any,
Expand Down
Loading