diff options
author | kumavis <kumavis@users.noreply.github.com> | 2017-01-06 03:18:34 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-06 03:18:34 +0800 |
commit | 00ac5ca058691c58d6401098c3d6905728f12e39 (patch) | |
tree | 68e0208cba8f651eb548563217e6da5d947a05c6 /app/scripts | |
parent | e62f70660d922b0bf98e7595939f84821eff814a (diff) | |
parent | 70816d7cb0cf4850d03956801bb6d3ca04158f9f (diff) | |
download | tangerine-wallet-browser-00ac5ca058691c58d6401098c3d6905728f12e39.tar tangerine-wallet-browser-00ac5ca058691c58d6401098c3d6905728f12e39.tar.gz tangerine-wallet-browser-00ac5ca058691c58d6401098c3d6905728f12e39.tar.bz2 tangerine-wallet-browser-00ac5ca058691c58d6401098c3d6905728f12e39.tar.lz tangerine-wallet-browser-00ac5ca058691c58d6401098c3d6905728f12e39.tar.xz tangerine-wallet-browser-00ac5ca058691c58d6401098c3d6905728f12e39.tar.zst tangerine-wallet-browser-00ac5ca058691c58d6401098c3d6905728f12e39.zip |
Merge branch 'dev' into TearDownOnDisconnect
Diffstat (limited to 'app/scripts')
-rw-r--r-- | app/scripts/lib/eth-store.js | 144 | ||||
-rw-r--r-- | app/scripts/metamask-controller.js | 2 |
2 files changed, 145 insertions, 1 deletions
diff --git a/app/scripts/lib/eth-store.js b/app/scripts/lib/eth-store.js new file mode 100644 index 000000000..a42b2417f --- /dev/null +++ b/app/scripts/lib/eth-store.js @@ -0,0 +1,144 @@ +/* Ethereum Store + * + * This module is responsible for tracking any number of accounts + * and caching their current balances & transaction counts. + * + * It also tracks transaction hashes, and checks their inclusion status + * on each new block. + */ + +const EventEmitter = require('events').EventEmitter +const inherits = require('util').inherits +const async = require('async') +const clone = require('clone') +const EthQuery = require('eth-query') + +module.exports = EthereumStore + + +inherits(EthereumStore, EventEmitter) +function EthereumStore(engine) { + const self = this + EventEmitter.call(self) + self._currentState = { + accounts: {}, + transactions: {}, + } + self._query = new EthQuery(engine) + + engine.on('block', self._updateForBlock.bind(self)) +} + +// +// public +// + +EthereumStore.prototype.getState = function () { + const self = this + return clone(self._currentState) +} + +EthereumStore.prototype.addAccount = function (address) { + const self = this + self._currentState.accounts[address] = {} + self._didUpdate() + if (!self.currentBlockNumber) return + self._updateAccount(address, noop) +} + +EthereumStore.prototype.removeAccount = function (address) { + const self = this + delete self._currentState.accounts[address] + self._didUpdate() +} + +EthereumStore.prototype.addTransaction = function (txHash) { + const self = this + self._currentState.transactions[txHash] = {} + self._didUpdate() + if (!self.currentBlockNumber) return + self._updateTransaction(self.currentBlockNumber, txHash, noop) +} + +EthereumStore.prototype.removeTransaction = function (address) { + const self = this + delete self._currentState.transactions[address] + self._didUpdate() +} + + +// +// private +// + +EthereumStore.prototype._didUpdate = function () { + const self = this + var state = self.getState() + self.emit('update', state) +} + +EthereumStore.prototype._updateForBlock = function (block) { + const self = this + var blockNumber = '0x' + block.number.toString('hex') + self.currentBlockNumber = blockNumber + async.parallel([ + self._updateAccounts.bind(self), + self._updateTransactions.bind(self, blockNumber), + ], function (err) { + if (err) return console.error(err) + self.emit('block', self.getState()) + self._didUpdate() + }) +} + +EthereumStore.prototype._updateAccounts = function (cb) { + var accountsState = this._currentState.accounts + var addresses = Object.keys(accountsState) + async.each(addresses, this._updateAccount.bind(this), cb) +} + +EthereumStore.prototype._updateAccount = function (address, cb) { + var accountsState = this._currentState.accounts + this.getAccount(address, function (err, result) { + if (err) return cb(err) + result.address = address + // only populate if the entry is still present + if (accountsState[address]) { + accountsState[address] = result + } + cb(null, result) + }) +} + +EthereumStore.prototype.getAccount = function (address, cb) { + const query = this._query + async.parallel({ + balance: query.getBalance.bind(query, address), + nonce: query.getTransactionCount.bind(query, address), + code: query.getCode.bind(query, address), + }, cb) +} + +EthereumStore.prototype._updateTransactions = function (block, cb) { + const self = this + var transactionsState = self._currentState.transactions + var txHashes = Object.keys(transactionsState) + async.each(txHashes, self._updateTransaction.bind(self, block), cb) +} + +EthereumStore.prototype._updateTransaction = function (block, txHash, cb) { + const self = this + // would use the block here to determine how many confirmations the tx has + var transactionsState = self._currentState.transactions + self._query.getTransaction(txHash, function (err, result) { + if (err) return cb(err) + // only populate if the entry is still present + if (transactionsState[txHash]) { + transactionsState[txHash] = result + self._didUpdate() + } + cb(null, result) + }) +} + +function noop() {} diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 2e5b02a7b..76ca99b25 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1,6 +1,6 @@ const EventEmitter = require('events') const extend = require('xtend') -const EthStore = require('eth-store') +const EthStore = require('./lib/eth-store') const MetaMaskProvider = require('web3-provider-engine/zero.js') const KeyringController = require('./keyring-controller') const NoticeController = require('./notice-controller') |