@@ -748,13 +748,31 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
748748
749749 log .Infof ("Loop in quote request received" )
750750
751+ var (
752+ numDeposits = uint32 (len (req .DepositOutpoints ))
753+ err error
754+ )
755+
751756 htlcConfTarget , err := validateLoopInRequest (
752- req .ConfTarget , req .ExternalHtlc ,
757+ req .ConfTarget , req .ExternalHtlc , numDeposits , req . Amt ,
753758 )
754759 if err != nil {
755760 return nil , err
756761 }
757762
763+ // Retrieve deposits to calculate their total value.
764+ var summary * clientrpc.StaticAddressSummaryResponse
765+ if len (req .DepositOutpoints ) > 0 {
766+ summary , err = s .GetStaticAddressSummary (
767+ ctx , & clientrpc.StaticAddressSummaryRequest {
768+ Outpoints : req .DepositOutpoints ,
769+ },
770+ )
771+ if err != nil {
772+ return nil , err
773+ }
774+ }
775+
758776 var (
759777 routeHints [][]zpay32.HopHint
760778 lastHop * route.Vertex
@@ -777,14 +795,32 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
777795 }
778796 }
779797
798+ // The requested amount should be 0 here if the request contained
799+ // deposit outpoints.
800+ amount := btcutil .Amount (req .Amt )
801+ if amount != 0 && len (summary .FilteredDeposits ) > 0 {
802+ return nil , fmt .Errorf ("amount should be 0 for deposit " +
803+ "quotes" )
804+ }
805+
806+ // In case we quote for deposits we send the server both the total value
807+ // and the number of deposits. This is so the server can probe the total
808+ // amount and calculate the per input fee.
809+ if amount == 0 && len (summary .FilteredDeposits ) > 0 {
810+ for _ , deposit := range summary .FilteredDeposits {
811+ amount += btcutil .Amount (deposit .Value )
812+ }
813+ }
814+
780815 quote , err := s .impl .LoopInQuote (ctx , & loop.LoopInQuoteRequest {
781- Amount : btcutil . Amount ( req . Amt ) ,
816+ Amount : amount ,
782817 HtlcConfTarget : htlcConfTarget ,
783818 ExternalHtlc : req .ExternalHtlc ,
784819 LastHop : lastHop ,
785820 RouteHints : routeHints ,
786821 Private : req .Private ,
787822 Initiator : defaultLoopdInitiator ,
823+ NumDeposits : numDeposits ,
788824 })
789825 if err != nil {
790826 return nil , err
@@ -881,7 +917,7 @@ func (s *swapClientServer) LoopIn(ctx context.Context,
881917 log .Infof ("Loop in request received" )
882918
883919 htlcConfTarget , err := validateLoopInRequest (
884- in .HtlcConfTarget , in .ExternalHtlc ,
920+ in .HtlcConfTarget , in .ExternalHtlc , 0 , in . Amt ,
885921 )
886922 if err != nil {
887923 return nil , err
@@ -1710,7 +1746,13 @@ func validateConfTarget(target, defaultTarget int32) (int32, error) {
17101746
17111747// validateLoopInRequest fails if the mutually exclusive conf target and
17121748// external parameters are both set.
1713- func validateLoopInRequest (htlcConfTarget int32 , external bool ) (int32 , error ) {
1749+ func validateLoopInRequest (htlcConfTarget int32 , external bool ,
1750+ numDeposits uint32 , amount int64 ) (int32 , error ) {
1751+
1752+ if amount == 0 && numDeposits == 0 {
1753+ return 0 , errors .New ("either amount or deposits must be set" )
1754+ }
1755+
17141756 // If the htlc is going to be externally set, the htlcConfTarget should
17151757 // not be set, because it has no relevance when the htlc is external.
17161758 if external && htlcConfTarget != 0 {
@@ -1724,6 +1766,12 @@ func validateLoopInRequest(htlcConfTarget int32, external bool) (int32, error) {
17241766 return 0 , nil
17251767 }
17261768
1769+ // If the loop in uses static address deposits, we do not need to set a
1770+ // confirmation target since the HTLC won't be published by the client.
1771+ if numDeposits > 0 {
1772+ return 0 , nil
1773+ }
1774+
17271775 return validateConfTarget (htlcConfTarget , loop .DefaultHtlcConfTarget )
17281776}
17291777
0 commit comments