// createWallet prompts the user for information needed to generate a new wallet // and generates the wallet accordingly. The new wallet will reside at the // provided path. func createWallet(cfg *config) error { // When there is a legacy keystore, open it now to ensure any errors // don't end up exiting the process after the user has spent time // entering a bunch of information. netDir := networkDir(cfg.DataDir, activeNet.Params) keystorePath := filepath.Join(netDir, keystore.Filename) var legacyKeyStore *keystore.Store if fileExists(keystorePath) { var err error legacyKeyStore, err = keystore.OpenDir(netDir) if err != nil { return err } } // Start by prompting for the private passphrase. When there is an // existing keystore, the user will be promped for that passphrase, // otherwise they will be prompted for a new one. reader := bufio.NewReader(os.Stdin) privPass, err := promptConsolePrivatePass(reader, legacyKeyStore) if err != nil { return err } // Ascertain the public passphrase. This will either be a value // specified by the user or the default hard-coded public passphrase if // the user does not want the additional public data encryption. pubPass, err := promptConsolePublicPass(reader, privPass, cfg) if err != nil { return err } // Ascertain the wallet generation seed. This will either be an // automatically generated value the user has already confirmed or a // value the user has entered which has already been validated. seed, err := promptConsoleSeed(reader) if err != nil { return err } // Create the wallet. dbPath := filepath.Join(netDir, walletDbName) fmt.Println("Creating the wallet...") // Create the wallet database backed by bolt db. db, err := walletdb.Create("bdb", dbPath) if err != nil { return err } // Create the address manager. namespace, err := db.Namespace(waddrmgrNamespaceKey) if err != nil { return err } manager, err := waddrmgr.Create(namespace, seed, []byte(pubPass), []byte(privPass), activeNet.Params, nil) if err != nil { return err } // Import the addresses in the legacy keystore to the new wallet if // any exist. if legacyKeyStore != nil { fmt.Println("Importing addresses from existing wallet...") if err := manager.Unlock([]byte(privPass)); err != nil { return err } if err := convertLegacyKeystore(legacyKeyStore, manager); err != nil { return err } legacyKeyStore.Lock() legacyKeyStore = nil // Remove the legacy key store. if err := os.Remove(keystorePath); err != nil { fmt.Printf("WARN: Failed to remove legacy wallet "+ "from'%s'\n", keystorePath) } } manager.Close() fmt.Println("The wallet has been created successfully.") return nil }
// createWallet prompts the user for information needed to generate a new wallet // and generates the wallet accordingly. The new wallet will reside at the // provided path. func createWallet(cfg *config) error { dbDir := networkDir(cfg.AppDataDir.Value, activeNet.Params) loader := wallet.NewLoader(activeNet.Params, dbDir) // When there is a legacy keystore, open it now to ensure any errors // don't end up exiting the process after the user has spent time // entering a bunch of information. netDir := networkDir(cfg.AppDataDir.Value, activeNet.Params) keystorePath := filepath.Join(netDir, keystore.Filename) var legacyKeyStore *keystore.Store _, err := os.Stat(keystorePath) if err != nil && !os.IsNotExist(err) { // A stat error not due to a non-existant file should be // returned to the caller. return err } else if err == nil { // Keystore file exists. legacyKeyStore, err = keystore.OpenDir(netDir) if err != nil { return err } } // Start by prompting for the private passphrase. When there is an // existing keystore, the user will be promped for that passphrase, // otherwise they will be prompted for a new one. reader := bufio.NewReader(os.Stdin) privPass, err := prompt.PrivatePass(reader, legacyKeyStore) if err != nil { return err } // When there exists a legacy keystore, unlock it now and set up a // callback to import all keystore keys into the new walletdb // wallet if legacyKeyStore != nil { err = legacyKeyStore.Unlock(privPass) if err != nil { return err } // Import the addresses in the legacy keystore to the new wallet if // any exist, locking each wallet again when finished. loader.RunAfterLoad(func(w *wallet.Wallet) { defer legacyKeyStore.Lock() fmt.Println("Importing addresses from existing wallet...") err := w.Manager.Unlock(privPass) if err != nil { fmt.Printf("ERR: Failed to unlock new wallet "+ "during old wallet key import: %v", err) return } defer w.Manager.Lock() err = convertLegacyKeystore(legacyKeyStore, w.Manager) if err != nil { fmt.Printf("ERR: Failed to import keys from old "+ "wallet format: %v", err) return } // Remove the legacy key store. err = os.Remove(keystorePath) if err != nil { fmt.Printf("WARN: Failed to remove legacy wallet "+ "from'%s'\n", keystorePath) } }) } // Ascertain the public passphrase. This will either be a value // specified by the user or the default hard-coded public passphrase if // the user does not want the additional public data encryption. pubPass, err := prompt.PublicPass(reader, privPass, []byte(wallet.InsecurePubPassphrase), []byte(cfg.WalletPass)) if err != nil { return err } // Ascertain the wallet generation seed. This will either be an // automatically generated value the user has already confirmed or a // value the user has entered which has already been validated. seed, err := prompt.Seed(reader) if err != nil { return err } fmt.Println("Creating the wallet...") w, err := loader.CreateNewWallet(pubPass, privPass, seed) if err != nil { return err } w.Manager.Close() fmt.Println("The wallet has been created successfully.") return nil }