feat(client): Add flag & reading mnemonic from file (backport #20690) (#20712)

Co-authored-by: Hieu Vu <72878483+hieuvubk@users.noreply.github.com>
Co-authored-by: marbar3778 <marbar3778@yahoo.com>
This commit is contained in:
mergify[bot] 2024-06-18 11:01:32 +02:00 committed by GitHub
parent 5e0f76726e
commit d6428f7335
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 6 deletions

View File

@ -38,6 +38,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
## [Unreleased]
## Features
* (client) [#20690](https://github.com/cosmos/cosmos-sdk/pull/20690) Import mnemonic from file
## Improvements
* (x/authz,x/feegrant) [#20590](https://github.com/cosmos/cosmos-sdk/pull/20590) Provide updated keeper in depinject for authz and feegrant modules.

View File

@ -7,6 +7,8 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"os"
"sort"
"github.com/cosmos/go-bip39"
@ -35,6 +37,8 @@ const (
flagNoSort = "nosort"
flagHDPath = "hd-path"
flagPubKeyBase64 = "pubkey-base64"
flagIndiscreet = "indiscreet"
flagMnemonicSrc = "source"
// DefaultKeyPass contains the default key password for genesis transactions
DefaultKeyPass = "12345678"
@ -57,6 +61,11 @@ local keystore.
Use the --pubkey flag to add arbitrary public keys to the keystore for constructing
multisig transactions.
Use the --source flag to import mnemonic from a file in recover or interactive mode.
Example:
keys add testing --recover --source ./mnemonic.txt
You can create and store a multisig key by passing the list of key names stored in a keyring
and the minimum number of signatures required through --multisig-threshold. The keys are
sorted by address, unless the flag --nosort is set.
@ -83,6 +92,8 @@ Example:
f.Uint32(flagAccount, 0, "Account number for HD derivation (less than equal 2147483647)")
f.Uint32(flagIndex, 0, "Address index number for HD derivation (less than equal 2147483647)")
f.String(flags.FlagKeyType, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for")
f.Bool(flagIndiscreet, false, "Print seed phrase directly on current terminal (only valid when --no-backup is false)")
f.String(flagMnemonicSrc, "", "Import mnemonic from a file (only usable when recover or interactive is passed)")
// support old flags name for backwards compatibility
f.SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
@ -270,19 +281,34 @@ func runAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
var mnemonic, bip39Passphrase string
recoverFlag, _ := cmd.Flags().GetBool(flagRecover)
mnemonicSrc, _ := cmd.Flags().GetString(flagMnemonicSrc)
if recoverFlag {
mnemonic, err = input.GetString("Enter your bip39 mnemonic", inBuf)
if err != nil {
return err
if mnemonicSrc != "" {
mnemonic, err = readMnemonicFromFile(mnemonicSrc)
if err != nil {
return err
}
} else {
mnemonic, err = input.GetString("Enter your bip39 mnemonic", inBuf)
if err != nil {
return err
}
}
if !bip39.IsMnemonicValid(mnemonic) {
return errors.New("invalid mnemonic")
}
} else if interactive {
mnemonic, err = input.GetString("Enter your bip39 mnemonic, or hit enter to generate one.", inBuf)
if err != nil {
return err
if mnemonicSrc != "" {
mnemonic, err = readMnemonicFromFile(mnemonicSrc)
if err != nil {
return err
}
} else {
mnemonic, err = input.GetString("Enter your bip39 mnemonic, or hit enter to generate one.", inBuf)
if err != nil {
return err
}
}
if !bip39.IsMnemonicValid(mnemonic) && mnemonic != "" {
@ -377,3 +403,17 @@ func printCreate(cmd *cobra.Command, k *keyring.Record, showMnemonic bool, mnemo
return nil
}
func readMnemonicFromFile(filePath string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", err
}
defer file.Close()
bz, err := io.ReadAll(file)
if err != nil {
return "", err
}
return string(bz), nil
}