Skip to content

Commit

Permalink
feat(client/v2): get keyring from context (#19646)
Browse files Browse the repository at this point in the history
(cherry picked from commit ca195c1)

# Conflicts:
#	client/v2/CHANGELOG.md
#	client/v2/README.md
#	client/v2/autocli/app.go
#	client/v2/autocli/common.go
#	client/v2/autocli/common_test.go
#	client/v2/autocli/flag/pubkey.go
#	client/v2/autocli/msg.go
#	simapp/simd/cmd/root.go
  • Loading branch information
julienrbrt authored and mergify[bot] committed Jun 19, 2024
1 parent d6428f7 commit 5c36344
Show file tree
Hide file tree
Showing 24 changed files with 420 additions and 111 deletions.
23 changes: 23 additions & 0 deletions client/v2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,27 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

<<<<<<< HEAD
## [v2.0.0-beta.2] - 2024-XX-XX

### Improvements

* (deps) [#19810](https://github.com/cosmos/cosmos-sdk/pull/19810) Upgrade SDK version due to prometheus breaking change.
* (deps) [#19810](https://github.com/cosmos/cosmos-sdk/pull/19810) Bump `cosmossdk.io/store` to v1.1.0.
=======
<!-- ## [v2.1.0-rc.1] to be tagged after v0.51 final or in SDK agnostic version -->

### Features

* [#18626](https://github.com/cosmos/cosmos-sdk/pull/18626) Support for off-chain signing and verification of a file.
* [#18461](https://github.com/cosmos/cosmos-sdk/pull/18461) Support governance proposals.
* [#19039](https://github.com/cosmos/cosmos-sdk/pull/19039) Add support for pubkey in autocli.
* [#20266](https://github.com/cosmos/cosmos-sdk/pull/20266) Ability to override the short description in AutoCLI-generated top-level commands.

### Improvements

* [#19646](https://github.com/cosmos/cosmos-sdk/pull/19646) Use keyring from command context.
>>>>>>> ca195c152 (feat(client/v2): get keyring from context (#19646))
* [#20083](https://github.com/cosmos/cosmos-sdk/pull/20083) Integrate latest version of cosmos-proto and improve version filtering.
* [#19618](https://github.com/cosmos/cosmos-sdk/pull/19618) Marshal enum as string in queries.
* [#19060](https://github.com/cosmos/cosmos-sdk/pull/19060) Use client context from root (or enhanced) command in autocli commands.
Expand All @@ -56,6 +71,14 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#19060](https://github.com/cosmos/cosmos-sdk/pull/19060) Simplify key flag parsing logic in flag handler.
* [#20033](https://github.com/cosmos/cosmos-sdk/pull/20033) Respect output format from client ctx.

<<<<<<< HEAD
=======
### API Breaking Changes

* [#19646](https://github.com/cosmos/cosmos-sdk/pull/19646) Remove keyring from `autocli.AppOptions` and `flag.Builder` options.
* [#17709](https://github.com/cosmos/cosmos-sdk/pull/17709) Address codecs have been removed from `autocli.AppOptions` and `flag.Builder`. Instead client/v2 uses the address codecs present in the context (introduced in [#17503](https://github.com/cosmos/cosmos-sdk/pull/17503)).

>>>>>>> ca195c152 (feat(client/v2): get keyring from context (#19646))
## [v2.0.0-beta.1] - 2023-11-07

This is the first tagged version of client/v2.
Expand Down
89 changes: 73 additions & 16 deletions client/v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ if err := rootCmd.Execute(); err != nil {

### 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.
`autocli` uses a keyring for key name resolving names and signing transactions.

:::tip
This provides a better UX as it allows to resolve key names directly from the keyring in all transactions and commands.
AutoCLI provides a better UX than normal CLI as it allows to resolve key names directly from the keyring in all transactions and commands.

```sh
<appd> q bank balances alice
Expand All @@ -87,8 +87,9 @@ 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 keyring should be provided in the `appOptions` struct as follows, and can be gotten from the client context:
The keyring used for resolving names and signing transactions is provided via the `client.Context`.
The keyring is then converted to the `client/v2/autocli/keyring` interface.
If no keyring is provided, the `autocli` generated command will not be able to sign transactions, but will still be able to query the chain.

:::tip
The Cosmos SDK keyring and Hubl keyring both implement the `client/v2/autocli/keyring` interface, thanks to the following wrapper:
Expand All @@ -99,18 +100,6 @@ keyring.NewAutoCLIKeyring(kb)

:::

:::warning
When using AutoCLI the keyring will only be created once and before any command flag parsing.
:::

```go
// Set the keyring in the appOptions
appOptions.Keyring = keyring

err := autoCliOpts.EnhanceRootCommand(rootCmd)
...
```

## Signing

`autocli` supports signing transactions with the keyring.
Expand Down Expand Up @@ -224,3 +213,71 @@ https://github.com/cosmos/cosmos-sdk/blob/client/v2.0.0-beta.1/client/grpc/cmtse
To further enhance your CLI experience with Cosmos SDK-based blockchains, you can use `hubl`. `hubl` is a tool that allows you to query any Cosmos SDK-based blockchain using the new AutoCLI feature of the Cosmos SDK. With `hubl`, you can easily configure a new chain and query modules with just a few simple commands.

For more information on `hubl`, including how to configure a new chain and query a module, see the [Hubl documentation](https://docs.cosmos.network/main/tooling/hubl).
<<<<<<< HEAD
=======

# Off-Chain

Off-chain functionalities allow you to sign and verify files with two commands:

* `sign-file` for signing a file.
* `verify-file` for verifying a previously signed file.

Signing a file will result in a Tx with a `MsgSignArbitraryData` as described in the [Off-chain CIP](https://github.com/cosmos/cips/blob/main/cips/cip-X.md).

## Sign a file

To sign a file `sign-file` command offers some helpful flags:

```text
--encoding string Choose an encoding method for the file content to be added as msg data (no-encoding|base64|hex) (default "no-encoding")
--indent string Choose an indent for the tx (default " ")
--notEmitUnpopulated Don't show unpopulated fields in the tx
--output string Choose an output format for the tx (json|text (default "json")
--output-document string The document will be written to the given file instead of STDOUT
```

The `encoding` flag lets you choose how the contents of the file should be encoded. For example:

* `simd off-chain sign-file alice myFile.json`

* ```json
{
"@type": "/offchain.MsgSignArbitraryData",
"appDomain": "simd",
"signer": "cosmos1x33fy6rusfprkntvjsfregss7rvsvyy4lkwrqu",
"data": "Hello World!\n"
}
```

* `simd off-chain sign-file alice myFile.json --encoding base64`

* ```json
{
"@type": "/offchain.MsgSignArbitraryData",
"appDomain": "simd",
"signer": "cosmos1x33fy6rusfprkntvjsfregss7rvsvyy4lkwrqu",
"data": "SGVsbG8gV29ybGQhCg=="
}
```

* `simd off-chain sign-file alice myFile.json --encoding hex`

* ```json
{
"@type": "/offchain.MsgSignArbitraryData",
"appDomain": "simd",
"signer": "cosmos1x33fy6rusfprkntvjsfregss7rvsvyy4lkwrqu",
"data": "48656c6c6f20576f726c64210a"
}
```

## Verify a file

To verify a file only the key name used and the previously signed file are needed.

```text
➜ simd off-chain verify-file alice signedFile.json
Verification OK!
```
>>>>>>> ca195c152 (feat(client/v2): get keyring from context (#19646))
12 changes: 12 additions & 0 deletions client/v2/autocli/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import (

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/client/v2/autocli/flag"
<<<<<<< HEAD
"cosmossdk.io/client/v2/autocli/keyring"
"cosmossdk.io/core/address"
=======
>>>>>>> ca195c152 (feat(client/v2): get keyring from context (#19646))
"cosmossdk.io/core/appmodule"
"cosmossdk.io/depinject"

Expand Down Expand Up @@ -37,6 +40,7 @@ type AppOptions struct {
// module or need to be improved.
ModuleOptions map[string]*autocliv1.ModuleOptions `optional:"true"`

<<<<<<< HEAD
// AddressCodec is the address codec to use for the app.
AddressCodec address.Codec
ValidatorAddressCodec runtime.ValidatorAddressCodec
Expand All @@ -45,6 +49,8 @@ type AppOptions struct {
// Keyring is the keyring to use for client/v2.
Keyring keyring.Keyring `optional:"true"`

=======
>>>>>>> ca195c152 (feat(client/v2): get keyring from context (#19646))
// ClientCtx contains the necessary information needed to execute the commands.
ClientCtx client.Context
}
Expand All @@ -69,10 +75,16 @@ func (appOptions AppOptions) EnhanceRootCommand(rootCmd *cobra.Command) error {
Builder: flag.Builder{
TypeResolver: protoregistry.GlobalTypes,
FileResolver: appOptions.ClientCtx.InterfaceRegistry,
<<<<<<< HEAD
AddressCodec: appOptions.AddressCodec,
ValidatorAddressCodec: appOptions.ValidatorAddressCodec,
ConsensusAddressCodec: appOptions.ConsensusAddressCodec,
Keyring: appOptions.Keyring,
=======
AddressCodec: appOptions.ClientCtx.AddressCodec,
ValidatorAddressCodec: appOptions.ClientCtx.ValidatorAddressCodec,
ConsensusAddressCodec: appOptions.ClientCtx.ConsensusAddressCodec,
>>>>>>> ca195c152 (feat(client/v2): get keyring from context (#19646))
},
GetClientConn: func(cmd *cobra.Command) (grpc.ClientConnInterface, error) {
return client.GetClientQueryContext(cmd)
Expand Down
18 changes: 16 additions & 2 deletions client/v2/autocli/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,18 @@ func (b *Builder) buildMethodCommandCommon(descriptor protoreflect.MethodDescrip
Version: options.Version,
}

binder, err := b.AddMessageFlags(cmd.Context(), cmd.Flags(), inputType, options)
// we need to use a pointer to the context as the correct context is set in the RunE function
// however we need to set the flags before the RunE function is called
ctx := cmd.Context()
binder, err := b.AddMessageFlags(&ctx, cmd.Flags(), inputType, options)
if err != nil {
return nil, err
}

cmd.Args = binder.CobraArgs

cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx = cmd.Context()

input, err := binder.BuildMessage(args)
if err != nil {
return err
Expand All @@ -77,13 +81,23 @@ func (b *Builder) buildMethodCommandCommon(descriptor protoreflect.MethodDescrip

// 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.
<<<<<<< HEAD
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 {
=======
// marks the custom flag as required.
if binder.SignerInfo.FlagName != flags.FlagFrom {
if err := cmd.MarkFlagRequired(binder.SignerInfo.FlagName); err != nil {
return err
}

if err := cmd.Flags().Set(flags.FlagFrom, cmd.Flag(binder.SignerInfo.FlagName).Value.String()); err != nil {
>>>>>>> ca195c152 (feat(client/v2): get keyring from context (#19646))
return err
}
}
Expand Down
9 changes: 6 additions & 3 deletions client/v2/autocli/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ func initFixture(t *testing.T) *fixture {
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)

Expand All @@ -76,10 +73,16 @@ func initFixture(t *testing.T) *fixture {
Builder: flag.Builder{
TypeResolver: protoregistry.GlobalTypes,
FileResolver: protoregistry.GlobalFiles,
<<<<<<< HEAD
Keyring: akr,
AddressCodec: addresscodec.NewBech32Codec("cosmos"),
ValidatorAddressCodec: addresscodec.NewBech32Codec("cosmosvaloper"),
ConsensusAddressCodec: addresscodec.NewBech32Codec("cosmosvalcons"),
=======
AddressCodec: clientCtx.AddressCodec,
ValidatorAddressCodec: clientCtx.ValidatorAddressCodec,
ConsensusAddressCodec: clientCtx.ConsensusAddressCodec,
>>>>>>> ca195c152 (feat(client/v2): get keyring from context (#19646))
},
GetClientConn: func(*cobra.Command) (grpc.ClientConnInterface, error) {
return conn, nil
Expand Down
Loading

0 comments on commit 5c36344

Please sign in to comment.