Skip to content

Commit

Permalink
feat(cli): add did output only to show key command
Browse files Browse the repository at this point in the history
  • Loading branch information
ccamel committed Feb 10, 2024
1 parent 9fc09b6 commit 7a6eee2
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 58 deletions.
16 changes: 10 additions & 6 deletions client/keys/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@ import (

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/keys"
)

const (
flagListNames = "list-names"
listKeysCmd = "list"
)

// KeyOutput is the output format for keys when listing them.
// It is an improved copy of the KeyOutput from the keys module (github.com/cosmos/cosmos-sdk/client/keys/types.go).
type KeyOutput struct {
keys.KeyOutput
DID string `json:"did,omitempty" yaml:"did"`
// EnhanceListCmd replaces the original 'list' command implementation with our own 'list' command which
// will allow us to list did:key of the keys as well as the original keys.
func EnhanceListCmd(cmd *cobra.Command) {
for _, c := range cmd.Commands() {
if c.Name() == listKeysCmd {
c.RunE = runListCmd
break
}
}
}

// runListCmd retrieves all keys from the keyring and prints them to the console.
Expand Down
16 changes: 2 additions & 14 deletions client/keys/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ import (
"github.com/spf13/cobra"
)

const (
listKeysCmd = "list"
showKeysCmd = "show"
)

// Enhance augment the given command which is assumed to be the root command of the 'list' command.
// It will:
// - add the 'did' command.
Expand All @@ -19,15 +14,8 @@ func Enhance(cmd *cobra.Command) *cobra.Command {
DIDCmd(),
)

for _, c := range cmd.Commands() {
switch c.Name() {
case listKeysCmd:
c.RunE = runListCmd
case showKeysCmd:
c.RunE = runShowCmd
default:
}
}
EnhanceListCmd(cmd)
EnhanceShowCmd(cmd)

return cmd
}
64 changes: 44 additions & 20 deletions client/keys/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"

"github.com/samber/lo"
"github.com/spf13/cobra"

errorsmod "cosmossdk.io/errors"
Expand All @@ -20,9 +21,25 @@ import (
)

const (
flagDID = "did"
flagMultiSigThreshold = "multisig-threshold"
showKeysCmd = "show"
)

// EnhanceShowCmd replaces the original 'show' command implementation with our own 'show' command which
// will allow us to display the did:key of the key as well as the original key.
func EnhanceShowCmd(cmd *cobra.Command) {
for _, c := range cmd.Commands() {
if c.Name() == showKeysCmd {
c.RunE = runShowCmd

f := c.Flags()
f.BoolP(flagDID, "k", false, "Output the did:key only (overrides --output)")
break
}
}
}

func runShowCmd(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
Expand Down Expand Up @@ -52,11 +69,7 @@ func runShowCmd(cmd *cobra.Command, args []string) error {
return err
}

if err := processOutput(cmd, clientCtx, keyRecord, bechKeyOut); err != nil {
return err
}

return nil
return processOutput(cmd, clientCtx, keyRecord, bechKeyOut)
}

func fetchMultiSigKey(cmd *cobra.Command, clientCtx client.Context, args []string) (*keyring.Record, error) {
Expand Down Expand Up @@ -85,12 +98,16 @@ func fetchMultiSigKey(cmd *cobra.Command, clientCtx client.Context, args []strin
func checkFlagCompatibility(cmd *cobra.Command) error {
isShowAddr, _ := cmd.Flags().GetBool(keys.FlagAddress)
isShowPubKey, _ := cmd.Flags().GetBool(keys.FlagPublicKey)
if isShowAddr && isShowPubKey {
return errors.New("cannot use both --address and --pubkey at once")
isShowDid, _ := cmd.Flags().GetBool(flagDID)

nbFlags := lo.Count([]bool{isShowAddr, isShowPubKey, isShowDid}, true)

if nbFlags > 1 {
return errors.New("cannot use --address, --pubkey and --did at the same time")
}

isOutputSet := cmd.Flag(flags.FlagOutput) != nil && cmd.Flag(flags.FlagOutput).Changed
if isOutputSet && (isShowAddr || isShowPubKey) {
if isOutputSet && nbFlags > 0 {
return errors.New("cannot use --output with --address or --pubkey")
}

Expand All @@ -100,27 +117,34 @@ func checkFlagCompatibility(cmd *cobra.Command) error {
func processOutput(cmd *cobra.Command, clientCtx client.Context, k *keyring.Record, bechKeyOut bechKeyOutFn) error {
isShowAddr, _ := cmd.Flags().GetBool(keys.FlagAddress)
isShowPubKey, _ := cmd.Flags().GetBool(keys.FlagPublicKey)
isShowDid, _ := cmd.Flags().GetBool(flagDID)
isShowDevice, _ := cmd.Flags().GetBool(keys.FlagDevice)

if isShowDevice {
switch {
case isShowDevice:
return handleDeviceOutput(k)
}

if isShowAddr || isShowPubKey {
case isShowAddr || isShowPubKey || isShowDid:
ko, err := bechKeyOut(k)
if err != nil {
return err
}
out := ko.Address
if isShowPubKey {
out := ""
switch {
case isShowAddr:
out = ko.Address
case isShowPubKey:
out = ko.PubKey
case isShowDid:
out = ko.DID
}

_, err = fmt.Fprintln(cmd.OutOrStdout(), out)
return err
}

outputFormat := clientCtx.OutputFormat
return printKeyringRecord(cmd.OutOrStdout(), k, bechKeyOut, outputFormat)
default:
outputFormat := clientCtx.OutputFormat
return printKeyringRecord(cmd.OutOrStdout(), k, bechKeyOut, outputFormat)
}
}

func handleDeviceOutput(k *keyring.Record) error {
Expand Down Expand Up @@ -169,11 +193,11 @@ func validateMultisigThreshold(k, nKeys int) error {
func getBechKeyOut(bechPrefix string) (bechKeyOutFn, error) {
switch bechPrefix {
case sdk.PrefixAccount:
return keys.MkAccKeyOutput, nil
return toBechKeyOutFn(keys.MkAccKeyOutput), nil
case sdk.PrefixValidator:
return keys.MkValKeyOutput, nil
return toBechKeyOutFn(keys.MkValKeyOutput), nil
case sdk.PrefixConsensus:
return keys.MkConsKeyOutput, nil
return toBechKeyOutFn(keys.MkConsKeyOutput), nil
}

return nil, fmt.Errorf("invalid Bech32 prefix encoding provided: %s", bechPrefix)
Expand Down
49 changes: 31 additions & 18 deletions client/keys/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,18 @@ import (
"github.com/okp4/okp4d/x/logic/util"
)

type bechKeyOutFn func(k *cryptokeyring.Record) (keys.KeyOutput, error)
// KeyOutput is the output format for keys when listing them.
// It is an improved copy of the KeyOutput from the keys module (github.com/cosmos/cosmos-sdk/client/keys/types.go).
type KeyOutput struct {
keys.KeyOutput
DID string `json:"did,omitempty" yaml:"did"`
}

// bechKeyOutFn is a function that converts a record into a KeyOutput and returns an error if it fails.
type bechKeyOutFn func(k *cryptokeyring.Record) (KeyOutput, error)

func printKeyringRecord(w io.Writer, k *cryptokeyring.Record, bechKeyOut bechKeyOutFn, output string) error {
ko, err := mkKeyOutput(k, bechKeyOut)
ko, err := bechKeyOut(k)
if err != nil {
return err
}
Expand Down Expand Up @@ -83,9 +91,9 @@ func printTextRecords(w io.Writer, kos []KeyOutput) error {

func mkKeysOutput(records []*cryptokeyring.Record) ([]KeyOutput, error) {
kos := make([]KeyOutput, len(records))

bechKeyOut := toBechKeyOutFn(keys.MkAccKeyOutput)
for i, r := range records {
kko, err := mkKeyOutput(r, keys.MkAccKeyOutput)
kko, err := bechKeyOut(r)
if err != nil {
return nil, err
}
Expand All @@ -96,19 +104,24 @@ func mkKeysOutput(records []*cryptokeyring.Record) ([]KeyOutput, error) {
return kos, nil
}

func mkKeyOutput(record *cryptokeyring.Record, bechKeyOut bechKeyOutFn) (KeyOutput, error) {
kko, err := bechKeyOut(record)
if err != nil {
return KeyOutput{}, err
}
pk, err := record.GetPubKey()
if err != nil {
return KeyOutput{}, err
}
did, _ := util.CreateDIDKeyByPubKey(pk)
// toBechKeyOutFn converts a function that returns a KeyOutput and an error into a function that returns
// an extended KeyOutput and an error.
func toBechKeyOutFn(in func(k *cryptokeyring.Record) (keys.KeyOutput, error)) bechKeyOutFn {
return func(k *cryptokeyring.Record) (KeyOutput, error) {
ko, err := in(k)
if err != nil {
return KeyOutput{}, err
}

pk, err := k.GetPubKey()
if err != nil {
return KeyOutput{}, err
}
did, _ := util.CreateDIDKeyByPubKey(pk)

return KeyOutput{
KeyOutput: kko,
DID: did,
}, nil
return KeyOutput{
KeyOutput: ko,
DID: did,
}, nil
}
}

0 comments on commit 7a6eee2

Please sign in to comment.