diff --git a/crates/chain/src/tx_graph.rs b/crates/chain/src/tx_graph.rs
index 965174fe..199c85ea 100644
--- a/crates/chain/src/tx_graph.rs
+++ b/crates/chain/src/tx_graph.rs
@@ -258,6 +258,19 @@ impl TxGraph {
})
}
+ /// Iterate over graph transactions with no anchors or last-seen.
+ pub fn txs_with_no_anchor_or_last_seen(
+ &self,
+ ) -> impl Iterator- , A>> {
+ self.full_txs().filter_map(|tx| {
+ if tx.anchors.is_empty() && tx.last_seen_unconfirmed.is_none() {
+ Some(tx)
+ } else {
+ None
+ }
+ })
+ }
+
/// Get a transaction by txid. This only returns `Some` for full transactions.
///
/// Refer to [`get_txout`] for getting a specific [`TxOut`].
diff --git a/crates/chain/tests/test_tx_graph.rs b/crates/chain/tests/test_tx_graph.rs
index 907fec27..c46ab169 100644
--- a/crates/chain/tests/test_tx_graph.rs
+++ b/crates/chain/tests/test_tx_graph.rs
@@ -1127,6 +1127,8 @@ fn transactions_inserted_into_tx_graph_are_not_canonical_until_they_have_an_anch
let mut graph = TxGraph::::new(txs);
let full_txs: Vec<_> = graph.full_txs().collect();
assert_eq!(full_txs.len(), 2);
+ let unseen_txs: Vec<_> = graph.txs_with_no_anchor_or_last_seen().collect();
+ assert_eq!(unseen_txs.len(), 2);
// chain
let blocks: BTreeMap = [(0, h!("g")), (1, h!("A")), (2, h!("B"))]
@@ -1154,6 +1156,7 @@ fn transactions_inserted_into_tx_graph_are_not_canonical_until_they_have_an_anch
.map(|tx| tx.tx_node.txid)
.collect();
assert!(canonical_txids.contains(&txids[1]));
+ assert!(graph.txs_with_no_anchor_or_last_seen().next().is_none());
}
#[test]
diff --git a/crates/wallet/src/wallet/mod.rs b/crates/wallet/src/wallet/mod.rs
index 235f600b..105d07f8 100644
--- a/crates/wallet/src/wallet/mod.rs
+++ b/crates/wallet/src/wallet/mod.rs
@@ -27,7 +27,7 @@ use bdk_chain::{
self, ApplyHeaderError, CannotConnectError, CheckPoint, CheckPointIter, LocalChain,
},
spk_client::{FullScanRequest, FullScanResult, SyncRequest, SyncResult},
- tx_graph::{CanonicalTx, TxGraph},
+ tx_graph::{CanonicalTx, TxGraph, TxNode},
Append, BlockId, ChainPosition, ConfirmationTime, ConfirmationTimeHeightAnchor, FullTxOut,
Indexed, IndexedTxGraph,
};
@@ -2250,6 +2250,14 @@ impl Wallet {
self.indexed_graph.graph()
}
+ /// Iterate over transactions in the wallet that are unseen and unanchored likely
+ /// because they haven't been broadcast.
+ pub fn unbroadcast_transactions(
+ &self,
+ ) -> impl Iterator
- , ConfirmationTimeHeightAnchor>> {
+ self.tx_graph().txs_with_no_anchor_or_last_seen()
+ }
+
/// Get a reference to the inner [`KeychainTxOutIndex`].
pub fn spk_index(&self) -> &KeychainTxOutIndex {
&self.indexed_graph.index