// CreateEncryptedWallet creates a new default account with a wallet file // encrypted with passphrase. func (am *AccountManager) CreateEncryptedWallet(passphrase []byte) error { if len(am.AllAccounts()) != 0 { return ErrWalletExists } // Get current block's height and hash. bs, err := GetCurBlock() if err != nil { return err } // Create new wallet in memory. wlt, err := wallet.NewWallet("", "Default acccount", passphrase, activeNet.Params, &bs, cfg.KeypoolSize) if err != nil { return err } // Create new account and begin managing with the global account // manager. Registering will fail if the new account can not be // written immediately to disk. a := &Account{ Wallet: wlt, TxStore: txstore.New(), lockedOutpoints: map[btcwire.OutPoint]struct{}{}, } if err := am.RegisterNewAccount(a); err != nil { return err } // Begin tracking account against a connected btcd. a.Track() return nil }
// openSavedAccount opens a named account from disk. If the wallet does not // exist, errNoWallet is returned as an error. func openSavedAccount(name string, cfg *config) (*Account, error) { netdir := networkDir(cfg.Net()) if err := checkCreateDir(netdir); err != nil { return nil, &walletOpenError{ Err: err.Error(), } } wlt := new(wallet.Wallet) txs := txstore.New() a := &Account{ name: name, Wallet: wlt, TxStore: txs, } wfilepath := accountFilename("wallet.bin", name, netdir) txfilepath := accountFilename("tx.bin", name, netdir) var wfile, txfile *os.File // Read wallet file. wfile, err := os.Open(wfilepath) if err != nil { if os.IsNotExist(err) { // Must create and save wallet first. return nil, errNoWallet } msg := fmt.Sprintf("cannot open wallet file: %s", err) return nil, &walletOpenError{msg} } defer wfile.Close() if _, err = wlt.ReadFrom(wfile); err != nil { msg := fmt.Sprintf("cannot read wallet: %s", err) return nil, &walletOpenError{msg} } // Read tx file. If this fails, return a errNoTxs error and let // the caller decide if a rescan is necessary. var finalErr error if txfile, err = os.Open(txfilepath); err != nil { log.Errorf("cannot open tx file: %s", err) // This is not a error we should immediately return with, // but other errors can be more important, so only return // this if none of the others are hit. finalErr = errNoTxs a.fullRescan = true } else { defer txfile.Close() if _, err = txs.ReadFrom(txfile); err != nil { log.Errorf("cannot read tx file: %s", err) a.fullRescan = true finalErr = errNoTxs } } return a, finalErr }
// openSavedAccount opens a named account from disk. If the wallet does not // exist, errNoWallet is returned as an error. func openSavedAccount(name string, cfg *config) (*Account, error) { netdir := networkDir(activeNet.Params) if err := checkCreateDir(netdir); err != nil { return nil, &walletOpenError{ Err: err.Error(), } } wlt := new(wallet.Wallet) txs := txstore.New() a := &Account{ name: name, Wallet: wlt, TxStore: txs, lockedOutpoints: map[btcwire.OutPoint]struct{}{}, } walletPath := accountFilename("wallet.bin", name, netdir) txstorePath := accountFilename("tx.bin", name, netdir) // Read wallet file. walletFi, err := os.Open(walletPath) if err != nil { if os.IsNotExist(err) { // Must create and save wallet first. return nil, errNoWallet } msg := fmt.Sprintf("cannot open wallet file: %s", err) return nil, &walletOpenError{msg} } if _, err = wlt.ReadFrom(walletFi); err != nil { if err := walletFi.Close(); err != nil { log.Warnf("Cannot close wallet file: %v", err) } msg := fmt.Sprintf("Cannot read wallet: %s", err) return nil, &walletOpenError{msg} } // Read txstore file. If this fails, write a new empty transaction // store to disk, mark the wallet as unsynced, and write the unsynced // wallet to disk. // // This file is opened read/write so it may be truncated if a new empty // transaction store must be written. txstoreFi, err := os.OpenFile(txstorePath, os.O_RDWR, 0) if err != nil { if err := walletFi.Close(); err != nil { log.Warnf("Cannot close wallet file: %v", err) } if err := writeUnsyncedWallet(a, walletPath); err != nil { return nil, err } // Create and write empty txstore, if it doesn't exist. if !fileExists(txstorePath) { log.Warn("Transaction store file missing") if txstoreFi, err = os.Create(txstorePath); err != nil { return nil, fmt.Errorf("cannot create new "+ "txstore file: %v", err) } defer func() { if err := txstoreFi.Close(); err != nil { log.Warnf("Cannot close transaction "+ "store file: %v", err) } }() } else { return nil, fmt.Errorf("transaction store file "+ "exists but cannot be opened: %v", err) } if _, err := txs.WriteTo(txstoreFi); err != nil { log.Warn(err) } return a, nil } if _, err = txs.ReadFrom(txstoreFi); err != nil { if err := walletFi.Close(); err != nil { log.Warnf("Cannot close wallet file: %v", err) } if err := writeUnsyncedWallet(a, walletPath); err != nil { return nil, err } defer func() { if err := txstoreFi.Close(); err != nil { log.Warnf("Cannot close transaction store "+ "file: %v", err) } }() log.Warnf("Cannot read transaction store: %s", err) if _, err := txstoreFi.Seek(0, os.SEEK_SET); err != nil { return nil, err } if err := txstoreFi.Truncate(0); err != nil { return nil, err } if _, err := txs.WriteTo(txstoreFi); err != nil { log.Warn("Cannot write new transaction store: %v", err) } log.Infof("Wrote empty transaction store file") return a, nil } if err := walletFi.Close(); err != nil { log.Warnf("Cannot close wallet file: %v", err) } if err := txstoreFi.Close(); err != nil { log.Warnf("Cannot close transaction store file: %v", err) } return a, nil }