@@ -4,6 +4,7 @@ use crate::Error;
4
4
5
5
use lightning:: chain:: chaininterface:: { BroadcasterInterface , ConfirmationTarget , FeeEstimator } ;
6
6
7
+ use lightning:: events:: bump_transaction:: { Utxo , WalletSource } ;
7
8
use lightning:: ln:: msgs:: { DecodeError , UnsignedGossipMessage } ;
8
9
use lightning:: ln:: script:: ShutdownScript ;
9
10
use lightning:: sign:: {
@@ -19,8 +20,12 @@ use bdk::wallet::AddressIndex;
19
20
use bdk:: FeeRate ;
20
21
use bdk:: { SignOptions , SyncOptions } ;
21
22
23
+ use bitcoin:: address:: { Payload , WitnessVersion } ;
22
24
use bitcoin:: bech32:: u5;
23
25
use bitcoin:: blockdata:: locktime:: absolute:: LockTime ;
26
+ use bitcoin:: hash_types:: WPubkeyHash ;
27
+ use bitcoin:: hashes:: Hash ;
28
+ use bitcoin:: psbt:: PartiallySignedTransaction ;
24
29
use bitcoin:: secp256k1:: ecdh:: SharedSecret ;
25
30
use bitcoin:: secp256k1:: ecdsa:: { RecoverableSignature , Signature } ;
26
31
use bitcoin:: secp256k1:: { PublicKey , Scalar , Secp256k1 , Signing } ;
@@ -245,6 +250,97 @@ where
245
250
}
246
251
}
247
252
253
+ impl < D , B : Deref , E : Deref , L : Deref > WalletSource for Wallet < D , B , E , L >
254
+ where
255
+ D : BatchDatabase ,
256
+ B :: Target : BroadcasterInterface ,
257
+ E :: Target : FeeEstimator ,
258
+ L :: Target : Logger ,
259
+ {
260
+ fn list_confirmed_utxos ( & self ) -> Result < Vec < Utxo > , ( ) > {
261
+ let locked_wallet = self . inner . lock ( ) . unwrap ( ) ;
262
+ let mut utxos = Vec :: new ( ) ;
263
+ let txs = locked_wallet. list_transactions ( true ) . map_err ( |e| {
264
+ log_error ! ( self . logger, "Failed to retrieve transactions from wallet: {}" , e) ;
265
+ } ) ?;
266
+ let unspent = locked_wallet. list_unspent ( ) . map_err ( |e| {
267
+ log_error ! ( self . logger, "Failed to retrieve unspent transactions from wallet: {}" , e) ;
268
+ } ) ?;
269
+
270
+ for u in unspent {
271
+ for t in & txs {
272
+ if u. outpoint . txid == t. txid && t. confirmation_time . is_some ( ) {
273
+ let payload = Payload :: from_script ( & u. txout . script_pubkey ) . map_err ( |e| {
274
+ log_error ! ( self . logger, "Failed to retrieve script payload: {}" , e) ;
275
+ } ) ?;
276
+
277
+ match payload {
278
+ Payload :: WitnessProgram ( program) => {
279
+ if program. version ( ) == WitnessVersion :: V0
280
+ && program. program ( ) . len ( ) == 20
281
+ {
282
+ let wpkh = WPubkeyHash :: from_slice ( program. program ( ) . as_bytes ( ) )
283
+ . map_err ( |e| {
284
+ log_error ! (
285
+ self . logger,
286
+ "Failed to retrieve script payload: {}" ,
287
+ e
288
+ ) ;
289
+ } ) ?;
290
+ let utxo = Utxo :: new_v0_p2wpkh ( u. outpoint , u. txout . value , & wpkh) ;
291
+ utxos. push ( utxo) ;
292
+ } else {
293
+ log_error ! (
294
+ self . logger,
295
+ "Unexpected program length: {}" ,
296
+ program. program( ) . len( )
297
+ ) ;
298
+ }
299
+ }
300
+ _ => {
301
+ log_error ! (
302
+ self . logger,
303
+ "Tried to use a non-witness script. This must never happen."
304
+ ) ;
305
+ panic ! ( "Tried to use a non-witness script. This must never happen." ) ;
306
+ }
307
+ }
308
+ }
309
+ }
310
+ }
311
+
312
+ Ok ( utxos)
313
+ }
314
+
315
+ fn get_change_script ( & self ) -> Result < ScriptBuf , ( ) > {
316
+ let locked_wallet = self . inner . lock ( ) . unwrap ( ) ;
317
+ let address_info = locked_wallet. get_address ( AddressIndex :: New ) . map_err ( |e| {
318
+ log_error ! ( self . logger, "Failed to retrieve new address from wallet: {}" , e) ;
319
+ } ) ?;
320
+
321
+ Ok ( address_info. address . script_pubkey ( ) )
322
+ }
323
+
324
+ fn sign_psbt ( & self , mut psbt : PartiallySignedTransaction ) -> Result < Transaction , ( ) > {
325
+ let locked_wallet = self . inner . lock ( ) . unwrap ( ) ;
326
+
327
+ match locked_wallet. sign ( & mut psbt, SignOptions :: default ( ) ) {
328
+ Ok ( finalized) => {
329
+ if !finalized {
330
+ log_error ! ( self . logger, "Failed to finalize PSBT." ) ;
331
+ return Err ( ( ) ) ;
332
+ }
333
+ }
334
+ Err ( err) => {
335
+ log_error ! ( self . logger, "Failed to sign transaction: {}" , err) ;
336
+ return Err ( ( ) ) ;
337
+ }
338
+ }
339
+
340
+ Ok ( psbt. extract_tx ( ) )
341
+ }
342
+ }
343
+
248
344
/// Similar to [`KeysManager`], but overrides the destination and shutdown scripts so they are
249
345
/// directly spendable by the BDK wallet.
250
346
pub struct WalletKeysManager < D , B : Deref , E : Deref , L : Deref >
@@ -398,11 +494,10 @@ where
398
494
} ) ?;
399
495
400
496
match address. payload {
401
- bitcoin :: address :: Payload :: WitnessProgram ( program) => {
402
- ShutdownScript :: new_witness_program ( & program ) . map_err ( |e| {
497
+ Payload :: WitnessProgram ( program) => ShutdownScript :: new_witness_program ( & program )
498
+ . map_err ( |e| {
403
499
log_error ! ( self . logger, "Invalid shutdown script: {:?}" , e) ;
404
- } )
405
- }
500
+ } ) ,
406
501
_ => {
407
502
log_error ! (
408
503
self . logger,
0 commit comments