package main import ( "fmt" "os" "path" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/tendermint/tendermint/libs/cli" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/lcd" "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" "github.com/cosmos/cosmos-sdk/x/auth/types" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" ) var ( appCodec, cdc = simapp.MakeCodecs() ) func init() { authclient.Codec = appCodec } func main() { // Configure cobra to sort commands cobra.EnableCommandSorting = false // Read in the configuration file for the sdk config := sdk.GetConfig() config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub) config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub) config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub) config.Seal() // TODO: setup keybase, viper object, etc. to be passed into // the below functions and eliminate global vars, like we do // with the cdc rootCmd := &cobra.Command{ Use: "simcli", Short: "Command line interface for interacting with simd", } // Add --chain-id to persistent flags and mark it required rootCmd.PersistentFlags().String(flags.FlagChainID, "", "Chain ID of tendermint node") rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error { return initConfig(rootCmd) } // Construct Root Command rootCmd.AddCommand( rpc.StatusCommand(), client.ConfigCmd(simapp.DefaultCLIHome), queryCmd(cdc), txCmd(cdc), flags.LineBreak, lcd.ServeCommand(cdc, registerRoutes), flags.LineBreak, keys.Commands(), flags.LineBreak, flags.NewCompletionCmd(rootCmd, true), ) // Add flags and prefix all env exposed with GA executor := cli.PrepareMainCmd(rootCmd, "GA", simapp.DefaultCLIHome) err := executor.Execute() if err != nil { fmt.Printf("Failed executing CLI command: %s, exiting...\n", err) os.Exit(1) } } func queryCmd(cdc *codec.Codec) *cobra.Command { queryCmd := &cobra.Command{ Use: "query", Aliases: []string{"q"}, Short: "Querying subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, } queryCmd.AddCommand( authcmd.GetAccountCmd(cdc), flags.LineBreak, rpc.ValidatorCommand(cdc), rpc.BlockCommand(), authcmd.QueryTxsByEventsCmd(cdc), authcmd.QueryTxCmd(cdc), flags.LineBreak, ) // add modules' query commands clientCtx := client.Context{} clientCtx = clientCtx. WithJSONMarshaler(appCodec). WithCodec(cdc) simapp.ModuleBasics.AddQueryCommands(queryCmd, clientCtx) return queryCmd } func txCmd(cdc *codec.Codec) *cobra.Command { txCmd := &cobra.Command{ Use: "tx", Short: "Transactions subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, } clientCtx := client.Context{} clientCtx = clientCtx. WithJSONMarshaler(appCodec). WithTxGenerator(types.StdTxGenerator{Cdc: cdc}). WithAccountRetriever(types.NewAccountRetriever(appCodec)). WithCodec(cdc) txCmd.AddCommand( bankcmd.NewSendTxCmd(clientCtx), flags.LineBreak, authcmd.GetSignCommand(cdc), authcmd.GetSignBatchCommand(cdc), authcmd.GetMultiSignCommand(cdc), authcmd.GetValidateSignaturesCommand(cdc), flags.LineBreak, authcmd.GetBroadcastCommand(cdc), authcmd.GetEncodeCommand(cdc), authcmd.GetDecodeCommand(cdc), flags.LineBreak, ) // add modules' tx commands simapp.ModuleBasics.AddTxCommands(txCmd, clientCtx) return txCmd } // registerRoutes registers the routes from the different modules for the REST client. // NOTE: details on the routes added for each module are in the module documentation func registerRoutes(rs *lcd.RestServer) { rpc.RegisterRoutes(rs.ClientCtx, rs.Mux) authrest.RegisterTxRoutes(rs.ClientCtx, rs.Mux) simapp.ModuleBasics.RegisterRESTRoutes(rs.ClientCtx, rs.Mux) } func initConfig(cmd *cobra.Command) error { home, err := cmd.PersistentFlags().GetString(cli.HomeFlag) if err != nil { return err } cfgFile := path.Join(home, "config", "config.toml") if _, err := os.Stat(cfgFile); err == nil { viper.SetConfigFile(cfgFile) if err := viper.ReadInConfig(); err != nil { return err } } if err := viper.BindPFlag(flags.FlagChainID, cmd.PersistentFlags().Lookup(flags.FlagChainID)); err != nil { return err } if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil { return err } return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag)) }