chore(client/v2): sync client/v2 with main (backport #22493, #22817) (#22820)

Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
mergify[bot] 2024-12-10 22:30:41 +01:00 committed by GitHub
parent 0cf6cd800c
commit 3ba671f0e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
91 changed files with 1405 additions and 508 deletions

View File

@ -54,11 +54,13 @@ Ref: https://keepachangelog.com/en/1.0.0/
### API Breaking Changes
* [#17709](https://github.com/cosmos/cosmos-sdk/pull/17709) Address codecs have been removed from `autocli.AppOptions` and `flag.Builder`. Instead client/v2 uses the address codecs present in the context (introduced in [#17503](https://github.com/cosmos/cosmos-sdk/pull/17503)).
* [#22493](https://github.com/cosmos/cosmos-sdk/pull/22493) Refactored `client/v2` package to remove v1 context dependencies, while introducing new packages for client configuration, context management, and formatted output with improved transaction handling and flag support.
### Bug Fixes
* [#21853](https://github.com/cosmos/cosmos-sdk/pull/21853) Fix `*big.Int` unmarshalling in txs.
* [#22576](https://github.com/cosmos/cosmos-sdk/pull/22576) Fix duplicate command addition in `autocli` when custom enhanced command has a different name than module name
* [#22817](https://github.com/cosmos/cosmos-sdk/pull/22817) Add DecCoin support in autocli flag builder.
## [v2.0.0-beta.5] - 2024-09-18
@ -66,6 +68,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#21712](https://github.com/cosmos/cosmos-sdk/pull/21712) Marshal `type` field as proto message url in queries instead of amino name.
## [v2.0.0-beta.4] - 2024-07-16
### Bug Fixes
* [#20964](https://github.com/cosmos/cosmos-sdk/pull/20964) Fix `GetNodeHomeDirectory` helper in `client/v2/helpers` to respect the `(PREFIX)_HOME` environment variable.

View File

@ -3,19 +3,20 @@ package autocli
import (
"github.com/cosmos/gogoproto/proto"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/protobuf/reflect/protoregistry"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/client/v2/autocli/flag"
"cosmossdk.io/core/address"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/x/tx/signing"
"github.com/cosmos/cosmos-sdk/client"
sdkflags "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
)
// AppOptions are input options for an autocli enabled app. These options can be built via depinject based on an app config.
@ -38,8 +39,15 @@ type AppOptions struct {
// module or need to be improved.
ModuleOptions map[string]*autocliv1.ModuleOptions `optional:"true"`
// ClientCtx contains the necessary information needed to execute the commands.
ClientCtx client.Context
AddressCodec address.Codec // AddressCodec is used to encode/decode account addresses.
ValidatorAddressCodec address.ValidatorAddressCodec // ValidatorAddressCodec is used to encode/decode validator addresses.
ConsensusAddressCodec address.ConsensusAddressCodec // ConsensusAddressCodec is used to encode/decode consensus addresses.
// Cdc is the codec used for binary encoding/decoding of messages.
Cdc codec.Codec
// TxConfigOpts contains options for configuring transaction handling.
TxConfigOpts authtx.ConfigOptions
skipValidation bool
}
@ -63,19 +71,19 @@ func (appOptions AppOptions) EnhanceRootCommand(rootCmd *cobra.Command) error {
builder := &Builder{
Builder: flag.Builder{
TypeResolver: protoregistry.GlobalTypes,
FileResolver: appOptions.ClientCtx.InterfaceRegistry,
AddressCodec: appOptions.ClientCtx.AddressCodec,
ValidatorAddressCodec: appOptions.ClientCtx.ValidatorAddressCodec,
ConsensusAddressCodec: appOptions.ClientCtx.ConsensusAddressCodec,
},
GetClientConn: func(cmd *cobra.Command) (grpc.ClientConnInterface, error) {
return client.GetClientQueryContext(cmd)
FileResolver: appOptions.Cdc.InterfaceRegistry(),
AddressCodec: appOptions.AddressCodec,
ValidatorAddressCodec: appOptions.ValidatorAddressCodec,
ConsensusAddressCodec: appOptions.ConsensusAddressCodec,
},
GetClientConn: getQueryClientConn(appOptions.Cdc),
AddQueryConnFlags: func(c *cobra.Command) {
sdkflags.AddQueryFlagsToCmd(c)
sdkflags.AddKeyringFlags(c.Flags())
},
AddTxConnFlags: sdkflags.AddTxFlagsToCmd,
AddTxConnFlags: sdkflags.AddTxFlagsToCmd,
Cdc: appOptions.Cdc,
EnabledSignModes: appOptions.TxConfigOpts.EnabledSignModes,
}
return appOptions.EnhanceRootCommandWithBuilder(rootCmd, builder)
@ -170,9 +178,9 @@ func NewAppOptionsFromConfig(
return AppOptions{
Modules: cfg.Modules,
ClientCtx: client.Context{InterfaceRegistry: interfaceRegistry},
ModuleOptions: moduleOptions,
skipValidation: true,
Cdc: codec.NewProtoCodec(interfaceRegistry),
}, nil
}

View File

@ -5,6 +5,9 @@ import (
"google.golang.org/grpc"
"cosmossdk.io/client/v2/autocli/flag"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
)
// Builder manages options for building CLI commands.
@ -19,6 +22,9 @@ type Builder struct {
// AddQueryConnFlags and AddTxConnFlags are functions that add flags to query and transaction commands
AddQueryConnFlags func(*cobra.Command)
AddTxConnFlags func(*cobra.Command)
Cdc codec.Codec
EnabledSignModes []signing.SignMode
}
// ValidateAndComplete the builder fields.

View File

@ -1,18 +1,29 @@
package autocli
import (
"context"
"crypto/tls"
"fmt"
"strings"
"strconv"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
grpcinsecure "google.golang.org/grpc/credentials/insecure"
"google.golang.org/protobuf/reflect/protoreflect"
"sigs.k8s.io/yaml"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
apitxsigning "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
"cosmossdk.io/client/v2/autocli/config"
"cosmossdk.io/client/v2/autocli/keyring"
"cosmossdk.io/client/v2/broadcast/comet"
clientcontext "cosmossdk.io/client/v2/context"
"cosmossdk.io/client/v2/internal/flags"
"cosmossdk.io/client/v2/internal/print"
"cosmossdk.io/client/v2/internal/util"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
)
type cmdType int
@ -62,8 +73,13 @@ func (b *Builder) buildMethodCommandCommon(descriptor protoreflect.MethodDescrip
}
cmd.Args = binder.CobraArgs
cmd.PreRunE = b.preRunE()
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx = cmd.Context()
ctx, err = b.getContext(cmd)
if err != nil {
return err
}
input, err := binder.BuildMessage(args)
if err != nil {
@ -237,27 +253,132 @@ func enhanceCustomCmd(builder *Builder, cmd *cobra.Command, cmdType cmdType, mod
// outOrStdoutFormat formats the output based on the output flag and writes it to the command's output stream.
func (b *Builder) outOrStdoutFormat(cmd *cobra.Command, out []byte) error {
clientCtx := client.Context{}
if v := cmd.Context().Value(client.ClientContextKey); v != nil {
clientCtx = *(v.(*client.Context))
p, err := print.NewPrinter(cmd)
if err != nil {
return err
}
flagSet := cmd.Flags()
if clientCtx.OutputFormat == "" || flagSet.Changed(flags.FlagOutput) {
output, _ := flagSet.GetString(flags.FlagOutput)
clientCtx = clientCtx.WithOutputFormat(output)
return p.PrintBytes(out)
}
// getContext creates and returns a new context.Context with an autocli.Context value.
// It initializes a printer and, if necessary, a keyring based on command flags.
func (b *Builder) getContext(cmd *cobra.Command) (context.Context, error) {
// if the command uses the keyring this must be set
var (
k keyring.Keyring
err error
)
if cmd.Flags().Lookup(flags.FlagKeyringDir) != nil && cmd.Flags().Lookup(flags.FlagKeyringBackend) != nil {
k, err = keyring.NewKeyringFromFlags(cmd.Flags(), b.AddressCodec, cmd.InOrStdin(), b.Cdc)
if err != nil {
return nil, err
}
} else {
k = keyring.NoKeyring{}
}
var err error
outputType := clientCtx.OutputFormat
// if the output type is text, convert the json to yaml
// if output type is json or nil, default to json
if outputType == flags.OutputFormatText {
out, err = yaml.JSONToYAML(out)
clientCtx := clientcontext.Context{
Flags: cmd.Flags(),
AddressCodec: b.AddressCodec,
ValidatorAddressCodec: b.ValidatorAddressCodec,
ConsensusAddressCodec: b.ConsensusAddressCodec,
Cdc: b.Cdc,
Keyring: k,
EnabledSignModes: signModesToApiSignModes(b.EnabledSignModes),
}
return clientcontext.SetInContext(cmd.Context(), clientCtx), nil
}
// preRunE returns a function that sets flags from the configuration before running a command.
// It is used as a PreRunE hook for cobra commands to ensure flags are properly initialized
// from the configuration before command execution.
func (b *Builder) preRunE() func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
err := b.setFlagsFromConfig(cmd)
if err != nil {
return err
}
return nil
}
}
// setFlagsFromConfig sets command flags from the provided configuration.
// It only sets flags that haven't been explicitly changed by the user.
func (b *Builder) setFlagsFromConfig(cmd *cobra.Command) error {
conf, err := config.CreateClientConfigFromFlags(cmd.Flags())
if err != nil {
return err
}
flagsToSet := map[string]string{
flags.FlagChainID: conf.ChainID,
flags.FlagKeyringBackend: conf.KeyringBackend,
flags.FlagFrom: conf.KeyringDefaultKeyName,
flags.FlagOutput: conf.Output,
flags.FlagNode: conf.Node,
flags.FlagBroadcastMode: conf.BroadcastMode,
flags.FlagGrpcAddress: conf.GRPC.Address,
flags.FlagGrpcInsecure: strconv.FormatBool(conf.GRPC.Insecure),
}
for flagName, value := range flagsToSet {
if flag := cmd.Flags().Lookup(flagName); flag != nil && !cmd.Flags().Changed(flagName) {
if err := cmd.Flags().Set(flagName, value); err != nil {
return err
}
}
}
cmd.Println(strings.TrimSpace(string(out)))
return nil
}
// getQueryClientConn returns a function that creates a gRPC client connection based on command flags.
// It handles the creation of secure or insecure connections and falls back to a CometBFT broadcaster
// if no gRPC address is specified.
func getQueryClientConn(cdc codec.Codec) func(cmd *cobra.Command) (grpc.ClientConnInterface, error) {
return func(cmd *cobra.Command) (grpc.ClientConnInterface, error) {
var err error
creds := grpcinsecure.NewCredentials()
insecure := true
if cmd.Flags().Lookup(flags.FlagGrpcInsecure) != nil {
insecure, err = cmd.Flags().GetBool(flags.FlagGrpcInsecure)
if err != nil {
return nil, err
}
}
if !insecure {
creds = credentials.NewTLS(&tls.Config{MinVersion: tls.VersionTLS12})
}
var addr string
if cmd.Flags().Lookup(flags.FlagGrpcAddress) != nil {
addr, err = cmd.Flags().GetString(flags.FlagGrpcAddress)
if err != nil {
return nil, err
}
}
if addr == "" {
// if grpc-addr has not been set, use the default clientConn
// TODO: default is comet
node, err := cmd.Flags().GetString(flags.FlagNode)
if err != nil {
return nil, err
}
return comet.NewCometBFTBroadcaster(node, comet.BroadcastSync, cdc)
}
return grpc.NewClient(addr, []grpc.DialOption{grpc.WithTransportCredentials(creds)}...)
}
}
// signModesToApiSignModes converts a slice of signing.SignMode to a slice of apitxsigning.SignMode.
func signModesToApiSignModes(modes []signing.SignMode) []apitxsigning.SignMode {
r := make([]apitxsigning.SignMode, len(modes))
for i, m := range modes {
r[i] = apitxsigning.SignMode(m)
}
return r
}

View File

@ -32,6 +32,10 @@ type fixture struct {
conn *testClientConn
b *Builder
clientCtx client.Context
home string
chainID string
kBackend string
}
func initFixture(t *testing.T) *fixture {
@ -85,7 +89,8 @@ func initFixture(t *testing.T) *fixture {
return conn, nil
},
AddQueryConnFlags: flags.AddQueryFlagsToCmd,
AddTxConnFlags: flags.AddTxFlagsToCmd,
AddTxConnFlags: addTxAndGlobalFlagsToCmd,
Cdc: encodingConfig.Codec,
}
assert.NilError(t, b.ValidateAndComplete())
@ -93,9 +98,19 @@ func initFixture(t *testing.T) *fixture {
conn: conn,
b: b,
clientCtx: clientCtx,
home: home,
chainID: "autocli-test",
kBackend: sdkkeyring.BackendMemory,
}
}
func addTxAndGlobalFlagsToCmd(cmd *cobra.Command) {
f := cmd.Flags()
f.String("home", "", "home directory")
flags.AddTxFlagsToCmd(cmd)
}
func runCmd(fixture *fixture, command func(moduleName string, f *fixture) (*cobra.Command, error), args ...string) (*bytes.Buffer, error) {
out := &bytes.Buffer{}
cmd, err := command("test", fixture)

View File

@ -0,0 +1,133 @@
package config
import (
"errors"
"fmt"
"os"
"path"
"path/filepath"
"strings"
"github.com/pelletier/go-toml/v2"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"cosmossdk.io/client/v2/internal/flags"
)
type Config struct {
ChainID string `mapstructure:"chain-id" toml:"chain-id" comment:"The chain ID of the blockchain network"`
KeyringBackend string `mapstructure:"keyring-backend" toml:"keyring-backend" comment:"The keyring backend to use (os|file|kwallet|pass|test|memory)"`
KeyringDefaultKeyName string `mapstructure:"keyring-default-keyname" toml:"keyring-default-keyname" comment:"The default key name to use for signing transactions"`
Output string `mapstructure:"output" toml:"output" comment:"The output format for queries (text|json)"`
Node string `mapstructure:"node" toml:"node" comment:"The RPC endpoint URL for the node to connect to"`
BroadcastMode string `mapstructure:"broadcast-mode" toml:"broadcast-mode" comment:"How transactions are broadcast to the network (sync|async|block)"`
GRPC GRPCConfig `mapstructure:",squash" comment:"The gRPC client configuration"`
}
// GRPCConfig holds the gRPC client configuration.
type GRPCConfig struct {
Address string `mapstructure:"grpc-address" toml:"grpc-address" comment:"The gRPC server address to connect to"`
Insecure bool `mapstructure:"grpc-insecure" toml:"grpc-insecure" comment:"Allow gRPC over insecure connections"`
}
func DefaultConfig() *Config {
return &Config{
ChainID: "",
KeyringBackend: "os",
KeyringDefaultKeyName: "",
Output: "text",
Node: "tcp://localhost:26657",
BroadcastMode: "sync",
}
}
// CreateClientConfig creates a new client configuration or reads an existing one.
func CreateClientConfig(homeDir, chainID string, v *viper.Viper) (*Config, error) {
if homeDir == "" {
return nil, errors.New("home dir can't be empty")
}
configPath := filepath.Join(homeDir, "config")
configFilePath := filepath.Join(configPath, "client.toml")
// when client.toml does not exist create and init with default values
if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
if err := os.MkdirAll(configPath, os.ModePerm); err != nil {
return nil, fmt.Errorf("couldn't make client config: %w", err)
}
conf := DefaultConfig()
if chainID != "" {
// chain-id will be written to the client.toml while initiating the chain.
conf.ChainID = chainID
}
if err := writeConfigFile(configFilePath, conf); err != nil {
return nil, fmt.Errorf("could not write client config to the file: %w", err)
}
}
conf, err := readConfig(configPath, v)
if err != nil {
return nil, fmt.Errorf("couldn't get client config: %w", err)
}
return conf, nil
}
// CreateClientConfigFromFlags creates a client configuration from command-line flags.
func CreateClientConfigFromFlags(set *pflag.FlagSet) (*Config, error) {
homeDir, _ := set.GetString(flags.FlagHome)
if homeDir == "" {
return DefaultConfig(), nil
}
chainID, _ := set.GetString(flags.FlagChainID)
v := viper.New()
executableName, err := os.Executable()
if err != nil {
return nil, err
}
v.SetEnvPrefix(path.Base(executableName))
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
v.AutomaticEnv()
return CreateClientConfig(homeDir, chainID, v)
}
// writeConfigFile renders config using the template and writes it to
// configFilePath.
func writeConfigFile(configFilePath string, config *Config) error {
b, err := toml.Marshal(config)
if err != nil {
return err
}
if dir := filepath.Dir(configFilePath); dir != "" {
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return err
}
}
return os.WriteFile(configFilePath, b, 0o600)
}
// readConfig reads values from client.toml file and unmarshalls them into ClientConfig
func readConfig(configPath string, v *viper.Viper) (*Config, error) {
v.AddConfigPath(configPath)
v.SetConfigName("client")
v.SetConfigType("toml")
if err := v.ReadInConfig(); err != nil {
return nil, err
}
conf := DefaultConfig()
if err := v.Unmarshal(conf); err != nil {
return nil, err
}
return conf, nil
}

View File

@ -7,13 +7,12 @@ import (
"google.golang.org/protobuf/reflect/protoreflect"
"cosmossdk.io/client/v2/autocli/keyring"
clientcontext "cosmossdk.io/client/v2/context"
"cosmossdk.io/core/address"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
)
@ -44,19 +43,19 @@ type addressValue struct {
value string
}
func (a addressValue) Get(protoreflect.Value) (protoreflect.Value, error) {
func (a *addressValue) Get(protoreflect.Value) (protoreflect.Value, error) {
return protoreflect.ValueOfString(a.value), nil
}
func (a addressValue) String() string {
func (a *addressValue) String() string {
return a.value
}
// Set implements the flag.Value interface for addressValue.
func (a *addressValue) Set(s string) error {
// we get the keyring on set, as in NewValue the context is the parent context (before RunE)
keyring := getKeyringFromCtx(a.ctx)
addr, err := keyring.LookupAddressByKeyName(s)
k := getKeyringFromCtx(a.ctx)
addr, err := k.LookupAddressByKeyName(s)
if err == nil {
addrStr, err := a.addressCodec.BytesToString(addr)
if err != nil {
@ -77,7 +76,7 @@ func (a *addressValue) Set(s string) error {
return nil
}
func (a addressValue) Type() string {
func (a *addressValue) Type() string {
return "account address or key name"
}
@ -110,8 +109,8 @@ func (a consensusAddressValue) String() string {
func (a *consensusAddressValue) Set(s string) error {
// we get the keyring on set, as in NewValue the context is the parent context (before RunE)
keyring := getKeyringFromCtx(a.ctx)
addr, err := keyring.LookupAddressByKeyName(s)
k := getKeyringFromCtx(a.ctx)
addr, err := k.LookupAddressByKeyName(s)
if err == nil {
addrStr, err := a.addressCodec.BytesToString(addr)
if err != nil {
@ -147,20 +146,18 @@ func (a *consensusAddressValue) Set(s string) error {
return nil
}
// getKeyringFromCtx retrieves the keyring from the provided context.
// If the context is nil or does not contain a valid client context,
// it returns a no-op keyring implementation.
func getKeyringFromCtx(ctx *context.Context) keyring.Keyring {
dctx := *ctx
if dctx != nil {
if clientCtx := dctx.Value(client.ClientContextKey); clientCtx != nil {
k, err := sdkkeyring.NewAutoCLIKeyring(clientCtx.(*client.Context).Keyring, clientCtx.(*client.Context).AddressCodec)
if err != nil {
panic(fmt.Errorf("failed to create keyring: %w", err))
}
return k
} else if k := dctx.Value(keyring.KeyringContextKey); k != nil {
return k.(*keyring.KeyringImpl)
}
if *ctx == nil {
return keyring.NoKeyring{}
}
return keyring.NoKeyring{}
c, err := clientcontext.ClientContextFromGoContext(*ctx)
if err != nil {
return keyring.NoKeyring{}
}
return c.Keyring
}

View File

@ -60,6 +60,7 @@ func (b *Builder) init() {
b.messageFlagTypes["google.protobuf.Timestamp"] = timestampType{}
b.messageFlagTypes["google.protobuf.Duration"] = durationType{}
b.messageFlagTypes["cosmos.base.v1beta1.Coin"] = coinType{}
b.messageFlagTypes["cosmos.base.v1beta1.DecCoin"] = decCoinType{}
}
if b.scalarFlagTypes == nil {

View File

@ -33,6 +33,10 @@ func (c *coinValue) Get(protoreflect.Value) (protoreflect.Value, error) {
}
func (c *coinValue) String() string {
if c.value == nil {
return ""
}
return c.value.String()
}

View File

@ -0,0 +1,58 @@
package flag
import (
"context"
"errors"
"strings"
"google.golang.org/protobuf/reflect/protoreflect"
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
"cosmossdk.io/client/v2/internal/coins"
)
type decCoinType struct{}
type decCoinValue struct {
value *basev1beta1.DecCoin
}
func (c decCoinType) NewValue(*context.Context, *Builder) Value {
return &decCoinValue{}
}
func (c decCoinType) DefaultValue() string {
return "zero"
}
func (c *decCoinValue) Get(protoreflect.Value) (protoreflect.Value, error) {
if c.value == nil {
return protoreflect.Value{}, nil
}
return protoreflect.ValueOfMessage(c.value.ProtoReflect()), nil
}
func (c *decCoinValue) String() string {
if c.value == nil {
return ""
}
return c.value.String()
}
func (c *decCoinValue) Set(stringValue string) error {
if strings.Contains(stringValue, ",") {
return errors.New("coin flag must be a single coin, specific multiple coins with multiple flags or spaces")
}
coin, err := coins.ParseDecCoin(stringValue)
if err != nil {
return err
}
c.value = coin
return nil
}
func (c *decCoinValue) Type() string {
return "cosmos.base.v1beta1.DecCoin"
}

View File

@ -1,10 +1,15 @@
package keyring
import (
"context"
"io"
"github.com/spf13/pflag"
signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
"cosmossdk.io/core/address"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/crypto/types"
)
@ -20,9 +25,32 @@ type KeyringImpl struct {
k Keyring
}
// NewKeyringInContext returns a new context with the keyring set.
func NewKeyringInContext(ctx context.Context, k Keyring) context.Context {
return context.WithValue(ctx, KeyringContextKey, NewKeyringImpl(k))
// NewKeyringFromFlags creates a new Keyring instance based on command-line flags.
// It retrieves the keyring backend and directory from flags, creates a new keyring,
// and wraps it with an AutoCLI-compatible interface.
func NewKeyringFromFlags(flagSet *pflag.FlagSet, ac address.Codec, input io.Reader, cdc codec.Codec, opts ...keyring.Option) (Keyring, error) {
backEnd, err := flagSet.GetString("keyring-backend")
if err != nil {
return nil, err
}
keyringDir, err := flagSet.GetString("keyring-dir")
if err != nil {
return nil, err
}
if keyringDir == "" {
keyringDir, err = flagSet.GetString("home")
if err != nil {
return nil, err
}
}
k, err := keyring.New("autoclikeyring", backEnd, keyringDir, input, cdc, opts...)
if err != nil {
return nil, err
}
return keyring.NewAutoCLIKeyring(k, ac)
}
func NewKeyringImpl(k Keyring) *KeyringImpl {

View File

@ -1,6 +1,7 @@
package autocli
import (
"bufio"
"context"
"fmt"
@ -13,8 +14,11 @@ import (
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/client/v2/autocli/flag"
"cosmossdk.io/client/v2/internal/flags"
"cosmossdk.io/client/v2/internal/print"
"cosmossdk.io/client/v2/internal/util"
v2tx "cosmossdk.io/client/v2/tx"
addresscodec "cosmossdk.io/core/address"
"cosmossdk.io/core/transaction"
// the following will be extracted to a separate module
// https://github.com/cosmos/cosmos-sdk/issues/14403
@ -23,6 +27,7 @@ import (
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/input"
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
)
@ -228,3 +233,76 @@ func (b *Builder) handleGovProposal(
return clienttx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), proposal)
}
// generateOrBroadcastTxWithV2 generates or broadcasts a transaction with the provided messages using v2 transaction handling.
//
//nolint:unused // It'll be used once BuildMsgMethodCommand is updated to use factory v2.
func (b *Builder) generateOrBroadcastTxWithV2(cmd *cobra.Command, msgs ...transaction.Msg) error {
ctx, err := b.getContext(cmd)
if err != nil {
return err
}
cConn, err := b.GetClientConn(cmd)
if err != nil {
return err
}
var bz []byte
genOnly, _ := cmd.Flags().GetBool(v2tx.FlagGenerateOnly)
isDryRun, _ := cmd.Flags().GetBool(v2tx.FlagDryRun)
if genOnly {
bz, err = v2tx.GenerateOnly(ctx, cConn, msgs...)
} else if isDryRun {
bz, err = v2tx.DryRun(ctx, cConn, msgs...)
} else {
skipConfirm, _ := cmd.Flags().GetBool("yes")
if skipConfirm {
bz, err = v2tx.GenerateAndBroadcastTxCLI(ctx, cConn, msgs...)
} else {
bz, err = v2tx.GenerateAndBroadcastTxCLIWithPrompt(ctx, cConn, b.userConfirmation(cmd), msgs...)
}
}
if err != nil {
return err
}
output, _ := cmd.Flags().GetString(flags.FlagOutput)
p := print.Printer{
Output: cmd.OutOrStdout(),
OutputFormat: output,
}
return p.PrintBytes(bz)
}
// userConfirmation returns a function that prompts the user for confirmation
// before signing and broadcasting a transaction.
//
//nolint:unused // It is used in generateOrBroadcastTxWithV2 however linting is complaining.
func (b *Builder) userConfirmation(cmd *cobra.Command) func([]byte) (bool, error) {
format, _ := cmd.Flags().GetString(flags.FlagOutput)
printer := print.Printer{
Output: cmd.OutOrStdout(),
OutputFormat: format,
}
return func(bz []byte) (bool, error) {
err := printer.PrintBytes(bz)
if err != nil {
return false, err
}
buf := bufio.NewReader(cmd.InOrStdin())
ok, err := input.GetConfirmation("confirm transaction before signing and broadcasting", buf, cmd.ErrOrStderr())
if err != nil {
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "error: %v\ncanceled transaction\n", err)
return false, err
}
if !ok {
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), "canceled transaction")
return false, nil
}
return true, nil
}
}

View File

@ -55,6 +55,7 @@ func TestMsg(t *testing.T) {
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
"--generate-only",
"--output", "json",
"--chain-id", fixture.chainID,
)
assert.NilError(t, err)
assertNormalizedJSONEqual(t, out.Bytes(), goldenLoad(t, "msg-output.golden"))
@ -74,6 +75,7 @@ func TestMsg(t *testing.T) {
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
"--generate-only",
"--output", "json",
"--chain-id", fixture.chainID,
)
assert.NilError(t, err)
assertNormalizedJSONEqual(t, out.Bytes(), goldenLoad(t, "msg-output.golden"))
@ -93,8 +95,10 @@ func TestMsg(t *testing.T) {
}), "send",
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
"--from", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk",
"--generate-only",
"--output", "json",
"--generate-only",
"--chain-id", fixture.chainID,
"--keyring-backend", fixture.kBackend,
)
assert.NilError(t, err)
assertNormalizedJSONEqual(t, out.Bytes(), goldenLoad(t, "msg-output.golden"))
@ -116,8 +120,9 @@ func TestMsg(t *testing.T) {
}), "send",
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
"--sender", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk",
"--generate-only",
"--output", "json",
"--generate-only",
"--chain-id", fixture.chainID,
)
assert.NilError(t, err)
assertNormalizedJSONEqual(t, out.Bytes(), goldenLoad(t, "msg-output.golden"))

View File

@ -8,15 +8,15 @@ import (
"strings"
"time"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/math"
"cosmossdk.io/x/tx/signing/aminojson"
"github.com/spf13/cobra"
"google.golang.org/grpc/metadata"
"google.golang.org/protobuf/reflect/protoreflect"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/client/v2/internal/flags"
"cosmossdk.io/client/v2/internal/util"
"cosmossdk.io/math"
"cosmossdk.io/x/tx/signing/aminojson"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -116,7 +116,6 @@ func (b *Builder) AddQueryServiceCommands(cmd *cobra.Command, cmdDescriptor *aut
// BuildQueryMethodCommand creates a gRPC query command for the given service method. This can be used to auto-generate
// just a single command for a single service rpc method.
func (b *Builder) BuildQueryMethodCommand(ctx context.Context, descriptor protoreflect.MethodDescriptor, options *autocliv1.RpcCommandOptions) (*cobra.Command, error) {
getClientConn := b.GetClientConn
serviceDescriptor := descriptor.Parent().(protoreflect.ServiceDescriptor)
methodName := fmt.Sprintf("/%s/%s", serviceDescriptor.FullName(), descriptor.Name())
outputType := util.ResolveMessageType(b.TypeResolver, descriptor.Output())
@ -130,13 +129,13 @@ func (b *Builder) BuildQueryMethodCommand(ctx context.Context, descriptor protor
}
cmd, err := b.buildMethodCommandCommon(descriptor, options, func(cmd *cobra.Command, input protoreflect.Message) error {
clientConn, err := getClientConn(cmd)
clientConn, err := b.GetClientConn(cmd)
if err != nil {
return err
}
output := outputType.New()
if err := clientConn.Invoke(cmd.Context(), methodName, input.Interface(), output.Interface()); err != nil {
if err := clientConn.Invoke(b.queryContext(cmd.Context(), cmd), methodName, input.Interface(), output.Interface()); err != nil {
return err
}
@ -170,6 +169,25 @@ func (b *Builder) BuildQueryMethodCommand(ctx context.Context, descriptor protor
return cmd, nil
}
// queryContext returns a new context with metadata for block height if specified.
// If the context already has metadata, it is returned as-is. Otherwise, if a height
// flag is present on the command, it adds an x-cosmos-block-height metadata value
// with the specified height.
func (b *Builder) queryContext(ctx context.Context, cmd *cobra.Command) context.Context {
md, _ := metadata.FromOutgoingContext(ctx)
if md != nil {
return ctx
}
md = map[string][]string{}
if cmd.Flags().Lookup("height") != nil {
h, _ := cmd.Flags().GetInt64("height")
md["x-cosmos-block-height"] = []string{fmt.Sprintf("%d", h)}
}
return metadata.NewOutgoingContext(ctx, md)
}
func encoder(encoder aminojson.Encoder) aminojson.Encoder {
return encoder.DefineTypeEncoding("google.protobuf.Duration", func(_ *aminojson.Encoder, msg protoreflect.Message, w io.Writer) error {
var (

View File

@ -18,6 +18,7 @@ Flags:
--gas-prices string Determine the transaction fee by multiplying max gas units by gas prices (e.g. 0.1uatom), rounding up to nearest denom unit
--generate-only Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase only accessed when providing a key name)
-h, --help help for send
--home string home directory
--keyring-backend string Select keyring's backend (os|file|kwallet|pass|test|memory) (default "os")
--keyring-dir string The client Keyring directory; if omitted, the default 'home' directory will be used
--ledger Use a connected Ledger device

View File

@ -0,0 +1,146 @@
package comet
import (
"context"
"errors"
"strconv"
abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
rpcclient "github.com/cometbft/cometbft/rpc/client"
gogogrpc "github.com/cosmos/gogoproto/grpc"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/encoding"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
errorsmod "cosmossdk.io/errors"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
const grpcBlockHeightHeader = "x-cosmos-block-height"
var (
_ gogogrpc.ClientConn = &CometBFTBroadcaster{}
_ grpc.ClientConnInterface = &CometBFTBroadcaster{}
)
func (c *CometBFTBroadcaster) NewStream(_ context.Context, _ *grpc.StreamDesc, _ string, _ ...grpc.CallOption) (grpc.ClientStream, error) {
return nil, errors.New("not implemented")
}
// Invoke implements the gRPC ClientConn interface by forwarding the RPC call to CometBFT's ABCI Query.
// It marshals the request, sends it as an ABCI query, and unmarshals the response.
func (c *CometBFTBroadcaster) Invoke(ctx context.Context, method string, req, reply interface{}, opts ...grpc.CallOption) (err error) {
reqBz, err := c.getRPCCodec().Marshal(req)
if err != nil {
return err
}
// parse height header
md, _ := metadata.FromOutgoingContext(ctx)
var height int64
if heights := md.Get(grpcBlockHeightHeader); len(heights) > 0 {
height, err = strconv.ParseInt(heights[0], 10, 64)
if err != nil {
return err
}
if height < 0 {
return errorsmod.Wrapf(
sdkerrors.ErrInvalidRequest,
"client.Context.Invoke: height (%d) from %q must be >= 0", height, grpcBlockHeightHeader)
}
}
abciR := abci.QueryRequest{
Path: method,
Data: reqBz,
Height: height,
}
res, err := c.queryABCI(ctx, abciR)
if err != nil {
return err
}
err = c.getRPCCodec().Unmarshal(res.Value, reply)
if err != nil {
return err
}
// Create header metadata. For now the headers contain:
// - block height
// We then parse all the call options, if the call option is a
// HeaderCallOption, then we manually set the value of that header to the
// metadata.
md = metadata.Pairs(grpcBlockHeightHeader, strconv.FormatInt(res.Height, 10))
for _, callOpt := range opts {
header, ok := callOpt.(grpc.HeaderCallOption)
if !ok {
continue
}
*header.HeaderAddr = md
}
if c.cdc.InterfaceRegistry() != nil {
return types.UnpackInterfaces(reply, c.cdc.InterfaceRegistry())
}
return nil
}
// queryABCI performs an ABCI query request to the CometBFT RPC client.
// If the RPC query fails or returns a non-OK response, it will return an error.
// The response is converted from ABCI error codes to gRPC status errors.
func (c *CometBFTBroadcaster) queryABCI(ctx context.Context, req abci.QueryRequest) (abci.QueryResponse, error) {
opts := rpcclient.ABCIQueryOptions{
Height: req.Height,
Prove: req.Prove,
}
result, err := c.rpcClient.ABCIQueryWithOptions(ctx, req.Path, req.Data, opts)
if err != nil {
return abci.QueryResponse{}, err
}
if !result.Response.IsOK() {
return abci.QueryResponse{}, sdkErrorToGRPCError(result.Response)
}
return result.Response, nil
}
// sdkErrorToGRPCError converts an ABCI query response error code to an appropriate gRPC status error.
// It maps common SDK error codes to their gRPC equivalents:
// - ErrInvalidRequest -> InvalidArgument
// - ErrUnauthorized -> Unauthenticated
// - ErrKeyNotFound -> NotFound
// Any other error codes are mapped to Unknown.
func sdkErrorToGRPCError(resp abci.QueryResponse) error {
switch resp.Code {
case sdkerrors.ErrInvalidRequest.ABCICode():
return status.Error(codes.InvalidArgument, resp.Log)
case sdkerrors.ErrUnauthorized.ABCICode():
return status.Error(codes.Unauthenticated, resp.Log)
case sdkerrors.ErrKeyNotFound.ABCICode():
return status.Error(codes.NotFound, resp.Log)
default:
return status.Error(codes.Unknown, resp.Log)
}
}
// getRPCCodec returns the gRPC codec for the CometBFT broadcaster.
// If the broadcaster's codec implements GRPCCodecProvider, it returns its gRPC codec.
// Otherwise, it creates a new ProtoCodec with the broadcaster's interface registry and returns its gRPC codec.
func (c *CometBFTBroadcaster) getRPCCodec() encoding.Codec {
cdc, ok := c.cdc.(codec.GRPCCodecProvider)
if !ok {
return codec.NewProtoCodec(c.cdc.InterfaceRegistry()).GRPCCodec()
}
return cdc.GRPCCodec()
}

View File

@ -66,11 +66,11 @@ var _ broadcast.Broadcaster = &CometBFTBroadcaster{}
type CometBFTBroadcaster struct {
rpcClient CometRPC
mode string
cdc codec.JSONCodec
cdc codec.Codec
}
// NewCometBFTBroadcaster creates a new CometBFTBroadcaster.
func NewCometBFTBroadcaster(rpcURL, mode string, cdc codec.JSONCodec) (*CometBFTBroadcaster, error) {
func NewCometBFTBroadcaster(rpcURL, mode string, cdc codec.Codec) (*CometBFTBroadcaster, error) {
if cdc == nil {
return nil, errors.New("codec can't be nil")
}

View File

@ -7,8 +7,8 @@ import (
"github.com/cometbft/cometbft/mempool"
coretypes "github.com/cometbft/cometbft/rpc/core/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1"
mockrpc "cosmossdk.io/client/v2/broadcast/comet/testutil"
@ -22,7 +22,7 @@ var cdc = testutil.CodecOptions{}.NewCodec()
func TestNewCometBftBroadcaster(t *testing.T) {
tests := []struct {
name string
cdc codec.JSONCodec
cdc codec.Codec
mode string
want *CometBFTBroadcaster
wantErr bool

View File

@ -1,5 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: client/v2/broadcast/comet/comet.go
//
// Generated by this command:
//
// mockgen -source=client/v2/broadcast/comet/comet.go -package testutil -destination client/v2/broadcast/comet/testutil/comet_mock.go
//
// Package testutil is a generated GoMock package.
package testutil
@ -12,13 +17,14 @@ import (
client "github.com/cometbft/cometbft/rpc/client"
coretypes "github.com/cometbft/cometbft/rpc/core/types"
types "github.com/cometbft/cometbft/types"
gomock "github.com/golang/mock/gomock"
gomock "go.uber.org/mock/gomock"
)
// MockCometRPC is a mock of CometRPC interface.
type MockCometRPC struct {
ctrl *gomock.Controller
recorder *MockCometRPCMockRecorder
isgomock struct{}
}
// MockCometRPCMockRecorder is the mock recorder for MockCometRPC.
@ -48,7 +54,7 @@ func (m *MockCometRPC) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo,
}
// ABCIInfo indicates an expected call of ABCIInfo.
func (mr *MockCometRPCMockRecorder) ABCIInfo(ctx interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) ABCIInfo(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ABCIInfo", reflect.TypeOf((*MockCometRPC)(nil).ABCIInfo), ctx)
}
@ -63,7 +69,7 @@ func (m *MockCometRPC) ABCIQuery(ctx context.Context, path string, data bytes.He
}
// ABCIQuery indicates an expected call of ABCIQuery.
func (mr *MockCometRPCMockRecorder) ABCIQuery(ctx, path, data interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) ABCIQuery(ctx, path, data any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ABCIQuery", reflect.TypeOf((*MockCometRPC)(nil).ABCIQuery), ctx, path, data)
}
@ -78,7 +84,7 @@ func (m *MockCometRPC) ABCIQueryWithOptions(ctx context.Context, path string, da
}
// ABCIQueryWithOptions indicates an expected call of ABCIQueryWithOptions.
func (mr *MockCometRPCMockRecorder) ABCIQueryWithOptions(ctx, path, data, opts interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) ABCIQueryWithOptions(ctx, path, data, opts any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ABCIQueryWithOptions", reflect.TypeOf((*MockCometRPC)(nil).ABCIQueryWithOptions), ctx, path, data, opts)
}
@ -93,7 +99,7 @@ func (m *MockCometRPC) Block(ctx context.Context, height *int64) (*coretypes.Res
}
// Block indicates an expected call of Block.
func (mr *MockCometRPCMockRecorder) Block(ctx, height interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) Block(ctx, height any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Block", reflect.TypeOf((*MockCometRPC)(nil).Block), ctx, height)
}
@ -108,7 +114,7 @@ func (m *MockCometRPC) BlockByHash(ctx context.Context, hash []byte) (*coretypes
}
// BlockByHash indicates an expected call of BlockByHash.
func (mr *MockCometRPCMockRecorder) BlockByHash(ctx, hash interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) BlockByHash(ctx, hash any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByHash", reflect.TypeOf((*MockCometRPC)(nil).BlockByHash), ctx, hash)
}
@ -123,7 +129,7 @@ func (m *MockCometRPC) BlockResults(ctx context.Context, height *int64) (*corety
}
// BlockResults indicates an expected call of BlockResults.
func (mr *MockCometRPCMockRecorder) BlockResults(ctx, height interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) BlockResults(ctx, height any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockResults", reflect.TypeOf((*MockCometRPC)(nil).BlockResults), ctx, height)
}
@ -138,7 +144,7 @@ func (m *MockCometRPC) BlockSearch(ctx context.Context, query string, page, perP
}
// BlockSearch indicates an expected call of BlockSearch.
func (mr *MockCometRPCMockRecorder) BlockSearch(ctx, query, page, perPage, orderBy interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) BlockSearch(ctx, query, page, perPage, orderBy any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockSearch", reflect.TypeOf((*MockCometRPC)(nil).BlockSearch), ctx, query, page, perPage, orderBy)
}
@ -153,7 +159,7 @@ func (m *MockCometRPC) BlockchainInfo(ctx context.Context, minHeight, maxHeight
}
// BlockchainInfo indicates an expected call of BlockchainInfo.
func (mr *MockCometRPCMockRecorder) BlockchainInfo(ctx, minHeight, maxHeight interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) BlockchainInfo(ctx, minHeight, maxHeight any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockchainInfo", reflect.TypeOf((*MockCometRPC)(nil).BlockchainInfo), ctx, minHeight, maxHeight)
}
@ -168,7 +174,7 @@ func (m *MockCometRPC) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*core
}
// BroadcastTxAsync indicates an expected call of BroadcastTxAsync.
func (mr *MockCometRPCMockRecorder) BroadcastTxAsync(ctx, tx interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) BroadcastTxAsync(ctx, tx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BroadcastTxAsync", reflect.TypeOf((*MockCometRPC)(nil).BroadcastTxAsync), ctx, tx)
}
@ -183,7 +189,7 @@ func (m *MockCometRPC) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*cor
}
// BroadcastTxCommit indicates an expected call of BroadcastTxCommit.
func (mr *MockCometRPCMockRecorder) BroadcastTxCommit(ctx, tx interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) BroadcastTxCommit(ctx, tx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BroadcastTxCommit", reflect.TypeOf((*MockCometRPC)(nil).BroadcastTxCommit), ctx, tx)
}
@ -198,7 +204,7 @@ func (m *MockCometRPC) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coret
}
// BroadcastTxSync indicates an expected call of BroadcastTxSync.
func (mr *MockCometRPCMockRecorder) BroadcastTxSync(ctx, tx interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) BroadcastTxSync(ctx, tx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BroadcastTxSync", reflect.TypeOf((*MockCometRPC)(nil).BroadcastTxSync), ctx, tx)
}
@ -213,7 +219,7 @@ func (m *MockCometRPC) Commit(ctx context.Context, height *int64) (*coretypes.Re
}
// Commit indicates an expected call of Commit.
func (mr *MockCometRPCMockRecorder) Commit(ctx, height interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) Commit(ctx, height any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockCometRPC)(nil).Commit), ctx, height)
}
@ -228,7 +234,7 @@ func (m *MockCometRPC) Status(arg0 context.Context) (*coretypes.ResultStatus, er
}
// Status indicates an expected call of Status.
func (mr *MockCometRPCMockRecorder) Status(arg0 interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) Status(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Status", reflect.TypeOf((*MockCometRPC)(nil).Status), arg0)
}
@ -243,7 +249,7 @@ func (m *MockCometRPC) Tx(ctx context.Context, hash []byte, prove bool) (*corety
}
// Tx indicates an expected call of Tx.
func (mr *MockCometRPCMockRecorder) Tx(ctx, hash, prove interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) Tx(ctx, hash, prove any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Tx", reflect.TypeOf((*MockCometRPC)(nil).Tx), ctx, hash, prove)
}
@ -258,7 +264,7 @@ func (m *MockCometRPC) TxSearch(ctx context.Context, query string, prove bool, p
}
// TxSearch indicates an expected call of TxSearch.
func (mr *MockCometRPCMockRecorder) TxSearch(ctx, query, prove, page, perPage, orderBy interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) TxSearch(ctx, query, prove, page, perPage, orderBy any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TxSearch", reflect.TypeOf((*MockCometRPC)(nil).TxSearch), ctx, query, prove, page, perPage, orderBy)
}
@ -273,7 +279,7 @@ func (m *MockCometRPC) Validators(ctx context.Context, height *int64, page, perP
}
// Validators indicates an expected call of Validators.
func (mr *MockCometRPCMockRecorder) Validators(ctx, height, page, perPage interface{}) *gomock.Call {
func (mr *MockCometRPCMockRecorder) Validators(ctx, height, page, perPage any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validators", reflect.TypeOf((*MockCometRPC)(nil).Validators), ctx, height, page, perPage)
}

View File

@ -0,0 +1,55 @@
package context
import (
gocontext "context"
"errors"
"github.com/spf13/pflag"
apisigning "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
"cosmossdk.io/client/v2/autocli/keyring"
"cosmossdk.io/core/address"
"github.com/cosmos/cosmos-sdk/codec"
)
// ContextKey is a key used to store and retrieve Context from a Go context.Context.
var ContextKey contextKey
// contextKey is an empty struct used as a key type for storing Context in a context.Context.
type contextKey struct{}
// Context represents the client context used in autocli commands.
// It contains various components needed for command execution.
type Context struct {
Flags *pflag.FlagSet
AddressCodec address.Codec
ValidatorAddressCodec address.ValidatorAddressCodec
ConsensusAddressCodec address.ConsensusAddressCodec
Cdc codec.Codec
Keyring keyring.Keyring
EnabledSignModes []apisigning.SignMode
}
// SetInContext stores the provided autocli.Context in the given Go context.Context.
// It returns a new context.Context containing the autocli.Context value.
func SetInContext(goCtx gocontext.Context, cliCtx Context) gocontext.Context {
return gocontext.WithValue(goCtx, ContextKey, cliCtx)
}
// ClientContextFromGoContext returns the autocli.Context from a given Go context.
// It checks if the context contains a valid autocli.Context and returns it.
func ClientContextFromGoContext(ctx gocontext.Context) (*Context, error) {
if c := ctx.Value(ContextKey); c != nil {
cliCtx, ok := c.(Context)
if !ok {
return nil, errors.New("context value is not of type autocli.Context")
}
return &cliCtx, nil
}
return nil, errors.New("context does not contain autocli.Context value")
}

View File

@ -13,6 +13,7 @@ require (
github.com/cosmos/cosmos-sdk v0.52.0
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
go.uber.org/mock v0.5.0
google.golang.org/grpc v1.68.1
google.golang.org/protobuf v1.35.2
gotest.tools/v3 v3.5.1
@ -35,10 +36,10 @@ require (
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/collections v0.4.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/core/testing v0.0.0-20241108153815-606544c7be7e // indirect
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/errors v1.0.1
cosmossdk.io/log v1.5.0
cosmossdk.io/math v1.4.0
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
@ -59,7 +60,7 @@ require (
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/cometbft/cometbft v1.0.0-rc2.0.20241127125717-4ce33b646ac9
github.com/cometbft/cometbft-db v1.0.1 // indirect
github.com/cometbft/cometbft/api v1.0.0-rc2 // indirect
github.com/cometbft/cometbft/api v1.0.0-rc2
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-db v1.1.0 // indirect
github.com/cosmos/go-bip39 v1.0.0
@ -85,7 +86,7 @@ require (
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.3 // indirect
@ -127,7 +128,7 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pelletier/go-toml/v2 v2.2.3
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
@ -145,7 +146,7 @@ require (
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/viper v1.19.0 // indirect
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.10.0
github.com/subosito/gotenv v1.6.0 // indirect
github.com/supranational/blst v0.3.13 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o=

View File

@ -16,20 +16,47 @@ var coinRegex = regexp.MustCompile(`^(\d+(\.\d+)?)([a-zA-Z][a-zA-Z0-9\/\:\._\-]{
// ParseCoin parses a coin from a string. The string must be in the format
// <amount><denom>, where <amount> is a number and <denom> is a valid denom.
func ParseCoin(input string) (*basev1beta1.Coin, error) {
amount, denom, err := parseCoin(input)
if err != nil {
return nil, err
}
return &basev1beta1.Coin{
Amount: amount,
Denom: denom,
}, nil
}
// ParseDecCoin parses a decCoin from a string. The string must be in the format
// <amount><denom>, where <amount> is a number and <denom> is a valid denom.
func ParseDecCoin(input string) (*basev1beta1.DecCoin, error) {
amount, denom, err := parseCoin(input)
if err != nil {
return nil, err
}
return &basev1beta1.DecCoin{
Amount: amount,
Denom: denom,
}, nil
}
// parseCoin parses a coin string into its amount and denom components.
// The input string must be in the format <amount><denom>.
// It returns the amount string, denom string, and any error encountered.
// Returns an error if the input is empty or doesn't match the expected format.
func parseCoin(input string) (amount, denom string, err error) {
input = strings.TrimSpace(input)
if input == "" {
return nil, errors.New("empty input when parsing coin")
return "", "", errors.New("empty input when parsing coin")
}
matches := coinRegex.FindStringSubmatch(input)
if len(matches) == 0 {
return nil, errors.New("invalid input format")
return "", "", errors.New("invalid input format")
}
return &basev1beta1.Coin{
Amount: matches[1],
Denom: matches[3],
}, nil
return matches[1], matches[3], nil
}

View File

@ -1,16 +1,72 @@
package coins_test
package coins
import (
"testing"
"github.com/stretchr/testify/require"
"cosmossdk.io/client/v2/internal/coins"
)
func TestDecodeCoin(t *testing.T) {
func Test_parseCoin(t *testing.T) {
tests := []struct {
name string
input string
amount string
denom string
err string
}{
{
name: "ok",
input: "1000stake",
amount: "1000",
denom: "stake",
},
{
name: "empty",
input: "",
err: "empty input when parsing coin",
},
{
name: "empty denom",
input: "1000",
err: "invalid input format",
},
{
name: "empty amount",
input: "stake",
err: "invalid input format",
},
{
name: "<denom><amount> format",
input: "stake1000",
err: "invalid input format",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
amount, denom, err := parseCoin(tt.input)
if tt.err != "" {
require.Error(t, err)
require.Contains(t, err.Error(), tt.err)
} else {
require.NoError(t, err)
require.Equal(t, tt.amount, amount)
require.Equal(t, tt.denom, denom)
}
})
}
}
func TestParseCoin(t *testing.T) {
encodedCoin := "1000000000foo"
coin, err := coins.ParseCoin(encodedCoin)
coin, err := ParseCoin(encodedCoin)
require.NoError(t, err)
require.Equal(t, "1000000000", coin.Amount)
require.Equal(t, "foo", coin.Denom)
}
func TestParseDecCoin(t *testing.T) {
encodedCoin := "1000000000foo"
coin, err := ParseDecCoin(encodedCoin)
require.NoError(t, err)
require.Equal(t, "1000000000", coin.Amount)
require.Equal(t, "foo", coin.Denom)

View File

@ -2,6 +2,12 @@ package flags
// This defines flag names that can be used in autocli.
const (
// FlagHome is the flag to specify the home dir of the app.
FlagHome = "home"
// FlagChainID is the flag to specify the chain ID of the network.
FlagChainID = "chain-id"
// FlagFrom is the flag to set the from address with which to sign the transaction.
FlagFrom = "from"
@ -14,9 +20,24 @@ const (
// FlagNoPrompt is the flag to not use a prompt for commands.
FlagNoPrompt = "no-prompt"
// FlagKeyringDir is the flag to specify the directory where the keyring is stored.
FlagKeyringDir = "keyring-dir"
// FlagKeyringBackend is the flag to specify which backend to use for the keyring (e.g. os, file, test).
FlagKeyringBackend = "keyring-backend"
// FlagNoProposal is the flag convert a gov proposal command into a normal command.
// This is used to allow user of chains with custom authority to not use gov submit proposals for usual proposal commands.
FlagNoProposal = "no-proposal"
// FlagNode is the flag to specify the node address to connect to.
FlagNode = "node"
// FlagBroadcastMode is the flag to specify the broadcast mode for transactions.
FlagBroadcastMode = "broadcast-mode"
// FlagGrpcAddress is the flag to specify the gRPC server address to connect to.
FlagGrpcAddress = "grpc-addr"
// FlagGrpcInsecure is the flag to allow insecure gRPC connections.
FlagGrpcInsecure = "grpc-insecure"
)
// List of supported output formats

View File

@ -0,0 +1,84 @@
package print
import (
"encoding/json"
"fmt"
"io"
"os"
"github.com/spf13/cobra"
"sigs.k8s.io/yaml"
"cosmossdk.io/client/v2/internal/flags"
)
const (
jsonOutput = flags.OutputFormatJSON
textOutput = flags.OutputFormatText
)
// Printer handles formatted output of different types of data
type Printer struct {
Output io.Writer
OutputFormat string
}
// NewPrinter creates a new Printer instance with default stdout
func NewPrinter(cmd *cobra.Command) (*Printer, error) {
outputFormat, err := cmd.Flags().GetString("output")
if err != nil {
return nil, err
}
if outputFormat != jsonOutput && outputFormat != textOutput {
return nil, fmt.Errorf("unsupported output format: %s", outputFormat)
}
return &Printer{
Output: cmd.OutOrStdout(),
OutputFormat: outputFormat,
}, nil
}
// PrintString prints the raw string
func (p *Printer) PrintString(str string) error {
return p.PrintBytes([]byte(str))
}
// PrintRaw prints raw JSON message without marshaling
func (p *Printer) PrintRaw(toPrint json.RawMessage) error {
return p.PrintBytes(toPrint)
}
// PrintBytes prints and formats bytes
func (p *Printer) PrintBytes(out []byte) error {
var err error
if p.OutputFormat == textOutput {
if !json.Valid(out) {
return fmt.Errorf("invalid JSON")
}
out, err = yaml.JSONToYAML(out)
if err != nil {
return err
}
}
writer := p.Output
if writer == nil {
writer = os.Stdout
}
_, err = writer.Write(out)
if err != nil {
return err
}
if p.OutputFormat != textOutput {
_, err = writer.Write([]byte("\n"))
if err != nil {
return err
}
}
return nil
}

View File

@ -4298,7 +4298,7 @@ var file_testpb_msg_proto_rawDesc = []byte{
0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x6c, 0x61, 0x77, 0x62,
0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0xca, 0xb4, 0x2d,
0x13, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x76, 0x30, 0x2e, 0x35,
0x32, 0x2e, 0x30, 0x20, 0x42, 0x86, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x65, 0x73,
0x33, 0x2e, 0x30, 0x20, 0x42, 0x86, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x65, 0x73,
0x74, 0x70, 0x62, 0x42, 0x08, 0x4d, 0x73, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d,
0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x63, 0x6c,

View File

@ -6,15 +6,24 @@ import (
"github.com/spf13/cobra"
"cosmossdk.io/client/v2/autocli/config"
"cosmossdk.io/client/v2/autocli/keyring"
"cosmossdk.io/client/v2/broadcast/comet"
clientcontext "cosmossdk.io/client/v2/context"
v2flags "cosmossdk.io/client/v2/internal/flags"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)
const (
flagEncoding = "encoding"
flagFileFormat = "file-format"
flagBech32 = "bech32"
)
// OffChain off-chain utilities.
@ -31,6 +40,7 @@ func OffChain() *cobra.Command {
)
flags.AddKeyringFlags(cmd.PersistentFlags())
cmd.PersistentFlags().String(flagBech32, "cosmos", "address bech32 prefix")
return cmd
}
@ -42,7 +52,19 @@ func SignFile() *cobra.Command {
Long: "Sign a file using a given key.",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
ir := types.NewInterfaceRegistry()
cryptocodec.RegisterInterfaces(ir)
cdc := codec.NewProtoCodec(ir)
c, err := config.CreateClientConfigFromFlags(cmd.Flags())
if err != nil {
return err
}
keyringBackend := c.KeyringBackend
if !cmd.Flags().Changed(v2flags.FlagKeyringBackend) {
_ = cmd.Flags().Set(v2flags.FlagKeyringBackend, keyringBackend)
}
bz, err := os.ReadFile(args[1])
if err != nil {
@ -53,8 +75,29 @@ func SignFile() *cobra.Command {
outputFormat, _ := cmd.Flags().GetString(v2flags.FlagOutput)
outputFile, _ := cmd.Flags().GetString(flags.FlagOutputDocument)
signMode, _ := cmd.Flags().GetString(flags.FlagSignMode)
bech32Prefix, _ := cmd.Flags().GetString(flagBech32)
signedTx, err := Sign(clientCtx, bz, args[0], encoding, signMode, outputFormat)
ac := address.NewBech32Codec(bech32Prefix)
k, err := keyring.NewKeyringFromFlags(cmd.Flags(), ac, cmd.InOrStdin(), cdc)
if err != nil {
return err
}
// off-chain does not need to query any information
conn, err := comet.NewCometBFTBroadcaster("", comet.BroadcastSync, cdc)
if err != nil {
return err
}
ctx := clientcontext.Context{
Flags: cmd.Flags(),
AddressCodec: ac,
ValidatorAddressCodec: address.NewBech32Codec(sdk.GetBech32PrefixValAddr(bech32Prefix)),
Cdc: cdc,
Keyring: k,
}
signedTx, err := Sign(ctx, bz, conn, args[0], encoding, signMode, outputFormat)
if err != nil {
return err
}
@ -87,10 +130,8 @@ func VerifyFile() *cobra.Command {
Long: "Verify a previously signed file with the given key.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
ir := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(ir)
bz, err := os.ReadFile(args[0])
if err != nil {
@ -98,8 +139,18 @@ func VerifyFile() *cobra.Command {
}
fileFormat, _ := cmd.Flags().GetString(flagFileFormat)
bech32Prefix, _ := cmd.Flags().GetString(flagBech32)
err = Verify(clientCtx, bz, fileFormat)
ac := address.NewBech32Codec(bech32Prefix)
ctx := clientcontext.Context{
Flags: cmd.Flags(),
AddressCodec: ac,
ValidatorAddressCodec: address.NewBech32Codec(sdk.GetBech32PrefixValAddr(bech32Prefix)),
Cdc: cdc,
}
err = Verify(ctx, bz, fileFormat)
if err == nil {
cmd.Println("Verification OK!")
}

View File

@ -2,32 +2,17 @@ package offchain
import (
"context"
"testing"
"errors"
"github.com/stretchr/testify/require"
gogogrpc "github.com/cosmos/gogoproto/grpc"
"google.golang.org/grpc"
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
"cosmossdk.io/x/tx/signing"
"cosmossdk.io/x/tx/signing/aminojson"
"cosmossdk.io/x/tx/signing/direct"
"cosmossdk.io/x/tx/signing/directaux"
"cosmossdk.io/x/tx/signing/textual"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/testutil"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
)
const (
addressCodecPrefix = "cosmos"
validatorAddressCodecPrefix = "cosmosvaloper"
mnemonic = "have embark stumble card pistol fun gauge obtain forget oil awesome lottery unfold corn sure original exist siren pudding spread uphold dwarf goddess card"
)
const mnemonic = "have embark stumble card pistol fun gauge obtain forget oil awesome lottery unfold corn sure original exist siren pudding spread uphold dwarf goddess card"
func getCodec() codec.Codec {
registry := testutil.CodecOptions{}.NewInterfaceRegistry()
@ -36,111 +21,14 @@ func getCodec() codec.Codec {
return codec.NewProtoCodec(registry)
}
func newGRPCCoinMetadataQueryFn(grpcConn grpc.ClientConnInterface) textual.CoinMetadataQueryFn {
return func(ctx context.Context, denom string) (*bankv1beta1.Metadata, error) {
bankQueryClient := bankv1beta1.NewQueryClient(grpcConn)
res, err := bankQueryClient.DenomMetadata(ctx, &bankv1beta1.QueryDenomMetadataRequest{
Denom: denom,
})
if err != nil {
return nil, err
}
var _ gogogrpc.ClientConn = mockClientConn{}
return res.Metadata, nil
}
type mockClientConn struct{}
func (c mockClientConn) Invoke(_ context.Context, _ string, _, _ interface{}, _ ...grpc.CallOption) error {
return errors.New("not implemented")
}
// testConfig fulfills client.TxConfig although SignModeHandler is the only method implemented.
type testConfig struct {
handler *signing.HandlerMap
}
func (t testConfig) SignModeHandler() *signing.HandlerMap {
return t.handler
}
func (t testConfig) TxEncoder() sdk.TxEncoder {
return nil
}
func (t testConfig) TxDecoder() sdk.TxDecoder {
return nil
}
func (t testConfig) TxJSONEncoder() sdk.TxEncoder {
return nil
}
func (t testConfig) TxJSONDecoder() sdk.TxDecoder {
return nil
}
func (t testConfig) MarshalSignatureJSON(v2s []signingtypes.SignatureV2) ([]byte, error) {
return nil, nil
}
func (t testConfig) UnmarshalSignatureJSON(bytes []byte) ([]signingtypes.SignatureV2, error) {
return nil, nil
}
func (t testConfig) NewTxBuilder() client.TxBuilder {
return nil
}
func (t testConfig) WrapTxBuilder(s sdk.Tx) (client.TxBuilder, error) {
return nil, nil
}
func (t testConfig) SigningContext() *signing.Context {
return nil
}
func newTestConfig(t *testing.T) *testConfig {
t.Helper()
enabledSignModes := []signingtypes.SignMode{
signingtypes.SignMode_SIGN_MODE_DIRECT,
signingtypes.SignMode_SIGN_MODE_DIRECT_AUX,
signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
signingtypes.SignMode_SIGN_MODE_TEXTUAL,
}
var err error
signingOptions := signing.Options{
AddressCodec: address.NewBech32Codec(addressCodecPrefix),
ValidatorAddressCodec: address.NewBech32Codec(validatorAddressCodecPrefix),
}
signingContext, err := signing.NewContext(signingOptions)
require.NoError(t, err)
lenSignModes := len(enabledSignModes)
handlers := make([]signing.SignModeHandler, lenSignModes)
for i, m := range enabledSignModes {
var err error
switch m {
case signingtypes.SignMode_SIGN_MODE_DIRECT:
handlers[i] = &direct.SignModeHandler{}
case signingtypes.SignMode_SIGN_MODE_DIRECT_AUX:
handlers[i], err = directaux.NewSignModeHandler(directaux.SignModeHandlerOptions{
TypeResolver: signingOptions.TypeResolver,
SignersContext: signingContext,
})
require.NoError(t, err)
case signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON:
handlers[i] = aminojson.NewSignModeHandler(aminojson.SignModeHandlerOptions{
FileResolver: signingOptions.FileResolver,
TypeResolver: signingOptions.TypeResolver,
})
case signingtypes.SignMode_SIGN_MODE_TEXTUAL:
handlers[i], err = textual.NewSignModeHandler(textual.SignModeOptions{
CoinMetadataQuerier: newGRPCCoinMetadataQueryFn(client.Context{}),
FileResolver: signingOptions.FileResolver,
TypeResolver: signingOptions.TypeResolver,
})
require.NoError(t, err)
}
}
handler := signing.NewHandlerMap(handlers...)
return &testConfig{handler: handler}
func (c mockClientConn) NewStream(_ context.Context, _ *grpc.StreamDesc, _ string, _ ...grpc.CallOption) (grpc.ClientStream, error) {
return nil, errors.New("not implemented")
}

View File

@ -4,13 +4,14 @@ import (
"context"
"fmt"
gogogrpc "github.com/cosmos/gogoproto/grpc"
apisigning "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
clientcontext "cosmossdk.io/client/v2/context"
"cosmossdk.io/client/v2/internal/account"
"cosmossdk.io/client/v2/internal/offchain"
clitx "cosmossdk.io/client/v2/tx"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/version"
)
@ -29,20 +30,20 @@ var enabledSignModes = []apisigning.SignMode{
}
// Sign signs given bytes using the specified encoder and SignMode.
func Sign(ctx client.Context, rawBytes []byte, fromName, encoding, signMode, output string) (string, error) {
func Sign(
ctx clientcontext.Context,
rawBytes []byte,
conn gogogrpc.ClientConn,
fromName, encoding, signMode, output string,
) (string, error) {
digest, err := encodeDigest(encoding, rawBytes)
if err != nil {
return "", err
}
keybase, err := keyring.NewAutoCLIKeyring(ctx.Keyring, ctx.AddressCodec)
if err != nil {
return "", err
}
txConfig, err := clitx.NewTxConfig(clitx.ConfigOptions{
AddressCodec: ctx.AddressCodec,
Cdc: ctx.Codec,
Cdc: ctx.Cdc,
ValidatorAddressCodec: ctx.ValidatorAddressCodec,
EnabledSignModes: enabledSignModes,
})
@ -50,7 +51,7 @@ func Sign(ctx client.Context, rawBytes []byte, fromName, encoding, signMode, out
return "", err
}
accRetriever := account.NewAccountRetriever(ctx.AddressCodec, ctx, ctx.InterfaceRegistry)
accRetriever := account.NewAccountRetriever(ctx.AddressCodec, conn, ctx.Cdc.InterfaceRegistry())
sm, err := getSignMode(signMode)
if err != nil {
@ -66,12 +67,12 @@ func Sign(ctx client.Context, rawBytes []byte, fromName, encoding, signMode, out
},
}
txf, err := clitx.NewFactory(keybase, ctx.Codec, accRetriever, txConfig, ctx.AddressCodec, ctx, params)
txf, err := clitx.NewFactory(ctx.Keyring, ctx.Cdc, accRetriever, txConfig, ctx.AddressCodec, conn, params)
if err != nil {
return "", err
}
pubKey, err := keybase.GetPubKey(fromName)
pubKey, err := ctx.Keyring.GetPubKey(fromName)
if err != nil {
return "", err
}

View File

@ -5,23 +5,28 @@ import (
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/client"
clientcontext "cosmossdk.io/client/v2/context"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
)
func TestSign(t *testing.T) {
ac := address.NewBech32Codec("cosmos")
vc := address.NewBech32Codec("cosmosvaloper")
k := keyring.NewInMemory(getCodec())
_, err := k.NewAccount("signVerify", mnemonic, "", "m/44'/118'/0'/0/0", hd.Secp256k1)
require.NoError(t, err)
ctx := client.Context{
TxConfig: newTestConfig(t),
Codec: getCodec(),
AddressCodec: address.NewBech32Codec("cosmos"),
ValidatorAddressCodec: address.NewBech32Codec("cosmosvaloper"),
Keyring: k,
autoKeyring, err := keyring.NewAutoCLIKeyring(k, ac)
require.NoError(t, err)
ctx := clientcontext.Context{
AddressCodec: ac,
ValidatorAddressCodec: vc,
Cdc: getCodec(),
Keyring: autoKeyring,
}
tests := []struct {
name string
@ -52,7 +57,7 @@ func TestSign(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Sign(ctx, tt.rawBytes, "signVerify", tt.encoding, tt.signMode, "json")
got, err := Sign(ctx, tt.rawBytes, mockClientConn{}, "signVerify", tt.encoding, tt.signMode, "json")
if tt.wantErr {
require.Error(t, err)
} else {

View File

@ -8,19 +8,20 @@ import (
"google.golang.org/protobuf/types/known/anypb"
clientcontext "cosmossdk.io/client/v2/context"
clitx "cosmossdk.io/client/v2/tx"
"cosmossdk.io/core/address"
txsigning "cosmossdk.io/x/tx/signing"
"github.com/cosmos/cosmos-sdk/client"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
)
// Verify verifies a digest after unmarshalling it.
func Verify(ctx client.Context, digest []byte, fileFormat string) error {
func Verify(ctx clientcontext.Context, digest []byte, fileFormat string) error {
txConfig, err := clitx.NewTxConfig(clitx.ConfigOptions{
AddressCodec: ctx.AddressCodec,
Cdc: ctx.Codec,
Cdc: ctx.Cdc,
ValidatorAddressCodec: ctx.ValidatorAddressCodec,
EnabledSignModes: enabledSignModes,
})
@ -33,12 +34,12 @@ func Verify(ctx client.Context, digest []byte, fileFormat string) error {
return err
}
return verify(ctx, dTx)
return verify(ctx.AddressCodec, txConfig, dTx)
}
// verify verifies given Tx.
func verify(ctx client.Context, dTx clitx.Tx) error {
signModeHandler := ctx.TxConfig.SignModeHandler()
func verify(addressCodec address.Codec, txConfig clitx.TxConfig, dTx clitx.Tx) error {
signModeHandler := txConfig.SignModeHandler()
signers, err := dTx.GetSigners()
if err != nil {
@ -60,7 +61,7 @@ func verify(ctx client.Context, dTx clitx.Tx) error {
return errors.New("signature does not match its respective signer")
}
addr, err := ctx.AddressCodec.BytesToString(pubKey.Address())
addr, err := addressCodec.BytesToString(pubKey.Address())
if err != nil {
return err
}

View File

@ -6,59 +6,53 @@ import (
"github.com/stretchr/testify/require"
_ "cosmossdk.io/api/cosmos/crypto/secp256k1"
clientcontext "cosmossdk.io/client/v2/context"
clitx "cosmossdk.io/client/v2/tx"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
)
func Test_Verify(t *testing.T) {
ctx := client.Context{
TxConfig: newTestConfig(t),
Codec: getCodec(),
ctx := clientcontext.Context{
AddressCodec: address.NewBech32Codec("cosmos"),
ValidatorAddressCodec: address.NewBech32Codec("cosmosvaloper"),
Cdc: getCodec(),
}
tests := []struct {
name string
digest []byte
fileFormat string
ctx client.Context
wantErr bool
}{
{
name: "verify json",
digest: []byte("{\"body\":{\"messages\":[{\"@type\":\"/offchain.MsgSignArbitraryData\", \"app_domain\":\"<appd>\", \"signer\":\"cosmos16877zjk85kwlap3wclpmx34e0xllg2erc7u7m4\", \"data\":\"{\\n\\t\\\"name\\\": \\\"Sarah\\\",\\n\\t\\\"surname\\\": \\\"Connor\\\",\\n\\t\\\"age\\\": 29\\n}\\n\"}], \"timeout_timestamp\":\"0001-01-01T00:00:00Z\"}, \"auth_info\":{\"signer_infos\":[{\"public_key\":{\"@type\":\"/cosmos.crypto.secp256k1.PubKey\", \"key\":\"Ahhu3idSSUAQXtDBvBjUlCPWH3od4rXyWgb7L4scSj4m\"}, \"mode_info\":{\"single\":{\"mode\":\"SIGN_MODE_DIRECT\"}}}], \"fee\":{}}, \"signatures\":[\"tdXsO5uNqIBFSBKEA1e3Wrcb6ejriP9HwlcBTkU7EUJzuezjg6Rvr1a+Kp6umCAN7MWoBHRT2cmqzDfg6RjaYA==\"]}"),
fileFormat: "json",
ctx: ctx,
},
{
name: "wrong signer json",
digest: []byte("{\"body\":{\"messages\":[{\"@type\":\"/offchain.MsgSignArbitraryData\", \"app_domain\":\"<appd>\", \"signer\":\"cosmos1xv9e39mkhhyg5aneu2myj82t7029sv48qu3pgj\", \"data\":\"{\\n\\t\\\"name\\\": \\\"Sarah\\\",\\n\\t\\\"surname\\\": \\\"Connor\\\",\\n\\t\\\"age\\\": 29\\n}\\n\"}], \"timeout_timestamp\":\"0001-01-01T00:00:00Z\"}, \"auth_info\":{\"signer_infos\":[{\"public_key\":{\"@type\":\"/cosmos.crypto.secp256k1.PubKey\", \"key\":\"Ahhu3idSSUAQXtDBvBjUlCPWH3od4rXyWgb7L4scSj4m\"}, \"mode_info\":{\"single\":{\"mode\":\"SIGN_MODE_DIRECT\"}}}], \"fee\":{}}, \"signatures\":[\"tdXsO5uNqIBFSBKEA1e3Wrcb6ejriP9HwlcBTkU7EUJzuezjg6Rvr1a+Kp6umCAN7MWoBHRT2cmqzDfg6RjaYA==\"]}"),
fileFormat: "json",
ctx: ctx,
wantErr: true,
},
{
name: "verify text",
digest: []byte("body:{messages:{[/offchain.MsgSignArbitraryData]:{app_domain:\"<appd>\" signer:\"cosmos16877zjk85kwlap3wclpmx34e0xllg2erc7u7m4\" data:\"{\\n\\t\\\"name\\\": \\\"Sarah\\\",\\n\\t\\\"surname\\\": \\\"Connor\\\",\\n\\t\\\"age\\\": 29\\n}\\n\"}} timeout_timestamp:{seconds:-62135596800}} auth_info:{signer_infos:{public_key:{[/cosmos.crypto.secp256k1.PubKey]:{key:\"\\x02\\x18n\\xde'RI@\\x10^\\xd0\\xc1\\xbc\\x18Ԕ#\\xd6\\x1fz\\x1d\\xe2\\xb5\\xf2Z\\x06\\xfb/\\x8b\\x1cJ>&\"}} mode_info:{single:{mode:SIGN_MODE_DIRECT}}} fee:{}} signatures:\"\\xb5\\xd5\\xec;\\x9b\\x8d\\xa8\\x80EH\\x12\\x84\\x03W\\xb7Z\\xb7\\x1b\\xe9\\xe8\\xeb\\x88\\xffG\\xc2W\\x01NE;\\x11Bs\\xb9\\xecヤo\\xafV\\xbe*\\x9e\\xae\\x98 \\r\\xecŨ\\x04tS\\xd9ɪ\\xcc7\\xe0\\xe9\\x18\\xda`\"\n"),
fileFormat: "text",
ctx: ctx,
},
{
name: "wrong signer text",
digest: []byte("body:{messages:{[/offchain.MsgSignArbitraryData]:{app_domain:\"<appd>\" signer:\"cosmos1xv9e39mkhhyg5aneu2myj82t7029sv48qu3pgj\" data:\"{\\n\\t\\\"name\\\": \\\"Sarah\\\",\\n\\t\\\"surname\\\": \\\"Connor\\\",\\n\\t\\\"age\\\": 29\\n}\\n\"}} timeout_timestamp:{seconds:-62135596800}} auth_info:{signer_infos:{public_key:{[/cosmos.crypto.secp256k1.PubKey]:{key:\"\\x02\\x18n\\xde'RI@\\x10^\\xd0\\xc1\\xbc\\x18Ԕ#\\xd6\\x1fz\\x1d\\xe2\\xb5\\xf2Z\\x06\\xfb/\\x8b\\x1cJ>&\"}} mode_info:{single:{mode:SIGN_MODE_DIRECT}}} fee:{}} signatures:\"\\xb5\\xd5\\xec;\\x9b\\x8d\\xa8\\x80EH\\x12\\x84\\x03W\\xb7Z\\xb7\\x1b\\xe9\\xe8\\xeb\\x88\\xffG\\xc2W\\x01NE;\\x11Bs\\xb9\\xecヤo\\xafV\\xbe*\\x9e\\xae\\x98 \\r\\xecŨ\\x04tS\\xd9ɪ\\xcc7\\xe0\\xe9\\x18\\xda`\"\n"),
fileFormat: "text",
ctx: ctx,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := Verify(tt.ctx, tt.digest, tt.fileFormat)
err := Verify(ctx, tt.digest, tt.fileFormat)
if tt.wantErr {
require.Error(t, err)
} else {
@ -69,19 +63,23 @@ func Test_Verify(t *testing.T) {
}
func Test_SignVerify(t *testing.T) {
ac := address.NewBech32Codec("cosmos")
k := keyring.NewInMemory(getCodec())
_, err := k.NewAccount("signVerify", mnemonic, "", "m/44'/118'/0'/0/0", hd.Secp256k1)
require.NoError(t, err)
ctx := client.Context{
TxConfig: newTestConfig(t),
Codec: getCodec(),
autoKeyring, err := keyring.NewAutoCLIKeyring(k, ac)
require.NoError(t, err)
ctx := clientcontext.Context{
AddressCodec: address.NewBech32Codec("cosmos"),
ValidatorAddressCodec: address.NewBech32Codec("cosmosvaloper"),
Keyring: k,
Cdc: getCodec(),
Keyring: autoKeyring,
}
tx, err := Sign(ctx, []byte("Hello World!"), "signVerify", "no-encoding", "direct", "json")
tx, err := Sign(ctx, []byte("Hello World!"), mockClientConn{}, "signVerify", "no-encoding", "direct", "json")
require.NoError(t, err)
err = Verify(ctx, []byte(tx), "json")

View File

@ -19,9 +19,10 @@ var (
// jsonMarshalOptions configures JSON marshaling for protobuf messages.
jsonMarshalOptions = protojson.MarshalOptions{
Indent: "",
UseProtoNames: true,
UseEnumNumbers: false,
Indent: "",
UseProtoNames: true,
UseEnumNumbers: false,
EmitUnpopulated: true,
}
// textMarshalOptions

View File

@ -44,7 +44,7 @@ type Factory struct {
txConfig TxConfig
txParams TxParameters
tx txState
tx *txState
}
func NewFactoryFromFlagSet(flags *pflag.FlagSet, keybase keyring.Keyring, cdc codec.BinaryCodec, accRetriever account.AccountRetriever,
@ -81,38 +81,37 @@ func NewFactory(keybase keyring.Keyring, cdc codec.BinaryCodec, accRetriever acc
txConfig: txConfig,
txParams: parameters,
tx: txState{},
tx: &txState{},
}, nil
}
// validateFlagSet checks the provided flags for consistency and requirements based on the operation mode.
func validateFlagSet(flags *pflag.FlagSet, offline bool) error {
dryRun, _ := flags.GetBool(flags2.FlagDryRun)
if offline && dryRun {
return errors.New("dry-run: cannot use offline mode")
}
generateOnly, _ := flags.GetBool(flags2.FlagGenerateOnly)
chainID, _ := flags.GetString(flags2.FlagChainID)
if offline {
if !flags.Changed(flags2.FlagAccountNumber) || !flags.Changed(flags2.FlagSequence) {
if !generateOnly && (!flags.Changed(flags2.FlagAccountNumber) || !flags.Changed(flags2.FlagSequence)) {
return errors.New("account-number and sequence must be set in offline mode")
}
if generateOnly && chainID != "" {
return errors.New("chain ID cannot be used when offline and generate-only flags are set")
}
gas, _ := flags.GetString(flags2.FlagGas)
gasSetting, _ := flags2.ParseGasSetting(gas)
if gasSetting.Simulate {
return errors.New("simulate and offline flags cannot be set at the same time")
}
}
generateOnly, _ := flags.GetBool(flags2.FlagGenerateOnly)
chainID, _ := flags.GetString(flags2.FlagChainID)
if offline && generateOnly && chainID != "" {
return errors.New("chain ID cannot be used when offline and generate-only flags are set")
}
if chainID == "" {
} else if chainID == "" {
return errors.New("chain ID required but not specified")
}
dryRun, _ := flags.GetBool(flags2.FlagDryRun)
if offline && dryRun {
return errors.New("dry-run: cannot use offline mode")
}
return nil
}

View File

@ -10,23 +10,23 @@ const (
defaultGasLimit = 200000
gasFlagAuto = "auto"
flagTimeoutTimestamp = "timeout-timestamp"
flagChainID = "chain-id"
flagNote = "note"
flagSignMode = "sign-mode"
flagAccountNumber = "account-number"
flagSequence = "sequence"
flagFrom = "from"
flagDryRun = "dry-run"
flagGas = "gas"
flagGasAdjustment = "gas-adjustment"
flagGasPrices = "gas-prices"
flagFees = "fees"
flagFeePayer = "fee-payer"
flagFeeGranter = "fee-granter"
flagUnordered = "unordered"
flagOffline = "offline"
flagGenerateOnly = "generate-only"
FlagTimeoutTimestamp = "timeout-timestamp"
FlagChainID = "chain-id"
FlagNote = "note"
FlagSignMode = "sign-mode"
FlagAccountNumber = "account-number"
FlagSequence = "sequence"
FlagFrom = "from"
FlagDryRun = "dry-run"
FlagGas = "gas"
FlagGasAdjustment = "gas-adjustment"
FlagGasPrices = "gas-prices"
FlagFees = "fees"
FlagFeePayer = "fee-payer"
FlagFeeGranter = "fee-granter"
FlagUnordered = "unordered"
FlagOffline = "offline"
FlagGenerateOnly = "generate-only"
)
// parseGasSetting parses a string gas value. The value may either be 'auto',

View File

@ -1,91 +1,165 @@
package tx
import (
"bufio"
"context"
"errors"
"fmt"
"os"
"github.com/cosmos/gogoproto/grpc"
"github.com/cosmos/gogoproto/proto"
"github.com/spf13/pflag"
apitxsigning "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
"cosmossdk.io/client/v2/broadcast"
"cosmossdk.io/client/v2/broadcast/comet"
clientcontext "cosmossdk.io/client/v2/context"
"cosmossdk.io/client/v2/internal/account"
"cosmossdk.io/client/v2/internal/flags"
"cosmossdk.io/core/transaction"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/codec"
)
// GenerateOrBroadcastTxCLIWithBroadcaster will either generate and print an unsigned transaction
// GenerateAndBroadcastTxCLIWithBroadcaster will either generate and print an unsigned transaction
// or sign it and broadcast it with the specified broadcaster returning an error upon failure.
func GenerateOrBroadcastTxCLIWithBroadcaster(ctx client.Context, flagSet *pflag.FlagSet, broadcaster broadcast.Broadcaster, msgs ...transaction.Msg) error {
if err := validateMessages(msgs...); err != nil {
return err
}
txf, err := newFactory(ctx, flagSet)
func GenerateAndBroadcastTxCLIWithBroadcaster(
ctx context.Context,
conn grpc.ClientConn,
broadcaster broadcast.Broadcaster,
msgs ...transaction.Msg,
) ([]byte, error) {
txf, err := initFactory(ctx, conn, msgs...)
if err != nil {
return err
return nil, err
}
genOnly, _ := flagSet.GetBool(flagGenerateOnly)
if genOnly {
return generateOnly(ctx, txf, msgs...)
err = generateTx(txf, msgs...)
if err != nil {
return nil, err
}
isDryRun, _ := flagSet.GetBool(flagDryRun)
if isDryRun {
return dryRun(txf, msgs...)
}
return BroadcastTx(ctx, txf, broadcaster, msgs...)
return BroadcastTx(ctx, txf, broadcaster)
}
// GenerateOrBroadcastTxCLI will either generate and print an unsigned transaction
// GenerateAndBroadcastTxCLI will either generate and print an unsigned transaction
// or sign it and broadcast it using default CometBFT broadcaster, returning an error upon failure.
func GenerateOrBroadcastTxCLI(ctx client.Context, flagSet *pflag.FlagSet, msgs ...transaction.Msg) error {
cometBroadcaster, err := getCometBroadcaster(ctx, flagSet)
func GenerateAndBroadcastTxCLI(ctx context.Context, conn grpc.ClientConn, msgs ...transaction.Msg) ([]byte, error) {
cBroadcaster, err := cometBroadcaster(ctx)
if err != nil {
return err
return nil, err
}
return GenerateOrBroadcastTxCLIWithBroadcaster(ctx, flagSet, cometBroadcaster, msgs...)
return GenerateAndBroadcastTxCLIWithBroadcaster(ctx, conn, cBroadcaster, msgs...)
}
// GenerateAndBroadcastTxCLIWithPrompt generates, signs and broadcasts a transaction after prompting the user for confirmation.
// It takes a context, gRPC client connection, prompt function for user confirmation, and transaction messages.
// The prompt function receives the unsigned transaction bytes and returns a boolean indicating user confirmation and any error.
// Returns the broadcast response bytes and any error encountered.
func GenerateAndBroadcastTxCLIWithPrompt(
ctx context.Context,
conn grpc.ClientConn,
prompt func([]byte) (bool, error),
msgs ...transaction.Msg,
) ([]byte, error) {
txf, err := initFactory(ctx, conn, msgs...)
if err != nil {
return nil, err
}
err = generateTx(txf, msgs...)
if err != nil {
return nil, err
}
confirmed, err := askConfirmation(txf, prompt)
if err != nil {
return nil, err
}
if !confirmed {
return nil, nil
}
cBroadcaster, err := cometBroadcaster(ctx)
if err != nil {
return nil, err
}
return BroadcastTx(ctx, txf, cBroadcaster)
}
// GenerateOnly generates an unsigned transaction without broadcasting it.
// It initializes a transaction factory using the provided context, connection and messages,
// then generates an unsigned transaction.
// Returns the unsigned transaction bytes and any error encountered.
func GenerateOnly(ctx context.Context, conn grpc.ClientConn, msgs ...transaction.Msg) ([]byte, error) {
txf, err := initFactory(ctx, conn)
if err != nil {
return nil, err
}
return generateOnly(txf, msgs...)
}
// DryRun simulates a transaction without broadcasting it to the network.
// It initializes a transaction factory using the provided context, connection and messages,
// then performs a dry run simulation of the transaction.
// Returns the simulation response bytes and any error encountered.
func DryRun(ctx context.Context, conn grpc.ClientConn, msgs ...transaction.Msg) ([]byte, error) {
txf, err := initFactory(ctx, conn, msgs...)
if err != nil {
return nil, err
}
return dryRun(txf, msgs...)
}
// initFactory initializes a new transaction Factory and validates the provided messages.
// It retrieves the client v2 context from the provided context, validates all messages,
// and creates a new transaction Factory using the client context and connection.
// Returns the initialized Factory and any error encountered.
func initFactory(ctx context.Context, conn grpc.ClientConn, msgs ...transaction.Msg) (Factory, error) {
clientCtx, err := clientcontext.ClientContextFromGoContext(ctx)
if err != nil {
return Factory{}, err
}
if err := validateMessages(msgs...); err != nil {
return Factory{}, err
}
txf, err := newFactory(*clientCtx, conn)
if err != nil {
return Factory{}, err
}
return txf, nil
}
// getCometBroadcaster returns a new CometBFT broadcaster based on the provided context and flag set.
func getCometBroadcaster(ctx client.Context, flagSet *pflag.FlagSet) (broadcast.Broadcaster, error) {
url, _ := flagSet.GetString("node")
mode, _ := flagSet.GetString("broadcast-mode")
return comet.NewCometBFTBroadcaster(url, mode, ctx.Codec)
func getCometBroadcaster(cdc codec.Codec, flagSet *pflag.FlagSet) (broadcast.Broadcaster, error) {
url, _ := flagSet.GetString(flags.FlagNode)
mode, _ := flagSet.GetString(flags.FlagBroadcastMode)
return comet.NewCometBFTBroadcaster(url, mode, cdc)
}
// newFactory creates a new transaction Factory based on the provided context and flag set.
// It initializes a new CLI keyring, extracts transaction parameters from the flag set,
// configures transaction settings, and sets up an account retriever for the transaction Factory.
func newFactory(ctx client.Context, flagSet *pflag.FlagSet) (Factory, error) {
k, err := keyring.NewAutoCLIKeyring(ctx.Keyring, ctx.AddressCodec)
if err != nil {
return Factory{}, err
}
func newFactory(ctx clientcontext.Context, conn grpc.ClientConn) (Factory, error) {
txConfig, err := NewTxConfig(ConfigOptions{
AddressCodec: ctx.AddressCodec,
Cdc: ctx.Codec,
Cdc: ctx.Cdc,
ValidatorAddressCodec: ctx.ValidatorAddressCodec,
EnabledSignModes: ctx.TxConfig.SignModeHandler().SupportedModes(),
EnabledSignModes: ctx.EnabledSignModes,
})
if err != nil {
return Factory{}, err
}
accRetriever := account.NewAccountRetriever(ctx.AddressCodec, ctx, ctx.InterfaceRegistry)
accRetriever := account.NewAccountRetriever(ctx.AddressCodec, conn, ctx.Cdc.InterfaceRegistry())
txf, err := NewFactoryFromFlagSet(flagSet, k, ctx.Codec, accRetriever, txConfig, ctx.AddressCodec, ctx)
txf, err := NewFactoryFromFlagSet(ctx.Flags, ctx.Keyring, ctx.Cdc, accRetriever, txConfig, ctx.AddressCodec, conn)
if err != nil {
return Factory{}, err
}
@ -115,30 +189,29 @@ func validateMessages(msgs ...transaction.Msg) error {
// generateOnly prepares the transaction and prints the unsigned transaction string.
// It first calls Prepare on the transaction factory to set up any necessary pre-conditions.
// If preparation is successful, it generates an unsigned transaction string using the provided messages.
func generateOnly(ctx client.Context, txf Factory, msgs ...transaction.Msg) error {
func generateOnly(txf Factory, msgs ...transaction.Msg) ([]byte, error) {
uTx, err := txf.UnsignedTxString(msgs...)
if err != nil {
return err
return nil, err
}
return ctx.PrintString(uTx)
return []byte(uTx), nil
}
// dryRun performs a dry run of the transaction to estimate the gas required.
// It prepares the transaction factory and simulates the transaction with the provided messages.
func dryRun(txf Factory, msgs ...transaction.Msg) error {
func dryRun(txf Factory, msgs ...transaction.Msg) ([]byte, error) {
_, gas, err := txf.Simulate(msgs...)
if err != nil {
return err
return nil, err
}
_, err = fmt.Fprintf(os.Stderr, "%s\n", GasEstimateResponse{GasEstimate: gas})
return err
return []byte(fmt.Sprintf(`{"gas_estimate": %d}`, gas)), nil
}
// SimulateTx simulates a tx and returns the simulation response obtained by the query.
func SimulateTx(ctx client.Context, flagSet *pflag.FlagSet, msgs ...transaction.Msg) (proto.Message, error) {
txf, err := newFactory(ctx, flagSet)
func SimulateTx(ctx clientcontext.Context, conn grpc.ClientConn, msgs ...transaction.Msg) (proto.Message, error) {
txf, err := newFactory(ctx, conn)
if err != nil {
return nil, err
}
@ -147,10 +220,10 @@ func SimulateTx(ctx client.Context, flagSet *pflag.FlagSet, msgs ...transaction.
return simulation, err
}
// BroadcastTx attempts to generate, sign and broadcast a transaction with the
// given set of messages. It will also simulate gas requirements if necessary.
// It will return an error upon failure.
func BroadcastTx(clientCtx client.Context, txf Factory, broadcaster broadcast.Broadcaster, msgs ...transaction.Msg) error {
// generateTx generates an unsigned transaction using the provided transaction factory and messages.
// If simulation and execution are enabled, it first calculates the gas requirements.
// It then builds the unsigned transaction with the provided messages.
func generateTx(txf Factory, msgs ...transaction.Msg) error {
if txf.simulateAndExecute() {
err := txf.calculateGas(msgs...)
if err != nil {
@ -158,58 +231,29 @@ func BroadcastTx(clientCtx client.Context, txf Factory, broadcaster broadcast.Br
}
}
err := txf.BuildUnsignedTx(msgs...)
if err != nil {
return err
return txf.BuildUnsignedTx(msgs...)
}
// BroadcastTx attempts to sign and broadcast a transaction using the provided factory and broadcaster.
// GenerateTx must be called first to prepare the transaction for signing.
// This function then signs the transaction using the factory's signing capabilities, encodes it,
// and finally broadcasts it using the provided broadcaster.
func BroadcastTx(ctx context.Context, txf Factory, broadcaster broadcast.Broadcaster) ([]byte, error) {
if len(txf.tx.msgs) == 0 {
return nil, errors.New("no messages to broadcast")
}
if !clientCtx.SkipConfirm {
encoder := txf.txConfig.TxJSONEncoder()
if encoder == nil {
return errors.New("failed to encode transaction: tx json encoder is nil")
}
unsigTx, err := txf.getTx()
if err != nil {
return err
}
txBytes, err := encoder(unsigTx)
if err != nil {
return fmt.Errorf("failed to encode transaction: %w", err)
}
if err := clientCtx.PrintRaw(txBytes); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "error: %v\n%s\n", err, txBytes)
}
buf := bufio.NewReader(os.Stdin)
ok, err := input.GetConfirmation("confirm transaction before signing and broadcasting", buf, os.Stderr)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "error: %v\ncanceled transaction\n", err)
return err
}
if !ok {
_, _ = fmt.Fprintln(os.Stderr, "canceled transaction")
return nil
}
}
signedTx, err := txf.sign(clientCtx.CmdContext, true)
signedTx, err := txf.sign(ctx, true)
if err != nil {
return err
return nil, err
}
txBytes, err := txf.txConfig.TxEncoder()(signedTx)
if err != nil {
return err
return nil, err
}
res, err := broadcaster.Broadcast(context.Background(), txBytes)
if err != nil {
return err
}
return clientCtx.PrintString(string(res))
return broadcaster.Broadcast(ctx, txBytes)
}
// countDirectSigners counts the number of DIRECT signers in a signature data.
@ -233,6 +277,38 @@ func countDirectSigners(sigData SignatureData) int {
}
}
// cometBroadcaster returns a broadcast.Broadcaster implementation that uses the CometBFT RPC client.
// It extracts the client context from the provided context and uses it to create a CometBFT broadcaster.
func cometBroadcaster(ctx context.Context) (broadcast.Broadcaster, error) {
c, err := clientcontext.ClientContextFromGoContext(ctx)
if err != nil {
return nil, err
}
return getCometBroadcaster(c.Cdc, c.Flags)
}
// askConfirmation encodes the transaction as JSON and prompts the user for confirmation using the provided prompter function.
// It returns the user's confirmation response and any error that occurred during the process.
func askConfirmation(txf Factory, prompter func([]byte) (bool, error)) (bool, error) {
encoder := txf.txConfig.TxJSONEncoder()
if encoder == nil {
return false, errors.New("failed to encode transaction: tx json encoder is nil")
}
tx, err := txf.getTx()
if err != nil {
return false, err
}
txBytes, err := encoder(tx)
if err != nil {
return false, fmt.Errorf("failed to encode transaction: %w", err)
}
return prompter(txBytes)
}
// getSignMode returns the corresponding apitxsigning.SignMode based on the provided mode string.
func getSignMode(mode string) apitxsigning.SignMode {
switch mode {

View File

@ -148,20 +148,21 @@ type Tx interface {
// txParamsFromFlagSet extracts the transaction parameters from the provided FlagSet.
func txParamsFromFlagSet(flags *pflag.FlagSet, keybase keyring2.Keyring, ac address.Codec) (params TxParameters, err error) {
timestampUnix, _ := flags.GetInt64(flagTimeoutTimestamp)
timestampUnix, _ := flags.GetInt64(FlagTimeoutTimestamp)
timeoutTimestamp := time.Unix(timestampUnix, 0)
chainID, _ := flags.GetString(flagChainID)
memo, _ := flags.GetString(flagNote)
signMode, _ := flags.GetString(flagSignMode)
chainID, _ := flags.GetString(FlagChainID)
memo, _ := flags.GetString(FlagNote)
signMode, _ := flags.GetString(FlagSignMode)
accNumber, _ := flags.GetUint64(flagAccountNumber)
sequence, _ := flags.GetUint64(flagSequence)
from, _ := flags.GetString(flagFrom)
accNumber, _ := flags.GetUint64(FlagAccountNumber)
sequence, _ := flags.GetUint64(FlagSequence)
from, _ := flags.GetString(FlagFrom)
var fromName, fromAddress string
var addr []byte
isDryRun, _ := flags.GetBool(flagDryRun)
if isDryRun {
isDryRun, _ := flags.GetBool(FlagDryRun)
generateOnly, _ := flags.GetBool(FlagGenerateOnly)
if isDryRun || generateOnly {
addr, err = ac.StringToBytes(from)
} else {
fromName, fromAddress, _, err = keybase.KeyInfo(from)
@ -173,16 +174,16 @@ func txParamsFromFlagSet(flags *pflag.FlagSet, keybase keyring2.Keyring, ac addr
return params, err
}
gas, _ := flags.GetString(flagGas)
gas, _ := flags.GetString(FlagGas)
simulate, gasValue, _ := parseGasSetting(gas)
gasAdjustment, _ := flags.GetFloat64(flagGasAdjustment)
gasPrices, _ := flags.GetString(flagGasPrices)
gasAdjustment, _ := flags.GetFloat64(FlagGasAdjustment)
gasPrices, _ := flags.GetString(FlagGasPrices)
fees, _ := flags.GetString(flagFees)
feePayer, _ := flags.GetString(flagFeePayer)
feeGrater, _ := flags.GetString(flagFeeGranter)
fees, _ := flags.GetString(FlagFees)
feePayer, _ := flags.GetString(FlagFeePayer)
feeGrater, _ := flags.GetString(FlagFeeGranter)
unordered, _ := flags.GetBool(flagUnordered)
unordered, _ := flags.GetBool(FlagUnordered)
gasConfig, err := NewGasConfig(gasValue, gasAdjustment, gasPrices)
if err != nil {

2
go.mod
View File

@ -12,7 +12,7 @@ require (
cosmossdk.io/errors v1.0.1
cosmossdk.io/log v1.5.0
cosmossdk.io/math v1.4.0
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b
cosmossdk.io/schema v0.4.0
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000

4
go.sum
View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -20,7 +20,7 @@ require (
cosmossdk.io/errors v1.0.1
cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5
cosmossdk.io/log v1.5.0
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b //main
cosmossdk.io/schema v0.4.0 //main
cosmossdk.io/server/v2 v2.0.0-20241209145349-34f407d6367a // main
cosmossdk.io/server/v2/appmanager v0.0.0-20241203212527-7d117425d880 // main
cosmossdk.io/server/v2/stf v0.0.0-20241204101618-7fa2356c07aa // main

View File

@ -22,8 +22,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/server/v2 v2.0.0-20241209145349-34f407d6367a h1:qkO+rB9yD6+bTGgQpaf+oyvgEdkPs5TUaFK3OEYh3AI=
cosmossdk.io/server/v2 v2.0.0-20241209145349-34f407d6367a/go.mod h1:sb6WEIMHAT+8z7iM6IbBeSf+62wSkss2q+coDxmOi/o=
cosmossdk.io/server/v2/appmanager v0.0.0-20241203212527-7d117425d880 h1:0mtB8fSvDjD835WwWF4rGk9qy5TjVjk2jsW14L37v0E=

View File

@ -61,7 +61,7 @@ require (
cloud.google.com/go/iam v1.1.8 // indirect
cloud.google.com/go/storage v1.42.0 // indirect
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.2 // indirect

View File

@ -211,8 +211,8 @@ cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -121,7 +121,10 @@ func NewRootCmd() *cobra.Command {
}
autoCliOpts := tempApp.AutoCliOpts()
autoCliOpts.ClientCtx = initClientCtx
autoCliOpts.AddressCodec = initClientCtx.AddressCodec
autoCliOpts.ValidatorAddressCodec = initClientCtx.ValidatorAddressCodec
autoCliOpts.ConsensusAddressCodec = initClientCtx.ConsensusAddressCodec
autoCliOpts.Cdc = initClientCtx.Codec
nodeCmds := nodeservice.NewNodeCommands()
autoCliOpts.ModuleOptions[nodeCmds.Name()] = nodeCmds.AutoCLIOptions()

View File

@ -59,7 +59,7 @@ require (
cosmossdk.io/collections v0.4.1-0.20241209183624-332d0b106d1b // indirect; main
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/server/v2/appmanager v0.0.0-20241203212527-7d117425d880 // indirect; main
cosmossdk.io/server/v2/stf v0.0.0-20241204101618-7fa2356c07aa // indirect; main
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6 // indirect; main

View File

@ -215,8 +215,8 @@ cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/runtime/v2 v2.0.0-20241204100030-c47fb8ab2dcb h1:tsdNkxdlG5g5AWOxFpLfX5/eCU6LGN7hV1VAULCY2Lk=
cosmossdk.io/runtime/v2 v2.0.0-20241204100030-c47fb8ab2dcb/go.mod h1:7DCLOq3Xzyq+DA0WoMD5HcZUuflShDmq6g2qgh2yVdI=
cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/server/v2 v2.0.0-20241209145349-34f407d6367a h1:qkO+rB9yD6+bTGgQpaf+oyvgEdkPs5TUaFK3OEYh3AI=
cosmossdk.io/server/v2 v2.0.0-20241209145349-34f407d6367a/go.mod h1:sb6WEIMHAT+8z7iM6IbBeSf+62wSkss2q+coDxmOi/o=
cosmossdk.io/server/v2/appmanager v0.0.0-20241203212527-7d117425d880 h1:0mtB8fSvDjD835WwWF4rGk9qy5TjVjk2jsW14L37v0E=

View File

@ -73,7 +73,7 @@ require (
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 // indirect
cosmossdk.io/indexer/postgres v0.0.0-20241128094659-bd76b47e1d8b // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/server/v2/appmanager v0.0.0-20241107153845-4e240908dd60 // indirect
cosmossdk.io/x/circuit v0.0.0-20230613133644-0a778132a60f // indirect
cosmossdk.io/x/epochs v0.0.0-20240522060652-a1ae4c3e0337 // indirect

View File

@ -215,8 +215,8 @@ cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/runtime/v2 v2.0.0-20241107153845-4e240908dd60 h1:305IbyP2jaJeKNRglxBtEAY/JKz8rD3l+081zrAThGY=
cosmossdk.io/runtime/v2 v2.0.0-20241107153845-4e240908dd60/go.mod h1:zXxA8bHeShGxzTLR9m3OdF+aJ/IEmWSnrz343Ri6Me8=
cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/server/v2/appmanager v0.0.0-20241107153845-4e240908dd60 h1:M26/YrNRru59kzRkW/Mm7bnpEEsnR9rIFdNFGTXicGQ=
cosmossdk.io/server/v2/appmanager v0.0.0-20241107153845-4e240908dd60/go.mod h1:mONOF8GRbxs5R04zMscuQQI1gx/XHTY7imKjcwLI5uo=
cosmossdk.io/server/v2/stf v0.0.0-20241107153845-4e240908dd60 h1:+PYG1Wjsu8ZX5vvINPu7UjRxzT9m9sJ9SlS8MVApmOU=

View File

@ -25,7 +25,7 @@ require (
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/log v1.5.0 // indirect
cosmossdk.io/math v1.4.0 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -33,7 +33,7 @@ require (
cosmossdk.io/errors v1.0.1
cosmossdk.io/log v1.5.0
cosmossdk.io/math v1.4.0
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect
filippo.io/edwards25519 v1.1.0 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -23,7 +23,7 @@ require (
cosmossdk.io/depinject v1.1.0 // indirect
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/log v1.5.0 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect; main

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -39,7 +39,7 @@ require (
cosmossdk.io/errors v1.0.1
cosmossdk.io/log v1.5.0 // indirect
cosmossdk.io/math v1.4.0
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b
cosmossdk.io/schema v0.4.0
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
filippo.io/edwards25519 v1.1.0 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -31,7 +31,7 @@ require (
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/collections v0.4.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/core/testing v0.0.0-20241108153815-606544c7be7e
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.2 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -157,7 +157,7 @@ require (
sigs.k8s.io/yaml v1.4.0 // indirect
)
require cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b
require cosmossdk.io/schema v0.4.0
require (
github.com/bytedance/sonic v1.12.4 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -9,7 +9,7 @@ require (
cosmossdk.io/core/testing v0.0.0-20241108153815-606544c7be7e // main
cosmossdk.io/depinject v1.1.0
cosmossdk.io/errors v1.0.1
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b
cosmossdk.io/schema v0.4.0
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6 // main
github.com/cosmos/cosmos-sdk v0.52.0
github.com/cosmos/gogoproto v1.7.0

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -8,7 +8,7 @@ require (
cosmossdk.io/core v1.0.0-alpha.6 // main
cosmossdk.io/core/testing v0.0.0-20241108153815-606544c7be7e // main
cosmossdk.io/depinject v1.1.0
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b
cosmossdk.io/schema v0.4.0
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6
github.com/cometbft/cometbft v1.0.0-rc2.0.20241127125717-4ce33b646ac9
github.com/cometbft/cometbft/api v1.0.0-rc2

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -10,7 +10,7 @@ require (
cosmossdk.io/depinject v1.1.0
cosmossdk.io/errors v1.0.1
cosmossdk.io/math v1.4.0
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b
cosmossdk.io/schema v0.4.0
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000
github.com/cosmos/cosmos-proto v1.0.0-beta.5

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -20,7 +20,7 @@ require (
google.golang.org/grpc v1.68.1
)
require cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b
require cosmossdk.io/schema v0.4.0
require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.35.2-20241120201313-68e42a58b301.1 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -28,7 +28,7 @@ require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.35.2-20241120201313-68e42a58b301.1 // indirect
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/log v1.5.0 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect; main

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -44,7 +44,7 @@ require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.35.2-20241120201313-68e42a58b301.1 // indirect
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/log v1.5.0 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect; main

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o=

View File

@ -48,7 +48,7 @@ require (
require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.35.2-20241120201313-68e42a58b301.1 // indirect
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -38,7 +38,7 @@ require (
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/collections v0.4.1-0.20241209183624-332d0b106d1b // indirect; main
cosmossdk.io/core/testing v0.0.0-20241108153815-606544c7be7e // main
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/x/epochs v0.0.0-20240522060652-a1ae4c3e0337 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect; main
filippo.io/edwards25519 v1.1.0 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -29,7 +29,7 @@ require (
require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.35.2-20241120201313-68e42a58b301.1 // indirect
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b
cosmossdk.io/schema v0.4.0
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect; main

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -26,7 +26,7 @@ require (
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/collections v0.4.1-0.20241209183624-332d0b106d1b // indirect; main
cosmossdk.io/core/testing v0.0.0-20241108153815-606544c7be7e // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect; main

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -29,7 +29,7 @@ require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.35.2-20241120201313-68e42a58b301.1 // indirect
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/collections v0.4.1-0.20241209183624-332d0b106d1b // indirect; main
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect; main
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -28,7 +28,7 @@ require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.35.2-20241120201313-68e42a58b301.1 // indirect
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/log v1.5.0 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect; main

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -30,7 +30,7 @@ require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.35.2-20241120201313-68e42a58b301.1 // indirect
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.35.2-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/log v1.5.0 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect
filippo.io/edwards25519 v1.1.0 // indirect

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -10,7 +10,7 @@ require (
cosmossdk.io/depinject v1.1.0
cosmossdk.io/errors v1.0.1
cosmossdk.io/math v1.4.0
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b
cosmossdk.io/schema v0.4.0
cosmossdk.io/store v1.1.1-0.20240909133312-50288938d1b6
github.com/cometbft/cometbft v1.0.0-rc2.0.20241127125717-4ce33b646ac9 // indirect
github.com/cometbft/cometbft/api v1.0.0-rc2

View File

@ -20,8 +20,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=

View File

@ -42,7 +42,7 @@ require (
cloud.google.com/go/storage v1.42.0 // indirect
cosmossdk.io/collections v0.4.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/math v1.4.0 // indirect
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b // indirect
cosmossdk.io/schema v0.4.0 // indirect
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/tx v1.0.0-alpha.2 // indirect; main

View File

@ -208,8 +208,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b h1:ymo4PrM7Q4tPpEtce6IdH/kurphOAE6DmzHux1tniNY=
cosmossdk.io/schema v0.3.1-0.20241209183624-332d0b106d1b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o=