Skip to content

Commit 4e6752f

Browse files
committed
cli: static address deposit withdrawal command
1 parent c948c76 commit 4e6752f

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

cmd/loop/staticaddr.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@ package main
22

33
import (
44
"context"
5+
"encoding/hex"
6+
"errors"
57
"fmt"
8+
"strconv"
9+
"strings"
610

11+
"github.com/btcsuite/btcd/chaincfg/chainhash"
712
"github.com/lightninglabs/loop/looprpc"
813
"github.com/urfave/cli"
914
)
@@ -16,6 +21,7 @@ var staticAddressCommands = cli.Command{
1621
Subcommands: []cli.Command{
1722
newStaticAddressCommand,
1823
listUnspentCommand,
24+
withdrawalCommand,
1925
},
2026
}
2127

@@ -104,3 +110,113 @@ func listUnspent(ctx *cli.Context) error {
104110

105111
return nil
106112
}
113+
114+
var withdrawalCommand = cli.Command{
115+
Name: "withdraw",
116+
ShortName: "w",
117+
Usage: "Withdraw from static address deposits.",
118+
Description: `
119+
Withdraws from all or selected static address deposits by sweeping them
120+
back to our lnd wallet.
121+
`,
122+
Flags: []cli.Flag{
123+
cli.StringSliceFlag{
124+
Name: "utxo",
125+
Usage: "specify utxos as outpoints(tx:idx) which will" +
126+
"be closed.",
127+
},
128+
cli.BoolFlag{
129+
Name: "all",
130+
Usage: "withdraws all static address deposits.",
131+
},
132+
},
133+
Action: withdraw,
134+
}
135+
136+
func withdraw(ctx *cli.Context) error {
137+
if ctx.NArg() > 0 {
138+
return cli.ShowCommandHelp(ctx, "withdraw")
139+
}
140+
141+
client, cleanup, err := getClient(ctx)
142+
if err != nil {
143+
return err
144+
}
145+
defer cleanup()
146+
147+
var (
148+
req = &looprpc.WithdrawDepositsRequest{}
149+
isAllSelected = ctx.IsSet("all")
150+
isUtxoSelected = ctx.IsSet("utxo")
151+
outpoints []*looprpc.OutPoint
152+
ctxb = context.Background()
153+
)
154+
155+
switch {
156+
case isAllSelected == isUtxoSelected:
157+
return errors.New("must select either all or some utxos")
158+
159+
case isAllSelected:
160+
case isUtxoSelected:
161+
utxos := ctx.StringSlice("utxo")
162+
outpoints, err = utxosToOutpoints(utxos)
163+
if err != nil {
164+
return err
165+
}
166+
167+
req.Outpoints = outpoints
168+
169+
default:
170+
return fmt.Errorf("unknown withdrawal request")
171+
}
172+
173+
resp, err := client.WithdrawDeposits(ctxb, &looprpc.WithdrawDepositsRequest{
174+
Outpoints: outpoints,
175+
All: isAllSelected,
176+
})
177+
if err != nil {
178+
return err
179+
}
180+
181+
printRespJSON(resp)
182+
183+
return nil
184+
}
185+
186+
func utxosToOutpoints(utxos []string) ([]*looprpc.OutPoint, error) {
187+
var outpoints []*looprpc.OutPoint
188+
if len(utxos) == 0 {
189+
return nil, fmt.Errorf("no utxos specified")
190+
}
191+
for _, utxo := range utxos {
192+
outpoint, err := NewProtoOutPoint(utxo)
193+
if err != nil {
194+
return nil, err
195+
}
196+
outpoints = append(outpoints, outpoint)
197+
}
198+
199+
return outpoints, nil
200+
}
201+
202+
// NewProtoOutPoint parses an OutPoint into its corresponding lnrpc.OutPoint
203+
// type.
204+
func NewProtoOutPoint(op string) (*looprpc.OutPoint, error) {
205+
parts := strings.Split(op, ":")
206+
if len(parts) != 2 {
207+
return nil, errors.New("outpoint should be of the form " +
208+
"txid:index")
209+
}
210+
txid := parts[0]
211+
if hex.DecodedLen(len(txid)) != chainhash.HashSize {
212+
return nil, fmt.Errorf("invalid hex-encoded txid %v", txid)
213+
}
214+
outputIndex, err := strconv.Atoi(parts[1])
215+
if err != nil {
216+
return nil, fmt.Errorf("invalid output index: %v", err)
217+
}
218+
return &looprpc.OutPoint{
219+
TxidStr: txid,
220+
OutputIndex: uint32(outputIndex),
221+
}, nil
222+
}

0 commit comments

Comments
 (0)