github.com/prysmaticlabs/prysm@v1.4.4/validator/keymanager/derived/mnemonic.go (about) 1 package derived 2 3 import ( 4 "fmt" 5 "os" 6 7 "github.com/pkg/errors" 8 "github.com/prysmaticlabs/prysm/shared/promptutil" 9 "github.com/prysmaticlabs/prysm/shared/rand" 10 "github.com/tyler-smith/go-bip39" 11 ) 12 13 const confirmationText = "Confirm you have written down the recovery words somewhere safe (offline) [y|Y]" 14 15 // EnglishMnemonicGenerator implements methods for creating 16 // mnemonic seed phrases in english using a given 17 // source of entropy such as a private key. 18 type EnglishMnemonicGenerator struct { 19 skipMnemonicConfirm bool 20 } 21 22 // GenerateAndConfirmMnemonic requires confirming the generated mnemonics. 23 func GenerateAndConfirmMnemonic( 24 skipMnemonicConfirm bool, 25 ) (string, error) { 26 mnemonicRandomness := make([]byte, 32) 27 if _, err := rand.NewGenerator().Read(mnemonicRandomness); err != nil { 28 return "", errors.Wrap(err, "could not initialize mnemonic source of randomness") 29 } 30 m := &EnglishMnemonicGenerator{ 31 skipMnemonicConfirm: skipMnemonicConfirm, 32 } 33 phrase, err := m.Generate(mnemonicRandomness) 34 if err != nil { 35 return "", errors.Wrap(err, "could not generate wallet seed") 36 } 37 if err := m.ConfirmAcknowledgement(phrase); err != nil { 38 return "", errors.Wrap(err, "could not confirm mnemonic acknowledgement") 39 } 40 return phrase, nil 41 } 42 43 // Generate a mnemonic seed phrase in english using a source of 44 // entropy given as raw bytes. 45 func (m *EnglishMnemonicGenerator) Generate(data []byte) (string, error) { 46 return bip39.NewMnemonic(data) 47 } 48 49 // ConfirmAcknowledgement displays the mnemonic phrase to the user 50 // and confirms the user has written down the phrase securely offline. 51 func (m *EnglishMnemonicGenerator) ConfirmAcknowledgement(phrase string) error { 52 log.Info( 53 "Write down the sentence below, as it is your only " + 54 "means of recovering your wallet", 55 ) 56 fmt.Printf( 57 `=================Wallet Seed Recovery Phrase==================== 58 59 %s 60 61 ===================================================================`, 62 phrase) 63 fmt.Println("") 64 if m.skipMnemonicConfirm { 65 return nil 66 } 67 // Confirm the user has written down the mnemonic phrase offline. 68 _, err := promptutil.ValidatePrompt(os.Stdin, confirmationText, promptutil.ValidateConfirmation) 69 if err != nil { 70 log.Errorf("Could not confirm acknowledgement of prompt, please enter y") 71 } 72 return nil 73 } 74 75 // Uses the provided mnemonic seed phrase to generate the 76 // appropriate seed file for recovering a derived wallets. 77 func seedFromMnemonic(mnemonic, mnemonicPassphrase string) ([]byte, error) { 78 if ok := bip39.IsMnemonicValid(mnemonic); !ok { 79 return nil, bip39.ErrInvalidMnemonic 80 } 81 return bip39.NewSeed(mnemonic, mnemonicPassphrase), nil 82 }