@@ -35,6 +35,7 @@ use bitcoin::{OutPoint, PubkeyHash, Sequence, ScriptBuf, Transaction, TxIn, TxOu
3535use  bitcoin:: blockdata:: constants:: WITNESS_SCALE_FACTOR ; 
3636use  bitcoin:: blockdata:: locktime:: absolute:: LockTime ; 
3737use  bitcoin:: consensus:: Encodable ; 
38+ use  bitcoin:: psbt:: PartiallySignedTransaction ; 
3839use  bitcoin:: secp256k1; 
3940use  bitcoin:: secp256k1:: Secp256k1 ; 
4041use  bitcoin:: secp256k1:: ecdsa:: Signature ; 
@@ -343,7 +344,10 @@ pub trait CoinSelectionSource {
343344	)  -> Result < CoinSelection ,  ( ) > ; 
344345	/// Signs and provides the full witness for all inputs within the transaction known to the 
345346/// trait (i.e., any provided via [`CoinSelectionSource::select_confirmed_utxos`]). 
346- fn  sign_tx ( & self ,  tx :  Transaction )  -> Result < Transaction ,  ( ) > ; 
347+ /// 
348+ /// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the 
349+ /// unsigned transaction and then sign it with your wallet. 
350+ fn  sign_psbt ( & self ,  psbt :  PartiallySignedTransaction )  -> Result < Transaction ,  ( ) > ; 
347351} 
348352
349353/// An alternative to [`CoinSelectionSource`] that can be implemented and used along [`Wallet`] to 
@@ -357,7 +361,10 @@ pub trait WalletSource {
357361	/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within 
358362/// the transaction known to the wallet (i.e., any provided via 
359363/// [`WalletSource::list_confirmed_utxos`]). 
360- fn  sign_tx ( & self ,  tx :  Transaction )  -> Result < Transaction ,  ( ) > ; 
364+ /// 
365+ /// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the 
366+ /// unsigned transaction and then sign it with your wallet. 
367+ fn  sign_psbt ( & self ,  psbt :  PartiallySignedTransaction )  -> Result < Transaction ,  ( ) > ; 
361368} 
362369
363370/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would 
@@ -504,8 +511,8 @@ where
504511			. or_else ( |_| do_coin_selection ( true ,  true ) ) 
505512	} 
506513
507- 	fn  sign_tx ( & self ,  tx :   Transaction )  -> Result < Transaction ,  ( ) >  { 
508- 		self . source . sign_tx ( tx ) 
514+ 	fn  sign_psbt ( & self ,  psbt :   PartiallySignedTransaction )  -> Result < Transaction ,  ( ) >  { 
515+ 		self . source . sign_psbt ( psbt ) 
509516	} 
510517} 
511518
@@ -549,16 +556,16 @@ where
549556	} 
550557
551558	/// Updates a transaction with the result of a successful coin selection attempt. 
552- fn  process_coin_selection ( & self ,  tx :  & mut  Transaction ,  mut   coin_selection :  CoinSelection )  { 
553- 		for  utxo in  coin_selection. confirmed_utxos . drain ( .. )  { 
559+ fn  process_coin_selection ( & self ,  tx :  & mut  Transaction ,  coin_selection :  & CoinSelection )  { 
560+ 		for  utxo in  coin_selection. confirmed_utxos . iter ( )  { 
554561			tx. input . push ( TxIn  { 
555562				previous_output :  utxo. outpoint , 
556563				script_sig :  ScriptBuf :: new ( ) , 
557564				sequence :  Sequence :: ZERO , 
558565				witness :  Witness :: new ( ) , 
559566			} ) ; 
560567		} 
561- 		if  let  Some ( change_output)  = coin_selection. change_output . take ( )  { 
568+ 		if  let  Some ( change_output)  = coin_selection. change_output . clone ( )  { 
562569			tx. output . push ( change_output) ; 
563570		}  else  if  tx. output . is_empty ( )  { 
564571			// We weren't provided a change output, likely because the input set was a perfect 
@@ -595,7 +602,7 @@ where
595602
596603		log_debug ! ( self . logger,  "Peforming coin selection for commitment package (commitment and anchor transaction) targeting {} sat/kW" , 
597604			package_target_feerate_sat_per_1000_weight) ; 
598- 		let  coin_selection = self . utxo_source . select_confirmed_utxos ( 
605+ 		let  coin_selection:   CoinSelection  = self . utxo_source . select_confirmed_utxos ( 
599606			claim_id,  must_spend,  & [ ] ,  package_target_feerate_sat_per_1000_weight, 
600607		) ?; 
601608
@@ -613,15 +620,29 @@ where
613620		let  total_input_amount = must_spend_amount +
614621			coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value ) . sum :: < u64 > ( ) ; 
615622
616- 		self . process_coin_selection ( & mut  anchor_tx,  coin_selection) ; 
623+ 		self . process_coin_selection ( & mut  anchor_tx,  & coin_selection) ; 
617624		let  anchor_txid = anchor_tx. txid ( ) ; 
618625
619- 		debug_assert_eq ! ( anchor_tx. output. len( ) ,  1 ) ; 
626+ 		// construct psbt 
627+ 		let  mut  anchor_psbt = PartiallySignedTransaction :: from_unsigned_tx ( anchor_tx) . unwrap ( ) ; 
628+ 		// add witness_utxo to anchor input 
629+ 		anchor_psbt. inputs [ 0 ] . witness_utxo  = Some ( anchor_descriptor. previous_utxo ( ) ) ; 
630+ 		// add witness_utxo to remaining inputs 
631+ 		for  ( idx,  utxo)  in  coin_selection. confirmed_utxos . into_iter ( ) . enumerate ( )  { 
632+ 			// add 1 to skip the anchor input 
633+ 			let  index = idx + 1 ; 
634+ 			debug_assert_eq ! ( anchor_psbt. unsigned_tx. input[ index] . previous_output,  utxo. outpoint) ; 
635+ 			if  utxo. output . script_pubkey . is_witness_program ( )  { 
636+ 				anchor_psbt. inputs [ index] . witness_utxo  = Some ( utxo. output ) ; 
637+ 			} 
638+ 		} 
639+ 
640+ 		debug_assert_eq ! ( anchor_psbt. unsigned_tx. output. len( ) ,  1 ) ; 
620641		#[ cfg( debug_assertions) ]  
621- 		let  unsigned_tx_weight = anchor_tx . weight ( ) . to_wu ( )  - ( anchor_tx . input . len ( )  as  u64  *  EMPTY_SCRIPT_SIG_WEIGHT ) ; 
642+ 		let  unsigned_tx_weight = anchor_psbt . unsigned_tx . weight ( ) . to_wu ( )  - ( anchor_psbt . unsigned_tx . input . len ( )  as  u64  *  EMPTY_SCRIPT_SIG_WEIGHT ) ; 
622643
623644		log_debug ! ( self . logger,  "Signing anchor transaction {}" ,  anchor_txid) ; 
624- 		anchor_tx = self . utxo_source . sign_tx ( anchor_tx ) ?; 
645+ 		anchor_tx = self . utxo_source . sign_psbt ( anchor_psbt ) ?; 
625646
626647		let  signer = anchor_descriptor. derive_channel_signer ( & self . signer_provider ) ; 
627648		let  anchor_sig = signer. sign_holder_anchor_input ( & anchor_tx,  0 ,  & self . secp ) ?; 
@@ -690,7 +711,7 @@ where
690711		#[ cfg( debug_assertions) ]  
691712		let  must_spend_amount =	must_spend. iter ( ) . map ( |input| input. previous_utxo . value ) . sum :: < u64 > ( ) ; 
692713
693- 		let  coin_selection = self . utxo_source . select_confirmed_utxos ( 
714+ 		let  coin_selection:   CoinSelection  = self . utxo_source . select_confirmed_utxos ( 
694715			claim_id,  must_spend,  & htlc_tx. output ,  target_feerate_sat_per_1000_weight, 
695716		) ?; 
696717
@@ -701,13 +722,30 @@ where
701722		let  total_input_amount = must_spend_amount +
702723			coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value ) . sum :: < u64 > ( ) ; 
703724
704- 		self . process_coin_selection ( & mut  htlc_tx,  coin_selection) ; 
725+ 		self . process_coin_selection ( & mut  htlc_tx,  & coin_selection) ; 
726+ 
727+ 		// construct psbt 
728+ 		let  mut  htlc_psbt = PartiallySignedTransaction :: from_unsigned_tx ( htlc_tx) . unwrap ( ) ; 
729+ 		// add witness_utxo to htlc inputs 
730+ 		for  ( i,  htlc_descriptor)  in  htlc_descriptors. iter ( ) . enumerate ( )  { 
731+ 			debug_assert_eq ! ( htlc_psbt. unsigned_tx. input[ i] . previous_output,  htlc_descriptor. outpoint( ) ) ; 
732+ 			htlc_psbt. inputs [ i] . witness_utxo  = Some ( htlc_descriptor. previous_utxo ( & self . secp ) ) ; 
733+ 		} 
734+ 		// add witness_utxo to remaining inputs 
735+ 		for  ( idx,  utxo)  in  coin_selection. confirmed_utxos . into_iter ( ) . enumerate ( )  { 
736+ 			// offset to skip the htlc inputs 
737+ 			let  index = idx + htlc_descriptors. len ( ) ; 
738+ 			debug_assert_eq ! ( htlc_psbt. unsigned_tx. input[ index] . previous_output,  utxo. outpoint) ; 
739+ 			if  utxo. output . script_pubkey . is_witness_program ( )  { 
740+ 				htlc_psbt. inputs [ index] . witness_utxo  = Some ( utxo. output ) ; 
741+ 			} 
742+ 		} 
705743
706744		#[ cfg( debug_assertions) ]  
707- 		let  unsigned_tx_weight = htlc_tx . weight ( ) . to_wu ( )  - ( htlc_tx . input . len ( )  as  u64  *  EMPTY_SCRIPT_SIG_WEIGHT ) ; 
745+ 		let  unsigned_tx_weight = htlc_psbt . unsigned_tx . weight ( ) . to_wu ( )  - ( htlc_psbt . unsigned_tx . input . len ( )  as  u64  *  EMPTY_SCRIPT_SIG_WEIGHT ) ; 
708746
709- 		log_debug ! ( self . logger,  "Signing HTLC transaction {}" ,  htlc_tx . txid( ) ) ; 
710- 		htlc_tx = self . utxo_source . sign_tx ( htlc_tx ) ?; 
747+ 		log_debug ! ( self . logger,  "Signing HTLC transaction {}" ,  htlc_psbt . unsigned_tx . txid( ) ) ; 
748+ 		htlc_tx = self . utxo_source . sign_psbt ( htlc_psbt ) ?; 
711749
712750		let  mut  signers = BTreeMap :: new ( ) ; 
713751		for  ( idx,  htlc_descriptor)  in  htlc_descriptors. iter ( ) . enumerate ( )  { 
0 commit comments