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  }