-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
feat(client): Add flag & reading mnemonic from file #20690
Changes from all commits
e0a3735
6d7a634
e065be7
b838bcd
e05bfa2
454a697
a86dda8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -7,6 +7,8 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
"encoding/json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"errors" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"io" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"os" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"sort" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"strings" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -38,6 +40,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
flagHDPath = "hd-path" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
flagPubKeyBase64 = "pubkey-base64" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
flagIndiscreet = "indiscreet" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
flagMnemonicSrc = "source" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// DefaultKeyPass contains the default key password for genesis transactions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DefaultKeyPass = "12345678" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -60,6 +63,11 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
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. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -87,6 +95,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -282,19 +291,34 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -404,3 +428,17 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+431
to
+444
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve error handling in The function - return "", err
+ return "", fmt.Errorf("failed to open mnemonic source file: %w", err)
- return "", err
+ return "", fmt.Errorf("failed to read mnemonic from file: %w", err) Committable suggestion
Suggested change
ToolsGitHub Check: gosec
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tip
Codebase Verification
Consider enhancing the error handling in
readMnemonicFromFile
to provide more user-friendly and informative error messages. Currently, the function returns raw errors fromos.Open
andio.ReadAll
, which may not be clear to end-users.client/keys/add.go:430
: Wrap the error fromos.Open
with a message indicating the file could not be opened.client/keys/add.go:436
: Wrap the error fromio.ReadAll
with a message indicating the file could not be read.Analysis chain
The implementation for reading the mnemonic from a file is correctly placed under the conditions checking the
flagRecover
andflagInteractive
. However, consider handling the scenario where the file path might be incorrect or the file might be empty.Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 221
Script:
Length of output: 662