// ExportWatchingWallet returns a watching-only version of the wallet serialized // database as a base64-encoded string. func (w *Wallet) ExportWatchingWallet(pubPass string) (string, error) { tmpDir, err := ioutil.TempDir("", "btcwallet") if err != nil { return "", err } defer os.RemoveAll(tmpDir) // Create a new file and write a copy of the current database into it. woDbPath := filepath.Join(tmpDir, walletDbWatchingOnlyName) fi, err := os.OpenFile(woDbPath, os.O_CREATE|os.O_RDWR, 0600) if err != nil { return "", err } if err := w.db.Copy(fi); err != nil { fi.Close() return "", err } fi.Close() defer os.Remove(woDbPath) // Open the new database, get the address manager namespace, and open // it. woDb, err := walletdb.Open("bdb", woDbPath) if err != nil { _ = os.Remove(woDbPath) return "", err } defer woDb.Close() namespace, err := woDb.Namespace(waddrmgrNamespaceKey) if err != nil { return "", err } woMgr, err := waddrmgr.Open(namespace, []byte(pubPass), w.chainParams, nil) if err != nil { return "", err } defer woMgr.Close() // Convert the namespace to watching only if needed. if err := woMgr.ConvertToWatchingOnly(); err != nil { // Only return the error is it's not because it's already // watching-only. When it is already watching-only, the code // just falls through to the export below. if !waddrmgr.IsError(err, waddrmgr.ErrWatchingOnly) { return "", err } } // Export the watching only wallet's serialized data. woWallet := *w woWallet.db = woDb woWallet.Manager = woMgr return woWallet.exportBase64() }
// Open loads an already-created wallet from the passed database and namespaces. func Open(pubPass []byte, params *chaincfg.Params, db walletdb.DB, waddrmgrNS, wtxmgrNS walletdb.Namespace, cbs *waddrmgr.OpenCallbacks) (*Wallet, error) { addrMgr, err := waddrmgr.Open(waddrmgrNS, pubPass, params, cbs) if err != nil { return nil, err } txMgr, err := wtxmgr.Open(wtxmgrNS) if err != nil { if !wtxmgr.IsNoExists(err) { return nil, err } log.Info("No recorded transaction history -- needs full rescan") err = addrMgr.SetSyncedTo(nil) if err != nil { return nil, err } txMgr, err = wtxmgr.Create(wtxmgrNS) if err != nil { return nil, err } } log.Infof("Opened wallet") // TODO: log balance? last sync height? w := &Wallet{ db: db, Manager: addrMgr, TxStore: txMgr, lockedOutpoints: map[wire.OutPoint]struct{}{}, FeeIncrement: defaultFeeIncrement, rescanAddJob: make(chan *RescanJob), rescanBatch: make(chan *rescanBatch), rescanNotifications: make(chan interface{}), rescanProgress: make(chan *RescanProgressMsg), rescanFinished: make(chan *RescanFinishedMsg), createTxRequests: make(chan createTxRequest), unlockRequests: make(chan unlockRequest), lockRequests: make(chan struct{}), holdUnlockRequests: make(chan chan HeldUnlock), lockState: make(chan bool), changePassphrase: make(chan changePassphraseRequest), chainParams: params, quit: make(chan struct{}), } return w, nil }