@@ -2,8 +2,13 @@ package main
22
33import (
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
@@ -105,3 +111,111 @@ func listUnspent(ctx *cli.Context) error {
105111
106112 return nil
107113}
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