mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
cmd/loop: warn for low-confirmation static deposits
Warn before dispatching a static loop-in that selects deposits below the conservative six-confirmation threshold. Mirror automatic coin selection before prompting so the warning reflects both manual and auto-selected deposits. Cover manual and auto-selected warning paths in CLI tests.
This commit is contained in:
parent
c718e9a9fb
commit
43b16ff3e1
10 changed files with 1032 additions and 7 deletions
|
|
@ -4,14 +4,17 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/lightninglabs/loop/labels"
|
||||
"github.com/lightninglabs/loop/looprpc"
|
||||
"github.com/lightninglabs/loop/staticaddr/deposit"
|
||||
"github.com/lightninglabs/loop/staticaddr/loopin"
|
||||
"github.com/lightninglabs/loop/swapserverrpc"
|
||||
"github.com/lightningnetwork/lnd"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
|
@ -553,11 +556,7 @@ func staticAddressLoopIn(ctx context.Context, cmd *cli.Command) error {
|
|||
allDeposits := depositList.FilteredDeposits
|
||||
|
||||
if len(allDeposits) == 0 {
|
||||
errString := fmt.Sprintf("no confirmed deposits available, "+
|
||||
"deposits need at least %v confirmations",
|
||||
deposit.MinConfs)
|
||||
|
||||
return errors.New(errString)
|
||||
return errors.New("no deposited outputs available")
|
||||
}
|
||||
|
||||
var depositOutpoints []string
|
||||
|
|
@ -614,6 +613,28 @@ func staticAddressLoopIn(ctx context.Context, cmd *cli.Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Warn the user if any selected deposits have fewer than 6
|
||||
// confirmations, as the swap payment won't be received immediately
|
||||
// for those.
|
||||
summary, err := client.GetStaticAddressSummary(
|
||||
ctx, &looprpc.StaticAddressSummaryRequest{},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
depositsToCheck := warningDepositOutpoints(
|
||||
allDeposits, depositOutpoints, autoSelectDepositsForQuote,
|
||||
quoteReq.Amt,
|
||||
)
|
||||
warning := lowConfDepositWarning(
|
||||
allDeposits, depositsToCheck,
|
||||
int64(summary.RelativeExpiryBlocks),
|
||||
)
|
||||
if warning != "" {
|
||||
fmt.Println(warning)
|
||||
}
|
||||
|
||||
if !(cmd.Bool("force") || cmd.Bool("f")) {
|
||||
err = displayInDetails(quoteReq, quote, cmd.Bool("verbose"))
|
||||
if err != nil {
|
||||
|
|
@ -669,6 +690,162 @@ func depositsToOutpoints(deposits []*looprpc.Deposit) []string {
|
|||
return outpoints
|
||||
}
|
||||
|
||||
var warningSelectionDustLimit = int64(lnwallet.DustLimitForSize(input.P2TRSize))
|
||||
|
||||
// warningDepositOutpoints returns the deposit outpoints to check for
|
||||
// low-confirmation warnings.
|
||||
func warningDepositOutpoints(allDeposits []*looprpc.Deposit,
|
||||
selectedOutpoints []string, autoSelect bool, targetAmount int64) []string {
|
||||
|
||||
if !autoSelect {
|
||||
return selectedOutpoints
|
||||
}
|
||||
|
||||
return autoSelectedWarningOutpoints(allDeposits, targetAmount)
|
||||
}
|
||||
|
||||
// autoSelectedWarningOutpoints returns the outpoints selected by the same
|
||||
// ordering used for automatic static loop-in deposit selection.
|
||||
func autoSelectedWarningOutpoints(allDeposits []*looprpc.Deposit,
|
||||
targetAmount int64) []string {
|
||||
|
||||
if targetAmount <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// KEEP IN SYNC with staticaddr/loopin.SelectDeposits.
|
||||
deposits := filterSwappableWarningDeposits(allDeposits)
|
||||
sort.Slice(deposits, func(i, j int) bool {
|
||||
iConfirmed := deposits[i].ConfirmationHeight > 0
|
||||
jConfirmed := deposits[j].ConfirmationHeight > 0
|
||||
if iConfirmed != jConfirmed {
|
||||
return iConfirmed
|
||||
}
|
||||
|
||||
if deposits[i].Value == deposits[j].Value {
|
||||
return deposits[i].BlocksUntilExpiry <
|
||||
deposits[j].BlocksUntilExpiry
|
||||
}
|
||||
|
||||
return deposits[i].Value > deposits[j].Value
|
||||
})
|
||||
|
||||
selectedOutpoints := make([]string, 0, len(deposits))
|
||||
var selectedAmount int64
|
||||
for _, deposit := range deposits {
|
||||
selectedOutpoints = append(selectedOutpoints, deposit.Outpoint)
|
||||
selectedAmount += deposit.Value
|
||||
if selectedAmount == targetAmount {
|
||||
return selectedOutpoints
|
||||
}
|
||||
|
||||
if selectedAmount > targetAmount &&
|
||||
selectedAmount-targetAmount >= warningSelectionDustLimit {
|
||||
|
||||
return selectedOutpoints
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// filterSwappableWarningDeposits filters deposits for CLI warning selection.
|
||||
func filterSwappableWarningDeposits(
|
||||
allDeposits []*looprpc.Deposit) []*looprpc.Deposit {
|
||||
|
||||
swappable := make([]*looprpc.Deposit, 0, len(allDeposits))
|
||||
minBlocksUntilExpiry := int64(
|
||||
loopin.DefaultLoopInOnChainCltvDelta + loopin.DepositHtlcDelta,
|
||||
)
|
||||
for _, deposit := range allDeposits {
|
||||
// Unconfirmed deposits remain swappable because their CSV timeout has
|
||||
// not started yet. This mirrors loopin.IsSwappable.
|
||||
if deposit.ConfirmationHeight > 0 &&
|
||||
deposit.BlocksUntilExpiry < minBlocksUntilExpiry {
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
swappable = append(swappable, deposit)
|
||||
}
|
||||
|
||||
return swappable
|
||||
}
|
||||
|
||||
// conservativeWarningConfs is the highest default confirmation tier used by
|
||||
// the server's dynamic confirmation-risk policy.
|
||||
//
|
||||
// The CLI does not currently know the server's exact policy, so we use this
|
||||
// conservative threshold for warnings without promising immediate execution.
|
||||
const conservativeWarningConfs = 6
|
||||
|
||||
// lowConfDepositWarning checks the selected deposits against a conservative
|
||||
// confirmation threshold and returns a warning string if any are found.
|
||||
func lowConfDepositWarning(allDeposits []*looprpc.Deposit,
|
||||
selectedOutpoints []string, csvExpiry int64) string {
|
||||
|
||||
depositMap := make(map[string]*looprpc.Deposit, len(allDeposits))
|
||||
for _, d := range allDeposits {
|
||||
depositMap[d.Outpoint] = d
|
||||
}
|
||||
|
||||
var lowConfEntries []string
|
||||
for _, op := range selectedOutpoints {
|
||||
d, ok := depositMap[op]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
var confs int64
|
||||
switch {
|
||||
case d.ConfirmationHeight <= 0:
|
||||
confs = 0
|
||||
|
||||
case csvExpiry > 0:
|
||||
// For confirmed deposits we can compute
|
||||
// confirmations as CSVExpiry - BlocksUntilExpiry + 1.
|
||||
confs = csvExpiry - d.BlocksUntilExpiry + 1
|
||||
|
||||
default:
|
||||
// Can't determine confirmations without the CSV expiry.
|
||||
continue
|
||||
}
|
||||
|
||||
if confs >= conservativeWarningConfs {
|
||||
continue
|
||||
}
|
||||
|
||||
if confs == 0 {
|
||||
lowConfEntries = append(
|
||||
lowConfEntries,
|
||||
fmt.Sprintf(" - %s (unconfirmed)", op),
|
||||
)
|
||||
} else {
|
||||
lowConfEntries = append(
|
||||
lowConfEntries,
|
||||
fmt.Sprintf(
|
||||
" - %s (%d confirmations)", op,
|
||||
confs,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if len(lowConfEntries) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"\nWARNING: The following deposits are below the "+
|
||||
"conservative %d-confirmation threshold:\n%s\n"+
|
||||
"The swap payment for these deposits may wait for "+
|
||||
"more confirmations depending on the server's "+
|
||||
"confirmation-risk policy.\n",
|
||||
conservativeWarningConfs,
|
||||
strings.Join(lowConfEntries, "\n"),
|
||||
)
|
||||
}
|
||||
|
||||
func displayNewAddressWarning() error {
|
||||
fmt.Printf("\nWARNING: Be aware that loosing your l402.token file in " +
|
||||
".loop under your home directory will take your ability to " +
|
||||
|
|
|
|||
220
cmd/loop/staticaddr_test.go
Normal file
220
cmd/loop/staticaddr_test.go
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightninglabs/loop/looprpc"
|
||||
"github.com/lightninglabs/loop/staticaddr/deposit"
|
||||
"github.com/lightninglabs/loop/staticaddr/loopin"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestLowConfDepositWarningConfirmedOnly verifies confirmed deposits below the
|
||||
// conservative warning threshold are included in the warning text.
|
||||
func TestLowConfDepositWarningConfirmedOnly(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
deposits := []*looprpc.Deposit{
|
||||
{
|
||||
Outpoint: "confirmed-low",
|
||||
ConfirmationHeight: 100,
|
||||
BlocksUntilExpiry: 140,
|
||||
},
|
||||
{
|
||||
Outpoint: "confirmed-high",
|
||||
ConfirmationHeight: 95,
|
||||
BlocksUntilExpiry: 139,
|
||||
},
|
||||
}
|
||||
|
||||
warning := lowConfDepositWarning(
|
||||
deposits, []string{"confirmed-low", "confirmed-high"}, 144,
|
||||
)
|
||||
|
||||
require.Contains(t, warning, "confirmed-low (5 confirmations)")
|
||||
require.NotContains(t, warning, "confirmed-high")
|
||||
}
|
||||
|
||||
// TestLowConfDepositWarningUnconfirmed verifies unconfirmed deposits get a
|
||||
// warning that the swap may wait for confirmation-risk acceptance.
|
||||
func TestLowConfDepositWarningUnconfirmed(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
deposits := []*looprpc.Deposit{
|
||||
{
|
||||
Outpoint: "mempool",
|
||||
ConfirmationHeight: 0,
|
||||
BlocksUntilExpiry: 144,
|
||||
},
|
||||
}
|
||||
|
||||
warning := lowConfDepositWarning(deposits, []string{"mempool"}, 144)
|
||||
|
||||
require.Contains(t, warning, "mempool (unconfirmed)")
|
||||
require.True(
|
||||
t,
|
||||
strings.Contains(
|
||||
warning,
|
||||
"conservative 6-confirmation threshold",
|
||||
),
|
||||
)
|
||||
require.NotContains(t, warning, "executed immediately")
|
||||
}
|
||||
|
||||
// TestWarningDepositOutpointsAutoSelectPrefersConfirmed verifies automatic
|
||||
// warning selection keeps the loop-in preference for confirmed outputs.
|
||||
func TestWarningDepositOutpointsAutoSelectPrefersConfirmed(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const csvExpiry = 1100
|
||||
|
||||
deposits := []*looprpc.Deposit{
|
||||
{
|
||||
Outpoint: "mempool-large",
|
||||
Value: 2_000_000,
|
||||
ConfirmationHeight: 0,
|
||||
BlocksUntilExpiry: csvExpiry,
|
||||
},
|
||||
{
|
||||
Outpoint: "confirmed",
|
||||
Value: 1_500_000,
|
||||
ConfirmationHeight: 100,
|
||||
BlocksUntilExpiry: csvExpiry - 5,
|
||||
},
|
||||
}
|
||||
|
||||
selected := warningDepositOutpoints(deposits, nil, true, 1_000_000)
|
||||
|
||||
require.Equal(t, []string{"confirmed"}, selected)
|
||||
require.Empty(t, lowConfDepositWarning(deposits, selected, csvExpiry))
|
||||
}
|
||||
|
||||
// TestWarningDepositOutpointsAutoSelectIncludesNeededUnconfirmed verifies the
|
||||
// warning path includes mempool deposits when they are needed for the target.
|
||||
func TestWarningDepositOutpointsAutoSelectIncludesNeededUnconfirmed(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const csvExpiry = 1100
|
||||
|
||||
deposits := []*looprpc.Deposit{
|
||||
{
|
||||
Outpoint: "confirmed-small",
|
||||
Value: 500_000,
|
||||
ConfirmationHeight: 100,
|
||||
BlocksUntilExpiry: csvExpiry - 5,
|
||||
},
|
||||
{
|
||||
Outpoint: "mempool-large",
|
||||
Value: 2_000_000,
|
||||
ConfirmationHeight: 0,
|
||||
BlocksUntilExpiry: csvExpiry,
|
||||
},
|
||||
}
|
||||
|
||||
selected := warningDepositOutpoints(deposits, nil, true, 1_000_000)
|
||||
|
||||
require.Equal(
|
||||
t, []string{"confirmed-small", "mempool-large"}, selected,
|
||||
)
|
||||
|
||||
warning := lowConfDepositWarning(deposits, selected, csvExpiry)
|
||||
require.Contains(t, warning, "mempool-large (unconfirmed)")
|
||||
require.NotContains(t, warning, "confirmed-small")
|
||||
}
|
||||
|
||||
// TestWarningDepositSelectionMatchesLoopInSelection verifies CLI warning
|
||||
// selection matches the loop-in selector.
|
||||
func TestWarningDepositSelectionMatchesLoopInSelection(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const (
|
||||
blockHeight = uint32(10_000)
|
||||
csvExpiry = uint32(1_200)
|
||||
targetAmount = int64(2_500_000)
|
||||
)
|
||||
|
||||
type fixture struct {
|
||||
name string
|
||||
value int64
|
||||
confirmationHeight int64
|
||||
}
|
||||
|
||||
fixtures := []fixture{
|
||||
{
|
||||
name: "mempool-huge",
|
||||
value: 3_000_000,
|
||||
confirmationHeight: 0,
|
||||
},
|
||||
{
|
||||
name: "confirmed-later-expiry",
|
||||
value: 2_000_000,
|
||||
confirmationHeight: 9_900,
|
||||
},
|
||||
{
|
||||
name: "confirmed-earlier-expiry",
|
||||
value: 2_000_000,
|
||||
confirmationHeight: 9_890,
|
||||
},
|
||||
{
|
||||
name: "confirmed-small",
|
||||
value: 600_000,
|
||||
confirmationHeight: 9_900,
|
||||
},
|
||||
{
|
||||
name: "confirmed-too-close-to-expiry",
|
||||
value: 5_000_000,
|
||||
confirmationHeight: 9_849,
|
||||
},
|
||||
}
|
||||
|
||||
rpcDeposits := make([]*looprpc.Deposit, 0, len(fixtures))
|
||||
loopInDeposits := make([]*deposit.Deposit, 0, len(fixtures))
|
||||
for idx, fixture := range fixtures {
|
||||
hash := chainhash.Hash{byte(idx + 1)}
|
||||
outpoint := wire.OutPoint{
|
||||
Hash: hash,
|
||||
Index: uint32(idx),
|
||||
}
|
||||
|
||||
blocksUntilExpiry := int64(0)
|
||||
if fixture.confirmationHeight > 0 {
|
||||
blocksUntilExpiry = fixture.confirmationHeight +
|
||||
int64(csvExpiry) - int64(blockHeight)
|
||||
}
|
||||
|
||||
rpcDeposits = append(rpcDeposits, &looprpc.Deposit{
|
||||
Outpoint: outpoint.String(),
|
||||
Value: fixture.value,
|
||||
ConfirmationHeight: fixture.confirmationHeight,
|
||||
BlocksUntilExpiry: blocksUntilExpiry,
|
||||
})
|
||||
loopInDeposits = append(loopInDeposits, &deposit.Deposit{
|
||||
OutPoint: outpoint,
|
||||
Value: btcutil.Amount(fixture.value),
|
||||
ConfirmationHeight: fixture.confirmationHeight,
|
||||
})
|
||||
}
|
||||
|
||||
cliSelected := autoSelectedWarningOutpoints(
|
||||
rpcDeposits, targetAmount,
|
||||
)
|
||||
|
||||
loopInSelected, err := loopin.SelectDeposits(
|
||||
btcutil.Amount(targetAmount), loopInDeposits, csvExpiry,
|
||||
blockHeight,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
loopInSelectedOutpoints := make([]string, 0, len(loopInSelected))
|
||||
for _, selected := range loopInSelected {
|
||||
loopInSelectedOutpoints = append(
|
||||
loopInSelectedOutpoints, selected.OutPoint.String(),
|
||||
)
|
||||
}
|
||||
|
||||
require.Equal(t, loopInSelectedOutpoints, cliSelected)
|
||||
}
|
||||
2
cmd/loop/testdata/sessions/AGENTS.md
vendored
2
cmd/loop/testdata/sessions/AGENTS.md
vendored
|
|
@ -71,7 +71,7 @@ Base URL: `http://127.0.0.1:12345`
|
|||
| `quote/` | `loop quote out` (success + verbose), `loop quote in` (help + verbose), `loop quote out` (help), `loop quote in` (deposit_outpoint success), `loop quote in` (positional + last_hop) |
|
||||
| `static/` | `loop static withdraw` (no selection error), `loop static withdraw` (invalid utxo), `loop static withdraw` (all success), `loop static withdraw` (utxo + dest_addr success), `loop static listwithdrawals`, `loop static listswaps` |
|
||||
| `static-autoloop/` | `loop setparams --loopinsource static-address` (success + no-experimental error), `loop getparams` (static-address loop-in source), `loop suggestswaps` (static loop-in suggestion) |
|
||||
| `static-loop-in/` | `loop static new`, `loop static` (help), `loop static listunspent` (incl alias), `loop static listdeposits`, `loop static summary`, `loop static in` (multiple args/flags cases), `loop static in` (duplicate outpoints), `loop static in` (positional low amount error), `loop static in` (positional + last_hop + payment_timeout), `loop static in` (all cancel) |
|
||||
| `static-loop-in/` | `loop static new`, `loop static` (help), `loop static listunspent` (incl alias), `loop static listdeposits`, `loop static summary`, `loop static in` (multiple args/flags cases), `loop static in` (duplicate outpoints), `loop static in` (positional low amount error), `loop static in` (positional + last_hop + payment_timeout), `loop static in` (all cancel), `loop static in` (explicit and automatically selected low-confirmation warnings) |
|
||||
| `static-filters/` | `loop static listdeposits --filter ...` for each state (deposited/withdrawing/withdrawn/looping_in/looped_in/publish_expired_deposit/sweep_htlc_timeout/htlc_timeout_swept/wait_for_expiry_sweep/expired/failed) |
|
||||
| `swaps/` | `loop listswaps` (success + conflicting filters + loop_out_only filters + loop_in_only), `loop swapinfo` (success + invalid id + id flag errors), `loop abandonswap` (help + invalid id + success) |
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,37 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 65,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticAddressSummaryRequest",
|
||||
"payload": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 65,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.StaticAddressSummaryResponse",
|
||||
"payload": {
|
||||
"static_address": "bcrt1pfu9g59aqtxd39653f76y4c8z7r3t9tmcvrvhl57a3dgj3epdwxdqcd9fpw",
|
||||
"relative_expiry_blocks": "14400",
|
||||
"total_num_deposits": 1,
|
||||
"value_unconfirmed_satoshis": "0",
|
||||
"value_deposited_satoshis": "2500000",
|
||||
"value_expired_satoshis": "0",
|
||||
"value_withdrawn_satoshis": "0",
|
||||
"value_looped_in_satoshis": "0",
|
||||
"value_htlc_timeout_sweeps_satoshis": "0",
|
||||
"value_channels_opened": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 65,
|
||||
"kind": "stdout",
|
||||
|
|
|
|||
|
|
@ -94,6 +94,37 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 500,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticAddressSummaryRequest",
|
||||
"payload": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 500,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.StaticAddressSummaryResponse",
|
||||
"payload": {
|
||||
"static_address": "bcrt1pfu9g59aqtxd39653f76y4c8z7r3t9tmcvrvhl57a3dgj3epdwxdqcd9fpw",
|
||||
"relative_expiry_blocks": "14400",
|
||||
"total_num_deposits": 1,
|
||||
"value_unconfirmed_satoshis": "0",
|
||||
"value_deposited_satoshis": "500000",
|
||||
"value_expired_satoshis": "0",
|
||||
"value_withdrawn_satoshis": "0",
|
||||
"value_looped_in_satoshis": "0",
|
||||
"value_htlc_timeout_sweeps_satoshis": "0",
|
||||
"value_channels_opened": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 500,
|
||||
"kind": "grpc",
|
||||
|
|
|
|||
|
|
@ -99,6 +99,37 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 446,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticAddressSummaryRequest",
|
||||
"payload": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 446,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.StaticAddressSummaryResponse",
|
||||
"payload": {
|
||||
"static_address": "bcrt1pfu9g59aqtxd39653f76y4c8z7r3t9tmcvrvhl57a3dgj3epdwxdqcd9fpw",
|
||||
"relative_expiry_blocks": "14400",
|
||||
"total_num_deposits": 1,
|
||||
"value_unconfirmed_satoshis": "0",
|
||||
"value_deposited_satoshis": "500000",
|
||||
"value_expired_satoshis": "0",
|
||||
"value_withdrawn_satoshis": "0",
|
||||
"value_looped_in_satoshis": "0",
|
||||
"value_htlc_timeout_sweeps_satoshis": "0",
|
||||
"value_channels_opened": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 446,
|
||||
"kind": "stdout",
|
||||
|
|
|
|||
|
|
@ -127,6 +127,37 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 50,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticAddressSummaryRequest",
|
||||
"payload": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 50,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.StaticAddressSummaryResponse",
|
||||
"payload": {
|
||||
"static_address": "bcrt1p604kzzh28764kkw45yps48weergwljggamhhe7tqfglzjzang6cs43f2m2",
|
||||
"relative_expiry_blocks": "14400",
|
||||
"total_num_deposits": 4,
|
||||
"value_unconfirmed_satoshis": "0",
|
||||
"value_deposited_satoshis": "2546150",
|
||||
"value_expired_satoshis": "0",
|
||||
"value_withdrawn_satoshis": "0",
|
||||
"value_looped_in_satoshis": "0",
|
||||
"value_htlc_timeout_sweeps_satoshis": "0",
|
||||
"value_channels_opened": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 50,
|
||||
"kind": "grpc",
|
||||
|
|
|
|||
|
|
@ -118,6 +118,37 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 45,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticAddressSummaryRequest",
|
||||
"payload": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 45,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.StaticAddressSummaryResponse",
|
||||
"payload": {
|
||||
"static_address": "bcrt1p604kzzh28764kkw45yps48weergwljggamhhe7tqfglzjzang6cs43f2m2",
|
||||
"relative_expiry_blocks": "14400",
|
||||
"total_num_deposits": 3,
|
||||
"value_unconfirmed_satoshis": "0",
|
||||
"value_deposited_satoshis": "2046150",
|
||||
"value_expired_satoshis": "0",
|
||||
"value_withdrawn_satoshis": "0",
|
||||
"value_looped_in_satoshis": "0",
|
||||
"value_htlc_timeout_sweeps_satoshis": "0",
|
||||
"value_channels_opened": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 45,
|
||||
"kind": "grpc",
|
||||
|
|
|
|||
242
cmd/loop/testdata/sessions/static-loop-in/25_loop-static-in-low-conf-utxo.json
vendored
Normal file
242
cmd/loop/testdata/sessions/static-loop-in/25_loop-static-in-low-conf-utxo.json
vendored
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
{
|
||||
"metadata": {
|
||||
"args": [
|
||||
"loop",
|
||||
"static",
|
||||
"in",
|
||||
"--amt",
|
||||
"500000",
|
||||
"--utxo",
|
||||
"188f55042e49cfa9942cc1f8e216c5e8679a7036e9ee6449d0fcc6c6b81561be:0",
|
||||
"--network",
|
||||
"regtest"
|
||||
],
|
||||
"env": {},
|
||||
"version": "0.31.7-beta commit=vbump-lndclient-70-g352a68cd43f1976a937faaf76041bc078fdd16f6 commit_hash=352a68cd43f1976a937faaf76041bc078fdd16f6",
|
||||
"duration": 2826015164,
|
||||
"clock_start_unix": 1769407086
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"time_ms": 3,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/ListStaticAddressDeposits",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.ListStaticAddressDepositsRequest",
|
||||
"payload": {
|
||||
"state_filter": "DEPOSITED",
|
||||
"outpoints": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 22,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/ListStaticAddressDeposits",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.ListStaticAddressDepositsResponse",
|
||||
"payload": {
|
||||
"filtered_deposits": [
|
||||
{
|
||||
"id": "6mq78FccC6ghF66fIIZhTqzqiykT3AVEtwwA3ng1PnE=",
|
||||
"state": "DEPOSITED",
|
||||
"outpoint": "188f55042e49cfa9942cc1f8e216c5e8679a7036e9ee6449d0fcc6c6b81561be:0",
|
||||
"value": "2500000",
|
||||
"confirmation_height": "131",
|
||||
"blocks_until_expiry": "14396",
|
||||
"swap_hash": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 22,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetLoopInQuote",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.QuoteRequest",
|
||||
"payload": {
|
||||
"amt": "500000",
|
||||
"conf_target": 0,
|
||||
"external_htlc": false,
|
||||
"swap_publication_deadline": "0",
|
||||
"loop_in_last_hop": "",
|
||||
"loop_in_route_hints": [],
|
||||
"private": false,
|
||||
"deposit_outpoints": [
|
||||
"188f55042e49cfa9942cc1f8e216c5e8679a7036e9ee6449d0fcc6c6b81561be:0"
|
||||
],
|
||||
"asset_info": null,
|
||||
"auto_select_deposits": false,
|
||||
"fast": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 65,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetLoopInQuote",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.InQuoteResponse",
|
||||
"payload": {
|
||||
"swap_fee_sat": "1824",
|
||||
"htlc_publish_fee_sat": "0",
|
||||
"cltv_delta": 0,
|
||||
"conf_target": 0,
|
||||
"quoted_amt": "500000"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 65,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticAddressSummaryRequest",
|
||||
"payload": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 65,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.StaticAddressSummaryResponse",
|
||||
"payload": {
|
||||
"static_address": "bcrt1pfu9g59aqtxd39653f76y4c8z7r3t9tmcvrvhl57a3dgj3epdwxdqcd9fpw",
|
||||
"relative_expiry_blocks": "14400",
|
||||
"total_num_deposits": 1,
|
||||
"value_unconfirmed_satoshis": "0",
|
||||
"value_deposited_satoshis": "2500000",
|
||||
"value_expired_satoshis": "0",
|
||||
"value_withdrawn_satoshis": "0",
|
||||
"value_looped_in_satoshis": "0",
|
||||
"value_htlc_timeout_sweeps_satoshis": "0",
|
||||
"value_channels_opened": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 65,
|
||||
"kind": "stdout",
|
||||
"data": {
|
||||
"lines": [
|
||||
"\n",
|
||||
"WARNING: The following deposits are below the conservative 6-confirmation threshold:\n",
|
||||
" - 188f55042e49cfa9942cc1f8e216c5e8679a7036e9ee6449d0fcc6c6b81561be:0 (5 confirmations)\n",
|
||||
"The swap payment for these deposits may wait for more confirmations depending on the server's confirmation-risk policy.\n",
|
||||
"\n",
|
||||
"Previously deposited on-chain: 500000 sat\n",
|
||||
"Receive off-chain: 498176 sat\n",
|
||||
"Estimated total fee: 1824 sat\n",
|
||||
"\n",
|
||||
"CONTINUE SWAP? (y/n): {\n",
|
||||
" \"amount\": \"2500000\",\n",
|
||||
" \"change\": \"2000000\",\n",
|
||||
" \"fast\": false,\n",
|
||||
" \"htlc_cltv\": 1136,\n",
|
||||
" \"initiation_height\": 136,\n",
|
||||
" \"initiator\": \"loop-cli\",\n",
|
||||
" \"label\": \"\",\n",
|
||||
" \"max_swap_fee_satoshis\": \"1824\",\n",
|
||||
" \"payment_timeout_seconds\": 60,\n",
|
||||
" \"protocol_version\": \"V0\",\n",
|
||||
" \"quoted_swap_fee_satoshis\": \"1824\",\n",
|
||||
" \"state\": \"SignHtlcTx\",\n",
|
||||
" \"swap_amount\": \"500000\",\n",
|
||||
" \"swap_hash\": \"9f19fb5042a5de6da2f1ce183c5e224fd7802db408e9afdd598ee8174b2bce3f\",\n",
|
||||
" \"used_deposits\": [\n",
|
||||
" {\n",
|
||||
" \"blocks_until_expiry\": \"14396\",\n",
|
||||
" \"confirmation_height\": \"131\",\n",
|
||||
" \"id\": \"ea6abbf0571c0ba82117ae9f2086614eacea8b2913dc0544b70c00de78353e71\",\n",
|
||||
" \"outpoint\": \"188f55042e49cfa9942cc1f8e216c5e8679a7036e9ee6449d0fcc6c6b81561be:0\",\n",
|
||||
" \"state\": \"LOOPING_IN\",\n",
|
||||
" \"swap_hash\": \"\",\n",
|
||||
" \"value\": \"2500000\"\n",
|
||||
" }\n",
|
||||
" ]\n",
|
||||
"}\n"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 2358,
|
||||
"kind": "stdin",
|
||||
"data": {
|
||||
"text": "y\n"
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 2358,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/StaticAddressLoopIn",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticAddressLoopInRequest",
|
||||
"payload": {
|
||||
"outpoints": [
|
||||
"188f55042e49cfa9942cc1f8e216c5e8679a7036e9ee6449d0fcc6c6b81561be:0"
|
||||
],
|
||||
"max_swap_fee_satoshis": "1824",
|
||||
"last_hop": "",
|
||||
"label": "",
|
||||
"initiator": "loop-cli",
|
||||
"route_hints": [],
|
||||
"private": false,
|
||||
"payment_timeout_seconds": 60,
|
||||
"amount": "500000",
|
||||
"fast": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 2824,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/StaticAddressLoopIn",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.StaticAddressLoopInResponse",
|
||||
"payload": {
|
||||
"swap_hash": "nxn7UEKl3m2i8c4YPF4iT9eALbQI6a/dWY7oF0srzj8=",
|
||||
"state": "SignHtlcTx",
|
||||
"amount": "2500000",
|
||||
"htlc_cltv": 1136,
|
||||
"quoted_swap_fee_satoshis": "1824",
|
||||
"max_swap_fee_satoshis": "1824",
|
||||
"initiation_height": 136,
|
||||
"protocol_version": "V0",
|
||||
"label": "",
|
||||
"initiator": "loop-cli",
|
||||
"payment_timeout_seconds": 60,
|
||||
"used_deposits": [
|
||||
{
|
||||
"id": "6mq78FccC6ghF66fIIZhTqzqiykT3AVEtwwA3ng1PnE=",
|
||||
"state": "LOOPING_IN",
|
||||
"outpoint": "188f55042e49cfa9942cc1f8e216c5e8679a7036e9ee6449d0fcc6c6b81561be:0",
|
||||
"value": "2500000",
|
||||
"confirmation_height": "131",
|
||||
"blocks_until_expiry": "14396",
|
||||
"swap_hash": ""
|
||||
}
|
||||
],
|
||||
"swap_amount": "500000",
|
||||
"change": "2000000",
|
||||
"fast": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 2826,
|
||||
"kind": "exit",
|
||||
"data": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
231
cmd/loop/testdata/sessions/static-loop-in/26_loop-static-in-auto-unconfirmed.json
vendored
Normal file
231
cmd/loop/testdata/sessions/static-loop-in/26_loop-static-in-auto-unconfirmed.json
vendored
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
{
|
||||
"metadata": {
|
||||
"args": [
|
||||
"/home/user/bin/loop",
|
||||
"static",
|
||||
"in",
|
||||
"--network",
|
||||
"regtest",
|
||||
"500000",
|
||||
"--payment_timeout",
|
||||
"30s",
|
||||
"--last_hop",
|
||||
"0271d6e29301159d9e1cc5d3983479a51f3b3c0c682eda7f16aa1f47dfe09b22f7",
|
||||
"--force"
|
||||
],
|
||||
"env": {
|
||||
"HOME": "/home/user"
|
||||
},
|
||||
"version": "0.31.7-beta commit=v0.31.7-beta-28-g6d8ddfc59ddc2dcfd1a9b4e4b3c53a9cf15dd845 commit_hash=6d8ddfc59ddc2dcfd1a9b4e4b3c53a9cf15dd845",
|
||||
"duration": 1078774451,
|
||||
"clock_start_unix": 1769407086
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"time_ms": 4,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/ListStaticAddressDeposits",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.ListStaticAddressDepositsRequest",
|
||||
"payload": {
|
||||
"state_filter": "DEPOSITED",
|
||||
"outpoints": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 179,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/ListStaticAddressDeposits",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.ListStaticAddressDepositsResponse",
|
||||
"payload": {
|
||||
"filtered_deposits": [
|
||||
{
|
||||
"id": "j71tovlF3ikFqn+pOGB0TZOH00ZEhDYOluRnpR3jvJ0=",
|
||||
"state": "DEPOSITED",
|
||||
"outpoint": "9fa0d5dd5348794aa0541dd2729497f0907890606d044e1c4757bdc848f38df8:0",
|
||||
"value": "500000",
|
||||
"confirmation_height": "0",
|
||||
"blocks_until_expiry": "14400",
|
||||
"swap_hash": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 180,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetLoopInQuote",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.QuoteRequest",
|
||||
"payload": {
|
||||
"amt": "500000",
|
||||
"conf_target": 0,
|
||||
"external_htlc": false,
|
||||
"swap_publication_deadline": "0",
|
||||
"loop_in_last_hop": "AnHW4pMBFZ2eHMXTmDR5pR87PAxoLtp/FqofR9/gmyL3",
|
||||
"loop_in_route_hints": [],
|
||||
"private": false,
|
||||
"deposit_outpoints": [],
|
||||
"asset_info": null,
|
||||
"auto_select_deposits": true,
|
||||
"fast": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 500,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetLoopInQuote",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.InQuoteResponse",
|
||||
"payload": {
|
||||
"swap_fee_sat": "1824",
|
||||
"htlc_publish_fee_sat": "0",
|
||||
"cltv_delta": 0,
|
||||
"conf_target": 0,
|
||||
"quoted_amt": "500000"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 500,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticAddressSummaryRequest",
|
||||
"payload": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 500,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/GetStaticAddressSummary",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.StaticAddressSummaryResponse",
|
||||
"payload": {
|
||||
"static_address": "bcrt1pfu9g59aqtxd39653f76y4c8z7r3t9tmcvrvhl57a3dgj3epdwxdqcd9fpw",
|
||||
"relative_expiry_blocks": "14400",
|
||||
"total_num_deposits": 1,
|
||||
"value_unconfirmed_satoshis": "500000",
|
||||
"value_deposited_satoshis": "0",
|
||||
"value_expired_satoshis": "0",
|
||||
"value_withdrawn_satoshis": "0",
|
||||
"value_looped_in_satoshis": "0",
|
||||
"value_htlc_timeout_sweeps_satoshis": "0",
|
||||
"value_channels_opened": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 500,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/StaticAddressLoopIn",
|
||||
"event": "request",
|
||||
"message_type": "looprpc.StaticAddressLoopInRequest",
|
||||
"payload": {
|
||||
"outpoints": [],
|
||||
"max_swap_fee_satoshis": "1824",
|
||||
"last_hop": "AnHW4pMBFZ2eHMXTmDR5pR87PAxoLtp/FqofR9/gmyL3",
|
||||
"label": "",
|
||||
"initiator": "loop-cli",
|
||||
"route_hints": [],
|
||||
"private": false,
|
||||
"payment_timeout_seconds": 30,
|
||||
"amount": "500000",
|
||||
"fast": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 1078,
|
||||
"kind": "grpc",
|
||||
"data": {
|
||||
"method": "/looprpc.SwapClient/StaticAddressLoopIn",
|
||||
"event": "response",
|
||||
"message_type": "looprpc.StaticAddressLoopInResponse",
|
||||
"payload": {
|
||||
"swap_hash": "hDAjN0JANkGTlqt5ZN14uFsaSBqfHbc9tc3e5XwkQ+c=",
|
||||
"state": "SignHtlcTx",
|
||||
"amount": "500000",
|
||||
"htlc_cltv": 1165,
|
||||
"quoted_swap_fee_satoshis": "1824",
|
||||
"max_swap_fee_satoshis": "1824",
|
||||
"initiation_height": 165,
|
||||
"protocol_version": "V0",
|
||||
"label": "",
|
||||
"initiator": "loop-cli",
|
||||
"payment_timeout_seconds": 30,
|
||||
"used_deposits": [
|
||||
{
|
||||
"id": "j71tovlF3ikFqn+pOGB0TZOH00ZEhDYOluRnpR3jvJ0=",
|
||||
"state": "LOOPING_IN",
|
||||
"outpoint": "9fa0d5dd5348794aa0541dd2729497f0907890606d044e1c4757bdc848f38df8:0",
|
||||
"value": "500000",
|
||||
"confirmation_height": "0",
|
||||
"blocks_until_expiry": "14400",
|
||||
"swap_hash": ""
|
||||
}
|
||||
],
|
||||
"swap_amount": "500000",
|
||||
"change": "0",
|
||||
"fast": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 1078,
|
||||
"kind": "stdout",
|
||||
"data": {
|
||||
"lines": [
|
||||
"\n",
|
||||
"WARNING: The following deposits are below the conservative 6-confirmation threshold:\n",
|
||||
" - 9fa0d5dd5348794aa0541dd2729497f0907890606d044e1c4757bdc848f38df8:0 (unconfirmed)\n",
|
||||
"The swap payment for these deposits may wait for more confirmations depending on the server's confirmation-risk policy.\n",
|
||||
"\n",
|
||||
"{\n",
|
||||
" \"amount\": \"500000\",\n",
|
||||
" \"change\": \"0\",\n",
|
||||
" \"fast\": false,\n",
|
||||
" \"htlc_cltv\": 1165,\n",
|
||||
" \"initiation_height\": 165,\n",
|
||||
" \"initiator\": \"loop-cli\",\n",
|
||||
" \"label\": \"\",\n",
|
||||
" \"max_swap_fee_satoshis\": \"1824\",\n",
|
||||
" \"payment_timeout_seconds\": 30,\n",
|
||||
" \"protocol_version\": \"V0\",\n",
|
||||
" \"quoted_swap_fee_satoshis\": \"1824\",\n",
|
||||
" \"state\": \"SignHtlcTx\",\n",
|
||||
" \"swap_amount\": \"500000\",\n",
|
||||
" \"swap_hash\": \"84302337424036419396ab7964dd78b85b1a481a9f1db73db5cddee57c2443e7\",\n",
|
||||
" \"used_deposits\": [\n",
|
||||
" {\n",
|
||||
" \"blocks_until_expiry\": \"14400\",\n",
|
||||
" \"confirmation_height\": \"0\",\n",
|
||||
" \"id\": \"8fbd6da2f945de2905aa7fa93860744d9387d3464484360e96e467a51de3bc9d\",\n",
|
||||
" \"outpoint\": \"9fa0d5dd5348794aa0541dd2729497f0907890606d044e1c4757bdc848f38df8:0\",\n",
|
||||
" \"state\": \"LOOPING_IN\",\n",
|
||||
" \"swap_hash\": \"\",\n",
|
||||
" \"value\": \"500000\"\n",
|
||||
" }\n",
|
||||
" ]\n",
|
||||
"}\n"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"time_ms": 1078,
|
||||
"kind": "exit",
|
||||
"data": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue