diff --git a/cmd/network/add_local.go b/cmd/network/add_local.go index 586f8292..bfb74e18 100644 --- a/cmd/network/add_local.go +++ b/cmd/network/add_local.go @@ -5,67 +5,103 @@ import ( "fmt" "github.com/spf13/cobra" + flag "github.com/spf13/pflag" "github.com/oasisprotocol/oasis-sdk/client-sdk/go/config" "github.com/oasisprotocol/oasis-sdk/client-sdk/go/connection" + "github.com/oasisprotocol/cli/cmd/common" cliConfig "github.com/oasisprotocol/cli/config" ) -var addLocalCmd = &cobra.Command{ - Use: "add-local ", - Short: "Add a new local network", - Args: cobra.ExactArgs(2), - Run: func(cmd *cobra.Command, args []string) { - cfg := cliConfig.Global() - name, rpc := args[0], args[1] - - net := config.Network{ - RPC: rpc, - } - // Validate initial network configuration early. - cobra.CheckErr(config.ValidateIdentifier(name)) - if !net.IsLocalRPC() { - cobra.CheckErr(fmt.Errorf("rpc-endpoint '%s' is not local", rpc)) - } - - // Connect to the network and query the chain context. - ctx := context.Background() - conn, err := connection.ConnectNoVerify(ctx, &net) - cobra.CheckErr(err) - - chainContext, err := conn.Consensus().GetChainContext(ctx) - cobra.CheckErr(err) - net.ChainContext = chainContext - cobra.CheckErr(net.Validate()) - - // With a very high probability, the user is going to be - // adding a local endpoint for an existing network, so try - // to clone config details from any of the hardcoded - // defaults. - var clonedDefault bool - for _, defaultNet := range config.DefaultNetworks.All { - if defaultNet.ChainContext != chainContext { - continue +var ( + symbol string + numDecimals uint + description string + + addLocalCmd = &cobra.Command{ + Use: "add-local ", + Short: "Add a new local network", + Args: cobra.ExactArgs(2), + Run: func(cmd *cobra.Command, args []string) { + cfg := cliConfig.Global() + name, rpc := args[0], args[1] + + net := config.Network{ + RPC: rpc, + } + // Validate initial network configuration early. + cobra.CheckErr(config.ValidateIdentifier(name)) + if !net.IsLocalRPC() { + cobra.CheckErr(fmt.Errorf("rpc-endpoint '%s' is not local", rpc)) + } + + // Connect to the network and query the chain context. + ctx := context.Background() + conn, err := connection.ConnectNoVerify(ctx, &net) + cobra.CheckErr(err) + + chainContext, err := conn.Consensus().GetChainContext(ctx) + cobra.CheckErr(err) + net.ChainContext = chainContext + cobra.CheckErr(net.Validate()) + + // With a very high probability, the user is going to be + // adding a local endpoint for an existing network, so try + // to clone config details from any of the hardcoded + // defaults. + var clonedDefault bool + for _, defaultNet := range config.DefaultNetworks.All { + if defaultNet.ChainContext != chainContext { + continue + } + + // Yep. + net.Denomination = defaultNet.Denomination + net.ParaTimes = defaultNet.ParaTimes + clonedDefault = true + break + } + + if symbol != "" { + net.Denomination.Symbol = symbol + } + + if numDecimals != 0 { + net.Denomination.Decimals = uint8(numDecimals) + } + + if description != "" { + net.Description = description } - // Yep. - net.Denomination = defaultNet.Denomination - net.ParaTimes = defaultNet.ParaTimes - clonedDefault = true - break - } - - // If we failed to crib details from a hardcoded config, - // ask the user. - if !clonedDefault { - networkDetailsFromSurvey(&net) - } - - err = cfg.Networks.Add(name, &net) - cobra.CheckErr(err) - - err = cfg.Save() - cobra.CheckErr(err) - }, + // If we failed to crib details from a hardcoded config, + // and user did not set -y flag ask the user. + if !clonedDefault && !common.GetAnswerYes() { + networkDetailsFromSurvey(&net) + } + + err = cfg.Networks.Add(name, &net) + cobra.CheckErr(err) + + err = cfg.Save() + cobra.CheckErr(err) + }, + } +) + +func init() { + addLocalCmd.Flags().AddFlagSet(common.AnswerYesFlag) + + symbolFlag := flag.NewFlagSet("", flag.ContinueOnError) + symbolFlag.StringVar(&symbol, "symbol", "", "network's symbol") + addLocalCmd.Flags().AddFlagSet(symbolFlag) + + numDecimalsFlag := flag.NewFlagSet("", flag.ContinueOnError) + numDecimalsFlag.UintVar(&numDecimals, "num-decimals", 0, "network's number of decimals") + addLocalCmd.Flags().AddFlagSet(numDecimalsFlag) + + descriptionFlag := flag.NewFlagSet("", flag.ContinueOnError) + descriptionFlag.StringVar(&description, "description", "", "network's description") + addLocalCmd.Flags().AddFlagSet(descriptionFlag) } diff --git a/cmd/paratime/add.go b/cmd/paratime/add.go index 89c764ba..c96334df 100644 --- a/cmd/paratime/add.go +++ b/cmd/paratime/add.go @@ -5,75 +5,121 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/spf13/cobra" + flag "github.com/spf13/pflag" "github.com/oasisprotocol/oasis-sdk/client-sdk/go/config" + "github.com/oasisprotocol/cli/cmd/common" cliConfig "github.com/oasisprotocol/cli/config" ) -var addCmd = &cobra.Command{ - Use: "add ", - Short: "Add a new ParaTime", - Args: cobra.ExactArgs(3), - Run: func(cmd *cobra.Command, args []string) { - cfg := cliConfig.Global() - network, name, id := args[0], args[1], args[2] - - net, exists := cfg.Networks.All[network] - if !exists { - cobra.CheckErr(fmt.Errorf("network '%s' does not exist", network)) - } - - pt := config.ParaTime{ - ID: id, - } - // Validate initial paratime configuration early. - cobra.CheckErr(config.ValidateIdentifier(name)) - cobra.CheckErr(pt.Validate()) - - // Ask user for some additional parameters. - questions := []*survey.Question{ - { - Name: "description", - Prompt: &survey.Input{Message: "Description:"}, - }, - { - Name: "symbol", - Prompt: &survey.Input{ - Message: "Denomination symbol:", - Default: net.Denomination.Symbol, - }, - }, - { - Name: "decimals", - Prompt: &survey.Input{ - Message: "Denomination decimal places:", - Default: fmt.Sprintf("%d", net.Denomination.Decimals), +var ( + symbol string + numDecimals uint + description string + + addCmd = &cobra.Command{ + Use: "add ", + Short: "Add a new ParaTime", + Args: cobra.ExactArgs(3), + Run: func(cmd *cobra.Command, args []string) { + cfg := cliConfig.Global() + network, name, id := args[0], args[1], args[2] + + net, exists := cfg.Networks.All[network] + if !exists { + cobra.CheckErr(fmt.Errorf("network '%s' does not exist", network)) + } + + pt := config.ParaTime{ + ID: id, + } + // Validate initial paratime configuration early. + cobra.CheckErr(config.ValidateIdentifier(name)) + cobra.CheckErr(pt.Validate()) + + paratimeInfo := struct { + Description string + Symbol string + Decimals uint8 + }{ + Symbol: net.Denomination.Symbol, + Decimals: net.Denomination.Decimals, + } + + if symbol != "" { + paratimeInfo.Symbol = symbol + } + + if numDecimals != 0 { + paratimeInfo.Decimals = uint8(numDecimals) + } + + if description != "" { + paratimeInfo.Description = description + } + + if !common.GetAnswerYes() { + // Ask user for some additional parameters. + questions := []*survey.Question{ + { + Name: "description", + Prompt: &survey.Input{ + Message: "Description:", + Default: paratimeInfo.Description, + }, + }, + { + Name: "symbol", + Prompt: &survey.Input{ + Message: "Denomination symbol:", + Default: paratimeInfo.Symbol, + }, + }, + { + Name: "decimals", + Prompt: &survey.Input{ + Message: "Denomination decimal places:", + Default: fmt.Sprintf("%d", paratimeInfo.Decimals), + }, + Validate: survey.Required, + }, + } + + err := survey.Ask(questions, ¶timeInfo) + cobra.CheckErr(err) + } + + pt.Description = paratimeInfo.Description + pt.Denominations = map[string]*config.DenominationInfo{ + config.NativeDenominationKey: { + Symbol: paratimeInfo.Symbol, + Decimals: paratimeInfo.Decimals, }, - Validate: survey.Required, - }, - } - answers := struct { - Description string - Symbol string - Decimals uint8 - }{} - err := survey.Ask(questions, &answers) - cobra.CheckErr(err) - - pt.Description = answers.Description - pt.Denominations = map[string]*config.DenominationInfo{ - config.NativeDenominationKey: { - Symbol: answers.Symbol, - Decimals: answers.Decimals, - }, - } - pt.ConsensusDenomination = config.NativeDenominationKey // TODO: Make this configurable. - - err = net.ParaTimes.Add(name, &pt) - cobra.CheckErr(err) - - err = cfg.Save() - cobra.CheckErr(err) - }, + } + pt.ConsensusDenomination = config.NativeDenominationKey // TODO: Make this configurable. + + err := net.ParaTimes.Add(name, &pt) + cobra.CheckErr(err) + + err = cfg.Save() + cobra.CheckErr(err) + }, + } +) + +func init() { + addCmd.Flags().AddFlagSet(common.AnswerYesFlag) + + symbolFlag := flag.NewFlagSet("", flag.ContinueOnError) + symbolFlag.StringVar(&symbol, "symbol", "", "paratime's symbol") + addCmd.Flags().AddFlagSet(symbolFlag) + + numDecimalsFlag := flag.NewFlagSet("", flag.ContinueOnError) + numDecimalsFlag.UintVar(&numDecimals, "num-decimals", 0, "paratime's number of decimals") + addCmd.Flags().AddFlagSet(numDecimalsFlag) + + descriptionFlag := flag.NewFlagSet("", flag.ContinueOnError) + descriptionFlag.StringVar(&description, "description", "", "paratime's description") + addCmd.Flags().AddFlagSet(descriptionFlag) } diff --git a/docs/network.md b/docs/network.md index 505f2c78..34500a5e 100644 --- a/docs/network.md +++ b/docs/network.md @@ -53,13 +53,23 @@ For Unix sockets, use: `network add-local ` command can be used if you are running `oasis-node` on your local machine. In this case, Oasis CLI will -autodetect the native token symbol and decimal places, the chain domain -separation context and registered ParaTimes. +autodetect the chain domain separation context. For the Oasis Mainnet and +Testnet chains, the native token symbol, the number of decimal places and +registered ParaTimes will automatically be predefined. Otherwise, the Oasis CLI +will ask you to enter them. -``` +```shell oasis network add-local testnet_local unix:/node_testnet/data/internal.sock ``` +To override the defaults, you can pass `--num-decimals`, `--symbol` and +`--description` parameters. This is especially useful, if you are running the +command in a [non-interactive mode](account.md#y): + +```shell +oasis network add-local testnet_local unix:/node_testnet/data/internal.sock --num-decimals 9 --symbol TEST --description "Work machine - Localnet" -y +``` + ## List Networks {#list} Invoke `network list` to list all configured networks. diff --git a/docs/paratime.md b/docs/paratime.md index 7effa74a..a7aca4bc 100644 --- a/docs/paratime.md +++ b/docs/paratime.md @@ -41,6 +41,13 @@ oasis paratime add testnet sapphire2 0000000000000000000000000000000000000000000 ? Denomination decimal places: 18 ``` +You can also enable [non-interactive mode](account.md#y) and pass +`--num-decimals`, `--symbol` and `--description` parameters directly: + +```shell +oasis paratime add testnet sapphire2 000000000000000000000000000000000000000000000000a6d1e3ebf60dff6d --num-decimals 18 --symbol TEST --description "Testnet Sapphire 2" -y +``` + :::danger Decimal places of the native and ParaTime token may differ! Emerald and Sapphire use **18 decimals** for compatibility with