Skip to content

Commit 45135b3

Browse files
temp 1
1 parent 3e61d2a commit 45135b3

File tree

3 files changed

+69
-3
lines changed

3 files changed

+69
-3
lines changed

wallet/src/wallet/mod.rs

+40-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ use crate::wallet::{
7272
error::{BuildFeeBumpError, CreateTxError, MiniscriptPsbtError},
7373
signer::{SignOptions, SignerError, SignerOrdering, SignersContainer, TransactionSigner},
7474
tx_builder::{FeePolicy, TxBuilder, TxParams},
75-
utils::{check_nsequence_rbf, After, Older, SecpCtx},
75+
utils::{check_nsequence_rbf, After, Older, SecpCtx, TxDetails},
7676
};
7777

7878
// re-exports
@@ -821,6 +821,45 @@ impl Wallet {
821821
.map(|((k, i), full_txo)| new_local_utxo(k, i, full_txo))
822822
}
823823

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