From 7d64654906d34f6273638ff369b8a278701619a7 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Mon, 5 Dec 2022 15:59:32 -0600 Subject: [PATCH 1/2] Use reflection + Generics to delete most CLI boilerplate for queries (#3611) Makes new, far more succinct methods, to build tx and query CLI's (cherry picked from commit ce98bbb7a56e168b90e1ebd2ddafe3b4be236302) # Conflicts: # x/valset-pref/client/cli/query.go # x/valset-pref/client/cli/tx.go --- CHANGELOG.md | 1 + osmoutils/generic_helper.go | 17 + osmoutils/osmocli/flag_advice.go | 13 + osmoutils/osmocli/index_cmd.go | 31 ++ osmoutils/osmocli/parsers.go | 279 +++++++++++++ osmoutils/osmocli/query_cmd_wrap.go | 132 ++++++ osmoutils/osmocli/string_formatter.go | 49 +++ osmoutils/osmocli/tx_cmd_wrap.go | 89 ++++ x/epochs/client/cli/query.go | 97 +---- x/epochs/client/cli/query_test.go | 73 ---- x/epochs/client/cli/tx.go | 25 -- x/epochs/module.go | 2 +- x/gamm/client/cli/flags.go | 9 +- x/gamm/client/cli/query.go | 350 +++------------- x/gamm/client/cli/tx.go | 497 ++++++---------------- x/ibc-rate-limit/client/cli/query.go | 56 +-- x/incentives/client/cli/query.go | 302 +++----------- x/incentives/client/cli/tx.go | 47 +-- x/lockup/client/cli/cli_test.go | 34 +- x/lockup/client/cli/query.go | 503 +++-------------------- x/lockup/client/cli/tx.go | 171 +------- x/lockup/client/testutil/test_helpers.go | 2 +- x/mint/client/cli/query.go | 14 +- x/mint/client/cli/query_test.go | 60 --- x/pool-incentives/client/cli/cli_test.go | 35 -- x/pool-incentives/client/cli/query.go | 252 ++---------- x/superfluid/client/cli/query.go | 363 +++------------- x/superfluid/client/cli/tx.go | 135 +----- x/tokenfactory/client/cli/query.go | 106 +---- x/tokenfactory/client/cli/tx.go | 160 +------ x/twap/client/cli/query.go | 115 +----- x/txfees/client/cli/query.go | 136 ++---- x/txfees/client/cli/tx.go | 11 +- x/valset-pref/client/cli/query.go | 25 ++ x/valset-pref/client/cli/tx.go | 68 +++ 35 files changed, 1204 insertions(+), 3055 deletions(-) create mode 100644 osmoutils/generic_helper.go create mode 100644 osmoutils/osmocli/flag_advice.go create mode 100644 osmoutils/osmocli/index_cmd.go create mode 100644 osmoutils/osmocli/parsers.go create mode 100644 osmoutils/osmocli/query_cmd_wrap.go create mode 100644 osmoutils/osmocli/string_formatter.go create mode 100644 osmoutils/osmocli/tx_cmd_wrap.go delete mode 100644 x/epochs/client/cli/query_test.go delete mode 100644 x/epochs/client/cli/tx.go delete mode 100644 x/mint/client/cli/query_test.go create mode 100644 x/valset-pref/client/cli/query.go create mode 100644 x/valset-pref/client/cli/tx.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f4f36efadf..8515189aad5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Misc Improvements +* [#3611](https://github.com/osmosis-labs/osmosis/pull/3611) Introduce osmocli, to automate thousands of lines of CLI boilerplate ## v13.0.0 diff --git a/osmoutils/generic_helper.go b/osmoutils/generic_helper.go new file mode 100644 index 00000000000..0a008afcbf2 --- /dev/null +++ b/osmoutils/generic_helper.go @@ -0,0 +1,17 @@ +package osmoutils + +import "reflect" + +// MakeNew makes a new instance of generic T. +// if T is a pointer, makes a new instance of the underlying struct via reflection, +// and then a pointer to it. +func MakeNew[T any]() T { + var v T + if typ := reflect.TypeOf(v); typ.Kind() == reflect.Ptr { + elem := typ.Elem() + //nolint:forcetypeassert + return reflect.New(elem).Interface().(T) // must use reflect + } else { + return *new(T) // v is not ptr, alloc with new + } +} diff --git a/osmoutils/osmocli/flag_advice.go b/osmoutils/osmocli/flag_advice.go new file mode 100644 index 00000000000..c86eedeefde --- /dev/null +++ b/osmoutils/osmocli/flag_advice.go @@ -0,0 +1,13 @@ +package osmocli + +type FlagAdvice struct { + HasPagination bool + + // Map of FieldName -> FlagName + CustomFlagOverrides map[string]string + + // Tx sender value + IsTx bool + TxSenderFieldName string + FromValue string +} diff --git a/osmoutils/osmocli/index_cmd.go b/osmoutils/osmocli/index_cmd.go new file mode 100644 index 00000000000..b1d3f0da1d6 --- /dev/null +++ b/osmoutils/osmocli/index_cmd.go @@ -0,0 +1,31 @@ +package osmocli + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +// Index command, but short is not set. That is left to caller. +func IndexCmd(moduleName string) *cobra.Command { + return &cobra.Command{ + Use: moduleName, + Short: fmt.Sprintf("Querying commands for the %s module", moduleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: indexRunCmd, + } +} + +func indexRunCmd(cmd *cobra.Command, args []string) error { + usageTemplate := `Usage:{{if .HasAvailableSubCommands}} + {{.CommandPath}} [command]{{end}} + +{{if .HasAvailableSubCommands}}Available Commands:{{range .Commands}}{{if .IsAvailableCommand}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}} + +Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} +` + cmd.SetUsageTemplate(usageTemplate) + return cmd.Help() +} diff --git a/osmoutils/osmocli/parsers.go b/osmoutils/osmocli/parsers.go new file mode 100644 index 00000000000..87db8fc3bcb --- /dev/null +++ b/osmoutils/osmocli/parsers.go @@ -0,0 +1,279 @@ +package osmocli + +import ( + "fmt" + "reflect" + "strconv" + "strings" + "time" + + "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/pflag" + + "github.com/osmosis-labs/osmosis/v13/osmoutils" +) + +// Parses arguments 1-1 from args +// makes an exception, where it allows Pagination to come from flags. +func ParseFieldsFromFlagsAndArgs[reqP any](flagAdvice FlagAdvice, flags *pflag.FlagSet, args []string) (reqP, error) { + req := osmoutils.MakeNew[reqP]() + v := reflect.ValueOf(req).Elem() + t := v.Type() + + argIndexOffset := 0 + // Iterate over the fields in the struct + for i := 0; i < t.NumField(); i++ { + arg := "" + if len(args) > i+argIndexOffset { + arg = args[i+argIndexOffset] + } + usedArg, err := ParseField(v, t, i, arg, flagAdvice, flags) + if err != nil { + return req, err + } + if !usedArg { + argIndexOffset -= 1 + } + } + return req, nil +} + +func ParseNumFields[reqP any]() int { + req := osmoutils.MakeNew[reqP]() + v := reflect.ValueOf(req).Elem() + t := v.Type() + return t.NumField() +} + +func ParseExpectedQueryFnName[reqP any]() string { + req := osmoutils.MakeNew[reqP]() + v := reflect.ValueOf(req).Elem() + s := v.Type().String() + // handle some non-std queries + var prefixTrimmed string + if strings.Contains(s, "Query") { + prefixTrimmed = strings.Split(s, "Query")[1] + } else { + prefixTrimmed = strings.Split(s, ".")[1] + } + suffixTrimmed := strings.TrimSuffix(prefixTrimmed, "Request") + return suffixTrimmed +} + +func ParseHasPagination[reqP any]() bool { + req := osmoutils.MakeNew[reqP]() + t := reflect.ValueOf(req).Elem().Type() + for i := 0; i < t.NumField(); i++ { + fType := t.Field(i) + if fType.Type.String() == paginationType { + return true + } + } + return false +} + +const paginationType = "*query.PageRequest" + +// ParseField parses field #fieldIndex from either an arg or a flag. +// Returns true if it was parsed from an argument. +// Returns error if there was an issue in parsing this field. +func ParseField(v reflect.Value, t reflect.Type, fieldIndex int, arg string, flagAdvice FlagAdvice, flags *pflag.FlagSet) (bool, error) { + fVal := v.Field(fieldIndex) + fType := t.Field(fieldIndex) + // fmt.Printf("Field %d: %s %s %s\n", fieldIndex, fType.Name, fType.Type, fType.Type.Kind()) + + parsedFromFlag, err := ParseFieldFromFlag(fVal, fType, flagAdvice, flags) + if err != nil { + return false, err + } + if parsedFromFlag { + return false, nil + } + return true, ParseFieldFromArg(fVal, fType, arg) +} + +// ParseFieldFromFlag attempts to parses the value of a field in a struct from a flag. +// The field is identified by the provided `reflect.StructField`. +// The flag advice and `pflag.FlagSet` are used to determine the flag to parse the field from. +// If the field corresponds to a value from a flag, true is returned. +// Otherwise, `false` is returned. +// In the true case, the parsed value is set on the provided `reflect.Value`. +// An error is returned if there is an issue parsing the field from the flag. +func ParseFieldFromFlag(fVal reflect.Value, fType reflect.StructField, flagAdvice FlagAdvice, flags *pflag.FlagSet) (bool, error) { + lowercaseFieldNameStr := strings.ToLower(fType.Name) + if flagName, ok := flagAdvice.CustomFlagOverrides[lowercaseFieldNameStr]; ok { + return true, parseFieldFromDirectlySetFlag(fVal, fType, flagAdvice, flagName, flags) + } + + kind := fType.Type.Kind() + switch kind { + case reflect.String: + if flagAdvice.IsTx { + // matchesFieldName is true if lowercaseFieldNameStr is the same as TxSenderFieldName, + // or if TxSenderFieldName is left blank, then matches fields named "sender" or "owner" + matchesFieldName := (flagAdvice.TxSenderFieldName == lowercaseFieldNameStr) || + (flagAdvice.TxSenderFieldName == "" && (lowercaseFieldNameStr == "sender" || lowercaseFieldNameStr == "owner")) + if matchesFieldName { + fVal.SetString(flagAdvice.FromValue) + return true, nil + } + } + case reflect.Ptr: + if flagAdvice.HasPagination { + typeStr := fType.Type.String() + if typeStr == paginationType { + pageReq, err := client.ReadPageRequest(flags) + if err != nil { + return true, err + } + fVal.Set(reflect.ValueOf(pageReq)) + return true, nil + } + } + } + return false, nil +} + +func parseFieldFromDirectlySetFlag(fVal reflect.Value, fType reflect.StructField, flagAdvice FlagAdvice, flagName string, flags *pflag.FlagSet) error { + // get string. If its a string great, run through arg parser. Otherwise try setting directly + s, err := flags.GetString(flagName) + if err != nil { + flag := flags.Lookup(flagName) + if flag == nil { + return fmt.Errorf("Programmer set the flag name wrong. Flag %s does not exist", flagName) + } + t := flag.Value.Type() + if t == "uint64" { + u, err := flags.GetUint64(flagName) + if err != nil { + return err + } + fVal.SetUint(u) + return nil + } + } + return ParseFieldFromArg(fVal, fType, s) +} + +func ParseFieldFromArg(fVal reflect.Value, fType reflect.StructField, arg string) error { + switch fType.Type.Kind() { + // SetUint allows anyof type u8, u16, u32, u64, and uint + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + u, err := ParseUint(arg, fType.Name) + if err != nil { + return err + } + fVal.SetUint(u) + return nil + // SetInt allows anyof type i8,i16,i32,i64 and int + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + typeStr := fType.Type.String() + var i int64 + var err error + if typeStr == "time.Duration" { + dur, err2 := time.ParseDuration(arg) + i, err = int64(dur), err2 + } else { + i, err = ParseInt(arg, fType.Name) + } + if err != nil { + return err + } + fVal.SetInt(i) + return nil + case reflect.String: + s, err := ParseDenom(arg, fType.Name) + if err != nil { + return err + } + fVal.SetString(s) + return nil + case reflect.Ptr: + case reflect.Slice: + typeStr := fType.Type.String() + if typeStr == "types.Coins" { + coins, err := ParseCoins(arg, fType.Name) + if err != nil { + return err + } + fVal.Set(reflect.ValueOf(coins)) + return nil + } + case reflect.Struct: + typeStr := fType.Type.String() + var v any + var err error + if typeStr == "types.Coin" { + v, err = ParseCoin(arg, fType.Name) + } else if typeStr == "types.Int" { + v, err = ParseSdkInt(arg, fType.Name) + } else { + return fmt.Errorf("struct field type not recognized. Got type %v", fType) + } + + if err != nil { + return err + } + fVal.Set(reflect.ValueOf(v)) + return nil + } + fmt.Println(fType.Type.Kind().String()) + return fmt.Errorf("field type not recognized. Got type %v", fType) +} + +func ParseUint(arg string, fieldName string) (uint64, error) { + v, err := strconv.ParseUint(arg, 10, 64) + if err != nil { + return 0, fmt.Errorf("could not parse %s as uint for field %s: %w", arg, fieldName, err) + } + return v, nil +} + +func ParseInt(arg string, fieldName string) (int64, error) { + v, err := strconv.ParseInt(arg, 10, 64) + if err != nil { + return 0, fmt.Errorf("could not parse %s as int for field %s: %w", arg, fieldName, err) + } + return v, nil +} + +func ParseUnixTime(arg string, fieldName string) (time.Time, error) { + timeUnix, err := strconv.ParseInt(arg, 10, 64) + if err != nil { + return time.Time{}, fmt.Errorf("could not parse %s as unix time for field %s: %w", arg, fieldName, err) + } + startTime := time.Unix(timeUnix, 0) + return startTime, nil +} + +func ParseDenom(arg string, fieldName string) (string, error) { + return strings.TrimSpace(arg), nil +} + +// TODO: Make this able to read from some local alias file for denoms. +func ParseCoin(arg string, fieldName string) (sdk.Coin, error) { + coin, err := sdk.ParseCoinNormalized(arg) + if err != nil { + return sdk.Coin{}, fmt.Errorf("could not parse %s as sdk.Coin for field %s: %w", arg, fieldName, err) + } + return coin, nil +} + +// TODO: Make this able to read from some local alias file for denoms. +func ParseCoins(arg string, fieldName string) (sdk.Coins, error) { + coins, err := sdk.ParseCoinsNormalized(arg) + if err != nil { + return sdk.Coins{}, fmt.Errorf("could not parse %s as sdk.Coins for field %s: %w", arg, fieldName, err) + } + return coins, nil +} + +// TODO: This really shouldn't be getting used in the CLI, its misdesign on the CLI ux +func ParseSdkInt(arg string, fieldName string) (sdk.Int, error) { + i, ok := sdk.NewIntFromString(arg) + if !ok { + return sdk.Int{}, fmt.Errorf("could not parse %s as sdk.Int for field %s", arg, fieldName) + } + return i, nil +} diff --git a/osmoutils/osmocli/query_cmd_wrap.go b/osmoutils/osmocli/query_cmd_wrap.go new file mode 100644 index 00000000000..3fa68f2f090 --- /dev/null +++ b/osmoutils/osmocli/query_cmd_wrap.go @@ -0,0 +1,132 @@ +package osmocli + +import ( + "context" + "fmt" + "reflect" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + grpc1 "github.com/gogo/protobuf/grpc" + "github.com/gogo/protobuf/proto" + "github.com/spf13/cobra" +) + +func QueryIndexCmd(moduleName string) *cobra.Command { + cmd := IndexCmd(moduleName) + cmd.Short = fmt.Sprintf("Querying commands for the %s module", moduleName) + return cmd +} + +type QueryDescriptor struct { + Use string + Short string + Long string + + HasPagination bool + + QueryFnName string + + // Map of FieldName -> FlagName + CustomFlagOverrides map[string]string +} + +func SimpleQueryFromDescriptor[reqP proto.Message, querier any](desc QueryDescriptor, newQueryClientFn func(grpc1.ClientConn) querier) *cobra.Command { + numArgs := ParseNumFields[reqP]() - len(desc.CustomFlagOverrides) + if desc.HasPagination { + numArgs = numArgs - 1 + } + if len(desc.CustomFlagOverrides) == 0 { + desc.CustomFlagOverrides = map[string]string{} + } + flagAdvice := FlagAdvice{ + HasPagination: desc.HasPagination, + CustomFlagOverrides: desc.CustomFlagOverrides, + } + cmd := &cobra.Command{ + Use: desc.Use, + Short: desc.Short, + Long: desc.Long, + Args: cobra.ExactArgs(numArgs), + RunE: NewQueryLogicAllFieldsAsArgs[reqP]( + flagAdvice, desc.QueryFnName, newQueryClientFn), + } + flags.AddQueryFlagsToCmd(cmd) + if desc.HasPagination { + cmdName := strings.Split(desc.Use, " ")[0] + flags.AddPaginationFlagsToCmd(cmd, cmdName) + } + + return cmd +} + +// SimpleQueryCmd builds a query, for the common, simple case. +// It detects that the querier function name is the same as the ProtoMessage name, +// with just the "Query" and "Request" args chopped off. +// It expects all proto fields to appear as arguments, in order. +func SimpleQueryCmd[reqP proto.Message, querier any](use string, short string, long string, + moduleName string, newQueryClientFn func(grpc1.ClientConn) querier) *cobra.Command { + desc := QueryDescriptor{ + Use: use, + Short: short, + Long: FormatLongDesc(long, NewLongMetadata(moduleName).WithShort(short)), + HasPagination: ParseHasPagination[reqP](), + QueryFnName: ParseExpectedQueryFnName[reqP](), + } + return SimpleQueryFromDescriptor[reqP](desc, newQueryClientFn) +} + +func GetParams[reqP proto.Message, querier any](moduleName string, + newQueryClientFn func(grpc1.ClientConn) querier) *cobra.Command { + return SimpleQueryFromDescriptor[reqP](QueryDescriptor{ + Use: "params [flags]", + Short: fmt.Sprintf("Get the params for the x/%s module", moduleName), + QueryFnName: "Params", + }, newQueryClientFn) +} + +func callQueryClientFn[reqP proto.Message, querier any](ctx context.Context, fnName string, req reqP, q querier) (res proto.Message, err error) { + qVal := reflect.ValueOf(q) + method := qVal.MethodByName(fnName) + args := []reflect.Value{ + reflect.ValueOf(ctx), + reflect.ValueOf(req), + } + results := method.Call(args) + if len(results) != 2 { + panic("We got something wrong") + } + if !results[1].IsNil() { + //nolint:forcetypeassert + err = results[1].Interface().(error) + return res, err + } + //nolint:forcetypeassert + res = results[0].Interface().(proto.Message) + return res, nil +} + +func NewQueryLogicAllFieldsAsArgs[reqP proto.Message, querier any](flagAdvice FlagAdvice, keeperFnName string, + newQueryClientFn func(grpc1.ClientConn) querier) func(cmd *cobra.Command, args []string) error { + return func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := newQueryClientFn(clientCtx) + var req reqP + + req, err = ParseFieldsFromFlagsAndArgs[reqP](flagAdvice, cmd.Flags(), args) + if err != nil { + return err + } + + res, err := callQueryClientFn(cmd.Context(), keeperFnName, req, queryClient) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + } +} diff --git a/osmoutils/osmocli/string_formatter.go b/osmoutils/osmocli/string_formatter.go new file mode 100644 index 00000000000..43c57725e7c --- /dev/null +++ b/osmoutils/osmocli/string_formatter.go @@ -0,0 +1,49 @@ +package osmocli + +import ( + "fmt" + "strings" + "text/template" + + "github.com/cosmos/cosmos-sdk/version" +) + +type LongMetadata struct { + BinaryName string + CommandPrefix string + Short string + + // Newline Example: + ExampleHeader string +} + +func NewLongMetadata(moduleName string) *LongMetadata { + commandPrefix := fmt.Sprintf("$ %s q %s", version.AppName, moduleName) + return &LongMetadata{ + BinaryName: version.AppName, + CommandPrefix: commandPrefix, + } +} + +func (m *LongMetadata) WithShort(short string) *LongMetadata { + m.Short = short + return m +} + +func FormatLongDesc(longString string, meta *LongMetadata) string { + template, err := template.New("long_description").Parse(longString) + if err != nil { + panic("incorrectly configured long message") + } + bld := strings.Builder{} + meta.ExampleHeader = "\n\nExample:" + err = template.Execute(&bld, meta) + if err != nil { + panic("incorrectly configured long message") + } + return strings.TrimSpace(bld.String()) +} + +func FormatLongDescDirect(longString string, moduleName string) string { + return FormatLongDesc(longString, NewLongMetadata(moduleName)) +} diff --git a/osmoutils/osmocli/tx_cmd_wrap.go b/osmoutils/osmocli/tx_cmd_wrap.go new file mode 100644 index 00000000000..6f63a33e800 --- /dev/null +++ b/osmoutils/osmocli/tx_cmd_wrap.go @@ -0,0 +1,89 @@ +package osmocli + +import ( + "fmt" + "strings" + + "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/spf13/cobra" + "github.com/spf13/pflag" +) + +func TxIndexCmd(moduleName string) *cobra.Command { + cmd := IndexCmd(moduleName) + cmd.Short = fmt.Sprintf("%s transactions subcommands", moduleName) + return cmd +} + +type TxCliDesc struct { + Use string + Short string + Long string + Example string + + NumArgs int + // Contract: len(args) = NumArgs + ParseAndBuildMsg func(clientCtx client.Context, args []string, flags *pflag.FlagSet) (sdk.Msg, error) + TxSignerFieldName string + + // Map of FieldName -> FlagName + CustomFlagOverrides map[string]string +} + +func BuildTxCli[M sdk.Msg](desc *TxCliDesc) *cobra.Command { + desc.TxSignerFieldName = strings.ToLower(desc.TxSignerFieldName) + if desc.NumArgs == 0 { + // NumArgs = NumFields - 1, since 1 field is from the msg + desc.NumArgs = ParseNumFields[M]() - 1 - len(desc.CustomFlagOverrides) + } + if len(desc.CustomFlagOverrides) == 0 { + desc.CustomFlagOverrides = map[string]string{} + } + desc.ParseAndBuildMsg = func(clientCtx client.Context, args []string, flags *pflag.FlagSet) (sdk.Msg, error) { + flagAdvice := FlagAdvice{ + IsTx: true, + TxSenderFieldName: desc.TxSignerFieldName, + FromValue: clientCtx.GetFromAddress().String(), + CustomFlagOverrides: desc.CustomFlagOverrides, + } + return ParseFieldsFromFlagsAndArgs[M](flagAdvice, flags, args) + } + return desc.BuildCommandCustomFn() +} + +// Creates a new cobra command given the description. +// Its up to then caller to add CLI flags, aside from `flags.AddTxFlagsToCmd(cmd)` +func (desc TxCliDesc) BuildCommandCustomFn() *cobra.Command { + cmd := &cobra.Command{ + Use: desc.Use, + Short: desc.Short, + Args: cobra.ExactArgs(desc.NumArgs), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + msg, err := desc.ParseAndBuildMsg(clientCtx, args, cmd.Flags()) + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + if desc.Example != "" { + cmd.Example = desc.Example + } + if desc.Long != "" { + cmd.Long = desc.Long + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} diff --git a/x/epochs/client/cli/query.go b/x/epochs/client/cli/query.go index b3827abd60c..9cce798ccef 100644 --- a/x/epochs/client/cli/query.go +++ b/x/epochs/client/cli/query.go @@ -1,28 +1,15 @@ package cli import ( - "fmt" - "strings" - "github.com/spf13/cobra" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/epochs/types" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/version" ) // GetQueryCmd returns the cli query commands for this module. func GetQueryCmd() *cobra.Command { - // Group epochs queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } + cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand( GetCmdEpochsInfos(), @@ -32,76 +19,24 @@ func GetQueryCmd() *cobra.Command { return cmd } -// GetCmdEpochsInfos provide running epochInfos. func GetCmdEpochsInfos() *cobra.Command { - cmd := &cobra.Command{ - Use: "epoch-infos", - Short: "Query running epochInfos", - Long: strings.TrimSpace( - fmt.Sprintf(`Query running epoch infos. - -Example: -$ %s query epochs epoch-infos + return osmocli.SimpleQueryCmd[*types.QueryEpochsInfoRequest]( + "epoch-infos", + "Query running epochInfos", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} epoch-infos `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.EpochInfos(cmd.Context(), &types.QueryEpochsInfoRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdCurrentEpoch provides current epoch by specified identifier. func GetCmdCurrentEpoch() *cobra.Command { - cmd := &cobra.Command{ - Use: "current-epoch", - Short: "Query current epoch by specified identifier", - Long: strings.TrimSpace( - fmt.Sprintf(`Query current epoch by specified identifier. - -Example: -$ %s query epochs current-epoch day + return osmocli.SimpleQueryCmd[*types.QueryCurrentEpochRequest]( + "current-epoch [identifier]", + "Query current epoch by specified identifier", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} current-epoch day `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - 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.CurrentEpoch(cmd.Context(), &types.QueryCurrentEpochRequest{ - Identifier: args[0], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } diff --git a/x/epochs/client/cli/query_test.go b/x/epochs/client/cli/query_test.go deleted file mode 100644 index d03511c37ca..00000000000 --- a/x/epochs/client/cli/query_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package cli_test - -import ( - gocontext "context" - "testing" - "time" - - "github.com/stretchr/testify/suite" - - "github.com/osmosis-labs/osmosis/v13/app/apptesting" - "github.com/osmosis-labs/osmosis/v13/x/epochs/types" -) - -type QueryTestSuite struct { - apptesting.KeeperTestHelper - queryClient types.QueryClient -} - -func (s *QueryTestSuite) SetupSuite() { - s.Setup() - s.queryClient = types.NewQueryClient(s.QueryHelper) - - // add new epoch - epoch := types.EpochInfo{ - Identifier: "weekly", - StartTime: time.Time{}, - Duration: time.Hour, - CurrentEpoch: 0, - CurrentEpochStartHeight: 0, - CurrentEpochStartTime: time.Time{}, - EpochCountingStarted: false, - } - s.App.EpochsKeeper.AddEpochInfo(s.Ctx, epoch) - - s.Commit() -} - -func (s *QueryTestSuite) TestQueriesNeverAlterState() { - testCases := []struct { - name string - query string - input interface{} - output interface{} - }{ - { - "Query current epoch", - "/osmosis.epochs.v1beta1.Query/CurrentEpoch", - &types.QueryCurrentEpochRequest{Identifier: "weekly"}, - &types.QueryCurrentEpochResponse{}, - }, - { - "Query epochs info", - "/osmosis.epochs.v1beta1.Query/EpochInfos", - &types.QueryEpochsInfoRequest{}, - &types.QueryEpochsInfoResponse{}, - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - s.SetupSuite() - err := s.QueryHelper.Invoke(gocontext.Background(), tc.query, tc.input, tc.output) - s.Require().NoError(err) - s.StateNotAltered() - }) - } -} - -func TestQueryTestSuite(t *testing.T) { - suite.Run(t, new(QueryTestSuite)) -} diff --git a/x/epochs/client/cli/tx.go b/x/epochs/client/cli/tx.go deleted file mode 100644 index 46932dbef9f..00000000000 --- a/x/epochs/client/cli/tx.go +++ /dev/null @@ -1,25 +0,0 @@ -package cli - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/client" - - // "github.com/cosmos/cosmos-sdk/client/flags". - "github.com/osmosis-labs/osmosis/v13/x/epochs/types" -) - -// GetTxCmd returns the transaction commands for this module. -func GetTxCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - return cmd -} diff --git a/x/epochs/module.go b/x/epochs/module.go index 71ab4c8f2d9..65d14405268 100644 --- a/x/epochs/module.go +++ b/x/epochs/module.go @@ -84,7 +84,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // GetTxCmd returns the capability module's root tx command. func (a AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.GetTxCmd() + return nil } // GetQueryCmd returns the capability module's root query command. diff --git a/x/gamm/client/cli/flags.go b/x/gamm/client/cli/flags.go index 0cb98129b54..05ef34caccc 100644 --- a/x/gamm/client/cli/flags.go +++ b/x/gamm/client/cli/flags.go @@ -111,19 +111,14 @@ func FlagSetExitPool() *flag.FlagSet { return fs } -func FlagSetJoinSwapExternAmount() *flag.FlagSet { +func FlagSetJustPoolId() *flag.FlagSet { fs := flag.NewFlagSet("", flag.ContinueOnError) - fs.Uint64(FlagPoolId, 0, "The id of pool") - return fs } func FlagSetAdjustScalingFactors() *flag.FlagSet { - fs := flag.NewFlagSet("", flag.ContinueOnError) - - fs.Uint64(FlagPoolId, 0, "The id of pool") + fs := FlagSetJustPoolId() fs.String(FlagScalingFactors, "", "The scaling factors") - return fs } diff --git a/x/gamm/client/cli/query.go b/x/gamm/client/cli/query.go index 51a10ed2757..b91c01ffe3a 100644 --- a/x/gamm/client/cli/query.go +++ b/x/gamm/client/cli/query.go @@ -16,20 +16,14 @@ import ( "github.com/spf13/cobra" "gopkg.in/yaml.v2" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/gamm/pool-models/balancer" "github.com/osmosis-labs/osmosis/v13/x/gamm/types" ) // GetQueryCmd returns the cli query commands for this module. func GetQueryCmd() *cobra.Command { - // Group gamm queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } + cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand( GetCmdPool(), @@ -49,45 +43,16 @@ func GetQueryCmd() *cobra.Command { return cmd } -// GetCmdPool returns pool. func GetCmdPool() *cobra.Command { - cmd := &cobra.Command{ - Use: "pool ", - Short: "Query pool", - Long: strings.TrimSpace( - fmt.Sprintf(`Query pool. + return osmocli.SimpleQueryCmd[*types.QueryPoolRequest]( + "pool [poolID]", + "Query pool", + `Query pool. Example: -$ %s query gamm pool 1 +{{.CommandPrefix}} pool 1 `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - poolID, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - res, err := queryClient.Pool(cmd.Context(), &types.QueryPoolRequest{ - PoolId: uint64(poolID), - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } // TODO: Push this to the SDK. @@ -112,82 +77,23 @@ func writeOutputBoilerplate(ctx client.Context, out []byte) error { return nil } -// GetCmdPools return pools. func GetCmdPools() *cobra.Command { - cmd := &cobra.Command{ - Use: "pools", - Short: "Query pools", - Long: strings.TrimSpace( - fmt.Sprintf(`Query pools. -Example: -$ %s query gamm pools -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - res, err := queryClient.Pools(cmd.Context(), &types.QueryPoolsRequest{ - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "pools") - - return cmd + return osmocli.SimpleQueryCmd[*types.QueryPoolsRequest]( + "pools", + "Query pools", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} pools`, + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdNumPools return number of pools available. func GetCmdNumPools() *cobra.Command { - cmd := &cobra.Command{ - Use: "num-pools", - Short: "Query number of pools", - Long: strings.TrimSpace( - fmt.Sprintf(`Query number of pools. -Example: -$ %s query gamm num-pools -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.NumPools(cmd.Context(), &types.QueryNumPoolsRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.QueryNumPoolsRequest]( + "num-pools", + "Query number of pools", + "{{.Short}}", + types.ModuleName, types.NewQueryClient, + ) } // GetCmdPoolParams return pool params. @@ -250,160 +156,53 @@ $ %s query gamm pool-params 1 return cmd } -// GetCmd return total share. func GetCmdTotalPoolLiquidity() *cobra.Command { - cmd := &cobra.Command{ - Use: "total-pool-liquidity ", - Short: "Query total-pool-liquidity", - Long: strings.TrimSpace( - fmt.Sprintf(`Query total-pool-liquidity. + return osmocli.SimpleQueryCmd[*types.QueryTotalPoolLiquidityRequest]( + "total-pool-liquidity [poolID]", + "Query total-pool-liquidity", + `Query total-pool-liquidity. Example: -$ %s query gamm total-pool-liquidity 1 +{{.CommandPrefix}} total-pool-liquidity 1 `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - poolID, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - res, err := queryClient.TotalPoolLiquidity(cmd.Context(), &types.QueryTotalPoolLiquidityRequest{ - PoolId: uint64(poolID), - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdTotalShares return total share. func GetCmdTotalShares() *cobra.Command { - cmd := &cobra.Command{ - Use: "total-share ", - Short: "Query total-share", - Long: strings.TrimSpace( - fmt.Sprintf(`Query total-share. + return osmocli.SimpleQueryCmd[*types.QueryTotalSharesRequest]( + "total-share [poolID]", + "Query total-share", + `Query total-share. Example: -$ %s query gamm total-share 1 +{{.CommandPrefix}} total-share 1 `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - poolID, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - res, err := queryClient.TotalShares(cmd.Context(), &types.QueryTotalSharesRequest{ - PoolId: uint64(poolID), - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdQueryTotalLiquidity return total liquidity. func GetCmdQueryTotalLiquidity() *cobra.Command { - cmd := &cobra.Command{ - Use: "total-liquidity", - Short: "Query total-liquidity", - Long: strings.TrimSpace( - fmt.Sprintf(`Query total-liquidity. + return osmocli.SimpleQueryCmd[*types.QueryTotalLiquidityRequest]( + "total-liquidity", + "Query total-liquidity", + `Query total-liquidity. Example: -$ %s query gamm total-liquidity +{{.CommandPrefix}} total-liquidity `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.TotalLiquidity(cmd.Context(), &types.QueryTotalLiquidityRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdSpotPrice returns spot price func GetCmdSpotPrice() *cobra.Command { - cmd := &cobra.Command{ - Use: "spot-price ", - Short: "Query spot-price", - Args: cobra.ExactArgs(3), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(clientCtx) - - poolID, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - // nolint: staticcheck - res, err := queryClient.SpotPrice(cmd.Context(), &types.QuerySpotPriceRequest{ - PoolId: uint64(poolID), - BaseAssetDenom: args[1], - QuoteAssetDenom: args[2], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - return cmd + //nolint:staticcheck + return osmocli.SimpleQueryCmd[*types.QuerySpotPriceRequest]( + "spot-price [quote-asset-denom] [base-asset-denom]", + "Query spot-price (LEGACY, arguments are reversed!!)", + `Query spot price (Legacy). +Example: +{{.CommandPrefix}} spot-price 1 uosmo ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2 +`, + types.ModuleName, types.NewQueryClient, + ) } // GetCmdEstimateSwapExactAmountIn returns estimation of output coin when amount of x token input. @@ -576,42 +375,13 @@ $ %s query gamm pools-with-filter // GetCmdPoolType returns pool type given pool id. func GetCmdPoolType() *cobra.Command { - cmd := &cobra.Command{ - Use: "pool-type ", - Short: "Query pool type", - Long: strings.TrimSpace( - fmt.Sprintf(`Query pool type + return osmocli.SimpleQueryCmd[*types.QueryPoolTypeRequest]( + "pool-type ", + "Query pool type", + `Query pool type Example: -$ %s query gamm pool-type +{{.CommandPrefix}} pool-type `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - poolID, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - res, err := queryClient.PoolType(cmd.Context(), &types.QueryPoolTypeRequest{ - PoolId: uint64(poolID), - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } diff --git a/x/gamm/client/cli/tx.go b/x/gamm/client/cli/tx.go index 2fe57502ceb..9323e6937b9 100644 --- a/x/gamm/client/cli/tx.go +++ b/x/gamm/client/cli/tx.go @@ -10,6 +10,7 @@ import ( "github.com/spf13/cobra" flag "github.com/spf13/pflag" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/gamm/pool-models/balancer" "github.com/osmosis-labs/osmosis/v13/x/gamm/pool-models/stableswap" "github.com/osmosis-labs/osmosis/v13/x/gamm/types" @@ -45,6 +46,10 @@ func NewTxCmd() *cobra.Command { return txCmd } +var poolIdFlagOverride = map[string]string{ + "poolid": FlagPoolId, +} + func NewCreatePoolCmd() *cobra.Command { cmd := &cobra.Command{ Use: "create-pool [flags]", @@ -86,12 +91,12 @@ For stableswap (demonstrating need for a 1:1000 scaling factor, see doc) var msg sdk.Msg if poolType == "balancer" || poolType == "uniswap" { - txf, msg, err = NewBuildCreateBalancerPoolMsg(clientCtx, txf, cmd.Flags()) + msg, err = NewBuildCreateBalancerPoolMsg(clientCtx, cmd.Flags()) if err != nil { return err } } else if poolType == "stableswap" { - txf, msg, err = NewBuildCreateStableswapPoolMsg(clientCtx, txf, cmd.Flags()) + msg, err = NewBuildCreateStableswapPoolMsg(clientCtx, cmd.Flags()) if err != nil { return err } @@ -110,308 +115,161 @@ For stableswap (demonstrating need for a 1:1000 scaling factor, see doc) } func NewJoinPoolCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "join-pool", - Short: "join a new pool and provide the liquidity to it", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - txf, msg, err := NewBuildJoinPoolMsg(clientCtx, txf, cmd.Flags()) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } + cmd := osmocli.TxCliDesc{ + Use: "join-pool", + Short: "join a new pool and provide the liquidity to it", + NumArgs: 0, + ParseAndBuildMsg: NewBuildJoinPoolMsg, + }.BuildCommandCustomFn() cmd.Flags().AddFlagSet(FlagSetJoinPool()) - flags.AddTxFlagsToCmd(cmd) - _ = cmd.MarkFlagRequired(FlagPoolId) _ = cmd.MarkFlagRequired(FlagShareAmountOut) _ = cmd.MarkFlagRequired(FlagMaxAmountsIn) - return cmd } func NewExitPoolCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "exit-pool", - Short: "exit a new pool and withdraw the liquidity from it", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - txf, msg, err := NewBuildExitPoolMsg(clientCtx, txf, cmd.Flags()) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } + cmd := osmocli.TxCliDesc{ + Use: "exit-pool", + Short: "exit a new pool and withdraw the liquidity from it", + NumArgs: 0, + ParseAndBuildMsg: NewBuildExitPoolMsg, + }.BuildCommandCustomFn() cmd.Flags().AddFlagSet(FlagSetExitPool()) - flags.AddTxFlagsToCmd(cmd) - _ = cmd.MarkFlagRequired(FlagPoolId) _ = cmd.MarkFlagRequired(FlagShareAmountIn) _ = cmd.MarkFlagRequired(FlagMinAmountsOut) - return cmd } func NewSwapExactAmountInCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "swap-exact-amount-in [token-in] [token-out-min-amount]", - Short: "swap exact amount in", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - txf, msg, err := NewBuildSwapExactAmountInMsg(clientCtx, args[0], args[1], txf, cmd.Flags()) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } + cmd := osmocli.TxCliDesc{ + Use: "swap-exact-amount-in [token-in] [token-out-min-amount]", + Short: "swap exact amount in", + NumArgs: 2, + ParseAndBuildMsg: NewBuildSwapExactAmountInMsg, + }.BuildCommandCustomFn() cmd.Flags().AddFlagSet(FlagSetQuerySwapRoutes()) - flags.AddTxFlagsToCmd(cmd) _ = cmd.MarkFlagRequired(FlagSwapRoutePoolIds) _ = cmd.MarkFlagRequired(FlagSwapRouteDenoms) - return cmd } func NewSwapExactAmountOutCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "swap-exact-amount-out [token-out] [token-in-max-amount]", - Short: "swap exact amount out", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - txf, msg, err := NewBuildSwapExactAmountOutMsg(clientCtx, args[0], args[1], txf, cmd.Flags()) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } + cmd := osmocli.TxCliDesc{ + Use: "swap-exact-amount-out [token-out] [token-in-max-amount]", + Short: "swap exact amount out", + NumArgs: 2, + ParseAndBuildMsg: NewBuildSwapExactAmountOutMsg, + }.BuildCommandCustomFn() cmd.Flags().AddFlagSet(FlagSetSwapAmountOutRoutes()) - flags.AddTxFlagsToCmd(cmd) _ = cmd.MarkFlagRequired(FlagSwapRoutePoolIds) _ = cmd.MarkFlagRequired(FlagSwapRouteDenoms) - return cmd } func NewJoinSwapExternAmountIn() *cobra.Command { - cmd := &cobra.Command{ - Use: "join-swap-extern-amount-in [token-in] [share-out-min-amount]", - Short: "join swap extern amount in", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - txf, msg, err := NewBuildJoinSwapExternAmountInMsg(clientCtx, args[0], args[1], txf, cmd.Flags()) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } + cmd := osmocli.BuildTxCli[*types.MsgJoinSwapExternAmountIn](&osmocli.TxCliDesc{ + Use: "join-swap-extern-amount-in [token-in] [share-out-min-amount]", + Short: "join swap extern amount in", + CustomFlagOverrides: poolIdFlagOverride, + }) - cmd.Flags().AddFlagSet(FlagSetJoinSwapExternAmount()) - flags.AddTxFlagsToCmd(cmd) + cmd.Flags().AddFlagSet(FlagSetJustPoolId()) _ = cmd.MarkFlagRequired(FlagPoolId) - return cmd } func NewJoinSwapShareAmountOut() *cobra.Command { - cmd := &cobra.Command{ - Use: "join-swap-share-amount-out [token-in-denom] [token-in-max-amount] [share-out-amount]", - Short: "join swap share amount out", - Args: cobra.ExactArgs(3), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + cmd := osmocli.BuildTxCli[*types.MsgJoinSwapShareAmountOut](&osmocli.TxCliDesc{ + Use: "join-swap-share-amount-out [token-in-denom] [token-in-max-amount] [share-out-amount]", + Short: "join swap share amount out", + CustomFlagOverrides: poolIdFlagOverride, + }) - txf, msg, err := NewBuildJoinSwapShareAmountOutMsg(clientCtx, args[0], args[1], args[2], txf, cmd.Flags()) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - cmd.Flags().AddFlagSet(FlagSetJoinSwapExternAmount()) - flags.AddTxFlagsToCmd(cmd) + cmd.Flags().AddFlagSet(FlagSetJustPoolId()) _ = cmd.MarkFlagRequired(FlagPoolId) - return cmd } func NewExitSwapExternAmountOut() *cobra.Command { - cmd := &cobra.Command{ - Use: "exit-swap-extern-amount-out [token-out] [share-in-max-amount]", - Short: "exit swap extern amount out", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } + cmd := osmocli.BuildTxCli[*types.MsgExitSwapExternAmountOut](&osmocli.TxCliDesc{ + Use: "exit-swap-extern-amount-out [token-out] [share-in-max-amount]", + Short: "exit swap extern amount out", + CustomFlagOverrides: poolIdFlagOverride, + }) - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - txf, msg, err := NewBuildExitSwapExternAmountOutMsg(clientCtx, args[0], args[1], txf, cmd.Flags()) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - cmd.Flags().AddFlagSet(FlagSetJoinSwapExternAmount()) - flags.AddTxFlagsToCmd(cmd) + cmd.Flags().AddFlagSet(FlagSetJustPoolId()) _ = cmd.MarkFlagRequired(FlagPoolId) - return cmd } func NewExitSwapShareAmountIn() *cobra.Command { - cmd := &cobra.Command{ - Use: "exit-swap-share-amount-in [token-out-denom] [share-in-amount] [token-out-min-amount]", - Short: "exit swap share amount in", - Args: cobra.ExactArgs(3), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - txf, msg, err := NewBuildExitSwapShareAmountInMsg(clientCtx, args[0], args[1], args[2], txf, cmd.Flags()) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } + cmd := osmocli.BuildTxCli[*types.MsgExitSwapShareAmountIn](&osmocli.TxCliDesc{ + Use: "exit-swap-share-amount-in [token-out-denom] [share-in-amount] [token-out-min-amount]", + Short: "exit swap share amount in", + CustomFlagOverrides: poolIdFlagOverride, + }) - cmd.Flags().AddFlagSet(FlagSetJoinSwapExternAmount()) - flags.AddTxFlagsToCmd(cmd) + cmd.Flags().AddFlagSet(FlagSetJustPoolId()) _ = cmd.MarkFlagRequired(FlagPoolId) - return cmd } +// TODO: Change these flags to args. Required flags don't make that much sense. func NewStableSwapAdjustScalingFactorsCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "adjust-scaling-factors --pool-id=[pool-id] --scaling-factors=[scaling-factors]", - Short: "adjust scaling factors", - Example: "osmosisd adjust-scaling-factors --pool-id=1 --scaling-factors=\"100, 100\"", - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - txf, msg, err := NewStableSwapAdjustScalingFactorsMsg(clientCtx, txf, cmd.Flags()) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } + cmd := osmocli.TxCliDesc{ + Use: "adjust-scaling-factors --pool-id=[pool-id] --scaling-factors=[scaling-factors]", + Short: "adjust scaling factors", + Example: "osmosisd adjust-scaling-factors --pool-id=1 --scaling-factors=\"100, 100\"", + NumArgs: 0, + ParseAndBuildMsg: NewStableSwapAdjustScalingFactorsMsg, + }.BuildCommandCustomFn() cmd.Flags().AddFlagSet(FlagSetAdjustScalingFactors()) - flags.AddTxFlagsToCmd(cmd) _ = cmd.MarkFlagRequired(FlagPoolId) - + _ = cmd.MarkFlagRequired(FlagScalingFactors) return cmd } -func NewBuildCreateBalancerPoolMsg(clientCtx client.Context, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { +func NewBuildCreateBalancerPoolMsg(clientCtx client.Context, fs *flag.FlagSet) (sdk.Msg, error) { pool, err := parseCreateBalancerPoolFlags(fs) if err != nil { - return txf, nil, fmt.Errorf("failed to parse pool: %w", err) + return nil, fmt.Errorf("failed to parse pool: %w", err) } deposit, err := sdk.ParseCoinsNormalized(pool.InitialDeposit) if err != nil { - return txf, nil, err + return nil, err } poolAssetCoins, err := sdk.ParseDecCoins(pool.Weights) if err != nil { - return txf, nil, err + return nil, err } if len(deposit) != len(poolAssetCoins) { - return txf, nil, errors.New("deposit tokens and token weights should have same length") + return nil, errors.New("deposit tokens and token weights should have same length") } swapFee, err := sdk.NewDecFromStr(pool.SwapFee) if err != nil { - return txf, nil, err + return nil, err } exitFee, err := sdk.NewDecFromStr(pool.ExitFee) if err != nil { - return txf, nil, err + return nil, err } var poolAssets []balancer.PoolAsset for i := 0; i < len(poolAssetCoins); i++ { if poolAssetCoins[i].Denom != deposit[i].Denom { - return txf, nil, errors.New("deposit tokens and token weights should have same denom order") + return nil, errors.New("deposit tokens and token weights should have same denom order") } poolAssets = append(poolAssets, balancer.PoolAsset{ @@ -435,18 +293,18 @@ func NewBuildCreateBalancerPoolMsg(clientCtx client.Context, txf tx.Factory, fs if (pool.SmoothWeightChangeParams != smoothWeightChangeParamsInputs{}) { duration, err := time.ParseDuration(pool.SmoothWeightChangeParams.Duration) if err != nil { - return txf, nil, fmt.Errorf("could not parse duration: %w", err) + return nil, fmt.Errorf("could not parse duration: %w", err) } targetPoolAssetCoins, err := sdk.ParseDecCoins(pool.SmoothWeightChangeParams.TargetPoolWeights) if err != nil { - return txf, nil, err + return nil, err } var targetPoolAssets []balancer.PoolAsset for i := 0; i < len(targetPoolAssetCoins); i++ { if targetPoolAssetCoins[i].Denom != poolAssetCoins[i].Denom { - return txf, nil, errors.New("initial pool weights and target pool weights should have same denom order") + return nil, errors.New("initial pool weights and target pool weights should have same denom order") } targetPoolAssets = append(targetPoolAssets, balancer.PoolAsset{ @@ -465,7 +323,7 @@ func NewBuildCreateBalancerPoolMsg(clientCtx client.Context, txf tx.Factory, fs if pool.SmoothWeightChangeParams.StartTime != "" { startTime, err := time.Parse(time.RFC3339, pool.SmoothWeightChangeParams.StartTime) if err != nil { - return txf, nil, fmt.Errorf("could not parse time: %w", err) + return nil, fmt.Errorf("could not parse time: %w", err) } smoothWeightParams.StartTime = startTime @@ -474,29 +332,29 @@ func NewBuildCreateBalancerPoolMsg(clientCtx client.Context, txf tx.Factory, fs msg.PoolParams.SmoothWeightChangeParams = &smoothWeightParams } - return txf, msg, nil + return msg, nil } // Apologies to whoever has to touch this next, this code is horrendous -func NewBuildCreateStableswapPoolMsg(clientCtx client.Context, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { +func NewBuildCreateStableswapPoolMsg(clientCtx client.Context, fs *flag.FlagSet) (sdk.Msg, error) { flags, err := parseCreateStableswapPoolFlags(fs) if err != nil { - return txf, nil, fmt.Errorf("failed to parse pool: %w", err) + return nil, fmt.Errorf("failed to parse pool: %w", err) } deposit, err := ParseCoinsNoSort(flags.InitialDeposit) if err != nil { - return txf, nil, err + return nil, err } swapFee, err := sdk.NewDecFromStr(flags.SwapFee) if err != nil { - return txf, nil, err + return nil, err } exitFee, err := sdk.NewDecFromStr(flags.ExitFee) if err != nil { - return txf, nil, err + return nil, err } poolParams := &stableswap.PoolParams{ @@ -511,105 +369,99 @@ func NewBuildCreateStableswapPoolMsg(clientCtx client.Context, txf tx.Factory, f for _, i := range ints { u, err := strconv.ParseUint(i, 10, 64) if err != nil { - return txf, nil, err + return nil, err } scalingFactors = append(scalingFactors, u) } if len(scalingFactors) != len(deposit) { - return txf, nil, fmt.Errorf("number of scaling factors doesn't match number of assets") + return nil, fmt.Errorf("number of scaling factors doesn't match number of assets") } } - msg := &stableswap.MsgCreateStableswapPool{ + return &stableswap.MsgCreateStableswapPool{ Sender: clientCtx.GetFromAddress().String(), PoolParams: poolParams, InitialPoolLiquidity: deposit, ScalingFactors: scalingFactors, ScalingFactorController: flags.ScalingFactorController, FuturePoolGovernor: flags.FutureGovernor, - } - - return txf, msg, nil + }, nil } -func NewBuildJoinPoolMsg(clientCtx client.Context, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { +func NewBuildJoinPoolMsg(clientCtx client.Context, _args []string, fs *flag.FlagSet) (sdk.Msg, error) { poolId, err := fs.GetUint64(FlagPoolId) if err != nil { - return txf, nil, err + return nil, err } shareAmountOutStr, err := fs.GetString(FlagShareAmountOut) if err != nil { - return txf, nil, err + return nil, err } shareAmountOut, ok := sdk.NewIntFromString(shareAmountOutStr) if !ok { - return txf, nil, fmt.Errorf("invalid share amount out") + return nil, fmt.Errorf("invalid share amount out") } maxAmountsInStrs, err := fs.GetStringArray(FlagMaxAmountsIn) if err != nil { - return txf, nil, err + return nil, err } maxAmountsIn := sdk.Coins{} for i := 0; i < len(maxAmountsInStrs); i++ { parsed, err := sdk.ParseCoinsNormalized(maxAmountsInStrs[i]) if err != nil { - return txf, nil, err + return nil, err } maxAmountsIn = maxAmountsIn.Add(parsed...) } - msg := &types.MsgJoinPool{ + return &types.MsgJoinPool{ Sender: clientCtx.GetFromAddress().String(), PoolId: poolId, ShareOutAmount: shareAmountOut, TokenInMaxs: maxAmountsIn, - } - - return txf, msg, nil + }, nil } -func NewBuildExitPoolMsg(clientCtx client.Context, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { +func NewBuildExitPoolMsg(clientCtx client.Context, _args []string, fs *flag.FlagSet) (sdk.Msg, error) { poolId, err := fs.GetUint64(FlagPoolId) if err != nil { - return txf, nil, err + return nil, err } shareAmountInStr, err := fs.GetString(FlagShareAmountIn) if err != nil { - return txf, nil, err + return nil, err } shareAmountIn, ok := sdk.NewIntFromString(shareAmountInStr) if !ok { - return txf, nil, fmt.Errorf("invalid share amount in") + return nil, fmt.Errorf("invalid share amount in") } minAmountsOutStrs, err := fs.GetStringArray(FlagMinAmountsOut) if err != nil { - return txf, nil, err + return nil, err } minAmountsOut := sdk.Coins{} for i := 0; i < len(minAmountsOutStrs); i++ { parsed, err := sdk.ParseCoinsNormalized(minAmountsOutStrs[i]) if err != nil { - return txf, nil, err + return nil, err } minAmountsOut = minAmountsOut.Add(parsed...) } - msg := &types.MsgExitPool{ + return &types.MsgExitPool{ Sender: clientCtx.GetFromAddress().String(), PoolId: poolId, ShareInAmount: shareAmountIn, TokenOutMins: minAmountsOut, - } - - return txf, msg, nil + }, nil } func swapAmountInRoutes(fs *flag.FlagSet) ([]types.SwapAmountInRoute, error) { @@ -674,170 +526,63 @@ func swapAmountOutRoutes(fs *flag.FlagSet) ([]types.SwapAmountOutRoute, error) { return routes, nil } -func NewBuildSwapExactAmountInMsg(clientCtx client.Context, tokenInStr, tokenOutMinAmtStr string, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { +func NewBuildSwapExactAmountInMsg(clientCtx client.Context, args []string, fs *flag.FlagSet) (sdk.Msg, error) { + tokenInStr, tokenOutMinAmtStr := args[0], args[1] routes, err := swapAmountInRoutes(fs) if err != nil { - return txf, nil, err + return nil, err } tokenIn, err := sdk.ParseCoinNormalized(tokenInStr) if err != nil { - return txf, nil, err + return nil, err } tokenOutMinAmt, ok := sdk.NewIntFromString(tokenOutMinAmtStr) if !ok { - return txf, nil, fmt.Errorf("invalid token out min amount, %s", tokenOutMinAmtStr) + return nil, fmt.Errorf("invalid token out min amount, %s", tokenOutMinAmtStr) } - msg := &types.MsgSwapExactAmountIn{ + return &types.MsgSwapExactAmountIn{ Sender: clientCtx.GetFromAddress().String(), Routes: routes, TokenIn: tokenIn, TokenOutMinAmount: tokenOutMinAmt, - } - - return txf, msg, nil + }, nil } -func NewBuildSwapExactAmountOutMsg(clientCtx client.Context, tokenOutStr, tokenInMaxAmountStr string, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { +func NewBuildSwapExactAmountOutMsg(clientCtx client.Context, args []string, fs *flag.FlagSet) (sdk.Msg, error) { + tokenOutStr, tokenInMaxAmountStr := args[0], args[1] routes, err := swapAmountOutRoutes(fs) if err != nil { - return txf, nil, err + return nil, err } tokenOut, err := sdk.ParseCoinNormalized(tokenOutStr) if err != nil { - return txf, nil, err + return nil, err } tokenInMaxAmount, ok := sdk.NewIntFromString(tokenInMaxAmountStr) if !ok { - return txf, nil, errors.New("invalid token in max amount") + return nil, errors.New("invalid token in max amount") } - msg := &types.MsgSwapExactAmountOut{ + return &types.MsgSwapExactAmountOut{ Sender: clientCtx.GetFromAddress().String(), Routes: routes, TokenInMaxAmount: tokenInMaxAmount, TokenOut: tokenOut, - } - - return txf, msg, nil -} - -func NewBuildJoinSwapExternAmountInMsg(clientCtx client.Context, tokenInStr, shareOutMinAmountStr string, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { - poolID, err := fs.GetUint64(FlagPoolId) - if err != nil { - return txf, nil, err - } - - tokenIn, err := sdk.ParseCoinNormalized(tokenInStr) - if err != nil { - return txf, nil, err - } - - shareOutMinAmount, ok := sdk.NewIntFromString(shareOutMinAmountStr) - if !ok { - return txf, nil, errors.New("invalid share out min amount") - } - msg := &types.MsgJoinSwapExternAmountIn{ - Sender: clientCtx.GetFromAddress().String(), - PoolId: poolID, - TokenIn: tokenIn, - ShareOutMinAmount: shareOutMinAmount, - } - - return txf, msg, nil -} - -func NewBuildJoinSwapShareAmountOutMsg(clientCtx client.Context, tokenInDenom, tokenInMaxAmtStr, shareOutAmtStr string, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { - poolID, err := fs.GetUint64(FlagPoolId) - if err != nil { - return txf, nil, err - } - - tokenInMaxAmt, ok := sdk.NewIntFromString(tokenInMaxAmtStr) - if !ok { - return txf, nil, errors.New("token in max amount") - } - - shareOutAmt, ok := sdk.NewIntFromString(shareOutAmtStr) - if !ok { - return txf, nil, errors.New("share out amount") - } - - msg := &types.MsgJoinSwapShareAmountOut{ - Sender: clientCtx.GetFromAddress().String(), - PoolId: poolID, - TokenInDenom: tokenInDenom, - TokenInMaxAmount: tokenInMaxAmt, - ShareOutAmount: shareOutAmt, - } - - return txf, msg, nil -} - -func NewBuildExitSwapExternAmountOutMsg(clientCtx client.Context, tokenOutStr, shareInMaxAmtStr string, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { - poolID, err := fs.GetUint64(FlagPoolId) - if err != nil { - return txf, nil, err - } - - tokenOut, err := sdk.ParseCoinNormalized(tokenOutStr) - if err != nil { - return txf, nil, errors.New("token out") - } - - shareInMaxAmt, ok := sdk.NewIntFromString(shareInMaxAmtStr) - if !ok { - return txf, nil, errors.New("share in max amount") - } - - msg := &types.MsgExitSwapExternAmountOut{ - Sender: clientCtx.GetFromAddress().String(), - PoolId: poolID, - TokenOut: tokenOut, - ShareInMaxAmount: shareInMaxAmt, - } - - return txf, msg, nil + }, nil } -func NewBuildExitSwapShareAmountInMsg(clientCtx client.Context, tokenOutDenom, shareInAmtStr, tokenOutMinAmountStr string, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { +func NewStableSwapAdjustScalingFactorsMsg(clientCtx client.Context, _args []string, fs *flag.FlagSet) (sdk.Msg, error) { poolID, err := fs.GetUint64(FlagPoolId) if err != nil { - return txf, nil, err - } - - shareInAmt, ok := sdk.NewIntFromString(shareInAmtStr) - if !ok { - return txf, nil, errors.New("share in amount") - } - - tokenOutMinAmount, ok := sdk.NewIntFromString(tokenOutMinAmountStr) - if !ok { - return txf, nil, errors.New("token out min amount") - } - - msg := &types.MsgExitSwapShareAmountIn{ - Sender: clientCtx.GetFromAddress().String(), - PoolId: poolID, - TokenOutDenom: tokenOutDenom, - ShareInAmount: shareInAmt, - TokenOutMinAmount: tokenOutMinAmount, - } - - return txf, msg, nil -} - -func NewStableSwapAdjustScalingFactorsMsg(clientCtx client.Context, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { - poolID, err := fs.GetUint64(FlagPoolId) - if err != nil { - return txf, nil, err + return nil, err } scalingFactorsStr, err := fs.GetString(FlagScalingFactors) if err != nil { - return txf, nil, err + return nil, err } scalingFactorsStrSlice := strings.Split(scalingFactorsStr, ",") @@ -846,7 +591,7 @@ func NewStableSwapAdjustScalingFactorsMsg(clientCtx client.Context, txf tx.Facto for i, scalingFactorStr := range scalingFactorsStrSlice { scalingFactor, err := strconv.ParseUint(scalingFactorStr, 10, 64) if err != nil { - return txf, nil, err + return nil, err } scalingFactors[i] = scalingFactor } @@ -857,7 +602,7 @@ func NewStableSwapAdjustScalingFactorsMsg(clientCtx client.Context, txf tx.Facto ScalingFactors: scalingFactors, } - return txf, msg, nil + return msg, nil } // ParseCoinsNoSort parses coins from coinsStr but does not sort them. diff --git a/x/ibc-rate-limit/client/cli/query.go b/x/ibc-rate-limit/client/cli/query.go index db4ee8e2d96..d54f647a5cd 100644 --- a/x/ibc-rate-limit/client/cli/query.go +++ b/x/ibc-rate-limit/client/cli/query.go @@ -1,68 +1,20 @@ package cli import ( - "fmt" - "strings" - "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/version" - + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/ibc-rate-limit/types" ) // GetQueryCmd returns the cli query commands for this module. func GetQueryCmd() *cobra.Command { - // Group lockup queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } + cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand( - GetCmdParams(), + osmocli.GetParams[*types.QueryParamsRequest]( + types.ModuleName, types.NewQueryClient), ) return cmd } - -// GetCmdParams returns module params. -func GetCmdParams() *cobra.Command { - cmd := &cobra.Command{ - Use: "params", - Short: "Query module params", - Long: strings.TrimSpace( - fmt.Sprintf(`Query module params. - -Example: -$ %s query lockup params -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} diff --git a/x/incentives/client/cli/query.go b/x/incentives/client/cli/query.go index 2086c80e2f0..5f67881aac6 100644 --- a/x/incentives/client/cli/query.go +++ b/x/incentives/client/cli/query.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/cobra" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/incentives/types" lockuptypes "github.com/osmosis-labs/osmosis/v13/x/lockup/types" @@ -19,13 +20,7 @@ import ( // GetQueryCmd returns the query commands for this module. func GetQueryCmd() *cobra.Command { // group incentives queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } + cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand( GetCmdGauges(), @@ -43,278 +38,73 @@ func GetQueryCmd() *cobra.Command { // GetCmdGauges returns all available gauges. func GetCmdGauges() *cobra.Command { - cmd := &cobra.Command{ - Use: "gauges", - Short: "Query available gauges", - Long: strings.TrimSpace( - fmt.Sprintf(`Query available gauges. - -Example: -$ %s query incentives gauges -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - res, err := queryClient.Gauges(cmd.Context(), &types.GaugesRequest{ - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "incentives") - - return cmd + return osmocli.SimpleQueryCmd[*types.GaugesRequest]( + "gauges", + "Query available gauges", + `{{.Short}}`, + types.ModuleName, types.NewQueryClient, + ) } // GetCmdToDistributeCoins returns coins that are going to be distributed. func GetCmdToDistributeCoins() *cobra.Command { - cmd := &cobra.Command{ - Use: "to-distribute-coins", - Short: "Query coins that is going to be distributed", - Long: strings.TrimSpace( - fmt.Sprintf(`Query coins that is going to be distributed. - -Example: -$ %s query incentives to-distribute-coins -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.ModuleToDistributeCoins(cmd.Context(), &types.ModuleToDistributeCoinsRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.ModuleToDistributeCoinsRequest]( + "to-distribute-coins", + "Query coins that is going to be distributed", + `{{.Short}}`, + types.ModuleName, types.NewQueryClient, + ) } // GetCmdGaugeByID returns a gauge by ID. func GetCmdGaugeByID() *cobra.Command { - cmd := &cobra.Command{ - Use: "gauge-by-id [id]", - Short: "Query gauge by id.", - Long: strings.TrimSpace( - fmt.Sprintf(`Query gauge by id. - -Example: -$ %s query incentives gauge-by-id 1 -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - id, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - - res, err := queryClient.GaugeByID(cmd.Context(), &types.GaugeByIDRequest{Id: id}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.GaugeByIDRequest]( + "gauge-by-id [id]", + "Query gauge by id.", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} gauge-by-id 1 +`, types.ModuleName, types.NewQueryClient) } // GetCmdActiveGauges returns active gauges. func GetCmdActiveGauges() *cobra.Command { - cmd := &cobra.Command{ - Use: "active-gauges", - Short: "Query active gauges", - Long: strings.TrimSpace( - fmt.Sprintf(`Query active gauges. - -Example: -$ %s query incentives active-gauges -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - res, err := queryClient.ActiveGauges(cmd.Context(), &types.ActiveGaugesRequest{Pagination: pageReq}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "incentives") - - return cmd + return osmocli.SimpleQueryCmd[*types.ActiveGaugesRequest]( + "active-gauges", + "Query active gauges", + `{{.Short}}`, + types.ModuleName, types.NewQueryClient, + ) } // GetCmdActiveGaugesPerDenom returns active gauges for a specified denom. func GetCmdActiveGaugesPerDenom() *cobra.Command { - cmd := &cobra.Command{ - Use: "active-gauges-per-denom [denom]", - Short: "Query active gauges per denom", - Long: strings.TrimSpace( - fmt.Sprintf(`Query active gauges. - -Example: -$ %s query incentives active-gauges-per-denom [denom] -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - res, err := queryClient.ActiveGaugesPerDenom(cmd.Context(), &types.ActiveGaugesPerDenomRequest{Denom: args[0], Pagination: pageReq}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "incentives") - - return cmd + return osmocli.SimpleQueryCmd[*types.ActiveGaugesPerDenomRequest]( + "active-gauges-per-denom [denom]", + "Query active gauges per denom", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} active-gauges-per-denom gamm/pool/1`, + types.ModuleName, types.NewQueryClient, + ) } // GetCmdUpcomingGauges returns scheduled gauges. func GetCmdUpcomingGauges() *cobra.Command { - cmd := &cobra.Command{ - Use: "upcoming-gauges", - Short: "Query scheduled gauges", - Long: strings.TrimSpace( - fmt.Sprintf(`Query scheduled gauges. - -Example: -$ %s query incentives upcoming-gauges -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - res, err := queryClient.UpcomingGauges(cmd.Context(), &types.UpcomingGaugesRequest{Pagination: pageReq}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "incentives") - - return cmd + return osmocli.SimpleQueryCmd[*types.UpcomingGaugesRequest]( + "upcoming-gauges", + "Query upcoming gauges", + `{{.Short}}`, + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdUpcomingGaugesPerDenom returns active gauges for specified denom. +// GetCmdUpcomingGaugesPerDenom returns scheduled gauges for specified denom.. func GetCmdUpcomingGaugesPerDenom() *cobra.Command { - cmd := &cobra.Command{ - Use: "upcoming-gauges-per-denom [denom]", - Short: "Query scheduled gauges per denom", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - res, err := queryClient.UpcomingGaugesPerDenom(cmd.Context(), &types.UpcomingGaugesPerDenomRequest{Denom: args[0], Pagination: pageReq}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "incentives") - - return cmd + return osmocli.SimpleQueryCmd[*types.UpcomingGaugesPerDenomRequest]( + "upcoming-gauges-per-denom [denom]", + "Query scheduled gauges per denom", + `{{.Short}}`, + types.ModuleName, types.NewQueryClient, + ) } // GetCmdRewardsEst returns rewards estimation. diff --git a/x/incentives/client/cli/tx.go b/x/incentives/client/cli/tx.go index 21e969aa08f..a7431a59e81 100644 --- a/x/incentives/client/cli/tx.go +++ b/x/incentives/client/cli/tx.go @@ -2,12 +2,12 @@ package cli import ( "errors" - "fmt" "strconv" "time" "github.com/spf13/cobra" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/incentives/types" lockuptypes "github.com/osmosis-labs/osmosis/v13/x/lockup/types" @@ -19,14 +19,7 @@ import ( // GetTxCmd returns the transaction commands for this module. func GetTxCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - + cmd := osmocli.TxIndexCmd(types.ModuleName) cmd.AddCommand( NewCreateGaugeCmd(), NewAddToGaugeCmd(), @@ -114,41 +107,9 @@ func NewCreateGaugeCmd() *cobra.Command { return cmd } -// NewAddToGaugeCmd broadcasts a AddToGauge message. func NewAddToGaugeCmd() *cobra.Command { - cmd := &cobra.Command{ + return osmocli.BuildTxCli[*types.MsgAddToGauge](&osmocli.TxCliDesc{ Use: "add-to-gauge [gauge_id] [rewards] [flags]", Short: "add coins to gauge to distribute more rewards to users", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - gaugeId, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - - rewards, err := sdk.ParseCoinsNormalized(args[1]) - if err != nil { - return err - } - - msg := types.NewMsgAddToGauge( - clientCtx.GetFromAddress(), - gaugeId, - rewards, - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - cmd.Flags().AddFlagSet(FlagSetCreateGauge()) - flags.AddTxFlagsToCmd(cmd) - return cmd + }) } diff --git a/x/lockup/client/cli/cli_test.go b/x/lockup/client/cli/cli_test.go index 62fad3fec0b..ff4f41ba781 100644 --- a/x/lockup/client/cli/cli_test.go +++ b/x/lockup/client/cli/cli_test.go @@ -189,7 +189,7 @@ func (s *IntegrationTestSuite) TestBeginUnlockingCmd() { tc := tc s.Run(tc.name, func() { - cmd := cli.NewBeginUnlockingCmd() + cmd := cli.NewBeginUnlockingAllCmd() clientCtx := val.ClientCtx out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) @@ -735,38 +735,6 @@ func (s IntegrationTestSuite) TestCmdAccountLockedLongerDurationDenom() { } } -// TestGetCmdParams tests module params CLI query commands -func (s IntegrationTestSuite) TestGetCmdParams() { - val := s.network.Validators[0] - - testCases := []struct { - name string - args []string - }{ - { - "query module params", - []string{ - fmt.Sprintf("--%s=json", tmcli.OutputFlag), - }, - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - cmd := cli.GetCmdParams() - clientCtx := val.ClientCtx - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - s.Require().NoError(err) - - var result types.QueryParamsResponse - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)) - }) - } -} - func TestIntegrationTestSuite(t *testing.T) { suite.Run(t, new(IntegrationTestSuite)) } diff --git a/x/lockup/client/cli/query.go b/x/lockup/client/cli/query.go index be8f3fb0fda..23ff70c8539 100644 --- a/x/lockup/client/cli/query.go +++ b/x/lockup/client/cli/query.go @@ -16,19 +16,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/lockup/types" ) // GetQueryCmd returns the cli query commands for this module. func GetQueryCmd() *cobra.Command { - // Group lockup queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } + cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand( GetCmdModuleBalance(), @@ -48,7 +42,8 @@ func GetQueryCmd() *cobra.Command { GetCmdOutputLocksJson(), GetCmdSyntheticLockupsByLockupID(), GetCmdAccountLockedDuration(), - GetCmdParams(), + osmocli.GetParams[*types.QueryParamsRequest]( + types.ModuleName, types.NewQueryClient), ) return cmd @@ -58,78 +53,23 @@ func GetQueryCmd() *cobra.Command { // Lockup module is where coins of locks are held. // This includes locked balance and unlocked balance of the module. func GetCmdModuleBalance() *cobra.Command { - cmd := &cobra.Command{ - Use: "module-balance", - Short: "Query module balance", - Long: strings.TrimSpace( - fmt.Sprintf(`Query module balance. - -Example: -$ %s query lockup module-balance -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.ModuleBalance(cmd.Context(), &types.ModuleBalanceRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.ModuleBalanceRequest]( + "module-balance", + "Query module balance", + `{{.Short}}`, types.ModuleName, types.NewQueryClient) } // GetCmdModuleLockedAmount returns locked balance of the module, // which are all the tokens not unlocking + tokens that are not finished unlocking. func GetCmdModuleLockedAmount() *cobra.Command { - cmd := &cobra.Command{ - Use: "module-locked-amount", - Short: "Query module locked amount", - Long: strings.TrimSpace( - fmt.Sprintf(`Query module locked amount. - -Example: -$ %s query lockup module-locked-amount -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.ModuleLockedAmount(cmd.Context(), &types.ModuleLockedAmountRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.ModuleLockedAmountRequest]( + "module-locked-amount", + "Query locked amount", + `{{.Short}}`, types.ModuleName, types.NewQueryClient) } // GetCmdAccountUnlockableCoins returns unlockable coins which has finsihed unlocking. +// TODO: DELETE THIS + Actual query in subsequent PR func GetCmdAccountUnlockableCoins() *cobra.Command { cmd := &cobra.Command{ Use: "account-unlockable-coins
", @@ -168,76 +108,22 @@ $ %s query lockup account-unlockable-coins
// GetCmdAccountUnlockingCoins returns unlocking coins of a specific account. func GetCmdAccountUnlockingCoins() *cobra.Command { - cmd := &cobra.Command{ - Use: "account-unlocking-coins
", - Short: "Query account's unlocking coins", - Long: strings.TrimSpace( - fmt.Sprintf(`Query account's unlocking coins. - -Example: -$ %s query lockup account-unlocking-coins
-`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - 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.AccountUnlockingCoins(cmd.Context(), &types.AccountUnlockingCoinsRequest{Owner: args[0]}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.AccountUnlockingCoinsRequest]( + "account-unlocking-coins
", + "Query account's unlocking coins", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} account-unlocking-coins
+`, types.ModuleName, types.NewQueryClient) } -// GetCmdAccountLockedCoins returns locked coins that can't be withdrawn of a specific account. +// GetCmdAccountLockedCoins returns locked coins that that are still in a locked state from the specified account. func GetCmdAccountLockedCoins() *cobra.Command { - cmd := &cobra.Command{ - Use: "account-locked-coins
", - Short: "Query account's locked coins", - Long: strings.TrimSpace( - fmt.Sprintf(`Query account's locked coins. - -Example: -$ %s query lockup account-locked-coins
-`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - 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.AccountLockedCoins(cmd.Context(), &types.AccountLockedCoinsRequest{Owner: args[0]}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.AccountLockedCoinsRequest]( + "account-locked-coins
", + "Query account's locked coins", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} account-locked-coins
+`, types.ModuleName, types.NewQueryClient) } // GetCmdAccountLockedPastTime returns locks of an account with unlock time beyond timestamp. @@ -418,303 +304,72 @@ $ %s query lockup account-locked-pastime-denom
// GetCmdLockedByID returns lock by id. func GetCmdLockedByID() *cobra.Command { - cmd := &cobra.Command{ + q := osmocli.QueryDescriptor{ Use: "lock-by-id ", Short: "Query account's lock record by id", - Long: strings.TrimSpace( - fmt.Sprintf(`Query account's lock record by id. - -Example: -$ %s query lockup lock-by-id -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - id, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - panic(err) - } - - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.LockedByID(cmd.Context(), &types.LockedRequest{LockId: id}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, + Long: `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} lock-by-id 1`, + QueryFnName: "LockedByID", } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + q.Long = osmocli.FormatLongDesc(q.Long, osmocli.NewLongMetadata(types.ModuleName).WithShort(q.Short)) + return osmocli.SimpleQueryFromDescriptor[*types.LockedRequest](q, types.NewQueryClient) } // GetCmdSyntheticLockupsByLockupID returns synthetic lockups by lockup id. func GetCmdSyntheticLockupsByLockupID() *cobra.Command { - cmd := &cobra.Command{ - Use: "synthetic-lockups-by-lock-id ", - Short: "Query synthetic lockups by lockup id", - Long: strings.TrimSpace( - fmt.Sprintf(`Query synthetic lockups by lockup id. - -Example: -$ %s query lockup synthetic-lockups-by-lock-id -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - id, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - panic(err) - } - - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.SyntheticLockupsByLockupID(cmd.Context(), &types.SyntheticLockupsByLockupIDRequest{LockId: id}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.SyntheticLockupsByLockupIDRequest]( + "synthetic-lockups-by-lock-id ", + "Query synthetic lockups by lockup id", + `{{.Short}}`, types.ModuleName, types.NewQueryClient) } // GetCmdAccountLockedLongerDuration returns account locked records with longer duration. func GetCmdAccountLockedLongerDuration() *cobra.Command { - cmd := &cobra.Command{ - Use: "account-locked-longer-duration
", - Short: "Query account locked records with longer duration", - Long: strings.TrimSpace( - fmt.Sprintf(`Query account locked records with longer duration. - -Example: -$ %s query lockup account-locked-longer-duration
-`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - duration, err := time.ParseDuration(args[1]) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.AccountLockedLongerDuration(cmd.Context(), &types.AccountLockedLongerDurationRequest{Owner: args[0], Duration: duration}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.AccountLockedLongerDurationRequest]( + "account-locked-longer-duration
", + "Query account locked records with longer duration", + `{{.Short}}`, types.ModuleName, types.NewQueryClient) } -// GetCmdAccountLockedDuration returns account locked records with a specific duration. +// GetCmdAccountLockedLongerDuration returns account locked records with longer duration. func GetCmdAccountLockedDuration() *cobra.Command { - cmd := &cobra.Command{ - Use: "account-locked-duration
", - Short: "Query account locked records with a specific duration", - Example: strings.TrimSpace( - fmt.Sprintf(`Query account locked records with a specific duration. -Example: -$ %s query lockup account-locked-duration osmo1yl6hdjhmkf37639730gffanpzndzdpmhxy9ep3 604800s -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - duration, err := time.ParseDuration(args[1]) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.AccountLockedDuration(cmd.Context(), &types.AccountLockedDurationRequest{Owner: args[0], Duration: duration}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.AccountLockedDurationRequest]( + "account-locked-duration
", + "Query account locked records with a specific duration", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} account-locked-duration osmo1yl6hdjhmkf37639730gffanpzndzdpmhxy9ep3 604800s`, types.ModuleName, types.NewQueryClient) } // GetCmdAccountLockedLongerDurationNotUnlockingOnly returns account locked records with longer duration from unlocking only queue. func GetCmdAccountLockedLongerDurationNotUnlockingOnly() *cobra.Command { - cmd := &cobra.Command{ - Use: "account-locked-longer-duration-not-unlocking
", - Short: "Query account locked records with longer duration from unlocking only queue", - Long: strings.TrimSpace( - fmt.Sprintf(`Query account locked records with longer duration from unlocking only queue. - -Example: -$ %s query lockup account-locked-longer-duration-not-unlocking
-`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - duration, err := time.ParseDuration(args[1]) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.AccountLockedLongerDurationNotUnlockingOnly(cmd.Context(), &types.AccountLockedLongerDurationNotUnlockingOnlyRequest{Owner: args[0], Duration: duration}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.AccountLockedLongerDurationNotUnlockingOnlyRequest]( + "account-locked-longer-duration-not-unlocking
", + "Query account locked records with longer duration from unlocking only queue", + `{{.Short}}`, types.ModuleName, types.NewQueryClient) } // GetCmdAccountLockedLongerDurationDenom returns account's locks for a specific denom // with longer duration than the given duration. func GetCmdAccountLockedLongerDurationDenom() *cobra.Command { - cmd := &cobra.Command{ - Use: "account-locked-longer-duration-denom
", - Short: "Query locked records for a denom with longer duration", - Long: strings.TrimSpace( - fmt.Sprintf(`Query account's locked records for a denom with longer duration. - -Example: -$ %s query lockup account-locked-pastime
-`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(3), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - duration, err := time.ParseDuration(args[1]) - if err != nil { - return err - } - - denom := args[2] - - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.AccountLockedLongerDurationDenom(cmd.Context(), &types.AccountLockedLongerDurationDenomRequest{Owner: args[0], Duration: duration, Denom: denom}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.AccountLockedLongerDurationDenomRequest]( + "account-locked-longer-duration-denom
", + "Query locked records for a denom with longer duration", + `{{.Short}}`, types.ModuleName, types.NewQueryClient) } -// GetCmdTotalBondedByDenom returns total amount of locked asset of a specific denom. func GetCmdTotalLockedByDenom() *cobra.Command { - cmd := &cobra.Command{ + cmd := osmocli.SimpleQueryFromDescriptor[*types.LockedDenomRequest](osmocli.QueryDescriptor{ Use: "total-locked-of-denom ", Short: "Query locked amount for a specific denom bigger then duration provided", - Long: strings.TrimSpace( - fmt.Sprintf(`Query locked records for a specific denom bigger then duration provided. - -Example: -$ %s query lockup total-locked-of-denom -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - durationStr, err := cmd.Flags().GetString(FlagMinDuration) - if err != nil { - return err - } - - duration, err := time.ParseDuration(durationStr) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.LockedDenom(cmd.Context(), &types.LockedDenomRequest{Denom: args[0], Duration: duration}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) + Long: osmocli.FormatLongDescDirect(`{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} total-locked-of-denom uosmo --min-duration=0s`, types.ModuleName), + CustomFlagOverrides: map[string]string{ + "duration": FlagMinDuration, }, - } + QueryFnName: "LockedDenom", + }, types.NewQueryClient) cmd.Flags().AddFlagSet(FlagSetMinDuration()) - flags.AddQueryFlagsToCmd(cmd) - return cmd } @@ -800,39 +455,3 @@ $ %s query lockup output-all-locks return cmd } - -// GetCmdParams returns module params. -func GetCmdParams() *cobra.Command { - cmd := &cobra.Command{ - Use: "params", - Short: "Query module params", - Long: strings.TrimSpace( - fmt.Sprintf(`Query module params. - -Example: -$ %s query lockup params -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} diff --git a/x/lockup/client/cli/tx.go b/x/lockup/client/cli/tx.go index 34b370dbcb7..5a3319876d2 100644 --- a/x/lockup/client/cli/tx.go +++ b/x/lockup/client/cli/tx.go @@ -1,33 +1,18 @@ package cli import ( - "fmt" - "strconv" - "time" - "github.com/spf13/cobra" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/lockup/types" - - "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" ) // GetTxCmd returns the transaction commands for this module. func GetTxCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - + cmd := osmocli.TxIndexCmd(types.ModuleName) cmd.AddCommand( NewLockTokensCmd(), - NewBeginUnlockingCmd(), + NewBeginUnlockingAllCmd(), NewBeginUnlockByIDCmd(), NewForceUnlockByIdCmd(), ) @@ -35,46 +20,16 @@ func GetTxCmd() *cobra.Command { return cmd } -// NewLockTokensCmd creates a new lock with the specified duration and tokens from the user's account. func NewLockTokensCmd() *cobra.Command { - cmd := &cobra.Command{ + cmd := osmocli.BuildTxCli[*types.MsgLockTokens](&osmocli.TxCliDesc{ Use: "lock-tokens [tokens]", Short: "lock tokens into lockup pool from user account", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - coins, err := sdk.ParseCoinsNormalized(args[0]) - if err != nil { - return err - } - - durationStr, err := cmd.Flags().GetString(FlagDuration) - if err != nil { - return err - } - - duration, err := time.ParseDuration(durationStr) - if err != nil { - return err - } - - msg := types.NewMsgLockTokens( - clientCtx.GetFromAddress(), - duration, - coins, - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + CustomFlagOverrides: map[string]string{ + "duration": FlagDuration, }, - } + }) cmd.Flags().AddFlagSet(FlagSetLockTokens()) - flags.AddTxFlagsToCmd(cmd) err := cmd.MarkFlagRequired(FlagDuration) if err != nil { panic(err) @@ -82,125 +37,39 @@ func NewLockTokensCmd() *cobra.Command { return cmd } -// NewBeginUnlockingCmd starts unlocking all unlockable locks from user's account. -func NewBeginUnlockingCmd() *cobra.Command { - cmd := &cobra.Command{ +// TODO: We should change the Use string to be unlock-all +func NewBeginUnlockingAllCmd() *cobra.Command { + return osmocli.BuildTxCli[*types.MsgBeginUnlockingAll](&osmocli.TxCliDesc{ Use: "begin-unlock-tokens", - Short: "begin unlock not unlocking tokens from lockup pool for an account", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - msg := types.NewMsgBeginUnlockingAll( - clientCtx.GetFromAddress(), - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd + Short: "begin unlock not unlocking tokens from lockup pool for sender", + }) } // NewBeginUnlockByIDCmd unlocks individual period lock by ID. func NewBeginUnlockByIDCmd() *cobra.Command { - cmd := &cobra.Command{ + cmd := osmocli.BuildTxCli[*types.MsgBeginUnlocking](&osmocli.TxCliDesc{ Use: "begin-unlock-by-id [id]", Short: "begin unlock individual period lock by ID", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - id, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - coins := sdk.Coins(nil) - amountStr, err := cmd.Flags().GetString(FlagAmount) - if err != nil { - return err - } - - if amountStr != "" { - coins, err = sdk.ParseCoinsNormalized(amountStr) - if err != nil { - return err - } - } - - msg := types.NewMsgBeginUnlocking( - clientCtx.GetFromAddress(), - uint64(id), - coins, - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + CustomFlagOverrides: map[string]string{ + "coins": FlagAmount, }, - } + }) cmd.Flags().AddFlagSet(FlagSetUnlockTokens()) - - flags.AddTxFlagsToCmd(cmd) return cmd } // NewForceUnlockByIdCmd force unlocks individual period lock by ID if proper permissions exist. func NewForceUnlockByIdCmd() *cobra.Command { - cmd := &cobra.Command{ + cmd := osmocli.BuildTxCli[*types.MsgBeginUnlocking](&osmocli.TxCliDesc{ Use: "force-unlock-by-id [id]", Short: "force unlocks individual period lock by ID", Long: "force unlocks individual period lock by ID. if no amount provided, entire lock is unlocked", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - id, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - coins := sdk.Coins(nil) - amountStr, err := cmd.Flags().GetString(FlagAmount) - if err != nil { - return err - } - - if amountStr != "" { - coins, err = sdk.ParseCoinsNormalized(amountStr) - if err != nil { - return err - } - } - - msg := types.NewMsgForceUnlock( - clientCtx.GetFromAddress(), - uint64(id), - coins, - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + CustomFlagOverrides: map[string]string{ + "coins": FlagAmount, }, - } + }) cmd.Flags().AddFlagSet(FlagSetUnlockTokens()) - - flags.AddTxFlagsToCmd(cmd) return cmd } diff --git a/x/lockup/client/testutil/test_helpers.go b/x/lockup/client/testutil/test_helpers.go index 2f9d59ef89f..90a3d0f3f7b 100644 --- a/x/lockup/client/testutil/test_helpers.go +++ b/x/lockup/client/testutil/test_helpers.go @@ -39,5 +39,5 @@ func MsgBeginUnlocking(clientCtx client.Context, owner fmt.Stringer, extraArgs . } args = append(args, commonArgs...) - return clitestutil.ExecTestCLICmd(clientCtx, lockupcli.NewBeginUnlockingCmd(), args) + return clitestutil.ExecTestCLICmd(clientCtx, lockupcli.NewBeginUnlockingAllCmd(), args) } diff --git a/x/mint/client/cli/query.go b/x/mint/client/cli/query.go index 7b917ee7177..d88ffe70be7 100644 --- a/x/mint/client/cli/query.go +++ b/x/mint/client/cli/query.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/mint/types" "github.com/cosmos/cosmos-sdk/client" @@ -14,20 +15,13 @@ import ( // GetQueryCmd returns the cli query commands for the minting module. func GetQueryCmd() *cobra.Command { - mintingQueryCmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Querying commands for the minting module", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - mintingQueryCmd.AddCommand( + cmd := osmocli.QueryIndexCmd(types.ModuleName) + cmd.AddCommand( GetCmdQueryParams(), GetCmdQueryEpochProvisions(), ) - return mintingQueryCmd + return cmd } // GetCmdQueryParams implements a command to return the current minting diff --git a/x/mint/client/cli/query_test.go b/x/mint/client/cli/query_test.go deleted file mode 100644 index 67292edd54b..00000000000 --- a/x/mint/client/cli/query_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package cli_test - -import ( - gocontext "context" - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/osmosis-labs/osmosis/v13/app/apptesting" - "github.com/osmosis-labs/osmosis/v13/x/mint/types" -) - -type QueryTestSuite struct { - apptesting.KeeperTestHelper - queryClient types.QueryClient -} - -func (s *QueryTestSuite) SetupSuite() { - s.Setup() - s.queryClient = types.NewQueryClient(s.QueryHelper) - - s.Commit() -} - -func (s *QueryTestSuite) TestQueriesNeverAlterState() { - testCases := []struct { - name string - query string - input interface{} - output interface{} - }{ - { - "Query epoch provisions", - "/osmosis.mint.v1beta1.Query/EpochProvisions", - &types.QueryEpochProvisionsRequest{}, - &types.QueryEpochProvisionsResponse{}, - }, - { - "Query params", - "/osmosis.mint.v1beta1.Query/Params", - &types.QueryParamsRequest{}, - &types.QueryParamsResponse{}, - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - s.SetupSuite() - err := s.QueryHelper.Invoke(gocontext.Background(), tc.query, tc.input, tc.output) - s.Require().NoError(err) - s.StateNotAltered() - }) - } -} - -func TestQueryTestSuite(t *testing.T) { - suite.Run(t, new(QueryTestSuite)) -} diff --git a/x/pool-incentives/client/cli/cli_test.go b/x/pool-incentives/client/cli/cli_test.go index 8695b7b91bf..d0333ba9d77 100644 --- a/x/pool-incentives/client/cli/cli_test.go +++ b/x/pool-incentives/client/cli/cli_test.go @@ -107,41 +107,6 @@ func (s *IntegrationTestSuite) TestGetCmdDistrInfo() { } } -// TestGetCmdParams tests module params CLI query commands -func (s *IntegrationTestSuite) TestGetCmdParams() { - val := s.network.Validators[0] - - testCases := []struct { - name string - expectErr bool - respType proto.Message - }{ - { - "query module params", - false, &types.QueryParamsResponse{}, - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - cmd := cli.GetCmdParams() - clientCtx := val.ClientCtx - - args := []string{} - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err, out.String()) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - } - }) - } -} - // TestGetCmdLockableDurations tests lockable duration CLI query commands func (s *IntegrationTestSuite) TestGetCmdLockableDurations() { val := s.network.Validators[0] diff --git a/x/pool-incentives/client/cli/query.go b/x/pool-incentives/client/cli/query.go index 6d19c6f9078..9d98156a0b0 100644 --- a/x/pool-incentives/client/cli/query.go +++ b/x/pool-incentives/client/cli/query.go @@ -1,34 +1,21 @@ package cli import ( - "fmt" - "strconv" - "strings" - "github.com/spf13/cobra" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/pool-incentives/types" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/version" ) // GetQueryCmd returns the cli query commands for this module. func GetQueryCmd() *cobra.Command { - // Group queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } + cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand( GetCmdGaugeIds(), GetCmdDistrInfo(), - GetCmdParams(), + osmocli.GetParams[*types.QueryParamsRequest]( + types.ModuleName, types.NewQueryClient), GetCmdLockableDurations(), GetCmdIncentivizedPools(), GetCmdExternalIncentiveGauges(), @@ -39,223 +26,52 @@ func GetQueryCmd() *cobra.Command { // GetCmdGaugeIds takes the pool id and returns the matching gauge ids and durations. func GetCmdGaugeIds() *cobra.Command { - cmd := &cobra.Command{ - Use: "gauge-ids [pool-id]", - Short: "Query the matching gauge ids and durations by pool id", - Long: strings.TrimSpace( - fmt.Sprintf(`Query the matching gauge ids and durations by pool id. - -Example: -$ %s query pool-incentives gauge-ids 1 -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - poolId, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - - res, err := queryClient.GaugeIds(cmd.Context(), &types.QueryGaugeIdsRequest{ - PoolId: poolId, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.QueryGaugeIdsRequest]( + "gauge-ids [pool-id]", + "Query the matching gauge ids and durations by pool id", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} gauge-ids 1 +`, types.ModuleName, types.NewQueryClient) } // GetCmdDistrInfo takes the pool id and returns the matching gauge ids and weights. func GetCmdDistrInfo() *cobra.Command { - cmd := &cobra.Command{ - Use: "distr-info", - Short: "Query distribution info", - Long: strings.TrimSpace( - fmt.Sprintf(`Query distribution info. - -Example: -$ %s query pool-incentives distr-info -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.DistrInfo(cmd.Context(), &types.QueryDistrInfoRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - -// GetCmdParams returns module params. -func GetCmdParams() *cobra.Command { - cmd := &cobra.Command{ - Use: "params", - Short: "Query module params", - Long: strings.TrimSpace( - fmt.Sprintf(`Query module params. - -Example: -$ %s query pool-incentives params -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.QueryDistrInfoRequest]( + "distr-info", + "Query distribution info", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} distr-info +`, types.ModuleName, types.NewQueryClient) } // GetCmdLockableDurations returns lockable durations. func GetCmdLockableDurations() *cobra.Command { - cmd := &cobra.Command{ - Use: "lockable-durations", - Short: "Query lockable durations", - Long: strings.TrimSpace( - fmt.Sprintf(`Query lockable durations. + return osmocli.SimpleQueryCmd[*types.QueryLockableDurationsRequest]( + "lockable-durations", + "Query lockable durations", + `Query distribution info. Example: -$ %s query pool-incentives lockable-durations -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.LockableDurations(cmd.Context(), &types.QueryLockableDurationsRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd +{{.CommandPrefix}} lockable-durations +`, types.ModuleName, types.NewQueryClient) } -// GetCmdIncentivizedPools returns incentivized pools. func GetCmdIncentivizedPools() *cobra.Command { - cmd := &cobra.Command{ - Use: "incentivized-pools", - Short: "Query incentivized pools", - Long: strings.TrimSpace( - fmt.Sprintf(`Query incentivized pools. + return osmocli.SimpleQueryCmd[*types.QueryIncentivizedPoolsRequest]( + "incentivized-pools", + "Query incentivized pools", + `Query incentivized pools. Example: -$ %s query pool-incentives incentivized-pools -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.IncentivizedPools(cmd.Context(), &types.QueryIncentivizedPoolsRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd +{{.CommandPrefix}} incentivized-pools +`, types.ModuleName, types.NewQueryClient) } -// GetCmdIncentivizedPools returns incentivized pools. func GetCmdExternalIncentiveGauges() *cobra.Command { - cmd := &cobra.Command{ - Use: "external-incentivized-gauges", - Short: "Query external incentivized gauges", - Long: strings.TrimSpace( - fmt.Sprintf(`Query incentivized gauges. - -Example: -$ %s query pool-incentives external-incentivized-gauges -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.ExternalIncentiveGauges(cmd.Context(), &types.QueryExternalIncentiveGaugesRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.QueryExternalIncentiveGaugesRequest]( + "external-incentivized-gauges", + "Query external incentivized gauges", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} external-incentivized-gauges +`, types.ModuleName, types.NewQueryClient) } diff --git a/x/superfluid/client/cli/query.go b/x/superfluid/client/cli/query.go index e4a0b69e338..ccec36ca883 100644 --- a/x/superfluid/client/cli/query.go +++ b/x/superfluid/client/cli/query.go @@ -1,29 +1,20 @@ package cli import ( - "fmt" - "strconv" "strings" "github.com/spf13/cobra" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/superfluid/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/version" ) // GetQueryCmd returns the cli query commands for this module. func GetQueryCmd() *cobra.Command { - // Group superfluid queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } + cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand( GetCmdQueryParams(), @@ -65,6 +56,7 @@ $ query superfluid params return err } + // NOTE: THIS IS NON-STANDARD, SO WE HAVE TO THINK ABOUT BREAKING IT return clientCtx.PrintProto(&res.Params) }, } @@ -74,333 +66,94 @@ $ query superfluid params return cmd } -// GetCmdAllSuperfluidAssets returns all superfluid enabled assets. func GetCmdAllSuperfluidAssets() *cobra.Command { - cmd := &cobra.Command{ - Use: "all-superfluid-assets", - Short: "Query all superfluid assets", - Long: strings.TrimSpace( - fmt.Sprintf(`Query all superfluid assets. - -Example: -$ %s query superfluid all-superfluid-assets -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.AllAssets(cmd.Context(), &types.AllAssetsRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.AllAssetsRequest]( + "all-superfluid-assets", + "Query all superfluid assets", "", + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdAssetMultiplier returns multiplier of an asset by denom. func GetCmdAssetMultiplier() *cobra.Command { - cmd := &cobra.Command{ - Use: "asset-multiplier [denom]", - Short: "Query asset multiplier by denom", - Long: strings.TrimSpace( - fmt.Sprintf(`Query asset multiplier by denom. - -Example: -$ %s query superfluid asset-multiplier gamm/pool/1 + return osmocli.SimpleQueryCmd[*types.AssetMultiplierRequest]( + "asset-multiplier [denom]", + "Query asset multiplier by denom", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} asset-multiplier gamm/pool/1 `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - 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.AssetMultiplier(cmd.Context(), &types.AssetMultiplierRequest{ - Denom: args[0], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdAllIntermediaryAccounts returns all superfluid intermediary accounts. func GetCmdAllIntermediaryAccounts() *cobra.Command { - cmd := &cobra.Command{ - Use: "all-intermediary-accounts", - Short: "Query all superfluid intermediary accounts", - Long: strings.TrimSpace( - fmt.Sprintf(`Query all superfluid intermediary accounts. - -Example: -$ %s query superfluid all-intermediary-accounts -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - res, err := queryClient.AllIntermediaryAccounts(cmd.Context(), &types.AllIntermediaryAccountsRequest{ - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "superfluid") - - return cmd + return osmocli.SimpleQueryCmd[*types.AllIntermediaryAccountsRequest]( + "all-intermediary-accounts", + "Query all superfluid intermediary accounts", + `{{.Short}}`, + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdConnectedIntermediaryAccount returns connected intermediary account. func GetCmdConnectedIntermediaryAccount() *cobra.Command { - cmd := &cobra.Command{ - Use: "connected-intermediary-account [lock_id]", - Short: "Query connected intermediary account", - Long: strings.TrimSpace( - fmt.Sprintf(`Query connected intermediary account. - -Example: -$ %s query superfluid connected-intermediary-account 1 + return osmocli.SimpleQueryCmd[*types.ConnectedIntermediaryAccountRequest]( + "connected-intermediary-account [lock_id]", + "Query connected intermediary account", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} connected-intermediary-account 1 `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := types.NewQueryClient(clientCtx) - - lockId, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - res, err := queryClient.ConnectedIntermediaryAccount(cmd.Context(), &types.ConnectedIntermediaryAccountRequest{ - LockId: uint64(lockId), - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } // GetCmdSuperfluidDelegationAmount returns the coins superfluid delegated for a // delegator, validator, denom. func GetCmdSuperfluidDelegationAmount() *cobra.Command { - cmd := &cobra.Command{ - Use: "superfluid-delegation-amount [delegator_address] [validator_address] [denom]", - Short: "Query coins superfluid delegated for a delegator, validator, denom", - Args: cobra.ExactArgs(3), - 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.SuperfluidDelegationAmount(cmd.Context(), &types.SuperfluidDelegationAmountRequest{ - DelegatorAddress: args[0], - ValidatorAddress: args[1], - Denom: args[2], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.SuperfluidDelegationAmountRequest]( + "superfluid-delegation-amount [delegator_address] [validator_address] [denom]", + "Query coins superfluid delegated for a delegator, validator, denom", "", + types.ModuleName, types.NewQueryClient, + ) } // GetCmdSuperfluidDelegationsByDelegator returns the coins superfluid delegated for the specified delegator. func GetCmdSuperfluidDelegationsByDelegator() *cobra.Command { - cmd := &cobra.Command{ - Use: "superfluid-delegation-by-delegator [delegator_address]", - Short: "Query coins superfluid delegated for the specified delegator", - Args: cobra.ExactArgs(1), - 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.SuperfluidDelegationsByDelegator(cmd.Context(), &types.SuperfluidDelegationsByDelegatorRequest{ - DelegatorAddress: args[0], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.SuperfluidDelegationAmountRequest]( + "superfluid-delegation-by-delegator [delegator_address]", + "Query coins superfluid delegated for the specified delegator", "", + types.ModuleName, types.NewQueryClient, + ) } // GetCmdSuperfluidUndelegationsByDelegator returns the coins superfluid undelegated for the specified delegator. func GetCmdSuperfluidUndelegationsByDelegator() *cobra.Command { - cmd := &cobra.Command{ - Use: "superfluid-undelegation-by-delegator [delegator_address]", - Short: "Query coins superfluid undelegated for the specified delegator", - Args: cobra.ExactArgs(1), - 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.SuperfluidUndelegationsByDelegator(cmd.Context(), &types.SuperfluidUndelegationsByDelegatorRequest{ - DelegatorAddress: args[0], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.SuperfluidUndelegationsByDelegatorRequest]( + "superfluid-undelegation-by-delegator [delegator_address]", + "Query coins superfluid undelegated for the specified delegator", "", + types.ModuleName, types.NewQueryClient, + ) } // GetCmdTotalSuperfluidDelegations returns total amount of base denom delegated via superfluid staking. func GetCmdTotalSuperfluidDelegations() *cobra.Command { - cmd := &cobra.Command{ - Use: "total-superfluid-delegations", - Short: "Query total amount of osmo delegated via superfluid staking", - Args: cobra.ExactArgs(0), - 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.TotalSuperfluidDelegations(cmd.Context(), &types.TotalSuperfluidDelegationsRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.TotalSuperfluidDelegationsRequest]( + "total-superfluid-delegations", + "Query total amount of osmo delegated via superfluid staking", "", + types.ModuleName, types.NewQueryClient, + ) } func GetCmdTotalDelegationByDelegator() *cobra.Command { - cmd := &cobra.Command{ - Use: "total-delegation-by-delegator [delegator_address]", - Short: "Query both superfluid delegation and normal delegation", - Args: cobra.ExactArgs(1), - 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.TotalDelegationByDelegator(cmd.Context(), &types.QueryTotalDelegationByDelegatorRequest{ - DelegatorAddress: args[0], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.QueryTotalDelegationByDelegatorRequest]( + "total-delegation-by-delegator [delegator_address]", + "Query both superfluid delegation and normal delegation", "", + types.ModuleName, types.NewQueryClient, + ) } func GetCmdUnpoolWhitelist() *cobra.Command { - cmd := &cobra.Command{ - Use: "unpool-whitelist", - Short: "Query whitelisted pool ids to unpool.", - 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.UnpoolWhitelist(cmd.Context(), &types.QueryUnpoolWhitelistRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.QueryUnpoolWhitelistRequest]( + "unpool-whitelist", + "Query whitelisted pool ids to unpool", "", + types.ModuleName, types.NewQueryClient, + ) } diff --git a/x/superfluid/client/cli/tx.go b/x/superfluid/client/cli/tx.go index 991d66857e4..97256e63862 100644 --- a/x/superfluid/client/cli/tx.go +++ b/x/superfluid/client/cli/tx.go @@ -1,7 +1,6 @@ package cli import ( - "fmt" "strconv" "strings" @@ -9,6 +8,7 @@ import ( flag "github.com/spf13/pflag" "github.com/osmosis-labs/osmosis/v13/osmoutils" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/superfluid/types" "github.com/cosmos/cosmos-sdk/client" @@ -21,14 +21,7 @@ import ( // GetTxCmd returns the transaction commands for this module. func GetTxCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - + cmd := osmocli.TxIndexCmd(types.ModuleName) cmd.AddCommand( NewSuperfluidDelegateCmd(), NewSuperfluidUndelegateCmd(), @@ -79,108 +72,20 @@ func NewSuperfluidDelegateCmd() *cobra.Command { return cmd } -// NewSuperfluidUndelegateCmd broadcast MsgSuperfluidUndelegate. func NewSuperfluidUndelegateCmd() *cobra.Command { - cmd := &cobra.Command{ + return osmocli.BuildTxCli[*types.MsgSuperfluidUndelegate](&osmocli.TxCliDesc{ Use: "undelegate [lock_id] [flags]", Short: "superfluid undelegate a lock from a validator", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - lockId, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - msg := types.NewMsgSuperfluidUndelegate( - clientCtx.GetFromAddress(), - uint64(lockId), - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd + }) } -// NewSuperfluidUnbondLock broadcast MsgSuperfluidUndelegate and. func NewSuperfluidUnbondLockCmd() *cobra.Command { - cmd := &cobra.Command{ + return osmocli.BuildTxCli[*types.MsgSuperfluidUnbondLock](&osmocli.TxCliDesc{ Use: "unbond-lock [lock_id] [flags]", Short: "unbond lock that has been superfluid staked", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - lockId, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - msg := types.NewMsgSuperfluidUnbondLock( - clientCtx.GetFromAddress(), - uint64(lockId), - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd + }) } -// NewSuperfluidRedelegateCmd broadcast MsgSuperfluidRedelegate -// func NewSuperfluidRedelegateCmd() *cobra.Command { -// cmd := &cobra.Command{ -// Use: "redelegate [lock_id] [val_addr] [flags]", -// Short: "superfluid redelegate a lock to a new validator", -// Args: cobra.ExactArgs(2), -// RunE: func(cmd *cobra.Command, args []string) error { -// clientCtx, err := client.GetClientTxContext(cmd) -// if err != nil { -// return err -// } - -// txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - -// lockId, err := strconv.Atoi(args[0]) -// if err != nil { -// return err -// } - -// valAddr, err := sdk.ValAddressFromBech32(args[1]) -// if err != nil { -// return err -// } - -// msg := types.NewMsgSuperfluidRedelegate( -// clientCtx.GetFromAddress(), -// uint64(lockId), -// valAddr, -// ) - -// return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) -// }, -// } - -// flags.AddTxFlagsToCmd(cmd) -// return cmd -// } - // NewCmdSubmitSetSuperfluidAssetsProposal implements a command handler for submitting a superfluid asset set proposal transaction. func NewCmdSubmitSetSuperfluidAssetsProposal() *cobra.Command { cmd := &cobra.Command{ @@ -375,35 +280,11 @@ func NewCmdLockAndSuperfluidDelegate() *cobra.Command { return cmd } -// NewCmdUnPoolWhitelistedPool implements a command handler for unpooling whitelisted pools. func NewCmdUnPoolWhitelistedPool() *cobra.Command { - cmd := &cobra.Command{ + return osmocli.BuildTxCli[*types.MsgUnPoolWhitelistedPool](&osmocli.TxCliDesc{ Use: "unpool-whitelisted-pool [pool_id] [flags]", Short: "unpool whitelisted pool", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - sender := clientCtx.GetFromAddress() - - poolId, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - msg := types.NewMsgUnPoolWhitelistedPool(sender, uint64(poolId)) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd + }) } // NewCmdUpdateUnpoolWhitelistProposal defines the command to create a new update unpool whitelist proposal command. diff --git a/x/tokenfactory/client/cli/query.go b/x/tokenfactory/client/cli/query.go index cf9a1eefa8d..dd7f8b524de 100644 --- a/x/tokenfactory/client/cli/query.go +++ b/x/tokenfactory/client/cli/query.go @@ -1,34 +1,25 @@ package cli import ( - "fmt" // "strings" "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - // "github.com/cosmos/cosmos-sdk/client/flags" // sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/tokenfactory/types" ) // GetQueryCmd returns the cli query commands for this module func GetQueryCmd() *cobra.Command { - // Group tokenfactory queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } + cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand( - GetParams(), + osmocli.GetParams[*types.QueryParamsRequest]( + types.ModuleName, types.NewQueryClient), GetCmdDenomAuthorityMetadata(), GetCmdDenomsFromCreator(), ) @@ -36,87 +27,18 @@ func GetQueryCmd() *cobra.Command { return cmd } -// GetParams returns the params for the module -func GetParams() *cobra.Command { - cmd := &cobra.Command{ - Use: "params [flags]", - Short: "Get the params for the x/tokenfactory module", - Args: cobra.ExactArgs(0), - 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) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - -// GetCmdDenomAuthorityMetadata returns the authority metadata for a queried denom func GetCmdDenomAuthorityMetadata() *cobra.Command { - cmd := &cobra.Command{ - Use: "denom-authority-metadata [denom] [flags]", - Short: "Get the authority metadata for a specific denom", - Args: cobra.ExactArgs(1), - 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.DenomAuthorityMetadata(cmd.Context(), &types.QueryDenomAuthorityMetadataRequest{ - Denom: args[0], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.QueryDenomAuthorityMetadataRequest]( + "denom-authority-metadata [denom] [flags]", + "Get the authority metadata for a specific denom", "", + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdDenomsFromCreator a command to get a list of all tokens created by a specific creator address func GetCmdDenomsFromCreator() *cobra.Command { - cmd := &cobra.Command{ - Use: "denoms-from-creator [creator address] [flags]", - Short: "Returns a list of all tokens created by a specific creator address", - Args: cobra.ExactArgs(1), - 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.DenomsFromCreator(cmd.Context(), &types.QueryDenomsFromCreatorRequest{ - Creator: args[0], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + return osmocli.SimpleQueryCmd[*types.QueryDenomsFromCreatorRequest]( + "denoms-from-creator [creator address] [flags]", + "Returns a list of all tokens created by a specific creator address", "", + types.ModuleName, types.NewQueryClient, + ) } diff --git a/x/tokenfactory/client/cli/tx.go b/x/tokenfactory/client/cli/tx.go index 7c375ceabef..f5cc29d292c 100644 --- a/x/tokenfactory/client/cli/tx.go +++ b/x/tokenfactory/client/cli/tx.go @@ -1,29 +1,16 @@ 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/client/flags" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/tokenfactory/types" ) // GetTxCmd returns the transaction commands for this module func GetTxCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - + cmd := osmocli.TxIndexCmd(types.ModuleName) cmd.AddCommand( NewCreateDenomCmd(), NewMintCmd(), @@ -35,155 +22,30 @@ func GetTxCmd() *cobra.Command { return cmd } -// NewCreateDenomCmd broadcast MsgCreateDenom func NewCreateDenomCmd() *cobra.Command { - cmd := &cobra.Command{ + return osmocli.BuildTxCli[*types.MsgCreateDenom](&osmocli.TxCliDesc{ Use: "create-denom [subdenom] [flags]", - Short: "create a new denom from an account", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - msg := types.NewMsgCreateDenom( - clientCtx.GetFromAddress().String(), - args[0], - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd + Short: "create a new denom from an account. (Costs osmo though!)", + }) } -// NewMintCmd broadcast MsgMint func NewMintCmd() *cobra.Command { - cmd := &cobra.Command{ + return osmocli.BuildTxCli[*types.MsgMint](&osmocli.TxCliDesc{ Use: "mint [amount] [flags]", Short: "Mint a denom to an address. Must have admin authority to do so.", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - amount, err := sdk.ParseCoinNormalized(args[0]) - if err != nil { - return err - } - - msg := types.NewMsgMint( - clientCtx.GetFromAddress().String(), - amount, - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd + }) } -// NewBurnCmd broadcast MsgBurn func NewBurnCmd() *cobra.Command { - cmd := &cobra.Command{ + return osmocli.BuildTxCli[*types.MsgBurn](&osmocli.TxCliDesc{ Use: "burn [amount] [flags]", Short: "Burn tokens from an address. Must have admin authority to do so.", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - amount, err := sdk.ParseCoinNormalized(args[0]) - if err != nil { - return err - } - - msg := types.NewMsgBurn( - clientCtx.GetFromAddress().String(), - amount, - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd + }) } -// // NewForceTransferCmd broadcast MsgForceTransfer -// func NewForceTransferCmd() *cobra.Command { -// cmd := &cobra.Command{ -// Use: "force-transfer [amount] [transfer-from-address] [transfer-to-address] [flags]", -// Short: "Force transfer tokens from one address to another address. Must have admin authority to do so.", -// Args: cobra.ExactArgs(3), -// RunE: func(cmd *cobra.Command, args []string) error { -// clientCtx, err := client.GetClientTxContext(cmd) -// if err != nil { -// return err -// } - -// txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - -// amount, err := sdk.ParseCoinNormalized(args[0]) -// if err != nil { -// return err -// } - -// msg := types.NewMsgForceTransfer( -// clientCtx.GetFromAddress().String(), -// amount, -// args[1], -// args[2], -// ) - -// return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) -// }, -// } - -// flags.AddTxFlagsToCmd(cmd) -// return cmd -// } - -// NewChangeAdminCmd broadcast MsgChangeAdmin func NewChangeAdminCmd() *cobra.Command { - cmd := &cobra.Command{ + return osmocli.BuildTxCli[*types.MsgChangeAdmin](&osmocli.TxCliDesc{ Use: "change-admin [denom] [new-admin-address] [flags]", Short: "Changes the admin address for a factory-created denom. Must have admin authority to do so.", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - - msg := types.NewMsgChangeAdmin( - clientCtx.GetFromAddress().String(), - args[0], - args[1], - ) - - return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - return cmd + }) } diff --git a/x/twap/client/cli/query.go b/x/twap/client/cli/query.go index 213f82a9fa1..13bccff1e1a 100644 --- a/x/twap/client/cli/query.go +++ b/x/twap/client/cli/query.go @@ -2,15 +2,14 @@ package twapcli import ( "fmt" - "strconv" "strings" "time" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" gammtypes "github.com/osmosis-labs/osmosis/v13/x/gamm/types" "github.com/osmosis-labs/osmosis/v13/x/twap/client/queryproto" "github.com/osmosis-labs/osmosis/v13/x/twap/types" @@ -18,17 +17,8 @@ import ( // GetQueryCmd returns the cli query commands for this module. func GetQueryCmd() *cobra.Command { - // Group superfluid queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - + cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand(GetQueryTwapCommand()) - cmd.AddCommand(GetQueryTwapLegacyCommand()) return cmd } @@ -38,16 +28,12 @@ func GetQueryTwapCommand() *cobra.Command { cmd := &cobra.Command{ Use: "twap [poolid] [base denom] [start time] [end time]", Short: "Query twap", - Long: strings.TrimSpace( - fmt.Sprintf(`Query twap for pool. Start time must be unix time. End time can be unix time or duration. + Long: osmocli.FormatLongDescDirect(`Query twap for pool. Start time must be unix time. End time can be unix time or duration. Example: -$ %s q twap 1 uosmo 1667088000 24h -$ %s q twap 1 uosmo 1667088000 1667174400 -`, - version.AppName, version.AppName, - ), - ), +{{.CommandPrefix}} twap 1 uosmo 1667088000 24h +{{.CommandPrefix}} twap 1 uosmo 1667088000 1667174400 +`, types.ModuleName), Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { // boilerplate parse fields @@ -99,76 +85,10 @@ $ %s q twap 1 uosmo 1667088000 1667174400 return cmd } -// GetQueryTwapCommand returns multiplier of an asset by denom. -func GetQueryTwapLegacyCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "twap-legacy [poolid] [base denom] [start time] [end time]", - Short: "Query twap", - Long: strings.TrimSpace( - fmt.Sprintf(`Query twap for pool. Start time must be unix time. End time can be unix time or duration. - -Example: -$ %s q twap 1 uosmo 1667088000 24h -$ %s q twap 1 uosmo 1667088000 1667174400 -`, - version.AppName, version.AppName, - ), - ), - Args: cobra.ExactArgs(4), - RunE: func(cmd *cobra.Command, args []string) error { - poolId, baseDenom, startTime, endTime, err := twapQueryParseArgs(args) - if err != nil { - return err - } - - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - queryClient := queryproto.NewQueryClient(clientCtx) - gammClient := gammtypes.NewQueryClient(clientCtx) - liquidity, err := gammClient.TotalPoolLiquidity(cmd.Context(), &gammtypes.QueryTotalPoolLiquidityRequest{PoolId: poolId}) - if err != nil { - return err - } - if len(liquidity.Liquidity) != 2 { - return fmt.Errorf("pool %d has %d assets of liquidity, CLI support only exists for 2 assets right now.", poolId, len(liquidity.Liquidity)) - } - quoteDenom := "" - if liquidity.Liquidity[0].Denom == baseDenom { - quoteDenom = liquidity.Liquidity[1].Denom - } else if liquidity.Liquidity[1].Denom == baseDenom { - quoteDenom = liquidity.Liquidity[0].Denom - } else { - return fmt.Errorf("pool %d doesn't have provided baseDenom %s, has %s and %s", - poolId, baseDenom, liquidity.Liquidity[0], liquidity.Liquidity[1]) - } - - // nolint: staticcheck - res, err := queryClient.ArithmeticTwap(cmd.Context(), &queryproto.ArithmeticTwapRequest{ - PoolId: poolId, - BaseAsset: baseDenom, - QuoteAsset: quoteDenom, - StartTime: startTime, - EndTime: &endTime, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - func twapQueryParseArgs(args []string) (poolId uint64, baseDenom string, startTime time.Time, endTime time.Time, err error) { // boilerplate parse fields // - poolId, err = parseUint(args[0], "poolId") + poolId, err = osmocli.ParseUint(args[0], "poolId") if err != nil { return } @@ -177,14 +97,14 @@ func twapQueryParseArgs(args []string) (poolId uint64, baseDenom string, startTi baseDenom = strings.TrimSpace(args[1]) // - startTime, err = parseUnixTime(args[2], "start time") + startTime, err = osmocli.ParseUnixTime(args[2], "start time") if err != nil { return } // END TIME PARSE: ONEOF {, } // try parsing in unix time, if failed try parsing in duration - endTime, err = parseUnixTime(args[3], "end time") + endTime, err = osmocli.ParseUnixTime(args[3], "end time") if err != nil { // TODO if we don't use protoreflect: // make better error combiner, rather than just returning last error @@ -197,20 +117,3 @@ func twapQueryParseArgs(args []string) (poolId uint64, baseDenom string, startTi } return poolId, baseDenom, startTime, endTime, nil } - -func parseUint(arg string, fieldName string) (uint64, error) { - v, err := strconv.ParseUint(arg, 10, 64) - if err != nil { - return 0, fmt.Errorf("could not parse %s as uint for field %s: %w", arg, fieldName, err) - } - return v, nil -} - -func parseUnixTime(arg string, fieldName string) (time.Time, error) { - timeUnix, err := strconv.ParseInt(arg, 10, 64) - if err != nil { - return time.Time{}, fmt.Errorf("could not parse %s as unix time for field %s: %w", arg, fieldName, err) - } - startTime := time.Unix(timeUnix, 0) - return startTime, nil -} diff --git a/x/txfees/client/cli/query.go b/x/txfees/client/cli/query.go index f1078d1f4a5..9f709ed24b6 100644 --- a/x/txfees/client/cli/query.go +++ b/x/txfees/client/cli/query.go @@ -1,28 +1,15 @@ package cli import ( - "fmt" - "strings" - "github.com/spf13/cobra" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/txfees/types" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/version" ) // GetQueryCmd returns the cli query commands for this module. func GetQueryCmd() *cobra.Command { - // Group queries under a subcommand - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } + cmd := osmocli.QueryIndexCmd(types.ModuleName) cmd.AddCommand( GetCmdFeeTokens(), @@ -33,112 +20,35 @@ func GetQueryCmd() *cobra.Command { return cmd } -// GetCmdFeeTokens takes the pool id and returns the matching gauge ids and durations. func GetCmdFeeTokens() *cobra.Command { - cmd := &cobra.Command{ - Use: "fee-tokens", - Short: "Query the list of non-basedenom fee tokens and their associated pool ids", - Long: strings.TrimSpace( - fmt.Sprintf(`Query the list of non-basedenom fee tokens and their associated pool ids - -Example: -$ %s query txfees fee-tokens + return osmocli.SimpleQueryCmd[*types.QueryFeeTokensRequest]( + "fee-tokens", + "Query the list of non-basedenom fee tokens and their associated pool ids", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} fee-tokens `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.FeeTokens(cmd.Context(), &types.QueryFeeTokensRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdDenomPoolID takes the pool id and returns the matching gauge ids and durations. func GetCmdDenomPoolID() *cobra.Command { - cmd := &cobra.Command{ - Use: "denom-pool-id", - Short: "Query the pool id associated with a specific whitelisted fee token", - Long: strings.TrimSpace( - fmt.Sprintf(`Query the pool id associated with a specific fee token - -Example: -$ %s query txfees denom-pool-id [denom] + return osmocli.SimpleQueryCmd[*types.QueryDenomPoolIdRequest]( + "denom-pool-id", + "Query the pool id associated with a specific whitelisted fee token", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} denom-pool-id [denom] `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - 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.DenomPoolId(cmd.Context(), &types.QueryDenomPoolIdRequest{ - Denom: args[0], - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } -// GetCmdBaseDenom takes the pool id and returns the matching gauge ids and weights. func GetCmdBaseDenom() *cobra.Command { - cmd := &cobra.Command{ - Use: "base-denom", - Short: "Query the base fee denom", - Long: strings.TrimSpace( - fmt.Sprintf(`Query the base fee denom. - -Example: -$ %s query txfees base-denom + return osmocli.SimpleQueryCmd[*types.QueryBaseDenomRequest]( + "base-denom", + "Query the base fee denom", + `{{.Short}}{{.ExampleHeader}} +{{.CommandPrefix}} base-denom `, - version.AppName, - ), - ), - Args: cobra.ExactArgs(0), - 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.BaseDenom(cmd.Context(), &types.QueryBaseDenomRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd + types.ModuleName, types.NewQueryClient, + ) } diff --git a/x/txfees/client/cli/tx.go b/x/txfees/client/cli/tx.go index 33da28b1053..d2d7b46a667 100644 --- a/x/txfees/client/cli/tx.go +++ b/x/txfees/client/cli/tx.go @@ -13,22 +13,15 @@ import ( "github.com/cosmos/cosmos-sdk/x/gov/client/cli" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" "github.com/osmosis-labs/osmosis/v13/x/txfees/types" ) func NewTxCmd() *cobra.Command { - txCmd := &cobra.Command{ - Use: types.ModuleName, - Short: "txfees transaction subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - + txCmd := osmocli.TxIndexCmd(types.ModuleName) txCmd.AddCommand( NewCmdSubmitUpdateFeeTokenProposal(), ) - return txCmd } diff --git a/x/valset-pref/client/cli/query.go b/x/valset-pref/client/cli/query.go new file mode 100644 index 00000000000..d2aedb80562 --- /dev/null +++ b/x/valset-pref/client/cli/query.go @@ -0,0 +1,25 @@ +package valsetprefcli + +import ( + "github.com/spf13/cobra" + + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" + "github.com/osmosis-labs/osmosis/v13/x/valset-pref/client/queryproto" + "github.com/osmosis-labs/osmosis/v13/x/valset-pref/types" +) + +// GetQueryCmd returns the cli query commands for this module. +func GetQueryCmd() *cobra.Command { + cmd := osmocli.QueryIndexCmd(types.ModuleName) + cmd.AddCommand(GetCmdValSetPref()) + return cmd +} + +// GetCmdValSetPref takes the address and returns the existing validator set for that address. +func GetCmdValSetPref() *cobra.Command { + return osmocli.SimpleQueryCmd[*queryproto.UserValidatorPreferencesRequest]( + "val-set [address]", + "Query the validator set for a specific user address", "", + types.ModuleName, queryproto.NewQueryClient, + ) +} diff --git a/x/valset-pref/client/cli/tx.go b/x/valset-pref/client/cli/tx.go new file mode 100644 index 00000000000..1b6cfcb2004 --- /dev/null +++ b/x/valset-pref/client/cli/tx.go @@ -0,0 +1,68 @@ +package valsetprefcli + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + "github.com/osmosis-labs/osmosis/v13/osmoutils" + "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" + "github.com/osmosis-labs/osmosis/v13/x/valset-pref/types" +) + +func GetTxCmd() *cobra.Command { + txCmd := osmocli.TxIndexCmd(types.ModuleName) + txCmd.AddCommand( + NewSetValSetCmd(), + ) + + return txCmd +} + +func NewSetValSetCmd() *cobra.Command { + return osmocli.TxCliDesc{ + Use: "set-valset [delegator_addr] [validators] [weights]", + Short: "Creates a new validator set for the delegator with valOperAddress and weight", + Example: "osmosisd tx valset-pref set-valset osmo1... osmovaloper1abc...,osmovaloper1def... 0.56,0.44", + NumArgs: 3, + ParseAndBuildMsg: NewMsgSetValidatorSetPreference, + }.BuildCommandCustomFn() +} + +func NewMsgSetValidatorSetPreference(clientCtx client.Context, args []string, fs *pflag.FlagSet) (sdk.Msg, error) { + delAddr, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return nil, err + } + + valAddrs := osmoutils.ParseSdkValAddressFromString(args[1], ",") + + weights, err := osmoutils.ParseSdkDecFromString(args[2], ",") + if err != nil { + return nil, err + } + + if len(valAddrs) != len(weights) { + return nil, fmt.Errorf("the length of validator addresses and weights not matched") + } + + if len(valAddrs) == 0 { + return nil, fmt.Errorf("records is empty") + } + + var valset []types.ValidatorPreference + for i, val := range valAddrs { + valset = append(valset, types.ValidatorPreference{ + Weight: weights[i], + ValOperAddress: val.String(), + }) + } + + return types.NewMsgSetValidatorSetPreference( + delAddr, + valset, + ), nil +} From 9b33741cb4d0529b9635ff67dd3623d2fd7e5b6e Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Mon, 5 Dec 2022 17:09:57 -0600 Subject: [PATCH 2/2] Fix conflicts --- x/valset-pref/client/cli/query.go | 25 ------------ x/valset-pref/client/cli/tx.go | 68 ------------------------------- 2 files changed, 93 deletions(-) delete mode 100644 x/valset-pref/client/cli/query.go delete mode 100644 x/valset-pref/client/cli/tx.go diff --git a/x/valset-pref/client/cli/query.go b/x/valset-pref/client/cli/query.go deleted file mode 100644 index d2aedb80562..00000000000 --- a/x/valset-pref/client/cli/query.go +++ /dev/null @@ -1,25 +0,0 @@ -package valsetprefcli - -import ( - "github.com/spf13/cobra" - - "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" - "github.com/osmosis-labs/osmosis/v13/x/valset-pref/client/queryproto" - "github.com/osmosis-labs/osmosis/v13/x/valset-pref/types" -) - -// GetQueryCmd returns the cli query commands for this module. -func GetQueryCmd() *cobra.Command { - cmd := osmocli.QueryIndexCmd(types.ModuleName) - cmd.AddCommand(GetCmdValSetPref()) - return cmd -} - -// GetCmdValSetPref takes the address and returns the existing validator set for that address. -func GetCmdValSetPref() *cobra.Command { - return osmocli.SimpleQueryCmd[*queryproto.UserValidatorPreferencesRequest]( - "val-set [address]", - "Query the validator set for a specific user address", "", - types.ModuleName, queryproto.NewQueryClient, - ) -} diff --git a/x/valset-pref/client/cli/tx.go b/x/valset-pref/client/cli/tx.go deleted file mode 100644 index 1b6cfcb2004..00000000000 --- a/x/valset-pref/client/cli/tx.go +++ /dev/null @@ -1,68 +0,0 @@ -package valsetprefcli - -import ( - "fmt" - - "github.com/cosmos/cosmos-sdk/client" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - - "github.com/osmosis-labs/osmosis/v13/osmoutils" - "github.com/osmosis-labs/osmosis/v13/osmoutils/osmocli" - "github.com/osmosis-labs/osmosis/v13/x/valset-pref/types" -) - -func GetTxCmd() *cobra.Command { - txCmd := osmocli.TxIndexCmd(types.ModuleName) - txCmd.AddCommand( - NewSetValSetCmd(), - ) - - return txCmd -} - -func NewSetValSetCmd() *cobra.Command { - return osmocli.TxCliDesc{ - Use: "set-valset [delegator_addr] [validators] [weights]", - Short: "Creates a new validator set for the delegator with valOperAddress and weight", - Example: "osmosisd tx valset-pref set-valset osmo1... osmovaloper1abc...,osmovaloper1def... 0.56,0.44", - NumArgs: 3, - ParseAndBuildMsg: NewMsgSetValidatorSetPreference, - }.BuildCommandCustomFn() -} - -func NewMsgSetValidatorSetPreference(clientCtx client.Context, args []string, fs *pflag.FlagSet) (sdk.Msg, error) { - delAddr, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - return nil, err - } - - valAddrs := osmoutils.ParseSdkValAddressFromString(args[1], ",") - - weights, err := osmoutils.ParseSdkDecFromString(args[2], ",") - if err != nil { - return nil, err - } - - if len(valAddrs) != len(weights) { - return nil, fmt.Errorf("the length of validator addresses and weights not matched") - } - - if len(valAddrs) == 0 { - return nil, fmt.Errorf("records is empty") - } - - var valset []types.ValidatorPreference - for i, val := range valAddrs { - valset = append(valset, types.ValidatorPreference{ - Weight: weights[i], - ValOperAddress: val.String(), - }) - } - - return types.NewMsgSetValidatorSetPreference( - delAddr, - valset, - ), nil -}