2022-07-08 14:34:53 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/hex"
|
2023-08-24 15:12:12 +02:00
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
2022-07-08 14:34:53 +02:00
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/lightninglabs/lightning-terminal/litrpc"
|
|
|
|
|
"github.com/lightninglabs/lightning-terminal/rules"
|
2024-04-15 16:12:58 +02:00
|
|
|
"github.com/lightninglabs/lightning-terminal/session"
|
2024-01-26 14:01:16 +01:00
|
|
|
"github.com/lightningnetwork/lnd/lnrpc"
|
2022-07-08 14:34:53 +02:00
|
|
|
"github.com/urfave/cli"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var autopilotCommands = cli.Command{
|
|
|
|
|
Name: "autopilot",
|
2023-10-26 12:31:40 -06:00
|
|
|
Usage: "Manage autopilot sessions",
|
|
|
|
|
Category: "LNC",
|
2022-07-08 14:34:53 +02:00
|
|
|
Subcommands: []cli.Command{
|
2023-03-19 17:52:48 +02:00
|
|
|
listAutopilotFeaturesCmd,
|
|
|
|
|
addAutopilotSessionCmd,
|
|
|
|
|
revokeAutopilotSessionCmd,
|
|
|
|
|
listAutopilotSessionsCmd,
|
|
|
|
|
},
|
2023-10-26 12:31:40 -06:00
|
|
|
Description: "Manage autopilot sessions.",
|
2023-03-19 17:52:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var listAutopilotFeaturesCmd = cli.Command{
|
2023-12-19 09:28:34 +01:00
|
|
|
Name: "features",
|
|
|
|
|
ShortName: "f",
|
|
|
|
|
Usage: "List available Autopilot features.",
|
2023-10-26 12:31:40 -06:00
|
|
|
Description: "List available Autopilot features.",
|
2023-12-19 09:28:34 +01:00
|
|
|
Action: listFeatures,
|
2023-03-19 17:52:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var addAutopilotSessionCmd = cli.Command{
|
|
|
|
|
Name: "add",
|
|
|
|
|
ShortName: "a",
|
|
|
|
|
Usage: "Initialize an Autopilot session.",
|
2024-01-26 14:01:16 +01:00
|
|
|
Description: `
|
|
|
|
|
Initialize an Autopilot session.
|
|
|
|
|
|
|
|
|
|
If one of the 'feature-' flags is set for any 'feature', then that flag
|
|
|
|
|
must be provided for each 'feature'.
|
|
|
|
|
|
|
|
|
|
The rules and configuration options available for each feature can be
|
|
|
|
|
seen in the 'autopilot features' output. For a rule, all fields must be
|
|
|
|
|
set since the unset ones are interpreteded as zero values. Rule values
|
|
|
|
|
must adhere to the limits found in 'autopilot features'. If a rule is
|
|
|
|
|
not set, default values are used.
|
|
|
|
|
|
|
|
|
|
An example call for AutoFees reads:
|
|
|
|
|
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
./litcli autopilot add --label=customRules \
|
|
|
|
|
--feature=AutoFees \
|
|
|
|
|
--feature-rules='{
|
|
|
|
|
"rules": {
|
|
|
|
|
"channel-policy-bounds": {
|
|
|
|
|
"chan_policy_bounds": {
|
|
|
|
|
"min_base_msat": "0",
|
|
|
|
|
"max_base_msat": "10000",
|
|
|
|
|
"min_rate_ppm": 10,
|
|
|
|
|
"max_rate_ppm": 5000,
|
|
|
|
|
"min_cltv_delta": 60,
|
|
|
|
|
"max_cltv_delta": 120,
|
|
|
|
|
"min_htlc_msat": "1",
|
|
|
|
|
"max_htlc_msat": "100000000000"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"peer-restriction": {
|
|
|
|
|
"peer_restrict": {
|
|
|
|
|
"peer_ids": [
|
|
|
|
|
"abcabc",
|
|
|
|
|
"defdef"
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}' \
|
|
|
|
|
--feature-config='{}'`,
|
2023-03-19 17:52:48 +02:00
|
|
|
Action: initAutopilotSession,
|
|
|
|
|
Flags: []cli.Flag{
|
|
|
|
|
labelFlag,
|
|
|
|
|
expiryFlag,
|
|
|
|
|
mailboxServerAddrFlag,
|
|
|
|
|
devserver,
|
|
|
|
|
cli.StringSliceFlag{
|
|
|
|
|
Name: "feature",
|
|
|
|
|
Required: true,
|
2022-07-08 14:34:53 +02:00
|
|
|
},
|
2024-01-26 14:01:16 +01:00
|
|
|
cli.StringSliceFlag{
|
2023-03-19 17:52:48 +02:00
|
|
|
Name: "channel-restrict-list",
|
2024-01-26 14:01:16 +01:00
|
|
|
Usage: "[deprecated] List of channel IDs that the " +
|
2023-03-19 17:52:48 +02:00
|
|
|
"Autopilot server should not " +
|
|
|
|
|
"perform actions on. In the " +
|
|
|
|
|
"form of: chanID1,chanID2,...",
|
2024-01-26 14:01:16 +01:00
|
|
|
Hidden: true,
|
2022-07-08 14:34:53 +02:00
|
|
|
},
|
2024-01-26 14:01:16 +01:00
|
|
|
cli.StringSliceFlag{
|
2023-03-19 17:52:48 +02:00
|
|
|
Name: "peer-restrict-list",
|
2024-01-26 14:01:16 +01:00
|
|
|
Usage: "[deprecated] List of peer IDs that the " +
|
2023-03-19 17:52:48 +02:00
|
|
|
"Autopilot server should not " +
|
|
|
|
|
"perform actions on. In the " +
|
|
|
|
|
"form of: peerID1,peerID2,...",
|
2024-01-26 14:01:16 +01:00
|
|
|
Hidden: true,
|
2022-07-08 14:34:53 +02:00
|
|
|
},
|
2023-06-19 16:16:04 +02:00
|
|
|
cli.StringFlag{
|
|
|
|
|
Name: "group_id",
|
|
|
|
|
Usage: "The hex encoded group ID of the session " +
|
2023-10-26 12:31:40 -06:00
|
|
|
"group to link this one to.",
|
2023-06-19 16:16:04 +02:00
|
|
|
},
|
2023-08-24 15:12:12 +02:00
|
|
|
cli.StringSliceFlag{
|
|
|
|
|
Name: "feature-config",
|
2023-10-26 12:31:40 -06:00
|
|
|
Usage: "JSON-serialized configuration with the " +
|
|
|
|
|
"expected format: {\"version\":0," +
|
|
|
|
|
"\"option1\":\"parameter1\"," +
|
|
|
|
|
"\"option2\":\"parameter2\",...}. An empty " +
|
|
|
|
|
"configuration is allowed with {} to use the " +
|
|
|
|
|
"default configuration.",
|
2023-08-24 15:12:12 +02:00
|
|
|
},
|
2024-01-26 14:01:16 +01:00
|
|
|
cli.StringSliceFlag{
|
|
|
|
|
Name: "feature-rules",
|
|
|
|
|
Usage: `JSON-serialized rule map (see main ` +
|
|
|
|
|
`description for a format example).` +
|
|
|
|
|
`An empty rule map is allowed with {} to ` +
|
|
|
|
|
`use the default rules.`,
|
|
|
|
|
},
|
2024-04-15 16:12:58 +02:00
|
|
|
cli.StringFlag{
|
|
|
|
|
Name: "privacy-flags",
|
2025-12-09 15:57:14 +00:00
|
|
|
Usage: "String representation of privacy flags " +
|
|
|
|
|
"to set for the session. Each individual " +
|
|
|
|
|
"flag will remove privacy from certain " +
|
|
|
|
|
"aspects of messages transmitted to " +
|
|
|
|
|
"autopilot. The strongest privacy is on by " +
|
2024-04-15 16:12:58 +02:00
|
|
|
"default and an empty string means full " +
|
|
|
|
|
"privacy. Some features may not be able to " +
|
|
|
|
|
"run correctly with full privacy, see the " +
|
|
|
|
|
"autopilot features call for a list of " +
|
|
|
|
|
"default required privacy flags. Those " +
|
|
|
|
|
"minimally required privacy flags are set " +
|
|
|
|
|
"automatically if nothing is specified here. " +
|
|
|
|
|
"Combining several features will " +
|
|
|
|
|
"require the union of all individual " +
|
|
|
|
|
"feature's privacy flags, which is why it is " +
|
|
|
|
|
"recommended to register each feature " +
|
|
|
|
|
"separately for best privacy. Linking to a " +
|
|
|
|
|
"previous session must preserve privacy " +
|
|
|
|
|
"flags of the previous session. Example: " +
|
|
|
|
|
"\"ClearPubkeys|ClearAmounts\"",
|
|
|
|
|
},
|
2022-07-08 14:34:53 +02:00
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-19 17:52:48 +02:00
|
|
|
var revokeAutopilotSessionCmd = cli.Command{
|
2023-12-19 09:28:34 +01:00
|
|
|
Name: "revoke",
|
|
|
|
|
ShortName: "r",
|
|
|
|
|
Usage: "Revoke an Autopilot session.",
|
2023-10-26 12:31:40 -06:00
|
|
|
Description: "Revoke an active Autopilot session.",
|
2023-12-19 09:28:34 +01:00
|
|
|
Action: revokeAutopilotSession,
|
2023-03-19 17:52:48 +02:00
|
|
|
Flags: []cli.Flag{
|
|
|
|
|
cli.StringFlag{
|
|
|
|
|
Name: "localpubkey",
|
2023-10-26 12:31:40 -06:00
|
|
|
Usage: "Local pubkey of the " +
|
|
|
|
|
"session to revoke.",
|
2023-03-19 17:52:48 +02:00
|
|
|
Required: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var listAutopilotSessionsCmd = cli.Command{
|
2023-12-19 09:28:34 +01:00
|
|
|
Name: "list",
|
|
|
|
|
ShortName: "l",
|
|
|
|
|
Usage: "List all Autopilot sessions.",
|
2023-10-26 12:31:40 -06:00
|
|
|
Description: "List all Autopilot sessions.\n",
|
2023-12-19 09:28:34 +01:00
|
|
|
Action: listAutopilotSessions,
|
2023-03-19 17:52:48 +02:00
|
|
|
}
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
func revokeAutopilotSession(cli *cli.Context) error {
|
|
|
|
|
ctx := getContext()
|
|
|
|
|
clientConn, cleanup, err := connectClient(cli, false)
|
2022-07-08 14:34:53 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer cleanup()
|
|
|
|
|
client := litrpc.NewAutopilotClient(clientConn)
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
pubkey, err := hex.DecodeString(cli.String("localpubkey"))
|
2022-07-08 14:34:53 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp, err := client.RevokeAutopilotSession(
|
2025-01-13 09:07:30 +02:00
|
|
|
ctx, &litrpc.RevokeAutopilotSessionRequest{
|
2022-07-08 14:34:53 +02:00
|
|
|
LocalPublicKey: pubkey,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printRespJSON(resp)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
func listAutopilotSessions(cli *cli.Context) error {
|
|
|
|
|
ctx := getContext()
|
|
|
|
|
clientConn, cleanup, err := connectClient(cli, false)
|
2023-03-19 17:52:48 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer cleanup()
|
|
|
|
|
client := litrpc.NewAutopilotClient(clientConn)
|
|
|
|
|
|
|
|
|
|
resp, err := client.ListAutopilotSessions(
|
2025-01-13 09:07:30 +02:00
|
|
|
ctx, &litrpc.ListAutopilotSessionsRequest{},
|
2023-03-19 17:52:48 +02:00
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printRespJSON(resp)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
func listFeatures(cli *cli.Context) error {
|
|
|
|
|
ctx := getContext()
|
|
|
|
|
clientConn, cleanup, err := connectClient(cli, false)
|
2022-07-08 14:34:53 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer cleanup()
|
|
|
|
|
client := litrpc.NewAutopilotClient(clientConn)
|
|
|
|
|
|
|
|
|
|
resp, err := client.ListAutopilotFeatures(
|
2025-01-13 09:07:30 +02:00
|
|
|
ctx, &litrpc.ListAutopilotFeaturesRequest{},
|
2022-07-08 14:34:53 +02:00
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printRespJSON(resp)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
func initAutopilotSession(cli *cli.Context) error {
|
|
|
|
|
sessionLength := time.Second * time.Duration(cli.Uint64("expiry"))
|
2022-07-08 14:34:53 +02:00
|
|
|
sessionExpiry := time.Now().Add(sessionLength).Unix()
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
ctx := getContext()
|
|
|
|
|
clientConn, cleanup, err := connectClient(cli, false)
|
2022-07-08 14:34:53 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer cleanup()
|
|
|
|
|
client := litrpc.NewAutopilotClient(clientConn)
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
features := cli.StringSlice("feature")
|
2024-01-26 14:01:16 +01:00
|
|
|
|
|
|
|
|
// Check that the user only sets unique features.
|
|
|
|
|
fs := make(map[string]struct{})
|
|
|
|
|
for _, feature := range features {
|
|
|
|
|
if _, ok := fs[feature]; ok {
|
|
|
|
|
return fmt.Errorf("feature %v is set multiple times",
|
|
|
|
|
feature)
|
|
|
|
|
}
|
|
|
|
|
fs[feature] = struct{}{}
|
2022-07-08 14:34:53 +02:00
|
|
|
}
|
|
|
|
|
|
2024-01-26 14:01:16 +01:00
|
|
|
// Check that the user did not set multiple restrict lists.
|
|
|
|
|
var chanRestrictList, peerRestrictList string
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
channelRestrictSlice := cli.StringSlice("channel-restrict-list")
|
2024-01-26 14:01:16 +01:00
|
|
|
if len(channelRestrictSlice) > 1 {
|
|
|
|
|
return fmt.Errorf("channel-restrict-list can only be used once")
|
|
|
|
|
} else if len(channelRestrictSlice) == 1 {
|
|
|
|
|
chanRestrictList = channelRestrictSlice[0]
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
peerRestrictSlice := cli.StringSlice("peer-restrict-list")
|
2024-01-26 14:01:16 +01:00
|
|
|
if len(peerRestrictSlice) > 1 {
|
|
|
|
|
return fmt.Errorf("peer-restrict-list can only be used once")
|
|
|
|
|
} else if len(peerRestrictSlice) == 1 {
|
|
|
|
|
peerRestrictList = peerRestrictSlice[0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// rulesMap stores the rules per each feature.
|
|
|
|
|
rulesMap := make(map[string]*litrpc.RulesMap)
|
2025-01-13 09:07:30 +02:00
|
|
|
rulesFlags := cli.StringSlice("feature-rules")
|
2024-01-26 14:01:16 +01:00
|
|
|
|
|
|
|
|
// For legacy flags, we allow setting the channel and peer restrict
|
|
|
|
|
// lists when only a single feature is added.
|
|
|
|
|
if chanRestrictList != "" || peerRestrictList != "" {
|
|
|
|
|
// Check that the user did not set both the legacy flags and the
|
|
|
|
|
// generic rules flags together.
|
|
|
|
|
if len(rulesFlags) > 0 {
|
|
|
|
|
return fmt.Errorf("either set channel-restrict-list/" +
|
|
|
|
|
"peer-restrict-list or feature-rules, not both")
|
2022-07-08 14:34:53 +02:00
|
|
|
}
|
|
|
|
|
|
2024-01-26 14:01:16 +01:00
|
|
|
if len(features) > 1 {
|
|
|
|
|
return fmt.Errorf("cannot set channel-restrict-list/" +
|
|
|
|
|
"peer-restrict-list when multiple features " +
|
|
|
|
|
"are set")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
feature := features[0]
|
|
|
|
|
|
|
|
|
|
// Init the rule map for this feature.
|
|
|
|
|
ruleMap := make(map[string]*litrpc.RuleValue)
|
|
|
|
|
|
|
|
|
|
if chanRestrictList != "" {
|
|
|
|
|
var chanIDs []uint64
|
|
|
|
|
chans := strings.Split(chanRestrictList, ",")
|
|
|
|
|
for _, c := range chans {
|
|
|
|
|
i, err := strconv.ParseUint(c, 10, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
chanIDs = append(chanIDs, i)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
channelRestrict := &litrpc.ChannelRestrict{
|
|
|
|
|
ChannelIds: chanIDs,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ruleMap[rules.ChannelRestrictName] = &litrpc.RuleValue{
|
|
|
|
|
Value: &litrpc.RuleValue_ChannelRestrict{
|
|
|
|
|
ChannelRestrict: channelRestrict,
|
2022-07-08 14:34:53 +02:00
|
|
|
},
|
2024-01-26 14:01:16 +01:00
|
|
|
}
|
2022-07-08 14:34:53 +02:00
|
|
|
}
|
|
|
|
|
|
2024-01-26 14:01:16 +01:00
|
|
|
if peerRestrictList != "" {
|
|
|
|
|
peerIDs := strings.Split(peerRestrictList, ",")
|
2022-07-08 14:34:53 +02:00
|
|
|
|
2024-01-26 14:01:16 +01:00
|
|
|
ruleMap[rules.PeersRestrictName] = &litrpc.RuleValue{
|
|
|
|
|
Value: &litrpc.RuleValue_PeerRestrict{
|
|
|
|
|
PeerRestrict: &litrpc.PeerRestrict{
|
|
|
|
|
PeerIds: peerIDs,
|
|
|
|
|
},
|
2022-07-08 14:34:53 +02:00
|
|
|
},
|
2024-01-26 14:01:16 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rulesMap[feature] = &litrpc.RulesMap{Rules: ruleMap}
|
|
|
|
|
} else {
|
|
|
|
|
// We make sure that if the rules or configs flags are set, they
|
|
|
|
|
// are set for all features, to avoid ambiguity.
|
|
|
|
|
if len(rulesFlags) > 0 && len(features) != len(rulesFlags) {
|
|
|
|
|
return fmt.Errorf("number of features (%v) and rules "+
|
|
|
|
|
"(%v) must match", len(features),
|
|
|
|
|
len(rulesFlags))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse the rules and store them in the rulesMap.
|
|
|
|
|
for i, rulesFlag := range rulesFlags {
|
|
|
|
|
var ruleMap litrpc.RulesMap
|
|
|
|
|
|
|
|
|
|
// We allow empty rules, to signal the usage of the
|
|
|
|
|
// default rules when the session is registered.
|
|
|
|
|
if rulesFlag != "{}" {
|
|
|
|
|
err = lnrpc.ProtoJSONUnmarshalOpts.Unmarshal(
|
|
|
|
|
[]byte(rulesFlag), &ruleMap,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rulesMap[features[i]] = &ruleMap
|
2022-07-08 14:34:53 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
configs := cli.StringSlice("feature-config")
|
2023-08-24 15:12:12 +02:00
|
|
|
if len(configs) > 0 && len(features) != len(configs) {
|
|
|
|
|
return fmt.Errorf("number of features (%v) and configurations "+
|
|
|
|
|
"(%v) must match", len(features), len(configs))
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-26 14:01:16 +01:00
|
|
|
// Parse the configs and store them in the configsMap.
|
|
|
|
|
configsMap := make(map[string][]byte)
|
|
|
|
|
for i, configFlag := range configs {
|
2023-08-24 15:12:12 +02:00
|
|
|
var config []byte
|
|
|
|
|
|
|
|
|
|
// We allow empty configs, to signal the usage of the default
|
|
|
|
|
// configuration when the session is registered.
|
2024-01-26 14:01:16 +01:00
|
|
|
if configFlag != "{}" {
|
2023-08-24 15:12:12 +02:00
|
|
|
// We expect the config to be a JSON dictionary, so we
|
|
|
|
|
// unmarshal it into a map to do a first validation.
|
|
|
|
|
var configMap map[string]interface{}
|
|
|
|
|
err := json.Unmarshal([]byte(configs[i]), &configMap)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("could not parse "+
|
|
|
|
|
"configuration for feature %v: %v",
|
2024-01-26 14:01:16 +01:00
|
|
|
features[i], err)
|
2023-08-24 15:12:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
config = []byte(configs[i])
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-26 14:01:16 +01:00
|
|
|
configsMap[features[i]] = config
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
featureMap := make(map[string]*litrpc.FeatureConfig)
|
|
|
|
|
for _, feature := range features {
|
|
|
|
|
// Map access for unknown features will return their zero value
|
|
|
|
|
// if not set, which is what we want to signal default usage.
|
2022-07-08 14:34:53 +02:00
|
|
|
featureMap[feature] = &litrpc.FeatureConfig{
|
2024-01-26 14:01:16 +01:00
|
|
|
Rules: rulesMap[feature],
|
|
|
|
|
Config: configsMap[feature],
|
2022-07-08 14:34:53 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-19 16:16:04 +02:00
|
|
|
var groupID []byte
|
2025-01-13 09:07:30 +02:00
|
|
|
if cli.IsSet("group_id") {
|
|
|
|
|
groupID, err = hex.DecodeString(cli.String("group_id"))
|
2023-06-19 16:16:04 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-15 16:12:58 +02:00
|
|
|
var privacyFlags uint64
|
|
|
|
|
var privacyFlagsSet bool
|
2025-01-13 09:07:30 +02:00
|
|
|
if cli.IsSet("privacy-flags") {
|
2024-04-15 16:12:58 +02:00
|
|
|
privacyFlagsSet = true
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
flags, err := session.Parse(cli.String("privacy-flags"))
|
2024-04-15 16:12:58 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
privacyFlags = flags.Serialize()
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-08 14:34:53 +02:00
|
|
|
resp, err := client.AddAutopilotSession(
|
2025-01-13 09:07:30 +02:00
|
|
|
ctx, &litrpc.AddAutopilotSessionRequest{
|
|
|
|
|
Label: cli.String("label"),
|
2022-07-08 14:34:53 +02:00
|
|
|
ExpiryTimestampSeconds: uint64(sessionExpiry),
|
2025-01-13 09:07:30 +02:00
|
|
|
MailboxServerAddr: cli.String("mailboxserveraddr"),
|
|
|
|
|
DevServer: cli.Bool("devserver"),
|
2022-07-08 14:34:53 +02:00
|
|
|
Features: featureMap,
|
2023-06-19 16:16:04 +02:00
|
|
|
LinkedGroupId: groupID,
|
2024-04-15 16:12:58 +02:00
|
|
|
PrivacyFlags: privacyFlags,
|
|
|
|
|
PrivacyFlagsSet: privacyFlagsSet,
|
2022-07-08 14:34:53 +02:00
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printRespJSON(resp)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|