@@ -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 
@@ -613,15 +620,28 @@ 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+ 			anchor_psbt. inputs [ index] . witness_utxo  = Some ( utxo. output ) ; 
636+ 		} 
637+ 
638+ 		debug_assert_eq ! ( anchor_psbt. unsigned_tx. output. len( ) ,  1 ) ; 
620639		#[ cfg( debug_assertions) ]  
621- 		let  unsigned_tx_weight = anchor_tx . weight ( ) . to_wu ( )  - ( anchor_tx . input . len ( )  as  u64  *  EMPTY_SCRIPT_SIG_WEIGHT ) ; 
640+ 		let  unsigned_tx_weight = anchor_psbt . unsigned_tx . weight ( ) . to_wu ( )  - ( anchor_psbt . unsigned_tx . input . len ( )  as  u64  *  EMPTY_SCRIPT_SIG_WEIGHT ) ; 
622641
623642		log_debug ! ( self . logger,  "Signing anchor transaction {}" ,  anchor_txid) ; 
624- 		anchor_tx = self . utxo_source . sign_tx ( anchor_tx) ?; 
643+ 		debug_assert ! ( anchor_psbt. inputs. iter( ) . all( |i| i. witness_utxo. is_some( ) ) ) ; 
644+ 		anchor_tx = self . utxo_source . sign_psbt ( anchor_psbt) ?; 
625645
626646		let  signer = anchor_descriptor. derive_channel_signer ( & self . signer_provider ) ; 
627647		let  anchor_sig = signer. sign_holder_anchor_input ( & anchor_tx,  0 ,  & self . secp ) ?; 
@@ -701,13 +721,29 @@ where
701721		let  total_input_amount = must_spend_amount +
702722			coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value ) . sum :: < u64 > ( ) ; 
703723
704- 		self . process_coin_selection ( & mut  htlc_tx,  coin_selection) ; 
724+ 		self . process_coin_selection ( & mut  htlc_tx,  & coin_selection) ; 
725+ 
726+ 		// construct psbt 
727+ 		let  mut  htlc_psbt = PartiallySignedTransaction :: from_unsigned_tx ( htlc_tx) . unwrap ( ) ; 
728+ 		// add witness_utxo to htlc inputs 
729+ 		for  ( i,  htlc_descriptor)  in  htlc_descriptors. iter ( ) . enumerate ( )  { 
730+ 			debug_assert_eq ! ( htlc_psbt. unsigned_tx. input[ i] . previous_output,  htlc_descriptor. outpoint( ) ) ; 
731+ 			htlc_psbt. inputs [ i] . witness_utxo  = Some ( htlc_descriptor. previous_utxo ( & self . secp ) ) ; 
732+ 		} 
733+ 		// add witness_utxo to remaining inputs 
734+ 		for  ( idx,  utxo)  in  coin_selection. confirmed_utxos . into_iter ( ) . enumerate ( )  { 
735+ 			// offset to skip the htlc inputs 
736+ 			let  index = idx + htlc_descriptors. len ( ) ; 
737+ 			debug_assert_eq ! ( htlc_psbt. unsigned_tx. input[ index] . previous_output,  utxo. outpoint) ; 
738+ 			htlc_psbt. inputs [ index] . witness_utxo  = Some ( utxo. output ) ; 
739+ 		} 
705740
706741		#[ cfg( debug_assertions) ]  
707- 		let  unsigned_tx_weight = htlc_tx . weight ( ) . to_wu ( )  - ( htlc_tx . input . len ( )  as  u64  *  EMPTY_SCRIPT_SIG_WEIGHT ) ; 
742+ 		let  unsigned_tx_weight = htlc_psbt . unsigned_tx . weight ( ) . to_wu ( )  - ( htlc_psbt . unsigned_tx . input . len ( )  as  u64  *  EMPTY_SCRIPT_SIG_WEIGHT ) ; 
708743
709- 		log_debug ! ( self . logger,  "Signing HTLC transaction {}" ,  htlc_tx. txid( ) ) ; 
710- 		htlc_tx = self . utxo_source . sign_tx ( htlc_tx) ?; 
744+ 		log_debug ! ( self . logger,  "Signing HTLC transaction {}" ,  htlc_psbt. unsigned_tx. txid( ) ) ; 
745+ 		debug_assert ! ( htlc_psbt. inputs. iter( ) . all( |i| i. witness_utxo. is_some( ) ) ) ; 
746+ 		htlc_tx = self . utxo_source . sign_psbt ( htlc_psbt) ?; 
711747
712748		let  mut  signers = BTreeMap :: new ( ) ; 
713749		for  ( idx,  htlc_descriptor)  in  htlc_descriptors. iter ( ) . enumerate ( )  { 
0 commit comments