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
@@ -24,6 +28,15 @@ pub struct BalanceDetails {
2428 pub total_lightning_balance_sats : u64 ,
2529 /// A detailed list of all known Lightning balances.
2630 pub lightning_balances : Vec < LightningBalance > ,
31+ /// A detailed list of balances currently being swept from the Lightning to the on-chain
32+ /// wallet.
33+ ///
34+ /// These are balances resulting from channel closures that may have been encumbered by a
35+ /// delay, but are now being claimed and useable once sufficiently confirmed on-chain.
36+ ///
37+ /// Note that, depending on the sync status of the wallets, swept balances listed here might or
38+ /// might not already be accounted for in [`Self::total_onchain_balance_sats`].
39+ pub sweeper_balances : Vec < SweeperBalance > ,
2740}
2841
2942/// Details about the status of a known Lightning balance.
@@ -190,3 +203,90 @@ impl LightningBalance {
190203 }
191204 }
192205}
206+
207+ /// Details about the status of a known balance currently being swept to our on-chain wallet.
208+ #[ derive( Debug , Clone ) ]
209+ pub enum SweeperBalance {
210+ /// The spendable output is about to be swept, but a spending transaction has yet to be generated and
211+ /// broadcast.
212+ PendingBroadcast {
213+ /// The identifier of the channel this balance belongs to.
214+ channel_id : Option < ChannelId > ,
215+ /// The amount, in satoshis, of the output being swept.
216+ amount_satoshis : u64 ,
217+ } ,
218+ /// A spending transaction has been generated and broadcast and is awaiting confirmation
219+ /// on-chain.
220+ BroadcastAwaitingConfirmation {
221+ /// The identifier of the channel this balance belongs to.
222+ channel_id : Option < ChannelId > ,
223+ /// The best height when we last broadcast a transaction spending the output being swept.
224+ latest_broadcast_height : u32 ,
225+ /// The identifier of the transaction spending the swept output we last broadcast.
226+ latest_spending_txid : Txid ,
227+ /// The amount, in satoshis, of the output being swept.
228+ amount_satoshis : u64 ,
229+ } ,
230+ /// A spending transaction has been confirmed on-chain and is awaiting threshold confirmations.
231+ ///
232+ /// It will be considered irrevocably confirmed after reaching [`ANTI_REORG_DELAY`].
233+ ///
234+ /// [`ANTI_REORG_DELAY`]: lightning::chain::channelmonitor::ANTI_REORG_DELAY
235+ AwaitingThresholdConfirmations {
236+ /// The identifier of the channel this balance belongs to.
237+ channel_id : Option < ChannelId > ,
238+ /// The identifier of the confirmed transaction spending the swept output.
239+ latest_spending_txid : Txid ,
240+ /// The hash of the block in which the spending transaction was confirmed.
241+ confirmation_hash : BlockHash ,
242+ /// The height at which the spending transaction was confirmed.
243+ confirmation_height : u32 ,
244+ /// The amount, in satoshis, of the output being swept.
245+ amount_satoshis : u64 ,
246+ } ,
247+ }
248+
249+ impl SweeperBalance {
250+ pub ( crate ) fn from_tracked_spendable_output ( output_info : SpendableOutputInfo ) -> Self {
251+ if let Some ( confirmation_hash) = output_info. confirmation_hash {
252+ debug_assert ! ( output_info. confirmation_height. is_some( ) ) ;
253+ debug_assert ! ( output_info. latest_spending_tx. is_some( ) ) ;
254+ let channel_id = output_info. channel_id ;
255+ let confirmation_height = output_info
256+ . confirmation_height
257+ . expect ( "Height must be set if the output is confirmed" ) ;
258+ let latest_spending_txid = output_info
259+ . latest_spending_tx
260+ . as_ref ( )
261+ . expect ( "Spending tx must be set if the output is confirmed" )
262+ . txid ( ) ;
263+ let amount_satoshis = output_info. value_satoshis ( ) ;
264+ Self :: AwaitingThresholdConfirmations {
265+ channel_id,
266+ latest_spending_txid,
267+ confirmation_hash,
268+ confirmation_height,
269+ amount_satoshis,
270+ }
271+ } else if let Some ( latest_broadcast_height) = output_info. latest_broadcast_height {
272+ debug_assert ! ( output_info. latest_spending_tx. is_some( ) ) ;
273+ let channel_id = output_info. channel_id ;
274+ let latest_spending_txid = output_info
275+ . latest_spending_tx
276+ . as_ref ( )
277+ . expect ( "Spending tx must be set if the spend was broadcast" )
278+ . txid ( ) ;
279+ let amount_satoshis = output_info. value_satoshis ( ) ;
280+ Self :: BroadcastAwaitingConfirmation {
281+ channel_id,
282+ latest_broadcast_height,
283+ latest_spending_txid,
284+ amount_satoshis,
285+ }
286+ } else {
287+ let channel_id = output_info. channel_id ;
288+ let amount_satoshis = output_info. value_satoshis ( ) ;
289+ Self :: PendingBroadcast { channel_id, amount_satoshis }
290+ }
291+ }
292+ }
0 commit comments