feat(client/v2): support gov proposals (cherry-pick #18461) (#24359)

Co-authored-by: Alex | Interchain Labs <alex@interchainlabs.io>
This commit is contained in:
julienrbrt 2025-04-03 16:52:56 +02:00 committed by GitHub
parent 877b4fb2dc
commit a2cf15cd38
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 213 additions and 42 deletions

View File

@ -47,7 +47,7 @@ func ValidatePromptAddress(input string) error {
return fmt.Errorf("invalid address: %w", err)
}
// ValidatePromptYesNo validates that the input is valid sdk.COins
// ValidatePromptCoins validates that the input contains valid sdk.Coins
func ValidatePromptCoins(input string) error {
if _, err := sdk.ParseCoinsNormalized(input); err != nil {
return fmt.Errorf("invalid coins: %w", err)

View File

@ -36,6 +36,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
## [Unreleased]
### Features
* [#24359](https://github.com/cosmos/cosmos-sdk/pull/24359) Support governance proposals.
### Bug Fixes
* (cli) [#24330](https://github.com/cosmos/cosmos-sdk/pull/24330) Use the gogoproto merge registry as a file resolver instead of the interface registry.
@ -99,7 +103,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#20083](https://github.com/cosmos/cosmos-sdk/pull/20083) Integrate latest version of cosmos-proto and improve version filtering.
* [#19618](https://github.com/cosmos/cosmos-sdk/pull/19618) Marshal enum as string in queries.
* [#19060](https://github.com/cosmos/cosmos-sdk/pull/19060) Use client context from root (or enhanced) command in autocli commands.
* Note, the given command must have a `client.Context` in its context.
* Note, the given command must have a `client.Context` in its context.
* [#19216](https://github.com/cosmos/cosmos-sdk/pull/19216) Do not overwrite TxConfig, use directly the one provided in context. TxConfig should always be set in the `client.Context` in `root.go` of an app.
* [#20266](https://github.com/cosmos/cosmos-sdk/pull/20266) Add ability to override the short description in AutoCLI-generated top-level commands.

View File

@ -110,7 +110,7 @@ This field is automatically filled when using the `--from` flag or defining the
AutoCLI currently supports only one signer per transaction.
:::
## Module Wiring & Customization
## Module wiring & Customization
The `AutoCLIOptions()` method on your module allows to specify custom commands, sub-commands or flags for each service, as it was a `cobra.Command` instance, within the `RpcCommandOptions` struct. Defining such options will customize the behavior of the `autocli` command generation, which by default generates a command for each method in your gRPC service.
@ -126,6 +126,11 @@ The `AutoCLIOptions()` method on your module allows to specify custom commands,
}
```
:::tip
AutoCLI can create a gov proposal of any tx by simply setting the `GovProposal` field to `true` in the `autocli.RpcCommandOptions` struct.
Users can however use the `--no-proposal` flag to disable the proposal creation (which is useful if the authority isn't the gov module on a chain).
:::
### Specifying Subcommands
By default, `autocli` generates a command for each method in your gRPC service. However, you can specify subcommands to group related commands together. To specify subcommands, use the `autocliv1.ServiceCommandDescriptor` struct.

View File

@ -248,10 +248,10 @@ func (b *Builder) addMessageFlags(ctx *context.Context, flagSet *pflag.FlagSet,
flagOpts := commandOptions.FlagOptions[fieldName]
name, hasValue, err := b.addFieldFlag(ctx, flagSet, field, flagOpts, options)
flagOptsByFlagName[name] = flagOpts
if err != nil {
return nil, err
}
flagOptsByFlagName[name] = flagOpts
messageBinder.flagBindings = append(messageBinder.flagBindings, fieldBinding{
hasValue: hasValue,

View File

@ -4,6 +4,7 @@ import (
"context"
"fmt"
gogoproto "github.com/cosmos/gogoproto/proto"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
@ -11,10 +12,15 @@ import (
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/client/v2/autocli/flag"
"cosmossdk.io/client/v2/internal/flags"
"cosmossdk.io/client/v2/internal/util"
addresscodec "cosmossdk.io/core/address"
"github.com/cosmos/cosmos-sdk/client"
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
)
// BuildMsgCommand builds the msg commands for all the provided modules. If a custom command is provided for a
@ -123,6 +129,12 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor
fd := input.Descriptor().Fields().ByName(protoreflect.Name(flag.GetSignerFieldName(input.Descriptor())))
addressCodec := b.AddressCodec
// handle gov proposals commands
skipProposal, _ := cmd.Flags().GetBool(flags.FlagNoProposal)
if options.GovProposal && !skipProposal {
return b.handleGovProposal(cmd, input, clientCtx, addressCodec, fd)
}
// set signer to signer field if empty
if addr := input.Get(fd).String(); addr == "" {
scalarType, ok := flag.GetScalarType(fd)
@ -166,5 +178,50 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor
// silence usage only for inner txs & queries commands
cmd.SilenceUsage = true
// set gov proposal flags if command is a gov proposal
if options.GovProposal {
govcli.AddGovPropFlagsToCmd(cmd)
cmd.Flags().Bool(flags.FlagNoProposal, false, "Skip gov proposal and submit a normal transaction")
}
return cmd, nil
}
// handleGovProposal sets the authority field of the message to the gov module address and creates a gov proposal.
func (b *Builder) handleGovProposal(
cmd *cobra.Command,
input protoreflect.Message,
clientCtx client.Context,
addressCodec addresscodec.Codec,
fd protoreflect.FieldDescriptor,
) error {
govAuthority := authtypes.NewModuleAddress(govtypes.ModuleName)
authority, err := addressCodec.BytesToString(govAuthority.Bytes())
if err != nil {
return fmt.Errorf("failed to convert gov authority: %w", err)
}
input.Set(fd, protoreflect.ValueOfString(authority))
signerFromFlag := clientCtx.GetFromAddress()
signer, err := addressCodec.BytesToString(signerFromFlag.Bytes())
if err != nil {
return fmt.Errorf("failed to set signer on message, got %q: %w", signerFromFlag, err)
}
proposal, err := govcli.ReadGovPropCmdFlags(signer, cmd.Flags())
if err != nil {
return err
}
// AutoCLI uses protov2 messages, while the SDK only supports proto v1 messages.
// Here we use dynamicpb, to create a proto v1 compatible message.
// The SDK codec will handle protov2 -> protov1 (marshal)
msg := dynamicpb.NewMessage(input.Descriptor())
proto.Merge(msg, input.Interface())
if err := proposal.SetMsgs([]gogoproto.Message{msg}); err != nil {
return fmt.Errorf("failed to set msg in proposal %w", err)
}
return clienttx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), proposal)
}

View File

@ -51,6 +51,7 @@ func TestMsg(t *testing.T) {
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
"--generate-only",
"--output", "json",
"--chain-id", "test-chain",
)
assert.NilError(t, err)
golden.Assert(t, out.String(), "msg-output.golden")

View File

@ -2,6 +2,8 @@ module cosmossdk.io/client/v2
go 1.23.2
replace github.com/cosmos/cosmos-sdk => ../..
require (
cosmossdk.io/api v0.9.0
cosmossdk.io/core v0.11.3
@ -38,6 +40,7 @@ require (
github.com/bytedance/sonic/loader v0.2.4 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
@ -107,6 +110,7 @@ require (
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/linxGnu/grocksdb v1.8.14 // indirect
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/minio/highwayhash v1.0.3 // indirect

View File

@ -95,10 +95,14 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
@ -149,8 +153,6 @@ github.com/cosmos/cosmos-db v1.1.1 h1:FezFSU37AlBC8S98NlSagL76oqBRWq/prTPvFcEJNC
github.com/cosmos/cosmos-db v1.1.1/go.mod h1:AghjcIPqdhSLP/2Z0yha5xPH3nLnskz81pBx3tcVSAw=
github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA=
github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec=
github.com/cosmos/cosmos-sdk v0.53.0-rc.2 h1:KdQRIp6z/hQK9VppPU1exuXobLLwhrrRIrAOlzzaIf0=
github.com/cosmos/cosmos-sdk v0.53.0-rc.2/go.mod h1:GCGPg/EJ9FCygDZ8yHxuq3aM577FC706LpXwl2LbXKQ=
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE=
@ -892,6 +894,7 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -10,6 +10,13 @@ const (
// FlagNoIndent is the flag to not indent the output.
FlagNoIndent = "no-indent"
// FlagNoPrompt is the flag to not use a prompt for commands.
FlagNoPrompt = "no-prompt"
// FlagNoProposal is the flag convert a gov proposal command into a normal command.
// This is used to allow user of chains with custom authority to not use gov submit proposals for usual proposal commands.
FlagNoProposal = "no-proposal"
)
// List of supported output formats

View File

@ -80,8 +80,12 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
Service: authv1beta1.Msg_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "UpdateParams",
Skip: true, // skipped because authority gated
RpcMethod: "UpdateParams",
Use: "update-params-proposal [params]",
Short: "Submit a proposal to update auth module params. Note: the entire params must be provided.",
Example: fmt.Sprintf(`%s tx auth update-params-proposal '{ "max_memo_characters": 0, "tx_sig_limit": 0, "tx_size_cost_per_byte": 0, "sig_verify_cost_ed25519": 0, "sig_verify_cost_secp256k1": 0 }'`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "params"}},
GovProposal: true,
},
},
},

View File

@ -1,10 +1,13 @@
package bank
import (
"fmt"
"strings"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
"github.com/cosmos/cosmos-sdk/version"
)
// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface.
@ -88,7 +91,7 @@ To look up all denoms, do not provide any arguments.`,
},
Tx: &autocliv1.ServiceCommandDescriptor{
Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
EnhanceCustomCommand: false, // use custom commands only until v0.51
EnhanceCustomCommand: true,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "Send",
@ -101,16 +104,23 @@ Note: multiple coins can be send by space separated.`,
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "from_address"}, {ProtoField: "to_address"}, {ProtoField: "amount", Varargs: true}},
},
{
RpcMethod: "UpdateParams",
Skip: true, // skipped because authority gated
RpcMethod: "UpdateParams",
Use: "update-params-proposal [params]",
Short: "Submit a proposal to update bank module params. Note: the entire params must be provided.",
Example: fmt.Sprintf(`%s tx bank update-params-proposal '{ "default_send_enabled": true }'`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "params"}},
GovProposal: true,
},
{
RpcMethod: "SetSendEnabled",
Skip: true, // skipped because authority gated
},
{
RpcMethod: "Burn",
Skip: true, // skipped because available from v0.51
RpcMethod: "SetSendEnabled",
Use: "set-send-enabled-proposal [send_enabled]",
Short: "Submit a proposal to set/update/delete send enabled entries",
Example: fmt.Sprintf(`%s tx bank set-send-enabled-proposal '{"denom":"stake","enabled":true}'`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "send_enabled", Varargs: true}},
FlagOptions: map[string]*autocliv1.FlagOptions{
"use_default_for": {Name: "use-default-for", Usage: "Use default for the given denom (delete a send enabled entry)"},
},
GovProposal: true,
},
},
},

View File

@ -1,10 +1,13 @@
package consensus
import (
"fmt"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
consensusv1 "cosmossdk.io/api/cosmos/consensus/v1"
"github.com/cosmos/cosmos-sdk/client/grpc/cmtservice"
"github.com/cosmos/cosmos-sdk/version"
)
// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface.
@ -28,7 +31,16 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "UpdateParams",
Skip: true, // skipped because authority gated
Use: "update-params-proposal [params]",
Short: "Submit a proposal to update consensus module params. Note: the entire params must be provided.",
Example: fmt.Sprintf(`%s tx consensus update-params-proposal '{ params }'`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "block"},
{ProtoField: "evidence"},
{ProtoField: "validator"},
{ProtoField: "abci"},
},
GovProposal: true,
},
},
},

View File

@ -1,8 +1,11 @@
package crisis
import (
"fmt"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
crisisv1beta1 "cosmossdk.io/api/cosmos/crisis/v1beta1"
"github.com/cosmos/cosmos-sdk/version"
)
// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface.
@ -21,8 +24,12 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
},
},
{
RpcMethod: "UpdateParams",
Skip: true, // Skipped because UpdateParams is authority gated
RpcMethod: "UpdateParams",
Use: "update-params-proposal [params]",
Short: "Submit a proposal to update crisis module params. Note: the entire params must be provided.",
Example: fmt.Sprintf(`%s tx crisis update-params-proposal '{ "constant_fee": {"denom": "stake", "amount": "1000"} }'`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "params"}},
GovProposal: true,
},
},
},

View File

@ -4,7 +4,7 @@ import (
"fmt"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
distirbuitonv1beta1 "cosmossdk.io/api/cosmos/distribution/v1beta1"
distributionv1beta1 "cosmossdk.io/api/cosmos/distribution/v1beta1"
"github.com/cosmos/cosmos-sdk/version"
)
@ -13,7 +13,7 @@ import (
func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
return &autocliv1.ModuleOptions{
Query: &autocliv1.ServiceCommandDescriptor{
Service: distirbuitonv1beta1.Query_ServiceDesc.ServiceName,
Service: distributionv1beta1.Query_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "Params",
@ -88,7 +88,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
},
},
Tx: &autocliv1.ServiceCommandDescriptor{
Service: distirbuitonv1beta1.Msg_ServiceDesc.ServiceName,
Service: distributionv1beta1.Msg_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "SetWithdrawAddress",
@ -135,15 +135,26 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
},
},
{
RpcMethod: "UpdateParams",
Skip: true, // skipped because authority gated
RpcMethod: "UpdateParams",
Use: "update-params-proposal [params]",
Short: "Submit a proposal to update distribution module params. Note: the entire params must be provided.",
Example: fmt.Sprintf(`%s tx distribution update-params-proposal '{ "community_tax": "20000", "base_proposer_reward": "0", "bonus_proposer_reward": "0", "withdraw_addr_enabled": true }'`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "params"}},
GovProposal: true,
},
{
RpcMethod: "CommunityPoolSpend",
Skip: true, // skipped because authority gated
Use: "community-pool-spend-proposal [recipient] [amount]",
Example: fmt.Sprintf(`$ %s tx distribution community-pool-spend-proposal [recipient] 100uatom`, version.AppName),
Short: "Submit a proposal to spend from the community pool",
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "recipient"},
{ProtoField: "amount", Varargs: true},
},
GovProposal: true,
},
},
EnhanceCustomCommand: false, // use custom commands only until v0.51
EnhanceCustomCommand: true,
},
}
}

View File

@ -131,8 +131,13 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
},
},
{
RpcMethod: "UpdateParams",
Skip: true, // skipped because authority gated
RpcMethod: "UpdateParams",
Use: "update-params-proposal [params]",
Short: "Submit a proposal to update gov module params. Note: the entire params must be provided.",
Long: fmt.Sprintf("Submit a proposal to update gov module params. Note: the entire params must be provided.\n See the fields to fill in by running `%s query gov params --output json`", version.AppName),
Example: fmt.Sprintf(`%s tx gov update-params-proposal '{ params }'`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "params"}},
GovProposal: true,
},
},
EnhanceCustomCommand: false, // use custom commands only until v0.51

View File

@ -53,6 +53,8 @@ var suggestedProposalTypes = []proposalType{
// Prompt prompts the user for all values of the given type.
// data is the struct to be filled
// namePrefix is the name to be displayed as "Enter <namePrefix> <field>"
// TODO: when bringing this in autocli, use proto message instead
// this will simplify the get address logic
func Prompt[T any](data T, namePrefix string) (T, error) {
v := reflect.ValueOf(&data).Elem()
if v.Kind() == reflect.Interface {

View File

@ -27,6 +27,8 @@ const (
flagStatus = "status"
FlagMetadata = "metadata"
FlagSummary = "summary"
FlagExpedited = "expedited"
// Deprecated: only used for v1beta1 legacy proposals.
FlagProposal = "proposal"
// Deprecated: only used for v1beta1 legacy proposals.

View File

@ -131,13 +131,14 @@ func AddGovPropFlagsToCmd(cmd *cobra.Command) {
cmd.Flags().String(FlagMetadata, "", "The metadata to include with the governance proposal")
cmd.Flags().String(FlagTitle, "", "The title to put on the governance proposal")
cmd.Flags().String(FlagSummary, "", "The summary to include with the governance proposal")
cmd.Flags().Bool(FlagExpedited, false, "Whether to expedite the governance proposal")
}
// ReadGovPropFlags parses a MsgSubmitProposal from the provided context and flags.
// ReadGovPropCmdFlags parses a MsgSubmitProposal from the provided context and flags.
// Setting the messages is up to the caller.
//
// See also AddGovPropFlagsToCmd.
func ReadGovPropFlags(clientCtx client.Context, flagSet *pflag.FlagSet) (*govv1.MsgSubmitProposal, error) {
func ReadGovPropCmdFlags(proposer string, flagSet *pflag.FlagSet) (*govv1.MsgSubmitProposal, error) {
rv := &govv1.MsgSubmitProposal{}
deposit, err := flagSet.GetString(FlagDeposit)
@ -166,7 +167,21 @@ func ReadGovPropFlags(clientCtx client.Context, flagSet *pflag.FlagSet) (*govv1.
return nil, fmt.Errorf("could not read summary: %w", err)
}
rv.Proposer = clientCtx.GetFromAddress().String()
rv.Expedited, err = flagSet.GetBool(FlagExpedited)
if err != nil {
return nil, fmt.Errorf("could not read expedited: %w", err)
}
rv.Proposer = proposer
return rv, nil
}
// ReadGovPropFlags parses a MsgSubmitProposal from the provided context and flags.
// Setting the messages is up to the caller.
//
// See also AddGovPropFlagsToCmd.
// Deprecated: use ReadPropCmdFlags instead, as this depends on global bech32 prefixes.
func ReadGovPropFlags(clientCtx client.Context, flagSet *pflag.FlagSet) (*govv1.MsgSubmitProposal, error) {
return ReadGovPropCmdFlags(clientCtx.GetFromAddress().String(), flagSet)
}

View File

@ -1,8 +1,12 @@
package mint
import (
"fmt"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
mintv1beta1 "cosmossdk.io/api/cosmos/mint/v1beta1"
"github.com/cosmos/cosmos-sdk/version"
)
func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
@ -31,8 +35,13 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
Service: mintv1beta1.Msg_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "UpdateParams",
Skip: true, // skipped because authority gated
RpcMethod: "UpdateParams",
Use: "update-params-proposal [params]",
Short: "Submit a proposal to update mint module params. Note: the entire params must be provided.",
Long: fmt.Sprintf("Submit a proposal to update mint module params. Note: the entire params must be provided.\n See the fields to fill in by running `%s query mint params --output json`", version.AppName),
Example: fmt.Sprintf(`%s tx mint update-params-proposal '{ "mint_denom": "stake", ... }'`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "params"}},
GovProposal: true,
},
},
},

View File

@ -46,8 +46,13 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
Example: fmt.Sprintf("%s tx slashing unjail --from [validator]", version.AppName),
},
{
RpcMethod: "UpdateParams",
Skip: true, // skipped because authority gated
RpcMethod: "UpdateParams",
Use: "update-params-proposal [params]",
Short: "Submit a proposal to update slashing module params. Note: the entire params must be provided.",
Long: fmt.Sprintf("Submit a proposal to update slashing module params. Note: the entire params must be provided.\n See the fields to fill in by running `%s query slashing params --output json`", version.AppName),
Example: fmt.Sprintf(`%s tx slashing update-params-proposal '{ "signed_blocks_window": "100", ... }'`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "params"}},
GovProposal: true,
},
},
},

View File

@ -174,8 +174,13 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "validator_address"}, {ProtoField: "amount"}, {ProtoField: "creation_height"}},
},
{
RpcMethod: "UpdateParams",
Skip: true, // skipped because authority gated
RpcMethod: "UpdateParams",
Use: "update-params-proposal [params]",
Short: "Submit a proposal to update staking module params. Note: the entire params must be provided.",
Long: fmt.Sprintf("Submit a proposal to update staking module params. Note: the entire params must be provided.\n See the fields to fill in by running `%s query staking params --output json`", version.AppName),
Example: fmt.Sprintf(`%s tx staking update-params-proposal '{ "unbonding_time": "504h0m0s", ... }'`, version.AppName),
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "params"}},
GovProposal: true,
},
},
EnhanceCustomCommand: false, // use custom commands only until v0.51

View File

@ -49,15 +49,18 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
Tx: &autocliv1.ServiceCommandDescriptor{
Service: upgradev1beta1.Msg_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "CancelUpgrade",
Use: "cancel-upgrade-proposal",
Short: "Submit a proposal to cancel a planned chain upgrade.",
GovProposal: true,
},
{
RpcMethod: "SoftwareUpgrade",
Skip: true, // skipped because authority gated
},
{
RpcMethod: "CancelUpgrade",
Skip: true, // skipped because authority gated
},
},
EnhanceCustomCommand: true,
},
}
}