@@ -4,14 +4,17 @@ import (
44 "context"
55 "errors"
66 "fmt"
7+ "sort"
78 "strings"
89
910 "github.com/lightninglabs/loop/labels"
1011 "github.com/lightninglabs/loop/looprpc"
1112 "github.com/lightninglabs/loop/staticaddr/loopin"
1213 "github.com/lightninglabs/loop/swapserverrpc"
1314 lndcommands "github.com/lightningnetwork/lnd/cmd/commands"
15+ "github.com/lightningnetwork/lnd/input"
1416 "github.com/lightningnetwork/lnd/lnrpc"
17+ "github.com/lightningnetwork/lnd/lnwallet"
1518 "github.com/lightningnetwork/lnd/routing/route"
1619 "github.com/urfave/cli/v3"
1720)
@@ -620,11 +623,10 @@ func staticAddressLoopIn(ctx context.Context, cmd *cli.Command) error {
620623 // Warn the user if any selected deposits have fewer than 6
621624 // confirmations, as the swap payment won't be received immediately
622625 // for those.
623- depositsToCheck := depositOutpoints
624- if autoSelectDepositsForQuote {
625- // When auto-selecting, any deposit could be chosen.
626- depositsToCheck = depositsToOutpoints (allDeposits )
627- }
626+ depositsToCheck := warningDepositOutpoints (
627+ allDeposits , depositOutpoints , autoSelectDepositsForQuote ,
628+ quoteReq .Amt ,
629+ )
628630 warning := lowConfDepositWarning (
629631 allDeposits , depositsToCheck ,
630632 int64 (summary .RelativeExpiryBlocks ),
@@ -688,6 +690,83 @@ func depositsToOutpoints(deposits []*looprpc.Deposit) []string {
688690 return outpoints
689691}
690692
693+ var warningSelectionDustLimit = int64 (lnwallet .DustLimitForSize (input .P2TRSize ))
694+
695+ func warningDepositOutpoints (allDeposits []* looprpc.Deposit ,
696+ selectedOutpoints []string , autoSelect bool , targetAmount int64 ) []string {
697+
698+ if ! autoSelect {
699+ return selectedOutpoints
700+ }
701+
702+ return autoSelectedWarningOutpoints (allDeposits , targetAmount )
703+ }
704+
705+ func autoSelectedWarningOutpoints (allDeposits []* looprpc.Deposit ,
706+ targetAmount int64 ) []string {
707+
708+ if targetAmount <= 0 {
709+ return nil
710+ }
711+
712+ // KEEP IN SYNC with staticaddr/loopin.SelectDeposits.
713+ deposits := filterSwappableWarningDeposits (allDeposits )
714+ sort .Slice (deposits , func (i , j int ) bool {
715+ iConfirmed := deposits [i ].ConfirmationHeight > 0
716+ jConfirmed := deposits [j ].ConfirmationHeight > 0
717+ if iConfirmed != jConfirmed {
718+ return iConfirmed
719+ }
720+
721+ if deposits [i ].Value == deposits [j ].Value {
722+ return deposits [i ].BlocksUntilExpiry <
723+ deposits [j ].BlocksUntilExpiry
724+ }
725+
726+ return deposits [i ].Value > deposits [j ].Value
727+ })
728+
729+ selectedOutpoints := make ([]string , 0 , len (deposits ))
730+ var selectedAmount int64
731+ for _ , deposit := range deposits {
732+ selectedOutpoints = append (selectedOutpoints , deposit .Outpoint )
733+ selectedAmount += deposit .Value
734+ if selectedAmount == targetAmount {
735+ return selectedOutpoints
736+ }
737+
738+ if selectedAmount > targetAmount &&
739+ selectedAmount - targetAmount >= warningSelectionDustLimit {
740+
741+ return selectedOutpoints
742+ }
743+ }
744+
745+ return nil
746+ }
747+
748+ func filterSwappableWarningDeposits (
749+ allDeposits []* looprpc.Deposit ) []* looprpc.Deposit {
750+
751+ swappable := make ([]* looprpc.Deposit , 0 , len (allDeposits ))
752+ minBlocksUntilExpiry := int64 (
753+ loopin .DefaultLoopInOnChainCltvDelta + loopin .DepositHtlcDelta ,
754+ )
755+ for _ , deposit := range allDeposits {
756+ // Unconfirmed deposits remain swappable because their CSV timeout has
757+ // not started yet. This mirrors loopin.IsSwappable.
758+ if deposit .ConfirmationHeight > 0 &&
759+ deposit .BlocksUntilExpiry < minBlocksUntilExpiry {
760+
761+ continue
762+ }
763+
764+ swappable = append (swappable , deposit )
765+ }
766+
767+ return swappable
768+ }
769+
691770// conservativeWarningConfs is the highest default confirmation tier used by
692771// the server's dynamic confirmation-risk policy.
693772//
0 commit comments