The command processes list of transactions from file (one StdTx each line), generate signed transactions or signatures and print their JSON encoding, delimited by '\n'. As the signatures are generated, the command increments the sequence number automatically. Author: @jgimeno Reviewed-by: @alessio
181 lines
5.0 KiB
Go
181 lines
5.0 KiB
Go
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))
|
|
}
|