|
4 | 4 | "context" |
5 | 5 | "errors" |
6 | 6 | "fmt" |
| 7 | + "strings" |
7 | 8 |
|
8 | 9 | "github.com/lightninglabs/loop/labels" |
9 | 10 | "github.com/lightninglabs/loop/looprpc" |
@@ -555,6 +556,13 @@ func staticAddressLoopIn(ctx context.Context, cmd *cli.Command) error { |
555 | 556 | return errors.New("no deposited outputs available") |
556 | 557 | } |
557 | 558 |
|
| 559 | + summary, err := client.GetStaticAddressSummary( |
| 560 | + ctx, &looprpc.StaticAddressSummaryRequest{}, |
| 561 | + ) |
| 562 | + if err != nil { |
| 563 | + return err |
| 564 | + } |
| 565 | + |
558 | 566 | var depositOutpoints []string |
559 | 567 | switch { |
560 | 568 | case isAllSelected && isUtxoSelected: |
@@ -609,6 +617,22 @@ func staticAddressLoopIn(ctx context.Context, cmd *cli.Command) error { |
609 | 617 | return err |
610 | 618 | } |
611 | 619 |
|
| 620 | + // Warn the user if any selected deposits have fewer than 6 |
| 621 | + // confirmations, as the swap payment won't be received immediately |
| 622 | + // for those. |
| 623 | + depositsToCheck := depositOutpoints |
| 624 | + if autoSelectDepositsForQuote { |
| 625 | + // When auto-selecting, any deposit could be chosen. |
| 626 | + depositsToCheck = depositsToOutpoints(allDeposits) |
| 627 | + } |
| 628 | + warning := lowConfDepositWarning( |
| 629 | + allDeposits, depositsToCheck, |
| 630 | + int64(summary.RelativeExpiryBlocks), |
| 631 | + ) |
| 632 | + if warning != "" { |
| 633 | + fmt.Println(warning) |
| 634 | + } |
| 635 | + |
612 | 636 | if !(cmd.Bool("force") || cmd.Bool("f")) { |
613 | 637 | err = displayInDetails(quoteReq, quote, cmd.Bool("verbose")) |
614 | 638 | if err != nil { |
@@ -664,6 +688,80 @@ func depositsToOutpoints(deposits []*looprpc.Deposit) []string { |
664 | 688 | return outpoints |
665 | 689 | } |
666 | 690 |
|
| 691 | +// conservativeWarningConfs is the highest default confirmation tier used by |
| 692 | +// the server's dynamic confirmation-risk policy. |
| 693 | +// |
| 694 | +// The CLI does not currently know the server's exact policy, so we use this |
| 695 | +// conservative threshold for warnings without promising immediate execution. |
| 696 | +const conservativeWarningConfs = 6 |
| 697 | + |
| 698 | +// lowConfDepositWarning checks the selected deposits against a conservative |
| 699 | +// confirmation threshold and returns a warning string if any are found. |
| 700 | +func lowConfDepositWarning(allDeposits []*looprpc.Deposit, |
| 701 | + selectedOutpoints []string, csvExpiry int64) string { |
| 702 | + |
| 703 | + depositMap := make(map[string]*looprpc.Deposit, len(allDeposits)) |
| 704 | + for _, d := range allDeposits { |
| 705 | + depositMap[d.Outpoint] = d |
| 706 | + } |
| 707 | + |
| 708 | + var lowConfEntries []string |
| 709 | + for _, op := range selectedOutpoints { |
| 710 | + d, ok := depositMap[op] |
| 711 | + if !ok { |
| 712 | + continue |
| 713 | + } |
| 714 | + |
| 715 | + var confs int64 |
| 716 | + switch { |
| 717 | + case d.ConfirmationHeight <= 0: |
| 718 | + confs = 0 |
| 719 | + |
| 720 | + case csvExpiry > 0: |
| 721 | + // For confirmed deposits we can compute |
| 722 | + // confirmations as CSVExpiry - BlocksUntilExpiry + 1. |
| 723 | + confs = csvExpiry - d.BlocksUntilExpiry + 1 |
| 724 | + |
| 725 | + default: |
| 726 | + // Can't determine confirmations without the CSV expiry. |
| 727 | + continue |
| 728 | + } |
| 729 | + |
| 730 | + if confs >= conservativeWarningConfs { |
| 731 | + continue |
| 732 | + } |
| 733 | + |
| 734 | + if confs == 0 { |
| 735 | + lowConfEntries = append( |
| 736 | + lowConfEntries, |
| 737 | + fmt.Sprintf(" - %s (unconfirmed)", op), |
| 738 | + ) |
| 739 | + } else { |
| 740 | + lowConfEntries = append( |
| 741 | + lowConfEntries, |
| 742 | + fmt.Sprintf( |
| 743 | + " - %s (%d confirmations)", op, |
| 744 | + confs, |
| 745 | + ), |
| 746 | + ) |
| 747 | + } |
| 748 | + } |
| 749 | + |
| 750 | + if len(lowConfEntries) == 0 { |
| 751 | + return "" |
| 752 | + } |
| 753 | + |
| 754 | + return fmt.Sprintf( |
| 755 | + "\nWARNING: The following deposits are below the "+ |
| 756 | + "conservative %d-confirmation threshold:\n%s\n"+ |
| 757 | + "The swap payment for these deposits may wait for "+ |
| 758 | + "more confirmations depending on the server's "+ |
| 759 | + "confirmation-risk policy.\n", |
| 760 | + conservativeWarningConfs, |
| 761 | + strings.Join(lowConfEntries, "\n"), |
| 762 | + ) |
| 763 | +} |
| 764 | + |
667 | 765 | func displayNewAddressWarning() error { |
668 | 766 | fmt.Printf("\nWARNING: Be aware that loosing your l402.token file in " + |
669 | 767 | ".loop under your home directory will take your ability to " + |
|
0 commit comments