Synopsis This document details how to build CLI and REST interfaces for a module. Examples from various Cosmos SDK modules are included.

Pre-requisite Readings

CLI

One of the main interfaces for an application is the command-line interface. This entrypoint adds commands from the application’s modules enabling end-users to create messages wrapped in transactions and queries. The CLI files are typically found in the module’s ./client/cli folder.

Transaction Commands

In order to create messages that trigger state changes, end-users must create transactions that wrap and deliver the messages. A transaction command creates a transaction that includes one or more messages. Transaction commands typically have their own tx.go file that lives within the module’s ./client/cli folder. The commands are specified in getter functions and the name of the function should include the name of the command. Here is an example from the x/bank module:
package cli

import (
    
	"fmt"
    "github.com/spf13/cobra"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/client/flags"
    "github.com/cosmos/cosmos-sdk/client/tx"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/x/bank/types"
)

var FlagSplit = "split"

/ NewTxCmd returns a root CLI command handler for all x/bank transaction commands.
func NewTxCmd() *cobra.Command {
    txCmd := &cobra.Command{
    Use:                        types.ModuleName,
    Short:                      "Bank transaction subcommands",
    DisableFlagParsing:         true,
    SuggestionsMinimumDistance: 2,
    RunE:                       client.ValidateCmd,
}

txCmd.AddCommand(
		NewSendTxCmd(),
		NewMultiSendTxCmd(),
	)

return txCmd
}

/ NewSendTxCmd returns a CLI command handler for creating a MsgSend transaction.
func NewSendTxCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "send [from_key_or_address] [to_address] [amount]",
    Short: "Send funds from one account to another.",
    Long: `Send funds from one account to another.
Note, the '--from' flag is ignored as it is implied from [from_key_or_address].
When using '--dry-run' a key name cannot be used, only a bech32 address.
`,
    Args: cobra.ExactArgs(3),
    RunE: func(cmd *cobra.Command, args []string)

error {
    cmd.Flags().Set(flags.FlagFrom, args[0])

clientCtx, err := client.GetClientTxContext(cmd)
    if err != nil {
    return err
}

toAddr, err := sdk.AccAddressFromBech32(args[1])
    if err != nil {
    return err
}

coins, err := sdk.ParseCoinsNormalized(args[2])
    if err != nil {
    return err
}
    msg := types.NewMsgSend(clientCtx.GetFromAddress(), toAddr, coins)

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}

/ NewMultiSendTxCmd returns a CLI command handler for creating a MsgMultiSend transaction.
/ For a better UX this command is limited to send funds from one account to two or more accounts.
func NewMultiSendTxCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "multi-send [from_key_or_address] [to_address_1, to_address_2, ...] [amount]",
    Short: "Send funds from one account to two or more accounts.",
    Long: `Send funds from one account to two or more accounts.
By default, sends the [amount] to each address of the list.
Using the '--split' flag, the [amount] is split equally between the addresses.
Note, the '--from' flag is ignored as it is implied from [from_key_or_address].
When using '--dry-run' a key name cannot be used, only a bech32 address.
`,
    Args: cobra.MinimumNArgs(4),
    RunE: func(cmd *cobra.Command, args []string)

error {
    cmd.Flags().Set(flags.FlagFrom, args[0])

clientCtx, err := client.GetClientTxContext(cmd)
    if err != nil {
    return err
}

coins, err := sdk.ParseCoinsNormalized(args[len(args)-1])
    if err != nil {
    return err
}
    if coins.IsZero() {
    return fmt.Errorf("must send positive amount")
}

split, err := cmd.Flags().GetBool(FlagSplit)
    if err != nil {
    return err
}
    totalAddrs := sdk.NewInt(int64(len(args) - 2))
			/ coins to be received by the addresses
    sendCoins := coins
    if split {
    sendCoins = coins.QuoInt(totalAddrs)
}

var output []types.Output
    for _, arg := range args[1 : len(args)-1] {
    toAddr, err := sdk.AccAddressFromBech32(arg)
    if err != nil {
    return err
}

output = append(output, types.NewOutput(toAddr, sendCoins))
}

			/ amount to be send from the from address
			var amount sdk.Coins
    if split {
				/ user input: 1000stake to send to 3 addresses
				/ actual: 333stake to each address (=> 999stake actually sent)

amount = sendCoins.MulInt(totalAddrs)
}

else {
    amount = coins.MulInt(totalAddrs)
}
    msg := types.NewMsgMultiSend([]types.Input{
    types.NewInput(clientCtx.FromAddress, amount)
}, output)

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

cmd.Flags().Bool(FlagSplit, false, "Send the equally split token amount to each address")

flags.AddTxFlagsToCmd(cmd)

return cmd
}
In the example, NewSendTxCmd() creates and returns the transaction command for a transaction that wraps and delivers MsgSend. MsgSend is the message used to send tokens from one account to another. In general, the getter function does the following:
  • Constructs the command: Read the Cobra Documentation for more detailed information on how to create commands.
    • Use: Specifies the format of the user input required to invoke the command. In the example above, send is the name of the transaction command and [from_key_or_address], [to_address], and [amount] are the arguments.
    • Args: The number of arguments the user provides. In this case, there are exactly three: [from_key_or_address], [to_address], and [amount].
    • Short and Long: Descriptions for the command. A Short description is expected. A Long description can be used to provide additional information that is displayed when a user adds the --help flag.
    • RunE: Defines a function that can return an error. This is the function that is called when the command is executed. This function encapsulates all of the logic to create a new transaction.
      • The function typically starts by getting the clientCtx, which can be done with client.GetClientTxContext(cmd). The clientCtx contains information relevant to transaction handling, including information about the user. In this example, the clientCtx is used to retrieve the address of the sender by calling clientCtx.GetFromAddress().
      • If applicable, the command’s arguments are parsed. In this example, the arguments [to_address] and [amount] are both parsed.
      • A message is created using the parsed arguments and information from the clientCtx. The constructor function of the message type is called directly. In this case, types.NewMsgSend(fromAddr, toAddr, amount). Its good practice to call, if possible, the necessary message validation methods before broadcasting the message.
      • Depending on what the user wants, the transaction is either generated offline or signed and broadcasted to the preconfigured node using tx.GenerateOrBroadcastTxCLI(clientCtx, flags, msg).
  • Adds transaction flags: All transaction commands must add a set of transaction flags. The transaction flags are used to collect additional information from the user (e.g. the amount of fees the user is willing to pay). The transaction flags are added to the constructed command using AddTxFlagsToCmd(cmd).
  • Returns the command: Finally, the transaction command is returned.
Each module must implement NewTxCmd(), which aggregates all of the transaction commands of the module. Here is an example from the x/bank module:
package cli

import (
    
	"fmt"
    "github.com/spf13/cobra"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/client/flags"
    "github.com/cosmos/cosmos-sdk/client/tx"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/x/bank/types"
)

var FlagSplit = "split"

/ NewTxCmd returns a root CLI command handler for all x/bank transaction commands.
func NewTxCmd() *cobra.Command {
    txCmd := &cobra.Command{
    Use:                        types.ModuleName,
    Short:                      "Bank transaction subcommands",
    DisableFlagParsing:         true,
    SuggestionsMinimumDistance: 2,
    RunE:                       client.ValidateCmd,
}

txCmd.AddCommand(
		NewSendTxCmd(),
		NewMultiSendTxCmd(),
	)

return txCmd
}

/ NewSendTxCmd returns a CLI command handler for creating a MsgSend transaction.
func NewSendTxCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "send [from_key_or_address] [to_address] [amount]",
    Short: "Send funds from one account to another.",
    Long: `Send funds from one account to another.
Note, the '--from' flag is ignored as it is implied from [from_key_or_address].
When using '--dry-run' a key name cannot be used, only a bech32 address.
`,
    Args: cobra.ExactArgs(3),
    RunE: func(cmd *cobra.Command, args []string)

error {
    cmd.Flags().Set(flags.FlagFrom, args[0])

clientCtx, err := client.GetClientTxContext(cmd)
    if err != nil {
    return err
}

toAddr, err := sdk.AccAddressFromBech32(args[1])
    if err != nil {
    return err
}

coins, err := sdk.ParseCoinsNormalized(args[2])
    if err != nil {
    return err
}
    msg := types.NewMsgSend(clientCtx.GetFromAddress(), toAddr, coins)

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}

/ NewMultiSendTxCmd returns a CLI command handler for creating a MsgMultiSend transaction.
/ For a better UX this command is limited to send funds from one account to two or more accounts.
func NewMultiSendTxCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "multi-send [from_key_or_address] [to_address_1, to_address_2, ...] [amount]",
    Short: "Send funds from one account to two or more accounts.",
    Long: `Send funds from one account to two or more accounts.
By default, sends the [amount] to each address of the list.
Using the '--split' flag, the [amount] is split equally between the addresses.
Note, the '--from' flag is ignored as it is implied from [from_key_or_address].
When using '--dry-run' a key name cannot be used, only a bech32 address.
`,
    Args: cobra.MinimumNArgs(4),
    RunE: func(cmd *cobra.Command, args []string)

error {
    cmd.Flags().Set(flags.FlagFrom, args[0])

clientCtx, err := client.GetClientTxContext(cmd)
    if err != nil {
    return err
}

coins, err := sdk.ParseCoinsNormalized(args[len(args)-1])
    if err != nil {
    return err
}
    if coins.IsZero() {
    return fmt.Errorf("must send positive amount")
}

split, err := cmd.Flags().GetBool(FlagSplit)
    if err != nil {
    return err
}
    totalAddrs := sdk.NewInt(int64(len(args) - 2))
			/ coins to be received by the addresses
    sendCoins := coins
    if split {
    sendCoins = coins.QuoInt(totalAddrs)
}

var output []types.Output
    for _, arg := range args[1 : len(args)-1] {
    toAddr, err := sdk.AccAddressFromBech32(arg)
    if err != nil {
    return err
}

output = append(output, types.NewOutput(toAddr, sendCoins))
}

			/ amount to be send from the from address
			var amount sdk.Coins
    if split {
				/ user input: 1000stake to send to 3 addresses
				/ actual: 333stake to each address (=> 999stake actually sent)

amount = sendCoins.MulInt(totalAddrs)
}

else {
    amount = coins.MulInt(totalAddrs)
}
    msg := types.NewMsgMultiSend([]types.Input{
    types.NewInput(clientCtx.FromAddress, amount)
}, output)

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

cmd.Flags().Bool(FlagSplit, false, "Send the equally split token amount to each address")

flags.AddTxFlagsToCmd(cmd)

return cmd
}
Each module must also implement the GetTxCmd() method for AppModuleBasic that simply returns NewTxCmd(). This allows the root command to easily aggregate all of the transaction commands for each module. Here is an example:
package bank

import (
    
	"context"
    "encoding/json"
    "fmt"
    "time"

	modulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
    "cosmossdk.io/core/appmodule"
    "cosmossdk.io/depinject"
	gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
	store "github.com/cosmos/cosmos-sdk/store/types"
    "github.com/cosmos/cosmos-sdk/telemetry"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/types/module"
	simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
    "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
    "github.com/cosmos/cosmos-sdk/x/bank/exported"
    "github.com/cosmos/cosmos-sdk/x/bank/keeper"
	v1bank "github.com/cosmos/cosmos-sdk/x/bank/migrations/v1"
    "github.com/cosmos/cosmos-sdk/x/bank/simulation"
    "github.com/cosmos/cosmos-sdk/x/bank/types"
	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
)

/ ConsensusVersion defines the current x/bank module consensus version.
const ConsensusVersion = 4

var (
	_ module.AppModule           = AppModule{
}
	_ module.AppModuleBasic      = AppModuleBasic{
}
	_ module.AppModuleSimulation = AppModule{
}
)

/ AppModuleBasic defines the basic application module used by the bank module.
type AppModuleBasic struct {
    cdc codec.Codec
}

/ Name returns the bank module's name.
func (AppModuleBasic)

Name()

string {
    return types.ModuleName
}

/ RegisterLegacyAminoCodec registers the bank module's types on the LegacyAmino codec.
func (AppModuleBasic)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    types.RegisterLegacyAminoCodec(cdc)
}

/ DefaultGenesis returns default genesis state as raw bytes for the bank
/ module.
func (AppModuleBasic)

DefaultGenesis(cdc codec.JSONCodec)

json.RawMessage {
    return cdc.MustMarshalJSON(types.DefaultGenesisState())
}

/ ValidateGenesis performs genesis state validation for the bank module.
func (AppModuleBasic)

ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage)

error {
    var data types.GenesisState
    if err := cdc.UnmarshalJSON(bz, &data); err != nil {
    return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
}

return data.Validate()
}

/ RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the bank module.
func (AppModuleBasic)

RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *gwruntime.ServeMux) {
    if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
    panic(err)
}
}

/ GetTxCmd returns the root tx command for the bank module.
func (AppModuleBasic)

GetTxCmd() *cobra.Command {
    return cli.NewTxCmd()
}

/ GetQueryCmd returns no root query command for the bank module.
func (AppModuleBasic)

GetQueryCmd() *cobra.Command {
    return cli.GetQueryCmd()
}

/ RegisterInterfaces registers interfaces and implementations of the bank module.
func (AppModuleBasic)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    types.RegisterInterfaces(registry)

	/ Register legacy interfaces for migration scripts.
	v1bank.RegisterInterfaces(registry)
}

/ AppModule implements an application module for the bank module.
type AppModule struct {
    AppModuleBasic

	keeper        keeper.Keeper
	accountKeeper types.AccountKeeper

	/ legacySubspace is used solely for migration of x/params managed parameters
	legacySubspace exported.Subspace
}

var _ appmodule.AppModule = AppModule{
}

/ IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (am AppModule)

IsOnePerModuleType() {
}

/ IsAppModule implements the appmodule.AppModule interface.
func (am AppModule)

IsAppModule() {
}

/ RegisterServices registers module services.
func (am AppModule)

RegisterServices(cfg module.Configurator) {
    types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))

types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
    m := keeper.NewMigrator(am.keeper.(keeper.BaseKeeper), am.legacySubspace)
    if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil {
    panic(fmt.Sprintf("failed to migrate x/bank from version 1 to 2: %v", err))
}
    if err := cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3); err != nil {
    panic(fmt.Sprintf("failed to migrate x/bank from version 2 to 3: %v", err))
}
    if err := cfg.RegisterMigration(types.ModuleName, 3, m.Migrate3to4); err != nil {
    panic(fmt.Sprintf("failed to migrate x/bank from version 3 to 4: %v", err))
}
}

/ NewAppModule creates a new AppModule object
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.AccountKeeper, ss exported.Subspace)

AppModule {
    return AppModule{
    AppModuleBasic: AppModuleBasic{
    cdc: cdc
},
		keeper:         keeper,
		accountKeeper:  accountKeeper,
		legacySubspace: ss,
}
}

/ Name returns the bank module's name.
func (AppModule)

Name()

string {
    return types.ModuleName
}

/ RegisterInvariants registers the bank module invariants.
func (am AppModule)

RegisterInvariants(ir sdk.InvariantRegistry) {
    keeper.RegisterInvariants(ir, am.keeper)
}

/ QuerierRoute returns the bank module's querier route name.
func (AppModule)

QuerierRoute()

string {
    return types.RouterKey
}

/ InitGenesis performs genesis initialization for the bank module. It returns
/ no validator updates.
func (am AppModule)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
    start := time.Now()

var genesisState types.GenesisState
	cdc.MustUnmarshalJSON(data, &genesisState)

telemetry.MeasureSince(start, "InitGenesis", "crisis", "unmarshal")

am.keeper.InitGenesis(ctx, &genesisState)

return []abci.ValidatorUpdate{
}
}

/ ExportGenesis returns the exported genesis state as raw bytes for the bank
/ module.
func (am AppModule)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

json.RawMessage {
    gs := am.keeper.ExportGenesis(ctx)

return cdc.MustMarshalJSON(gs)
}

/ ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule)

ConsensusVersion()

uint64 {
    return ConsensusVersion
}

/ AppModuleSimulation functions

/ GenerateGenesisState creates a randomized GenState of the bank module.
func (AppModule)

GenerateGenesisState(simState *module.SimulationState) {
    simulation.RandomizedGenState(simState)
}

/ ProposalContents doesn't return any content functions for governance proposals.
func (AppModule)

ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent {
    return nil
}

/ RegisterStoreDecoder registers a decoder for supply module's types
func (am AppModule)

RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {
}

/ WeightedOperations returns the all the gov module operations with their respective weights.
func (am AppModule)

WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
    return simulation.WeightedOperations(
		simState.AppParams, simState.Cdc, am.accountKeeper, am.keeper,
	)
}

/ App Wiring Setup

func init() {
    appmodule.Register(&modulev1.Module{
},
		appmodule.Provide(ProvideModule),
	)
}

type BankInputs struct {
    depinject.In

	Config *modulev1.Module
	Cdc    codec.Codec
	Key    *store.KVStoreKey

	AccountKeeper types.AccountKeeper

	/ LegacySubspace is used solely for migration of x/params managed parameters
	LegacySubspace exported.Subspace `optional:"true"`
}

type BankOutputs struct {
    depinject.Out

	BankKeeper keeper.BaseKeeper
	Module     appmodule.AppModule
}

func ProvideModule(in BankInputs)

BankOutputs {
	/ Configure blocked module accounts.
	/
	/ Default behavior for blockedAddresses is to regard any module mentioned in
	/ AccountKeeper's module account permissions as blocked.
    blockedAddresses := make(map[string]bool)
    if len(in.Config.BlockedModuleAccountsOverride) > 0 {
    for _, moduleName := range in.Config.BlockedModuleAccountsOverride {
    blockedAddresses[authtypes.NewModuleAddress(moduleName).String()] = true
}
	
}

else {
    for _, permission := range in.AccountKeeper.GetModulePermissions() {
    blockedAddresses[permission.GetAddress().String()] = true
}
	
}

	/ default to governance authority if not provided
    authority := authtypes.NewModuleAddress(govtypes.ModuleName)
    if in.Config.Authority != "" {
    authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority)
}
    bankKeeper := keeper.NewBaseKeeper(
		in.Cdc,
		in.Key,
		in.AccountKeeper,
		blockedAddresses,
		authority.String(),
	)
    m := NewAppModule(in.Cdc, bankKeeper, in.AccountKeeper, in.LegacySubspace)

return BankOutputs{
    BankKeeper: bankKeeper,
    Module: m
}
}

Query Commands

Queries allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own query.go file in the module’s ./client/cli folder. Like transaction commands, they are specified in getter functions. Here is an example of a query command from the x/auth module:
package cli

import (
    
	"context"
    "fmt"
    "strconv"
    "strings"
    "github.com/spf13/cobra"
	tmtypes "github.com/tendermint/tendermint/types"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/client/flags"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/types/errors"
    "github.com/cosmos/cosmos-sdk/types/query"
    "github.com/cosmos/cosmos-sdk/version"
	authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
    "github.com/cosmos/cosmos-sdk/x/auth/types"
)

const (
	flagEvents = "events"
	flagType   = "type"

	typeHash   = "hash"
	typeAccSeq = "acc_seq"
	typeSig    = "signature"

	eventFormat = "{
    eventType
}.{
    eventAttribute
}={
    value
}"
)

/ GetQueryCmd returns the transaction commands for this module
func GetQueryCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:                        types.ModuleName,
    Short:                      "Querying commands for the auth module",
    DisableFlagParsing:         true,
    SuggestionsMinimumDistance: 2,
    RunE:                       client.ValidateCmd,
}

cmd.AddCommand(
		GetAccountCmd(),
		GetAccountAddressByIDCmd(),
		GetAccountsCmd(),
		QueryParamsCmd(),
		QueryModuleAccountsCmd(),
		QueryModuleAccountByNameCmd(),
	)

return cmd
}

/ QueryParamsCmd returns the command handler for evidence parameter querying.
func QueryParamsCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "params",
    Short: "Query the current auth parameters",
    Args:  cobra.NoArgs,
    Long: strings.TrimSpace(`Query the current auth parameters:

$ <appd> query auth params
`),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{
})
    if err != nil {
    return err
}

return clientCtx.PrintProto(&res.Params)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

/ GetAccountCmd returns a query account that will display the state of the
/ account at a given address.
func GetAccountCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "account [address]",
    Short: "Query for account by address",
    Args:  cobra.ExactArgs(1),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}

key, err := sdk.AccAddressFromBech32(args[0])
    if err != nil {
    return err
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.Account(cmd.Context(), &types.QueryAccountRequest{
    Address: key.String()
})
    if err != nil {
    node, err2 := clientCtx.GetNode()
    if err2 != nil {
    return err2
}

status, err2 := node.Status(context.Background())
    if err2 != nil {
    return err2
}
    catchingUp := status.SyncInfo.CatchingUp
    if !catchingUp {
    return errors.Wrapf(err, "your node may be syncing, please check node status using `/status`")
}

return err
}

return clientCtx.PrintProto(res.Account)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

/ GetAccountAddressByIDCmd returns a query account that will display the account address of a given account id.
func GetAccountAddressByIDCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:     "address-by-acc-num [acc-num]",
    Aliases: []string{"address-by-id"
},
    Short:   "Query for an address by account number",
    Args:    cobra.ExactArgs(1),
    Example: fmt.Sprintf("%s q auth address-by-acc-num 1", version.AppName),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}

accNum, err := strconv.ParseUint(args[0], 10, 64)
    if err != nil {
    return err
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.AccountAddressByID(cmd.Context(), &types.QueryAccountAddressByIDRequest{
    AccountId: accNum,
})
    if err != nil {
    return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

/ GetAccountsCmd returns a query command that will display a list of accounts
func GetAccountsCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "accounts",
    Short: "Query all the accounts",
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}

pageReq, err := client.ReadPageRequest(cmd.Flags())
    if err != nil {
    return err
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.Accounts(cmd.Context(), &types.QueryAccountsRequest{
    Pagination: pageReq
})
    if err != nil {
    return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

flags.AddPaginationFlagsToCmd(cmd, "all-accounts")

return cmd
}

/ QueryAllModuleAccountsCmd returns a list of all the existing module accounts with their account information and permissions
func QueryModuleAccountsCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "module-accounts",
    Short: "Query all module accounts",
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.ModuleAccounts(context.Background(), &types.QueryModuleAccountsRequest{
})
    if err != nil {
    return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

/ QueryModuleAccountByNameCmd returns a command to
func QueryModuleAccountByNameCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:     "module-account [module-name]",
    Short:   "Query module account info by module name",
    Args:    cobra.ExactArgs(1),
    Example: fmt.Sprintf("%s q auth module-account auth", version.AppName),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}
    moduleName := args[0]
    if len(moduleName) == 0 {
    return fmt.Errorf("module name should not be empty")
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.ModuleAccountByName(context.Background(), &types.QueryModuleAccountByNameRequest{
    Name: moduleName
})
    if err != nil {
    return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

/ QueryTxsByEventsCmd returns a command to search through transactions by events.
func QueryTxsByEventsCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "txs",
    Short: "Query for paginated transactions that match a set of events",
    Long: strings.TrimSpace(
			fmt.Sprintf(`
Search for transactions that match the exact given events where results are paginated.
Each event takes the form of '%s'. Please refer
to each module's documentation for the full set of events to query for. Each module
documents its respective events under 'xx_events.md'.

Example:
$ %s query txs --%s 'message.sender=cosmos1...&message.action=withdraw_delegator_reward' --page 1 --limit 30
`, eventFormat, version.AppName, flagEvents),
		),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}

eventsRaw, _ := cmd.Flags().GetString(flagEvents)
    eventsStr := strings.Trim(eventsRaw, "'")

var events []string
    if strings.Contains(eventsStr, "&") {
    events = strings.Split(eventsStr, "&")
}

else {
    events = append(events, eventsStr)
}

var tmEvents []string
    for _, event := range events {
    if !strings.Contains(event, "=") {
    return fmt.Errorf("invalid event; event %s should be of the format: %s", event, eventFormat)
}

else if strings.Count(event, "=") > 1 {
    return fmt.Errorf("invalid event; event %s should be of the format: %s", event, eventFormat)
}
    tokens := strings.Split(event, "=")
    if tokens[0] == tmtypes.TxHeightKey {
    event = fmt.Sprintf("%s=%s", tokens[0], tokens[1])
}

else {
    event = fmt.Sprintf("%s='%s'", tokens[0], tokens[1])
}

tmEvents = append(tmEvents, event)
}

page, _ := cmd.Flags().GetInt(flags.FlagPage)

limit, _ := cmd.Flags().GetInt(flags.FlagLimit)

txs, err := authtx.QueryTxsByEvents(clientCtx, tmEvents, page, limit, "")
    if err != nil {
    return err
}

return clientCtx.PrintProto(txs)
},
}

flags.AddQueryFlagsToCmd(cmd)

cmd.Flags().Int(flags.FlagPage, query.DefaultPage, "Query a specific page of paginated results")

cmd.Flags().Int(flags.FlagLimit, query.DefaultLimit, "Query number of transactions results per page returned")

cmd.Flags().String(flagEvents, "", fmt.Sprintf("list of transaction events in the form of %s", eventFormat))

cmd.MarkFlagRequired(flagEvents)

return cmd
}

/ QueryTxCmd implements the default command for a tx query.
func QueryTxCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "tx --type=[hash|acc_seq|signature] [hash|acc_seq|signature]",
    Short: "Query for a transaction by hash, \"<addr>/<seq>\" combination or comma-separated signatures in a committed block",
    Long: strings.TrimSpace(fmt.Sprintf(`
Example:
$ %s query tx <hash>
$ %s query tx --%s=%s <addr>/<sequence>
$ %s query tx --%s=%s <sig1_base64>,<sig2_base64...>
`,
			version.AppName,
			version.AppName, flagType, typeAccSeq,
			version.AppName, flagType, typeSig)),
    Args: cobra.ExactArgs(1),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}

typ, _ := cmd.Flags().GetString(flagType)
    switch typ {
    case typeHash:
				{
    if args[0] == "" {
    return fmt.Errorf("argument should be a tx hash")
}

					/ If hash is given, then query the tx by hash.
					output, err := authtx.QueryTx(clientCtx, args[0])
    if err != nil {
    return err
}
    if output.Empty() {
    return fmt.Errorf("no transaction found with hash %s", args[0])
}

return clientCtx.PrintProto(output)
}
    case typeSig:
				{
    sigParts, err := ParseSigArgs(args)
    if err != nil {
    return err
}
    tmEvents := make([]string, len(sigParts))
    for i, sig := range sigParts {
    tmEvents[i] = fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, sig)
}

txs, err := authtx.QueryTxsByEvents(clientCtx, tmEvents, query.DefaultPage, query.DefaultLimit, "")
    if err != nil {
    return err
}
    if len(txs.Txs) == 0 {
    return fmt.Errorf("found no txs matching given signatures")
}
    if len(txs.Txs) > 1 {
						/ This case means there's a bug somewhere else in the code. Should not happen.
						return errors.ErrLogic.Wrapf("found %d txs matching given signatures", len(txs.Txs))
}

return clientCtx.PrintProto(txs.Txs[0])
}
    case typeAccSeq:
				{
    if args[0] == "" {
    return fmt.Errorf("`acc_seq` type takes an argument '<addr>/<seq>'")
}
    tmEvents := []string{
    fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeyAccountSequence, args[0]),
}

txs, err := authtx.QueryTxsByEvents(clientCtx, tmEvents, query.DefaultPage, query.DefaultLimit, "")
    if err != nil {
    return err
}
    if len(txs.Txs) == 0 {
    return fmt.Errorf("found no txs matching given address and sequence combination")
}
    if len(txs.Txs) > 1 {
						/ This case means there's a bug somewhere else in the code. Should not happen.
						return fmt.Errorf("found %d txs matching given address and sequence combination", len(txs.Txs))
}

return clientCtx.PrintProto(txs.Txs[0])
}

default:
				return fmt.Errorf("unknown --%s value %s", flagType, typ)
}
	
},
}

flags.AddQueryFlagsToCmd(cmd)

cmd.Flags().String(flagType, typeHash, fmt.Sprintf("The type to be used when querying tx, can be one of \"%s\", \"%s\", \"%s\"", typeHash, typeAccSeq, typeSig))

return cmd
}

/ ParseSigArgs parses comma-separated signatures from the CLI arguments.
func ParseSigArgs(args []string) ([]string, error) {
    if len(args) != 1 || args[0] == "" {
    return nil, fmt.Errorf("argument should be comma-separated signatures")
}

return strings.Split(args[0], ","), nil
}
In the example, GetAccountCmd() creates and returns a query command that returns the state of an account based on the provided account address. In general, the getter function does the following:
  • Constructs the command: Read the Cobra Documentation for more detailed information on how to create commands.
    • Use: Specifies the format of the user input required to invoke the command. In the example above, account is the name of the query command and [address] is the argument.
    • Args: The number of arguments the user provides. In this case, there is exactly one: [address].
    • Short and Long: Descriptions for the command. A Short description is expected. A Long description can be used to provide additional information that is displayed when a user adds the --help flag.
    • RunE: Defines a function that can return an error. This is the function that is called when the command is executed. This function encapsulates all of the logic to create a new query.
      • The function typically starts by getting the clientCtx, which can be done with client.GetClientQueryContext(cmd). The clientCtx contains information relevant to query handling.
      • If applicable, the command’s arguments are parsed. In this example, the argument [address] is parsed.
      • A new queryClient is initialized using NewQueryClient(clientCtx). The queryClient is then used to call the appropriate query.
      • The clientCtx.PrintProto method is used to format the proto.Message object so that the results can be printed back to the user.
  • Adds query flags: All query commands must add a set of query flags. The query flags are added to the constructed command using AddQueryFlagsToCmd(cmd).
  • Returns the command: Finally, the query command is returned.
Each module must implement GetQueryCmd(), which aggregates all of the query commands of the module. Here is an example from the x/auth module:
package cli

import (
    
	"context"
    "fmt"
    "strconv"
    "strings"
    "github.com/spf13/cobra"
	tmtypes "github.com/tendermint/tendermint/types"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/client/flags"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/types/errors"
    "github.com/cosmos/cosmos-sdk/types/query"
    "github.com/cosmos/cosmos-sdk/version"
	authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
    "github.com/cosmos/cosmos-sdk/x/auth/types"
)

const (
	flagEvents = "events"
	flagType   = "type"

	typeHash   = "hash"
	typeAccSeq = "acc_seq"
	typeSig    = "signature"

	eventFormat = "{
    eventType
}.{
    eventAttribute
}={
    value
}"
)

/ GetQueryCmd returns the transaction commands for this module
func GetQueryCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:                        types.ModuleName,
    Short:                      "Querying commands for the auth module",
    DisableFlagParsing:         true,
    SuggestionsMinimumDistance: 2,
    RunE:                       client.ValidateCmd,
}

cmd.AddCommand(
		GetAccountCmd(),
		GetAccountAddressByIDCmd(),
		GetAccountsCmd(),
		QueryParamsCmd(),
		QueryModuleAccountsCmd(),
		QueryModuleAccountByNameCmd(),
	)

return cmd
}

/ QueryParamsCmd returns the command handler for evidence parameter querying.
func QueryParamsCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "params",
    Short: "Query the current auth parameters",
    Args:  cobra.NoArgs,
    Long: strings.TrimSpace(`Query the current auth parameters:

$ <appd> query auth params
`),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{
})
    if err != nil {
    return err
}

return clientCtx.PrintProto(&res.Params)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

/ GetAccountCmd returns a query account that will display the state of the
/ account at a given address.
func GetAccountCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "account [address]",
    Short: "Query for account by address",
    Args:  cobra.ExactArgs(1),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}

key, err := sdk.AccAddressFromBech32(args[0])
    if err != nil {
    return err
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.Account(cmd.Context(), &types.QueryAccountRequest{
    Address: key.String()
})
    if err != nil {
    node, err2 := clientCtx.GetNode()
    if err2 != nil {
    return err2
}

status, err2 := node.Status(context.Background())
    if err2 != nil {
    return err2
}
    catchingUp := status.SyncInfo.CatchingUp
    if !catchingUp {
    return errors.Wrapf(err, "your node may be syncing, please check node status using `/status`")
}

return err
}

return clientCtx.PrintProto(res.Account)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

/ GetAccountAddressByIDCmd returns a query account that will display the account address of a given account id.
func GetAccountAddressByIDCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:     "address-by-acc-num [acc-num]",
    Aliases: []string{"address-by-id"
},
    Short:   "Query for an address by account number",
    Args:    cobra.ExactArgs(1),
    Example: fmt.Sprintf("%s q auth address-by-acc-num 1", version.AppName),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}

accNum, err := strconv.ParseUint(args[0], 10, 64)
    if err != nil {
    return err
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.AccountAddressByID(cmd.Context(), &types.QueryAccountAddressByIDRequest{
    AccountId: accNum,
})
    if err != nil {
    return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

/ GetAccountsCmd returns a query command that will display a list of accounts
func GetAccountsCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "accounts",
    Short: "Query all the accounts",
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}

pageReq, err := client.ReadPageRequest(cmd.Flags())
    if err != nil {
    return err
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.Accounts(cmd.Context(), &types.QueryAccountsRequest{
    Pagination: pageReq
})
    if err != nil {
    return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

flags.AddPaginationFlagsToCmd(cmd, "all-accounts")

return cmd
}

/ QueryAllModuleAccountsCmd returns a list of all the existing module accounts with their account information and permissions
func QueryModuleAccountsCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "module-accounts",
    Short: "Query all module accounts",
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.ModuleAccounts(context.Background(), &types.QueryModuleAccountsRequest{
})
    if err != nil {
    return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

/ QueryModuleAccountByNameCmd returns a command to
func QueryModuleAccountByNameCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:     "module-account [module-name]",
    Short:   "Query module account info by module name",
    Args:    cobra.ExactArgs(1),
    Example: fmt.Sprintf("%s q auth module-account auth", version.AppName),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}
    moduleName := args[0]
    if len(moduleName) == 0 {
    return fmt.Errorf("module name should not be empty")
}
    queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.ModuleAccountByName(context.Background(), &types.QueryModuleAccountByNameRequest{
    Name: moduleName
})
    if err != nil {
    return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

/ QueryTxsByEventsCmd returns a command to search through transactions by events.
func QueryTxsByEventsCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "txs",
    Short: "Query for paginated transactions that match a set of events",
    Long: strings.TrimSpace(
			fmt.Sprintf(`
Search for transactions that match the exact given events where results are paginated.
Each event takes the form of '%s'. Please refer
to each module's documentation for the full set of events to query for. Each module
documents its respective events under 'xx_events.md'.

Example:
$ %s query txs --%s 'message.sender=cosmos1...&message.action=withdraw_delegator_reward' --page 1 --limit 30
`, eventFormat, version.AppName, flagEvents),
		),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}

eventsRaw, _ := cmd.Flags().GetString(flagEvents)
    eventsStr := strings.Trim(eventsRaw, "'")

var events []string
    if strings.Contains(eventsStr, "&") {
    events = strings.Split(eventsStr, "&")
}

else {
    events = append(events, eventsStr)
}

var tmEvents []string
    for _, event := range events {
    if !strings.Contains(event, "=") {
    return fmt.Errorf("invalid event; event %s should be of the format: %s", event, eventFormat)
}

else if strings.Count(event, "=") > 1 {
    return fmt.Errorf("invalid event; event %s should be of the format: %s", event, eventFormat)
}
    tokens := strings.Split(event, "=")
    if tokens[0] == tmtypes.TxHeightKey {
    event = fmt.Sprintf("%s=%s", tokens[0], tokens[1])
}

else {
    event = fmt.Sprintf("%s='%s'", tokens[0], tokens[1])
}

tmEvents = append(tmEvents, event)
}

page, _ := cmd.Flags().GetInt(flags.FlagPage)

limit, _ := cmd.Flags().GetInt(flags.FlagLimit)

txs, err := authtx.QueryTxsByEvents(clientCtx, tmEvents, page, limit, "")
    if err != nil {
    return err
}

return clientCtx.PrintProto(txs)
},
}

flags.AddQueryFlagsToCmd(cmd)

cmd.Flags().Int(flags.FlagPage, query.DefaultPage, "Query a specific page of paginated results")

cmd.Flags().Int(flags.FlagLimit, query.DefaultLimit, "Query number of transactions results per page returned")

cmd.Flags().String(flagEvents, "", fmt.Sprintf("list of transaction events in the form of %s", eventFormat))

cmd.MarkFlagRequired(flagEvents)

return cmd
}

/ QueryTxCmd implements the default command for a tx query.
func QueryTxCmd() *cobra.Command {
    cmd := &cobra.Command{
    Use:   "tx --type=[hash|acc_seq|signature] [hash|acc_seq|signature]",
    Short: "Query for a transaction by hash, \"<addr>/<seq>\" combination or comma-separated signatures in a committed block",
    Long: strings.TrimSpace(fmt.Sprintf(`
Example:
$ %s query tx <hash>
$ %s query tx --%s=%s <addr>/<sequence>
$ %s query tx --%s=%s <sig1_base64>,<sig2_base64...>
`,
			version.AppName,
			version.AppName, flagType, typeAccSeq,
			version.AppName, flagType, typeSig)),
    Args: cobra.ExactArgs(1),
    RunE: func(cmd *cobra.Command, args []string)

error {
    clientCtx, err := client.GetClientQueryContext(cmd)
    if err != nil {
    return err
}

typ, _ := cmd.Flags().GetString(flagType)
    switch typ {
    case typeHash:
				{
    if args[0] == "" {
    return fmt.Errorf("argument should be a tx hash")
}

					/ If hash is given, then query the tx by hash.
					output, err := authtx.QueryTx(clientCtx, args[0])
    if err != nil {
    return err
}
    if output.Empty() {
    return fmt.Errorf("no transaction found with hash %s", args[0])
}

return clientCtx.PrintProto(output)
}
    case typeSig:
				{
    sigParts, err := ParseSigArgs(args)
    if err != nil {
    return err
}
    tmEvents := make([]string, len(sigParts))
    for i, sig := range sigParts {
    tmEvents[i] = fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, sig)
}

txs, err := authtx.QueryTxsByEvents(clientCtx, tmEvents, query.DefaultPage, query.DefaultLimit, "")
    if err != nil {
    return err
}
    if len(txs.Txs) == 0 {
    return fmt.Errorf("found no txs matching given signatures")
}
    if len(txs.Txs) > 1 {
						/ This case means there's a bug somewhere else in the code. Should not happen.
						return errors.ErrLogic.Wrapf("found %d txs matching given signatures", len(txs.Txs))
}

return clientCtx.PrintProto(txs.Txs[0])
}
    case typeAccSeq:
				{
    if args[0] == "" {
    return fmt.Errorf("`acc_seq` type takes an argument '<addr>/<seq>'")
}
    tmEvents := []string{
    fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeyAccountSequence, args[0]),
}

txs, err := authtx.QueryTxsByEvents(clientCtx, tmEvents, query.DefaultPage, query.DefaultLimit, "")
    if err != nil {
    return err
}
    if len(txs.Txs) == 0 {
    return fmt.Errorf("found no txs matching given address and sequence combination")
}
    if len(txs.Txs) > 1 {
						/ This case means there's a bug somewhere else in the code. Should not happen.
						return fmt.Errorf("found %d txs matching given address and sequence combination", len(txs.Txs))
}

return clientCtx.PrintProto(txs.Txs[0])
}

default:
				return fmt.Errorf("unknown --%s value %s", flagType, typ)
}
	
},
}

flags.AddQueryFlagsToCmd(cmd)

cmd.Flags().String(flagType, typeHash, fmt.Sprintf("The type to be used when querying tx, can be one of \"%s\", \"%s\", \"%s\"", typeHash, typeAccSeq, typeSig))

return cmd
}

/ ParseSigArgs parses comma-separated signatures from the CLI arguments.
func ParseSigArgs(args []string) ([]string, error) {
    if len(args) != 1 || args[0] == "" {
    return nil, fmt.Errorf("argument should be comma-separated signatures")
}

return strings.Split(args[0], ","), nil
}
Each module must also implement the GetQueryCmd() method for AppModuleBasic that returns the GetQueryCmd() function. This allows for the root command to easily aggregate all of the query commands for each module. Here is an example:
package bank

import (
    
	"context"
    "encoding/json"
    "fmt"
    "time"

	modulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
    "cosmossdk.io/core/appmodule"
    "cosmossdk.io/depinject"
	gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
	store "github.com/cosmos/cosmos-sdk/store/types"
    "github.com/cosmos/cosmos-sdk/telemetry"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/types/module"
	simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
    "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
    "github.com/cosmos/cosmos-sdk/x/bank/exported"
    "github.com/cosmos/cosmos-sdk/x/bank/keeper"
	v1bank "github.com/cosmos/cosmos-sdk/x/bank/migrations/v1"
    "github.com/cosmos/cosmos-sdk/x/bank/simulation"
    "github.com/cosmos/cosmos-sdk/x/bank/types"
	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
)

/ ConsensusVersion defines the current x/bank module consensus version.
const ConsensusVersion = 4

var (
	_ module.AppModule           = AppModule{
}
	_ module.AppModuleBasic      = AppModuleBasic{
}
	_ module.AppModuleSimulation = AppModule{
}
)

/ AppModuleBasic defines the basic application module used by the bank module.
type AppModuleBasic struct {
    cdc codec.Codec
}

/ Name returns the bank module's name.
func (AppModuleBasic)

Name()

string {
    return types.ModuleName
}

/ RegisterLegacyAminoCodec registers the bank module's types on the LegacyAmino codec.
func (AppModuleBasic)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    types.RegisterLegacyAminoCodec(cdc)
}

/ DefaultGenesis returns default genesis state as raw bytes for the bank
/ module.
func (AppModuleBasic)

DefaultGenesis(cdc codec.JSONCodec)

json.RawMessage {
    return cdc.MustMarshalJSON(types.DefaultGenesisState())
}

/ ValidateGenesis performs genesis state validation for the bank module.
func (AppModuleBasic)

ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage)

error {
    var data types.GenesisState
    if err := cdc.UnmarshalJSON(bz, &data); err != nil {
    return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
}

return data.Validate()
}

/ RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the bank module.
func (AppModuleBasic)

RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *gwruntime.ServeMux) {
    if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
    panic(err)
}
}

/ GetTxCmd returns the root tx command for the bank module.
func (AppModuleBasic)

GetTxCmd() *cobra.Command {
    return cli.NewTxCmd()
}

/ GetQueryCmd returns no root query command for the bank module.
func (AppModuleBasic)

GetQueryCmd() *cobra.Command {
    return cli.GetQueryCmd()
}

/ RegisterInterfaces registers interfaces and implementations of the bank module.
func (AppModuleBasic)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    types.RegisterInterfaces(registry)

	/ Register legacy interfaces for migration scripts.
	v1bank.RegisterInterfaces(registry)
}

/ AppModule implements an application module for the bank module.
type AppModule struct {
    AppModuleBasic

	keeper        keeper.Keeper
	accountKeeper types.AccountKeeper

	/ legacySubspace is used solely for migration of x/params managed parameters
	legacySubspace exported.Subspace
}

var _ appmodule.AppModule = AppModule{
}

/ IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (am AppModule)

IsOnePerModuleType() {
}

/ IsAppModule implements the appmodule.AppModule interface.
func (am AppModule)

IsAppModule() {
}

/ RegisterServices registers module services.
func (am AppModule)

RegisterServices(cfg module.Configurator) {
    types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))

types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
    m := keeper.NewMigrator(am.keeper.(keeper.BaseKeeper), am.legacySubspace)
    if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil {
    panic(fmt.Sprintf("failed to migrate x/bank from version 1 to 2: %v", err))
}
    if err := cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3); err != nil {
    panic(fmt.Sprintf("failed to migrate x/bank from version 2 to 3: %v", err))
}
    if err := cfg.RegisterMigration(types.ModuleName, 3, m.Migrate3to4); err != nil {
    panic(fmt.Sprintf("failed to migrate x/bank from version 3 to 4: %v", err))
}
}

/ NewAppModule creates a new AppModule object
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, accountKeeper types.AccountKeeper, ss exported.Subspace)

AppModule {
    return AppModule{
    AppModuleBasic: AppModuleBasic{
    cdc: cdc
},
		keeper:         keeper,
		accountKeeper:  accountKeeper,
		legacySubspace: ss,
}
}

/ Name returns the bank module's name.
func (AppModule)

Name()

string {
    return types.ModuleName
}

/ RegisterInvariants registers the bank module invariants.
func (am AppModule)

RegisterInvariants(ir sdk.InvariantRegistry) {
    keeper.RegisterInvariants(ir, am.keeper)
}

/ QuerierRoute returns the bank module's querier route name.
func (AppModule)

QuerierRoute()

string {
    return types.RouterKey
}

/ InitGenesis performs genesis initialization for the bank module. It returns
/ no validator updates.
func (am AppModule)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
    start := time.Now()

var genesisState types.GenesisState
	cdc.MustUnmarshalJSON(data, &genesisState)

telemetry.MeasureSince(start, "InitGenesis", "crisis", "unmarshal")

am.keeper.InitGenesis(ctx, &genesisState)

return []abci.ValidatorUpdate{
}
}

/ ExportGenesis returns the exported genesis state as raw bytes for the bank
/ module.
func (am AppModule)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

json.RawMessage {
    gs := am.keeper.ExportGenesis(ctx)

return cdc.MustMarshalJSON(gs)
}

/ ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule)

ConsensusVersion()

uint64 {
    return ConsensusVersion
}

/ AppModuleSimulation functions

/ GenerateGenesisState creates a randomized GenState of the bank module.
func (AppModule)

GenerateGenesisState(simState *module.SimulationState) {
    simulation.RandomizedGenState(simState)
}

/ ProposalContents doesn't return any content functions for governance proposals.
func (AppModule)

ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent {
    return nil
}

/ RegisterStoreDecoder registers a decoder for supply module's types
func (am AppModule)

RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {
}

/ WeightedOperations returns the all the gov module operations with their respective weights.
func (am AppModule)

WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
    return simulation.WeightedOperations(
		simState.AppParams, simState.Cdc, am.accountKeeper, am.keeper,
	)
}

/ App Wiring Setup

func init() {
    appmodule.Register(&modulev1.Module{
},
		appmodule.Provide(ProvideModule),
	)
}

type BankInputs struct {
    depinject.In

	Config *modulev1.Module
	Cdc    codec.Codec
	Key    *store.KVStoreKey

	AccountKeeper types.AccountKeeper

	/ LegacySubspace is used solely for migration of x/params managed parameters
	LegacySubspace exported.Subspace `optional:"true"`
}

type BankOutputs struct {
    depinject.Out

	BankKeeper keeper.BaseKeeper
	Module     appmodule.AppModule
}

func ProvideModule(in BankInputs)

BankOutputs {
	/ Configure blocked module accounts.
	/
	/ Default behavior for blockedAddresses is to regard any module mentioned in
	/ AccountKeeper's module account permissions as blocked.
    blockedAddresses := make(map[string]bool)
    if len(in.Config.BlockedModuleAccountsOverride) > 0 {
    for _, moduleName := range in.Config.BlockedModuleAccountsOverride {
    blockedAddresses[authtypes.NewModuleAddress(moduleName).String()] = true
}
	
}

else {
    for _, permission := range in.AccountKeeper.GetModulePermissions() {
    blockedAddresses[permission.GetAddress().String()] = true
}
	
}

	/ default to governance authority if not provided
    authority := authtypes.NewModuleAddress(govtypes.ModuleName)
    if in.Config.Authority != "" {
    authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority)
}
    bankKeeper := keeper.NewBaseKeeper(
		in.Cdc,
		in.Key,
		in.AccountKeeper,
		blockedAddresses,
		authority.String(),
	)
    m := NewAppModule(in.Cdc, bankKeeper, in.AccountKeeper, in.LegacySubspace)

return BankOutputs{
    BankKeeper: bankKeeper,
    Module: m
}
}

Flags

Flags allow users to customize commands. --fees and --gas-prices are examples of flags that allow users to set the fees and gas prices for their transactions. Flags that are specific to a module are typically created in a flags.go file in the module’s ./client/cli folder. When creating a flag, developers set the value type, the name of the flag, the default value, and a description about the flag. Developers also have the option to mark flags as required so that an error is thrown if the user does not include a value for the flag. Here is an example that adds the --from flag to a command:
cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign")
In this example, the value of the flag is a String, the name of the flag is from (the value of the FlagFrom constant), the default value of the flag is "", and there is a description that will be displayed when a user adds --help to the command. Here is an example that marks the --from flag as required:
cmd.MarkFlagRequired(FlagFrom)
For more detailed information on creating flags, visit the Cobra Documentation. As mentioned in transaction commands, there is a set of flags that all transaction commands must add. This is done with the AddTxFlagsToCmd method defined in the Cosmos SDK’s ./client/flags package.
package flags

import (
    
	"fmt"
    "strconv"
    "github.com/spf13/cobra"
    "github.com/spf13/pflag"
	tmcli "github.com/tendermint/tendermint/libs/cli"
    "github.com/cosmos/cosmos-sdk/crypto/keyring"
)

const (
	/ DefaultGasAdjustment is applied to gas estimates to avoid tx execution
	/ failures due to state changes that might occur between the tx simulation
	/ and the actual run.
	DefaultGasAdjustment = 1.0
	DefaultGasLimit      = 200000
	GasFlagAuto          = "auto"

	/ DefaultKeyringBackend
	DefaultKeyringBackend = keyring.BackendOS

	/ BroadcastSync defines a tx broadcasting mode where the client waits for
	/ a CheckTx execution response only.
	BroadcastSync = "sync"
	/ BroadcastAsync defines a tx broadcasting mode where the client returns
	/ immediately.
	BroadcastAsync = "async"

	/ SignModeDirect is the value of the --sign-mode flag for SIGN_MODE_DIRECT
	SignModeDirect = "direct"
	/ SignModeLegacyAminoJSON is the value of the --sign-mode flag for SIGN_MODE_LEGACY_AMINO_JSON
	SignModeLegacyAminoJSON = "amino-json"
	/ SignModeDirectAux is the value of the --sign-mode flag for SIGN_MODE_DIRECT_AUX
	SignModeDirectAux = "direct-aux"
	/ SignModeEIP191 is the value of the --sign-mode flag for SIGN_MODE_EIP_191
	SignModeEIP191 = "eip-191"
)

/ List of CLI flags
const (
	FlagHome             = tmcli.HomeFlag
	FlagKeyringDir       = "keyring-dir"
	FlagUseLedger        = "ledger"
	FlagChainID          = "chain-id"
	FlagNode             = "node"
	FlagGRPC             = "grpc-addr"
	FlagGRPCInsecure     = "grpc-insecure"
	FlagHeight           = "height"
	FlagGasAdjustment    = "gas-adjustment"
	FlagFrom             = "from"
	FlagName             = "name"
	FlagAccountNumber    = "account-number"
	FlagSequence         = "sequence"
	FlagNote             = "note"
	FlagFees             = "fees"
	FlagGas              = "gas"
	FlagGasPrices        = "gas-prices"
	FlagBroadcastMode    = "broadcast-mode"
	FlagDryRun           = "dry-run"
	FlagGenerateOnly     = "generate-only"
	FlagOffline          = "offline"
	FlagOutputDocument   = "output-document" / inspired by wget -O
	FlagSkipConfirmation = "yes"
	FlagProve            = "prove"
	FlagKeyringBackend   = "keyring-backend"
	FlagPage             = "page"
	FlagLimit            = "limit"
	FlagSignMode         = "sign-mode"
	FlagPageKey          = "page-key"
	FlagOffset           = "offset"
	FlagCountTotal       = "count-total"
	FlagTimeoutHeight    = "timeout-height"
	FlagKeyAlgorithm     = "algo"
	FlagFeePayer         = "fee-payer"
	FlagFeeGranter       = "fee-granter"
	FlagReverse          = "reverse"
	FlagTip              = "tip"
	FlagAux              = "aux"
	/ FlagOutput is the flag to set the output format.
	/ This differs from FlagOutputDocument that is used to set the output file.
	FlagOutput = tmcli.OutputFlag

	/ Tendermint logging flags
	FlagLogLevel  = "log_level"
	FlagLogFormat = "log_format"
)

/ LineBreak can be included in a command list to provide a blank line
/ to help with readability
var LineBreak = &cobra.Command{
    Run: func(*cobra.Command, []string) {
}}

/ AddQueryFlagsToCmd adds common flags to a module query command.
func AddQueryFlagsToCmd(cmd *cobra.Command) {
    cmd.Flags().String(FlagNode, "tcp:/localhost:26657", "<host>:<port> to Tendermint RPC interface for this chain")

cmd.Flags().String(FlagGRPC, "", "the gRPC endpoint to use for this chain")

cmd.Flags().Bool(FlagGRPCInsecure, false, "allow gRPC over insecure channels, if not TLS the server must use TLS")

cmd.Flags().Int64(FlagHeight, 0, "Use a specific height to query state at (this can error if the node is pruning state)")

cmd.Flags().StringP(FlagOutput, "o", "text", "Output format (text|json)")

	/ some base commands does not require chainID e.g `simd testnet` while subcommands do
	/ hence the flag should not be required for those commands
	_ = cmd.MarkFlagRequired(FlagChainID)
}

/ AddTxFlagsToCmd adds common flags to a module tx command.
func AddTxFlagsToCmd(cmd *cobra.Command) {
    f := cmd.Flags()

f.StringP(FlagOutput, "o", "json", "Output format (text|json)")

f.String(FlagFrom, "", "Name or address of private key with which to sign")

f.Uint64P(FlagAccountNumber, "a", 0, "The account number of the signing account (offline mode only)")

f.Uint64P(FlagSequence, "s", 0, "The sequence number of the signing account (offline mode only)")

f.String(FlagNote, "", "Note to add a description to the transaction (previously --memo)")

f.String(FlagFees, "", "Fees to pay along with transaction; eg: 10uatom")

f.String(FlagGasPrices, "", "Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom)")

f.String(FlagNode, "tcp:/localhost:26657", "<host>:<port> to tendermint rpc interface for this chain")

f.Bool(FlagUseLedger, false, "Use a connected Ledger device")

f.Float64(FlagGasAdjustment, DefaultGasAdjustment, "adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored ")

f.StringP(FlagBroadcastMode, "b", BroadcastSync, "Transaction broadcasting mode (sync|async)")

f.Bool(FlagDryRun, false, "ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible)")

f.Bool(FlagGenerateOnly, false, "Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase only accessed when providing a key name)")

f.Bool(FlagOffline, false, "Offline mode (does not allow any online functionality)")

f.BoolP(FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation")

f.String(FlagSignMode, "", "Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature")

f.Uint64(FlagTimeoutHeight, 0, "Set a block timeout height to prevent the tx from being committed past a certain height")

f.String(FlagFeePayer, "", "Fee payer pays fees for the transaction instead of deducting from the signer")

f.String(FlagFeeGranter, "", "Fee granter grants fees for the transaction")

f.String(FlagTip, "", "Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator")

f.Bool(FlagAux, false, "Generate aux signer data instead of sending a tx")

f.String(FlagChainID, "", "The network chain ID")
	/ --gas can accept integers and "auto"
	f.String(FlagGas, "", fmt.Sprintf("gas limit to set per-transaction; set to %q to calculate sufficient gas automatically. Note: %q option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of %q. (default %d)",
		GasFlagAuto, GasFlagAuto, FlagFees, DefaultGasLimit))

AddKeyringFlags(f)
}

/ AddKeyringFlags sets common keyring flags
func AddKeyringFlags(flags *pflag.FlagSet) {
    flags.String(FlagKeyringDir, "", "The client Keyring directory; if omitted, the default 'home' directory will be used")

flags.String(FlagKeyringBackend, DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test|memory)")
}

/ AddPaginationFlagsToCmd adds common pagination flags to cmd
func AddPaginationFlagsToCmd(cmd *cobra.Command, query string) {
    cmd.Flags().Uint64(FlagPage, 1, fmt.Sprintf("pagination page of %s to query for. This sets offset to a multiple of limit", query))

cmd.Flags().String(FlagPageKey, "", fmt.Sprintf("pagination page-key of %s to query for", query))

cmd.Flags().Uint64(FlagOffset, 0, fmt.Sprintf("pagination offset of %s to query for", query))

cmd.Flags().Uint64(FlagLimit, 100, fmt.Sprintf("pagination limit of %s to query for", query))

cmd.Flags().Bool(FlagCountTotal, false, fmt.Sprintf("count total number of records in %s to query for", query))

cmd.Flags().Bool(FlagReverse, false, "results are sorted in descending order")
}

/ GasSetting encapsulates the possible values passed through the --gas flag.
type GasSetting struct {
    Simulate bool
	Gas      uint64
}

func (v *GasSetting)

String()

string {
    if v.Simulate {
    return GasFlagAuto
}

return strconv.FormatUint(v.Gas, 10)
}

/ ParseGasSetting parses a string gas value. The value may either be 'auto',
/ which indicates a transaction should be executed in simulate mode to
/ automatically find a sufficient gas value, or a string integer. It returns an
/ error if a string integer is provided which cannot be parsed.
func ParseGasSetting(gasStr string) (GasSetting, error) {
    switch gasStr {
    case "":
		return GasSetting{
    false, DefaultGasLimit
}, nil
    case GasFlagAuto:
		return GasSetting{
    true, 0
}, nil

	default:
		gas, err := strconv.ParseUint(gasStr, 10, 64)
    if err != nil {
    return GasSetting{
}, fmt.Errorf("gas must be either integer or %s", GasFlagAuto)
}

return GasSetting{
    false, gas
}, nil
}
}
Since AddTxFlagsToCmd(cmd *cobra.Command) includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). Similarly, there is a AddQueryFlagsToCmd(cmd *cobra.Command) to add common flags to a module query command.
package flags

import (
    
	"fmt"
    "strconv"
    "github.com/spf13/cobra"
    "github.com/spf13/pflag"
	tmcli "github.com/tendermint/tendermint/libs/cli"
    "github.com/cosmos/cosmos-sdk/crypto/keyring"
)

const (
	/ DefaultGasAdjustment is applied to gas estimates to avoid tx execution
	/ failures due to state changes that might occur between the tx simulation
	/ and the actual run.
	DefaultGasAdjustment = 1.0
	DefaultGasLimit      = 200000
	GasFlagAuto          = "auto"

	/ DefaultKeyringBackend
	DefaultKeyringBackend = keyring.BackendOS

	/ BroadcastSync defines a tx broadcasting mode where the client waits for
	/ a CheckTx execution response only.
	BroadcastSync = "sync"
	/ BroadcastAsync defines a tx broadcasting mode where the client returns
	/ immediately.
	BroadcastAsync = "async"

	/ SignModeDirect is the value of the --sign-mode flag for SIGN_MODE_DIRECT
	SignModeDirect = "direct"
	/ SignModeLegacyAminoJSON is the value of the --sign-mode flag for SIGN_MODE_LEGACY_AMINO_JSON
	SignModeLegacyAminoJSON = "amino-json"
	/ SignModeDirectAux is the value of the --sign-mode flag for SIGN_MODE_DIRECT_AUX
	SignModeDirectAux = "direct-aux"
	/ SignModeEIP191 is the value of the --sign-mode flag for SIGN_MODE_EIP_191
	SignModeEIP191 = "eip-191"
)

/ List of CLI flags
const (
	FlagHome             = tmcli.HomeFlag
	FlagKeyringDir       = "keyring-dir"
	FlagUseLedger        = "ledger"
	FlagChainID          = "chain-id"
	FlagNode             = "node"
	FlagGRPC             = "grpc-addr"
	FlagGRPCInsecure     = "grpc-insecure"
	FlagHeight           = "height"
	FlagGasAdjustment    = "gas-adjustment"
	FlagFrom             = "from"
	FlagName             = "name"
	FlagAccountNumber    = "account-number"
	FlagSequence         = "sequence"
	FlagNote             = "note"
	FlagFees             = "fees"
	FlagGas              = "gas"
	FlagGasPrices        = "gas-prices"
	FlagBroadcastMode    = "broadcast-mode"
	FlagDryRun           = "dry-run"
	FlagGenerateOnly     = "generate-only"
	FlagOffline          = "offline"
	FlagOutputDocument   = "output-document" / inspired by wget -O
	FlagSkipConfirmation = "yes"
	FlagProve            = "prove"
	FlagKeyringBackend   = "keyring-backend"
	FlagPage             = "page"
	FlagLimit            = "limit"
	FlagSignMode         = "sign-mode"
	FlagPageKey          = "page-key"
	FlagOffset           = "offset"
	FlagCountTotal       = "count-total"
	FlagTimeoutHeight    = "timeout-height"
	FlagKeyAlgorithm     = "algo"
	FlagFeePayer         = "fee-payer"
	FlagFeeGranter       = "fee-granter"
	FlagReverse          = "reverse"
	FlagTip              = "tip"
	FlagAux              = "aux"
	/ FlagOutput is the flag to set the output format.
	/ This differs from FlagOutputDocument that is used to set the output file.
	FlagOutput = tmcli.OutputFlag

	/ Tendermint logging flags
	FlagLogLevel  = "log_level"
	FlagLogFormat = "log_format"
)

/ LineBreak can be included in a command list to provide a blank line
/ to help with readability
var LineBreak = &cobra.Command{
    Run: func(*cobra.Command, []string) {
}}

/ AddQueryFlagsToCmd adds common flags to a module query command.
func AddQueryFlagsToCmd(cmd *cobra.Command) {
    cmd.Flags().String(FlagNode, "tcp:/localhost:26657", "<host>:<port> to Tendermint RPC interface for this chain")

cmd.Flags().String(FlagGRPC, "", "the gRPC endpoint to use for this chain")

cmd.Flags().Bool(FlagGRPCInsecure, false, "allow gRPC over insecure channels, if not TLS the server must use TLS")

cmd.Flags().Int64(FlagHeight, 0, "Use a specific height to query state at (this can error if the node is pruning state)")

cmd.Flags().StringP(FlagOutput, "o", "text", "Output format (text|json)")

	/ some base commands does not require chainID e.g `simd testnet` while subcommands do
	/ hence the flag should not be required for those commands
	_ = cmd.MarkFlagRequired(FlagChainID)
}

/ AddTxFlagsToCmd adds common flags to a module tx command.
func AddTxFlagsToCmd(cmd *cobra.Command) {
    f := cmd.Flags()

f.StringP(FlagOutput, "o", "json", "Output format (text|json)")

f.String(FlagFrom, "", "Name or address of private key with which to sign")

f.Uint64P(FlagAccountNumber, "a", 0, "The account number of the signing account (offline mode only)")

f.Uint64P(FlagSequence, "s", 0, "The sequence number of the signing account (offline mode only)")

f.String(FlagNote, "", "Note to add a description to the transaction (previously --memo)")

f.String(FlagFees, "", "Fees to pay along with transaction; eg: 10uatom")

f.String(FlagGasPrices, "", "Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom)")

f.String(FlagNode, "tcp:/localhost:26657", "<host>:<port> to tendermint rpc interface for this chain")

f.Bool(FlagUseLedger, false, "Use a connected Ledger device")

f.Float64(FlagGasAdjustment, DefaultGasAdjustment, "adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored ")

f.StringP(FlagBroadcastMode, "b", BroadcastSync, "Transaction broadcasting mode (sync|async)")

f.Bool(FlagDryRun, false, "ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible)")

f.Bool(FlagGenerateOnly, false, "Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase only accessed when providing a key name)")

f.Bool(FlagOffline, false, "Offline mode (does not allow any online functionality)")

f.BoolP(FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation")

f.String(FlagSignMode, "", "Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature")

f.Uint64(FlagTimeoutHeight, 0, "Set a block timeout height to prevent the tx from being committed past a certain height")

f.String(FlagFeePayer, "", "Fee payer pays fees for the transaction instead of deducting from the signer")

f.String(FlagFeeGranter, "", "Fee granter grants fees for the transaction")

f.String(FlagTip, "", "Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator")

f.Bool(FlagAux, false, "Generate aux signer data instead of sending a tx")

f.String(FlagChainID, "", "The network chain ID")
	/ --gas can accept integers and "auto"
	f.String(FlagGas, "", fmt.Sprintf("gas limit to set per-transaction; set to %q to calculate sufficient gas automatically. Note: %q option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of %q. (default %d)",
		GasFlagAuto, GasFlagAuto, FlagFees, DefaultGasLimit))

AddKeyringFlags(f)
}

/ AddKeyringFlags sets common keyring flags
func AddKeyringFlags(flags *pflag.FlagSet) {
    flags.String(FlagKeyringDir, "", "The client Keyring directory; if omitted, the default 'home' directory will be used")

flags.String(FlagKeyringBackend, DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test|memory)")
}

/ AddPaginationFlagsToCmd adds common pagination flags to cmd
func AddPaginationFlagsToCmd(cmd *cobra.Command, query string) {
    cmd.Flags().Uint64(FlagPage, 1, fmt.Sprintf("pagination page of %s to query for. This sets offset to a multiple of limit", query))

cmd.Flags().String(FlagPageKey, "", fmt.Sprintf("pagination page-key of %s to query for", query))

cmd.Flags().Uint64(FlagOffset, 0, fmt.Sprintf("pagination offset of %s to query for", query))

cmd.Flags().Uint64(FlagLimit, 100, fmt.Sprintf("pagination limit of %s to query for", query))

cmd.Flags().Bool(FlagCountTotal, false, fmt.Sprintf("count total number of records in %s to query for", query))

cmd.Flags().Bool(FlagReverse, false, "results are sorted in descending order")
}

/ GasSetting encapsulates the possible values passed through the --gas flag.
type GasSetting struct {
    Simulate bool
	Gas      uint64
}

func (v *GasSetting)

String()

string {
    if v.Simulate {
    return GasFlagAuto
}

return strconv.FormatUint(v.Gas, 10)
}

/ ParseGasSetting parses a string gas value. The value may either be 'auto',
/ which indicates a transaction should be executed in simulate mode to
/ automatically find a sufficient gas value, or a string integer. It returns an
/ error if a string integer is provided which cannot be parsed.
func ParseGasSetting(gasStr string) (GasSetting, error) {
    switch gasStr {
    case "":
		return GasSetting{
    false, DefaultGasLimit
}, nil
    case GasFlagAuto:
		return GasSetting{
    true, 0
}, nil

	default:
		gas, err := strconv.ParseUint(gasStr, 10, 64)
    if err != nil {
    return GasSetting{
}, fmt.Errorf("gas must be either integer or %s", GasFlagAuto)
}

return GasSetting{
    false, gas
}, nil
}
}

gRPC

gRPC is a Remote Procedure Call (RPC) framework. RPC is the preferred way for external clients like wallets and exchanges to interact with a blockchain. In addition to providing an ABCI query pathway, the Cosmos SDK provides a gRPC proxy server that routes gRPC query requests to ABCI query requests. In order to do that, modules must implement RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) on AppModuleBasic to wire the client gRPC requests to the correct handler inside the module. Here’s an example from the x/auth module:
package auth

import (
    
	"context"
    "encoding/json"
    "fmt"

	gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
    "github.com/spf13/cobra"
	abci "github.com/tendermint/tendermint/abci/types"
    "cosmossdk.io/depinject"
    "cosmossdk.io/core/appmodule"

	modulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
	store "github.com/cosmos/cosmos-sdk/store/types"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/types/module"
	simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
    "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
    "github.com/cosmos/cosmos-sdk/x/auth/exported"
    "github.com/cosmos/cosmos-sdk/x/auth/keeper"
    "github.com/cosmos/cosmos-sdk/x/auth/simulation"
    "github.com/cosmos/cosmos-sdk/x/auth/types"
	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
)

/ ConsensusVersion defines the current x/auth module consensus version.
const ConsensusVersion = 4

var (
	_ module.AppModule           = AppModule{
}
	_ module.AppModuleBasic      = AppModuleBasic{
}
	_ module.AppModuleSimulation = AppModule{
}
)

/ AppModuleBasic defines the basic application module used by the auth module.
type AppModuleBasic struct{
}

/ Name returns the auth module's name.
func (AppModuleBasic)

Name()

string {
    return types.ModuleName
}

/ RegisterLegacyAminoCodec registers the auth module's types for the given codec.
func (AppModuleBasic)

RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
    types.RegisterLegacyAminoCodec(cdc)
}

/ DefaultGenesis returns default genesis state as raw bytes for the auth
/ module.
func (AppModuleBasic)

DefaultGenesis(cdc codec.JSONCodec)

json.RawMessage {
    return cdc.MustMarshalJSON(types.DefaultGenesisState())
}

/ ValidateGenesis performs genesis state validation for the auth module.
func (AppModuleBasic)

ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage)

error {
    var data types.GenesisState
    if err := cdc.UnmarshalJSON(bz, &data); err != nil {
    return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
}

return types.ValidateGenesis(data)
}

/ RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the auth module.
func (AppModuleBasic)

RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *gwruntime.ServeMux) {
    if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
    panic(err)
}
}

/ GetTxCmd returns the root tx command for the auth module.
func (AppModuleBasic)

GetTxCmd() *cobra.Command {
    return nil
}

/ GetQueryCmd returns the root query command for the auth module.
func (AppModuleBasic)

GetQueryCmd() *cobra.Command {
    return cli.GetQueryCmd()
}

/ RegisterInterfaces registers interfaces and implementations of the auth module.
func (AppModuleBasic)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    types.RegisterInterfaces(registry)
}

/ AppModule implements an application module for the auth module.
type AppModule struct {
    AppModuleBasic

	accountKeeper     keeper.AccountKeeper
	randGenAccountsFn types.RandomGenesisAccountsFn

	/ legacySubspace is used solely for migration of x/params managed parameters
	legacySubspace exported.Subspace
}

var _ appmodule.AppModule = AppModule{
}

/ IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (am AppModule)

IsOnePerModuleType() {
}

/ IsAppModule implements the appmodule.AppModule interface.
func (am AppModule)

IsAppModule() {
}

/ NewAppModule creates a new AppModule object
func NewAppModule(cdc codec.Codec, accountKeeper keeper.AccountKeeper, randGenAccountsFn types.RandomGenesisAccountsFn, ss exported.Subspace)

AppModule {
    return AppModule{
    AppModuleBasic:    AppModuleBasic{
},
		accountKeeper:     accountKeeper,
		randGenAccountsFn: randGenAccountsFn,
		legacySubspace:    ss,
}
}

/ Name returns the auth module's name.
func (AppModule)

Name()

string {
    return types.ModuleName
}

/ RegisterInvariants performs a no-op.
func (AppModule)

RegisterInvariants(_ sdk.InvariantRegistry) {
}

/ RegisterServices registers a GRPC query service to respond to the
/ module-specific GRPC queries.
func (am AppModule)

RegisterServices(cfg module.Configurator) {
    types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.accountKeeper))

types.RegisterQueryServer(cfg.QueryServer(), am.accountKeeper)
    m := keeper.NewMigrator(am.accountKeeper, cfg.QueryServer(), am.legacySubspace)
    if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil {
    panic(fmt.Sprintf("failed to migrate x/%s from version 1 to 2: %v", types.ModuleName, err))
}
    if err := cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3); err != nil {
    panic(fmt.Sprintf("failed to migrate x/%s from version 2 to 3: %v", types.ModuleName, err))
}
    if err := cfg.RegisterMigration(types.ModuleName, 3, m.Migrate3to4); err != nil {
    panic(fmt.Sprintf("failed to migrate x/%s from version 3 to 4: %v", types.ModuleName, err))
}

	/ see migrations/v5/doc.go
    if err := cfg.RegisterMigration(types.ModuleName, 4, func(ctx sdk.Context)

error {
    return nil
}); err != nil {
    panic(fmt.Sprintf("failed to migrate x/%s from version 4 to 5: %v", types.ModuleName, err))
}
}

/ InitGenesis performs genesis initialization for the auth module. It returns
/ no validator updates.
func (am AppModule)

InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
    var genesisState types.GenesisState
	cdc.MustUnmarshalJSON(data, &genesisState)

am.accountKeeper.InitGenesis(ctx, genesisState)

return []abci.ValidatorUpdate{
}
}

/ ExportGenesis returns the exported genesis state as raw bytes for the auth
/ module.
func (am AppModule)

ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec)

json.RawMessage {
    gs := am.accountKeeper.ExportGenesis(ctx)

return cdc.MustMarshalJSON(gs)
}

/ ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule)

ConsensusVersion()

uint64 {
    return ConsensusVersion
}

/ AppModuleSimulation functions

/ GenerateGenesisState creates a randomized GenState of the auth module
func (am AppModule)

GenerateGenesisState(simState *module.SimulationState) {
    simulation.RandomizedGenState(simState, am.randGenAccountsFn)
}

/ ProposalContents doesn't return any content functions for governance proposals.
func (AppModule)

ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
    return nil
}

/ RegisterStoreDecoder registers a decoder for auth module's types
func (am AppModule)

RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
    sdr[types.StoreKey] = simulation.NewDecodeStore(am.accountKeeper)
}

/ WeightedOperations doesn't return any auth module operation.
func (AppModule)

WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation {
    return nil
}

/
/ App Wiring Setup
/

func init() {
    appmodule.Register(&modulev1.Module{
},
		appmodule.Provide(ProvideModule),
	)
}

type AuthInputs struct {
    depinject.In

	Config *modulev1.Module
	Key    *store.KVStoreKey
	Cdc    codec.Codec

	RandomGenesisAccountsFn types.RandomGenesisAccountsFn `optional:"true"`
	AccountI                func()

types.AccountI         `optional:"true"`

	/ LegacySubspace is used solely for migration of x/params managed parameters
	LegacySubspace exported.Subspace `optional:"true"`
}

type AuthOutputs struct {
    depinject.Out

	AccountKeeper keeper.AccountKeeper
	Module        appmodule.AppModule
}

func ProvideModule(in AuthInputs)

AuthOutputs {
    maccPerms := map[string][]string{
}
    for _, permission := range in.Config.ModuleAccountPermissions {
    maccPerms[permission.Account] = permission.Permissions
}

	/ default to governance authority if not provided
    authority := types.NewModuleAddress(govtypes.ModuleName)
    if in.Config.Authority != "" {
    authority = types.NewModuleAddressOrBech32Address(in.Config.Authority)
}
    if in.RandomGenesisAccountsFn == nil {
    in.RandomGenesisAccountsFn = simulation.RandomGenesisAccounts
}
    if in.AccountI == nil {
    in.AccountI = types.ProtoBaseAccount
}
    k := keeper.NewAccountKeeper(in.Cdc, in.Key, in.AccountI, maccPerms, in.Config.Bech32Prefix, authority.String())
    m := NewAppModule(in.Cdc, k, in.RandomGenesisAccountsFn, in.LegacySubspace)

return AuthOutputs{
    AccountKeeper: k,
    Module: m
}
}

gRPC-gateway REST

Applications need to support web services that use HTTP requests (e.g. a web wallet like Keplr). grpc-gateway translates REST calls into gRPC calls, which might be useful for clients that do not use gRPC. Modules that want to expose REST queries should add google.api.http annotations to their rpc methods, such as in the example below from the x/auth module:
/ Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/auth/v1beta1/query.proto#L14-L89
gRPC gateway is started in-process along with the application and CometBFT. It can be enabled or disabled by setting gRPC Configuration enable in app.toml. The Cosmos SDK provides a command for generating Swagger documentation (protoc-gen-swagger). Setting swagger in app.toml defines if swagger documentation should be automatically registered.