@@ -36,8 +36,10 @@ import (
36
36
"github.com/lightninglabs/loop/swap"
37
37
"github.com/lightninglabs/loop/swapserverrpc"
38
38
"github.com/lightninglabs/taproot-assets/rfqmath"
39
+ "github.com/lightningnetwork/lnd/input"
39
40
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
40
41
"github.com/lightningnetwork/lnd/lntypes"
42
+ "github.com/lightningnetwork/lnd/lnwallet"
41
43
"github.com/lightningnetwork/lnd/queue"
42
44
"github.com/lightningnetwork/lnd/routing/route"
43
45
"github.com/lightningnetwork/lnd/zpay32"
@@ -884,21 +886,26 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
884
886
infof ("Loop in quote request received" )
885
887
886
888
var (
887
- numDeposits = uint32 (len (req .DepositOutpoints ))
888
- err error
889
+ selectedAmount = btcutil .Amount (req .Amt )
890
+ totalDepositAmount btcutil.Amount
891
+ numDeposits = len (req .DepositOutpoints )
892
+ err error
889
893
)
890
894
891
895
htlcConfTarget , err := validateLoopInRequest (
892
- req .ConfTarget , req .ExternalHtlc , numDeposits , req .Amt ,
896
+ req .ConfTarget , req .ExternalHtlc , uint32 (numDeposits ),
897
+ int64 (selectedAmount ),
893
898
)
894
899
if err != nil {
895
900
return nil , err
896
901
}
897
902
898
903
// Retrieve deposits to calculate their total value.
899
904
var depositList * looprpc.ListStaticAddressDepositsResponse
900
- amount := btcutil .Amount (req .Amt )
901
- if len (req .DepositOutpoints ) > 0 {
905
+
906
+ // If deposits are selected, we need to retrieve them to calculate the
907
+ // total value which we request a quote for.
908
+ if numDeposits > 0 {
902
909
depositList , err = s .ListStaticAddressDeposits (
903
910
ctx , & looprpc.ListStaticAddressDepositsRequest {
904
911
Outpoints : req .DepositOutpoints ,
@@ -913,20 +920,45 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
913
920
"deposit outpoints" )
914
921
}
915
922
916
- // The requested amount should be 0 here if the request
917
- // contained deposit outpoints.
918
- if amount != 0 && len (depositList .FilteredDeposits ) > 0 {
919
- return nil , fmt .Errorf ("amount should be 0 for " +
920
- "deposit quotes" )
923
+ if numDeposits != len (depositList .FilteredDeposits ) {
924
+ return nil , fmt .Errorf ("expected %d deposits, got %d" ,
925
+ numDeposits , len (depositList .FilteredDeposits ))
921
926
}
922
927
923
928
// In case we quote for deposits we send the server both the
924
- // total value and the number of deposits. This is so the server
925
- // can probe the total amount and calculate the per input fee.
926
- if amount == 0 && len (depositList .FilteredDeposits ) > 0 {
927
- for _ , deposit := range depositList .FilteredDeposits {
928
- amount += btcutil .Amount (deposit .Value )
929
- }
929
+ // selected value and the number of deposits. This is so the
930
+ // server can probe the selected value and calculate the per
931
+ // input fee.
932
+ for _ , deposit := range depositList .FilteredDeposits {
933
+ totalDepositAmount += btcutil .Amount (
934
+ deposit .Value ,
935
+ )
936
+ }
937
+
938
+ // If the selected amount would leave a dust change output or
939
+ // exceeds the total deposits value, we return an error.
940
+ dustLimit := lnwallet .DustLimitForSize (input .P2TRSize )
941
+ remainingAmount := totalDepositAmount - selectedAmount
942
+ switch {
943
+ case remainingAmount < 0 :
944
+ return nil , fmt .Errorf ("selected amount %v exceeds " +
945
+ "total deposit value %v" , selectedAmount ,
946
+ totalDepositAmount )
947
+
948
+ case remainingAmount > 0 && remainingAmount < dustLimit :
949
+ return nil , fmt .Errorf ("selected amount %v leaves " +
950
+ "dust change %v" , selectedAmount ,
951
+ totalDepositAmount )
952
+
953
+ default :
954
+ // If the remaining amount is 0 or equal or greater than
955
+ // the dust limit, we can proceed with the swap.
956
+ }
957
+
958
+ // If the client didn't select an amount we quote for the total
959
+ // deposits value.
960
+ if selectedAmount == 0 {
961
+ selectedAmount = totalDepositAmount
930
962
}
931
963
}
932
964
@@ -953,14 +985,14 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
953
985
}
954
986
955
987
quote , err := s .impl .LoopInQuote (ctx , & loop.LoopInQuoteRequest {
956
- Amount : amount ,
988
+ Amount : selectedAmount ,
957
989
HtlcConfTarget : htlcConfTarget ,
958
990
ExternalHtlc : req .ExternalHtlc ,
959
991
LastHop : lastHop ,
960
992
RouteHints : routeHints ,
961
993
Private : req .Private ,
962
994
Initiator : defaultLoopdInitiator ,
963
- NumDeposits : numDeposits ,
995
+ NumDeposits : uint32 ( numDeposits ) ,
964
996
})
965
997
if err != nil {
966
998
return nil , err
@@ -1804,6 +1836,7 @@ func (s *swapClientServer) StaticAddressLoopIn(ctx context.Context,
1804
1836
}
1805
1837
1806
1838
req := & loop.StaticAddressLoopInRequest {
1839
+ SelectedAmount : btcutil .Amount (in .Amount ),
1807
1840
DepositOutpoints : in .Outpoints ,
1808
1841
MaxSwapFee : btcutil .Amount (in .MaxSwapFeeSatoshis ),
1809
1842
Label : in .Label ,
0 commit comments