Skip to content

Commit

Permalink
feat(client): Add flag & reading mnemonic from file (backport #20690) (
Browse files Browse the repository at this point in the history
…#20712)

Co-authored-by: Hieu Vu <72878483+hieuvubk@users.noreply.github.com>
Co-authored-by: marbar3778 <marbar3778@yahoo.com>
  • Loading branch information
3 people authored Jun 18, 2024
1 parent 5e0f767 commit d6428f7
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
52 changes: 46 additions & 6 deletions client/keys/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"os"
"sort"

"github.com/cosmos/go-bip39"
Expand Down Expand Up @@ -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"
Expand All @@ -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.
Expand All @@ -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 {
Expand Down Expand Up @@ -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 != "" {
Expand Down Expand Up @@ -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
}

0 comments on commit d6428f7

Please sign in to comment.