@@ -479,7 +479,7 @@ impl Maker {
479479 connection_state. outgoing_contract . other_pubkey = Some ( message. next_party_tweakable_point ) ;
480480
481481 // Verify we have sufficient funds and get necessary data
482- let ( outgoing_privkey, funding_utxo ) = {
482+ let ( outgoing_privkey, selected_utxos ) = {
483483 let mut wallet = self . wallet . write ( ) ?;
484484
485485 // Sync wallet to get latest UTXO state
@@ -499,29 +499,29 @@ impl Maker {
499499 wallet. rpc . unlock_unspent_all ( ) . map_err ( WalletError :: Rpc ) ?;
500500 wallet. lock_unspendable_utxos ( ) ?;
501501
502- // Get funding UTXO from our wallet (excludes locked UTXOs)
503- let spendable_utxos = wallet. list_descriptor_utxo_spend_info ( ) ;
504- let funding_utxo = spendable_utxos
505- . into_iter ( )
506- . find ( |( utxo, _) | utxo. amount >= connection_state. swap_amount )
507- . map ( |( utxo, _) | utxo)
508- . ok_or_else ( || {
509- MakerError :: General ( "No single UTXO found with sufficient amount" )
502+ // Use coin_select to get UTXOs that sum to the required amount
503+ let selected_utxos = wallet
504+ . coin_select ( connection_state. swap_amount , MIN_FEE_RATE , None )
505+ . map_err ( |e| {
506+ MakerError :: General ( format ! ( "Coin selection failed: {:?}" , e) . leak ( ) )
510507 } ) ?;
511508
512- // Lock the selected UTXO to prevent double-spending in concurrent swaps
513- let funding_outpoint = OutPoint :: new ( funding_utxo. txid , funding_utxo. vout ) ;
509+ // Lock the selected UTXOs to prevent double-spending in concurrent swaps
510+ let funding_outpoints: Vec < OutPoint > = selected_utxos
511+ . iter ( )
512+ . map ( |( utxo, _) | OutPoint :: new ( utxo. txid , utxo. vout ) )
513+ . collect ( ) ;
514514 wallet
515515 . rpc
516- . lock_unspent ( & [ funding_outpoint ] )
516+ . lock_unspent ( & funding_outpoints )
517517 . map_err ( WalletError :: Rpc ) ?;
518518 log:: info!(
519- "[{}] Locked funding UTXO {} for swap" ,
519+ "[{}] Locked {} funding UTXOs for swap" ,
520520 self . config. network_port,
521- funding_outpoint
521+ funding_outpoints . len ( )
522522 ) ;
523523
524- ( outgoing_privkey, funding_utxo )
524+ ( outgoing_privkey, selected_utxos )
525525 } ;
526526
527527 // We expect only one contract for now
@@ -611,11 +611,6 @@ impl Maker {
611611 let outgoing_contract_txid = {
612612 let mut wallet = self . wallet . write ( ) ?;
613613
614- // Get the funding UTXO spend info
615- let funding_utxo_info = wallet
616- . get_utxo ( ( funding_utxo. txid , funding_utxo. vout ) ) ?
617- . ok_or_else ( || MakerError :: General ( "Funding UTXO not found" ) ) ?;
618-
619614 // Use Destination::Multi to send exact amount to contract and keep the fee as change
620615 let contract_address =
621616 bitcoin:: Address :: from_script ( & taproot_script, wallet. store . network )
@@ -629,7 +624,7 @@ impl Maker {
629624 outputs : vec ! [ ( contract_address, outgoing_contract_amount) ] ,
630625 op_return_data : None ,
631626 } ,
632- & [ ( funding_utxo . clone ( ) , funding_utxo_info ) ] ,
627+ & selected_utxos ,
633628 ) ?;
634629
635630 // Broadcast the signed transaction
@@ -913,19 +908,31 @@ impl Maker {
913908 ) ) ;
914909 }
915910
916- // Mark the incoming swapcoin as finished by storing the received private key
917- connection_state. incoming_contract . other_privkey =
918- Some ( privkey_handover_message. secret_key ) ;
919-
920- // Update the wallet with the completed incoming swapcoin
911+ // Record and remove the incoming swapcoin since we've successfully swept it
912+ // NOTE: We do NOT remove the outgoing swapcoin here - that happens after
913+ // the PrivateKeyHandover message is successfully sent (in server2.rs)
921914 {
922915 let mut wallet = self . wallet . write ( ) ?;
923- wallet. add_incoming_swapcoin_v2 ( & connection_state. incoming_contract ) ;
924- wallet. save_to_disk ( ) ?;
916+ let incoming_txid = connection_state
917+ . incoming_contract
918+ . contract_tx
919+ . compute_txid ( ) ;
920+
921+ // Record the swept coin to track swap balance
922+ let output_scriptpubkey = spending_tx. output [ 0 ] . script_pubkey . clone ( ) ;
923+ // [TODO] Look into the key value pair later, it shouldn't be both sriptpubkey
924+ wallet
925+ . store
926+ . swept_incoming_swapcoins
927+ . insert ( output_scriptpubkey. clone ( ) , output_scriptpubkey) ;
928+
929+ wallet. remove_incoming_swapcoin_v2 ( & incoming_txid) ;
925930 log:: info!(
926- "[{}] Marked incoming swapcoin as finished (other_privkey stored)" ,
927- self . config. network_port
931+ "[{}] Removed incoming swapcoin {} after successful sweep" ,
932+ self . config. network_port,
933+ incoming_txid
928934 ) ;
935+ wallet. save_to_disk ( ) ?;
929936 }
930937
931938 let privkey_handover_message = PrivateKeyHandover {
0 commit comments