Interchangable PrivKey implementations in keybase (#5278)
Allow for the keybase to be configured to override the implementation of the key that is saved to the keybase. Closes: #4941
This commit is contained in:
parent
efcd5fd315
commit
0e28da23e7
|
@ -76,6 +76,8 @@ if the provided arguments are invalid.
|
|||
`StdTx.Signatures` to get back the array of StdSignatures `[]StdSignature`.
|
||||
* (modules) [\#5299](https://github.com/cosmos/cosmos-sdk/pull/5299) `HandleDoubleSign` along with params `MaxEvidenceAge`
|
||||
and `DoubleSignJailEndTime` have moved from the `x/slashing` module to the `x/evidence` module.
|
||||
* (keys) [\#4941](https://github.com/cosmos/cosmos-sdk/issues/4941) Initializing a new keybase through `NewKeyringFromHomeFlag`, `NewKeyringFromDir`, `NewKeyBaseFromHomeFlag`, `NewKeyBaseFromDir`, or `NewInMemory` functions now accept optional parameters of type `KeybaseOption`. These optional parameters are also added on the keys subcommands functions, which are now public, and allows these options to be set on the commands or ignored to default to previous behavior.
|
||||
* The option introduced in this PR is `WithKeygenFunc` which allows a custom bytes to key implementation to be defined when keys are created.
|
||||
|
||||
### Client Breaking Changes
|
||||
|
||||
|
@ -146,6 +148,7 @@ that allows for arbitrary vesting periods.
|
|||
* `IncrementSequenceDecorator`: Increments the account sequence for each signer to prevent replay attacks.
|
||||
* (cli) [\#5223](https://github.com/cosmos/cosmos-sdk/issues/5223) Cosmos Ledger App v2.0.0 is now supported. The changes are backwards compatible and App v1.5.x is still supported.
|
||||
* (modules) [\#5249](https://github.com/cosmos/cosmos-sdk/pull/5249) Funds are now allowed to be directly sent to the community pool (via the distribution module account).
|
||||
* (keys) [\#4941](https://github.com/cosmos/cosmos-sdk/issues/4941) Introduce keybase option to allow overriding the default private key implementation of a key generated through the `keys add` cli command.
|
||||
|
||||
### Improvements
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
|
||||
bip39 "github.com/bartekn/go-bip39"
|
||||
|
@ -36,7 +37,8 @@ const (
|
|||
DefaultKeyPass = "12345678"
|
||||
)
|
||||
|
||||
func addKeyCommand() *cobra.Command {
|
||||
// AddKeyCommand defines a keys command to add a generated or recovered private key to keybase.
|
||||
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",
|
||||
|
@ -75,6 +77,24 @@ the flag --nosort is set.
|
|||
return cmd
|
||||
}
|
||||
|
||||
func getKeybase(transient bool, buf io.Reader) (keys.Keybase, error) {
|
||||
if transient {
|
||||
return keys.NewInMemory(), nil
|
||||
}
|
||||
|
||||
return NewKeyringFromHomeFlag(buf)
|
||||
}
|
||||
|
||||
func runAddCmd(cmd *cobra.Command, args []string) error {
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
kb, err := getKeybase(viper.GetBool(flagDryRun), inBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return RunAddCmd(cmd, args, kb, inBuf)
|
||||
}
|
||||
|
||||
/*
|
||||
input
|
||||
- bip39 mnemonic
|
||||
|
@ -84,26 +104,15 @@ input
|
|||
output
|
||||
- armor encrypted private key (saved to file)
|
||||
*/
|
||||
func runAddCmd(cmd *cobra.Command, args []string) error {
|
||||
var kb keys.Keybase
|
||||
func RunAddCmd(cmd *cobra.Command, args []string, kb keys.Keybase, inBuf *bufio.Reader) error {
|
||||
var err error
|
||||
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
name := args[0]
|
||||
|
||||
interactive := viper.GetBool(flagInteractive)
|
||||
showMnemonic := !viper.GetBool(flagNoBackup)
|
||||
|
||||
if viper.GetBool(flagDryRun) {
|
||||
// we throw this away, so don't enforce args,
|
||||
// we want to get a new random seed phrase quickly
|
||||
kb = keys.NewInMemory()
|
||||
} else {
|
||||
kb, err = NewKeyringFromHomeFlag(cmd.InOrStdin())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !viper.GetBool(flagDryRun) {
|
||||
_, err = kb.Get(name)
|
||||
if err == nil {
|
||||
// account exists, ask for user confirmation
|
||||
|
@ -273,9 +282,9 @@ func printCreate(cmd *cobra.Command, info keys.Info, showMnemonic bool, mnemonic
|
|||
|
||||
var jsonString []byte
|
||||
if viper.GetBool(flags.FlagIndentResponse) {
|
||||
jsonString, err = cdc.MarshalJSONIndent(out, "", " ")
|
||||
jsonString, err = KeysCdc.MarshalJSONIndent(out, "", " ")
|
||||
} else {
|
||||
jsonString, err = cdc.MarshalJSON(out)
|
||||
jsonString, err = KeysCdc.MarshalJSON(out)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -33,7 +33,7 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {
|
|||
config.SetBech32PrefixForValidator(bech32PrefixValAddr, bech32PrefixValPub)
|
||||
config.SetBech32PrefixForConsensusNode(bech32PrefixConsAddr, bech32PrefixConsPub)
|
||||
|
||||
cmd := addKeyCommand()
|
||||
cmd := AddKeyCommand()
|
||||
require.NotNil(t, cmd)
|
||||
|
||||
// Prepare a keybase
|
||||
|
@ -80,7 +80,7 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {
|
|||
|
||||
func Test_runAddCmdLedger(t *testing.T) {
|
||||
runningUnattended := isRunningUnattended()
|
||||
cmd := addKeyCommand()
|
||||
cmd := AddKeyCommand()
|
||||
require.NotNil(t, cmd)
|
||||
mockIn, _, _ := tests.ApplyMockIO(cmd)
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
|
||||
func Test_runAddCmdBasic(t *testing.T) {
|
||||
runningUnattended := isRunningUnattended()
|
||||
cmd := addKeyCommand()
|
||||
cmd := AddKeyCommand()
|
||||
assert.NotNil(t, cmd)
|
||||
mockIn, _, _ := tests.ApplyMockIO(cmd)
|
||||
|
||||
|
|
|
@ -4,20 +4,21 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
)
|
||||
|
||||
var cdc *codec.Codec
|
||||
// KeysCdc defines codec to be used with key operations
|
||||
var KeysCdc *codec.Codec
|
||||
|
||||
func init() {
|
||||
cdc = codec.New()
|
||||
codec.RegisterCrypto(cdc)
|
||||
cdc.Seal()
|
||||
KeysCdc = codec.New()
|
||||
codec.RegisterCrypto(KeysCdc)
|
||||
KeysCdc.Seal()
|
||||
}
|
||||
|
||||
// marshal keys
|
||||
func MarshalJSON(o interface{}) ([]byte, error) {
|
||||
return cdc.MarshalJSON(o)
|
||||
return KeysCdc.MarshalJSON(o)
|
||||
}
|
||||
|
||||
// unmarshal json
|
||||
func UnmarshalJSON(bz []byte, ptr interface{}) error {
|
||||
return cdc.UnmarshalJSON(bz, ptr)
|
||||
return KeysCdc.UnmarshalJSON(bz, ptr)
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ const (
|
|||
flagForce = "force"
|
||||
)
|
||||
|
||||
func deleteKeyCommand() *cobra.Command {
|
||||
// DeleteKeyCommand deletes a key from the key store.
|
||||
func DeleteKeyCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete <name>...",
|
||||
Short: "Delete the given keys",
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
|
||||
func Test_runDeleteCmd(t *testing.T) {
|
||||
runningUnattended := isRunningUnattended()
|
||||
deleteKeyCommand := deleteKeyCommand()
|
||||
deleteKeyCommand := DeleteKeyCommand()
|
||||
mockIn, _, _ := tests.ApplyMockIO(deleteKeyCommand)
|
||||
|
||||
yesF, _ := deleteKeyCommand.Flags().GetBool(flagYes)
|
||||
|
|
|
@ -8,7 +8,8 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
)
|
||||
|
||||
func exportKeyCommand() *cobra.Command {
|
||||
// ExportKeyCommand exports private keys from the key store.
|
||||
func ExportKeyCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "export <name>",
|
||||
Short: "Export private keys",
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
|
||||
func Test_runExportCmd(t *testing.T) {
|
||||
runningUnattended := isRunningUnattended()
|
||||
exportKeyCommand := exportKeyCommand()
|
||||
exportKeyCommand := ExportKeyCommand()
|
||||
mockIn, _, _ := tests.ApplyMockIO(exportKeyCommand)
|
||||
|
||||
// Now add a temporary keybase
|
||||
|
|
|
@ -9,7 +9,8 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
)
|
||||
|
||||
func importKeyCommand() *cobra.Command {
|
||||
// ImportKeyCommand imports private keys from a keyfile.
|
||||
func ImportKeyCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "import <name> <keyfile>",
|
||||
Short: "Import private keys into the local keybase",
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
|
||||
func Test_runImportCmd(t *testing.T) {
|
||||
runningUnattended := isRunningUnattended()
|
||||
importKeyCommand := importKeyCommand()
|
||||
importKeyCommand := ImportKeyCommand()
|
||||
mockIn, _, _ := tests.ApplyMockIO(importKeyCommand)
|
||||
|
||||
// Now add a temporary keybase
|
||||
|
|
|
@ -9,7 +9,8 @@ import (
|
|||
|
||||
const flagListNames = "list-names"
|
||||
|
||||
func listKeysCmd() *cobra.Command {
|
||||
// ListKeysCmd lists all keys in the key store.
|
||||
func ListKeysCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List all keys",
|
||||
|
|
|
@ -18,7 +18,7 @@ func Test_runListCmd(t *testing.T) {
|
|||
args []string
|
||||
}
|
||||
|
||||
cmdBasic := listKeysCmd()
|
||||
cmdBasic := ListKeysCmd()
|
||||
|
||||
// Prepare some keybases
|
||||
kbHome1, cleanUp1 := tests.NewTestCaseDir(t)
|
||||
|
|
|
@ -18,7 +18,8 @@ import (
|
|||
// is not needed for importing into the Keyring keystore.
|
||||
const migratePassphrase = "NOOP_PASSPHRASE"
|
||||
|
||||
func migrateCommand() *cobra.Command {
|
||||
// MigrateCommand migrates key information from legacy keybase to OS secret store.
|
||||
func MigrateCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "migrate",
|
||||
Short: "Migrate key information from the lagacy key database to the OS secret store, or encrypted file store as a fall-back and save it",
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
func Test_runMigrateCmd(t *testing.T) {
|
||||
cmd := addKeyCommand()
|
||||
cmd := AddKeyCommand()
|
||||
assert.NotNil(t, cmd)
|
||||
mockIn, _, _ := tests.ApplyMockIO(cmd)
|
||||
|
||||
|
@ -29,7 +29,7 @@ func Test_runMigrateCmd(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
|
||||
viper.Set(flags.FlagDryRun, true)
|
||||
cmd = migrateCommand()
|
||||
cmd = MigrateCommand()
|
||||
mockIn, _, _ = tests.ApplyMockIO(cmd)
|
||||
mockIn.Reset("test1234\n")
|
||||
assert.NoError(t, runMigrateCmd(cmd, []string{}))
|
||||
|
|
|
@ -17,7 +17,8 @@ const (
|
|||
mnemonicEntropySize = 256
|
||||
)
|
||||
|
||||
func mnemonicKeyCommand() *cobra.Command {
|
||||
// MnemonicKeyCommand computes the bip39 memonic for input entropy.
|
||||
func MnemonicKeyCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "mnemonic",
|
||||
Short: "Compute the bip39 mnemonic for some input entropy",
|
||||
|
|
|
@ -11,13 +11,13 @@ import (
|
|||
)
|
||||
|
||||
func Test_RunMnemonicCmdNormal(t *testing.T) {
|
||||
cmdBasic := mnemonicKeyCommand()
|
||||
cmdBasic := MnemonicKeyCommand()
|
||||
err := runMnemonicCmd(cmdBasic, []string{})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_RunMnemonicCmdUser(t *testing.T) {
|
||||
cmdUser := mnemonicKeyCommand()
|
||||
cmdUser := MnemonicKeyCommand()
|
||||
err := cmdUser.Flags().Set(flagUserEntropy, "1")
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
|
|
@ -67,7 +67,8 @@ func (bo bech32Output) String() string {
|
|||
return fmt.Sprintf("Bech32 Formats:\n%s", strings.Join(out, "\n"))
|
||||
}
|
||||
|
||||
func parseKeyStringCommand() *cobra.Command {
|
||||
// ParseKeyStringCommand parses an address from hex to bech32 and vice versa.
|
||||
func ParseKeyStringCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "parse <hex-or-bech32-address>",
|
||||
Short: "Parse address from hex to bech32 and vice versa",
|
||||
|
@ -124,9 +125,9 @@ func displayParseKeyInfo(stringer fmt.Stringer) {
|
|||
case OutputFormatJSON:
|
||||
|
||||
if viper.GetBool(flags.FlagIndentResponse) {
|
||||
out, err = cdc.MarshalJSONIndent(stringer, "", " ")
|
||||
out, err = KeysCdc.MarshalJSONIndent(stringer, "", " ")
|
||||
} else {
|
||||
out = cdc.MustMarshalJSON(stringer)
|
||||
out = KeysCdc.MustMarshalJSON(stringer)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,17 +20,17 @@ func Commands() *cobra.Command {
|
|||
needs to sign with a private key.`,
|
||||
}
|
||||
cmd.AddCommand(
|
||||
mnemonicKeyCommand(),
|
||||
addKeyCommand(),
|
||||
exportKeyCommand(),
|
||||
importKeyCommand(),
|
||||
listKeysCmd(),
|
||||
showKeysCmd(),
|
||||
MnemonicKeyCommand(),
|
||||
AddKeyCommand(),
|
||||
ExportKeyCommand(),
|
||||
ImportKeyCommand(),
|
||||
ListKeysCmd(),
|
||||
ShowKeysCmd(),
|
||||
flags.LineBreak,
|
||||
deleteKeyCommand(),
|
||||
updateKeyCommand(),
|
||||
parseKeyStringCommand(),
|
||||
migrateCommand(),
|
||||
DeleteKeyCommand(),
|
||||
UpdateKeyCommand(),
|
||||
ParseKeyStringCommand(),
|
||||
MigrateCommand(),
|
||||
)
|
||||
cmd.PersistentFlags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
|
||||
viper.BindPFlag(flags.FlagKeyringBackend, cmd.Flags().Lookup(flags.FlagKeyringBackend))
|
||||
|
|
|
@ -32,7 +32,8 @@ const (
|
|||
defaultMultiSigKeyName = "multi"
|
||||
)
|
||||
|
||||
func showKeysCmd() *cobra.Command {
|
||||
// ShowKeysCmd shows key information for a given key name.
|
||||
func ShowKeysCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "show [name [name...]]",
|
||||
Short: "Show key info for the given name",
|
||||
|
|
|
@ -28,7 +28,7 @@ func Test_multiSigKey_Properties(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_showKeysCmd(t *testing.T) {
|
||||
cmd := showKeysCmd()
|
||||
cmd := ShowKeysCmd()
|
||||
require.NotNil(t, cmd)
|
||||
require.Equal(t, "false", cmd.Flag(FlagAddress).DefValue)
|
||||
require.Equal(t, "false", cmd.Flag(FlagPublicKey).DefValue)
|
||||
|
@ -36,7 +36,7 @@ func Test_showKeysCmd(t *testing.T) {
|
|||
|
||||
func Test_runShowCmd(t *testing.T) {
|
||||
runningUnattended := isRunningUnattended()
|
||||
cmd := showKeysCmd()
|
||||
cmd := ShowKeysCmd()
|
||||
mockIn, _, _ := tests.ApplyMockIO(cmd)
|
||||
require.EqualError(t, runShowCmd(cmd, []string{"invalid"}), "The specified item could not be found in the keyring")
|
||||
require.EqualError(t, runShowCmd(cmd, []string{"invalid1", "invalid2"}), "The specified item could not be found in the keyring")
|
||||
|
|
|
@ -8,7 +8,9 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
)
|
||||
|
||||
func updateKeyCommand() *cobra.Command {
|
||||
// UpdateKeyCommand changes the password of a key in the keybase.
|
||||
// It takes no effect on keys managed by new the keyring-based keybase implementation.
|
||||
func UpdateKeyCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "update <name>",
|
||||
Short: "Change the password used to protect private key",
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
func Test_updateKeyCommand(t *testing.T) {
|
||||
cmd := updateKeyCommand()
|
||||
cmd := UpdateKeyCommand()
|
||||
assert.NotNil(t, cmd)
|
||||
// No flags or defaults to validate
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ func Test_runUpdateCmd(t *testing.T) {
|
|||
fakeKeyName1 := "runUpdateCmd_Key1"
|
||||
fakeKeyName2 := "runUpdateCmd_Key2"
|
||||
|
||||
cmd := updateKeyCommand()
|
||||
cmd := UpdateKeyCommand()
|
||||
|
||||
// fails because it requests a password
|
||||
assert.EqualError(t, runUpdateCmd(cmd, []string{fakeKeyName1}), "EOF")
|
||||
|
|
|
@ -26,30 +26,33 @@ const (
|
|||
|
||||
type bechKeyOutFn func(keyInfo keys.Info) (keys.KeyOutput, error)
|
||||
|
||||
// NewKeyBaseFromHomeFlag initializes a Keybase based on the configuration.
|
||||
func NewKeyBaseFromHomeFlag() (keys.Keybase, error) {
|
||||
// NewKeyBaseFromHomeFlag initializes a Keybase based on the configuration. Keybase
|
||||
// options can be applied when generating this new Keybase.
|
||||
func NewKeyBaseFromHomeFlag(opts ...keys.KeybaseOption) (keys.Keybase, error) {
|
||||
rootDir := viper.GetString(flags.FlagHome)
|
||||
return NewKeyBaseFromDir(rootDir)
|
||||
return NewKeyBaseFromDir(rootDir, opts...)
|
||||
}
|
||||
|
||||
// NewKeyBaseFromDir initializes a keybase at a particular dir.
|
||||
func NewKeyBaseFromDir(rootDir string) (keys.Keybase, error) {
|
||||
return getLazyKeyBaseFromDir(rootDir)
|
||||
// NewKeyBaseFromDir initializes a keybase at the rootDir directory. Keybase
|
||||
// options can be applied when generating this new Keybase.
|
||||
func NewKeyBaseFromDir(rootDir string, opts ...keys.KeybaseOption) (keys.Keybase, error) {
|
||||
return getLazyKeyBaseFromDir(rootDir, opts...)
|
||||
}
|
||||
|
||||
// NewInMemoryKeyBase returns a storage-less keybase.
|
||||
func NewInMemoryKeyBase() keys.Keybase { return keys.NewInMemory() }
|
||||
|
||||
// NewKeyBaseFromHomeFlag initializes a keyring based on configuration.
|
||||
func NewKeyringFromHomeFlag(input io.Reader) (keys.Keybase, error) {
|
||||
return NewKeyringFromDir(viper.GetString(flags.FlagHome), input)
|
||||
// NewKeyBaseFromHomeFlag initializes a keyring based on configuration. Keybase
|
||||
// options can be applied when generating this new Keybase.
|
||||
func NewKeyringFromHomeFlag(input io.Reader, opts ...keys.KeybaseOption) (keys.Keybase, error) {
|
||||
return NewKeyringFromDir(viper.GetString(flags.FlagHome), input, opts...)
|
||||
}
|
||||
|
||||
// NewKeyBaseFromDir initializes a keyring at the given directory.
|
||||
// If the viper flag flags.FlagKeyringBackend is set to file, it returns an on-disk keyring with
|
||||
// CLI prompt support only. If flags.FlagKeyringBackend is set to test it will return an on-disk,
|
||||
// password-less keyring that could be used for testing purposes.
|
||||
func NewKeyringFromDir(rootDir string, input io.Reader) (keys.Keybase, error) {
|
||||
func NewKeyringFromDir(rootDir string, input io.Reader, opts ...keys.KeybaseOption) (keys.Keybase, error) {
|
||||
keyringBackend := viper.GetString(flags.FlagKeyringBackend)
|
||||
switch keyringBackend {
|
||||
case flags.KeyringBackendTest:
|
||||
|
@ -62,8 +65,8 @@ func NewKeyringFromDir(rootDir string, input io.Reader) (keys.Keybase, error) {
|
|||
return nil, fmt.Errorf("unknown keyring backend %q", keyringBackend)
|
||||
}
|
||||
|
||||
func getLazyKeyBaseFromDir(rootDir string) (keys.Keybase, error) {
|
||||
return keys.New(defaultKeyDBName, filepath.Join(rootDir, "keys")), nil
|
||||
func getLazyKeyBaseFromDir(rootDir string, opts ...keys.KeybaseOption) (keys.Keybase, error) {
|
||||
return keys.New(defaultKeyDBName, filepath.Join(rootDir, "keys"), opts...), nil
|
||||
}
|
||||
|
||||
func printKeyInfo(keyInfo keys.Info, bechKeyOut bechKeyOutFn) {
|
||||
|
@ -80,9 +83,9 @@ func printKeyInfo(keyInfo keys.Info, bechKeyOut bechKeyOutFn) {
|
|||
var out []byte
|
||||
var err error
|
||||
if viper.GetBool(flags.FlagIndentResponse) {
|
||||
out, err = cdc.MarshalJSONIndent(ko, "", " ")
|
||||
out, err = KeysCdc.MarshalJSONIndent(ko, "", " ")
|
||||
} else {
|
||||
out, err = cdc.MarshalJSON(ko)
|
||||
out, err = KeysCdc.MarshalJSON(ko)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -107,9 +110,9 @@ func printInfos(infos []keys.Info) {
|
|||
var err error
|
||||
|
||||
if viper.GetBool(flags.FlagIndentResponse) {
|
||||
out, err = cdc.MarshalJSONIndent(kos, "", " ")
|
||||
out, err = KeysCdc.MarshalJSONIndent(kos, "", " ")
|
||||
} else {
|
||||
out, err = cdc.MarshalJSON(kos)
|
||||
out, err = KeysCdc.MarshalJSON(kos)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -7,16 +7,22 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
|
||||
)
|
||||
|
||||
var cdc *codec.Codec
|
||||
// CryptoCdc defines the codec required for keys and info
|
||||
var CryptoCdc *codec.Codec
|
||||
|
||||
func init() {
|
||||
cdc = codec.New()
|
||||
cryptoAmino.RegisterAmino(cdc)
|
||||
CryptoCdc = codec.New()
|
||||
cryptoAmino.RegisterAmino(CryptoCdc)
|
||||
RegisterCodec(CryptoCdc)
|
||||
CryptoCdc.Seal()
|
||||
}
|
||||
|
||||
// RegisterCodec registers concrete types and interfaces on the given codec.
|
||||
func RegisterCodec(cdc *codec.Codec) {
|
||||
cdc.RegisterInterface((*Info)(nil), nil)
|
||||
cdc.RegisterConcrete(hd.BIP44Params{}, "crypto/keys/hd/BIP44Params", nil)
|
||||
cdc.RegisterConcrete(localInfo{}, "crypto/keys/localInfo", nil)
|
||||
cdc.RegisterConcrete(ledgerInfo{}, "crypto/keys/ledgerInfo", nil)
|
||||
cdc.RegisterConcrete(offlineInfo{}, "crypto/keys/offlineInfo", nil)
|
||||
cdc.RegisterConcrete(multiInfo{}, "crypto/keys/multiInfo", nil)
|
||||
cdc.Seal()
|
||||
}
|
||||
|
|
|
@ -75,16 +75,17 @@ type dbKeybase struct {
|
|||
|
||||
// newDBKeybase creates a new dbKeybase instance using the provided DB for
|
||||
// reading and writing keys.
|
||||
func newDBKeybase(db dbm.DB) Keybase {
|
||||
func newDBKeybase(db dbm.DB, opts ...KeybaseOption) Keybase {
|
||||
return dbKeybase{
|
||||
base: baseKeybase{},
|
||||
base: newBaseKeybase(opts...),
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
// NewInMemory creates a transient keybase on top of in-memory storage
|
||||
// instance useful for testing purposes and on-the-fly key generation.
|
||||
func NewInMemory() Keybase { return newDBKeybase(dbm.NewMemDB()) }
|
||||
// Keybase options can be applied when generating this new Keybase.
|
||||
func NewInMemory(opts ...KeybaseOption) Keybase { return newDBKeybase(dbm.NewMemDB(), opts...) }
|
||||
|
||||
// CreateMnemonic generates a new key and persists it to storage, encrypted
|
||||
// using the provided password. It returns the generated mnemonic and the key Info.
|
||||
|
|
|
@ -16,9 +16,15 @@ import (
|
|||
)
|
||||
|
||||
type (
|
||||
kbOptions struct {
|
||||
keygenFunc PrivKeyGenFunc
|
||||
}
|
||||
|
||||
// baseKeybase is an auxiliary type that groups Keybase storage agnostic features
|
||||
// together.
|
||||
baseKeybase struct{}
|
||||
baseKeybase struct {
|
||||
options kbOptions
|
||||
}
|
||||
|
||||
keyWriter interface {
|
||||
writeLocalKeyer
|
||||
|
@ -34,6 +40,30 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
// WithKeygenFunc applies an overridden key generation function to generate the private key.
|
||||
func WithKeygenFunc(f PrivKeyGenFunc) KeybaseOption {
|
||||
return func(o *kbOptions) {
|
||||
o.keygenFunc = f
|
||||
}
|
||||
}
|
||||
|
||||
// newBaseKeybase generates the base keybase with defaulting to tendermint SECP256K1 key type
|
||||
func newBaseKeybase(optionsFns ...KeybaseOption) baseKeybase {
|
||||
// Default options for keybase
|
||||
options := kbOptions{keygenFunc: baseSecpPrivKeyGen}
|
||||
|
||||
for _, optionFn := range optionsFns {
|
||||
optionFn(&options)
|
||||
}
|
||||
|
||||
return baseKeybase{options: options}
|
||||
}
|
||||
|
||||
// baseSecpPrivKeyGen generates a secp256k1 private key from the given bytes
|
||||
func baseSecpPrivKeyGen(bz [32]byte) tmcrypto.PrivKey {
|
||||
return secp256k1.PrivKeySecp256k1(bz)
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
@ -72,7 +102,7 @@ func (kb baseKeybase) DecodeSignature(info Info, msg []byte) (sig []byte, pub tm
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := cdc.UnmarshalBinaryLengthPrefixed([]byte(signed), sig); err != nil {
|
||||
if err := CryptoCdc.UnmarshalBinaryLengthPrefixed([]byte(signed), sig); err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to decode signature")
|
||||
}
|
||||
|
||||
|
@ -101,9 +131,9 @@ func (kb baseKeybase) persistDerivedKey(
|
|||
var info Info
|
||||
|
||||
if passwd != "" {
|
||||
info = keyWriter.writeLocalKey(name, secp256k1.PrivKeySecp256k1(derivedPriv), passwd)
|
||||
info = keyWriter.writeLocalKey(name, kb.options.keygenFunc(derivedPriv), passwd)
|
||||
} else {
|
||||
info = kb.writeOfflineKey(keyWriter, name, secp256k1.PrivKeySecp256k1(derivedPriv).PubKey())
|
||||
info = kb.writeOfflineKey(keyWriter, name, kb.options.keygenFunc(derivedPriv).PubKey())
|
||||
}
|
||||
|
||||
return info, nil
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/mintkey"
|
||||
|
@ -401,7 +402,8 @@ func TestSeedPhrase(t *testing.T) {
|
|||
|
||||
func ExampleNew() {
|
||||
// Select the encryption and storage for your cryptostore
|
||||
cstore := NewInMemory()
|
||||
customKeyGenFunc := func(bz [32]byte) crypto.PrivKey { return secp256k1.PrivKeySecp256k1(bz) }
|
||||
cstore := NewInMemory(WithKeygenFunc(customKeyGenFunc))
|
||||
|
||||
sec := Secp256k1
|
||||
|
||||
|
|
|
@ -42,14 +42,17 @@ type keyringKeybase struct {
|
|||
|
||||
var maxPassphraseEntryAttempts = 3
|
||||
|
||||
// NewKeyring creates a new instance of a keyring.
|
||||
func NewKeyring(name string, dir string, userInput io.Reader) (Keybase, error) {
|
||||
// NewKeyring creates a new instance of a keyring. Keybase
|
||||
// options can be applied when generating this new Keybase.
|
||||
func NewKeyring(
|
||||
name string, dir string, userInput io.Reader, opts ...KeybaseOption,
|
||||
) (Keybase, error) {
|
||||
db, err := keyring.Open(lkbToKeyringConfig(name, dir, userInput, false))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newKeyringKeybase(db), nil
|
||||
return newKeyringKeybase(db, opts...), nil
|
||||
}
|
||||
|
||||
// NewKeyringFile creates a new instance of an encrypted file-backed keyring.
|
||||
|
@ -64,13 +67,13 @@ func NewKeyringFile(name string, dir string, userInput io.Reader) (Keybase, erro
|
|||
|
||||
// NewTestKeyring creates a new instance of an on-disk keyring for
|
||||
// testing purposes that does not prompt users for password.
|
||||
func NewTestKeyring(name string, dir string) (Keybase, error) {
|
||||
func NewTestKeyring(name string, dir string, opts ...KeybaseOption) (Keybase, error) {
|
||||
db, err := keyring.Open(lkbToKeyringConfig(name, dir, nil, true))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newKeyringKeybase(db), nil
|
||||
return newKeyringKeybase(db, opts...), nil
|
||||
}
|
||||
|
||||
// CreateMnemonic generates a new key and persists it to storage, encrypted
|
||||
|
@ -572,9 +575,9 @@ func fakePrompt(prompt string) (string, error) {
|
|||
return "test", nil
|
||||
}
|
||||
|
||||
func newKeyringKeybase(db keyring.Keyring) Keybase {
|
||||
func newKeyringKeybase(db keyring.Keyring, opts ...KeybaseOption) Keybase {
|
||||
return keyringKeybase{
|
||||
db: db,
|
||||
base: baseKeybase{},
|
||||
base: newBaseKeybase(opts...),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,17 +14,18 @@ var _ Keybase = lazyKeybase{}
|
|||
|
||||
// NOTE: lazyKeybase will be deprecated in favor of lazyKeybaseKeyring.
|
||||
type lazyKeybase struct {
|
||||
name string
|
||||
dir string
|
||||
name string
|
||||
dir string
|
||||
options []KeybaseOption
|
||||
}
|
||||
|
||||
// New creates a new instance of a lazy keybase.
|
||||
func New(name, dir string) Keybase {
|
||||
func New(name, dir string, opts ...KeybaseOption) Keybase {
|
||||
if err := cmn.EnsureDir(dir, 0700); err != nil {
|
||||
panic(fmt.Sprintf("failed to create Keybase directory: %s", err))
|
||||
}
|
||||
|
||||
return lazyKeybase{name: name, dir: dir}
|
||||
return lazyKeybase{name: name, dir: dir, options: opts}
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) List() ([]Info, error) {
|
||||
|
@ -34,7 +35,7 @@ func (lkb lazyKeybase) List() ([]Info, error) {
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).List()
|
||||
return newDBKeybase(db, lkb.options...).List()
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) Get(name string) (Info, error) {
|
||||
|
@ -44,7 +45,7 @@ func (lkb lazyKeybase) Get(name string) (Info, error) {
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).Get(name)
|
||||
return newDBKeybase(db, lkb.options...).Get(name)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) GetByAddress(address sdk.AccAddress) (Info, error) {
|
||||
|
@ -54,7 +55,7 @@ func (lkb lazyKeybase) GetByAddress(address sdk.AccAddress) (Info, error) {
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).GetByAddress(address)
|
||||
return newDBKeybase(db, lkb.options...).GetByAddress(address)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) Delete(name, passphrase string, skipPass bool) error {
|
||||
|
@ -64,7 +65,7 @@ func (lkb lazyKeybase) Delete(name, passphrase string, skipPass bool) error {
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).Delete(name, passphrase, skipPass)
|
||||
return newDBKeybase(db, lkb.options...).Delete(name, passphrase, skipPass)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error) {
|
||||
|
@ -74,7 +75,7 @@ func (lkb lazyKeybase) Sign(name, passphrase string, msg []byte) ([]byte, crypto
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).Sign(name, passphrase, msg)
|
||||
return newDBKeybase(db, lkb.options...).Sign(name, passphrase, msg)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error) {
|
||||
|
@ -84,7 +85,7 @@ func (lkb lazyKeybase) CreateMnemonic(name string, language Language, passwd str
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).CreateMnemonic(name, language, passwd, algo)
|
||||
return newDBKeybase(db, lkb.options...).CreateMnemonic(name, language, passwd, algo)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error) {
|
||||
|
@ -94,7 +95,8 @@ func (lkb lazyKeybase) CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd, account, index)
|
||||
return newDBKeybase(db,
|
||||
lkb.options...).CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd, account, index)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) Derive(name, mnemonic, bip39Passwd, encryptPasswd string, params hd.BIP44Params) (Info, error) {
|
||||
|
@ -104,7 +106,7 @@ func (lkb lazyKeybase) Derive(name, mnemonic, bip39Passwd, encryptPasswd string,
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).Derive(name, mnemonic, bip39Passwd, encryptPasswd, params)
|
||||
return newDBKeybase(db, lkb.options...).Derive(name, mnemonic, bip39Passwd, encryptPasswd, params)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) CreateLedger(name string, algo SigningAlgo, hrp string, account, index uint32) (info Info, err error) {
|
||||
|
@ -114,7 +116,7 @@ func (lkb lazyKeybase) CreateLedger(name string, algo SigningAlgo, hrp string, a
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).CreateLedger(name, algo, hrp, account, index)
|
||||
return newDBKeybase(db, lkb.options...).CreateLedger(name, algo, hrp, account, index)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) CreateOffline(name string, pubkey crypto.PubKey) (info Info, err error) {
|
||||
|
@ -124,7 +126,7 @@ func (lkb lazyKeybase) CreateOffline(name string, pubkey crypto.PubKey) (info In
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).CreateOffline(name, pubkey)
|
||||
return newDBKeybase(db, lkb.options...).CreateOffline(name, pubkey)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) CreateMulti(name string, pubkey crypto.PubKey) (info Info, err error) {
|
||||
|
@ -134,7 +136,7 @@ func (lkb lazyKeybase) CreateMulti(name string, pubkey crypto.PubKey) (info Info
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).CreateMulti(name, pubkey)
|
||||
return newDBKeybase(db, lkb.options...).CreateMulti(name, pubkey)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) Update(name, oldpass string, getNewpass func() (string, error)) error {
|
||||
|
@ -144,7 +146,7 @@ func (lkb lazyKeybase) Update(name, oldpass string, getNewpass func() (string, e
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).Update(name, oldpass, getNewpass)
|
||||
return newDBKeybase(db, lkb.options...).Update(name, oldpass, getNewpass)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) Import(name string, armor string) (err error) {
|
||||
|
@ -154,7 +156,7 @@ func (lkb lazyKeybase) Import(name string, armor string) (err error) {
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).Import(name, armor)
|
||||
return newDBKeybase(db, lkb.options...).Import(name, armor)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) ImportPrivKey(name string, armor string, passphrase string) error {
|
||||
|
@ -164,7 +166,7 @@ func (lkb lazyKeybase) ImportPrivKey(name string, armor string, passphrase strin
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).ImportPrivKey(name, armor, passphrase)
|
||||
return newDBKeybase(db, lkb.options...).ImportPrivKey(name, armor, passphrase)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) ImportPubKey(name string, armor string) (err error) {
|
||||
|
@ -174,7 +176,7 @@ func (lkb lazyKeybase) ImportPubKey(name string, armor string) (err error) {
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).ImportPubKey(name, armor)
|
||||
return newDBKeybase(db, lkb.options...).ImportPubKey(name, armor)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) Export(name string) (armor string, err error) {
|
||||
|
@ -184,7 +186,7 @@ func (lkb lazyKeybase) Export(name string) (armor string, err error) {
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).Export(name)
|
||||
return newDBKeybase(db, lkb.options...).Export(name)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) ExportPubKey(name string) (armor string, err error) {
|
||||
|
@ -194,7 +196,7 @@ func (lkb lazyKeybase) ExportPubKey(name string) (armor string, err error) {
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).ExportPubKey(name)
|
||||
return newDBKeybase(db, lkb.options...).ExportPubKey(name)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) ExportPrivateKeyObject(name string, passphrase string) (crypto.PrivKey, error) {
|
||||
|
@ -204,7 +206,7 @@ func (lkb lazyKeybase) ExportPrivateKeyObject(name string, passphrase string) (c
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).ExportPrivateKeyObject(name, passphrase)
|
||||
return newDBKeybase(db, lkb.options...).ExportPrivateKeyObject(name, passphrase)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) ExportPrivKey(name string, decryptPassphrase string,
|
||||
|
@ -216,7 +218,7 @@ func (lkb lazyKeybase) ExportPrivKey(name string, decryptPassphrase string,
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
return newDBKeybase(db).ExportPrivKey(name, decryptPassphrase, encryptPassphrase)
|
||||
return newDBKeybase(db, lkb.options...).ExportPrivKey(name, decryptPassphrase, encryptPassphrase)
|
||||
}
|
||||
|
||||
func (lkb lazyKeybase) CloseDB() {}
|
||||
|
|
|
@ -5,9 +5,12 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
tmamino "github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
@ -371,3 +374,77 @@ func TestLazySeedPhrase(t *testing.T) {
|
|||
require.Equal(t, info.GetPubKey().Address(), newInfo.GetPubKey().Address())
|
||||
require.Equal(t, info.GetPubKey(), newInfo.GetPubKey())
|
||||
}
|
||||
|
||||
var _ crypto.PrivKey = testPriv{}
|
||||
var _ crypto.PubKey = testPub{}
|
||||
var testCdc *amino.Codec
|
||||
|
||||
type testPriv []byte
|
||||
|
||||
func (privkey testPriv) PubKey() crypto.PubKey { return testPub{} }
|
||||
func (privkey testPriv) Bytes() []byte {
|
||||
return testCdc.MustMarshalBinaryBare(privkey)
|
||||
}
|
||||
func (privkey testPriv) Sign(msg []byte) ([]byte, error) { return []byte{}, nil }
|
||||
func (privkey testPriv) Equals(other crypto.PrivKey) bool { return true }
|
||||
|
||||
type testPub []byte
|
||||
|
||||
func (key testPub) Address() crypto.Address { return crypto.Address{} }
|
||||
func (key testPub) Bytes() []byte {
|
||||
return testCdc.MustMarshalBinaryBare(key)
|
||||
}
|
||||
func (key testPub) VerifyBytes(msg []byte, sig []byte) bool { return true }
|
||||
func (key testPub) Equals(other crypto.PubKey) bool { return true }
|
||||
|
||||
func TestKeygenOverride(t *testing.T) {
|
||||
dir, cleanup := tests.NewTestCaseDir(t)
|
||||
defer cleanup()
|
||||
|
||||
// Save existing codec and reset after test
|
||||
cryptoCdc := CryptoCdc
|
||||
defer func() {
|
||||
CryptoCdc = cryptoCdc
|
||||
}()
|
||||
|
||||
// Setup testCdc encoding and decoding new key type
|
||||
testCdc = codec.New()
|
||||
RegisterCodec(testCdc)
|
||||
tmamino.RegisterAmino(testCdc)
|
||||
|
||||
// Set up codecs for using new key types
|
||||
privName, pubName := "test/priv_name", "test/pub_name"
|
||||
tmamino.RegisterKeyType(testPriv{}, privName)
|
||||
tmamino.RegisterKeyType(testPub{}, pubName)
|
||||
testCdc.RegisterConcrete(testPriv{}, privName, nil)
|
||||
testCdc.RegisterConcrete(testPub{}, pubName, nil)
|
||||
CryptoCdc = testCdc
|
||||
|
||||
overrideCalled := false
|
||||
dummyFunc := func(bz [32]byte) crypto.PrivKey {
|
||||
overrideCalled = true
|
||||
return testPriv(bz[:])
|
||||
}
|
||||
|
||||
kb := New("keybasename", dir, WithKeygenFunc(dummyFunc))
|
||||
|
||||
testName, pw := "name", "testPassword"
|
||||
|
||||
// create new key which will generate with
|
||||
info, _, err := kb.CreateMnemonic(testName, English, pw, Secp256k1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, info.GetName(), testName)
|
||||
|
||||
// Assert overridden function was called
|
||||
require.True(t, overrideCalled)
|
||||
|
||||
// export private key object
|
||||
exported, err := kb.ExportPrivateKeyObject(testName, pw)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
|
||||
// require that the key type is the new key
|
||||
_, ok := exported.(testPriv)
|
||||
require.True(t, ok)
|
||||
|
||||
require.True(t, exported.PubKey().Equals(info.GetPubKey()))
|
||||
}
|
||||
|
|
|
@ -306,11 +306,19 @@ func (i multiInfo) GetPath() (*hd.BIP44Params, error) {
|
|||
|
||||
// encoding info
|
||||
func marshalInfo(i Info) []byte {
|
||||
return cdc.MustMarshalBinaryLengthPrefixed(i)
|
||||
return CryptoCdc.MustMarshalBinaryLengthPrefixed(i)
|
||||
}
|
||||
|
||||
// decoding info
|
||||
func unmarshalInfo(bz []byte) (info Info, err error) {
|
||||
err = cdc.UnmarshalBinaryLengthPrefixed(bz, &info)
|
||||
err = CryptoCdc.UnmarshalBinaryLengthPrefixed(bz, &info)
|
||||
return
|
||||
}
|
||||
|
||||
type (
|
||||
// PrivKeyGenFunc defines the function to convert derived key bytes to a tendermint private key
|
||||
PrivKeyGenFunc func(bz [32]byte) crypto.PrivKey
|
||||
|
||||
// KeybaseOption overrides options for the db
|
||||
KeybaseOption func(*kbOptions)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue