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 ,
@@ -437,17 +453,18 @@ var payInvoiceCommand = cli.Command{
437453 This command attempts to pay an invoice using an asset channel as the
438454 source of the payment. The asset ID of the channel must be specified
439455 using the --asset_id flag.
456+
457+ This command is a shortcut for 'sendpayment --pay_req='.
440458 ` ,
441- ArgsUsage : "pay_req --asset_id=X" ,
459+ ArgsUsage : "pay_req [--asset_id=X | --group_key=X] " +
460+ "[--rfq_peer_pubkey=y] [--allow_overpay]" ,
442461 Flags : append (commands .PaymentFlags (),
443462 cli.Int64Flag {
444463 Name : "amt" ,
445464 Usage : "(optional) number of satoshis to fulfill the " +
446465 "invoice" ,
447466 },
448- assetIDFlag ,
449- rfqPeerPubKeyFlag ,
450- allowOverpayFlag ,
467+ assetIDFlag , groupKeyFlag , rfqPeerPubKeyFlag , allowOverpayFlag ,
451468 ),
452469 Action : payInvoice ,
453470}
@@ -486,15 +503,9 @@ func payInvoice(cli *cli.Context) error {
486503 return err
487504 }
488505
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 )
506+ assetIDBytes , groupKeyBytes , err := parseAssetIdentifier (cli )
496507 if err != nil {
497- return fmt .Errorf ("unable to decode assetID : %v " , err )
508+ return fmt .Errorf ("unable to parse asset identifier : %w " , err )
498509 }
499510
500511 rfqPeerKey , err := hex .DecodeString (cli .String (rfqPeerPubKeyFlag .Name ))
@@ -521,6 +532,7 @@ func payInvoice(cli *cli.Context) error {
521532 stream , err := tchrpcClient .SendPayment (
522533 ctx , & tchrpc.SendPaymentRequest {
523534 AssetId : assetIDBytes ,
535+ GroupKey : groupKeyBytes ,
524536 PeerPubkey : rfqPeerKey ,
525537 PaymentRequest : req ,
526538 AllowOverpay : allowOverpay ,
@@ -546,12 +558,19 @@ var addInvoiceCommand = cli.Command{
546558 Add a new invoice, expressing intent for a future payment, received in
547559 Taproot Assets.
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
572591func 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
692688func 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