Documentation ¶
Overview ¶
Copyright © 2021 AVA Labs, Inc. All rights reserved.
Package cmd implements cobra commander
Index ¶
Constants ¶
This section is empty.
Variables ¶
var AVAXWalletCmd = &cobra.Command{ Use: "avaxwallet", Short: "Tools for interacting with AVAX Payments over the network.", Long: `Tools for interacting with AVAX Payments over the network. Using this command you can send, and get the status of a transaction.`, Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, }
AVAXWalletCmd represents the avaxwallet command
var AVAXWalletGetBalanceCmd = &cobra.Command{ Use: "balance [node name] [address]", Short: "Checks the balance of an address from a node.", Long: `Checks the balance of an address from a node.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 2 { log := cfg.Config.Log if meta, err := pmgr.ProcManager.Metadata(args[0]); err == nil { var md node.Metadata metaBytes := []byte(meta) if err := json.Unmarshal(metaBytes, &md); err == nil { jrpcloc := fmt.Sprintf("http://%s:%s/ext/bc/avm", md.Serverhost, md.HTTPport) rpcClient := jsonrpc.NewClient(jrpcloc) response, err := rpcClient.Call("avm.getBalance", struct { Address string AssetID string }{ Address: args[1], AssetID: "AVAX", }) if err != nil { log.Error("error sent address: %s", args[1]) log.Error("rpcClient returned error: %s", err.Error()) } else if response.Error != nil { log.Error("error sent address: %s", args[1]) log.Error("rpcClient returned error: %d, %s", response.Error.Code, response.Error.Message) } else { var s struct { Balance string } err = response.GetObject(&s) if err != nil { log.Error("error on parsing response: %s", err.Error()) } else { log.Info("Balance: %s", s.Balance) } } } else { log.Error("unable to unmarshal metadata for node %s: %s", args[0], err.Error()) } } else { log.Error("node not found: %s", args[0]) } } else { cmd.Help() } }, }
AVAXWalletGetBalanceCmd will get the balance of an address from a node
var AVAXWalletNewKeyCmd = &cobra.Command{ Use: "newkey", Short: "Creates a random private key.", Long: `Creates a random private key.`, Run: func(cmd *cobra.Command, args []string) { log := cfg.Config.Log factory := crypto.FactorySECP256K1R{} if skGen, err := factory.NewPrivateKey(); err == nil { sk := skGen.(*crypto.PrivateKeySECP256K1R) str, err := formatting.EncodeWithChecksum(defaultEncoding, sk.Bytes()) if err != nil { log.Error("could not encode private key") } log.Info("PrivateKey: PrivateKey-%s", str) } else { log.Error("could not create private key") } }, }
AVAXWalletNewKeyCmd creates a new private key
var AVAXWalletSendCmd = &cobra.Command{ Use: "send [node name] [tx string]", Short: "Sends a transaction to a node.", Long: `Sends a transaction to a node.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 2 { log := cfg.Config.Log if meta, err := pmgr.ProcManager.Metadata(args[0]); err == nil { var md node.Metadata metaBytes := []byte(meta) if err := json.Unmarshal(metaBytes, &md); err == nil { jrpcloc := fmt.Sprintf("http://%s:%s/ext/bc/avm", md.Serverhost, md.HTTPport) rpcClient := jsonrpc.NewClient(jrpcloc) response, err := rpcClient.Call("avm.issueTx", struct { Tx string }{ Tx: args[1], }) if err != nil { log.Error("error sent tx: %s", args[1]) log.Error("rpcClient returned error: %s", err.Error()) } else if response.Error != nil { log.Error("error sent tx: %s", args[1]) log.Error("rpcClient returned error: %d, %s", response.Error.Code, response.Error.Message) } else { var s struct { TxID string } err = response.GetObject(&s) if err != nil { log.Error("error on parsing response: %s", err.Error()) } else { log.Info("TxID:%s", s.TxID) } } } else { log.Error("unable to unmarshal metadata for node %s: %s", args[0], err.Error()) } } else { log.Error("node not found: %s", args[0]) } } else { cmd.Help() } }, }
AVAXWalletSendCmd will send a transaction through a node
var AVAXWalletStatusCmd = &cobra.Command{ Use: "status [node name] [tx id]", Short: "Checks the status of a transaction on a node.", Long: `Checks the status of a transaction on a node.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 2 { log := cfg.Config.Log if meta, err := pmgr.ProcManager.Metadata(args[0]); err == nil { var md node.Metadata metaBytes := []byte(meta) if err := json.Unmarshal(metaBytes, &md); err == nil { jrpcloc := fmt.Sprintf("http://%s:%s/ext/bc/avm", md.Serverhost, md.HTTPport) rpcClient := jsonrpc.NewClient(jrpcloc) response, err := rpcClient.Call("avm.getTxStatus", struct { TxID string }{ TxID: args[1], }) if err != nil { log.Error("error sent txid: %s", args[1]) log.Error("rpcClient returned error: %s", err.Error()) } else if response.Error != nil { log.Error("error sent txid: %s", args[1]) log.Error("rpcClient returned error: %d, %s", response.Error.Code, response.Error.Message) } else { var s struct { Status string } err = response.GetObject(&s) if err != nil { log.Error("error on parsing response: %s", err.Error()) } else { log.Info("Status:%s", s.Status) } } } else { log.Error("unable to unmarshal metadata for node %s: %s", args[0], err.Error()) } } else { log.Error("node not found: %s", args[0]) } } else { cmd.Help() } }, }
AVAXWalletStatusCmd will get the status of a transaction for a particular node
var CallRPCCmd = &cobra.Command{ Use: "callrpc [node name] [endpoint] [method] [JSON params] [var scope] [var name]", Short: "Issues an RPC call to a node.", Long: `Issues an RPC call to a node endpoint for the specified method and params. Response is saved to the local varstore.`, Example: `callrpc n1 ext/bc/X avm.getBalance {"address":"X-KqpU28P2ipUxfTfwaT847wWxyXB4XuWad","assetID":"AVAX"} s v`, Args: cobra.MinimumNArgs(6), Run: func(cmd *cobra.Command, args []string) { log := cfg.Config.Log meta, err := pmgr.ProcManager.Metadata(args[0]) if err != nil { log.Error("process not found: %s", args[0]) return } var md node.Metadata if err = json.Unmarshal([]byte(meta), &md); err != nil { log.Error("unable to unmarshal metadata for process %s: %s", args[0], err.Error()) return } base := "http" if md.HTTPTLS { base = "https" } jrpcloc := fmt.Sprintf("%s://%s:%s/%s", base, md.Serverhost, md.HTTPport, args[1]) log.Info(jrpcloc) rpcClient := jsonrpc.NewClient(jrpcloc) argMap := make(map[string]interface{}) if err = json.Unmarshal([]byte(args[3]), &argMap); err != nil { log.Error("invalid JSON object: %s", args[3]) return } response, err := rpcClient.Call(args[2], argMap) if err != nil { log.Error("rpcClient returned error: %s", err.Error()) return } if response.Error != nil { log.Error("rpcClient returned error: %d, %s", response.Error.Code, response.Error.Message) return } resBytes, err := json.Marshal(response.Result) if err != nil { log.Error("rpcClient returned invalid JSON object: %v", response.Result) return } resVal := string(resBytes) log.Info("Response: %s", resVal) store, err := AvashVars.Get(args[4]) if err != nil { log.Error("store not found: %s", args[4]) return } store.Set(args[5], resVal) log.Info("Response saved to %q.%q", args[4], args[5]) }, }
CallRPCCmd issues an RPC to a node endpoint using JSONRPC protocol
var ExitCmd = &cobra.Command{ Use: "exit", Short: "Exit the shell.", Long: `Exit the shell, attempting to gracefully stop all processes first.`, Run: func(cmd *cobra.Command, args []string) { pmgr.ProcManager.StopAllProcesses() if pmgr.ProcManager.HasRunning() { cfg.Config.Log.Fatal("Unable to stop all processes, exiting anyway...") os.Exit(1) } cfg.Config.Log.Info("Cleanup successful, exiting...") os.Exit(0) }, }
ExitCmd represents the exit command
var NetworkCommand = &cobra.Command{ Use: "network", Short: "Tools for interacting with remote hosts.", Long: `Tools for interacting with remote hosts.`, Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, }
NetworkCommand represents the network command
var PMKillAllCmd = &cobra.Command{ Use: "killall [optional: delay in secs]", Short: "Kills all processes if currently running.", Long: `Kills all processes if currently running.`, Run: func(cmd *cobra.Command, args []string) { log := cfg.Config.Log delay := time.Duration(0) if len(args) >= 1 { if v, e := strconv.ParseInt(args[0], 10, 64); e == nil && v > 0 { delay = time.Duration(v) log.Info("all processes will be killed in %ds", int(delay)) } } delayRun(pmgr.ProcManager.KillAllProcesses, delay) }, }
PMKillAllCmd stops all processes in the procmanager
var PMKillCmd = &cobra.Command{ Use: "kill [node name] [optional: delay in secs]", Short: "Kills the process named if currently running.", Long: `Kills the process named if currently running.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 1 && args[0] != "" { log := cfg.Config.Log name := args[0] delay := time.Duration(0) if len(args) >= 2 { if v, e := strconv.ParseInt(args[1], 10, 64); e == nil && v > 0 { delay = time.Duration(v) log.Info("process will stop in %ds: %s", int(delay), name) } } kill := func() { err := pmgr.ProcManager.KillProcess(name) if err != nil { log.Error(err.Error()) } } delayRun(kill, delay) } else { cmd.Help() } }, }
PMKillCmd represents the stop operation on the procmanager command
var PMListCmd = &cobra.Command{ Use: "list", Short: "Lists the processes currently running.", Long: `Lists the processes currently running in tabular format.`, Run: func(cmd *cobra.Command, args []string) { table := tablewriter.NewWriter(AvalancheShell.rl.Stdout()) table = pmgr.ProcManager.ProcessTable(table) table.Render() }, }
PMListCmd represents the list operation on the procmanager command
var PMMetadataCmd = &cobra.Command{ Use: "metadata [node name]", Short: "Prints the metadata associated with the node name.", Long: `Prints the metadata associated with the node name.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 1 && args[0] != "" { log := cfg.Config.Log name := args[0] metadata, err := pmgr.ProcManager.Metadata(name) if err != nil { log.Error(err.Error()) } log.Info(metadata) } else { cmd.Help() } }, }
PMMetadataCmd represents the list operation on the procmanager command
var PMRemoveAllCmd = &cobra.Command{ Use: "removeall [optional: delay in secs]", Short: "Removes all processes.", Long: `Removes all processes. It will stop the process if it is running.`, Run: func(cmd *cobra.Command, args []string) { log := cfg.Config.Log delay := time.Duration(0) if len(args) >= 1 { if v, e := strconv.ParseInt(args[0], 10, 64); e == nil && v > 0 { delay = time.Duration(v) log.Info("all processes will be removed in %ds", int(delay)) } } delayRun(pmgr.ProcManager.RemoveAllProcesses, delay) }, }
PMRemoveAllCmd represents the list operation on the procmanager command
var PMRemoveCmd = &cobra.Command{ Use: "remove [node name] [optional: delay in secs]", Short: "Removes the process named.", Long: `Removes the process named. It will stop the process if it is running.`, Run: func(cmd *cobra.Command, args []string) { if !(len(args) >= 1 && args[0] != "") { cmd.Help() } log := cfg.Config.Log name := args[0] delay := time.Duration(0) if len(args) >= 2 { if v, e := strconv.ParseInt(args[1], 10, 64); e == nil && v > 0 { delay = time.Duration(v) log.Info("process will be removed in %ds: %s", int(delay), name) } } remove := func() { err := pmgr.ProcManager.RemoveProcess(name) if err != nil { log.Error(err.Error()) } } delayRun(remove, delay) }, }
PMRemoveCmd represents the list operation on the procmanager command
var PMStartAllCmd = &cobra.Command{ Use: "startall [optional: delay in secs]", Short: "Starts all processes if currently stopped.", Long: `Starts all processes if currently stopped.`, Run: func(cmd *cobra.Command, args []string) { log := cfg.Config.Log delay := time.Duration(0) if len(args) >= 1 { if v, e := strconv.ParseInt(args[0], 10, 64); e == nil && v > 0 { delay = time.Duration(v) log.Info("all processes will start in %ds", int(delay)) } } delayRun(pmgr.ProcManager.StartAllProcesses, delay) }, }
PMStartAllCmd starts all processes in the procmanager
var PMStartCmd = &cobra.Command{ Use: "start [node name] [optional: delay in secs]", Short: "Starts the process named if not currently running.", Long: `Starts the process named if not currently running.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 1 && args[0] != "" { log := cfg.Config.Log name := args[0] delay := time.Duration(0) if len(args) >= 2 { if v, e := strconv.ParseInt(args[1], 10, 64); e == nil && v > 0 { delay = time.Duration(v) log.Info("process will start in %ds: %s", int(delay), name) } } start := func() { err := pmgr.ProcManager.StartProcess(name) if err != nil { log.Error(err.Error()) } } delayRun(start, delay) } else { cmd.Help() } }, }
PMStartCmd represents the start operation on the procmanager command
var PMStopAllCmd = &cobra.Command{ Use: "stopall [optional: delay in secs]", Short: "Stops all processes if currently running.", Long: `Stops all processes if currently running.`, Run: func(cmd *cobra.Command, args []string) { log := cfg.Config.Log delay := time.Duration(0) if len(args) >= 1 { if v, e := strconv.ParseInt(args[0], 10, 64); e == nil && v > 0 { delay = time.Duration(v) log.Info("all processes will stop in %ds", int(delay)) } } delayRun(pmgr.ProcManager.StopAllProcesses, delay) }, }
PMStopAllCmd stops all processes in the procmanager
var PMStopCmd = &cobra.Command{ Use: "stop [node name] [optional: delay in secs]", Short: "Stops the process named if currently running.", Long: `Stops the process named if currently running.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 1 && args[0] != "" { log := cfg.Config.Log name := args[0] delay := time.Duration(0) if len(args) >= 2 { if v, e := strconv.ParseInt(args[1], 10, 64); e == nil && v > 0 { delay = time.Duration(v) log.Info("process will stop in %ds: %s", int(delay), name) } } stop := func() { err := pmgr.ProcManager.StopProcess(name) if err != nil { log.Error(err.Error()) } } delayRun(stop, delay) } else { cmd.Help() } }, }
PMStopCmd represents the stop operation on the procmanager command
var ProcmanagerCmd = &cobra.Command{ Use: "procmanager", Short: "Access the process manager for the avash client.", Long: `Access the process manager for the avash client. Using this command you can list, stop, and start processes registered with the process manager.`, Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, }
ProcmanagerCmd represents the procmanager command
var RootCmd *cobra.Command
var RunScriptCmd = &cobra.Command{ Use: "runscript [script file]", Short: "Runs the provided script.", Long: `Runs the script provided in the argument, relative to the present working directory.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 1 { log := cfg.Config.Log L := lua.NewState() L.OpenLibs() defer L.Close() L.SetGlobal("avash_call", L.NewFunction(AvashCall)) L.SetGlobal("avash_sleepmicro", L.NewFunction(AvashSleepMicro)) L.SetGlobal("avash_setvar", L.NewFunction(AvashSetVar)) filename := args[0] log.Info("RunScript: Running " + filename) if err := L.DoFile(filename); err != nil { log.Error("RunScript: Failed to run " + filename + "\n" + err.Error()) } else { log.Info("RunScript: Successfully ran " + filename) } } else { cmd.Help() } }, }
RunScriptCmd represents the exit command
var SSHDeployCommand = &cobra.Command{ Use: "deploy [config file]", Short: "Deploys a remote network of nodes.", Long: `Deploys a remote network of nodes from the provided config file.`, Run: func(cmd *cobra.Command, args []string) { log := cfg.Config.Log netCfg, err := network.InitConfig(args[0]) if err != nil { log.Error(err.Error()) return } log.Info("Deployment starting... (this process typically takes 3-6 minutes depending on host)") if err := network.Deploy(netCfg, false); err != nil { log.Error(err.Error()) return } log.Info("All hosts finished.") }, }
SSHDeployCommand deploys a network config through an SSH client
var SSHRemoveCommand = &cobra.Command{ Use: "remove [config file]", Short: "Removes a remote network of nodes.", Long: `Removes a remote network of nodes from the provided config file.`, Run: func(cmd *cobra.Command, args []string) { log := cfg.Config.Log netCfg, err := network.InitConfig(args[0]) if err != nil { log.Error(err.Error()) return } log.Info("Removal starting...") if err := network.Remove(netCfg, false); err != nil { log.Error(err.Error()) return } log.Info("All hosts finished.") }, }
SSHRemoveCommand removes a network config through an SSH client
var SetOutputCmd = &cobra.Command{ Use: "setoutput [log output] [log level]", Short: "Sets log output.", Long: `Sets the log level of a specific log output type.`, Run: func(cmd *cobra.Command, args []string) { if len(args) < 2 { cmd.Help() return } log := cfg.Config.Log output, outErr := logging.ToOutput(args[0]) level, lvlErr := logging.ToLevel(args[1]) if outErr != nil { log.Error(outErr.Error()) return } if lvlErr != nil { log.Error(lvlErr.Error()) return } log.SetLevel(output, level) log.Info("%s log level set: %s", output.String(), level.String()) }, }
SetOutputCmd sets the shell output type and verbosity
var StartnodeCmd = &cobra.Command{ Use: "startnode [node name] args...", Short: "Starts a node process and gives it a name.", Long: `Starts an Avalanche client node using pmgo and gives it a name. Example: startnode MyNode1 --public-ip=127.0.0.1 --staking-port=9651 --http-port=9650 ... `, Run: func(cmd *cobra.Command, args []string) { if len(args) < 1 { cmd.Help() return } log := cfg.Config.Log name := args[0] datadir := cfg.Config.DataDir basename := sanitize.BaseName(name) datapath := datadir + "/" + basename if basename == "" { log.Error("Process name can't be empty") return } err := validateConsensusArgs( flags.SnowSampleSize, flags.SnowQuorumSize, flags.SnowVirtuousCommitThreshold, flags.SnowRogueCommitThreshold, ) if err != nil { log.Error(err.Error()) return } args, md := node.FlagsToArgs(flags, sanitize.Path(datapath), false) defer func() { flags = node.DefaultFlags() }() mdbytes, _ := json.MarshalIndent(md, " ", " ") metadata := string(mdbytes) meta := flags.Meta if meta != "" { metadata = meta } avalancheLocation := flags.ClientLocation if avalancheLocation == "" { avalancheLocation = cfg.Config.AvalancheLocation } err = pmgr.ProcManager.AddProcess(avalancheLocation, "avalanche node", args, name, metadata, nil, nil, nil) if err != nil { log.Error(err.Error()) return } log.Info("Created process %s.", name) pmgr.ProcManager.StartProcess(name) }, }
StartnodeCmd represents the startnode command
var VarStoreCmd = &cobra.Command{ Use: "varstore", Short: "Tools for creating variable stores and printing variables within them.", Long: `Tools for creating variable stores and printing variables within them. Using this command you can create variable stores, list all variables they store, and print data placed into these stores. Variable assigment and update is often managed by avash commands.`, Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, }
VarStoreCmd represents the vars command
var VarStoreCreateCmd = &cobra.Command{ Use: "create [store name]", Short: "Creates a variable store.", Long: `Creates a variable store. If it exists, it prints "name conflict" otherwise it prints "store created".`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 1 { log := cfg.Config.Log store := args[0] if err := AvashVars.Create(store); err == nil { log.Info("store created: " + store) } else { log.Error("name conflict: " + store) } } else { cmd.Help() } }, }
VarStoreCreateCmd will attempt to get a genesis key and send a transaction
var VarStoreListCmd = &cobra.Command{ Use: "list [store name]", Short: "Lists all stores. If store provided, lists all variables in the store.", Long: `Lists all stores. If store provided, lists all variables in the store. If the store exists, it will print a new-line separated string of variables in this store. If the store does not exist, it will print "store not found".`, Run: func(cmd *cobra.Command, args []string) { log := cfg.Config.Log results := []string{} if len(args) >= 1 { if store, err := AvashVars.Get(args[0]); err == nil { results = store.List() } else { log.Error("store not found:" + args[0]) } } else { results = AvashVars.List() } radix.Sort(results) for _, v := range results { log.Info(v) } }, }
VarStoreListCmd will attempt to get a genesis key and send a transaction
var VarStorePrintCmd = &cobra.Command{ Use: "print [store] [variable]", Short: "Prints a variable that is within the store.", Long: `Prints a variable that is within the store. If it doesn't exist, it prints the default JSON string "{}".`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 2 { log := cfg.Config.Log if store, err := AvashVars.Get(args[0]); err == nil { if v, e := store.Get(args[1]); e == nil { log.Info(v) } else { log.Info("{}") } } else { log.Info("{}") } } else { cmd.Help() } }, }
VarStorePrintCmd will attempt to get a genesis key and send a transaction
var VarStoreSetCmd = &cobra.Command{ Use: "set [store] [variable] [value]", Short: "Sets a simple variable that within the store.", Long: `Sets a simple variable that within the store. Store must exist. May not have spaces, even quoted. Existing values are overwritten.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 3 { log := cfg.Config.Log if store, err := AvashVars.Get(args[0]); err == nil { store.Set(args[1], args[2]) log.Info("variable set: %q.%q=%q", args[0], args[1], args[2]) } else { log.Error("store not found: " + args[0]) } } else { cmd.Help() } }, }
VarStoreSetCmd will attempt to get a genesis key and send a transaction
var VarStoreStoreDumpCmd = &cobra.Command{ Use: "storedump [store] [filename]", Short: "Writes the store to a file.", Long: `Writes the store to a file.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 2 { log := cfg.Config.Log if store, err := AvashVars.Get(args[0]); err == nil { stashdir := cfg.Config.DataDir basename := filepath.Base(args[1]) basedir := filepath.Dir(stashdir + "/" + args[1]) os.MkdirAll(basedir, os.ModePerm) outputfile := basedir + "/" + basename if marshalled, err := store.JSON(); err == nil { if err := ioutil.WriteFile(outputfile, marshalled, 0755); err != nil { log.Error("unable to write file: %s - %s", string(outputfile), err.Error()) } else { log.Info("VarStore written to: %s", outputfile) } } else { log.Error("unable to marshal: %s", err.Error()) } } else { log.Error("store not found: %s", args[0]) } } else { cmd.Help() } }, }
VarStoreStoreDumpCmd writes the store to the filename specified in the stash
var VarStoreVarDumpCmd = &cobra.Command{ Use: "vardump [store] [variable] [filename]", Short: "Writes the variable to a file.", Long: `Writes the variable set to a file.`, Run: func(cmd *cobra.Command, args []string) { if len(args) >= 3 { log := cfg.Config.Log if store, err := AvashVars.Get(args[0]); err == nil { if variable, e := store.Get(args[1]); e == nil { stashdir := cfg.Config.DataDir basename := filepath.Base(args[2]) basedir := filepath.Dir(stashdir + "/" + args[2]) os.MkdirAll(basedir, os.ModePerm) outputfile := basedir + "/" + basename if err := ioutil.WriteFile(outputfile, []byte(variable), 0755); err != nil { log.Error("unable to write file: %s - %s", string(outputfile), err.Error()) } else { log.Info("VarStore written to: %s", outputfile) } } else { log.Error("variable not found: %s -> %s", args[0], args[1]) } } else { log.Error("store not found: %s", args[0]) } } else { cmd.Help() } }, }
VarStoreVarDumpCmd writes the variable to the filename specified in the stash
Functions ¶
func AvashSetVar ¶
AvashSetVar sets a variable to a string, necessary because `varstore set` can't deal with spaces yet
func AvashSleepMicro ¶
AvashSleepMicro function to sleep for N microseconds
Types ¶
type Shell ¶
type Shell struct {
// contains filtered or unexported fields
}
Shell is a helper struct for storing history and the instance of the shell prompt
var AvalancheShell *Shell
AvalancheShell is the shell for our little client
type VarScope ¶
VarScope is a scope of the variable