diff options
author | Chi Kei Chan <chikeichan@gmail.com> | 2017-09-28 13:54:21 +0800 |
---|---|---|
committer | Chi Kei Chan <chikeichan@gmail.com> | 2017-09-28 13:54:21 +0800 |
commit | e711a4193f34b532c78526d68a32baff93eb061d (patch) | |
tree | fe76102102c875ee6eaaee8cb57829899936c519 /app/scripts/lib/account-tracker.js | |
parent | deee689426f0b6236093128b47be81faf56d6b75 (diff) | |
parent | 5a1d50cd431819874f634679a1ea47fa64f9fbb4 (diff) | |
download | tangerine-wallet-browser-e711a4193f34b532c78526d68a32baff93eb061d.tar tangerine-wallet-browser-e711a4193f34b532c78526d68a32baff93eb061d.tar.gz tangerine-wallet-browser-e711a4193f34b532c78526d68a32baff93eb061d.tar.bz2 tangerine-wallet-browser-e711a4193f34b532c78526d68a32baff93eb061d.tar.lz tangerine-wallet-browser-e711a4193f34b532c78526d68a32baff93eb061d.tar.xz tangerine-wallet-browser-e711a4193f34b532c78526d68a32baff93eb061d.tar.zst tangerine-wallet-browser-e711a4193f34b532c78526d68a32baff93eb061d.zip |
Merge branch 'mmn' into merge
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..cdc21282d --- /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) { + this._currentBlockNumber = block.number + const currentBlockGasLimit = block.gasLimit + + this.store.updateState({ currentBlockGasLimit }) + + 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 |