@@ -7,11 +7,17 @@ import (
7
7
"os"
8
8
"strconv"
9
9
10
+ "github.com/lightninglabs/lightning-terminal/accounts"
10
11
"github.com/lightninglabs/lightning-terminal/litrpc"
11
12
"github.com/lightningnetwork/lnd/lncfg"
12
13
"github.com/urfave/cli"
13
14
)
14
15
16
+ const (
17
+ idName = "id"
18
+ labelName = "label"
19
+ )
20
+
15
21
var accountsCommands = []cli.Command {
16
22
{
17
23
Name : "accounts" ,
@@ -22,6 +28,7 @@ var accountsCommands = []cli.Command{
22
28
createAccountCommand ,
23
29
updateAccountCommand ,
24
30
listAccountsCommand ,
31
+ accountInfoCommand ,
25
32
removeAccountCommand ,
26
33
},
27
34
},
@@ -31,7 +38,7 @@ var createAccountCommand = cli.Command{
31
38
Name : "create" ,
32
39
ShortName : "c" ,
33
40
Usage : "Create a new off-chain account with a balance." ,
34
- ArgsUsage : "balance [expiration_date]" ,
41
+ ArgsUsage : "balance [expiration_date] [--label=LABEL] [--save_to=FILE] " ,
35
42
Description : `
36
43
Adds an entry to the account database. This entry represents an amount
37
44
of satoshis (account balance) that can be spent using off-chain
@@ -61,6 +68,10 @@ var createAccountCommand = cli.Command{
61
68
Usage : "store the account macaroon created for the " +
62
69
"account to the given file" ,
63
70
},
71
+ cli.StringFlag {
72
+ Name : labelName ,
73
+ Usage : "(optional) the unique label of the account" ,
74
+ },
64
75
},
65
76
Action : createAccount ,
66
77
}
@@ -111,6 +122,7 @@ func createAccount(ctx *cli.Context) error {
111
122
req := & litrpc.CreateAccountRequest {
112
123
AccountBalance : initialBalance ,
113
124
ExpirationDate : expirationDate ,
125
+ Label : ctx .String (labelName ),
114
126
}
115
127
resp , err := client .CreateAccount (ctxb , req )
116
128
if err != nil {
@@ -139,16 +151,20 @@ var updateAccountCommand = cli.Command{
139
151
Name : "update" ,
140
152
ShortName : "u" ,
141
153
Usage : "Update an existing off-chain account." ,
142
- ArgsUsage : "id new_balance [new_expiration_date] [--save_to=]" ,
154
+ ArgsUsage : "[id | label] new_balance [new_expiration_date] [--save_to=]" ,
143
155
Description : `
144
156
Updates an existing off-chain account and sets either a new balance or
145
157
new expiration date or both.
146
158
` ,
147
159
Flags : []cli.Flag {
148
160
cli.StringFlag {
149
- Name : "id" ,
161
+ Name : idName ,
150
162
Usage : "the ID of the account to update" ,
151
163
},
164
+ cli.StringFlag {
165
+ Name : labelName ,
166
+ Usage : "(optional) the unique label of the account" ,
167
+ },
152
168
cli.Int64Flag {
153
169
Name : "new_balance" ,
154
170
Usage : "the new balance of the account; -1 means do " +
@@ -176,29 +192,15 @@ func updateAccount(ctx *cli.Context) error {
176
192
defer cleanup ()
177
193
client := litrpc .NewAccountsClient (clientConn )
178
194
195
+ id , label , args , err := parseIDOrLabel (ctx )
196
+ if err != nil {
197
+ return err
198
+ }
199
+
179
200
var (
180
- id []byte
181
201
newBalance int64
182
202
expirationDate int64
183
203
)
184
- args := ctx .Args ()
185
-
186
- // We parse the ID as hex even though we're supposed to send it as a hex
187
- // encoded string over the RPC. But that way we can verify it's actually
188
- // the id.
189
- switch {
190
- case ctx .IsSet ("id" ):
191
- id , err = hex .DecodeString (ctx .String ("id" ))
192
- case args .Present ():
193
- id , err = hex .DecodeString (args .First ())
194
- args = args .Tail ()
195
- default :
196
- return fmt .Errorf ("id is missing" )
197
- }
198
- if err != nil {
199
- return fmt .Errorf ("error decoding id: %v" , err )
200
- }
201
-
202
204
switch {
203
205
case ctx .IsSet ("new_balance" ):
204
206
newBalance = ctx .Int64 ("new_balance" )
@@ -224,7 +226,8 @@ func updateAccount(ctx *cli.Context) error {
224
226
}
225
227
226
228
req := & litrpc.UpdateAccountRequest {
227
- Id : hex .EncodeToString (id ),
229
+ Id : id ,
230
+ Label : label ,
228
231
AccountBalance : newBalance ,
229
232
ExpirationDate : expirationDate ,
230
233
}
@@ -267,19 +270,71 @@ func listAccounts(ctx *cli.Context) error {
267
270
return nil
268
271
}
269
272
273
+ var accountInfoCommand = cli.Command {
274
+ Name : "info" ,
275
+ ShortName : "i" ,
276
+ Usage : "Show information about a single off-chain account." ,
277
+ ArgsUsage : "[id | label]" ,
278
+ Description : `
279
+ Returns a single account entry from the account database.
280
+ ` ,
281
+ Flags : []cli.Flag {
282
+ cli.StringFlag {
283
+ Name : idName ,
284
+ Usage : "the ID of the account" ,
285
+ },
286
+ cli.StringFlag {
287
+ Name : labelName ,
288
+ Usage : "(optional) the unique label of the account" ,
289
+ },
290
+ },
291
+ Action : accountInfo ,
292
+ }
293
+
294
+ func accountInfo (ctx * cli.Context ) error {
295
+ ctxb := context .Background ()
296
+ clientConn , cleanup , err := connectClient (ctx )
297
+ if err != nil {
298
+ return err
299
+ }
300
+ defer cleanup ()
301
+ client := litrpc .NewAccountsClient (clientConn )
302
+
303
+ id , label , _ , err := parseIDOrLabel (ctx )
304
+ if err != nil {
305
+ return err
306
+ }
307
+
308
+ req := & litrpc.AccountInfoRequest {
309
+ Id : id ,
310
+ Label : label ,
311
+ }
312
+ resp , err := client .AccountInfo (ctxb , req )
313
+ if err != nil {
314
+ return err
315
+ }
316
+
317
+ printRespJSON (resp )
318
+ return nil
319
+ }
320
+
270
321
var removeAccountCommand = cli.Command {
271
322
Name : "remove" ,
272
323
ShortName : "r" ,
273
324
Usage : "Removes an off-chain account from the database." ,
274
- ArgsUsage : "id " ,
325
+ ArgsUsage : "[id | label] " ,
275
326
Description : `
276
327
Removes an account entry from the account database.
277
328
` ,
278
329
Flags : []cli.Flag {
279
330
cli.StringFlag {
280
- Name : "id" ,
331
+ Name : idName ,
281
332
Usage : "the ID of the account" ,
282
333
},
334
+ cli.StringFlag {
335
+ Name : labelName ,
336
+ Usage : "(optional) the unique label of the account" ,
337
+ },
283
338
},
284
339
Action : removeAccount ,
285
340
}
@@ -293,29 +348,59 @@ func removeAccount(ctx *cli.Context) error {
293
348
defer cleanup ()
294
349
client := litrpc .NewAccountsClient (clientConn )
295
350
296
- var accountID string
351
+ id , label , _ , err := parseIDOrLabel (ctx )
352
+ if err != nil {
353
+ return err
354
+ }
355
+
356
+ req := & litrpc.RemoveAccountRequest {
357
+ Id : id ,
358
+ Label : label ,
359
+ }
360
+ _ , err = client .RemoveAccount (ctxb , req )
361
+ return err
362
+ }
363
+
364
+ // parseIDOrLabel parses either the id or label from the command line.
365
+ func parseIDOrLabel (ctx * cli.Context ) (string , string , cli.Args , error ) {
366
+ var (
367
+ accountID string
368
+ label string
369
+ )
297
370
args := ctx .Args ()
298
371
299
372
switch {
300
- case ctx .IsSet ("id" ):
301
- accountID = ctx .String ("id" )
373
+ case ctx .IsSet (idName ) && ctx .IsSet (labelName ):
374
+ return "" , "" , nil , fmt .Errorf ("either account ID or label " +
375
+ "must be specified, not both" )
376
+
377
+ case ctx .IsSet (idName ):
378
+ accountID = ctx .String (idName )
379
+
380
+ case ctx .IsSet (labelName ):
381
+ label = ctx .String (labelName )
382
+
302
383
case args .Present ():
303
384
accountID = args .First ()
304
385
args = args .Tail ()
305
- default :
306
- return fmt .Errorf ("id argument missing" )
307
- }
308
386
309
- if len (accountID ) == 0 {
310
- return fmt .Errorf ("id argument missing" )
311
- }
312
- if _ , err := hex .DecodeString (accountID ); err != nil {
313
- return err
314
- }
387
+ // Since we have a positional argument, we cannot be sure it's
388
+ // an ID. So we check if it's an ID by trying to hex decode it
389
+ // and by checking the length. This will break if the user
390
+ // chooses labels that are also valid hex encoded IDs. But since
391
+ // the label is supposed to be human-readable, this should be
392
+ // unlikely.
393
+ _ , err := hex .DecodeString (accountID )
394
+ if len (accountID ) != hex .EncodedLen (accounts .AccountIDLen ) ||
395
+ err != nil {
396
+
397
+ label = accountID
398
+ accountID = ""
399
+ }
315
400
316
- req := & litrpc. RemoveAccountRequest {
317
- Id : accountID ,
401
+ default :
402
+ return "" , "" , nil , fmt . Errorf ( "id argument missing" )
318
403
}
319
- _ , err = client . RemoveAccount ( ctxb , req )
320
- return err
404
+
405
+ return accountID , label , args , nil
321
406
}
0 commit comments