Skip to content

Commit 76a1d15

Browse files
committed
loop: add manual static deposit recovery
Add recoverdeposit CLI/RPC support for verifying one static-address output on-chain, matching it to a derived static address, restoring the address/import, and directly creating or reactivating the deposit row. The recovery request also accepts optional seed metadata so operators can recover deposits before the local static-address seed row has been restored.
1 parent 40fd9bd commit 76a1d15

24 files changed

Lines changed: 2179 additions & 296 deletions

cmd/loop/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ var (
8989
listSwapsCommand, swapInfoCommand, getLiquidityParamsCommand,
9090
setLiquidityRuleCommand, suggestSwapCommand, setParamsCommand,
9191
getInfoCommand, abandonSwapCommand, recoverCommand,
92+
recoverDepositCommand,
9293
reservationsCommands,
9394
instantOutCommand, listInstantOutsCommand, stopCommand,
9495
printManCommand, printMarkdownCommand,

cmd/loop/recover.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,42 @@ var recoverCommand = &cli.Command{
2525
Action: runRecover,
2626
}
2727

28+
var recoverDepositCommand = &cli.Command{
29+
Name: "recoverdeposit",
30+
Usage: "recover one static address deposit from on-chain data",
31+
Description: "Verifies the provided transaction output on-chain, " +
32+
"restores the matching static address, stores the deposit, and " +
33+
"starts normal deposit tracking.",
34+
Flags: []cli.Flag{
35+
&cli.StringFlag{
36+
Name: "txid",
37+
Usage: "transaction ID containing the deposit output",
38+
Required: true,
39+
},
40+
&cli.UintFlag{
41+
Name: "vout",
42+
Usage: "deposit output index",
43+
Required: true,
44+
},
45+
&cli.IntFlag{
46+
Name: "height_hint",
47+
Usage: "block height hint for the deposit transaction",
48+
Required: true,
49+
},
50+
&cli.StringFlag{
51+
Name: "pkscript_hex",
52+
Usage: "expected static address P2TR pkScript in hex",
53+
Required: true,
54+
},
55+
&cli.UintFlag{
56+
Name: "scan_limit",
57+
Usage: "optional highest child index to scan in each " +
58+
"static address key family",
59+
},
60+
},
61+
Action: runRecoverDeposit,
62+
}
63+
2864
func runRecover(ctx context.Context, cmd *cli.Command) error {
2965
if cmd.NArg() > 0 {
3066
return showCommandHelp(ctx, cmd)
@@ -48,3 +84,31 @@ func runRecover(ctx context.Context, cmd *cli.Command) error {
4884
printRespJSON(resp)
4985
return nil
5086
}
87+
88+
func runRecoverDeposit(ctx context.Context, cmd *cli.Command) error {
89+
if cmd.NArg() > 0 {
90+
return showCommandHelp(ctx, cmd)
91+
}
92+
93+
client, cleanup, err := getClient(cmd)
94+
if err != nil {
95+
return err
96+
}
97+
defer cleanup()
98+
99+
resp, err := client.RecoverDeposit(
100+
ctx, &looprpc.RecoverDepositRequest{
101+
Txid: cmd.String("txid"),
102+
Vout: uint32(cmd.Uint("vout")),
103+
HeightHint: int32(cmd.Int("height_hint")),
104+
PkscriptHex: cmd.String("pkscript_hex"),
105+
ScanLimit: uint32(cmd.Uint("scan_limit")),
106+
},
107+
)
108+
if err != nil {
109+
return err
110+
}
111+
112+
printRespJSON(resp)
113+
return nil
114+
}

loopd/swapclient_server.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,6 +1297,44 @@ func (s *swapClientServer) Recover(ctx context.Context,
12971297
}, nil
12981298
}
12991299

1300+
// RecoverDeposit verifies and restores one static-address deposit from
1301+
// caller-supplied on-chain coordinates.
1302+
func (s *swapClientServer) RecoverDeposit(ctx context.Context,
1303+
req *looprpc.RecoverDepositRequest) (*looprpc.RecoverDepositResponse,
1304+
error) {
1305+
1306+
if s.recoveryService == nil {
1307+
return nil, status.Error(
1308+
codes.Unavailable, "recovery service not configured",
1309+
)
1310+
}
1311+
1312+
result, err := s.recoveryService.RecoverDeposit(
1313+
ctx, &recovery.RecoverDepositRequest{
1314+
TxID: req.GetTxid(),
1315+
VOut: req.GetVout(),
1316+
HeightHint: req.GetHeightHint(),
1317+
PkScriptHex: req.GetPkscriptHex(),
1318+
ScanLimit: req.GetScanLimit(),
1319+
},
1320+
)
1321+
if err != nil {
1322+
return nil, err
1323+
}
1324+
1325+
return &looprpc.RecoverDepositResponse{
1326+
Outpoint: result.OutPoint,
1327+
Value: int64(result.Value),
1328+
ConfirmationHeight: result.ConfirmationHeight,
1329+
ClientKeyFamily: result.ClientKeyFamily,
1330+
ClientKeyIndex: result.ClientKeyIndex,
1331+
StaticAddress: result.StaticAddress,
1332+
RecoveredAddress: result.RecoveredAddress,
1333+
RecoveredDeposit: result.RecoveredDeposit,
1334+
DepositId: result.DepositID,
1335+
}, nil
1336+
}
1337+
13001338
// GetInfo returns basic information about the loop daemon and details to swaps
13011339
// from the swap store.
13021340
func (s *swapClientServer) GetInfo(ctx context.Context,

loopd/swapclient_server_staticaddr_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ func (s *staticAddrDepositStore) UpdateDeposit(context.Context,
3434
return nil
3535
}
3636

37+
func (s *staticAddrDepositStore) UpdateRecoveredDeposit(context.Context,
38+
*deposit.Deposit) error {
39+
40+
return nil
41+
}
42+
3743
func (s *staticAddrDepositStore) GetDeposit(context.Context,
3844
deposit.ID) (*deposit.Deposit, error) {
3945

loopd/swapclient_server_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,12 @@ func (s *mockDepositStore) UpdateDeposit(_ context.Context,
10191019
return nil
10201020
}
10211021

1022+
func (s *mockDepositStore) UpdateRecoveredDeposit(_ context.Context,
1023+
_ *deposit.Deposit) error {
1024+
1025+
return nil
1026+
}
1027+
10221028
func (s *mockDepositStore) GetDeposit(_ context.Context,
10231029
_ deposit.ID) (*deposit.Deposit, error) {
10241030

loopdb/sqlc/querier.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

loopdb/sqlc/queries/static_address_deposits.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ SET
3232
WHERE
3333
deposits.deposit_id = $1;
3434

35+
-- name: UpdateRecoveredDeposit :exec
36+
UPDATE deposits
37+
SET
38+
tx_hash = $2,
39+
out_index = $3,
40+
amount = $4,
41+
confirmation_height = $5,
42+
timeout_sweep_pk_script = $6,
43+
static_address_id = $7
44+
WHERE
45+
deposits.deposit_id = $1;
46+
3547
-- name: InsertDepositUpdate :exec
3648
INSERT INTO deposit_updates (
3749
deposit_id,

loopdb/sqlc/static_address_deposits.sql.go

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)