diff --git a/cmd/account/entity.go b/cmd/account/entity.go index 0f9751d3..2de8a452 100644 --- a/cmd/account/entity.go +++ b/cmd/account/entity.go @@ -8,6 +8,8 @@ import ( "github.com/spf13/cobra" + "github.com/oasisprotocol/oasis-core/go/common/cbor" + "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" "github.com/oasisprotocol/oasis-core/go/common/entity" registry "github.com/oasisprotocol/oasis-core/go/registry/api" "github.com/oasisprotocol/oasis-sdk/client-sdk/go/connection" @@ -17,11 +19,60 @@ import ( ) var ( + entityOutputFile string + entityCmd = &cobra.Command{ Use: "entity", Short: "Entity management in the network's registry", } + entityInitCmd = &cobra.Command{ + Use: "init", + Short: "Init an empty entity file", + Run: func(cmd *cobra.Command, args []string) { + cfg := cliConfig.Global() + npa := common.GetNPASelection(cfg) + + if npa.Account == nil { + cobra.CheckErr("no accounts configured in your wallet") + } + + // Load the account and ensure it corresponds to the entity. + acc := common.LoadAccount(cfg, npa.AccountName) + signer := acc.ConsensusSigner() + if signer == nil { + cobra.CheckErr(fmt.Errorf("account '%s' does not support signing consensus transactions", npa.AccountName)) + } + + descriptor := entity.Entity{ + Versioned: cbor.NewVersioned(entity.LatestDescriptorVersion), + ID: signer.Public(), + Nodes: []signature.PublicKey{}, + } + + // Marshal to JSON, add explicit "nodes" field to hint user. + descriptorStr, err := json.Marshal(descriptor) + cobra.CheckErr(err) + var rawJSON map[string]interface{} + err = json.Unmarshal(descriptorStr, &rawJSON) + cobra.CheckErr(err) + rawJSON["nodes"] = []string{} + descriptorStr, err = common.PrettyJSONMarshal(rawJSON) + cobra.CheckErr(err) + + if entityOutputFile == "" { + fmt.Printf("%s\n", descriptorStr) + } else { + fout, err := os.Create(entityOutputFile) + cobra.CheckErr(err) + defer fout.Close() + + _, err = fout.Write(descriptorStr) + cobra.CheckErr(err) + } + }, + } + entityRegisterCmd = &cobra.Command{ Use: "register ", Short: "Register or update account entity in registry", @@ -118,12 +169,17 @@ var ( ) func init() { + entityInitCmd.Flags().StringVarP(&entityOutputFile, "output-file", "o", "", "output entity descriptor into specified JSON file") + entityInitCmd.Flags().AddFlagSet(common.AccountFlag) + entityInitCmd.Flags().AddFlagSet(common.YesFlag) + entityRegisterCmd.Flags().AddFlagSet(common.SelectorNAFlags) entityRegisterCmd.Flags().AddFlagSet(common.TxFlags) entityDeregisterCmd.Flags().AddFlagSet(common.SelectorNAFlags) entityDeregisterCmd.Flags().AddFlagSet(common.TxFlags) + entityCmd.AddCommand(entityInitCmd) entityCmd.AddCommand(entityRegisterCmd) entityCmd.AddCommand(entityDeregisterCmd) } diff --git a/cmd/common/selector.go b/cmd/common/selector.go index 84f1fac8..19d680f6 100644 --- a/cmd/common/selector.go +++ b/cmd/common/selector.go @@ -23,6 +23,8 @@ var ( ) var ( + // AccountFlag corresponds to the --account selector flag. + AccountFlag *flag.FlagSet // SelectorFlags contains the common selector flags for network/ParaTime/wallet. SelectorFlags *flag.FlagSet // SelectorNPFlags contains the common selector flags for network/ParaTime. @@ -103,11 +105,14 @@ func (npa *NPASelection) PrettyPrintNetwork() (out string) { } func init() { + AccountFlag = flag.NewFlagSet("", flag.ContinueOnError) + AccountFlag.StringVar(&selectedAccount, "account", "", "explicitly set account to use") + SelectorFlags = flag.NewFlagSet("", flag.ContinueOnError) SelectorFlags.StringVar(&selectedNetwork, "network", "", "explicitly set network to use") SelectorFlags.StringVar(&selectedParaTime, "paratime", "", "explicitly set ParaTime to use") SelectorFlags.BoolVar(&noParaTime, "no-paratime", false, "explicitly set that no ParaTime should be used") - SelectorFlags.StringVar(&selectedAccount, "account", "", "explicitly set account to use") + SelectorFlags.AddFlagSet(AccountFlag) SelectorNPFlags = flag.NewFlagSet("", flag.ContinueOnError) SelectorNPFlags.StringVar(&selectedNetwork, "network", "", "explicitly set network to use") @@ -116,7 +121,7 @@ func init() { SelectorNAFlags = flag.NewFlagSet("", flag.ContinueOnError) SelectorNAFlags.StringVar(&selectedNetwork, "network", "", "explicitly set network to use") - SelectorNAFlags.StringVar(&selectedAccount, "account", "", "explicitly set account to use") + SelectorNAFlags.AddFlagSet(AccountFlag) SelectorNFlags = flag.NewFlagSet("", flag.ContinueOnError) SelectorNFlags.StringVar(&selectedNetwork, "network", "", "explicitly set network to use") diff --git a/cmd/common/transaction.go b/cmd/common/transaction.go index 1afff7b0..5c1ea383 100644 --- a/cmd/common/transaction.go +++ b/cmd/common/transaction.go @@ -50,6 +50,9 @@ const ( ) var ( + // YesFlag corresponds to the yes-to-all flag. + YesFlag *flag.FlagSet + // TxFlags contains the common consensus transaction flags. TxFlags *flag.FlagSet @@ -564,13 +567,16 @@ func WaitForEvent( } func init() { + YesFlag = flag.NewFlagSet("", flag.ContinueOnError) + YesFlag.BoolVarP(&txYes, "yes", "y", false, "answer yes to all questions") + RuntimeTxFlags = flag.NewFlagSet("", flag.ContinueOnError) RuntimeTxFlags.BoolVar(&txOffline, "offline", false, "do not perform any operations requiring network access") RuntimeTxFlags.Uint64Var(&txNonce, "nonce", invalidNonce, "override nonce to use") RuntimeTxFlags.Uint64Var(&txGasLimit, "gas-limit", invalidGasLimit, "override gas limit to use (disable estimation)") RuntimeTxFlags.StringVar(&txGasPrice, "gas-price", "", "override gas price to use") RuntimeTxFlags.BoolVar(&txEncrypted, "encrypted", false, "encrypt transaction call data (requires online mode)") - RuntimeTxFlags.BoolVarP(&txYes, "yes", "y", false, "answer yes to all questions") + RuntimeTxFlags.AddFlagSet(YesFlag) RuntimeTxFlags.BoolVar(&txUnsigned, "unsigned", false, "do not sign transaction") RuntimeTxFlags.StringVar(&txFormat, "format", "json", "transaction output format (for offline/unsigned modes) [json, cbor]") RuntimeTxFlags.StringVarP(&txOutputFile, "output-file", "o", "", "output transaction into specified file instead of broadcasting") @@ -580,7 +586,7 @@ func init() { TxFlags.Uint64Var(&txNonce, "nonce", invalidNonce, "override nonce to use") TxFlags.Uint64Var(&txGasLimit, "gas-limit", invalidGasLimit, "override gas limit to use (disable estimation)") TxFlags.StringVar(&txGasPrice, "gas-price", "", "override gas price to use") - TxFlags.BoolVarP(&txYes, "yes", "y", false, "answer yes to all questions") + TxFlags.AddFlagSet(YesFlag) TxFlags.BoolVar(&txUnsigned, "unsigned", false, "do not sign transaction") TxFlags.StringVar(&txFormat, "format", "json", "transaction output format (for offline/unsigned modes) [json, cbor]") TxFlags.StringVarP(&txOutputFile, "output-file", "o", "", "output transaction into specified file instead of broadcasting")