Skip to content

Commit 7d080e6

Browse files
committed
cmd/loop: add command "loop out sweephtlc"
1 parent 7123fb4 commit 7d080e6

File tree

4 files changed

+168
-0
lines changed

4 files changed

+168
-0
lines changed

cmd/loop/loopout.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ var loopOutCommand = &cli.Command{
121121
verboseFlag,
122122
channelFlag,
123123
},
124+
Commands: []*cli.Command{
125+
sweepHtlcCommand,
126+
},
124127
Action: loopOut,
125128
}
126129

cmd/loop/sweephtlc.go

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"encoding/hex"
7+
"fmt"
8+
9+
"github.com/btcsuite/btcd/wire"
10+
"github.com/lightninglabs/loop/looprpc"
11+
"github.com/urfave/cli/v3"
12+
)
13+
14+
// sweepHtlcCommand exposes HTLC success-path sweeping over loop CLI.
15+
var sweepHtlcCommand = &cli.Command{
16+
Name: "sweephtlc",
17+
Usage: "sweep an HTLC output using the preimage success path",
18+
Flags: []cli.Flag{
19+
&cli.StringFlag{
20+
Name: "outpoint",
21+
Usage: "htlc outpoint to sweep (format: txid:vout)",
22+
Required: true,
23+
},
24+
&cli.StringFlag{
25+
Name: "htlcaddr",
26+
Usage: "htlc address corresponding to the outpoint",
27+
Required: true,
28+
},
29+
&cli.UintFlag{
30+
Name: "feerate",
31+
Usage: "fee rate to use in sat/vbyte",
32+
Required: true,
33+
},
34+
&cli.StringFlag{
35+
Name: "destaddr",
36+
Usage: "optional destination address; defaults to a " +
37+
"new wallet address",
38+
},
39+
&cli.StringFlag{
40+
Name: "preimage",
41+
Usage: "optional preimage hex to override stored " +
42+
"swap preimage",
43+
},
44+
&cli.BoolFlag{
45+
Name: "publish",
46+
Usage: "publish the sweep transaction immediately",
47+
Value: false,
48+
},
49+
},
50+
Action: sweepHtlc,
51+
}
52+
53+
// sweepHtlc executes the SweepHtlc RPC and prints the sweep transaction hex.
54+
func sweepHtlc(ctx context.Context, cmd *cli.Command) error {
55+
// Loopd connecting client.
56+
client, cleanup, err := getClient(cmd)
57+
if err != nil {
58+
return err
59+
}
60+
defer cleanup()
61+
62+
// Find the preimage if the user passed it.
63+
var preimage []byte
64+
if cmd.IsSet("preimage") {
65+
preimage, err = hex.DecodeString(cmd.String("preimage"))
66+
if err != nil {
67+
return fmt.Errorf("invalid preimage: %w", err)
68+
}
69+
}
70+
71+
// Call SweepHtlc on loopd trying to sweep the HTLC.
72+
resp, err := client.SweepHtlc(ctx, &looprpc.SweepHtlcRequest{
73+
Outpoint: cmd.String("outpoint"),
74+
DestAddress: cmd.String("destaddr"),
75+
HtlcAddress: cmd.String("htlcaddr"),
76+
SatPerVbyte: uint32(cmd.Uint("feerate")),
77+
Preimage: preimage,
78+
Publish: cmd.Bool("publish"),
79+
})
80+
if err != nil {
81+
return err
82+
}
83+
84+
// Always display the raw sweep transaction.
85+
fmt.Printf("sweep_tx_hex: %x\n", resp.SweepTx)
86+
87+
// Report publish status in a user-friendly way based on response.
88+
switch {
89+
case resp.GetNotRequested() != nil:
90+
fmt.Println("publish: not requested (pass --publish to " +
91+
"broadcast)")
92+
93+
case resp.GetPublished() != nil:
94+
fmt.Println("publish: success")
95+
96+
case resp.GetFailed() != nil:
97+
errMsg := resp.GetFailed().GetError()
98+
fmt.Printf("publish: failed: %s\n", errMsg)
99+
100+
return fmt.Errorf("publish failed: %s", errMsg)
101+
102+
default:
103+
fmt.Println("publish: unknown status")
104+
}
105+
106+
// Print txid if the transaction is valid.
107+
var tx wire.MsgTx
108+
if err := tx.Deserialize(bytes.NewReader(resp.SweepTx)); err == nil {
109+
fmt.Printf("sweep_txid: %s\n", tx.TxHash().String())
110+
} else {
111+
fmt.Printf("sweep_txid: could not decode tx: %v\n", err)
112+
}
113+
114+
// Print the fee-rate.
115+
fmt.Printf("fee_sats: %d\n", resp.FeeSats)
116+
117+
return nil
118+
}

docs/loop.1

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,31 @@ perform an off-chain to on-chain swap (looping out)
114114
.PP
115115
\fB--verbose, -v\fP: show expanded details
116116

117+
.SS sweephtlc
118+
.PP
119+
sweep an HTLC output using the preimage success path
120+
121+
.PP
122+
\fB--destaddr\fP="": optional destination address; defaults to a new wallet address
123+
124+
.PP
125+
\fB--feerate\fP="": fee rate to use in sat/vbyte (default: 0)
126+
127+
.PP
128+
\fB--help, -h\fP: show help
129+
130+
.PP
131+
\fB--htlcaddr\fP="": htlc address corresponding to the outpoint
132+
133+
.PP
134+
\fB--outpoint\fP="": htlc outpoint to sweep (format: txid:vout)
135+
136+
.PP
137+
\fB--preimage\fP="": optional preimage hex to override stored swap preimage
138+
139+
.PP
140+
\fB--publish\fP: publish the sweep transaction immediately
141+
117142
.SH in
118143
.PP
119144
perform an on-chain to off-chain swap (loop in)

docs/loop.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,28 @@ The following flags are supported:
5353
| `--channel="…"` | the comma-separated list of short channel IDs of the channels to loop out | string |
5454
| `--help` (`-h`) | show help | bool | `false` |
5555

56+
### `out sweephtlc` subcommand
57+
58+
sweep an HTLC output using the preimage success path.
59+
60+
Usage:
61+
62+
```bash
63+
$ loop [GLOBAL FLAGS] out sweephtlc [COMMAND FLAGS] [ARGUMENTS...]
64+
```
65+
66+
The following flags are supported:
67+
68+
| Name | Description | Type | Default value |
69+
|------------------|----------------------------------------------------------------|--------|:-------------:|
70+
| `--outpoint="…"` | htlc outpoint to sweep (format: txid:vout) | string |
71+
| `--htlcaddr="…"` | htlc address corresponding to the outpoint | string |
72+
| `--feerate="…"` | fee rate to use in sat/vbyte | uint | `0` |
73+
| `--destaddr="…"` | optional destination address; defaults to a new wallet address | string |
74+
| `--preimage="…"` | optional preimage hex to override stored swap preimage | string |
75+
| `--publish` | publish the sweep transaction immediately | bool | `false` |
76+
| `--help` (`-h`) | show help | bool | `false` |
77+
5678
### `in` command
5779

5880
perform an on-chain to off-chain swap (loop in).

0 commit comments

Comments
 (0)