Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
parent
3da9f9c9ec
commit
8334eefaaf
@ -38,6 +38,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Improvements
|
||||
|
||||
* (keyring) [#17913](https://github.com/cosmos/cosmos-sdk/pull/17913) Add `NewAutoCLIKeyring` for creating an AutoCLI keyring from a SDK keyring.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* (x/gov) [#17873](https://github.com/cosmos/cosmos-sdk/pull/17873) Fail any inactive and active proposals that cannot be decoded.
|
||||
|
||||
@ -117,7 +117,9 @@ func AddQueryFlagsToCmd(cmd *cobra.Command) {
|
||||
func AddTxFlagsToCmd(cmd *cobra.Command) {
|
||||
f := cmd.Flags()
|
||||
f.StringP(FlagOutput, "o", OutputFormatJSON, "Output format (text|json)")
|
||||
f.String(FlagFrom, "", "Name or address of private key with which to sign")
|
||||
if cmd.Flag(FlagFrom) == nil { // avoid flag redefinition when it's already been added by AutoCLI
|
||||
f.String(FlagFrom, "", "Name or address of private key with which to sign")
|
||||
}
|
||||
f.Uint64P(FlagAccountNumber, "a", 0, "The account number of the signing account (offline mode only)")
|
||||
f.Uint64P(FlagSequence, "s", 0, "The sequence number of the signing account (offline mode only)")
|
||||
f.String(FlagNote, "", "Note to add a description to the transaction (previously --memo)")
|
||||
|
||||
@ -410,7 +410,12 @@ func (f Factory) BuildSimTx(msgs ...sdk.Msg) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return f.txConfig.TxEncoder()(txb.GetTx())
|
||||
encoder := f.txConfig.TxEncoder()
|
||||
if encoder == nil {
|
||||
return nil, fmt.Errorf("cannot simulate tx: tx encoder is nil")
|
||||
}
|
||||
|
||||
return encoder(txb.GetTx())
|
||||
}
|
||||
|
||||
// getSimPK gets the public key to use for building a simulation tx.
|
||||
|
||||
@ -107,7 +107,7 @@ func BroadcastTx(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error {
|
||||
|
||||
txBytes, err := encoder(tx.GetTx())
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to encode transaction: %w", err)
|
||||
}
|
||||
|
||||
if err := clientCtx.PrintRaw(json.RawMessage(txBytes)); err != nil {
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
codegen:
|
||||
@(cd internal; buf generate)
|
||||
@(cd internal; buf generate)
|
||||
@ -75,7 +75,7 @@ if err := rootCmd.Execute(); err != nil {
|
||||
|
||||
### Keyring
|
||||
|
||||
`autocli` supports a keyring for key name resolving and signing transactions. Providing a keyring is optional, but if you want to use the `autocli` generated commands to sign transactions, you must provide a keyring.
|
||||
`autocli` uses a keyring for key name resolving and signing transactions. Providing a keyring is optional, but if you want to use the `autocli` generated commands to sign transactions, you must provide a keyring.
|
||||
|
||||
:::tip
|
||||
This provides a better UX as it allows to resolve key names directly from the keyring in all transactions and commands.
|
||||
@ -87,16 +87,23 @@ This provides a better UX as it allows to resolve key names directly from the ke
|
||||
|
||||
:::
|
||||
|
||||
The keyring to be provided to `client/v2` must match the `client/v2` keyring interface. The Cosmos SDK keyring and Hubl keyring both implement this interface.
|
||||
The keyring to be provided to `client/v2` must match the `client/v2` keyring interface.
|
||||
The keyring should be provided in the `appOptions` struct as follows, and can be gotten from the client context:
|
||||
|
||||
:::tip
|
||||
The Cosmos SDK keyring and Hubl keyring both implement the `client/v2/autocli/keyring` interface, thanks to the following wrapper:
|
||||
|
||||
```go
|
||||
keyring.NewAutoCLIKeyring(kb)
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::warning
|
||||
When using AutoCLI the keyring will only be created once and before any command flag parsing.
|
||||
:::
|
||||
|
||||
```go
|
||||
// Get the keyring from the client context
|
||||
keyring := ctx.Keyring
|
||||
// Set the keyring in the appOptions
|
||||
appOptions.Keyring = keyring
|
||||
|
||||
@ -104,6 +111,16 @@ err := autoCliOpts.EnhanceRootCommand(rootCmd)
|
||||
...
|
||||
```
|
||||
|
||||
## Signing
|
||||
|
||||
`autocli` supports signing transactions with the keyring.
|
||||
The [`cosmos.msg.v1.signer` protobuf annotation](https://github.com/cosmos/cosmos-sdk/blob/9dd34510e27376005e7e7ff3628eab9dbc8ad6dc/docs/build/building-modules/05-protobuf-annotations.md#L9) defines the signer field of the message.
|
||||
This field is automatically filled when using the `--from` flag or defining the signer as a positional argument.
|
||||
|
||||
:::warning
|
||||
AutoCLI currently supports only one signer per transaction.
|
||||
:::
|
||||
|
||||
## Module Wiring & Customization
|
||||
|
||||
The `AutoCLIOptions()` method on your module allows to specify custom commands, sub-commands or flags for each service, as it was a `cobra.Command` instance, within the `RpcCommandOptions` struct. Defining such options will customize the behavior of the `autocli` command generation, which by default generates a command for each method in your gRPC service.
|
||||
|
||||
@ -12,11 +12,11 @@ import (
|
||||
"cosmossdk.io/core/address"
|
||||
"cosmossdk.io/core/appmodule"
|
||||
"cosmossdk.io/depinject"
|
||||
"cosmossdk.io/log"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
sdkflags "github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
)
|
||||
|
||||
// AppOptions are autocli options for an app. These options can be built via depinject based on an app config. Ex:
|
||||
@ -30,9 +30,6 @@ import (
|
||||
type AppOptions struct {
|
||||
depinject.In
|
||||
|
||||
// Logger is the logger to use for client/v2.
|
||||
Logger log.Logger
|
||||
|
||||
// Modules are the AppModule implementations for the modules in the app.
|
||||
Modules map[string]appmodule.AppModule
|
||||
|
||||
@ -42,9 +39,6 @@ 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 is the address codec to use for the app.
|
||||
AddressCodec address.Codec
|
||||
ValidatorAddressCodec runtime.ValidatorAddressCodec
|
||||
@ -52,6 +46,12 @@ type AppOptions struct {
|
||||
|
||||
// Keyring is the keyring to use for client/v2.
|
||||
Keyring keyring.Keyring `optional:"true"`
|
||||
|
||||
// ClientCtx contains the necessary information needed to execute the commands.
|
||||
ClientCtx client.Context
|
||||
|
||||
// TxConfigOptions are the transactions config options.
|
||||
TxConfigOpts tx.ConfigOptions
|
||||
}
|
||||
|
||||
// EnhanceRootCommand enhances the provided root command with autocli AppOptions,
|
||||
@ -71,21 +71,21 @@ type AppOptions struct {
|
||||
// err = autoCliOpts.EnhanceRootCommand(rootCmd)
|
||||
func (appOptions AppOptions) EnhanceRootCommand(rootCmd *cobra.Command) error {
|
||||
builder := &Builder{
|
||||
Logger: appOptions.Logger,
|
||||
Builder: flag.Builder{
|
||||
TypeResolver: protoregistry.GlobalTypes,
|
||||
FileResolver: proto.HybridResolver,
|
||||
ClientCtx: appOptions.ClientCtx,
|
||||
AddressCodec: appOptions.AddressCodec,
|
||||
ValidatorAddressCodec: appOptions.ValidatorAddressCodec,
|
||||
ConsensusAddressCodec: appOptions.ConsensusAddressCodec,
|
||||
Keyring: appOptions.Keyring,
|
||||
},
|
||||
ClientCtx: appOptions.ClientCtx,
|
||||
TxConfigOpts: appOptions.TxConfigOpts,
|
||||
GetClientConn: func(cmd *cobra.Command) (grpc.ClientConnInterface, error) {
|
||||
return client.GetClientQueryContext(cmd)
|
||||
},
|
||||
AddQueryConnFlags: flags.AddQueryFlagsToCmd,
|
||||
AddTxConnFlags: flags.AddTxFlagsToCmd,
|
||||
AddQueryConnFlags: sdkflags.AddQueryFlagsToCmd,
|
||||
AddTxConnFlags: sdkflags.AddTxFlagsToCmd,
|
||||
}
|
||||
|
||||
return appOptions.EnhanceRootCommandWithBuilder(rootCmd, builder)
|
||||
|
||||
@ -8,7 +8,9 @@ import (
|
||||
|
||||
"cosmossdk.io/client/v2/autocli/flag"
|
||||
"cosmossdk.io/client/v2/autocli/keyring"
|
||||
"cosmossdk.io/log"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
)
|
||||
|
||||
// Builder manages options for building CLI commands.
|
||||
@ -16,13 +18,16 @@ type Builder struct {
|
||||
// flag.Builder embeds the flag builder and its options.
|
||||
flag.Builder
|
||||
|
||||
// Logger is the logger used by the builder.
|
||||
Logger log.Logger
|
||||
|
||||
// GetClientConn specifies how CLI commands will resolve a grpc.ClientConnInterface
|
||||
// from a given context.
|
||||
GetClientConn func(*cobra.Command) (grpc.ClientConnInterface, error)
|
||||
|
||||
// ClientCtx contains the necessary information needed to execute the commands.
|
||||
ClientCtx client.Context
|
||||
|
||||
// TxConfigOptions is required to support sign mode textual
|
||||
TxConfigOpts authtx.ConfigOptions
|
||||
|
||||
// AddQueryConnFlags and AddTxConnFlags are functions that add flags to query and transaction commands
|
||||
AddQueryConnFlags func(*cobra.Command)
|
||||
AddTxConnFlags func(*cobra.Command)
|
||||
@ -33,40 +38,28 @@ type Builder struct {
|
||||
// If the Logger is nil, it will be set to a nop logger.
|
||||
// If the keyring is nil, it will be set to a no keyring.
|
||||
func (b *Builder) ValidateAndComplete() error {
|
||||
if b.Logger == nil {
|
||||
b.Logger = log.NewNopLogger()
|
||||
if b.Builder.AddressCodec == nil {
|
||||
return errors.New("address codec is required in flag builder")
|
||||
}
|
||||
|
||||
if b.ClientCtx == nil {
|
||||
return errors.New("client context is required in builder")
|
||||
if b.Builder.ValidatorAddressCodec == nil {
|
||||
return errors.New("validator address codec is required in flag builder")
|
||||
}
|
||||
|
||||
if b.AddressCodec == nil {
|
||||
return errors.New("address codec is required in builder")
|
||||
if b.Builder.ConsensusAddressCodec == nil {
|
||||
return errors.New("consensus address codec is required in flag builder")
|
||||
}
|
||||
|
||||
if b.ValidatorAddressCodec == nil {
|
||||
return errors.New("validator address codec is required in builder")
|
||||
if b.Builder.Keyring == nil {
|
||||
b.Keyring = keyring.NoKeyring{}
|
||||
}
|
||||
|
||||
if b.ConsensusAddressCodec == nil {
|
||||
return errors.New("consensus address codec is required in builder")
|
||||
if b.Builder.TypeResolver == nil {
|
||||
return errors.New("type resolver is required in flag builder")
|
||||
}
|
||||
|
||||
if b.Keyring == nil {
|
||||
if b.ClientCtx.Keyring != nil {
|
||||
b.Keyring = b.ClientCtx.Keyring
|
||||
} else {
|
||||
b.Keyring = keyring.NoKeyring{}
|
||||
}
|
||||
}
|
||||
|
||||
if b.TypeResolver == nil {
|
||||
return errors.New("type resolver is required in builder")
|
||||
}
|
||||
|
||||
if b.FileResolver == nil {
|
||||
return errors.New("file resolver is required in builder")
|
||||
if b.Builder.FileResolver == nil {
|
||||
return errors.New("file resolver is required in flag builder")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@ -9,9 +9,8 @@ import (
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
"cosmossdk.io/client/v2/internal/flags"
|
||||
"cosmossdk.io/client/v2/internal/util"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
)
|
||||
|
||||
type cmdType int
|
||||
@ -66,6 +65,37 @@ func (b *Builder) buildMethodCommandCommon(descriptor protoreflect.MethodDescrip
|
||||
return err
|
||||
}
|
||||
|
||||
// signer related logic, triggers only when there is a signer defined
|
||||
if binder.SignerInfo.FieldName != "" {
|
||||
// mark the signer flag as required if defined
|
||||
// TODO(@julienrbrt): UX improvement by only marking the flag as required when there is more than one key in the keyring;
|
||||
// when there is only one key, use that key by default.
|
||||
if binder.SignerInfo.IsFlag {
|
||||
if err := cmd.MarkFlagRequired(binder.SignerInfo.FieldName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// the client context uses the from flag to determine the signer.
|
||||
// this sets the signer flags to the from flag value if a custom signer flag is set.
|
||||
if binder.SignerInfo.FieldName != flags.FlagFrom {
|
||||
signer, err := cmd.Flags().GetString(binder.SignerInfo.FieldName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get signer flag: %w", err)
|
||||
}
|
||||
|
||||
if err := cmd.Flags().Set(flags.FlagFrom, signer); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if the signer is not a flag, it is a positional argument
|
||||
// we need to get the correct positional arguments
|
||||
if err := cmd.Flags().Set(flags.FlagFrom, args[binder.SignerInfo.PositionalArgIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return exec(cmd, input)
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"gotest.tools/v3/assert"
|
||||
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
reflectionv2alpha1 "cosmossdk.io/api/cosmos/base/reflection/v2alpha1"
|
||||
"cosmossdk.io/client/v2/autocli/flag"
|
||||
"cosmossdk.io/client/v2/internal/testpb"
|
||||
@ -19,9 +20,11 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
type fixture struct {
|
||||
@ -47,24 +50,33 @@ func initFixture(t *testing.T) *fixture {
|
||||
clientConn, err := grpc.Dial(listener.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
assert.NilError(t, err)
|
||||
|
||||
appCodec := moduletestutil.MakeTestEncodingConfig().Codec
|
||||
kr, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, home, nil, appCodec)
|
||||
encodingConfig := moduletestutil.MakeTestEncodingConfig(bank.AppModuleBasic{})
|
||||
kr, err := sdkkeyring.New(sdk.KeyringServiceName(), sdkkeyring.BackendMemory, home, nil, encodingConfig.Codec)
|
||||
assert.NilError(t, err)
|
||||
|
||||
akr, err := sdkkeyring.NewAutoCLIKeyring(kr)
|
||||
assert.NilError(t, err)
|
||||
|
||||
interfaceRegistry := encodingConfig.Codec.InterfaceRegistry()
|
||||
banktypes.RegisterInterfaces(interfaceRegistry)
|
||||
|
||||
var initClientCtx client.Context
|
||||
initClientCtx = initClientCtx.
|
||||
WithKeyring(kr).
|
||||
WithKeyringDir(home).
|
||||
WithHomeDir(home).
|
||||
WithViper("")
|
||||
WithViper("").
|
||||
WithInterfaceRegistry(interfaceRegistry).
|
||||
WithTxConfig(encodingConfig.TxConfig).
|
||||
WithAccountRetriever(client.MockAccountRetriever{}).
|
||||
WithChainID("autocli-test")
|
||||
|
||||
conn := &testClientConn{ClientConn: clientConn}
|
||||
b := &Builder{
|
||||
Builder: flag.Builder{
|
||||
TypeResolver: protoregistry.GlobalTypes,
|
||||
FileResolver: protoregistry.GlobalFiles,
|
||||
ClientCtx: &initClientCtx,
|
||||
Keyring: kr,
|
||||
Keyring: akr,
|
||||
AddressCodec: addresscodec.NewBech32Codec("cosmos"),
|
||||
ValidatorAddressCodec: addresscodec.NewBech32Codec("cosmosvaloper"),
|
||||
ConsensusAddressCodec: addresscodec.NewBech32Codec("cosmosvalcons"),
|
||||
@ -74,6 +86,7 @@ func initFixture(t *testing.T) *fixture {
|
||||
},
|
||||
AddQueryConnFlags: flags.AddQueryFlagsToCmd,
|
||||
AddTxConnFlags: flags.AddTxFlagsToCmd,
|
||||
ClientCtx: initClientCtx,
|
||||
}
|
||||
assert.NilError(t, b.ValidateAndComplete())
|
||||
|
||||
@ -131,3 +144,82 @@ func (t testEchoServer) Echo(_ context.Context, request *testpb.EchoRequest) (*t
|
||||
}
|
||||
|
||||
var _ testpb.QueryServer = testEchoServer{}
|
||||
|
||||
func TestEnhanceCommand(t *testing.T) {
|
||||
b := &Builder{}
|
||||
// Test that the command has a subcommand
|
||||
cmd := &cobra.Command{Use: "test"}
|
||||
cmd.AddCommand(&cobra.Command{Use: "test"})
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
cmdTp := cmdType(i)
|
||||
|
||||
appOptions := AppOptions{
|
||||
ModuleOptions: map[string]*autocliv1.ModuleOptions{
|
||||
"test": {},
|
||||
},
|
||||
}
|
||||
|
||||
err := b.enhanceCommandCommon(cmd, cmdTp, appOptions, map[string]*cobra.Command{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
cmd = &cobra.Command{Use: "test"}
|
||||
|
||||
appOptions = AppOptions{
|
||||
ModuleOptions: map[string]*autocliv1.ModuleOptions{},
|
||||
}
|
||||
customCommands := map[string]*cobra.Command{
|
||||
"test2": {Use: "test"},
|
||||
}
|
||||
err = b.enhanceCommandCommon(cmd, cmdTp, appOptions, customCommands)
|
||||
assert.NilError(t, err)
|
||||
|
||||
cmd = &cobra.Command{Use: "test"}
|
||||
appOptions = AppOptions{
|
||||
ModuleOptions: map[string]*autocliv1.ModuleOptions{
|
||||
"test": {Tx: nil},
|
||||
},
|
||||
}
|
||||
err = b.enhanceCommandCommon(cmd, cmdTp, appOptions, map[string]*cobra.Command{})
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorBuildCommand(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
b := fixture.b
|
||||
b.AddQueryConnFlags = nil
|
||||
b.AddTxConnFlags = nil
|
||||
|
||||
commandDescriptor := &autocliv1.ServiceCommandDescriptor{
|
||||
Service: testpb.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
RpcMethod: "Send",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||
{
|
||||
ProtoField: "un-existent-proto-field",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
appOptions := AppOptions{
|
||||
ModuleOptions: map[string]*autocliv1.ModuleOptions{
|
||||
"test": {
|
||||
Query: commandDescriptor,
|
||||
Tx: commandDescriptor,
|
||||
},
|
||||
},
|
||||
ClientCtx: b.ClientCtx,
|
||||
}
|
||||
|
||||
_, err := b.BuildMsgCommand(appOptions, nil)
|
||||
assert.ErrorContains(t, err, "can't find field un-existent-proto-field")
|
||||
|
||||
appOptions.ModuleOptions["test"].Tx = &autocliv1.ServiceCommandDescriptor{Service: "un-existent-service"}
|
||||
appOptions.ModuleOptions["test"].Query = &autocliv1.ServiceCommandDescriptor{Service: "un-existent-service"}
|
||||
_, err = b.BuildMsgCommand(appOptions, nil)
|
||||
assert.ErrorContains(t, err, "can't find service un-existent-service")
|
||||
}
|
||||
|
||||
@ -80,7 +80,12 @@ func (a addressValue) Type() string {
|
||||
type consensusAddressStringType struct{}
|
||||
|
||||
func (a consensusAddressStringType) NewValue(ctx context.Context, b *Builder) Value {
|
||||
return &consensusAddressValue{addressValue: addressValue{addressCodec: b.ConsensusAddressCodec, keyring: b.Keyring}}
|
||||
return &consensusAddressValue{
|
||||
addressValue: addressValue{
|
||||
addressCodec: b.ConsensusAddressCodec,
|
||||
keyring: b.Keyring,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (a consensusAddressStringType) DefaultValue() string {
|
||||
|
||||
@ -14,11 +14,12 @@ import (
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
msgv1 "cosmossdk.io/api/cosmos/msg/v1"
|
||||
"cosmossdk.io/client/v2/autocli/keyring"
|
||||
"cosmossdk.io/client/v2/internal/flags"
|
||||
"cosmossdk.io/client/v2/internal/util"
|
||||
"cosmossdk.io/core/address"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
)
|
||||
|
||||
@ -41,16 +42,13 @@ type Builder struct {
|
||||
messageFlagTypes map[protoreflect.FullName]Type
|
||||
scalarFlagTypes map[string]Type
|
||||
|
||||
// AddressCodec is the address codec to use for the app.
|
||||
// Keyring is the keyring to use for client/v2.
|
||||
Keyring keyring.Keyring
|
||||
|
||||
// Address Codecs are the address codecs to use for client/v2.
|
||||
AddressCodec address.Codec
|
||||
ValidatorAddressCodec runtime.ValidatorAddressCodec
|
||||
ConsensusAddressCodec runtime.ConsensusAddressCodec
|
||||
|
||||
// Keyring implementation
|
||||
Keyring keyring.Keyring
|
||||
|
||||
// ClientCtx contains the necessary information needed to execute the commands.
|
||||
ClientCtx *client.Context
|
||||
}
|
||||
|
||||
func (b *Builder) init() {
|
||||
@ -69,35 +67,48 @@ func (b *Builder) init() {
|
||||
}
|
||||
}
|
||||
|
||||
// DefineMessageFlagType allows to extend custom protobuf message type handling for flags (and positional arguments).
|
||||
func (b *Builder) DefineMessageFlagType(messageName protoreflect.FullName, flagType Type) {
|
||||
b.init()
|
||||
b.messageFlagTypes[messageName] = flagType
|
||||
}
|
||||
|
||||
// DefineScalarFlagType allows to extend custom scalar type handling for flags (and positional arguments).
|
||||
func (b *Builder) DefineScalarFlagType(scalarName string, flagType Type) {
|
||||
b.init()
|
||||
b.scalarFlagTypes[scalarName] = flagType
|
||||
}
|
||||
|
||||
// AddMessageFlags adds flags for each field in the message to the flag set.
|
||||
func (b *Builder) AddMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, messageType protoreflect.MessageType, commandOptions *autocliv1.RpcCommandOptions) (*MessageBinder, error) {
|
||||
return b.addMessageFlags(ctx, flagSet, messageType, commandOptions, namingOptions{})
|
||||
}
|
||||
|
||||
// AddMessageFlags adds flags for each field in the message to the flag set.
|
||||
// addMessageFlags adds flags for each field in the message to the flag set.
|
||||
func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, messageType protoreflect.MessageType, commandOptions *autocliv1.RpcCommandOptions, options namingOptions) (*MessageBinder, error) {
|
||||
fields := messageType.Descriptor().Fields()
|
||||
numFields := fields.Len()
|
||||
handler := &MessageBinder{
|
||||
messageBinder := &MessageBinder{
|
||||
messageType: messageType,
|
||||
// positional args are also parsed using a FlagSet so that we can reuse all the same parsers
|
||||
positionalFlagSet: pflag.NewFlagSet("positional", pflag.ContinueOnError),
|
||||
}
|
||||
|
||||
fields := messageType.Descriptor().Fields()
|
||||
signerFieldName := GetSignerFieldName(messageType.Descriptor())
|
||||
|
||||
isPositional := map[string]bool{}
|
||||
n := len(commandOptions.PositionalArgs)
|
||||
// positional args are also parsed using a FlagSet so that we can reuse all the same parsers
|
||||
handler.positionalFlagSet = pflag.NewFlagSet("positional", pflag.ContinueOnError)
|
||||
|
||||
lengthPositionalArgsOptions := len(commandOptions.PositionalArgs)
|
||||
for i, arg := range commandOptions.PositionalArgs {
|
||||
isPositional[arg.ProtoField] = true
|
||||
|
||||
// verify if a positional field is a signer field
|
||||
if arg.ProtoField == signerFieldName {
|
||||
messageBinder.SignerInfo = SignerInfo{
|
||||
PositionalArgIndex: i,
|
||||
FieldName: arg.ProtoField,
|
||||
}
|
||||
}
|
||||
|
||||
field := fields.ByName(protoreflect.Name(arg.ProtoField))
|
||||
if field == nil {
|
||||
return nil, fmt.Errorf("can't find field %s on %s", arg.ProtoField, messageType.Descriptor().FullName())
|
||||
@ -108,24 +119,24 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m
|
||||
}
|
||||
|
||||
if arg.Varargs {
|
||||
if i != n-1 {
|
||||
if i != lengthPositionalArgsOptions-1 {
|
||||
return nil, fmt.Errorf("varargs positional argument %s must be the last argument", arg.ProtoField)
|
||||
}
|
||||
|
||||
handler.hasVarargs = true
|
||||
messageBinder.hasVarargs = true
|
||||
}
|
||||
|
||||
if arg.Optional {
|
||||
if i != n-1 {
|
||||
if i != lengthPositionalArgsOptions-1 {
|
||||
return nil, fmt.Errorf("optional positional argument %s must be the last argument", arg.ProtoField)
|
||||
}
|
||||
|
||||
handler.hasOptional = true
|
||||
messageBinder.hasOptional = true
|
||||
}
|
||||
|
||||
_, hasValue, err := b.addFieldFlag(
|
||||
ctx,
|
||||
handler.positionalFlagSet,
|
||||
messageBinder.positionalFlagSet,
|
||||
field,
|
||||
&autocliv1.FlagOptions{Name: fmt.Sprintf("%d", i)},
|
||||
namingOptions{},
|
||||
@ -134,21 +145,21 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handler.positionalArgs = append(handler.positionalArgs, fieldBinding{
|
||||
messageBinder.positionalArgs = append(messageBinder.positionalArgs, fieldBinding{
|
||||
field: field,
|
||||
hasValue: hasValue,
|
||||
})
|
||||
}
|
||||
|
||||
if handler.hasVarargs {
|
||||
handler.CobraArgs = cobra.MinimumNArgs(n - 1)
|
||||
handler.MandatoryArgUntil = n - 1
|
||||
} else if handler.hasOptional {
|
||||
handler.CobraArgs = cobra.RangeArgs(n-1, n)
|
||||
handler.MandatoryArgUntil = n - 1
|
||||
if messageBinder.hasVarargs {
|
||||
messageBinder.CobraArgs = cobra.MinimumNArgs(lengthPositionalArgsOptions - 1)
|
||||
messageBinder.mandatoryArgUntil = lengthPositionalArgsOptions - 1
|
||||
} else if messageBinder.hasOptional {
|
||||
messageBinder.CobraArgs = cobra.RangeArgs(lengthPositionalArgsOptions-1, lengthPositionalArgsOptions)
|
||||
messageBinder.mandatoryArgUntil = lengthPositionalArgsOptions - 1
|
||||
} else {
|
||||
handler.CobraArgs = cobra.ExactArgs(n)
|
||||
handler.MandatoryArgUntil = n
|
||||
messageBinder.CobraArgs = cobra.ExactArgs(lengthPositionalArgsOptions)
|
||||
messageBinder.mandatoryArgUntil = lengthPositionalArgsOptions
|
||||
}
|
||||
|
||||
// validate flag options
|
||||
@ -156,12 +167,42 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m
|
||||
if fields.ByName(protoreflect.Name(name)) == nil {
|
||||
return nil, fmt.Errorf("can't find field %s on %s specified as a flag", name, messageType.Descriptor().FullName())
|
||||
}
|
||||
|
||||
// verify if a flag is a signer field
|
||||
if name == signerFieldName {
|
||||
messageBinder.SignerInfo = SignerInfo{
|
||||
FieldName: name,
|
||||
IsFlag: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if signer has not been specified as positional arguments,
|
||||
// add it as `--from` flag (instead of --field-name flags)
|
||||
if signerFieldName != "" && messageBinder.SignerInfo.FieldName == "" {
|
||||
if commandOptions.FlagOptions == nil {
|
||||
commandOptions.FlagOptions = make(map[string]*autocliv1.FlagOptions)
|
||||
}
|
||||
|
||||
commandOptions.FlagOptions[signerFieldName] = &autocliv1.FlagOptions{
|
||||
Name: flags.FlagFrom,
|
||||
Usage: "Name or address with which to sign the message",
|
||||
Shorthand: "f",
|
||||
}
|
||||
|
||||
messageBinder.SignerInfo = SignerInfo{
|
||||
FieldName: flags.FlagFrom,
|
||||
IsFlag: true,
|
||||
}
|
||||
}
|
||||
|
||||
// define all other fields as flags
|
||||
flagOptsByFlagName := map[string]*autocliv1.FlagOptions{}
|
||||
for i := 0; i < numFields; i++ {
|
||||
for i := 0; i < fields.Len(); i++ {
|
||||
field := fields.Get(i)
|
||||
if isPositional[string(field.Name())] {
|
||||
// skips positional args and signer field if already set
|
||||
if isPositional[string(field.Name())] ||
|
||||
(string(field.Name()) == signerFieldName && messageBinder.SignerInfo.FieldName == flags.FlagFrom) {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -172,7 +213,7 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handler.flagBindings = append(handler.flagBindings, fieldBinding{
|
||||
messageBinder.flagBindings = append(messageBinder.flagBindings, fieldBinding{
|
||||
hasValue: hasValue,
|
||||
field: field,
|
||||
})
|
||||
@ -191,7 +232,7 @@ func (b *Builder) addMessageFlags(ctx context.Context, flagSet *pflag.FlagSet, m
|
||||
}
|
||||
})
|
||||
|
||||
return handler, nil
|
||||
return messageBinder, nil
|
||||
}
|
||||
|
||||
// bindPageRequest create a flag for pagination
|
||||
@ -266,10 +307,11 @@ func (b *Builder) addFieldFlag(ctx context.Context, flagSet *pflag.FlagSet, fiel
|
||||
|
||||
// This is a bit of hacking around the pflag API, but the
|
||||
// defaultValue is set in this way because this is much easier than trying
|
||||
// to parse the string into the types that StringSliceP, Int32P, etc. expect
|
||||
// to parse the string into the types that StringSliceP, Int32P, etc.
|
||||
if defaultValue != "" {
|
||||
err = flagSet.Set(name, defaultValue)
|
||||
}
|
||||
|
||||
return name, val, err
|
||||
}
|
||||
|
||||
@ -370,3 +412,14 @@ func (b *Builder) resolveFlagTypeBasic(field protoreflect.FieldDescriptor) Type
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetSignerFieldName gets signer field name of a message.
|
||||
// AutoCLI supports only one signer field per message.
|
||||
func GetSignerFieldName(descriptor protoreflect.MessageDescriptor) string {
|
||||
signersFields := proto.GetExtension(descriptor.Options(), msgv1.E_Signer).([]string)
|
||||
if len(signersFields) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return signersFields[0]
|
||||
}
|
||||
|
||||
@ -8,15 +8,26 @@ import (
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
// SignerInfo contains information about the signer field.
|
||||
// That field is special because it needs to be known for signing.
|
||||
// This struct keeps track of the field name and whether it is a flag.
|
||||
// IsFlag and PositionalArgIndex are mutually exclusive.
|
||||
type SignerInfo struct {
|
||||
PositionalArgIndex int
|
||||
IsFlag bool
|
||||
FieldName string
|
||||
}
|
||||
|
||||
// MessageBinder binds multiple flags in a flag set to a protobuf message.
|
||||
type MessageBinder struct {
|
||||
MandatoryArgUntil int
|
||||
CobraArgs cobra.PositionalArgs
|
||||
CobraArgs cobra.PositionalArgs
|
||||
SignerInfo SignerInfo
|
||||
|
||||
positionalFlagSet *pflag.FlagSet
|
||||
positionalArgs []fieldBinding
|
||||
hasVarargs bool
|
||||
hasOptional bool
|
||||
mandatoryArgUntil int
|
||||
|
||||
flagBindings []fieldBinding
|
||||
messageType protoreflect.MessageType
|
||||
@ -39,15 +50,14 @@ func (m MessageBinder) Bind(msg protoreflect.Message, positionalArgs []string) e
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("%d", i)
|
||||
if i == m.MandatoryArgUntil && m.hasVarargs {
|
||||
if i == m.mandatoryArgUntil && m.hasVarargs {
|
||||
for _, v := range positionalArgs[i:] {
|
||||
if err := m.positionalFlagSet.Set(name, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err := m.positionalFlagSet.Set(name, positionalArgs[i])
|
||||
if err != nil {
|
||||
if err := m.positionalFlagSet.Set(name, positionalArgs[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -55,16 +65,14 @@ func (m MessageBinder) Bind(msg protoreflect.Message, positionalArgs []string) e
|
||||
|
||||
// bind positional arg values to the message
|
||||
for _, arg := range m.positionalArgs {
|
||||
err := arg.bind(msg)
|
||||
if err != nil {
|
||||
if err := arg.bind(msg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// bind flag values to the message
|
||||
for _, binding := range m.flagBindings {
|
||||
err := binding.bind(msg)
|
||||
if err != nil {
|
||||
if err := binding.bind(msg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
package autocli
|
||||
|
||||
var flagNoIndent = "no-indent"
|
||||
@ -1,6 +1,23 @@
|
||||
package keyring
|
||||
|
||||
import (
|
||||
signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
|
||||
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
)
|
||||
|
||||
// Keyring is an interface used for signing transactions.
|
||||
// It aims to be simplistic and easy to use.
|
||||
type Keyring interface {
|
||||
// List returns the names of all keys stored in the keyring.
|
||||
List() ([]string, error)
|
||||
|
||||
// LookupAddressByKeyName returns the address of the key with the given name.
|
||||
LookupAddressByKeyName(name string) ([]byte, error)
|
||||
|
||||
// GetPubKey returns the public key of the key with the given name.
|
||||
GetPubKey(name string) (cryptotypes.PubKey, error)
|
||||
|
||||
// Sign signs the given bytes with the key with the given name.
|
||||
Sign(name string, msg []byte, signMode signingv1beta1.SignMode) ([]byte, error)
|
||||
}
|
||||
|
||||
@ -1,11 +1,31 @@
|
||||
package keyring
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
|
||||
signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
|
||||
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
)
|
||||
|
||||
var _ Keyring = NoKeyring{}
|
||||
|
||||
var errNoKeyring = errors.New("no keyring configured")
|
||||
|
||||
type NoKeyring struct{}
|
||||
|
||||
func (k NoKeyring) LookupAddressByKeyName(name string) ([]byte, error) {
|
||||
return nil, errors.New("no keyring configured")
|
||||
func (k NoKeyring) List() ([]string, error) {
|
||||
return nil, errNoKeyring
|
||||
}
|
||||
|
||||
func (k NoKeyring) LookupAddressByKeyName(name string) ([]byte, error) {
|
||||
return nil, errNoKeyring
|
||||
}
|
||||
|
||||
func (k NoKeyring) GetPubKey(name string) (cryptotypes.PubKey, error) {
|
||||
return nil, errNoKeyring
|
||||
}
|
||||
|
||||
func (k NoKeyring) Sign(name string, msg []byte, signMode signingv1beta1.SignMode) ([]byte, error) {
|
||||
return nil, errNoKeyring
|
||||
}
|
||||
|
||||
@ -4,12 +4,21 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/types/dynamicpb"
|
||||
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
"cosmossdk.io/client/v2/autocli/flag"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
authtxconfig "github.com/cosmos/cosmos-sdk/x/auth/tx/config"
|
||||
)
|
||||
|
||||
// BuildMsgCommand builds the msg commands for all the provided modules. If a custom command is provided for a
|
||||
@ -97,46 +106,56 @@ func (b *Builder) AddMsgServiceCommands(cmd *cobra.Command, cmdDescriptor *autoc
|
||||
|
||||
// BuildMsgMethodCommand returns a command that outputs the JSON representation of the message.
|
||||
func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor, options *autocliv1.RpcCommandOptions) (*cobra.Command, error) {
|
||||
jsonMarshalOptions := protojson.MarshalOptions{
|
||||
Indent: " ",
|
||||
UseProtoNames: true,
|
||||
UseEnumNumbers: false,
|
||||
EmitUnpopulated: true,
|
||||
Resolver: b.TypeResolver,
|
||||
}
|
||||
|
||||
cmd, err := b.buildMethodCommandCommon(descriptor, options, func(cmd *cobra.Command, input protoreflect.Message) error {
|
||||
if noIdent, _ := cmd.Flags().GetBool(flagNoIndent); noIdent {
|
||||
jsonMarshalOptions.Indent = ""
|
||||
}
|
||||
cmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &b.ClientCtx))
|
||||
|
||||
bz, err := jsonMarshalOptions.Marshal(input.Interface())
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clientCtx, err := client.ReadPersistentCommandFlags(*b.ClientCtx, cmd.Flags())
|
||||
// enable sign mode textual and config tx options
|
||||
b.TxConfigOpts.EnabledSignModes = append(b.TxConfigOpts.EnabledSignModes, signing.SignMode_SIGN_MODE_TEXTUAL)
|
||||
b.TxConfigOpts.TextualCoinMetadataQueryFn = authtxconfig.NewGRPCCoinMetadataQueryFn(clientCtx)
|
||||
|
||||
txConfigWithTextual, err := authtx.NewTxConfigWithOptions(
|
||||
codec.NewProtoCodec(clientCtx.InterfaceRegistry),
|
||||
b.TxConfigOpts,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
clientCtx = clientCtx.WithTxConfig(txConfigWithTextual)
|
||||
clientCtx.Output = cmd.OutOrStdout()
|
||||
|
||||
cmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &clientCtx))
|
||||
if err = client.SetCmdClientContextHandler(clientCtx, cmd); err != nil {
|
||||
return err
|
||||
// set signer to signer field if empty
|
||||
fd := input.Descriptor().Fields().ByName(protoreflect.Name(flag.GetSignerFieldName(input.Descriptor())))
|
||||
if addr := input.Get(fd).String(); addr == "" {
|
||||
signerFromFlag := clientCtx.GetFromAddress()
|
||||
signer, err := b.AddressCodec.BytesToString(signerFromFlag.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set signer on message, got %v: %w", signerFromFlag, err)
|
||||
}
|
||||
|
||||
input.Set(fd, protoreflect.ValueOfString(signer))
|
||||
}
|
||||
|
||||
clientCtx, err = client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// AutoCLI uses protov2 messages, while the SDK only supports proto v1 messages.
|
||||
// Here we use dynamicpb, to create a proto v1 compatible message.
|
||||
// The SDK codec will handle protov2 -> protov1 (marshal)
|
||||
msg := dynamicpb.NewMessage(input.Descriptor())
|
||||
proto.Merge(msg, input.Interface())
|
||||
|
||||
return b.outOrStdoutFormat(cmd, bz)
|
||||
return clienttx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
|
||||
})
|
||||
|
||||
if b.AddTxConnFlags != nil {
|
||||
b.AddTxConnFlags(cmd)
|
||||
}
|
||||
|
||||
cmd.Flags().BoolP(flagNoIndent, "", false, "Do not indent JSON output")
|
||||
// silence usage only for inner txs & queries commands
|
||||
if cmd != nil {
|
||||
cmd.SilenceUsage = true
|
||||
}
|
||||
|
||||
return cmd, err
|
||||
|
||||
@ -2,135 +2,97 @@ package autocli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/golden"
|
||||
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
|
||||
"cosmossdk.io/client/v2/internal/testpb"
|
||||
)
|
||||
|
||||
var buildModuleMsgCommand = func(moduleName string, b *Builder) (*cobra.Command, error) {
|
||||
cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
err := b.AddMsgServiceCommands(cmd, testCmdMsgDesc)
|
||||
err := b.AddMsgServiceCommands(cmd, bankAutoCLI)
|
||||
return cmd, err
|
||||
}
|
||||
|
||||
var testCmdMsgDesc = &autocliv1.ServiceCommandDescriptor{
|
||||
Service: testpb.Msg_ServiceDesc.ServiceName,
|
||||
func buildCustomModuleMsgCommand(cmdDescriptor *autocliv1.ServiceCommandDescriptor) func(moduleName string, b *Builder) (*cobra.Command, error) {
|
||||
return func(moduleName string, b *Builder) (*cobra.Command, error) {
|
||||
cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
err := b.AddMsgServiceCommands(cmd, cmdDescriptor)
|
||||
return cmd, err
|
||||
}
|
||||
}
|
||||
|
||||
var bankAutoCLI = &autocliv1.ServiceCommandDescriptor{
|
||||
Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
RpcMethod: "Send",
|
||||
Use: "send [pos1] [pos2] [pos3...]",
|
||||
Version: "1.0",
|
||||
Alias: []string{"s"},
|
||||
SuggestFor: []string{"send"},
|
||||
Example: "send 1 abc {}",
|
||||
Short: "send msg the value provided by the user",
|
||||
Long: "send msg the value provided by the user as a proto JSON object with populated with the provided fields and positional arguments",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||
{
|
||||
ProtoField: "positional1",
|
||||
},
|
||||
{
|
||||
ProtoField: "positional2",
|
||||
},
|
||||
{
|
||||
ProtoField: "positional3_varargs",
|
||||
Varargs: true,
|
||||
},
|
||||
},
|
||||
FlagOptions: map[string]*autocliv1.FlagOptions{
|
||||
"u32": {
|
||||
Name: "uint32",
|
||||
Shorthand: "u",
|
||||
Usage: "some random uint32",
|
||||
},
|
||||
"i32": {
|
||||
Usage: "some random int32",
|
||||
DefaultValue: "3",
|
||||
},
|
||||
"u64": {
|
||||
Usage: "some random uint64",
|
||||
DefaultValue: "5",
|
||||
},
|
||||
"deprecated_field": {
|
||||
Deprecated: "don't use this",
|
||||
},
|
||||
"shorthand_deprecated_field": {
|
||||
Shorthand: "d",
|
||||
Deprecated: "bad idea",
|
||||
},
|
||||
"hidden_bool": {
|
||||
Hidden: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
SubCommands: map[string]*autocliv1.ServiceCommandDescriptor{
|
||||
// we test the sub-command functionality using the same service with different options
|
||||
"deprecatedmsg": {
|
||||
Service: testpb.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
RpcMethod: "Send",
|
||||
Deprecated: "dont use this",
|
||||
Short: "deprecated subcommand",
|
||||
},
|
||||
},
|
||||
},
|
||||
"skipmsg": {
|
||||
Service: testpb.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
RpcMethod: "Send",
|
||||
Skip: true,
|
||||
Short: "skip subcommand",
|
||||
},
|
||||
},
|
||||
RpcMethod: "Send",
|
||||
Use: "send [from_key_or_address] [to_address] [amount] [flags]",
|
||||
Short: "Send coins from one account to another",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "from_address"}, {ProtoField: "to_address"}, {ProtoField: "amount"}},
|
||||
},
|
||||
},
|
||||
EnhanceCustomCommand: true,
|
||||
}
|
||||
|
||||
func TestMsgOptions(t *testing.T) {
|
||||
func TestMsg(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "send",
|
||||
"5", "6", "1foo",
|
||||
"--uint32", "7",
|
||||
"--u64", "8",
|
||||
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
|
||||
"--generate-only",
|
||||
"--output", "json",
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "msg-output.golden")
|
||||
|
||||
response := out.String()
|
||||
var output testpb.MsgRequest
|
||||
err = protojson.Unmarshal([]byte(response), &output)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, output.GetU32(), uint32(7))
|
||||
assert.Equal(t, output.GetPositional1(), int32(5))
|
||||
assert.Equal(t, output.GetPositional2(), "6")
|
||||
}
|
||||
|
||||
func TestMsgOutputFormat(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
|
||||
"send", "5", "6", "1foo",
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{
|
||||
Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
RpcMethod: "Send",
|
||||
Use: "send [from_key_or_address] [to_address] [amount] [flags]",
|
||||
Short: "Send coins from one account to another",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "to_address"}, {ProtoField: "amount"}},
|
||||
// from_address should be automatically added
|
||||
},
|
||||
},
|
||||
EnhanceCustomCommand: true,
|
||||
}), "send",
|
||||
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
|
||||
"--from", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk",
|
||||
"--generate-only",
|
||||
"--output", "json",
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, strings.Contains(out.String(), "{"))
|
||||
golden.Assert(t, out.String(), "msg-output.golden")
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
|
||||
"send", "5", "6", "1foo",
|
||||
"--output", "text",
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{
|
||||
Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
RpcMethod: "Send",
|
||||
Use: "send [from_key_or_address] [to_address] [amount] [flags]",
|
||||
Short: "Send coins from one account to another",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "to_address"}, {ProtoField: "amount"}},
|
||||
FlagOptions: map[string]*autocliv1.FlagOptions{
|
||||
"from_address": {Name: "sender"}, // use a custom flag for signer
|
||||
},
|
||||
},
|
||||
},
|
||||
EnhanceCustomCommand: true,
|
||||
}), "send",
|
||||
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
|
||||
"--sender", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk",
|
||||
"--generate-only",
|
||||
"--output", "json",
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, strings.Contains(out.String(), "positional1: 5"))
|
||||
golden.Assert(t, out.String(), "msg-output.golden")
|
||||
}
|
||||
|
||||
func TestMsgOptionsError(t *testing.T) {
|
||||
@ -138,92 +100,13 @@ func TestMsgOptionsError(t *testing.T) {
|
||||
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
|
||||
"send", "5",
|
||||
"--uint32", "7",
|
||||
"--u64", "8",
|
||||
)
|
||||
assert.ErrorContains(t, err, "requires at least 2 arg(s)")
|
||||
assert.ErrorContains(t, err, "accepts 3 arg(s)")
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
|
||||
"send", "5", "6", `{"denom":"foo","amount":"1"}`,
|
||||
"--uint32", "7",
|
||||
"--u64", "abc",
|
||||
"send", "foo", "bar", "invalid",
|
||||
)
|
||||
assert.ErrorContains(t, err, "invalid argument ")
|
||||
}
|
||||
|
||||
func TestDeprecatedMsg(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
|
||||
"send", "1", "abc", "--deprecated-field", "foo",
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, strings.Contains(out.String(), "--deprecated-field has been deprecated"))
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
|
||||
"send", "1", "abc", "5stake", "-d", "foo",
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, strings.Contains(out.String(), "--shorthand-deprecated-field has been deprecated"))
|
||||
}
|
||||
|
||||
func TestEverythingMsg(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
|
||||
"send",
|
||||
"1",
|
||||
"abc",
|
||||
"1234foo",
|
||||
"4321foo",
|
||||
"--output", "json",
|
||||
"--a-bool",
|
||||
"--an-enum", "two",
|
||||
"--a-message", `{"bar":"abc", "baz":-3}`,
|
||||
"--duration", "4h3s",
|
||||
"--uint32", "27",
|
||||
"--u64", "3267246890",
|
||||
"--i32", "-253",
|
||||
"--i64", "-234602347",
|
||||
"--str", "def",
|
||||
"--timestamp", "2019-01-02T00:01:02Z",
|
||||
"--a-coin", "10000000foo",
|
||||
"--an-address", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk",
|
||||
"--bz", "c2RncXdlZndkZ3NkZw==",
|
||||
"--page-count-total",
|
||||
"--page-key", "MTIzNTQ4N3NnaGRhcw==",
|
||||
"--page-limit", "1000",
|
||||
"--page-offset", "10",
|
||||
"--page-reverse",
|
||||
"--bools", "true",
|
||||
"--bools", "false,false,true",
|
||||
"--enums", "one",
|
||||
"--enums", "five",
|
||||
"--enums", "two",
|
||||
"--strings", "abc",
|
||||
"--strings", "xyz",
|
||||
"--strings", "xyz,qrs",
|
||||
"--durations", "3s",
|
||||
"--durations", "5s",
|
||||
"--durations", "10h",
|
||||
"--some-messages", "{}",
|
||||
"--some-messages", `{"bar":"baz"}`,
|
||||
"--some-messages", `{"baz":-1}`,
|
||||
"--uints", "1,2,3",
|
||||
"--uints", "4",
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
response := out.String()
|
||||
var output testpb.MsgRequest
|
||||
err = protojson.Unmarshal([]byte(response), &output)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, output.GetU32(), uint32(27))
|
||||
assert.Equal(t, output.GetU64(), uint64(3267246890))
|
||||
assert.Equal(t, output.GetPositional1(), int32(1))
|
||||
assert.Equal(t, output.GetPositional2(), "abc")
|
||||
assert.Equal(t, output.GetABool(), true)
|
||||
assert.Equal(t, output.GetAnEnum(), testpb.Enum_ENUM_TWO)
|
||||
assert.ErrorContains(t, err, "invalid argument")
|
||||
}
|
||||
|
||||
func TestHelpMsg(t *testing.T) {
|
||||
@ -236,19 +119,18 @@ func TestHelpMsg(t *testing.T) {
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "send", "-h")
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "help-echo-msg.golden")
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "deprecatedmsg", "send", "-h")
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "help-deprecated-msg.golden")
|
||||
}
|
||||
|
||||
func TestBuildMsgCommand(t *testing.T) {
|
||||
func TestBuildCustomMsgCommand(t *testing.T) {
|
||||
b := &Builder{}
|
||||
customCommandCalled := false
|
||||
appOptions := AppOptions{
|
||||
ModuleOptions: map[string]*autocliv1.ModuleOptions{
|
||||
"test": {
|
||||
Tx: testCmdMsgDesc,
|
||||
Tx: &autocliv1.ServiceCommandDescriptor{
|
||||
Service: testpb.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -264,46 +146,6 @@ func TestBuildMsgCommand(t *testing.T) {
|
||||
assert.Assert(t, customCommandCalled)
|
||||
}
|
||||
|
||||
func TestErrorBuildMsgCommand(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
b := fixture.b
|
||||
b.AddQueryConnFlags = nil
|
||||
b.AddTxConnFlags = nil
|
||||
|
||||
commandDescriptor := &autocliv1.ServiceCommandDescriptor{
|
||||
Service: testpb.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
RpcMethod: "Send",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||
{
|
||||
ProtoField: "un-existent-proto-field",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
appOptions := AppOptions{
|
||||
ModuleOptions: map[string]*autocliv1.ModuleOptions{
|
||||
"test": {
|
||||
Tx: commandDescriptor,
|
||||
},
|
||||
},
|
||||
AddressCodec: b.AddressCodec,
|
||||
ValidatorAddressCodec: b.ValidatorAddressCodec,
|
||||
ClientCtx: b.ClientCtx,
|
||||
}
|
||||
|
||||
_, err := b.BuildMsgCommand(appOptions, nil)
|
||||
assert.ErrorContains(t, err, "can't find field un-existent-proto-field")
|
||||
|
||||
nonExistentService := &autocliv1.ServiceCommandDescriptor{Service: "un-existent-service"}
|
||||
appOptions.ModuleOptions["test"].Tx = nonExistentService
|
||||
_, err = b.BuildMsgCommand(appOptions, nil)
|
||||
assert.ErrorContains(t, err, "can't find service un-existent-service")
|
||||
}
|
||||
|
||||
func TestNotFoundErrorsMsg(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
b := fixture.b
|
||||
@ -355,38 +197,3 @@ func TestNotFoundErrorsMsg(t *testing.T) {
|
||||
})
|
||||
assert.ErrorContains(t, err, "can't find field un-existent-flag")
|
||||
}
|
||||
|
||||
func TestEnhanceMessageCommand(t *testing.T) {
|
||||
b := &Builder{}
|
||||
// Test that the command has a subcommand
|
||||
cmd := &cobra.Command{Use: "test"}
|
||||
cmd.AddCommand(&cobra.Command{Use: "test"})
|
||||
|
||||
appOptions := AppOptions{
|
||||
ModuleOptions: map[string]*autocliv1.ModuleOptions{
|
||||
"test": {},
|
||||
},
|
||||
}
|
||||
|
||||
err := b.enhanceCommandCommon(cmd, msgCmdType, appOptions, map[string]*cobra.Command{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
cmd = &cobra.Command{Use: "test"}
|
||||
|
||||
appOptions.ModuleOptions = map[string]*autocliv1.ModuleOptions{}
|
||||
customCommands := map[string]*cobra.Command{
|
||||
"test2": {Use: "test"},
|
||||
}
|
||||
err = b.enhanceCommandCommon(cmd, msgCmdType, appOptions, customCommands)
|
||||
assert.NilError(t, err)
|
||||
|
||||
cmd = &cobra.Command{Use: "test"}
|
||||
appOptions = AppOptions{
|
||||
ModuleOptions: map[string]*autocliv1.ModuleOptions{
|
||||
"test": {Tx: nil},
|
||||
},
|
||||
}
|
||||
customCommands = map[string]*cobra.Command{}
|
||||
err = b.enhanceCommandCommon(cmd, msgCmdType, appOptions, customCommands)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
"cosmossdk.io/client/v2/internal/flags"
|
||||
"cosmossdk.io/client/v2/internal/util"
|
||||
)
|
||||
|
||||
@ -111,7 +112,7 @@ func (b *Builder) BuildQueryMethodCommand(descriptor protoreflect.MethodDescript
|
||||
}
|
||||
|
||||
cmd, err := b.buildMethodCommandCommon(descriptor, options, func(cmd *cobra.Command, input protoreflect.Message) error {
|
||||
if noIndent, _ := cmd.Flags().GetBool(flagNoIndent); noIndent {
|
||||
if noIndent, _ := cmd.Flags().GetBool(flags.FlagNoIndent); noIndent {
|
||||
encoderOptions.Indent = ""
|
||||
}
|
||||
|
||||
@ -141,7 +142,12 @@ func (b *Builder) BuildQueryMethodCommand(descriptor protoreflect.MethodDescript
|
||||
if b.AddQueryConnFlags != nil {
|
||||
b.AddQueryConnFlags(cmd)
|
||||
|
||||
cmd.Flags().BoolP(flagNoIndent, "", false, "Do not indent JSON output")
|
||||
cmd.Flags().BoolP(flags.FlagNoIndent, "", false, "Do not indent JSON output")
|
||||
}
|
||||
|
||||
// silence usage only for inner txs & queries commands
|
||||
if cmd != nil {
|
||||
cmd.SilenceUsage = true
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
|
||||
@ -613,7 +613,7 @@ func TestOutputFormat(t *testing.T) {
|
||||
assert.Assert(t, strings.Contains(out.String(), " positional1: 1"))
|
||||
}
|
||||
|
||||
func TestHelp(t *testing.T) {
|
||||
func TestHelpQuery(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "-h")
|
||||
@ -633,7 +633,7 @@ func TestHelp(t *testing.T) {
|
||||
golden.Assert(t, out.String(), "help-skip.golden")
|
||||
}
|
||||
|
||||
func TestDeprecated(t *testing.T) {
|
||||
func TestDeprecatedQuery(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "echo",
|
||||
@ -670,7 +670,7 @@ func TestBuildCustomQueryCommand(t *testing.T) {
|
||||
assert.Assert(t, customCommandCalled)
|
||||
}
|
||||
|
||||
func TestNotFoundErrors(t *testing.T) {
|
||||
func TestNotFoundErrorsQuery(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
b := fixture.b
|
||||
b.AddQueryConnFlags = nil
|
||||
|
||||
@ -1,65 +0,0 @@
|
||||
Command "send" is deprecated, dont use this
|
||||
deprecated subcommand
|
||||
|
||||
Usage:
|
||||
test deprecatedmsg send [flags]
|
||||
|
||||
Flags:
|
||||
--a-bool
|
||||
--a-coin cosmos.base.v1beta1.Coin
|
||||
--a-message testpb.AMessage (json)
|
||||
--a-validator-address account address or key name
|
||||
-a, --account-number uint The account number of the signing account (offline mode only)
|
||||
--an-address account address or key name
|
||||
--an-enum Enum (unspecified | one | two | five | neg-three) (default unspecified)
|
||||
--aux Generate aux signer data instead of sending a tx
|
||||
--bools bools (default [])
|
||||
-b, --broadcast-mode string Transaction broadcasting mode (sync|async) (default "sync")
|
||||
--bz binary
|
||||
--chain-id string The network chain ID
|
||||
--deprecated-field string
|
||||
--dry-run ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible)
|
||||
--duration duration
|
||||
--durations duration (repeated)
|
||||
--enums Enum (unspecified | one | two | five | neg-three) (repeated)
|
||||
--fee-granter string Fee granter grants fees for the transaction
|
||||
--fee-payer string Fee payer pays fees for the transaction instead of deducting from the signer
|
||||
--fees string Fees to pay along with transaction; eg: 10uatom
|
||||
--from string Name or address of private key with which to sign
|
||||
--gas string gas limit to set per-transaction; set to "auto" to calculate sufficient gas automatically. Note: "auto" option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of "fees". (default 200000)
|
||||
--gas-adjustment float adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored (default 1)
|
||||
--gas-prices string Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom)
|
||||
--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
|
||||
--hidden-bool
|
||||
--i32 int32
|
||||
--i64 int
|
||||
--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
|
||||
--no-indent Do not indent JSON output
|
||||
--node string <host>:<port> to CometBFT rpc interface for this chain (default "tcp://localhost:26657")
|
||||
--note string Note to add a description to the transaction (previously --memo)
|
||||
--offline Offline mode (does not allow any online functionality)
|
||||
-o, --output string Output format (text|json) (default "json")
|
||||
--page-count-total
|
||||
--page-key binary
|
||||
--page-limit uint
|
||||
--page-offset uint
|
||||
--page-reverse
|
||||
--positional1 int32
|
||||
--positional2 string
|
||||
--positional3-varargs cosmos.base.v1beta1.Coin (repeated)
|
||||
-s, --sequence uint The sequence number of the signing account (offline mode only)
|
||||
--shorthand-deprecated-field string
|
||||
--sign-mode string Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature
|
||||
--some-messages testpb.AMessage (json) (repeated)
|
||||
--str string
|
||||
--strings strings
|
||||
--timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height
|
||||
--timestamp timestamp (RFC 3339)
|
||||
--tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator
|
||||
--u32 uint32
|
||||
--u64 uint
|
||||
--uints uints (default [])
|
||||
-y, --yes Skip tx broadcasting prompt confirmation
|
||||
91
client/v2/autocli/testdata/help-echo-msg.golden
vendored
91
client/v2/autocli/testdata/help-echo-msg.golden
vendored
@ -1,67 +1,32 @@
|
||||
send msg the value provided by the user as a proto JSON object with populated with the provided fields and positional arguments
|
||||
Send coins from one account to another
|
||||
|
||||
Usage:
|
||||
test send [pos1] [pos2] [pos3...] [flags]
|
||||
|
||||
Aliases:
|
||||
send, s
|
||||
|
||||
Examples:
|
||||
send 1 abc {}
|
||||
test send [from_key_or_address] [to_address] [amount] [flags]
|
||||
|
||||
Flags:
|
||||
--a-bool
|
||||
--a-coin cosmos.base.v1beta1.Coin
|
||||
--a-message testpb.AMessage (json)
|
||||
--a-validator-address account address or key name
|
||||
-a, --account-number uint The account number of the signing account (offline mode only)
|
||||
--an-address account address or key name
|
||||
--an-enum Enum (unspecified | one | two | five | neg-three) (default unspecified)
|
||||
--aux Generate aux signer data instead of sending a tx
|
||||
--bools bools (default [])
|
||||
-b, --broadcast-mode string Transaction broadcasting mode (sync|async) (default "sync")
|
||||
--bz binary
|
||||
--chain-id string The network chain ID
|
||||
--deprecated-field string (DEPRECATED: don't use this)
|
||||
--dry-run ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible)
|
||||
--duration duration
|
||||
--durations duration (repeated)
|
||||
--enums Enum (unspecified | one | two | five | neg-three) (repeated)
|
||||
--fee-granter string Fee granter grants fees for the transaction
|
||||
--fee-payer string Fee payer pays fees for the transaction instead of deducting from the signer
|
||||
--fees string Fees to pay along with transaction; eg: 10uatom
|
||||
--from string Name or address of private key with which to sign
|
||||
--gas string gas limit to set per-transaction; set to "auto" to calculate sufficient gas automatically. Note: "auto" option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of "fees". (default 200000)
|
||||
--gas-adjustment float adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored (default 1)
|
||||
--gas-prices string Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom)
|
||||
--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
|
||||
--i32 int32 some random int32
|
||||
--i64 int
|
||||
--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
|
||||
--no-indent Do not indent JSON output
|
||||
--node string <host>:<port> to CometBFT rpc interface for this chain (default "tcp://localhost:26657")
|
||||
--note string Note to add a description to the transaction (previously --memo)
|
||||
--offline Offline mode (does not allow any online functionality)
|
||||
-o, --output string Output format (text|json) (default "json")
|
||||
--page-count-total
|
||||
--page-key binary
|
||||
--page-limit uint
|
||||
--page-offset uint
|
||||
--page-reverse
|
||||
-s, --sequence uint The sequence number of the signing account (offline mode only)
|
||||
-d, --shorthand-deprecated-field string (DEPRECATED: bad idea)
|
||||
--sign-mode string Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature
|
||||
--some-messages testpb.AMessage (json) (repeated)
|
||||
--str string
|
||||
--strings strings
|
||||
--timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height
|
||||
--timestamp timestamp (RFC 3339)
|
||||
--tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator
|
||||
--u64 uint some random uint64
|
||||
-u, --uint32 uint32 some random uint32
|
||||
--uints uints (default [])
|
||||
-v, --version version for send
|
||||
-y, --yes Skip tx broadcasting prompt confirmation
|
||||
-a, --account-number uint The account number of the signing account (offline mode only)
|
||||
--aux Generate aux signer data instead of sending a tx
|
||||
-b, --broadcast-mode string Transaction broadcasting mode (sync|async) (default "sync")
|
||||
--chain-id string The network chain ID
|
||||
--dry-run ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible)
|
||||
--fee-granter string Fee granter grants fees for the transaction
|
||||
--fee-payer string Fee payer pays fees for the transaction instead of deducting from the signer
|
||||
--fees string Fees to pay along with transaction; eg: 10uatom
|
||||
--from string Name or address of private key with which to sign
|
||||
--gas string gas limit to set per-transaction; set to "auto" to calculate sufficient gas automatically. Note: "auto" option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of "fees". (default 200000)
|
||||
--gas-adjustment float adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored (default 1)
|
||||
--gas-prices string Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom)
|
||||
--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
|
||||
--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
|
||||
--node string <host>:<port> to CometBFT rpc interface for this chain (default "tcp://localhost:26657")
|
||||
--note string Note to add a description to the transaction (previously --memo)
|
||||
--offline Offline mode (does not allow any online functionality)
|
||||
-o, --output string Output format (text|json) (default "json")
|
||||
-s, --sequence uint The sequence number of the signing account (offline mode only)
|
||||
--sign-mode string Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature
|
||||
--timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height
|
||||
--tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator
|
||||
-y, --yes Skip tx broadcasting prompt confirmation
|
||||
|
||||
@ -5,11 +5,13 @@ Usage:
|
||||
test [command]
|
||||
|
||||
Available Commands:
|
||||
completion Generate the autocompletion script for the specified shell
|
||||
deprecatedmsg Tx commands for the testpb.Msg service
|
||||
help Help about any command
|
||||
send send msg the value provided by the user
|
||||
skipmsg Tx commands for the testpb.Msg service
|
||||
burn
|
||||
completion Generate the autocompletion script for the specified shell
|
||||
help Help about any command
|
||||
multi-send
|
||||
send Send coins from one account to another
|
||||
set-send-enabled
|
||||
update-params
|
||||
|
||||
Flags:
|
||||
-h, --help help for test
|
||||
|
||||
1
client/v2/autocli/testdata/msg-output.golden
vendored
Normal file
1
client/v2/autocli/testdata/msg-output.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"body":{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","to_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","amount":[{"denom":"foo","amount":"1"}]}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":[]}
|
||||
@ -6,15 +6,14 @@ require (
|
||||
cosmossdk.io/api v0.7.1
|
||||
cosmossdk.io/core v0.11.0
|
||||
cosmossdk.io/depinject v1.0.0-alpha.4
|
||||
cosmossdk.io/log v1.2.1
|
||||
cosmossdk.io/x/tx v0.10.0
|
||||
github.com/cockroachdb/errors v1.11.1
|
||||
github.com/cosmos/cosmos-proto v1.0.0-beta.3
|
||||
github.com/cosmos/cosmos-sdk v0.50.0-rc.1
|
||||
github.com/cosmos/cosmos-sdk v0.50.0-rc.1.0.20231005110808-059498db8691
|
||||
github.com/cosmos/gogoproto v1.4.11
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
google.golang.org/grpc v1.58.1
|
||||
google.golang.org/grpc v1.58.2
|
||||
google.golang.org/protobuf v1.31.0
|
||||
gotest.tools/v3 v3.5.0
|
||||
sigs.k8s.io/yaml v1.3.0
|
||||
@ -23,6 +22,7 @@ require (
|
||||
require (
|
||||
cosmossdk.io/collections v0.4.0 // indirect
|
||||
cosmossdk.io/errors v1.0.0 // indirect
|
||||
cosmossdk.io/log v1.2.1 // indirect
|
||||
cosmossdk.io/math v1.1.3-rc.1 // indirect
|
||||
cosmossdk.io/store v1.0.0-rc.0 // indirect
|
||||
filippo.io/edwards25519 v1.0.0 // indirect
|
||||
@ -69,6 +69,7 @@ require (
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/glog v1.1.0 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
@ -109,7 +110,7 @@ require (
|
||||
github.com/mtibben/percent v0.2.1 // indirect
|
||||
github.com/oasisprotocol/curve25519-voi v0.0.0-20230110094441-db37f07504ce // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
@ -142,12 +143,14 @@ require (
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/term v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
nhooyr.io/websocket v1.8.6 // indirect
|
||||
pgregory.net/rapid v1.1.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/cosmos/cosmos-sdk => ./../../
|
||||
|
||||
@ -178,8 +178,6 @@ github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0
|
||||
github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U=
|
||||
github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o=
|
||||
github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I=
|
||||
github.com/cosmos/cosmos-sdk v0.50.0-rc.1 h1:1Z+SgLg8S2+DoiePz9aO5dSjJUgag8VFhFUSD/HGvOU=
|
||||
github.com/cosmos/cosmos-sdk v0.50.0-rc.1/go.mod h1:JbgPLZrh+yX+4+n1CPJ/uL9HrhZw6QVg0q7cTq2Iwq0=
|
||||
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
|
||||
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
|
||||
github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE=
|
||||
@ -641,8 +639,8 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
|
||||
github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b h1:vab8deKC4QoIfm9fJM59iuNz1ELGsuLoYYpiF+pHiG8=
|
||||
@ -795,6 +793,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo=
|
||||
github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
|
||||
github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c=
|
||||
@ -874,6 +873,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -944,6 +944,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -1099,6 +1100,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
|
||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -1176,12 +1178,12 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb h1:XFBgcDwm7irdHTbz4Zk2h7Mh+eis4nfJEFQFYzJzuIA=
|
||||
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
@ -1208,8 +1210,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58=
|
||||
google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I=
|
||||
google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
||||
19
client/v2/internal/flags/flags.go
Normal file
19
client/v2/internal/flags/flags.go
Normal file
@ -0,0 +1,19 @@
|
||||
package flags
|
||||
|
||||
// This defines flag names that can be used in autocli.
|
||||
const (
|
||||
// FlagFrom is the flag to set the from address with which to sign the transaction.
|
||||
FlagFrom = "from"
|
||||
|
||||
// FlagOutput is the flag to set the output format.
|
||||
FlagOutput = "output"
|
||||
|
||||
// FlagNoIndent is the flag to not indent the output.
|
||||
FlagNoIndent = "no-indent"
|
||||
)
|
||||
|
||||
// List of supported output formats
|
||||
const (
|
||||
OutputFormatJSON = "json"
|
||||
OutputFormatText = "text"
|
||||
)
|
||||
@ -12,16 +12,26 @@ import (
|
||||
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
type bankSendWrapper struct {
|
||||
*banktypes.MsgSend
|
||||
}
|
||||
|
||||
func (msg bankSendWrapper) GetSigners() []sdk.AccAddress {
|
||||
fromAddress, _ := sdk.AccAddressFromBech32(msg.FromAddress)
|
||||
return []sdk.AccAddress{fromAddress}
|
||||
}
|
||||
|
||||
func BenchmarkLegacyGetSigners(b *testing.B) {
|
||||
_, _, addr := testdata.KeyTestPubAddr()
|
||||
msg := &banktypes.MsgSend{
|
||||
msg := bankSendWrapper{&banktypes.MsgSend{
|
||||
FromAddress: addr.String(),
|
||||
ToAddress: "",
|
||||
Amount: nil,
|
||||
}
|
||||
}}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
fmt "fmt"
|
||||
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
|
||||
@ -63,13 +64,21 @@ func NewAnyWithValue(v proto.Message) (*Any, error) {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrPackAny, "Expecting non nil value to create a new Any")
|
||||
}
|
||||
|
||||
bz, err := proto.Marshal(v)
|
||||
var (
|
||||
bz []byte
|
||||
err error
|
||||
)
|
||||
if msg, ok := v.(protov2.Message); ok {
|
||||
bz, err = protov2.Marshal(msg)
|
||||
} else {
|
||||
bz, err = proto.Marshal(v)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Any{
|
||||
TypeUrl: "/" + proto.MessageName(v),
|
||||
TypeUrl: MsgTypeURL(v),
|
||||
Value: bz,
|
||||
cachedValue: v,
|
||||
}, nil
|
||||
@ -94,8 +103,17 @@ func UnsafePackAny(x interface{}) *Any {
|
||||
// the packed value so that it can be retrieved from GetCachedValue without
|
||||
// unmarshaling
|
||||
func (any *Any) pack(x proto.Message) error {
|
||||
any.TypeUrl = "/" + proto.MessageName(x)
|
||||
bz, err := proto.Marshal(x)
|
||||
any.TypeUrl = MsgTypeURL(x)
|
||||
|
||||
var (
|
||||
bz []byte
|
||||
err error
|
||||
)
|
||||
if msg, ok := x.(protov2.Message); ok {
|
||||
bz, err = protov2.Marshal(msg)
|
||||
} else {
|
||||
bz, err = proto.Marshal(x)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ func (registry *interfaceRegistry) EnsureRegistered(impl interface{}) error {
|
||||
// same typeURL.
|
||||
func (registry *interfaceRegistry) RegisterImplementations(iface interface{}, impls ...proto.Message) {
|
||||
for _, impl := range impls {
|
||||
typeURL := "/" + proto.MessageName(impl)
|
||||
typeURL := MsgTypeURL(impl)
|
||||
registry.registerImpl(iface, typeURL, impl)
|
||||
}
|
||||
}
|
||||
|
||||
15
codec/types/util.go
Normal file
15
codec/types/util.go
Normal file
@ -0,0 +1,15 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// MsgTypeURL returns the TypeURL of a `sdk.Msg`.
|
||||
func MsgTypeURL(msg proto.Message) string {
|
||||
if m, ok := msg.(protov2.Message); ok {
|
||||
return "/" + string(m.ProtoReflect().Descriptor().FullName())
|
||||
}
|
||||
|
||||
return "/" + proto.MessageName(msg)
|
||||
}
|
||||
86
crypto/keyring/autocli.go
Normal file
86
crypto/keyring/autocli.go
Normal file
@ -0,0 +1,86 @@
|
||||
package keyring
|
||||
|
||||
import (
|
||||
signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
|
||||
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
)
|
||||
|
||||
// autoCLIKeyring represents the keyring interface used by the AutoCLI.
|
||||
// It purposely does not import the AutoCLI package to avoid circular dependencies.
|
||||
type autoCLIKeyring interface {
|
||||
// List returns the names of all keys stored in the keyring.
|
||||
List() ([]string, error)
|
||||
|
||||
// LookupAddressByKeyName returns the address of the key with the given name.
|
||||
LookupAddressByKeyName(name string) ([]byte, error)
|
||||
|
||||
// GetPubKey returns the public key of the key with the given name.
|
||||
GetPubKey(name string) (cryptotypes.PubKey, error)
|
||||
|
||||
// Sign signs the given bytes with the key with the given name.
|
||||
Sign(name string, msg []byte, signMode signingv1beta1.SignMode) ([]byte, error)
|
||||
}
|
||||
|
||||
// NewAutoCLIKeyring wraps the SDK keyring and make it compatible with the AutoCLI keyring interfaces.
|
||||
func NewAutoCLIKeyring(kr Keyring) (autoCLIKeyring, error) {
|
||||
return &autoCLIKeyringAdapter{kr}, nil
|
||||
}
|
||||
|
||||
type autoCLIKeyringAdapter struct {
|
||||
Keyring
|
||||
}
|
||||
|
||||
func (a *autoCLIKeyringAdapter) List() ([]string, error) {
|
||||
list, err := a.Keyring.List()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
names := make([]string, len(list))
|
||||
for i, key := range list {
|
||||
names[i] = key.Name
|
||||
}
|
||||
|
||||
return names, nil
|
||||
}
|
||||
|
||||
// LookupAddressByKeyName returns the address of a key stored in the keyring
|
||||
func (a *autoCLIKeyringAdapter) LookupAddressByKeyName(name string) ([]byte, error) {
|
||||
record, err := a.Keyring.Key(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr, err := record.GetAddress()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
func (a *autoCLIKeyringAdapter) GetPubKey(name string) (cryptotypes.PubKey, error) {
|
||||
record, err := a.Keyring.Key(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return record.GetPubKey()
|
||||
}
|
||||
|
||||
func (a *autoCLIKeyringAdapter) Sign(name string, msg []byte, signMode signingv1beta1.SignMode) ([]byte, error) {
|
||||
record, err := a.Keyring.Key(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sdkSignMode, err := authsigning.APISignModeToInternal(signMode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signBytes, _, err := a.Keyring.Sign(record.Name, msg, sdkSignMode)
|
||||
return signBytes, err
|
||||
}
|
||||
@ -102,9 +102,6 @@ type Keyring interface {
|
||||
Exporter
|
||||
|
||||
Migrator
|
||||
|
||||
// Implements client/v2 keyring interface
|
||||
LookupAddressByKeyName(name string) ([]byte, error)
|
||||
}
|
||||
|
||||
// Signer is implemented by key stores that want to provide signing capabilities.
|
||||
@ -622,21 +619,6 @@ func (ks keystore) SupportedAlgorithms() (SigningAlgoList, SigningAlgoList) {
|
||||
return ks.options.SupportedAlgos, ks.options.SupportedAlgosLedger
|
||||
}
|
||||
|
||||
// LookupAddressByKeyName returns the address of a key stored in the keyring
|
||||
func (ks keystore) LookupAddressByKeyName(name string) ([]byte, error) {
|
||||
record, err := ks.Key(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr, err := record.GetAddress()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
// SignWithLedger signs a binary message with the ledger device referenced by an Info object
|
||||
// and returns the signed bytes and the public key. It returns an error if the device could
|
||||
// not be queried or it returned an error.
|
||||
|
||||
@ -4,7 +4,7 @@ go 1.21
|
||||
|
||||
require (
|
||||
cosmossdk.io/api v0.7.1
|
||||
cosmossdk.io/client/v2 v2.0.0-20230925151519-64e0e8980834
|
||||
cosmossdk.io/client/v2 v2.0.0-20231005120212-0062bf2e7141
|
||||
cosmossdk.io/collections v0.4.0 // indirect
|
||||
cosmossdk.io/core v0.11.0
|
||||
cosmossdk.io/depinject v1.0.0-alpha.4
|
||||
@ -33,7 +33,7 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.6 // indirect
|
||||
cloud.google.com/go v0.110.7 // indirect
|
||||
cloud.google.com/go/compute v1.23.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.1 // indirect
|
||||
@ -142,7 +142,7 @@ require (
|
||||
github.com/mtibben/percent v0.2.1 // indirect
|
||||
github.com/oasisprotocol/curve25519-voi v0.0.0-20230110094441-db37f07504ce // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
@ -177,10 +177,10 @@ require (
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.126.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/grpc v1.58.1 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
|
||||
google.golang.org/grpc v1.58.2 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
@ -32,8 +32,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9
|
||||
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
|
||||
cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
|
||||
cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
|
||||
cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q=
|
||||
cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o=
|
||||
cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw=
|
||||
cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY=
|
||||
cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=
|
||||
@ -189,8 +189,8 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V
|
||||
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
|
||||
cosmossdk.io/api v0.7.1 h1:PNQ1xN8+/0hj/sSD0ANqjkgfXFys+bZ5L8Hg7uzoUTU=
|
||||
cosmossdk.io/api v0.7.1/go.mod h1:ure9edhcROIHsngavM6mBLilMGFnfjhV/AaYhEMUkdo=
|
||||
cosmossdk.io/client/v2 v2.0.0-20230925151519-64e0e8980834 h1:08rY7bypF6jSE8XGJ9i5iiEO20gExOziLnI2NbKIxWo=
|
||||
cosmossdk.io/client/v2 v2.0.0-20230925151519-64e0e8980834/go.mod h1:6kpnEjoEwZIFZkxMPy+/8tKJggRy2OQ6X1LzrrVu8nM=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231005120212-0062bf2e7141 h1:ovyUcvPX740eqC7bnGZpw4yn5GS2bNZ5jacRqiDwqU8=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231005120212-0062bf2e7141/go.mod h1:0ycdqzdjVeUdKqgBbaxqSsc1C18GJc3uEF+uphv/MPg=
|
||||
cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=
|
||||
cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0=
|
||||
cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo=
|
||||
@ -866,8 +866,8 @@ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144T
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
|
||||
github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b h1:vab8deKC4QoIfm9fJM59iuNz1ELGsuLoYYpiF+pHiG8=
|
||||
@ -1605,12 +1605,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw
|
||||
google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
|
||||
google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
|
||||
google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb h1:XFBgcDwm7irdHTbz4Zk2h7Mh+eis4nfJEFQFYzJzuIA=
|
||||
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
@ -1652,8 +1652,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu
|
||||
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58=
|
||||
google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I=
|
||||
google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/config"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
@ -97,8 +98,8 @@ func NewRootCmd() *cobra.Command {
|
||||
// add keyring to autocli opts
|
||||
autoCliOpts := tempApp.AutoCliOpts()
|
||||
initClientCtx, _ = config.ReadFromClientConfig(initClientCtx)
|
||||
autoCliOpts.Keyring = initClientCtx.Keyring
|
||||
autoCliOpts.ClientCtx = &initClientCtx
|
||||
autoCliOpts.Keyring, _ = keyring.NewAutoCLIKeyring(initClientCtx.Keyring)
|
||||
autoCliOpts.ClientCtx = initClientCtx
|
||||
|
||||
if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil {
|
||||
panic(err)
|
||||
|
||||
@ -18,6 +18,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client/config"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
@ -33,7 +34,7 @@ func NewRootCmd() *cobra.Command {
|
||||
txConfigOpts tx.ConfigOptions
|
||||
autoCliOpts autocli.AppOptions
|
||||
moduleBasicManager module.BasicManager
|
||||
initClientCtx *client.Context
|
||||
clientCtx client.Context
|
||||
)
|
||||
|
||||
if err := depinject.Inject(
|
||||
@ -50,7 +51,7 @@ func NewRootCmd() *cobra.Command {
|
||||
&txConfigOpts,
|
||||
&autoCliOpts,
|
||||
&moduleBasicManager,
|
||||
&initClientCtx,
|
||||
&clientCtx,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -64,7 +65,6 @@ func NewRootCmd() *cobra.Command {
|
||||
cmd.SetOut(cmd.OutOrStdout())
|
||||
cmd.SetErr(cmd.ErrOrStderr())
|
||||
|
||||
clientCtx := *initClientCtx
|
||||
clientCtx = clientCtx.WithCmdContext(cmd.Context())
|
||||
clientCtx, err := client.ReadPersistentCommandFlags(clientCtx, cmd.Flags())
|
||||
if err != nil {
|
||||
@ -87,7 +87,6 @@ func NewRootCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
clientCtx = clientCtx.WithTxConfig(txConfigWithTextual)
|
||||
|
||||
if err := client.SetCmdClientContextHandler(clientCtx, cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -99,7 +98,7 @@ func NewRootCmd() *cobra.Command {
|
||||
},
|
||||
}
|
||||
|
||||
initRootCmd(rootCmd, initClientCtx.TxConfig, initClientCtx.InterfaceRegistry, initClientCtx.Codec, moduleBasicManager)
|
||||
initRootCmd(rootCmd, clientCtx.TxConfig, clientCtx.InterfaceRegistry, clientCtx.Codec, moduleBasicManager)
|
||||
|
||||
if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil {
|
||||
panic(err)
|
||||
@ -113,7 +112,7 @@ func ProvideClientContext(
|
||||
interfaceRegistry codectypes.InterfaceRegistry,
|
||||
txConfig client.TxConfig,
|
||||
legacyAmino *codec.LegacyAmino,
|
||||
) *client.Context {
|
||||
) client.Context {
|
||||
clientCtx := client.Context{}.
|
||||
WithCodec(appCodec).
|
||||
WithInterfaceRegistry(interfaceRegistry).
|
||||
@ -127,14 +126,14 @@ func ProvideClientContext(
|
||||
// Read the config again to overwrite the default values with the values from the config file
|
||||
clientCtx, _ = config.ReadFromClientConfig(clientCtx)
|
||||
|
||||
return &clientCtx
|
||||
return clientCtx
|
||||
}
|
||||
|
||||
func ProvideKeyring(clientCtx *client.Context, addressCodec address.Codec) (clientv2keyring.Keyring, error) {
|
||||
kb, err := client.NewKeyringFromBackend(*clientCtx, clientCtx.Keyring.Backend())
|
||||
func ProvideKeyring(clientCtx client.Context, addressCodec address.Codec) (clientv2keyring.Keyring, error) {
|
||||
kb, err := client.NewKeyringFromBackend(clientCtx, clientCtx.Keyring.Backend())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return kb, nil
|
||||
return keyring.NewAutoCLIKeyring(kb)
|
||||
}
|
||||
|
||||
14
tests/go.mod
14
tests/go.mod
@ -25,19 +25,19 @@ require (
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
google.golang.org/grpc v1.58.1
|
||||
google.golang.org/grpc v1.58.2
|
||||
google.golang.org/protobuf v1.31.0
|
||||
gotest.tools/v3 v3.5.1
|
||||
pgregory.net/rapid v1.1.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.6 // indirect
|
||||
cloud.google.com/go v0.110.7 // indirect
|
||||
cloud.google.com/go/compute v1.23.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.1 // indirect
|
||||
cloud.google.com/go/storage v1.30.1 // indirect
|
||||
cosmossdk.io/client/v2 v2.0.0-20230925151519-64e0e8980834 // indirect
|
||||
cosmossdk.io/client/v2 v2.0.0-20231005120212-0062bf2e7141 // indirect
|
||||
cosmossdk.io/collections v0.4.0 // indirect
|
||||
cosmossdk.io/x/circuit v0.0.0-20230925151519-64e0e8980834 // indirect
|
||||
filippo.io/edwards25519 v1.0.0 // indirect
|
||||
@ -140,7 +140,7 @@ require (
|
||||
github.com/mtibben/percent v0.2.1 // indirect
|
||||
github.com/oasisprotocol/curve25519-voi v0.0.0-20230110094441-db37f07504ce // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
@ -178,9 +178,9 @@ require (
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.126.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
28
tests/go.sum
28
tests/go.sum
@ -32,8 +32,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9
|
||||
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
|
||||
cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
|
||||
cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
|
||||
cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q=
|
||||
cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o=
|
||||
cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw=
|
||||
cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY=
|
||||
cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=
|
||||
@ -189,8 +189,8 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V
|
||||
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
|
||||
cosmossdk.io/api v0.7.1 h1:PNQ1xN8+/0hj/sSD0ANqjkgfXFys+bZ5L8Hg7uzoUTU=
|
||||
cosmossdk.io/api v0.7.1/go.mod h1:ure9edhcROIHsngavM6mBLilMGFnfjhV/AaYhEMUkdo=
|
||||
cosmossdk.io/client/v2 v2.0.0-20230925151519-64e0e8980834 h1:08rY7bypF6jSE8XGJ9i5iiEO20gExOziLnI2NbKIxWo=
|
||||
cosmossdk.io/client/v2 v2.0.0-20230925151519-64e0e8980834/go.mod h1:6kpnEjoEwZIFZkxMPy+/8tKJggRy2OQ6X1LzrrVu8nM=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231005120212-0062bf2e7141 h1:ovyUcvPX740eqC7bnGZpw4yn5GS2bNZ5jacRqiDwqU8=
|
||||
cosmossdk.io/client/v2 v2.0.0-20231005120212-0062bf2e7141/go.mod h1:0ycdqzdjVeUdKqgBbaxqSsc1C18GJc3uEF+uphv/MPg=
|
||||
cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=
|
||||
cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0=
|
||||
cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo=
|
||||
@ -867,8 +867,8 @@ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144T
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
|
||||
github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b h1:vab8deKC4QoIfm9fJM59iuNz1ELGsuLoYYpiF+pHiG8=
|
||||
@ -1606,12 +1606,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw
|
||||
google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
|
||||
google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
|
||||
google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb h1:XFBgcDwm7irdHTbz4Zk2h7Mh+eis4nfJEFQFYzJzuIA=
|
||||
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
@ -1653,8 +1653,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu
|
||||
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58=
|
||||
google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I=
|
||||
google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
protov2 "google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
)
|
||||
|
||||
@ -95,13 +96,7 @@ type TxDecoder func(txBytes []byte) (Tx, error)
|
||||
type TxEncoder func(tx Tx) ([]byte, error)
|
||||
|
||||
// MsgTypeURL returns the TypeURL of a `sdk.Msg`.
|
||||
func MsgTypeURL(msg proto.Message) string {
|
||||
if m, ok := msg.(protov2.Message); ok {
|
||||
return "/" + string(m.ProtoReflect().Descriptor().FullName())
|
||||
}
|
||||
|
||||
return "/" + proto.MessageName(msg)
|
||||
}
|
||||
var MsgTypeURL = codectypes.MsgTypeURL
|
||||
|
||||
// GetMsgFromTypeURL returns a `sdk.Msg` message type from a type URL
|
||||
func GetMsgFromTypeURL(cdc codec.Codec, input string) (Msg, error) {
|
||||
|
||||
@ -16,7 +16,7 @@ type SigVerifiableTx interface {
|
||||
}
|
||||
|
||||
// Tx defines a transaction interface that supports all standard message, signature
|
||||
// fee, memo, tips, and auxiliary interfaces.
|
||||
// fee, memo and auxiliary interfaces.
|
||||
type Tx interface {
|
||||
SigVerifiableTx
|
||||
|
||||
|
||||
@ -15,12 +15,6 @@ func NewMsgSend(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins) *MsgSend {
|
||||
return &MsgSend{FromAddress: fromAddr.String(), ToAddress: toAddr.String(), Amount: amount}
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgSend) GetSigners() []sdk.AccAddress {
|
||||
fromAddress, _ := sdk.AccAddressFromBech32(msg.FromAddress)
|
||||
return []sdk.AccAddress{fromAddress}
|
||||
}
|
||||
|
||||
// NewMsgMultiSend - construct arbitrary multi-in, multi-out send msg.
|
||||
func NewMsgMultiSend(in Input, out []Output) *MsgMultiSend {
|
||||
return &MsgMultiSend{Inputs: []Input{in}, Outputs: out}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user