Skip to content

Commit bc589b6

Browse files
committed
feat(wallet): expose TxGraph::verify_tx via Wallet
* Add feature `bitcoinconsensus` to Cargo.toml
1 parent e81fd4d commit bc589b6

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

crates/bdk/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ std = ["bitcoin/std", "miniscript/std", "bdk_chain/std"]
3333
compiler = ["miniscript/compiler"]
3434
all-keys = ["keys-bip39"]
3535
keys-bip39 = ["bip39"]
36+
bitcoinconsensus = ["bdk_chain/bitcoinconsensus"]
3637

3738
# This feature is used to run `cargo check` in our CI targeting wasm. It's not recommended
3839
# for libraries to explicitly include the "getrandom/js" feature, so we only do it when

crates/bdk/src/wallet/mod.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ use descriptor::error::Error as DescriptorError;
4444
use miniscript::psbt::{PsbtExt, PsbtInputExt, PsbtInputSatisfier};
4545

4646
use bdk_chain::tx_graph::CalculateFeeError;
47+
#[cfg(feature = "bitcoinconsensus")]
48+
use bdk_chain::tx_graph::VerifyTxError;
4749

4850
pub mod coin_selection;
4951
pub mod export;
@@ -2488,6 +2490,45 @@ impl<D> Wallet<D> {
24882490
.batch_insert_relevant_unconfirmed(unconfirmed_txs);
24892491
self.persist.stage(ChangeSet::from(indexed_graph_changeset));
24902492
}
2493+
2494+
/// Verify the given transaction is able to spend its inputs.
2495+
///
2496+
/// This method uses [`rust-bitcoinconsensus`] to verify a [`Transaction`], guaranteeing
2497+
/// that if the method succeeds, the transaction meets consensus criteria as defined in
2498+
/// Bitcoin's `libbitcoinconsensus`.
2499+
///
2500+
/// # Example
2501+
///
2502+
/// ```rust
2503+
/// # use bdk::SignOptions;
2504+
/// # use bdk::wallet::AddressIndex;
2505+
/// # let mut wallet = bdk::doctest_wallet!();
2506+
/// # let address = wallet.get_address(AddressIndex::New);
2507+
/// let mut builder = wallet.build_tx();
2508+
/// builder.add_recipient(address.script_pubkey(), 210_000);
2509+
/// let mut psbt = builder.finish().unwrap();
2510+
/// let _ = wallet.sign(&mut psbt, SignOptions::default()).unwrap();
2511+
/// let tx = psbt.extract_tx();
2512+
/// assert!(wallet.verify_tx(&tx).is_ok());
2513+
/// ```
2514+
///
2515+
/// **Note** that validation by the Bitcoin network can ultimately fail in other ways,
2516+
/// for example if a timelock hasn't been met. Also, verifying that a transaction
2517+
/// can spend its inputs doesn't guarantee it will be accepted to mempools or propagated
2518+
/// by nodes on the peer-to-peer network.
2519+
///
2520+
/// # Errors
2521+
///
2522+
/// If the previous output isn't found for one or more `tx` inputs.
2523+
///
2524+
/// If [`Script`] verification fails.
2525+
///
2526+
/// [`rust-bitcoinconsensus`]: https://docs.rs/bitcoinconsensus/latest/bitcoinconsensus/
2527+
#[cfg(feature = "bitcoinconsensus")]
2528+
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
2529+
pub fn verify_tx(&self, tx: &Transaction) -> Result<(), VerifyTxError> {
2530+
self.tx_graph().verify_tx(tx)
2531+
}
24912532
}
24922533

24932534
impl<D> AsRef<bdk_chain::tx_graph::TxGraph<ConfirmationTimeHeightAnchor>> for Wallet<D> {

0 commit comments

Comments
 (0)