Skip to content

Commit ac3d9c3

Browse files
committed
cmd: add --group_key CLI flag to all channel commands
1 parent bd41cfa commit ac3d9c3

File tree

1 file changed

+99
-69
lines changed

1 file changed

+99
-69
lines changed

cmd/litcli/ln.go

Lines changed: 99 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ import (
77
"encoding/hex"
88
"errors"
99
"fmt"
10-
"strconv"
1110

12-
"github.com/lightninglabs/taproot-assets/asset"
1311
"github.com/lightninglabs/taproot-assets/rfq"
1412
"github.com/lightninglabs/taproot-assets/rfqmath"
1513
"github.com/lightninglabs/taproot-assets/taprpc"
@@ -83,8 +81,16 @@ var fundChannelCommand = cli.Command{
8381
"channel.",
8482
},
8583
cli.StringFlag{
86-
Name: "asset_id",
87-
Usage: "The asset ID to commit to the channel.",
84+
Name: "asset_id",
85+
Usage: "The asset ID to commit to the channel; " +
86+
"cannot be used at the same time as " +
87+
"--group_key",
88+
},
89+
cli.StringFlag{
90+
Name: "group_key",
91+
Usage: "The group key to use for selecting assets to " +
92+
"commit to the channel; cannot be used at " +
93+
"the same time as --asset_id",
8894
},
8995
},
9096
Action: fundChannel,
@@ -106,9 +112,9 @@ func fundChannel(c *cli.Context) error {
106112
return fmt.Errorf("error fetching assets: %w", err)
107113
}
108114

109-
assetIDBytes, err := hex.DecodeString(c.String("asset_id"))
115+
assetIDBytes, groupKeyBytes, err := parseAssetIdentifier(c)
110116
if err != nil {
111-
return fmt.Errorf("error hex decoding asset ID: %w", err)
117+
return fmt.Errorf("unable to parse asset identifier: %w", err)
112118
}
113119

114120
requestedAmount := c.Uint64("asset_amount")
@@ -149,6 +155,7 @@ func fundChannel(c *cli.Context) error {
149155
ctx, &tchrpc.FundChannelRequest{
150156
AssetAmount: requestedAmount,
151157
AssetId: assetIDBytes,
158+
GroupKey: groupKeyBytes,
152159
PeerPubkey: nodePubBytes,
153160
FeeRateSatPerVbyte: uint32(c.Uint64("sat_per_vbyte")),
154161
PushSat: c.Int64("push_amt"),
@@ -167,7 +174,15 @@ var (
167174
assetIDFlag = cli.StringFlag{
168175
Name: "asset_id",
169176
Usage: "the asset ID of the asset to use when sending " +
170-
"payments with assets",
177+
"payments with assets; cannot be used at the same " +
178+
"time as --group_key",
179+
}
180+
181+
groupKeyFlag = cli.StringFlag{
182+
Name: "group_key",
183+
Usage: "the group key of the asset to use when sending " +
184+
"payments with assets; cannot be used at the same " +
185+
"time as --asset_id",
171186
}
172187

173188
assetAmountFlag = cli.Uint64Flag{
@@ -288,11 +303,12 @@ var sendPaymentCommand = cli.Command{
288303
289304
Note that this will only work in concert with the --keysend argument.
290305
`,
291-
ArgsUsage: commands.SendPaymentCommand.ArgsUsage + " --asset_id=X " +
292-
"--asset_amount=Y [--rfq_peer_pubkey=Z]",
306+
ArgsUsage: commands.SendPaymentCommand.ArgsUsage + " [--asset_id=X " +
307+
" | --group_key=X] --asset_amount=Y [--rfq_peer_pubkey=Z] " +
308+
"[--allow_overpay]",
293309
Flags: append(
294-
commands.SendPaymentCommand.Flags, assetIDFlag, assetAmountFlag,
295-
rfqPeerPubKeyFlag, allowOverpayFlag,
310+
commands.SendPaymentCommand.Flags, assetIDFlag, groupKeyFlag,
311+
assetAmountFlag, rfqPeerPubKeyFlag, allowOverpayFlag,
296312
),
297313
Action: sendPayment,
298314
}
@@ -322,18 +338,15 @@ func sendPayment(cliCtx *cli.Context) error {
322338
defer cleanup()
323339

324340
switch {
325-
case !cliCtx.IsSet(assetIDFlag.Name):
326-
return fmt.Errorf("the --asset_id flag must be set")
327341
case !cliCtx.IsSet("keysend"):
328342
return fmt.Errorf("the --keysend flag must be set")
329343
case !cliCtx.IsSet(assetAmountFlag.Name):
330344
return fmt.Errorf("--asset_amount must be set")
331345
}
332346

333-
assetIDStr := cliCtx.String(assetIDFlag.Name)
334-
assetIDBytes, err := hex.DecodeString(assetIDStr)
347+
assetIDBytes, groupKeyBytes, err := parseAssetIdentifier(cliCtx)
335348
if err != nil {
336-
return fmt.Errorf("unable to decode assetID: %v", err)
349+
return fmt.Errorf("unable to parse asset identifier: %w", err)
337350
}
338351

339352
assetAmountToSend := cliCtx.Uint64(assetAmountFlag.Name)
@@ -363,7 +376,9 @@ func sendPayment(cliCtx *cli.Context) error {
363376
"is instead: %v", len(destNode))
364377
}
365378

366-
rfqPeerKey, err := hex.DecodeString(cliCtx.String(rfqPeerPubKeyFlag.Name))
379+
rfqPeerKey, err := hex.DecodeString(
380+
cliCtx.String(rfqPeerPubKeyFlag.Name),
381+
)
367382
if err != nil {
368383
return fmt.Errorf("unable to decode RFQ peer public key: "+
369384
"%w", err)
@@ -412,6 +427,7 @@ func sendPayment(cliCtx *cli.Context) error {
412427
stream, err := tchrpcClient.SendPayment(
413428
ctx, &tchrpc.SendPaymentRequest{
414429
AssetId: assetIDBytes,
430+
GroupKey: groupKeyBytes,
415431
AssetAmount: assetAmountToSend,
416432
PeerPubkey: rfqPeerKey,
417433
PaymentRequest: req,
@@ -438,16 +454,15 @@ var payInvoiceCommand = cli.Command{
438454
source of the payment. The asset ID of the channel must be specified
439455
using the --asset_id flag.
440456
`,
441-
ArgsUsage: "pay_req --asset_id=X",
457+
ArgsUsage: "pay_req [--asset_id=X | --group_key=X] " +
458+
"[--rfq_peer_pubkey=y] [--allow_overpay]",
442459
Flags: append(commands.PaymentFlags(),
443460
cli.Int64Flag{
444461
Name: "amt",
445462
Usage: "(optional) number of satoshis to fulfill the " +
446463
"invoice",
447464
},
448-
assetIDFlag,
449-
rfqPeerPubKeyFlag,
450-
allowOverpayFlag,
465+
assetIDFlag, groupKeyFlag, rfqPeerPubKeyFlag, allowOverpayFlag,
451466
),
452467
Action: payInvoice,
453468
}
@@ -486,15 +501,9 @@ func payInvoice(cli *cli.Context) error {
486501
return err
487502
}
488503

489-
if !cli.IsSet(assetIDFlag.Name) {
490-
return fmt.Errorf("the --asset_id flag must be set")
491-
}
492-
493-
assetIDStr := cli.String(assetIDFlag.Name)
494-
495-
assetIDBytes, err := hex.DecodeString(assetIDStr)
504+
assetIDBytes, groupKeyBytes, err := parseAssetIdentifier(cli)
496505
if err != nil {
497-
return fmt.Errorf("unable to decode assetID: %v", err)
506+
return fmt.Errorf("unable to parse asset identifier: %w", err)
498507
}
499508

500509
rfqPeerKey, err := hex.DecodeString(cli.String(rfqPeerPubKeyFlag.Name))
@@ -521,6 +530,7 @@ func payInvoice(cli *cli.Context) error {
521530
stream, err := tchrpcClient.SendPayment(
522531
ctx, &tchrpc.SendPaymentRequest{
523532
AssetId: assetIDBytes,
533+
GroupKey: groupKeyBytes,
524534
PeerPubkey: rfqPeerKey,
525535
PaymentRequest: req,
526536
AllowOverpay: allowOverpay,
@@ -545,13 +555,22 @@ var addInvoiceCommand = cli.Command{
545555
Description: `
546556
Add a new invoice, expressing intent for a future payment, received in
547557
Taproot Assets.
558+
559+
This command is a shortcut for 'sendpayment --pay_req='.
548560
`,
549-
ArgsUsage: "asset_id asset_amount",
561+
ArgsUsage: "[--asset_id=X | --group_key=X] --asset_amount=Y " +
562+
"[--rfq_peer_pubkey=Z] ",
550563
Flags: append(
551564
commands.AddInvoiceCommand.Flags,
552565
cli.StringFlag{
553-
Name: "asset_id",
554-
Usage: "the asset ID of the asset to receive",
566+
Name: "asset_id",
567+
Usage: "the asset ID of the asset to receive; cannot " +
568+
"be used at the same time as --group_key",
569+
},
570+
cli.StringFlag{
571+
Name: "group_key",
572+
Usage: "the group key of the asset to receive; " +
573+
"cannot be used at the same time as --asset_id",
555574
},
556575
cli.Uint64Flag{
557576
Name: "asset_amount",
@@ -570,36 +589,15 @@ var addInvoiceCommand = cli.Command{
570589
}
571590

572591
func addInvoice(cli *cli.Context) error {
573-
args := cli.Args()
574592
ctx := getContext()
575593

576-
var assetIDStr string
577-
switch {
578-
case cli.IsSet("asset_id"):
579-
assetIDStr = cli.String("asset_id")
580-
case args.Present():
581-
assetIDStr = args.First()
582-
args = args.Tail()
583-
default:
584-
return fmt.Errorf("asset_id argument missing")
585-
}
586-
587594
var (
588-
assetAmount uint64
595+
assetAmount = cli.Uint64("asset_amount")
589596
preimage []byte
590597
descHash []byte
591598
err error
592599
)
593-
switch {
594-
case cli.IsSet("asset_amount"):
595-
assetAmount = cli.Uint64("asset_amount")
596-
case args.Present():
597-
assetAmount, err = strconv.ParseUint(args.First(), 10, 64)
598-
if err != nil {
599-
return fmt.Errorf("unable to parse asset amount %w",
600-
err)
601-
}
602-
default:
600+
if assetAmount == 0 {
603601
return fmt.Errorf("asset_amount argument missing")
604602
}
605603

@@ -620,14 +618,11 @@ func addInvoice(cli *cli.Context) error {
620618
expirySeconds = cli.Int64("expiry")
621619
}
622620

623-
assetIDBytes, err := hex.DecodeString(assetIDStr)
621+
assetIDBytes, groupKeyBytes, err := parseAssetIdentifier(cli)
624622
if err != nil {
625-
return fmt.Errorf("unable to decode assetID: %v", err)
623+
return fmt.Errorf("unable to parse asset identifier: %w", err)
626624
}
627625

628-
var assetID asset.ID
629-
copy(assetID[:], assetIDBytes)
630-
631626
rfqPeerKey, err := hex.DecodeString(cli.String(rfqPeerPubKeyFlag.Name))
632627
if err != nil {
633628
return fmt.Errorf("unable to decode RFQ peer public key: "+
@@ -643,6 +638,7 @@ func addInvoice(cli *cli.Context) error {
643638
channelsClient := tchrpc.NewTaprootAssetChannelsClient(tapdConn)
644639
resp, err := channelsClient.AddInvoice(ctx, &tchrpc.AddInvoiceRequest{
645640
AssetId: assetIDBytes,
641+
GroupKey: groupKeyBytes,
646642
AssetAmount: assetAmount,
647643
PeerPubkey: rfqPeerKey,
648644
InvoiceRequest: &lnrpc.Invoice{
@@ -678,33 +674,29 @@ var decodeAssetInvoiceCommand = cli.Command{
678674
Other information such as the decimal display of an asset, and the asset
679675
group information (if applicable) are also shown.
680676
`,
681-
ArgsUsage: "--pay_req=X --asset_id=X",
677+
ArgsUsage: "--pay_req=X [--asset_id=X | --group_key=X]",
682678
Flags: []cli.Flag{
683679
cli.StringFlag{
684680
Name: "pay_req",
685681
Usage: "a zpay32 encoded payment request to fulfill",
686682
},
687-
assetIDFlag,
683+
assetIDFlag, groupKeyFlag,
688684
},
689685
Action: decodeAssetInvoice,
690686
}
691687

692688
func decodeAssetInvoice(cli *cli.Context) error {
693689
ctx := getContext()
694690

695-
switch {
696-
case !cli.IsSet("pay_req"):
691+
if !cli.IsSet("pay_req") {
697692
return fmt.Errorf("pay_req argument missing")
698-
case !cli.IsSet(assetIDFlag.Name):
699-
return fmt.Errorf("the --asset_id flag must be set")
700693
}
701694

702695
payReq := cli.String("pay_req")
703696

704-
assetIDStr := cli.String(assetIDFlag.Name)
705-
assetIDBytes, err := hex.DecodeString(assetIDStr)
697+
assetIDBytes, groupKeyBytes, err := parseAssetIdentifier(cli)
706698
if err != nil {
707-
return fmt.Errorf("unable to decode assetID: %v", err)
699+
return fmt.Errorf("unable to parse asset identifier: %w", err)
708700
}
709701

710702
tapdConn, cleanup, err := connectSuperMacClient(ctx, cli)
@@ -716,6 +708,7 @@ func decodeAssetInvoice(cli *cli.Context) error {
716708
channelsClient := tchrpc.NewTaprootAssetChannelsClient(tapdConn)
717709
resp, err := channelsClient.DecodeAssetPayReq(ctx, &tchrpc.AssetPayReq{
718710
AssetId: assetIDBytes,
711+
GroupKey: groupKeyBytes,
719712
PayReqString: payReq,
720713
})
721714
if err != nil {
@@ -726,3 +719,40 @@ func decodeAssetInvoice(cli *cli.Context) error {
726719

727720
return nil
728721
}
722+
723+
// parseAssetIdentifier parses either the asset ID or group key from the command
724+
// line arguments.
725+
func parseAssetIdentifier(cli *cli.Context) ([]byte, []byte, error) {
726+
if !cli.IsSet(assetIDFlag.Name) && !cli.IsSet(groupKeyFlag.Name) {
727+
return nil, nil, fmt.Errorf("either the --asset_id or " +
728+
"--group_key flag must be set")
729+
}
730+
731+
var (
732+
assetIDBytes []byte
733+
groupKeyBytes []byte
734+
err error
735+
)
736+
if cli.IsSet("asset_id") {
737+
assetIDBytes, err = hex.DecodeString(cli.String("asset_id"))
738+
if err != nil {
739+
return nil, nil, fmt.Errorf("error hex decoding asset "+
740+
"ID: %w", err)
741+
}
742+
}
743+
744+
if cli.IsSet("group_key") {
745+
groupKeyBytes, err = hex.DecodeString(cli.String("group_key"))
746+
if err != nil {
747+
return nil, nil, fmt.Errorf("error hex decoding group "+
748+
"key: %w", err)
749+
}
750+
}
751+
752+
if len(assetIDBytes) == 0 && len(groupKeyBytes) == 0 {
753+
return nil, nil, fmt.Errorf("only one of --asset_id and " +
754+
"--group_key can be set")
755+
}
756+
757+
return assetIDBytes, groupKeyBytes, nil
758+
}

0 commit comments

Comments
 (0)