@@ -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,26 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
777795 }
778796 }
779797
798+ // The requested amount is 0 here if the request contained deposit
799+ // outpoints. In case we quote for deposits we send the server both the
800+ // total value and the number of deposits. This is so the server can
801+ // probe the total amount and calculate the per input fee.
802+ amount := btcutil .Amount (req .Amt )
803+ if amount == 0 && len (summary .FilteredDeposits ) > 0 {
804+ for _ , deposit := range summary .FilteredDeposits {
805+ amount += btcutil .Amount (deposit .Value )
806+ }
807+ }
808+
780809 quote , err := s .impl .LoopInQuote (ctx , & loop.LoopInQuoteRequest {
781- Amount : btcutil . Amount ( req . Amt ) ,
810+ Amount : amount ,
782811 HtlcConfTarget : htlcConfTarget ,
783812 ExternalHtlc : req .ExternalHtlc ,
784813 LastHop : lastHop ,
785814 RouteHints : routeHints ,
786815 Private : req .Private ,
787816 Initiator : defaultLoopdInitiator ,
817+ NumDeposits : numDeposits ,
788818 })
789819 if err != nil {
790820 return nil , err
@@ -881,7 +911,7 @@ func (s *swapClientServer) LoopIn(ctx context.Context,
881911 log .Infof ("Loop in request received" )
882912
883913 htlcConfTarget , err := validateLoopInRequest (
884- in .HtlcConfTarget , in .ExternalHtlc ,
914+ in .HtlcConfTarget , in .ExternalHtlc , 0 , in . Amt ,
885915 )
886916 if err != nil {
887917 return nil , err
@@ -1708,7 +1738,17 @@ func validateConfTarget(target, defaultTarget int32) (int32, error) {
17081738
17091739// validateLoopInRequest fails if the mutually exclusive conf target and
17101740// external parameters are both set.
1711- func validateLoopInRequest (htlcConfTarget int32 , external bool ) (int32 , error ) {
1741+ func validateLoopInRequest (htlcConfTarget int32 , external bool ,
1742+ numDeposits uint32 , amount int64 ) (int32 , error ) {
1743+
1744+ if numDeposits > 0 && amount == 0 {
1745+ return 0 , errors .New ("need to provide amount if deposits are " +
1746+ "set" )
1747+
1748+ } else if amount == 0 && numDeposits == 0 {
1749+ return 0 , errors .New ("either amount or deposits must be set" )
1750+ }
1751+
17121752 // If the htlc is going to be externally set, the htlcConfTarget should
17131753 // not be set, because it has no relevance when the htlc is external.
17141754 if external && htlcConfTarget != 0 {
@@ -1722,6 +1762,12 @@ func validateLoopInRequest(htlcConfTarget int32, external bool) (int32, error) {
17221762 return 0 , nil
17231763 }
17241764
1765+ // If the loop in uses static address deposits, we do not need to set a
1766+ // confirmation target since the HTLC won't be published by the client.
1767+ if numDeposits > 0 {
1768+ return 0 , nil
1769+ }
1770+
17251771 return validateConfTarget (htlcConfTarget , loop .DefaultHtlcConfTarget )
17261772}
17271773
0 commit comments