Skip to content

Commit

Permalink
feat(cmd): Add non-interactive mode network add-local, paratime add
Browse files Browse the repository at this point in the history
  • Loading branch information
amela committed Sep 6, 2024
1 parent 5ee5605 commit f874577
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 119 deletions.
144 changes: 90 additions & 54 deletions cmd/network/add_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 <name> <rpc-endpoint>",
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 <name> <rpc-endpoint>",
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)
}
168 changes: 104 additions & 64 deletions cmd/paratime/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,115 @@ 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 <network> <name> <id>",
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 <network> <name> <id>",
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())

denomInfo := struct {
Description string
Symbol string
Decimals uint8
}{}

if symbol != "" {
denomInfo.Symbol = symbol
}

if numDecimals != 0 {
denomInfo.Decimals = uint8(numDecimals)
}

if description != "" {
denomInfo.Description = description
}

if !common.GetAnswerYes() {
// 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),
},
Validate: survey.Required,
},
}

err := survey.Ask(questions, &denomInfo)
cobra.CheckErr(err)
}

pt.Description = denomInfo.Description
pt.Denominations = map[string]*config.DenominationInfo{
config.NativeDenominationKey: {
Symbol: denomInfo.Symbol,
Decimals: denomInfo.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)
}
9 changes: 8 additions & 1 deletion docs/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,17 @@ 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.

```
```shell
oasis network add-local testnet_local unix:/node_testnet/data/internal.sock
```

You can also enable non-interactive mode by passing the `-y`, `--num-decimals`,
`--symbol` and `--description` parameters:

```shell
oasis network add-local testnet_local unix:/node_testnet/data/internal.sock --num-decimals 9 --symbol TEST --description localTestnet -y
```

## List Networks {#list}

Invoke `network list` to list all configured networks.
Expand Down
7 changes: 7 additions & 0 deletions docs/paratime.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ oasis paratime add testnet sapphire2 0000000000000000000000000000000000000000000
? Denomination decimal places: 18
```

You can also enable non-interactive mode by passing the `-y`, `--num-decimals`,
`--symbol` and `--description` parameters:

```shell
oasis paratime add testnet sapphire2 000000000000000000000000000000000000000000000000a6d1e3ebf60dff6d --num-decimals 18 --symbol TEST --description testnet-sapphire2 -y
```

:::danger Decimal places of the native and ParaTime token may differ!

Emerald and Sapphire use **18 decimals** for compatibility with
Expand Down

0 comments on commit f874577

Please sign in to comment.