litcli: use cancellable contexts

In this commit, we use the signal.Interceptor to cancel the contexts we
use for our CLI calls.
This commit is contained in:
Elle Mouton 2025-01-13 09:07:30 +02:00
parent 0407505e6c
commit 76250ca835
No known key found for this signature in database
GPG key ID: D7D916376026F177
9 changed files with 236 additions and 218 deletions

View file

@ -1,7 +1,6 @@
package main
import (
"context"
"encoding/hex"
"fmt"
"os"
@ -75,9 +74,9 @@ spend that amount.`,
Action: createAccount,
}
func createAccount(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func createAccount(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
@ -88,11 +87,11 @@ func createAccount(ctx *cli.Context) error {
initialBalance uint64
expirationDate int64
)
args := ctx.Args()
args := cli.Args()
switch {
case ctx.IsSet("balance"):
initialBalance = ctx.Uint64("balance")
case cli.IsSet("balance"):
initialBalance = cli.Uint64("balance")
case args.Present():
initialBalance, err = strconv.ParseUint(args.First(), 10, 64)
if err != nil {
@ -102,8 +101,8 @@ func createAccount(ctx *cli.Context) error {
}
switch {
case ctx.IsSet("expiration_date"):
expirationDate = ctx.Int64("expiration_date")
case cli.IsSet("expiration_date"):
expirationDate = cli.Int64("expiration_date")
case args.Present():
expirationDate, err = strconv.ParseInt(args.First(), 10, 64)
if err != nil {
@ -117,9 +116,9 @@ func createAccount(ctx *cli.Context) error {
req := &litrpc.CreateAccountRequest{
AccountBalance: initialBalance,
ExpirationDate: expirationDate,
Label: ctx.String(labelName),
Label: cli.String(labelName),
}
resp, err := client.CreateAccount(ctxb, req)
resp, err := client.CreateAccount(ctx, req)
if err != nil {
return err
}
@ -128,8 +127,8 @@ func createAccount(ctx *cli.Context) error {
// User requested to store the newly baked account macaroon to a file
// in addition to printing it to the console.
if ctx.IsSet("save_to") {
fileName := lncfg.CleanAndExpandPath(ctx.String("save_to"))
if cli.IsSet("save_to") {
fileName := lncfg.CleanAndExpandPath(cli.String("save_to"))
err := os.WriteFile(fileName, resp.Macaroon, 0644)
if err != nil {
return fmt.Errorf("error writing account macaroon "+
@ -176,16 +175,16 @@ var updateAccountCommand = cli.Command{
Action: updateAccount,
}
func updateAccount(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func updateAccount(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewAccountsClient(clientConn)
id, label, args, err := parseIDOrLabel(ctx)
id, label, args, err := parseIDOrLabel(cli)
if err != nil {
return err
}
@ -195,8 +194,8 @@ func updateAccount(ctx *cli.Context) error {
expirationDate int64
)
switch {
case ctx.IsSet("new_balance"):
newBalance = ctx.Int64("new_balance")
case cli.IsSet("new_balance"):
newBalance = cli.Int64("new_balance")
case args.Present():
newBalance, err = strconv.ParseInt(args.First(), 10, 64)
if err != nil {
@ -206,8 +205,8 @@ func updateAccount(ctx *cli.Context) error {
}
switch {
case ctx.IsSet("new_expiration_date"):
expirationDate = ctx.Int64("new_expiration_date")
case cli.IsSet("new_expiration_date"):
expirationDate = cli.Int64("new_expiration_date")
case args.Present():
expirationDate, err = strconv.ParseInt(args.First(), 10, 64)
if err != nil {
@ -224,7 +223,7 @@ func updateAccount(ctx *cli.Context) error {
AccountBalance: newBalance,
ExpirationDate: expirationDate,
}
resp, err := client.UpdateAccount(ctxb, req)
resp, err := client.UpdateAccount(ctx, req)
if err != nil {
return err
}
@ -242,9 +241,9 @@ var listAccountsCommand = cli.Command{
Action: listAccounts,
}
func listAccounts(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func listAccounts(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
@ -252,7 +251,7 @@ func listAccounts(ctx *cli.Context) error {
client := litrpc.NewAccountsClient(clientConn)
req := &litrpc.ListAccountsRequest{}
resp, err := client.ListAccounts(ctxb, req)
resp, err := client.ListAccounts(ctx, req)
if err != nil {
return err
}
@ -281,16 +280,16 @@ var accountInfoCommand = cli.Command{
Action: accountInfo,
}
func accountInfo(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func accountInfo(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewAccountsClient(clientConn)
id, label, _, err := parseIDOrLabel(ctx)
id, label, _, err := parseIDOrLabel(cli)
if err != nil {
return err
}
@ -299,7 +298,7 @@ func accountInfo(ctx *cli.Context) error {
Id: id,
Label: label,
}
resp, err := client.AccountInfo(ctxb, req)
resp, err := client.AccountInfo(ctx, req)
if err != nil {
return err
}
@ -327,16 +326,16 @@ var removeAccountCommand = cli.Command{
Action: removeAccount,
}
func removeAccount(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func removeAccount(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewAccountsClient(clientConn)
id, label, _, err := parseIDOrLabel(ctx)
id, label, _, err := parseIDOrLabel(cli)
if err != nil {
return err
}
@ -345,7 +344,7 @@ func removeAccount(ctx *cli.Context) error {
Id: id,
Label: label,
}
_, err = client.RemoveAccount(ctxb, req)
_, err = client.RemoveAccount(ctx, req)
return err
}

View file

@ -1,7 +1,6 @@
package main
import (
"context"
"encoding/hex"
"fmt"
@ -98,49 +97,49 @@ var listActionsCommand = cli.Command{
},
}
func listActions(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func listActions(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewFirewallClient(clientConn)
state, err := parseActionState(ctx.String("state"))
state, err := parseActionState(cli.String("state"))
if err != nil {
return err
}
var sessionID []byte
if ctx.String("session_id") != "" {
sessionID, err = hex.DecodeString(ctx.String("session_id"))
if cli.String("session_id") != "" {
sessionID, err = hex.DecodeString(cli.String("session_id"))
if err != nil {
return err
}
}
var groupID []byte
if ctx.String("group_id") != "" {
groupID, err = hex.DecodeString(ctx.String("group_id"))
if cli.String("group_id") != "" {
groupID, err = hex.DecodeString(cli.String("group_id"))
if err != nil {
return err
}
}
resp, err := client.ListActions(
ctxb, &litrpc.ListActionsRequest{
ctx, &litrpc.ListActionsRequest{
SessionId: sessionID,
FeatureName: ctx.String("feature"),
ActorName: ctx.String("actor"),
MethodName: ctx.String("method"),
FeatureName: cli.String("feature"),
ActorName: cli.String("actor"),
MethodName: cli.String("method"),
State: state,
IndexOffset: ctx.Uint64("index_offset"),
MaxNumActions: ctx.Uint64("max_num_actions"),
Reversed: !ctx.Bool("oldest_first"),
CountTotal: ctx.Bool("count_total"),
StartTimestamp: ctx.Uint64("start_timestamp"),
EndTimestamp: ctx.Uint64("end_timestamp"),
IndexOffset: cli.Uint64("index_offset"),
MaxNumActions: cli.Uint64("max_num_actions"),
Reversed: !cli.Bool("oldest_first"),
CountTotal: cli.Bool("count_total"),
StartTimestamp: cli.Uint64("start_timestamp"),
EndTimestamp: cli.Uint64("end_timestamp"),
GroupId: groupID,
},
)

View file

@ -1,7 +1,6 @@
package main
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
@ -180,22 +179,22 @@ var listAutopilotSessionsCmd = cli.Command{
Action: listAutopilotSessions,
}
func revokeAutopilotSession(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func revokeAutopilotSession(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewAutopilotClient(clientConn)
pubkey, err := hex.DecodeString(ctx.String("localpubkey"))
pubkey, err := hex.DecodeString(cli.String("localpubkey"))
if err != nil {
return err
}
resp, err := client.RevokeAutopilotSession(
ctxb, &litrpc.RevokeAutopilotSessionRequest{
ctx, &litrpc.RevokeAutopilotSessionRequest{
LocalPublicKey: pubkey,
},
)
@ -208,9 +207,9 @@ func revokeAutopilotSession(ctx *cli.Context) error {
return nil
}
func listAutopilotSessions(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func listAutopilotSessions(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
@ -218,7 +217,7 @@ func listAutopilotSessions(ctx *cli.Context) error {
client := litrpc.NewAutopilotClient(clientConn)
resp, err := client.ListAutopilotSessions(
ctxb, &litrpc.ListAutopilotSessionsRequest{},
ctx, &litrpc.ListAutopilotSessionsRequest{},
)
if err != nil {
return err
@ -229,9 +228,9 @@ func listAutopilotSessions(ctx *cli.Context) error {
return nil
}
func listFeatures(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func listFeatures(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
@ -239,7 +238,7 @@ func listFeatures(ctx *cli.Context) error {
client := litrpc.NewAutopilotClient(clientConn)
resp, err := client.ListAutopilotFeatures(
ctxb, &litrpc.ListAutopilotFeaturesRequest{},
ctx, &litrpc.ListAutopilotFeaturesRequest{},
)
if err != nil {
return err
@ -250,19 +249,19 @@ func listFeatures(ctx *cli.Context) error {
return nil
}
func initAutopilotSession(ctx *cli.Context) error {
sessionLength := time.Second * time.Duration(ctx.Uint64("expiry"))
func initAutopilotSession(cli *cli.Context) error {
sessionLength := time.Second * time.Duration(cli.Uint64("expiry"))
sessionExpiry := time.Now().Add(sessionLength).Unix()
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewAutopilotClient(clientConn)
features := ctx.StringSlice("feature")
features := cli.StringSlice("feature")
// Check that the user only sets unique features.
fs := make(map[string]struct{})
@ -277,14 +276,14 @@ func initAutopilotSession(ctx *cli.Context) error {
// Check that the user did not set multiple restrict lists.
var chanRestrictList, peerRestrictList string
channelRestrictSlice := ctx.StringSlice("channel-restrict-list")
channelRestrictSlice := cli.StringSlice("channel-restrict-list")
if len(channelRestrictSlice) > 1 {
return fmt.Errorf("channel-restrict-list can only be used once")
} else if len(channelRestrictSlice) == 1 {
chanRestrictList = channelRestrictSlice[0]
}
peerRestrictSlice := ctx.StringSlice("peer-restrict-list")
peerRestrictSlice := cli.StringSlice("peer-restrict-list")
if len(peerRestrictSlice) > 1 {
return fmt.Errorf("peer-restrict-list can only be used once")
} else if len(peerRestrictSlice) == 1 {
@ -293,7 +292,7 @@ func initAutopilotSession(ctx *cli.Context) error {
// rulesMap stores the rules per each feature.
rulesMap := make(map[string]*litrpc.RulesMap)
rulesFlags := ctx.StringSlice("feature-rules")
rulesFlags := cli.StringSlice("feature-rules")
// For legacy flags, we allow setting the channel and peer restrict
// lists when only a single feature is added.
@ -379,7 +378,7 @@ func initAutopilotSession(ctx *cli.Context) error {
}
}
configs := ctx.StringSlice("feature-config")
configs := cli.StringSlice("feature-config")
if len(configs) > 0 && len(features) != len(configs) {
return fmt.Errorf("number of features (%v) and configurations "+
"(%v) must match", len(features), len(configs))
@ -420,8 +419,8 @@ func initAutopilotSession(ctx *cli.Context) error {
}
var groupID []byte
if ctx.IsSet("group_id") {
groupID, err = hex.DecodeString(ctx.String("group_id"))
if cli.IsSet("group_id") {
groupID, err = hex.DecodeString(cli.String("group_id"))
if err != nil {
return err
}
@ -429,10 +428,10 @@ func initAutopilotSession(ctx *cli.Context) error {
var privacyFlags uint64
var privacyFlagsSet bool
if ctx.IsSet("privacy-flags") {
if cli.IsSet("privacy-flags") {
privacyFlagsSet = true
flags, err := session.Parse(ctx.String("privacy-flags"))
flags, err := session.Parse(cli.String("privacy-flags"))
if err != nil {
return err
}
@ -441,11 +440,11 @@ func initAutopilotSession(ctx *cli.Context) error {
}
resp, err := client.AddAutopilotSession(
ctxb, &litrpc.AddAutopilotSessionRequest{
Label: ctx.String("label"),
ctx, &litrpc.AddAutopilotSessionRequest{
Label: cli.String("label"),
ExpiryTimestampSeconds: uint64(sessionExpiry),
MailboxServerAddr: ctx.String("mailboxserveraddr"),
DevServer: ctx.Bool("devserver"),
MailboxServerAddr: cli.String("mailboxserveraddr"),
DevServer: cli.Bool("devserver"),
Features: featureMap,
LinkedGroupId: groupID,
PrivacyFlags: privacyFlags,

View file

@ -91,17 +91,17 @@ var fundChannelCommand = cli.Command{
}
func fundChannel(c *cli.Context) error {
tapdConn, cleanup, err := connectSuperMacClient(c)
ctx := getContext()
tapdConn, cleanup, err := connectSuperMacClient(ctx, c)
if err != nil {
return fmt.Errorf("error creating tapd connection: %w", err)
}
defer cleanup()
ctxb := context.Background()
tapdClient := taprpc.NewTaprootAssetsClient(tapdConn)
tchrpcClient := tchrpc.NewTaprootAssetChannelsClient(tapdConn)
assets, err := tapdClient.ListAssets(ctxb, &taprpc.ListAssetRequest{})
assets, err := tapdClient.ListAssets(ctx, &taprpc.ListAssetRequest{})
if err != nil {
return fmt.Errorf("error fetching assets: %w", err)
}
@ -146,7 +146,7 @@ func fundChannel(c *cli.Context) error {
}
resp, err := tchrpcClient.FundChannel(
ctxb, &tchrpc.FundChannelRequest{
ctx, &tchrpc.FundChannelRequest{
AssetAmount: requestedAmount,
AssetId: assetIDBytes,
PeerPubkey: nodePubBytes,
@ -297,41 +297,46 @@ var sendPaymentCommand = cli.Command{
Action: sendPayment,
}
func sendPayment(ctx *cli.Context) error {
func sendPayment(cliCtx *cli.Context) error {
// Show command help if no arguments provided
if ctx.NArg() == 0 && ctx.NumFlags() == 0 {
_ = cli.ShowCommandHelp(ctx, "sendpayment")
if cliCtx.NArg() == 0 && cliCtx.NumFlags() == 0 {
_ = cli.ShowCommandHelp(cliCtx, "sendpayment")
return nil
}
lndConn, cleanup, err := connectClient(ctx, false)
lndConn, cleanup, err := connectClient(cliCtx, false)
if err != nil {
return fmt.Errorf("unable to make rpc conn: %w", err)
}
defer cleanup()
tapdConn, cleanup, err := connectSuperMacClient(ctx)
// NOTE: we don't use `getContext()` here since it assigns the global
// signal interceptor variable which will then cause
// commands.SendPaymentRequest to error out since it will try to do the
// same.
ctx := context.Background()
tapdConn, cleanup, err := connectSuperMacClient(ctx, cliCtx)
if err != nil {
return fmt.Errorf("error creating tapd connection: %w", err)
}
defer cleanup()
switch {
case !ctx.IsSet(assetIDFlag.Name):
case !cliCtx.IsSet(assetIDFlag.Name):
return fmt.Errorf("the --asset_id flag must be set")
case !ctx.IsSet("keysend"):
case !cliCtx.IsSet("keysend"):
return fmt.Errorf("the --keysend flag must be set")
case !ctx.IsSet(assetAmountFlag.Name):
case !cliCtx.IsSet(assetAmountFlag.Name):
return fmt.Errorf("--asset_amount must be set")
}
assetIDStr := ctx.String(assetIDFlag.Name)
assetIDStr := cliCtx.String(assetIDFlag.Name)
assetIDBytes, err := hex.DecodeString(assetIDStr)
if err != nil {
return fmt.Errorf("unable to decode assetID: %v", err)
}
assetAmountToSend := ctx.Uint64(assetAmountFlag.Name)
assetAmountToSend := cliCtx.Uint64(assetAmountFlag.Name)
if assetAmountToSend == 0 {
return fmt.Errorf("must specify asset amount to send")
}
@ -344,8 +349,8 @@ func sendPayment(ctx *cli.Context) error {
)
switch {
case ctx.IsSet("dest"):
destNode, err = hex.DecodeString(ctx.String("dest"))
case cliCtx.IsSet("dest"):
destNode, err = hex.DecodeString(cliCtx.String("dest"))
default:
return fmt.Errorf("destination txid argument missing")
}
@ -358,7 +363,7 @@ func sendPayment(ctx *cli.Context) error {
"is instead: %v", len(destNode))
}
rfqPeerKey, err := hex.DecodeString(ctx.String(rfqPeerPubKeyFlag.Name))
rfqPeerKey, err := hex.DecodeString(cliCtx.String(rfqPeerPubKeyFlag.Name))
if err != nil {
return fmt.Errorf("unable to decode RFQ peer public key: "+
"%w", err)
@ -373,7 +378,7 @@ func sendPayment(ctx *cli.Context) error {
DestCustomRecords: make(map[uint64][]byte),
}
if ctx.IsSet("payment_hash") {
if cliCtx.IsSet("payment_hash") {
return errors.New("cannot set payment hash when using " +
"keysend")
}
@ -392,10 +397,10 @@ func sendPayment(ctx *cli.Context) error {
rHash = hash[:]
req.PaymentHash = rHash
allowOverpay := ctx.Bool(allowOverpayFlag.Name)
allowOverpay := cliCtx.Bool(allowOverpayFlag.Name)
return commands.SendPaymentRequest(
ctx, req, lndConn, tapdConn, func(ctx context.Context,
cliCtx, req, lndConn, tapdConn, func(ctx context.Context,
payConn grpc.ClientConnInterface,
req *routerrpc.SendPaymentRequest) (
commands.PaymentResultStream, error) {
@ -447,21 +452,26 @@ var payInvoiceCommand = cli.Command{
Action: payInvoice,
}
func payInvoice(ctx *cli.Context) error {
args := ctx.Args()
ctxb := context.Background()
func payInvoice(cli *cli.Context) error {
args := cli.Args()
// NOTE: we don't use `getContext()` here since it assigns the global
// signal interceptor variable which will then cause
// commands.SendPaymentRequest to error out since it will try to do the
// same.
ctx := context.Background()
var payReq string
switch {
case ctx.IsSet("pay_req"):
payReq = ctx.String("pay_req")
case cli.IsSet("pay_req"):
payReq = cli.String("pay_req")
case args.Present():
payReq = args.First()
default:
return fmt.Errorf("pay_req argument missing")
}
superMacConn, cleanup, err := connectSuperMacClient(ctx)
superMacConn, cleanup, err := connectSuperMacClient(ctx, cli)
if err != nil {
return fmt.Errorf("unable to make rpc con: %w", err)
}
@ -471,35 +481,35 @@ func payInvoice(ctx *cli.Context) error {
lndClient := lnrpc.NewLightningClient(superMacConn)
decodeReq := &lnrpc.PayReqString{PayReq: payReq}
decodeResp, err := lndClient.DecodePayReq(ctxb, decodeReq)
decodeResp, err := lndClient.DecodePayReq(ctx, decodeReq)
if err != nil {
return err
}
if !ctx.IsSet(assetIDFlag.Name) {
if !cli.IsSet(assetIDFlag.Name) {
return fmt.Errorf("the --asset_id flag must be set")
}
assetIDStr := ctx.String(assetIDFlag.Name)
assetIDStr := cli.String(assetIDFlag.Name)
assetIDBytes, err := hex.DecodeString(assetIDStr)
if err != nil {
return fmt.Errorf("unable to decode assetID: %v", err)
}
rfqPeerKey, err := hex.DecodeString(ctx.String(rfqPeerPubKeyFlag.Name))
rfqPeerKey, err := hex.DecodeString(cli.String(rfqPeerPubKeyFlag.Name))
if err != nil {
return fmt.Errorf("unable to decode RFQ peer public key: "+
"%w", err)
}
allowOverpay := ctx.Bool(allowOverpayFlag.Name)
allowOverpay := cli.Bool(allowOverpayFlag.Name)
req := &routerrpc.SendPaymentRequest{
PaymentRequest: commands.StripPrefix(payReq),
}
return commands.SendPaymentRequest(
ctx, req, superMacConn, superMacConn, func(ctx context.Context,
cli, req, superMacConn, superMacConn, func(ctx context.Context,
payConn grpc.ClientConnInterface,
req *routerrpc.SendPaymentRequest) (
commands.PaymentResultStream, error) {
@ -559,14 +569,14 @@ var addInvoiceCommand = cli.Command{
Action: addInvoice,
}
func addInvoice(ctx *cli.Context) error {
args := ctx.Args()
ctxb := context.Background()
func addInvoice(cli *cli.Context) error {
args := cli.Args()
ctx := getContext()
var assetIDStr string
switch {
case ctx.IsSet("asset_id"):
assetIDStr = ctx.String("asset_id")
case cli.IsSet("asset_id"):
assetIDStr = cli.String("asset_id")
case args.Present():
assetIDStr = args.First()
args = args.Tail()
@ -581,8 +591,8 @@ func addInvoice(ctx *cli.Context) error {
err error
)
switch {
case ctx.IsSet("asset_amount"):
assetAmount = ctx.Uint64("asset_amount")
case cli.IsSet("asset_amount"):
assetAmount = cli.Uint64("asset_amount")
case args.Present():
assetAmount, err = strconv.ParseUint(args.First(), 10, 64)
if err != nil {
@ -593,21 +603,21 @@ func addInvoice(ctx *cli.Context) error {
return fmt.Errorf("asset_amount argument missing")
}
if ctx.IsSet("preimage") {
preimage, err = hex.DecodeString(ctx.String("preimage"))
if cli.IsSet("preimage") {
preimage, err = hex.DecodeString(cli.String("preimage"))
if err != nil {
return fmt.Errorf("unable to parse preimage: %w", err)
}
}
descHash, err = hex.DecodeString(ctx.String("description_hash"))
descHash, err = hex.DecodeString(cli.String("description_hash"))
if err != nil {
return fmt.Errorf("unable to parse description_hash: %w", err)
}
expirySeconds := int64(rfq.DefaultInvoiceExpiry.Seconds())
if ctx.IsSet("expiry") {
expirySeconds = ctx.Int64("expiry")
if cli.IsSet("expiry") {
expirySeconds = cli.Int64("expiry")
}
assetIDBytes, err := hex.DecodeString(assetIDStr)
@ -618,31 +628,31 @@ func addInvoice(ctx *cli.Context) error {
var assetID asset.ID
copy(assetID[:], assetIDBytes)
rfqPeerKey, err := hex.DecodeString(ctx.String(rfqPeerPubKeyFlag.Name))
rfqPeerKey, err := hex.DecodeString(cli.String(rfqPeerPubKeyFlag.Name))
if err != nil {
return fmt.Errorf("unable to decode RFQ peer public key: "+
"%w", err)
}
tapdConn, cleanup, err := connectSuperMacClient(ctx)
tapdConn, cleanup, err := connectSuperMacClient(ctx, cli)
if err != nil {
return fmt.Errorf("error creating tapd connection: %w", err)
}
defer cleanup()
channelsClient := tchrpc.NewTaprootAssetChannelsClient(tapdConn)
resp, err := channelsClient.AddInvoice(ctxb, &tchrpc.AddInvoiceRequest{
resp, err := channelsClient.AddInvoice(ctx, &tchrpc.AddInvoiceRequest{
AssetId: assetIDBytes,
AssetAmount: assetAmount,
PeerPubkey: rfqPeerKey,
InvoiceRequest: &lnrpc.Invoice{
Memo: ctx.String("memo"),
Memo: cli.String("memo"),
RPreimage: preimage,
DescriptionHash: descHash,
FallbackAddr: ctx.String("fallback_addr"),
FallbackAddr: cli.String("fallback_addr"),
Expiry: expirySeconds,
Private: ctx.Bool("private"),
IsAmp: ctx.Bool("amp"),
Private: cli.Bool("private"),
IsAmp: cli.Bool("amp"),
},
})
if err != nil {
@ -679,32 +689,32 @@ var decodeAssetInvoiceCommand = cli.Command{
Action: decodeAssetInvoice,
}
func decodeAssetInvoice(ctx *cli.Context) error {
ctxb := context.Background()
func decodeAssetInvoice(cli *cli.Context) error {
ctx := getContext()
switch {
case !ctx.IsSet("pay_req"):
case !cli.IsSet("pay_req"):
return fmt.Errorf("pay_req argument missing")
case !ctx.IsSet(assetIDFlag.Name):
case !cli.IsSet(assetIDFlag.Name):
return fmt.Errorf("the --asset_id flag must be set")
}
payReq := ctx.String("pay_req")
payReq := cli.String("pay_req")
assetIDStr := ctx.String(assetIDFlag.Name)
assetIDStr := cli.String(assetIDFlag.Name)
assetIDBytes, err := hex.DecodeString(assetIDStr)
if err != nil {
return fmt.Errorf("unable to decode assetID: %v", err)
}
tapdConn, cleanup, err := connectSuperMacClient(ctx)
tapdConn, cleanup, err := connectSuperMacClient(ctx, cli)
if err != nil {
return fmt.Errorf("unable to make rpc con: %w", err)
}
defer cleanup()
channelsClient := tchrpc.NewTaprootAssetChannelsClient(tapdConn)
resp, err := channelsClient.DecodeAssetPayReq(ctxb, &tchrpc.AssetPayReq{
resp, err := channelsClient.DecodeAssetPayReq(ctx, &tchrpc.AssetPayReq{
AssetId: assetIDBytes,
PayReqString: payReq,
})

View file

@ -15,6 +15,7 @@ import (
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/macaroons"
"github.com/lightningnetwork/lnd/signal"
"github.com/urfave/cli"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
@ -299,19 +300,18 @@ func printRespJSON(resp proto.Message) { // nolint
fmt.Println(string(jsonBytes))
}
func connectSuperMacClient(ctx *cli.Context) (grpc.ClientConnInterface,
func(), error) {
func connectSuperMacClient(ctx context.Context, cli *cli.Context) (
grpc.ClientConnInterface, func(), error) {
litdConn, cleanup, err := connectClient(ctx, false)
litdConn, cleanup, err := connectClient(cli, false)
if err != nil {
return nil, nil, fmt.Errorf("error connecting client: %w", err)
}
defer cleanup()
ctxb := context.Background()
litClient := litrpc.NewProxyClient(litdConn)
macResp, err := litClient.BakeSuperMacaroon(
ctxb, &litrpc.BakeSuperMacaroonRequest{},
ctx, &litrpc.BakeSuperMacaroonRequest{},
)
if err != nil {
return nil, nil, fmt.Errorf("error baking macaroon: %w", err)
@ -322,5 +322,21 @@ func connectSuperMacClient(ctx *cli.Context) (grpc.ClientConnInterface,
return nil, nil, fmt.Errorf("error decoding macaroon: %w", err)
}
return connectClientWithMac(ctx, macBytes)
return connectClientWithMac(cli, macBytes)
}
func getContext() context.Context {
shutdownInterceptor, err := signal.Intercept()
if err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
ctxc, cancel := context.WithCancel(context.Background())
go func() {
<-shutdownInterceptor.ShutdownChannel()
cancel()
}()
return ctxc
}

View file

@ -1,7 +1,6 @@
package main
import (
"context"
"encoding/hex"
"fmt"
@ -63,9 +62,9 @@ var privacyMapConvertStrCommand = cli.Command{
},
}
func privacyMapConvertStr(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func privacyMapConvertStr(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
@ -73,13 +72,13 @@ func privacyMapConvertStr(ctx *cli.Context) error {
client := litrpc.NewFirewallClient(clientConn)
var groupID []byte
if ctx.GlobalIsSet("group_id") {
groupID, err = hex.DecodeString(ctx.GlobalString("group_id"))
if cli.GlobalIsSet("group_id") {
groupID, err = hex.DecodeString(cli.GlobalString("group_id"))
if err != nil {
return err
}
} else if ctx.GlobalIsSet("session_id") {
groupID, err = hex.DecodeString(ctx.GlobalString("session_id"))
} else if cli.GlobalIsSet("session_id") {
groupID, err = hex.DecodeString(cli.GlobalString("session_id"))
if err != nil {
return err
}
@ -88,9 +87,9 @@ func privacyMapConvertStr(ctx *cli.Context) error {
}
resp, err := client.PrivacyMapConversion(
ctxb, &litrpc.PrivacyMapConversionRequest{
RealToPseudo: ctx.GlobalBool("realtopseudo"),
Input: ctx.String("input"),
ctx, &litrpc.PrivacyMapConversionRequest{
RealToPseudo: cli.GlobalBool("realtopseudo"),
Input: cli.String("input"),
GroupId: groupID,
},
)
@ -117,9 +116,9 @@ var privacyMapConvertUint64Command = cli.Command{
},
}
func privacyMapConvertUint64(ctx *cli.Context) error {
ctxb := context.Background()
clientConn, cleanup, err := connectClient(ctx, false)
func privacyMapConvertUint64(cli *cli.Context) error {
ctx := getContext()
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
@ -127,13 +126,13 @@ func privacyMapConvertUint64(ctx *cli.Context) error {
client := litrpc.NewFirewallClient(clientConn)
var groupID []byte
if ctx.GlobalIsSet("group_id") {
groupID, err = hex.DecodeString(ctx.GlobalString("group_id"))
if cli.GlobalIsSet("group_id") {
groupID, err = hex.DecodeString(cli.GlobalString("group_id"))
if err != nil {
return err
}
} else if ctx.GlobalIsSet("session_id") {
groupID, err = hex.DecodeString(ctx.GlobalString("session_id"))
} else if cli.GlobalIsSet("session_id") {
groupID, err = hex.DecodeString(cli.GlobalString("session_id"))
if err != nil {
return err
}
@ -141,11 +140,11 @@ func privacyMapConvertUint64(ctx *cli.Context) error {
return fmt.Errorf("must set group_id")
}
input := firewalldb.Uint64ToStr(ctx.Uint64("input"))
input := firewalldb.Uint64ToStr(cli.Uint64("input"))
resp, err := client.PrivacyMapConversion(
ctxb, &litrpc.PrivacyMapConversionRequest{
RealToPseudo: ctx.GlobalBool("realtopseudo"),
ctx, &litrpc.PrivacyMapConversionRequest{
RealToPseudo: cli.GlobalBool("realtopseudo"),
Input: input,
GroupId: groupID,
},

View file

@ -1,7 +1,6 @@
package main
import (
"context"
"crypto/rand"
"encoding/binary"
"encoding/hex"
@ -62,16 +61,16 @@ var litCommands = []cli.Command{
},
}
func getInfo(ctx *cli.Context) error {
clientConn, cleanup, err := connectClient(ctx, false)
func getInfo(cli *cli.Context) error {
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewProxyClient(clientConn)
ctxb := context.Background()
resp, err := client.GetInfo(ctxb, &litrpc.GetInfoRequest{})
ctx := getContext()
resp, err := client.GetInfo(ctx, &litrpc.GetInfoRequest{})
if err != nil {
return err
}
@ -81,16 +80,16 @@ func getInfo(ctx *cli.Context) error {
return nil
}
func shutdownLit(ctx *cli.Context) error {
clientConn, cleanup, err := connectClient(ctx, false)
func shutdownLit(cli *cli.Context) error {
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewProxyClient(clientConn)
ctxb := context.Background()
_, err = client.StopDaemon(ctxb, &litrpc.StopDaemonRequest{})
ctx := getContext()
_, err = client.StopDaemon(ctx, &litrpc.StopDaemonRequest{})
if err != nil {
return err
}
@ -100,11 +99,11 @@ func shutdownLit(ctx *cli.Context) error {
return nil
}
func bakeSuperMacaroon(ctx *cli.Context) error {
func bakeSuperMacaroon(cli *cli.Context) error {
var suffixBytes [4]byte
if ctx.IsSet("root_key_suffix") {
if cli.IsSet("root_key_suffix") {
suffixHex, err := hex.DecodeString(
ctx.String("root_key_suffix"),
cli.String("root_key_suffix"),
)
if err != nil {
return err
@ -119,18 +118,18 @@ func bakeSuperMacaroon(ctx *cli.Context) error {
}
suffix := binary.BigEndian.Uint32(suffixBytes[:])
clientConn, cleanup, err := connectClient(ctx, false)
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewProxyClient(clientConn)
ctxb := context.Background()
ctx := getContext()
resp, err := client.BakeSuperMacaroon(
ctxb, &litrpc.BakeSuperMacaroonRequest{
ctx, &litrpc.BakeSuperMacaroonRequest{
RootKeyIdSuffix: suffix,
ReadOnly: ctx.Bool("read_only"),
ReadOnly: cli.Bool("read_only"),
},
)
if err != nil {
@ -139,8 +138,8 @@ func bakeSuperMacaroon(ctx *cli.Context) error {
// If the user specified the optional --save_to parameter, we'll save
// the macaroon to that file.
if ctx.IsSet("save_to") {
macSavePath := lncfg.CleanAndExpandPath(ctx.String("save_to"))
if cli.IsSet("save_to") {
macSavePath := lncfg.CleanAndExpandPath(cli.String("save_to"))
superMacBytes, err := hex.DecodeString(resp.Macaroon)
if err != nil {
return err

View file

@ -1,7 +1,6 @@
package main
import (
"context"
"encoding/hex"
"fmt"
"time"
@ -96,41 +95,41 @@ var addSessionCommand = cli.Command{
},
}
func addSession(ctx *cli.Context) error {
clientConn, cleanup, err := connectClient(ctx, false)
func addSession(cli *cli.Context) error {
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewSessionsClient(clientConn)
sessTypeStr := ctx.String("type")
sessTypeStr := cli.String("type")
sessType, err := parseSessionType(sessTypeStr)
if err != nil {
return err
}
var macPerms []*litrpc.MacaroonPermission
for _, uri := range ctx.StringSlice("uri") {
for _, uri := range cli.StringSlice("uri") {
macPerms = append(macPerms, &litrpc.MacaroonPermission{
Entity: macaroons.PermissionEntityCustomURI,
Action: uri,
})
}
sessionLength := time.Second * time.Duration(ctx.Uint64("expiry"))
sessionLength := time.Second * time.Duration(cli.Uint64("expiry"))
sessionExpiry := time.Now().Add(sessionLength).Unix()
ctxb := context.Background()
ctx := getContext()
resp, err := client.AddSession(
ctxb, &litrpc.AddSessionRequest{
Label: ctx.String("label"),
ctx, &litrpc.AddSessionRequest{
Label: cli.String("label"),
SessionType: sessType,
ExpiryTimestampSeconds: uint64(sessionExpiry),
MailboxServerAddr: ctx.String("mailboxserveraddr"),
DevServer: ctx.Bool("devserver"),
MailboxServerAddr: cli.String("mailboxserveraddr"),
DevServer: cli.Bool("devserver"),
MacaroonCustomPermissions: macPerms,
AccountId: ctx.String("account_id"),
AccountId: cli.String("account_id"),
},
)
if err != nil {
@ -229,17 +228,17 @@ var sessionStateMap = map[litrpc.SessionState]sessionFilter{
}
func listSessions(filter sessionFilter) func(ctx *cli.Context) error {
return func(ctx *cli.Context) error {
clientConn, cleanup, err := connectClient(ctx, false)
return func(cli *cli.Context) error {
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewSessionsClient(clientConn)
ctxb := context.Background()
ctx := getContext()
resp, err := client.ListSessions(
ctxb, &litrpc.ListSessionsRequest{},
ctx, &litrpc.ListSessionsRequest{},
)
if err != nil {
return err
@ -279,22 +278,22 @@ var revokeSessionCommand = cli.Command{
},
}
func revokeSession(ctx *cli.Context) error {
clientConn, cleanup, err := connectClient(ctx, false)
func revokeSession(cli *cli.Context) error {
clientConn, cleanup, err := connectClient(cli, false)
if err != nil {
return err
}
defer cleanup()
client := litrpc.NewSessionsClient(clientConn)
pubkey, err := hex.DecodeString(ctx.String("localpubkey"))
pubkey, err := hex.DecodeString(cli.String("localpubkey"))
if err != nil {
return err
}
ctxb := context.Background()
ctx := getContext()
resp, err := client.RevokeSession(
ctxb, &litrpc.RevokeSessionRequest{
ctx, &litrpc.RevokeSessionRequest{
LocalPublicKey: pubkey,
},
)

View file

@ -1,8 +1,6 @@
package main
import (
"context"
"github.com/lightninglabs/lightning-terminal/litrpc"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/urfave/cli"
@ -18,8 +16,8 @@ var statusCommands = []cli.Command{
},
}
func getStatus(ctx *cli.Context) error {
clientConn, cleanup, err := connectClient(ctx, true)
func getStatus(cli *cli.Context) error {
clientConn, cleanup, err := connectClient(cli, true)
if err != nil {
return err
}
@ -27,9 +25,9 @@ func getStatus(ctx *cli.Context) error {
litClient := litrpc.NewStatusClient(clientConn)
// Get LiT's status.
ctxb := context.Background()
ctx := getContext()
litResp, err := litClient.SubServerStatus(
ctxb, &litrpc.SubServerStatusReq{},
ctx, &litrpc.SubServerStatusReq{},
)
if err != nil {
return err
@ -39,7 +37,7 @@ func getStatus(ctx *cli.Context) error {
// Get LND's state.
lndClient := lnrpc.NewStateClient(clientConn)
lndResp, err := lndClient.GetState(ctxb, &lnrpc.GetStateRequest{})
lndResp, err := lndClient.GetState(ctx, &lnrpc.GetStateRequest{})
if err != nil {
return err
}