@@ -34,8 +34,10 @@ import (
34
34
"github.com/lightninglabs/loop/swap"
35
35
"github.com/lightninglabs/loop/swapserverrpc"
36
36
"github.com/lightninglabs/taproot-assets/rfqmath"
37
+ "github.com/lightningnetwork/lnd/input"
37
38
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
38
39
"github.com/lightningnetwork/lnd/lntypes"
40
+ "github.com/lightningnetwork/lnd/lnwallet"
39
41
"github.com/lightningnetwork/lnd/queue"
40
42
"github.com/lightningnetwork/lnd/routing/route"
41
43
"github.com/lightningnetwork/lnd/zpay32"
@@ -843,21 +845,26 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
843
845
infof ("Loop in quote request received" )
844
846
845
847
var (
846
- numDeposits = uint32 (len (req .DepositOutpoints ))
847
- err error
848
+ selectedAmount = btcutil .Amount (req .Amt )
849
+ totalDepositAmount btcutil.Amount
850
+ numDeposits = len (req .DepositOutpoints )
851
+ err error
848
852
)
849
853
850
854
htlcConfTarget , err := validateLoopInRequest (
851
- req .ConfTarget , req .ExternalHtlc , numDeposits , req .Amt ,
855
+ req .ConfTarget , req .ExternalHtlc , uint32 (numDeposits ),
856
+ int64 (selectedAmount ),
852
857
)
853
858
if err != nil {
854
859
return nil , err
855
860
}
856
861
857
862
// Retrieve deposits to calculate their total value.
858
863
var depositList * looprpc.ListStaticAddressDepositsResponse
859
- amount := btcutil .Amount (req .Amt )
860
- if len (req .DepositOutpoints ) > 0 {
864
+
865
+ // If deposits are selected, we need to retrieve them to calculate the
866
+ // total value which we request a quote for.
867
+ if numDeposits > 0 {
861
868
depositList , err = s .ListStaticAddressDeposits (
862
869
ctx , & looprpc.ListStaticAddressDepositsRequest {
863
870
Outpoints : req .DepositOutpoints ,
@@ -872,20 +879,45 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
872
879
"deposit outpoints" )
873
880
}
874
881
875
- // The requested amount should be 0 here if the request
876
- // contained deposit outpoints.
877
- if amount != 0 && len (depositList .FilteredDeposits ) > 0 {
878
- return nil , fmt .Errorf ("amount should be 0 for " +
879
- "deposit quotes" )
882
+ if numDeposits != len (depositList .FilteredDeposits ) {
883
+ return nil , fmt .Errorf ("expected %d deposits, got %d" ,
884
+ numDeposits , len (depositList .FilteredDeposits ))
880
885
}
881
886
882
887
// In case we quote for deposits we send the server both the
883
- // total value and the number of deposits. This is so the server
884
- // can probe the total amount and calculate the per input fee.
885
- if amount == 0 && len (depositList .FilteredDeposits ) > 0 {
886
- for _ , deposit := range depositList .FilteredDeposits {
887
- amount += btcutil .Amount (deposit .Value )
888
- }
888
+ // selected value and the number of deposits. This is so the
889
+ // server can probe the selected value and calculate the per
890
+ // input fee.
891
+ for _ , deposit := range depositList .FilteredDeposits {
892
+ totalDepositAmount += btcutil .Amount (
893
+ deposit .Value ,
894
+ )
895
+ }
896
+
897
+ // If the selected amount would leave a dust change output or
898
+ // exceeds the total deposits value, we return an error.
899
+ dustLimit := lnwallet .DustLimitForSize (input .P2TRSize )
900
+ remainingAmount := totalDepositAmount - selectedAmount
901
+ switch {
902
+ case remainingAmount < 0 :
903
+ return nil , fmt .Errorf ("selected amount %v exceeds " +
904
+ "total deposit value %v" , selectedAmount ,
905
+ totalDepositAmount )
906
+
907
+ case remainingAmount > 0 && remainingAmount < dustLimit :
908
+ return nil , fmt .Errorf ("selected amount %v leaves " +
909
+ "dust change %v" , selectedAmount ,
910
+ totalDepositAmount )
911
+
912
+ default :
913
+ // If the remaining amount is 0 or equal or greater than
914
+ // the dust limit, we can proceed with the swap.
915
+ }
916
+
917
+ // If the client didn't select an amount we quote for the total
918
+ // deposits value.
919
+ if selectedAmount == 0 {
920
+ selectedAmount = totalDepositAmount
889
921
}
890
922
}
891
923
@@ -912,14 +944,14 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
912
944
}
913
945
914
946
quote , err := s .impl .LoopInQuote (ctx , & loop.LoopInQuoteRequest {
915
- Amount : amount ,
947
+ Amount : selectedAmount ,
916
948
HtlcConfTarget : htlcConfTarget ,
917
949
ExternalHtlc : req .ExternalHtlc ,
918
950
LastHop : lastHop ,
919
951
RouteHints : routeHints ,
920
952
Private : req .Private ,
921
953
Initiator : defaultLoopdInitiator ,
922
- NumDeposits : numDeposits ,
954
+ NumDeposits : uint32 ( numDeposits ) ,
923
955
})
924
956
if err != nil {
925
957
return nil , err
@@ -1763,6 +1795,7 @@ func (s *swapClientServer) StaticAddressLoopIn(ctx context.Context,
1763
1795
}
1764
1796
1765
1797
req := & loop.StaticAddressLoopInRequest {
1798
+ SelectedAmount : btcutil .Amount (in .Amount ),
1766
1799
DepositOutpoints : in .Outpoints ,
1767
1800
MaxSwapFee : btcutil .Amount (in .MaxSwapFeeSatoshis ),
1768
1801
Label : in .Label ,
0 commit comments