forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
keys new
and keys mnemonic
commands
Closes cosmos#2091.
- Loading branch information
Showing
11 changed files
with
456 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package keys | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
"github.com/cosmos/cosmos-sdk/crypto/keys" | ||
"fmt" | ||
"os/signal" | ||
"os" | ||
"syscall" | ||
"bytes" | ||
"github.com/cosmos/cosmos-sdk/client" | ||
"bufio" | ||
"github.com/cosmos/cosmos-sdk/crypto/keys/bip39" | ||
) | ||
|
||
const ( | ||
flagEntropy = "user" | ||
) | ||
|
||
func mnemonicCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "mnemonic", | ||
Short: "Creates a new mnemonic for use in key generation. Uses system entropy by default.", | ||
RunE: runMnemonicCmd, | ||
} | ||
cmd.Flags().Bool(flagEntropy, false, "Prompt the use to enter entropy. Otherwise, use the system's entropy.") | ||
return cmd | ||
} | ||
|
||
func runMnemonicCmd(cmd *cobra.Command, args []string) error { | ||
kb, err := GetKeyBase() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !viper.GetBool(flagEntropy) { | ||
return outputMnemonic(kb, nil) | ||
} | ||
|
||
stdin := client.BufferStdin() | ||
var buf bytes.Buffer | ||
done := make(chan bool) | ||
sigs := make(chan os.Signal, 1) | ||
signal.Notify(sigs, syscall.SIGTERM) | ||
|
||
// need below signal handling in order to prevent panics on SIGTERM | ||
go func() { | ||
<-sigs | ||
fmt.Println("Killed.") | ||
os.Exit(1) | ||
}() | ||
|
||
go func() { | ||
fmt.Println("Please provide entropy using your keyboard and press enter.") | ||
scanner := bufio.NewScanner(stdin) | ||
for scanner.Scan() { | ||
buf.Write(scanner.Bytes()) | ||
if buf.Len() >= bip39.FreshKeyEntropySize { | ||
done <- true | ||
return | ||
} | ||
|
||
fmt.Println("Please provide additional entropy and press enter.") | ||
} | ||
}() | ||
|
||
<-done | ||
if err != nil { | ||
return err | ||
} | ||
|
||
buf.Truncate(bip39.FreshKeyEntropySize) | ||
return outputMnemonic(kb, buf.Bytes()) | ||
|
||
} | ||
|
||
func outputMnemonic(kb keys.Keybase, entropy []byte) error { | ||
fmt.Println("Generating mnemonic...") | ||
mnemonic, err := kb.GenerateMnemonic(keys.English, entropy) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println(mnemonic) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package keys | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
"github.com/pkg/errors" | ||
"github.com/cosmos/cosmos-sdk/crypto/keys" | ||
"fmt" | ||
"github.com/cosmos/cosmos-sdk/client" | ||
"github.com/cosmos/cosmos-sdk/crypto/keys/hd" | ||
) | ||
|
||
const ( | ||
flagDefault = "default" | ||
) | ||
|
||
func newCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "new <name>", | ||
Args: cobra.ExactArgs(1), | ||
Short: "Creates a new key interactively, or with sensible defaults.", | ||
RunE: runNewCommand, | ||
} | ||
cmd.Flags().Bool(flagDefault, true, "Use system entropy to generate a new mnemonic and derive a key using default parameters") | ||
return cmd | ||
} | ||
|
||
func runNewCommand(cmd *cobra.Command, args []string) error { | ||
name := args[0] | ||
|
||
if name == "" { | ||
return errors.New("you must provide a name for the key") | ||
} | ||
|
||
kb, err := GetKeyBase() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
isDefault := viper.GetBool(flagDefault) | ||
if isDefault { | ||
_, seed, err := kb.CreateMnemonic(name, keys.English, "", keys.Secp256k1) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Printf("Seed: %s\n", seed) | ||
fmt.Printf("Successfully wrote encrypted priv key named %s\n", name) | ||
return nil | ||
} | ||
|
||
var mnemonic string | ||
var bip39Pw string | ||
var bip44Path string | ||
var encryptionPw string | ||
|
||
stdin := client.BufferStdin() | ||
printPrefixed("Enter your bip39 mnemonic.") | ||
printPrefixed("If you don't have one, just hit enter and one will be generated for you.") | ||
mnemonic, err = client.GetSeed("", stdin) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if mnemonic == "" { | ||
mnemonic, err = kb.GenerateMnemonic(keys.English, nil) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
printStep() | ||
printPrefixed("Enter your bip39 passphrase.") | ||
printPrefixed("If you don't have one, just hit enter and the default \"\" will be used.") | ||
bip39Pw, err = client.GetString("", stdin) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
printStep() | ||
printPrefixed("Enter your bip44 path. If you press enter, the default of m/44'/0'/0'/0/0 will be used.") | ||
bip44Path, err = client.GetString("", stdin) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if bip44Path == "" { | ||
bip44Path = "m/44'/0'/0'/0/0" | ||
} | ||
|
||
printStep() | ||
printPrefixed("Enter a password to encrypt the derived private key with.") | ||
encryptionPw, err = client.GetString("", stdin) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if encryptionPw == "" { | ||
return errors.New("you must define an encryption password") | ||
} | ||
|
||
printStep() | ||
|
||
params, err := hd.ParamsFromString(bip44Path) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = kb.Derive(name, mnemonic, encryptionPw, bip39Pw, *params) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Printf("Mnemonic: %s\n", mnemonic) | ||
fmt.Printf("Successfully wrote encrypted priv key named %s\n", name) | ||
|
||
return nil | ||
} | ||
|
||
func printPrefixed(msg string) { | ||
fmt.Printf("> %s\n", msg) | ||
} | ||
|
||
func printStep() { | ||
printPrefixed("-------------------------------------") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.