forked from cerc-io/laconicd-deprecated
Ethermint key generation (#78)
* WIP setting up Ethereum key CLI commands * Functional key gen and showing Ethereum address * Cleaned up changes * WIP setting up Ethereum key CLI commands * Functional key gen and showing Ethereum address * Cleaned up changes * Changed address to cosmos specific address * Remove default bech32 prefixes and add basic add command test * Changed Private key type to slice of bytes for compatibility and storability * switch back to using cosmos crypto Keybase interfaces * Changed key output to ethereum addressing instead of bitcoin and key generation to allow seeding from mnemonic and bip39 password * Updated show command and added test * Remove prefix requirement for showing keys and added existing keys commands to CLI temporarily * Removed unnecessary duplicate code * Readd prefixes for accounts temporarily * Fix linting issue * Remove TODO for setting PK to specific length of bytes (all functions use slice) * Cleaned up descriptions to remove multi-sigs
This commit is contained in:
+258
@@ -0,0 +1,258 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
cosmosKeys "github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/ethermint/crypto/keys"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/go-bip39"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
)
|
||||
|
||||
const (
|
||||
flagInteractive = "interactive"
|
||||
flagRecover = "recover"
|
||||
flagNoBackup = "no-backup"
|
||||
// flagDryRun = "dry-run"
|
||||
flagAccount = "account"
|
||||
flagIndex = "index"
|
||||
// flagNoSort = "nosort"
|
||||
|
||||
// DefaultKeyPass contains the default key password for genesis transactions
|
||||
DefaultKeyPass = "12345678"
|
||||
|
||||
mnemonicEntropySize = 256
|
||||
)
|
||||
|
||||
func addKeyCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "add <name>",
|
||||
Short: "Add an encrypted private key (either newly generated or recovered), encrypt it, and save to disk",
|
||||
Long: `Derive a new private key and encrypt to disk.
|
||||
Optionally specify a BIP39 mnemonic, a BIP39 passphrase to further secure the mnemonic,
|
||||
and a bip32 HD path to derive a specific account. The key will be stored under the given name
|
||||
and encrypted with the given password. The only input that is required is the encryption password.
|
||||
|
||||
If run with -i, it will prompt the user for BIP44 path, BIP39 mnemonic, and passphrase.
|
||||
The flag --recover allows one to recover a key from a seed passphrase.
|
||||
If run with --dry-run, a key would be generated (or recovered) but not stored to the
|
||||
local keystore.
|
||||
Use the --pubkey flag to add arbitrary public keys to the keystore for constructing
|
||||
multisig transactions.
|
||||
`,
|
||||
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().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")
|
||||
// cmd.Flags().Bool(flags.FlagUseLedger, false, "Store a local reference to a private key on a Ledger device")
|
||||
cmd.Flags().Bool(flagRecover, false, "Provide seed phrase to recover existing key instead of creating")
|
||||
cmd.Flags().Bool(flagNoBackup, false, "Don't print out seed phrase (if others are watching the terminal)")
|
||||
// cmd.Flags().Bool(flagDryRun, false, "Perform action, but don't add key to local keystore")
|
||||
cmd.Flags().Uint32(flagAccount, 0, "Account number for HD derivation")
|
||||
cmd.Flags().Uint32(flagIndex, 0, "Address index number for HD derivation")
|
||||
cmd.Flags().Bool(flags.FlagIndentResponse, false, "Add indent to JSON response")
|
||||
return cmd
|
||||
}
|
||||
|
||||
/*
|
||||
input
|
||||
- bip39 mnemonic
|
||||
- bip39 passphrase
|
||||
- bip44 path
|
||||
- local encryption password
|
||||
output
|
||||
- armor encrypted private key (saved to file)
|
||||
*/
|
||||
func runAddCmd(cmd *cobra.Command, args []string) error {
|
||||
var kb cosmosKeys.Keybase
|
||||
var err error
|
||||
var encryptPassword string
|
||||
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
name := args[0]
|
||||
|
||||
interactive := viper.GetBool(flagInteractive)
|
||||
showMnemonic := !viper.GetBool(flagNoBackup)
|
||||
|
||||
kb, err = clientkeys.NewKeyBaseFromHomeFlag()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = kb.Get(name)
|
||||
if err == nil {
|
||||
// account exists, ask for user confirmation
|
||||
response, err2 := input.GetConfirmation(fmt.Sprintf("override the existing name %s", name), inBuf)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
if !response {
|
||||
return errors.New("aborted")
|
||||
}
|
||||
}
|
||||
|
||||
// ask for a password when generating a local key
|
||||
if viper.GetString(FlagPublicKey) == "" && !viper.GetBool(flags.FlagUseLedger) {
|
||||
encryptPassword, err = input.GetCheckPassword(
|
||||
"Enter a passphrase to encrypt your key to disk:",
|
||||
"Repeat the passphrase:", inBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
if viper.GetString(FlagPublicKey) != "" {
|
||||
pk, err := sdk.GetAccPubKeyBech32(viper.GetString(FlagPublicKey))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = kb.CreateOffline(name, pk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
account := uint32(viper.GetInt(flagAccount))
|
||||
index := uint32(viper.GetInt(flagIndex))
|
||||
|
||||
// // If we're using ledger, only thing we need is the path and the bech32 prefix.
|
||||
// if viper.GetBool(flags.FlagUseLedger) {
|
||||
// bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix()
|
||||
// info, err := kb.CreateLedger(name, keys.Secp256k1, bech32PrefixAccAddr, account, index)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// return printCreate(cmd, info, false, "")
|
||||
// }
|
||||
|
||||
// Get bip39 mnemonic
|
||||
var mnemonic string
|
||||
var bip39Passphrase string
|
||||
|
||||
if interactive || viper.GetBool(flagRecover) {
|
||||
bip39Message := "Enter your bip39 mnemonic"
|
||||
if !viper.GetBool(flagRecover) {
|
||||
bip39Message = "Enter your bip39 mnemonic, or hit enter to generate one."
|
||||
}
|
||||
|
||||
mnemonic, err = input.GetString(bip39Message, inBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !bip39.IsMnemonicValid(mnemonic) {
|
||||
return errors.New("invalid mnemonic")
|
||||
}
|
||||
}
|
||||
|
||||
if len(mnemonic) == 0 {
|
||||
// read entropy seed straight from crypto.Rand and convert to mnemonic
|
||||
entropySeed, err := bip39.NewEntropy(mnemonicEntropySize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mnemonic, err = bip39.NewMnemonic(entropySeed[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// override bip39 passphrase
|
||||
if interactive {
|
||||
bip39Passphrase, err = input.GetString(
|
||||
"Enter your bip39 passphrase. This is combined with the mnemonic to derive the seed. "+
|
||||
"Most users should just hit enter to use the default, \"\"", inBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if they use one, make them re-enter it
|
||||
if len(bip39Passphrase) != 0 {
|
||||
p2, err := input.GetString("Repeat the passphrase:", inBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if bip39Passphrase != p2 {
|
||||
return errors.New("passphrases don't match")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info, err := kb.CreateAccount(name, mnemonic, bip39Passphrase, encryptPassword, account, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Recover key from seed passphrase
|
||||
if viper.GetBool(flagRecover) {
|
||||
// Hide mnemonic from output
|
||||
showMnemonic = false
|
||||
mnemonic = ""
|
||||
}
|
||||
|
||||
return printCreate(cmd, info, showMnemonic, mnemonic)
|
||||
}
|
||||
|
||||
func printCreate(cmd *cobra.Command, info cosmosKeys.Info, showMnemonic bool, mnemonic string) error {
|
||||
output := viper.Get(cli.OutputFlag)
|
||||
|
||||
switch output {
|
||||
case clientkeys.OutputFormatText:
|
||||
cmd.PrintErrln()
|
||||
printKeyInfo(info, keys.Bech32KeyOutput)
|
||||
|
||||
// print mnemonic unless requested not to.
|
||||
if showMnemonic {
|
||||
cmd.PrintErrln("\n**Important** write this mnemonic phrase in a safe place.")
|
||||
cmd.PrintErrln("It is the only way to recover your account if you ever forget your password.")
|
||||
cmd.PrintErrln("")
|
||||
cmd.PrintErrln(mnemonic)
|
||||
}
|
||||
case clientkeys.OutputFormatJSON:
|
||||
out, err := keys.Bech32KeyOutput(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if showMnemonic {
|
||||
out.Mnemonic = mnemonic
|
||||
}
|
||||
|
||||
var jsonString []byte
|
||||
if viper.GetBool(flags.FlagIndentResponse) {
|
||||
jsonString, err = cdc.MarshalJSONIndent(out, "", " ")
|
||||
} else {
|
||||
jsonString, err = cdc.MarshalJSON(out)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.PrintErrln(string(jsonString))
|
||||
default:
|
||||
return fmt.Errorf("I can't speak: %s", output)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
)
|
||||
|
||||
func TestAddCommandBasic(t *testing.T) {
|
||||
cmd := addKeyCommand()
|
||||
assert.NotNil(t, cmd)
|
||||
mockIn, _, _ := tests.ApplyMockIO(cmd)
|
||||
|
||||
kbHome, kbCleanUp := tests.NewTestCaseDir(t)
|
||||
assert.NotNil(t, kbHome)
|
||||
defer kbCleanUp()
|
||||
viper.Set(flags.FlagHome, kbHome)
|
||||
|
||||
viper.Set(cli.OutputFlag, OutputFormatText)
|
||||
|
||||
mockIn.Reset("test1234\ntest1234\n")
|
||||
err := runAddCmd(cmd, []string{"keyname1"})
|
||||
assert.NoError(t, err)
|
||||
|
||||
viper.Set(cli.OutputFlag, OutputFormatText)
|
||||
|
||||
mockIn.Reset("test1234\ntest1234\n")
|
||||
err = runAddCmd(cmd, []string{"keyname1"})
|
||||
assert.Error(t, err)
|
||||
|
||||
viper.Set(cli.OutputFlag, OutputFormatText)
|
||||
|
||||
mockIn.Reset("y\ntest1234\ntest1234\n")
|
||||
err = runAddCmd(cmd, []string{"keyname1"})
|
||||
assert.NoError(t, err)
|
||||
|
||||
viper.Set(cli.OutputFlag, OutputFormatJSON)
|
||||
|
||||
mockIn.Reset("test1234\ntest1234\n")
|
||||
err = runAddCmd(cmd, []string{"keyname2"})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
)
|
||||
|
||||
var cdc *codec.Codec
|
||||
|
||||
func init() {
|
||||
cdc = codec.New()
|
||||
codec.RegisterCrypto(cdc)
|
||||
cdc.Seal()
|
||||
}
|
||||
|
||||
// marshal keys
|
||||
func MarshalJSON(o interface{}) ([]byte, error) {
|
||||
return cdc.MarshalJSON(o)
|
||||
}
|
||||
|
||||
// unmarshal json
|
||||
func UnmarshalJSON(bz []byte, ptr interface{}) error {
|
||||
return cdc.UnmarshalJSON(bz, ptr)
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
)
|
||||
|
||||
// Commands registers a sub-tree of commands to interact with
|
||||
// local private key storage.
|
||||
func Commands() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "emintkeys",
|
||||
Short: "Add or view local private keys",
|
||||
Long: `Keys allows you to manage your local keystore for tendermint.
|
||||
|
||||
These keys may be in any format supported by go-crypto and can be
|
||||
used by light-clients, full nodes, or any other application that
|
||||
needs to sign with a private key.`,
|
||||
}
|
||||
cmd.AddCommand(
|
||||
// mnemonicKeyCommand(),
|
||||
addKeyCommand(),
|
||||
// exportKeyCommand(),
|
||||
// importKeyCommand(),
|
||||
// listKeysCmd(),
|
||||
showKeysCmd(),
|
||||
flags.LineBreak,
|
||||
// deleteKeyCommand(),
|
||||
// updateKeyCommand(),
|
||||
// parseKeyStringCommand(),
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto"
|
||||
cosmosKeys "github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/ethermint/crypto/keys"
|
||||
)
|
||||
|
||||
const (
|
||||
// FlagAddress is the flag for the user's address on the command line.
|
||||
FlagAddress = "address"
|
||||
// FlagPublicKey represents the user's public key on the command line.
|
||||
FlagPublicKey = "pubkey"
|
||||
// FlagBechPrefix defines a desired Bech32 prefix encoding for a key.
|
||||
FlagBechPrefix = "bech"
|
||||
// FlagDevice indicates that the information should be shown in the device
|
||||
FlagDevice = "device"
|
||||
)
|
||||
|
||||
func showKeysCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "show <name>",
|
||||
Short: "Show key info for the given name",
|
||||
Long: `Return public details of a single local key.`,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
RunE: runShowCmd,
|
||||
}
|
||||
|
||||
cmd.Flags().String(FlagBechPrefix, sdk.PrefixAccount, "The Bech32 prefix encoding for a key (acc|val|cons)")
|
||||
cmd.Flags().BoolP(FlagAddress, "a", false, "Output the address only (overrides --output)")
|
||||
cmd.Flags().BoolP(FlagPublicKey, "p", false, "Output the public key only (overrides --output)")
|
||||
cmd.Flags().BoolP(FlagDevice, "d", false, "Output the address in a ledger device")
|
||||
cmd.Flags().Bool(flags.FlagIndentResponse, false, "Add indent to JSON response")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runShowCmd(cmd *cobra.Command, args []string) (err error) {
|
||||
var info cosmosKeys.Info
|
||||
|
||||
if len(args) == 1 {
|
||||
info, err = GetKeyInfo(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return errors.New("Must provide only one name")
|
||||
}
|
||||
|
||||
isShowAddr := viper.GetBool(FlagAddress)
|
||||
isShowPubKey := viper.GetBool(FlagPublicKey)
|
||||
isShowDevice := viper.GetBool(FlagDevice)
|
||||
|
||||
isOutputSet := false
|
||||
tmp := cmd.Flag(cli.OutputFlag)
|
||||
if tmp != nil {
|
||||
isOutputSet = tmp.Changed
|
||||
}
|
||||
|
||||
if isShowAddr && isShowPubKey {
|
||||
return errors.New("cannot use both --address and --pubkey at once")
|
||||
}
|
||||
|
||||
if isOutputSet && (isShowAddr || isShowPubKey) {
|
||||
return errors.New("cannot use --output with --address or --pubkey")
|
||||
}
|
||||
|
||||
keyOutputFunction := keys.Bech32KeyOutput
|
||||
|
||||
switch {
|
||||
case isShowAddr:
|
||||
printKeyAddress(info, keyOutputFunction)
|
||||
case isShowPubKey:
|
||||
printPubKey(info, keyOutputFunction)
|
||||
default:
|
||||
printKeyInfo(info, keyOutputFunction)
|
||||
}
|
||||
|
||||
if isShowDevice {
|
||||
if isShowPubKey {
|
||||
return fmt.Errorf("the device flag (-d) can only be used for addresses not pubkeys")
|
||||
}
|
||||
if viper.GetString(FlagBechPrefix) != "acc" {
|
||||
return fmt.Errorf("the device flag (-d) can only be used for accounts")
|
||||
}
|
||||
// Override and show in the device
|
||||
if info.GetType() != cosmosKeys.TypeLedger {
|
||||
return fmt.Errorf("the device flag (-d) can only be used for accounts stored in devices")
|
||||
}
|
||||
|
||||
hdpath, err := info.GetPath()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return crypto.LedgerShowAddress(*hdpath, info.GetPubKey())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Determine if the different prefixes are necessary for ethermint
|
||||
// func getBechKeyOut(bechPrefix string) (bechKeyOutFn, error) {
|
||||
// switch bechPrefix {
|
||||
// case sdk.PrefixAccount:
|
||||
// return keys.Bech32KeyOutput, nil
|
||||
// case sdk.PrefixValidator:
|
||||
// return keys.Bech32ValKeyOutput, nil
|
||||
// case sdk.PrefixConsensus:
|
||||
// return keys.Bech32ConsKeyOutput, nil
|
||||
// }
|
||||
|
||||
// return nil, fmt.Errorf("invalid Bech32 prefix encoding provided: %s", bechPrefix)
|
||||
// }
|
||||
@@ -0,0 +1,52 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
)
|
||||
|
||||
func TestShowKeysCmd(t *testing.T) {
|
||||
cmd := showKeysCmd()
|
||||
assert.NotNil(t, cmd)
|
||||
assert.Equal(t, "false", cmd.Flag(FlagAddress).DefValue)
|
||||
assert.Equal(t, "false", cmd.Flag(FlagPublicKey).DefValue)
|
||||
}
|
||||
|
||||
func TestRunShowCmd(t *testing.T) {
|
||||
cmd := showKeysCmd()
|
||||
|
||||
err := runShowCmd(cmd, []string{"invalid"})
|
||||
assert.EqualError(t, err, "Key invalid not found")
|
||||
|
||||
// Prepare a key base
|
||||
// Now add a temporary keybase
|
||||
kbHome, cleanUp := tests.NewTestCaseDir(t)
|
||||
defer cleanUp()
|
||||
viper.Set(flags.FlagHome, kbHome)
|
||||
|
||||
fakeKeyName1 := "runShowCmd_Key1"
|
||||
fakeKeyName2 := "runShowCmd_Key2"
|
||||
kb, err := clientkeys.NewKeyBaseFromHomeFlag()
|
||||
assert.NoError(t, err)
|
||||
_, err = kb.CreateAccount(fakeKeyName1, tests.TestMnemonic, "", "", 0, 0)
|
||||
assert.NoError(t, err)
|
||||
_, err = kb.CreateAccount(fakeKeyName2, tests.TestMnemonic, "", "", 0, 1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// // Now try single key
|
||||
// err = runShowCmd(cmd, []string{fakeKeyName1})
|
||||
// assert.EqualError(t, err, "invalid Bech32 prefix encoding provided: ")
|
||||
|
||||
// // Now try single key - set bech to acc
|
||||
// viper.Set(FlagBechPrefix, sdk.PrefixAccount)
|
||||
err = runShowCmd(cmd, []string{fakeKeyName1})
|
||||
assert.NoError(t, err)
|
||||
err = runShowCmd(cmd, []string{fakeKeyName2})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
cosmosKeys "github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
)
|
||||
|
||||
// available output formats.
|
||||
const (
|
||||
OutputFormatText = "text"
|
||||
OutputFormatJSON = "json"
|
||||
)
|
||||
|
||||
type bechKeyOutFn func(keyInfo cosmosKeys.Info) (cosmosKeys.KeyOutput, error)
|
||||
|
||||
// GetKeyInfo returns key info for a given name. An error is returned if the
|
||||
// keybase cannot be retrieved or getting the info fails.
|
||||
func GetKeyInfo(name string) (cosmosKeys.Info, error) {
|
||||
keybase, err := clientkeys.NewKeyBaseFromHomeFlag()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return keybase.Get(name)
|
||||
}
|
||||
|
||||
func printKeyInfo(keyInfo cosmosKeys.Info, bechKeyOut bechKeyOutFn) {
|
||||
ko, err := bechKeyOut(keyInfo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
switch viper.Get(cli.OutputFlag) {
|
||||
case OutputFormatText:
|
||||
printTextInfos([]cosmosKeys.KeyOutput{ko})
|
||||
|
||||
case OutputFormatJSON:
|
||||
var out []byte
|
||||
var err error
|
||||
if viper.GetBool(flags.FlagIndentResponse) {
|
||||
out, err = cdc.MarshalJSONIndent(ko, "", " ")
|
||||
} else {
|
||||
out, err = cdc.MarshalJSON(ko)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println(string(out))
|
||||
}
|
||||
}
|
||||
|
||||
// func printInfos(infos []keys.Info) {
|
||||
// kos, err := keys.Bech32KeysOutput(infos)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
|
||||
// switch viper.Get(cli.OutputFlag) {
|
||||
// case OutputFormatText:
|
||||
// printTextInfos(kos)
|
||||
|
||||
// case OutputFormatJSON:
|
||||
// var out []byte
|
||||
// var err error
|
||||
|
||||
// if viper.GetBool(flags.FlagIndentResponse) {
|
||||
// out, err = cdc.MarshalJSONIndent(kos, "", " ")
|
||||
// } else {
|
||||
// out, err = cdc.MarshalJSON(kos)
|
||||
// }
|
||||
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// fmt.Printf("%s", out)
|
||||
// }
|
||||
// }
|
||||
|
||||
func printTextInfos(kos []cosmosKeys.KeyOutput) {
|
||||
out, err := yaml.Marshal(&kos)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println(string(out))
|
||||
}
|
||||
|
||||
func printKeyAddress(info cosmosKeys.Info, bechKeyOut bechKeyOutFn) {
|
||||
ko, err := bechKeyOut(info)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println(ko.Address)
|
||||
}
|
||||
|
||||
func printPubKey(info cosmosKeys.Info, bechKeyOut bechKeyOutFn) {
|
||||
ko, err := bechKeyOut(info)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println(ko.PubKey)
|
||||
}
|
||||
Reference in New Issue
Block a user