@@ -2,8 +2,13 @@ package main
2
2
3
3
import (
4
4
"context"
5
+ "encoding/hex"
6
+ "errors"
5
7
"fmt"
8
+ "strconv"
9
+ "strings"
6
10
11
+ "github.com/btcsuite/btcd/chaincfg/chainhash"
7
12
"github.com/lightninglabs/loop/looprpc"
8
13
"github.com/urfave/cli"
9
14
)
@@ -16,6 +21,7 @@ var staticAddressCommands = cli.Command{
16
21
Subcommands : []cli.Command {
17
22
newStaticAddressCommand ,
18
23
listUnspentCommand ,
24
+ withdrawalCommand ,
19
25
},
20
26
}
21
27
@@ -105,3 +111,111 @@ func listUnspent(ctx *cli.Context) error {
105
111
106
112
return nil
107
113
}
114
+
115
+ var withdrawalCommand = cli.Command {
116
+ Name : "withdraw" ,
117
+ ShortName : "w" ,
118
+ Usage : "Withdraw from static address deposits." ,
119
+ Description : `
120
+ Withdraws from all or selected static address deposits by sweeping them
121
+ back to our lnd wallet.
122
+ ` ,
123
+ Flags : []cli.Flag {
124
+ cli.StringSliceFlag {
125
+ Name : "utxo" ,
126
+ Usage : "specify utxos as outpoints(tx:idx) which will" +
127
+ "be withdrawn." ,
128
+ },
129
+ cli.BoolFlag {
130
+ Name : "all" ,
131
+ Usage : "withdraws all static address deposits." ,
132
+ },
133
+ },
134
+ Action : withdraw ,
135
+ }
136
+
137
+ func withdraw (ctx * cli.Context ) error {
138
+ if ctx .NArg () > 0 {
139
+ return cli .ShowCommandHelp (ctx , "withdraw" )
140
+ }
141
+
142
+ client , cleanup , err := getClient (ctx )
143
+ if err != nil {
144
+ return err
145
+ }
146
+ defer cleanup ()
147
+
148
+ var (
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
+ default :
168
+ return fmt .Errorf ("unknown withdrawal request" )
169
+ }
170
+
171
+ resp , err := client .WithdrawDeposits (ctxb , & looprpc.WithdrawDepositsRequest {
172
+ Outpoints : outpoints ,
173
+ All : isAllSelected ,
174
+ })
175
+ if err != nil {
176
+ return err
177
+ }
178
+
179
+ printRespJSON (resp )
180
+
181
+ return nil
182
+ }
183
+
184
+ func utxosToOutpoints (utxos []string ) ([]* looprpc.OutPoint , error ) {
185
+ outpoints := make ([]* looprpc.OutPoint , 0 , len (utxos ))
186
+ if len (utxos ) == 0 {
187
+ return nil , fmt .Errorf ("no utxos specified" )
188
+ }
189
+ for _ , utxo := range utxos {
190
+ outpoint , err := NewProtoOutPoint (utxo )
191
+ if err != nil {
192
+ return nil , err
193
+ }
194
+ outpoints = append (outpoints , outpoint )
195
+ }
196
+
197
+ return outpoints , nil
198
+ }
199
+
200
+ // NewProtoOutPoint parses an OutPoint into its corresponding lnrpc.OutPoint
201
+ // type.
202
+ func NewProtoOutPoint (op string ) (* looprpc.OutPoint , error ) {
203
+ parts := strings .Split (op , ":" )
204
+ if len (parts ) != 2 {
205
+ return nil , errors .New ("outpoint should be of the form " +
206
+ "txid:index" )
207
+ }
208
+ txid := parts [0 ]
209
+ if hex .DecodedLen (len (txid )) != chainhash .HashSize {
210
+ return nil , fmt .Errorf ("invalid hex-encoded txid %v" , txid )
211
+ }
212
+ outputIndex , err := strconv .Atoi (parts [1 ])
213
+ if err != nil {
214
+ return nil , fmt .Errorf ("invalid output index: %v" , err )
215
+ }
216
+
217
+ return & looprpc.OutPoint {
218
+ TxidStr : txid ,
219
+ OutputIndex : uint32 (outputIndex ),
220
+ }, nil
221
+ }
0 commit comments