Skip to content

Commit 0e2ca1c

Browse files
temp 1
1 parent 3e61d2a commit 0e2ca1c

File tree

3 files changed

+71
-2
lines changed

3 files changed

+71
-2
lines changed

wallet/src/wallet/mod.rs

+42
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ use crate::wallet::{
7676
};
7777

7878
// re-exports
79+
#[cfg(feature = "std")]
80+
use crate::wallet::utils::TxDetails;
81+
7982
pub use bdk_chain::Balance;
8083
pub use changeset::ChangeSet;
8184
pub use params::*;
@@ -821,6 +824,45 @@ impl Wallet {
821824
.map(|((k, i), full_txo)| new_local_utxo(k, i, full_txo))
822825
}
823826

827+
/// Build a [`TxDetails`] struct for a given transaction.
828+
///
829+
/// If the transaction with txid [`Txid`] cannot be found in the wallet's transaction graph,
830+
/// None is returned.
831+
// #[cfg(feature = "std")]
832+
pub fn get_tx_details(&self, txid: Txid) -> Option<TxDetails> {
833+
let tx_graph = self.indexed_graph.graph();
834+
let tx_index = &self.indexed_graph.index;
835+
836+
// It should be impossible to have more than 1 right? In which case I can use the `find()`
837+
// method on the collection instead of collecting into a vector.
838+
839+
// This relies on the impossibility of having 2 transactions with the same Txid in the list
840+
// canonical transactions but let me know if this is wrong!
841+
let optional_tx: Option<CanonicalTx<Arc<Transaction>, ConfirmationBlockTime>> = tx_graph
842+
.list_canonical_txs(&self.chain, self.chain.tip().block_id())
843+
.filter(|c_tx| tx_index.is_tx_relevant(&c_tx.tx_node.tx))
844+
.find(|tx| tx.tx_node.compute_txid() == txid);
845+
846+
let tx = optional_tx?;
847+
848+
let (sent, received) = self.sent_and_received(&tx.tx_node.tx);
849+
let fee = self.calculate_fee(&tx.tx_node.tx).unwrap();
850+
let fee_rate = self.calculate_fee_rate(&tx.tx_node.tx).unwrap();
851+
let chain_position = tx.chain_position;
852+
853+
let tx_details: TxDetails = TxDetails {
854+
txid,
855+
received,
856+
sent,
857+
fee,
858+
fee_rate,
859+
chain_position,
860+
tx: tx.tx_node.tx,
861+
};
862+
863+
Some(tx_details)
864+
}
865+
824866
/// List all relevant outputs (includes both spent and unspent, confirmed and unconfirmed).
825867
///
826868
/// To list only unspent outputs (UTXOs), use [`Wallet::list_unspent`] instead.

wallet/src/wallet/utils.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
// You may not use this file except in accordance with one or both of these
1010
// licenses.
1111

12+
use alloc::sync::Arc;
1213
use bitcoin::secp256k1::{All, Secp256k1};
13-
use bitcoin::{absolute, relative, Amount, Script, Sequence};
14-
14+
use bitcoin::{absolute, relative, Amount, FeeRate, Script, Sequence, Transaction, Txid};
15+
use chain::{ChainPosition, ConfirmationBlockTime};
1516
use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};
1617

1718
use rand_core::RngCore;
@@ -133,6 +134,18 @@ pub(crate) fn shuffle_slice<T>(list: &mut [T], rng: &mut impl RngCore) {
133134

134135
pub(crate) type SecpCtx = Secp256k1<All>;
135136

137+
/// Details about a transaction the wallet knows about.
138+
#[derive(Debug)]
139+
pub struct TxDetails {
140+
pub txid: Txid,
141+
pub received: Amount,
142+
pub sent: Amount,
143+
pub fee: Amount,
144+
pub fee_rate: FeeRate,
145+
pub chain_position: ChainPosition<ConfirmationBlockTime>,
146+
pub tx: Arc<Transaction>,
147+
}
148+
136149
#[cfg(test)]
137150
mod test {
138151
// When nSequence is lower than this flag the timelock is interpreted as block-height-based,

wallet/tests/wallet.rs

+14
Original file line numberDiff line numberDiff line change
@@ -4306,3 +4306,17 @@ fn test_wallet_transactions_relevant() {
43064306
assert!(full_tx_count_before < full_tx_count_after);
43074307
assert!(canonical_tx_count_before < canonical_tx_count_after);
43084308
}
4309+
4310+
#[test]
4311+
fn test_tx_details_method() {
4312+
let (test_wallet, txid_1) = get_funded_wallet_wpkh();
4313+
let tx_details_1 = test_wallet.get_tx_details(txid_1);
4314+
// dbg!(&tx_details);
4315+
4316+
// Transaction id not part of the TxGraph
4317+
let txid_2 = Txid::from_raw_hash(Hash::all_zeros());
4318+
let tx_details_2 = test_wallet.get_tx_details(txid_2);
4319+
4320+
assert!(tx_details_1.is_some());
4321+
assert!(tx_details_2.is_none());
4322+
}

0 commit comments

Comments
 (0)