@@ -895,25 +895,60 @@ 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+ }
932+
933+ info , err := s .lnd .Client .GetInfo (ctx )
934+ if err != nil {
935+ return nil , fmt .Errorf ("unable to get lnd info: %w" ,
936+ err )
937+ }
938+ selectedDeposits , err := loopin .SelectDeposits (
939+ selectedAmount , deposits , params .Expiry ,
940+ info .BlockHeight ,
941+ )
942+ if err != nil {
943+ return nil , fmt .Errorf ("unable to select deposits: %w" ,
944+ err )
945+ }
912946
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 (
947+ numDeposits = len (selectedDeposits )
948+ } else if len (req .DepositOutpoints ) > 0 {
949+ // If deposits are selected, we need to retrieve them to
950+ // calculate the total value which we request a quote for.
951+ depositList , err := s .ListStaticAddressDeposits (
917952 ctx , & looprpc.ListStaticAddressDepositsRequest {
918953 Outpoints : req .DepositOutpoints ,
919954 },
@@ -927,9 +962,13 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
927962 "deposit outpoints" )
928963 }
929964
930- if numDeposits != len (depositList .FilteredDeposits ) {
965+ if len (req .DepositOutpoints ) !=
966+ len (depositList .FilteredDeposits ) {
967+
931968 return nil , fmt .Errorf ("expected %d deposits, got %d" ,
932969 numDeposits , len (depositList .FilteredDeposits ))
970+ } else {
971+ numDeposits = len (depositList .FilteredDeposits )
933972 }
934973
935974 // In case we quote for deposits we send the server both the
@@ -942,12 +981,15 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
942981 )
943982 }
944983
945- selectedAmount , err = s .staticLoopInManager .SwapAmountFromSelectedAmount (
946- selectedAmount , totalDepositAmount ,
984+ // If a fractional amount is also selected, we check if it would
985+ // lead to a dust change output.
986+ selectedAmount , err = loopin .SwapAmountFromSelectedAmount (
987+ totalDepositAmount , selectedAmount ,
947988 )
948989 if err != nil {
949- return nil , fmt .Errorf ("error calculating swap " +
950- "amount from selected amount: %v" , err )
990+ return nil , fmt .Errorf ("error calculating " +
991+ "swap amount from selected amount: %v" ,
992+ err )
951993 }
952994 }
953995
@@ -1077,8 +1119,11 @@ func (s *swapClientServer) LoopIn(ctx context.Context,
10771119
10781120 infof ("Loop in request received" )
10791121
1122+ selectDeposits := false
1123+ numDeposits := uint32 (0 )
10801124 htlcConfTarget , err := validateLoopInRequest (
1081- in .HtlcConfTarget , in .ExternalHtlc , 0 , in .Amt ,
1125+ in .HtlcConfTarget , in .ExternalHtlc , numDeposits , in .Amt ,
1126+ selectDeposits ,
10821127 )
10831128 if err != nil {
10841129 return nil , err
@@ -2184,10 +2229,17 @@ func validateConfTarget(target, defaultTarget int32) (int32, error) {
21842229// validateLoopInRequest fails if the mutually exclusive conf target and
21852230// external parameters are both set.
21862231func validateLoopInRequest (htlcConfTarget int32 , external bool ,
2187- numDeposits uint32 , amount int64 ) (int32 , error ) {
2232+ numDeposits uint32 , amount int64 , autoSelectDeposits bool ) (int32 ,
2233+ error ) {
21882234
21892235 if amount == 0 && numDeposits == 0 {
2190- return 0 , errors .New ("either amount or deposits must be set" )
2236+ return 0 , errors .New ("either amount, or deposits or both " +
2237+ "must be set" )
2238+ }
2239+
2240+ if autoSelectDeposits && numDeposits > 0 {
2241+ return 0 , errors .New ("cannot auto-select deposits while " +
2242+ "providing deposits at the same time" )
21912243 }
21922244
21932245 // If the htlc is going to be externally set, the htlcConfTarget should
@@ -2205,7 +2257,7 @@ func validateLoopInRequest(htlcConfTarget int32, external bool,
22052257
22062258 // If the loop in uses static address deposits, we do not need to set a
22072259 // confirmation target since the HTLC won't be published by the client.
2208- if numDeposits > 0 {
2260+ if numDeposits > 0 || autoSelectDeposits {
22092261 return 0 , nil
22102262 }
22112263
0 commit comments