Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keys: CLI Remove Viper #6613

Merged
merged 16 commits into from
Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 46 additions & 40 deletions client/keys/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@ import (
"bytes"
"errors"
"fmt"
"io"
"sort"

bip39 "github.com/cosmos/go-bip39"
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/cli"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/cli"
)

const (
Expand Down Expand Up @@ -65,8 +61,9 @@ the flag --nosort is set.
Args: cobra.ExactArgs(1),
RunE: runAddCmd,
}

cmd.Flags().StringSlice(flagMultisig, nil, "Construct and store a multisig public key (implies --pubkey)")
cmd.Flags().Uint(flagMultiSigThreshold, 1, "K out of N required signatures. For use in conjunction with --multisig")
cmd.Flags().Int(flagMultiSigThreshold, 1, "K out of N required signatures. For use in conjunction with --multisig")
cmd.Flags().Bool(flagNoSort, false, "Keys passed to --multisig are taken in the order they're supplied")
cmd.Flags().String(FlagPublicKey, "", "Parse a public key in bech32 format and save it to disk")
cmd.Flags().BoolP(flagInteractive, "i", false, "Interactively prompt user for BIP39 passphrase and mnemonic")
Expand All @@ -86,23 +83,29 @@ the flag --nosort is set.
return cmd
}

func getKeybase(transient bool, buf io.Reader) (keyring.Keyring, error) {
if transient {
return keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, viper.GetString(flags.FlagHome), buf)
}
func runAddCmd(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())

return keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), buf)
}
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
dryRun, _ := cmd.Flags().GetBool(flags.FlagHome)

func runAddCmd(cmd *cobra.Command, args []string) error {
inBuf := bufio.NewReader(cmd.InOrStdin())
kb, err := getKeybase(viper.GetBool(flags.FlagDryRun), inBuf)
var (
kr keyring.Keyring
err error
)

if dryRun {
kr, err = keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, homeDir, buf)
} else {
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
kr, err = keyring.New(sdk.KeyringServiceName(), backend, homeDir, buf)
}

if err != nil {
return err
}

return RunAddCmd(cmd, args, kb, inBuf)
return RunAddCmd(cmd, args, kr, buf)
}

/*
Expand All @@ -118,16 +121,18 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
var err error

name := args[0]
interactive := viper.GetBool(flagInteractive)
showMnemonic := !viper.GetBool(flagNoBackup)
interactive, _ := cmd.Flags().GetBool(flagInteractive)
noBackup, _ := cmd.Flags().GetBool(flagNoBackup)
showMnemonic := !noBackup

keyringAlgos, _ := kb.SupportedAlgorithms()
algo, err := keyring.NewSigningAlgoFromString(viper.GetString(flagKeyAlgo), keyringAlgos)
algoStr, _ := cmd.Flags().GetString(flagKeyAlgo)
algo, err := keyring.NewSigningAlgoFromString(algoStr, keyringAlgos)
if err != nil {
return err
}

if !viper.GetBool(flags.FlagDryRun) {
if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); !dryRun {
_, err = kb.Key(name)
if err == nil {
// account exists, ask for user confirmation
Expand All @@ -146,11 +151,11 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
}
}

multisigKeys := viper.GetStringSlice(flagMultisig)
multisigKeys, _ := cmd.Flags().GetStringSlice(flagMultisig)
if len(multisigKeys) != 0 {
var pks []crypto.PubKey

multisigThreshold := viper.GetInt(flagMultiSigThreshold)
multisigThreshold, _ := cmd.Flags().GetInt(flagMultiSigThreshold)
if err := validateMultisigThreshold(multisigThreshold, len(multisigKeys)); err != nil {
return err
}
Expand All @@ -164,8 +169,7 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
pks = append(pks, k.GetPubKey())
}

// Handle --nosort
if !viper.GetBool(flagNoSort) {
if noSort, _ := cmd.Flags().GetBool(flagNoSort); !noSort {
sort.Slice(pks, func(i, j int) bool {
return bytes.Compare(pks[i].Address(), pks[j].Address()) < 0
})
Expand All @@ -177,13 +181,13 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
}

cmd.PrintErrf("Key %q saved to disk.\n", name)

return nil
}
}

if viper.GetString(FlagPublicKey) != "" {
pk, err := sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, viper.GetString(FlagPublicKey))
pubKey, _ := cmd.Flags().GetString(FlagPublicKey)
if pubKey != "" {
pk, err := sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, pubKey)
if err != nil {
return err
}
Expand All @@ -195,19 +199,20 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
return nil
}

coinType := uint32(viper.GetInt(flagCoinType))
account := uint32(viper.GetInt(flagAccount))
index := uint32(viper.GetInt(flagIndex))
hdPath := viper.GetString(flagHDPath)
coinType, _ := cmd.Flags().GetUint32(flagCoinType)
account, _ := cmd.Flags().GetUint32(flagAccount)
index, _ := cmd.Flags().GetUint32(flagIndex)
hdPath, _ := cmd.Flags().GetString(flagHDPath)
useLedger, _ := cmd.Flags().GetBool(flags.FlagUseLedger)

if len(hdPath) == 0 {
hdPath = hd.CreateHDPath(coinType, account, index).String()
} else if viper.GetBool(flags.FlagUseLedger) {
} else if useLedger {
return errors.New("cannot set custom bip32 path with ledger")
}

// If we're using ledger, only thing we need is the path and the bech32 prefix.
if viper.GetBool(flags.FlagUseLedger) {
if useLedger {
bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix()
info, err := kb.SaveLedgerKey(name, hd.Secp256k1, bech32PrefixAccAddr, coinType, account, index)

Expand All @@ -221,9 +226,10 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
// Get bip39 mnemonic
var mnemonic, bip39Passphrase string

if interactive || viper.GetBool(flagRecover) {
recover, _ := cmd.Flags().GetBool(flagRecover)
if interactive || recover {
bip39Message := "Enter your bip39 mnemonic"
if !viper.GetBool(flagRecover) {
if !recover {
bip39Message = "Enter your bip39 mnemonic, or hit enter to generate one."
}

Expand Down Expand Up @@ -278,7 +284,7 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
}

// Recover key from seed passphrase
if viper.GetBool(flagRecover) {
if recover {
// Hide mnemonic from output
showMnemonic = false
mnemonic = ""
Expand All @@ -288,12 +294,12 @@ func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *buf
}

func printCreate(cmd *cobra.Command, info keyring.Info, showMnemonic bool, mnemonic string) error {
output := viper.Get(cli.OutputFlag)
output, _ := cmd.Flags().GetString(cli.OutputFlag)

switch output {
case OutputFormatText:
cmd.PrintErrln()
printKeyInfo(cmd.OutOrStdout(), info, keyring.Bech32KeyOutput)
printKeyInfo(cmd.OutOrStdout(), info, keyring.Bech32KeyOutput, output)

// print mnemonic unless requested not to.
if showMnemonic {
Expand Down
59 changes: 32 additions & 27 deletions client/keys/add_ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
package keys

import (
"fmt"
"testing"

"github.com/spf13/viper"
"github.com/stretchr/testify/require"

"github.com/tendermint/tendermint/libs/cli"
Expand Down Expand Up @@ -34,29 +34,31 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {
config.SetBech32PrefixForConsensusNode(bech32PrefixConsAddr, bech32PrefixConsPub)

cmd := AddKeyCommand()
require.NotNil(t, cmd)
cmd.Flags().AddFlagSet(Commands().PersistentFlags())

// Prepare a keybase
kbHome, kbCleanUp := tests.NewTestCaseDir(t)
require.NotNil(t, kbHome)
t.Cleanup(kbCleanUp)
viper.Set(flags.FlagHome, kbHome)
viper.Set(flags.FlagUseLedger, true)
viper.Set(flagAccount, "0")
viper.Set(flagIndex, "0")
viper.Set(flagCoinType, "330")

// Test Text
viper.Set(cli.OutputFlag, OutputFormatText)
// set algo flag value to the default
viper.Set(flagKeyAlgo, string(hd.Secp256k1Type))
// Now enter password

cmd.SetArgs([]string{
"keyname1",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=true", flags.FlagUseLedger),
fmt.Sprintf("--%s=0", flagAccount),
fmt.Sprintf("--%s=0", flagIndex),
fmt.Sprintf("--%s=330", flagCoinType),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flagKeyAlgo, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})

mockIn, _, _ := tests.ApplyMockIO(cmd)
mockIn.Reset("test1234\ntest1234\n")
require.NoError(t, runAddCmd(cmd, []string{"keyname1"}))
require.NoError(t, cmd.Execute())

// Now check that it has been stored properly
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn)
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)
require.NotNil(t, kb)
t.Cleanup(func() {
Expand All @@ -82,32 +84,35 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {

func Test_runAddCmdLedger(t *testing.T) {
cmd := AddKeyCommand()
require.NotNil(t, cmd)
cmd.Flags().AddFlagSet(Commands().PersistentFlags())
mockIn, _, _ := tests.ApplyMockIO(cmd)

// Prepare a keybase
kbHome, kbCleanUp := tests.NewTestCaseDir(t)
require.NotNil(t, kbHome)
t.Cleanup(kbCleanUp)
viper.Set(flags.FlagHome, kbHome)
viper.Set(flags.FlagUseLedger, true)

// Test Text
viper.Set(cli.OutputFlag, OutputFormatText)
// set algo flag value to the default
viper.Set(flagKeyAlgo, string(hd.Secp256k1Type))
// Now enter password

cmd.SetArgs([]string{
"keyname1",
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
fmt.Sprintf("--%s=true", flags.FlagUseLedger),
fmt.Sprintf("--%s=%s", cli.OutputFlag, OutputFormatText),
fmt.Sprintf("--%s=%s", flagKeyAlgo, string(hd.Secp256k1Type)),
fmt.Sprintf("--%s=%d", flagCoinType, sdk.CoinType),
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
})
mockIn.Reset("test1234\ntest1234\n")
viper.Set(flagCoinType, sdk.CoinType)
require.NoError(t, runAddCmd(cmd, []string{"keyname1"}))

require.NoError(t, cmd.Execute())

// Now check that it has been stored properly
kb, err := keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn)
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
require.NoError(t, err)
require.NotNil(t, kb)
t.Cleanup(func() {
_ = kb.Delete("keyname1")
})

mockIn.Reset("test1234\n")
key1, err := kb.Key("keyname1")
require.NoError(t, err)
Expand Down
Loading