1
- use bitcoin:: secp256k1:: PublicKey ;
2
1
use lightning:: chain:: channelmonitor:: Balance as LdkBalance ;
3
2
use lightning:: ln:: { ChannelId , PaymentHash , PaymentPreimage } ;
4
3
4
+ use bitcoin:: secp256k1:: PublicKey ;
5
+ use bitcoin:: { BlockHash , Txid } ;
6
+
7
+ use crate :: sweep:: SpendableOutputInfo ;
8
+
5
9
/// Details of the known available balances returned by [`Node::list_balances`].
6
10
///
7
11
/// [`Node::list_balances`]: crate::Node::list_balances
@@ -24,6 +28,15 @@ pub struct BalanceDetails {
24
28
pub total_lightning_balance_sats : u64 ,
25
29
/// A detailed list of all known Lightning balances.
26
30
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 > ,
27
40
}
28
41
29
42
/// Details about the status of a known Lightning balance.
@@ -190,3 +203,90 @@ impl LightningBalance {
190
203
}
191
204
}
192
205
}
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