diff options
author | Dan Finlay <542863+danfinlay@users.noreply.github.com> | 2017-09-28 01:57:02 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-28 01:57:02 +0800 |
commit | e72083f6e81f888f714125f7c050e777ea5c9bdd (patch) | |
tree | 8177fb150ae254b838cabec028b3c5e08fbc951e /app/scripts/lib/account-tracker.js | |
parent | ff5e8746bee0d7461df02e7f2186ff7c90bfcb50 (diff) | |
parent | ca0dff06f5d9283e57b452dcc7e85c31b248b8aa (diff) | |
download | tangerine-wallet-browser-e72083f6e81f888f714125f7c050e777ea5c9bdd.tar tangerine-wallet-browser-e72083f6e81f888f714125f7c050e777ea5c9bdd.tar.gz tangerine-wallet-browser-e72083f6e81f888f714125f7c050e777ea5c9bdd.tar.bz2 tangerine-wallet-browser-e72083f6e81f888f714125f7c050e777ea5c9bdd.tar.lz tangerine-wallet-browser-e72083f6e81f888f714125f7c050e777ea5c9bdd.tar.xz tangerine-wallet-browser-e72083f6e81f888f714125f7c050e777ea5c9bdd.tar.zst tangerine-wallet-browser-e72083f6e81f888f714125f7c050e777ea5c9bdd.zip |
Merge branch 'master' into filter-fixes-moar
Diffstat (limited to 'app/scripts/lib/account-tracker.js')
-rw-r--r-- | app/scripts/lib/account-tracker.js | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/app/scripts/lib/account-tracker.js b/app/scripts/lib/account-tracker.js new file mode 100644 index 000000000..e2892b1ce --- /dev/null +++ b/app/scripts/lib/account-tracker.js @@ -0,0 +1,104 @@ +/* Account Tracker + * + * 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 async = require('async') +const EthQuery = require('eth-query') +const ObservableStore = require('obs-store') +const EventEmitter = require('events').EventEmitter +function noop () {} + + +class AccountTracker extends EventEmitter { + + constructor (opts = {}) { + super() + + const initState = { + accounts: {}, + currentBlockGasLimit: '', + } + this.store = new ObservableStore(initState) + + this._provider = opts.provider + this._query = new EthQuery(this._provider) + this._blockTracker = opts.blockTracker + // subscribe to latest block + this._blockTracker.on('block', this._updateForBlock.bind(this)) + // blockTracker.currentBlock may be null + this._currentBlockNumber = this._blockTracker.currentBlock + } + + // + // public + // + + addAccount (address) { + const accounts = this.store.getState().accounts + accounts[address] = {} + this.store.updateState({ accounts }) + if (!this._currentBlockNumber) return + this._updateAccount(address) + } + + removeAccount (address) { + const accounts = this.store.getState().accounts + delete accounts[address] + this.store.updateState({ accounts }) + } + + // + // private + // + + _updateForBlock (block) { + const blockNumber = '0x' + block.number.toString('hex') + this._currentBlockNumber = blockNumber + + this.store.updateState({ currentBlockGasLimit: `0x${block.gasLimit.toString('hex')}` }) + + async.parallel([ + this._updateAccounts.bind(this), + ], (err) => { + if (err) return console.error(err) + this.emit('block', this.store.getState()) + }) + } + + _updateAccounts (cb = noop) { + const accounts = this.store.getState().accounts + const addresses = Object.keys(accounts) + async.each(addresses, this._updateAccount.bind(this), cb) + } + + _updateAccount (address, cb = noop) { + this._getAccount(address, (err, result) => { + if (err) return cb(err) + result.address = address + const accounts = this.store.getState().accounts + // only populate if the entry is still present + if (accounts[address]) { + accounts[address] = result + this.store.updateState({ accounts }) + } + cb(null, result) + }) + } + + _getAccount (address, cb = noop) { + 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) + } + +} + +module.exports = AccountTracker |