1- use bitcoin:: secp256k1:: PublicKey ;
21use lightning:: chain:: channelmonitor:: Balance as LdkBalance ;
32use lightning:: ln:: { ChannelId , PaymentHash , PaymentPreimage } ;
43
4+ use bitcoin:: secp256k1:: PublicKey ;
5+ use bitcoin:: { BlockHash , Txid } ;
6+
7+ use crate :: sweep:: SpendableOutputInfo ;
8+
59/// Details of the known available balances returned by [`Node::list_balances`].
610///
711/// [`Node::list_balances`]: crate::Node::list_balances
@@ -15,6 +19,15 @@ pub struct BalanceDetails {
1519 pub total_lightning_balance_sats : u64 ,
1620 /// A detailed list of all known Lightning balances.
1721 pub lightning_balances : Vec < LightningBalance > ,
22+ /// A detailed list of balances currently being swept from the Lightning to the on-chain
23+ /// wallet.
24+ ///
25+ /// These are balances resulting from channel closures that may have been encumbered by a
26+ /// delay, but are now being claimed and useable once sufficiently confirmed on-chain.
27+ ///
28+ /// Note that, depending on the sync status of the wallets, swept balances listed here might or
29+ /// might not already be accounted for in [`Self::total_onchain_balance_sats`].
30+ pub sweeper_balances : Vec < SweeperBalance > ,
1831}
1932
2033/// Details about the status of a known Lightning balance.
@@ -184,3 +197,90 @@ impl LightningBalance {
184197 }
185198 }
186199}
200+
201+ /// Details about the status of a known balance currently being swept to our on-chain wallet.
202+ #[ derive( Debug , Clone ) ]
203+ pub enum SweeperBalance {
204+ /// The spendable output is about to be swept, but a spending transaction has yet to be generated and
205+ /// broadcast.
206+ PendingBroadcast {
207+ /// The identifier of the channel this balance belongs to.
208+ channel_id : Option < ChannelId > ,
209+ /// The amount, in satoshis, of the output being swept.
210+ amount_satoshis : u64 ,
211+ } ,
212+ /// A spending transaction has been generated and broadcast and is awaiting confirmation
213+ /// on-chain.
214+ BroadcastAwaitingConfirmation {
215+ /// The identifier of the channel this balance belongs to.
216+ channel_id : Option < ChannelId > ,
217+ /// The best height when we last broadcast a transaction spending the output being swept.
218+ latest_broadcast_height : u32 ,
219+ /// The identifier of the transaction spending the swept output we last broadcast.
220+ latest_spending_txid : Txid ,
221+ /// The amount, in satoshis, of the output being swept.
222+ amount_satoshis : u64 ,
223+ } ,
224+ /// A spending transaction has been confirmed on-chain and is awaiting threshold confirmations.
225+ ///
226+ /// It will be considered irrevocably confirmed after reaching [`ANTI_REORG_DELAY`].
227+ ///
228+ /// [`ANTI_REORG_DELAY`]: lightning::chain::channelmonitor::ANTI_REORG_DELAY
229+ AwaitingThresholdConfirmations {
230+ /// The identifier of the channel this balance belongs to.
231+ channel_id : Option < ChannelId > ,
232+ /// The identifier of the confirmed transaction spending the swept output.
233+ latest_spending_txid : Txid ,
234+ /// The hash of the block in which the spending transaction was confirmed.
235+ confirmation_hash : BlockHash ,
236+ /// The height at which the spending transaction was confirmed.
237+ confirmation_height : u32 ,
238+ /// The amount, in satoshis, of the output being swept.
239+ amount_satoshis : u64 ,
240+ } ,
241+ }
242+
243+ impl SweeperBalance {
244+ pub ( crate ) fn from_tracked_spendable_output ( output_info : SpendableOutputInfo ) -> Self {
245+ if let Some ( confirmation_hash) = output_info. confirmation_hash {
246+ debug_assert ! ( output_info. confirmation_height. is_some( ) ) ;
247+ debug_assert ! ( output_info. latest_spending_tx. is_some( ) ) ;
248+ let channel_id = output_info. channel_id ;
249+ let confirmation_height = output_info
250+ . confirmation_height
251+ . expect ( "Height must be set if the output is confirmed" ) ;
252+ let latest_spending_txid = output_info
253+ . latest_spending_tx
254+ . as_ref ( )
255+ . expect ( "Spending tx must be set if the output is confirmed" )
256+ . txid ( ) ;
257+ let amount_satoshis = output_info. value_satoshis ( ) ;
258+ Self :: AwaitingThresholdConfirmations {
259+ channel_id,
260+ latest_spending_txid,
261+ confirmation_hash,
262+ confirmation_height,
263+ amount_satoshis,
264+ }
265+ } else if let Some ( latest_broadcast_height) = output_info. latest_broadcast_height {
266+ debug_assert ! ( output_info. latest_spending_tx. is_some( ) ) ;
267+ let channel_id = output_info. channel_id ;
268+ let latest_spending_txid = output_info
269+ . latest_spending_tx
270+ . as_ref ( )
271+ . expect ( "Spending tx must be set if the spend was broadcast" )
272+ . txid ( ) ;
273+ let amount_satoshis = output_info. value_satoshis ( ) ;
274+ Self :: BroadcastAwaitingConfirmation {
275+ channel_id,
276+ latest_broadcast_height,
277+ latest_spending_txid,
278+ amount_satoshis,
279+ }
280+ } else {
281+ let channel_id = output_info. channel_id ;
282+ let amount_satoshis = output_info. value_satoshis ( ) ;
283+ Self :: PendingBroadcast { channel_id, amount_satoshis }
284+ }
285+ }
286+ }
0 commit comments