diff --git a/.pending/breaking/gaiacli/4142-Turn-gaiacli-tx b/.pending/breaking/gaiacli/4142-Turn-gaiacli-tx new file mode 100644 index 000000000000..ed4c73b5bd8c --- /dev/null +++ b/.pending/breaking/gaiacli/4142-Turn-gaiacli-tx @@ -0,0 +1,2 @@ +#4142 Turn gaiacli tx send's --from into a required argument. +New shorter syntax: `gaiacli tx send FROM TO AMOUNT` diff --git a/client/context/context.go b/client/context/context.go index ea87533ff4fd..0a42ff4afe26 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -58,9 +58,10 @@ type CLIContext struct { SkipConfirm bool } -// NewCLIContext returns a new initialized CLIContext with parameters from the -// command line using Viper. -func NewCLIContext() CLIContext { +// NewCLIContextWithFrom returns a new initialized CLIContext with parameters from the +// command line using Viper. It takes a key name or address and populates the FromName and +// FromAddress field accordingly. +func NewCLIContextWithFrom(from string) CLIContext { var rpc rpcclient.Client nodeURI := viper.GetString(client.FlagNode) @@ -68,7 +69,6 @@ func NewCLIContext() CLIContext { rpc = rpcclient.NewHTTP(nodeURI, "/websocket") } - from := viper.GetString(client.FlagFrom) genOnly := viper.GetBool(client.FlagGenerateOnly) fromAddress, fromName, err := GetFromFields(from, genOnly) if err != nil { @@ -104,6 +104,10 @@ func NewCLIContext() CLIContext { } } +// NewCLIContext returns a new initialized CLIContext with parameters from the +// command line using Viper. +func NewCLIContext() CLIContext { return NewCLIContextWithFrom(viper.GetString(client.FlagFrom)) } + func createVerifier() tmlite.Verifier { trustNodeDefined := viper.IsSet(client.FlagTrustNode) if !trustNodeDefined { diff --git a/cmd/gaia/cli_test/test_helpers.go b/cmd/gaia/cli_test/test_helpers.go index 1df5b93c9eb8..482cc60ad141 100644 --- a/cmd/gaia/cli_test/test_helpers.go +++ b/cmd/gaia/cli_test/test_helpers.go @@ -307,7 +307,7 @@ func (f *Fixtures) CLIConfig(key, value string, flags ...string) { // TxSend is gaiacli tx send func (f *Fixtures) TxSend(from string, to sdk.AccAddress, amount sdk.Coin, flags ...string) (bool, string, string) { - cmd := fmt.Sprintf("%s tx send %s %s %v --from=%s", f.GaiacliBinary, to, amount, f.Flags(), from) + cmd := fmt.Sprintf("%s tx send %s %s %s %v", f.GaiacliBinary, from, to, amount, f.Flags()) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass) } @@ -315,7 +315,7 @@ func (f *Fixtures) txSendWithConfirm( from string, to sdk.AccAddress, amount sdk.Coin, confirm string, flags ...string, ) (bool, string, string) { - cmd := fmt.Sprintf("%s tx send %s %s %v --from=%s", f.GaiacliBinary, to, amount, f.Flags(), from) + cmd := fmt.Sprintf("%s tx send %s %s %s %v", f.GaiacliBinary, from, to, amount, f.Flags()) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), confirm, client.DefaultKeyPass) } diff --git a/docs/cosmos-hub/gaiacli.md b/docs/cosmos-hub/gaiacli.md index 4aa133ec8dee..1b9e8e3fb610 100644 --- a/docs/cosmos-hub/gaiacli.md +++ b/docs/cosmos-hub/gaiacli.md @@ -187,13 +187,12 @@ When you query an account balance with zero tokens, you will get this error: `No The following command could be used to send coins from one account to another: ```bash -gaiacli tx send 10faucetToken \ - --chain-id= \ - --from= \ +gaiacli tx send 10faucetToken \ + --chain-id= ``` ::: warning Note -The `--amount` flag accepts the format `--amount=`. +The `amount` argument accepts the format ``. ::: ::: tip Note @@ -219,9 +218,8 @@ You can simulate a transaction without actually broadcasting it by appending the `--dry-run` flag to the command line: ```bash -gaiacli tx send 10faucetToken \ +gaiacli tx send 10faucetToken \ --chain-id= \ - --from= \ --dry-run ``` @@ -229,9 +227,8 @@ Furthermore, you can build a transaction and print its JSON format to STDOUT by appending `--generate-only` to the list of the command line arguments: ```bash -gaiacli tx send 10faucetToken \ +gaiacli tx send 10faucetToken \ --chain-id= \ - --from= \ --generate-only > unsignedSendTx.json ``` @@ -244,6 +241,7 @@ gaiacli tx sign \ ::: tip Note The `--generate-only` flag prevents `gaiacli` from accessing the local keybase. +Thus when such flag is supplied `` must be an address. ::: You can validate the transaction's signatures by typing the following: diff --git a/x/bank/client/cli/sendtx.go b/x/bank/client/cli/sendtx.go index bfdebb3cdadf..9225ae27855a 100644 --- a/x/bank/client/cli/sendtx.go +++ b/x/bank/client/cli/sendtx.go @@ -20,12 +20,12 @@ const ( // SendTxCmd will create a send tx and sign it with the given key. func SendTxCmd(cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "send [to_address] [amount]", + Use: "send [from_key_or_address] [to_address] [amount]", Short: "Create and sign a send tx", - Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - cliCtx := context.NewCLIContext(). + cliCtx := context.NewCLIContextWithFrom(args[0]). WithCodec(cdc). WithAccountDecoder(cdc) @@ -33,27 +33,24 @@ func SendTxCmd(cdc *codec.Codec) *cobra.Command { return err } - to, err := sdk.AccAddressFromBech32(args[0]) + to, err := sdk.AccAddressFromBech32(args[1]) if err != nil { return err } // parse coins trying to be sent - coins, err := sdk.ParseCoins(args[1]) + coins, err := sdk.ParseCoins(args[2]) if err != nil { return err } - from := cliCtx.GetFromAddress() - // build and sign the transaction, then broadcast to Tendermint - msg := bank.NewMsgSend(from, to, coins) + msg := bank.NewMsgSend(cliCtx.GetFromAddress(), to, coins) return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}, false) }, } cmd = client.PostCommands(cmd)[0] - cmd.MarkFlagRequired(client.FlagFrom) return cmd }