@@ -895,27 +895,57 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
895895 var (
896896 selectedAmount = btcutil .Amount (req .Amt )
897897 totalDepositAmount btcutil.Amount
898- numDeposits = len ( req .DepositOutpoints )
898+ autoSelectDeposits = req .SelectDeposits
899899 err error
900900 )
901901
902902 htlcConfTarget , err := validateLoopInRequest (
903- req .ConfTarget , req .ExternalHtlc , uint32 (numDeposits ),
904- int64 (selectedAmount ),
903+ req .ConfTarget , req .ExternalHtlc ,
904+ uint32 (len (req .DepositOutpoints )), int64 (selectedAmount ),
905+ autoSelectDeposits ,
905906 )
906907 if err != nil {
907908 return nil , err
908909 }
909910
910- // Retrieve deposits to calculate their total value.
911- var depositList * looprpc.ListStaticAddressDepositsResponse
911+ // If deposits should be automatically selected we do so and count the
912+ // number of deposits to quote for.
913+ numDeposits := 0
914+ if autoSelectDeposits {
915+ deposits , err := s .depositManager .GetActiveDepositsInState (
916+ deposit .Deposited ,
917+ )
918+ if err != nil {
919+ return nil , fmt .Errorf ("unable to retrieve all " +
920+ "deposits: %w" , err )
921+ }
922+
923+ // TODO(hieblmi): add params to deposit for multi-address
924+ // support.
925+ params , err := s .staticAddressManager .GetStaticAddressParameters (
926+ ctx ,
927+ )
928+ if err != nil {
929+ return nil , fmt .Errorf ("unable to retrieve static " +
930+ "address parameters: %w" , err )
931+ }
912932
913- // If deposits are selected, we need to retrieve them to calculate the
914- // total value which we request a quote for.
915- if numDeposits > 0 {
916- depositList , err = s .ListStaticAddressDeposits (
933+ selectedDeposits , err := s .staticLoopInManager .SelectDeposits (
934+ selectedAmount , deposits , params .Expiry ,
935+ )
936+ if err != nil {
937+ return nil , fmt .Errorf ("unable to select deposits: %w" ,
938+ err )
939+ }
940+
941+ numDeposits = len (selectedDeposits )
942+ } else if len (req .DepositOutpoints ) > 0 {
943+ // If deposits are selected, we need to retrieve them to
944+ // calculate the total value which we request a quote for.
945+ depositList , err := s .ListStaticAddressDeposits (
917946 ctx , & looprpc.ListStaticAddressDepositsRequest {
918- Outpoints : req .DepositOutpoints ,
947+ StateFilter : looprpc .DepositState_DEPOSITED ,
948+ Outpoints : req .DepositOutpoints ,
919949 },
920950 )
921951 if err != nil {
@@ -927,9 +957,13 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
927957 "deposit outpoints" )
928958 }
929959
930- if numDeposits != len (depositList .FilteredDeposits ) {
960+ if len (req .DepositOutpoints ) !=
961+ len (depositList .FilteredDeposits ) {
962+
931963 return nil , fmt .Errorf ("expected %d deposits, got %d" ,
932964 numDeposits , len (depositList .FilteredDeposits ))
965+ } else {
966+ numDeposits = len (depositList .FilteredDeposits )
933967 }
934968
935969 // In case we quote for deposits we send the server both the
@@ -942,12 +976,15 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
942976 )
943977 }
944978
945- selectedAmount , err = s .staticLoopInManager .SwapAmountFromSelectedAmount (
946- selectedAmount , totalDepositAmount ,
979+ // If a fractional amount is also selected, we check if it would
980+ // lead to a dust change output.
981+ selectedAmount , err = loopin .SwapAmountFromSelectedAmount (
982+ totalDepositAmount , selectedAmount ,
947983 )
948984 if err != nil {
949- return nil , fmt .Errorf ("error calculating swap " +
950- "amount from selected amount: %v" , err )
985+ return nil , fmt .Errorf ("error calculating " +
986+ "swap amount from selected amount: %v" ,
987+ err )
951988 }
952989 }
953990
@@ -1077,8 +1114,11 @@ func (s *swapClientServer) LoopIn(ctx context.Context,
10771114
10781115 infof ("Loop in request received" )
10791116
1117+ selectDeposits := false
1118+ numDeposits := uint32 (0 )
10801119 htlcConfTarget , err := validateLoopInRequest (
1081- in .HtlcConfTarget , in .ExternalHtlc , 0 , in .Amt ,
1120+ in .HtlcConfTarget , in .ExternalHtlc , numDeposits , in .Amt ,
1121+ selectDeposits ,
10821122 )
10831123 if err != nil {
10841124 return nil , err
@@ -2184,10 +2224,17 @@ func validateConfTarget(target, defaultTarget int32) (int32, error) {
21842224// validateLoopInRequest fails if the mutually exclusive conf target and
21852225// external parameters are both set.
21862226func validateLoopInRequest (htlcConfTarget int32 , external bool ,
2187- numDeposits uint32 , amount int64 ) (int32 , error ) {
2227+ numDeposits uint32 , amount int64 , autoSelectDeposits bool ) (int32 ,
2228+ error ) {
21882229
21892230 if amount == 0 && numDeposits == 0 {
2190- return 0 , errors .New ("either amount or deposits must be set" )
2231+ return 0 , errors .New ("either amount, or deposits or both " +
2232+ "must be set" )
2233+ }
2234+
2235+ if autoSelectDeposits && numDeposits > 0 {
2236+ return 0 , errors .New ("cannot auto-select deposits while " +
2237+ "providing deposits at the same time" )
21912238 }
21922239
21932240 // If the htlc is going to be externally set, the htlcConfTarget should
@@ -2205,7 +2252,7 @@ func validateLoopInRequest(htlcConfTarget int32, external bool,
22052252
22062253 // If the loop in uses static address deposits, we do not need to set a
22072254 // confirmation target since the HTLC won't be published by the client.
2208- if numDeposits > 0 {
2255+ if numDeposits > 0 || autoSelectDeposits {
22092256 return 0 , nil
22102257 }
22112258
0 commit comments