// 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 }
func exampleCreateTxStore() (*wtxmgr.Store, func(), error) { dir, err := ioutil.TempDir("", "pool_test_txstore") if err != nil { return nil, nil, err } db, err := walletdb.Create("bdb", filepath.Join(dir, "txstore.db")) if err != nil { return nil, nil, err } wtxmgrNamespace, err := db.Namespace([]byte("testtxstore")) if err != nil { return nil, nil, err } s, err := wtxmgr.Create(wtxmgrNamespace) if err != nil { return nil, nil, err } return s, func() { os.RemoveAll(dir) }, nil }
func TstCreateTxStore(t *testing.T) (store *wtxmgr.Store, tearDown func()) { dir, err := ioutil.TempDir("", "pool_test_txstore") if err != nil { t.Fatalf("Failed to create txstore dir: %v", err) } db, err := walletdb.Create("bdb", filepath.Join(dir, "txstore.db")) if err != nil { t.Fatalf("Failed to create walletdb: %v", err) } wtxmgrNamespace, err := db.Namespace([]byte("testtxstore")) if err != nil { t.Fatalf("Failed to create walletdb namespace: %v", err) } s, err := wtxmgr.Create(wtxmgrNamespace) if err != nil { t.Fatalf("Failed to create txstore: %v", err) } return s, func() { os.RemoveAll(dir) } }
// CreateNewWallet creates a new wallet using the provided public and private // passphrases. The seed is optional. If non-nil, addresses are derived from // this seed. If nil, a secure random seed is generated. func (l *Loader) CreateNewWallet(pubPassphrase, privPassphrase, seed []byte) (*Wallet, error) { defer l.mu.Unlock() l.mu.Lock() if l.wallet != nil { return nil, ErrLoaded } dbPath := filepath.Join(l.dbDirPath, walletDbName) exists, err := fileExists(dbPath) if err != nil { return nil, err } if exists { return nil, ErrExists } // Create the wallet database backed by bolt db. err = os.MkdirAll(l.dbDirPath, 0700) if err != nil { return nil, err } db, err := walletdb.Create("bdb", dbPath) if err != nil { return nil, err } // Create the address manager. if seed != nil { if len(seed) < hdkeychain.MinSeedBytes || len(seed) > hdkeychain.MaxSeedBytes { return nil, hdkeychain.ErrInvalidSeedLen } } addrMgrNamespace, err := db.Namespace(waddrmgrNamespaceKey) if err != nil { return nil, err } _, err = waddrmgr.Create(addrMgrNamespace, seed, pubPassphrase, privPassphrase, l.chainParams, nil) if err != nil { return nil, err } // Create empty transaction manager. txMgrNamespace, err := db.Namespace(wtxmgrNamespaceKey) if err != nil { return nil, err } _, err = wtxmgr.Create(txMgrNamespace) if err != nil { return nil, err } // Open the newly-created wallet. w, err := Open(pubPassphrase, l.chainParams, db, addrMgrNamespace, txMgrNamespace, nil) if err != nil { return nil, err } l.onLoaded(w, db) return w, nil }
func Example_basicUsage() { // Open the database. db, dbTeardown, err := testDB() defer dbTeardown() if err != nil { fmt.Println(err) return } // Create or open a db namespace for the transaction store. ns, err := db.Namespace([]byte("txstore")) if err != nil { fmt.Println(err) return } // Create (or open) the transaction store in the provided namespace. s, err := wtxmgr.Create(ns) if err != nil { fmt.Println(err) return } // Insert an unmined transaction that outputs 10 BTC to a wallet address // at output 0. err = s.InsertTx(exampleTxRecordA, nil) if err != nil { fmt.Println(err) return } err = s.AddCredit(exampleTxRecordA, nil, 0, false) if err != nil { fmt.Println(err) return } // Insert a second transaction which spends the output, and creates two // outputs. Mark the second one (5 BTC) as wallet change. err = s.InsertTx(exampleTxRecordB, nil) if err != nil { fmt.Println(err) return } err = s.AddCredit(exampleTxRecordB, nil, 1, true) if err != nil { fmt.Println(err) return } // Mine each transaction in a block at height 100. err = s.InsertTx(exampleTxRecordA, &exampleBlock100) if err != nil { fmt.Println(err) return } err = s.InsertTx(exampleTxRecordB, &exampleBlock100) if err != nil { fmt.Println(err) return } // Print the one confirmation balance. bal, err := s.Balance(1, 100) if err != nil { fmt.Println(err) return } fmt.Println(bal) // Fetch unspent outputs. utxos, err := s.UnspentOutputs() if err != nil { fmt.Println(err) } expectedOutPoint := wire.OutPoint{Hash: exampleTxRecordB.Hash, Index: 1} for _, utxo := range utxos { fmt.Println(utxo.OutPoint == expectedOutPoint) } // Output: // 5 BTC // true }