// ReadKeyFileToECPriv returns an extendedkey from a file. // If there's no file there, it'll make one. If there's a password needed, // it'll prompt for one. One stop function. func ReadKeyFileToECPriv( filename string, p *chaincfg.Params) (*hdkeychain.ExtendedKey, error) { key32 := new([32]byte) _, err := os.Stat(filename) if err != nil { if os.IsNotExist(err) { // no key found, generate and save one fmt.Printf("No file %s, generating.\n", filename) rn, err := hdkeychain.GenerateSeed(32) if err != nil { return nil, err } copy(key32[:], rn[:]) err = SaveKeyToFileInteractive(filename, key32) if err != nil { return nil, err } } else { // unknown error, crash fmt.Printf("unknown\n") return nil, err } } key, err := LoadKeyFromFileInteractive(filename) if err != nil { return nil, err } rootpriv, err := hdkeychain.NewMaster(key[:], p) if err != nil { return nil, err } return rootpriv, nil }
// Seed prompts the user whether they want to use an existing wallet generation // seed. When the user answers no, a seed will be generated and displayed to // the user along with prompting them for confirmation. When the user answers // yes, a the user is prompted for it. All prompts are repeated until the user // enters a valid response. func Seed(reader *bufio.Reader) ([]byte, error) { // Ascertain the wallet generation seed. useUserSeed, err := promptListBool(reader, "Do you have an "+ "existing wallet seed you want to use?", "no") if err != nil { return nil, err } if !useUserSeed { seed, err := hdkeychain.GenerateSeed(hdkeychain.RecommendedSeedLen) if err != nil { return nil, err } fmt.Println("Your wallet generation seed is:") fmt.Printf("%x\n", seed) fmt.Println("IMPORTANT: Keep the seed in a safe place as you\n" + "will NOT be able to restore your wallet without it.") fmt.Println("Please keep in mind that anyone who has access\n" + "to the seed can also restore your wallet thereby\n" + "giving them access to all your funds, so it is\n" + "imperative that you keep it in a secure location.") for { fmt.Print(`Once you have stored the seed in a safe ` + `and secure location, enter "OK" to continue: `) confirmSeed, err := reader.ReadString('\n') if err != nil { return nil, err } confirmSeed = strings.TrimSpace(confirmSeed) confirmSeed = strings.Trim(confirmSeed, `"`) if confirmSeed == "OK" { break } } return seed, nil } for { fmt.Print("Enter existing wallet seed: ") seedStr, err := reader.ReadString('\n') if err != nil { return nil, err } seedStr = strings.TrimSpace(strings.ToLower(seedStr)) seed, err := hex.DecodeString(seedStr) if err != nil || len(seed) < hdkeychain.MinSeedBytes || len(seed) > hdkeychain.MaxSeedBytes { fmt.Printf("Invalid seed specified. Must be a "+ "hexadecimal value that is at least %d bits and "+ "at most %d bits\n", hdkeychain.MinSeedBytes*8, hdkeychain.MaxSeedBytes*8) continue } return seed, nil } }