diff options
Diffstat (limited to 'app/scripts/lib/account-tracker.js')
-rw-r--r-- | app/scripts/lib/account-tracker.js | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/app/scripts/lib/account-tracker.js b/app/scripts/lib/account-tracker.js index 2e9340018..24c5ef7ee 100644 --- a/app/scripts/lib/account-tracker.js +++ b/app/scripts/lib/account-tracker.js @@ -11,6 +11,12 @@ const EthQuery = require('eth-query') const ObservableStore = require('obs-store') const log = require('loglevel') const pify = require('pify') +const Web3 = require('web3') +const SINGLE_CALL_BALANCES_ABI = require('single-call-balance-checker-abi') + +const { bnToHex } = require('./util') +const { MAINNET_CODE, RINKEYBY_CODE, ROPSTEN_CODE, KOVAN_CODE } = require('../controllers/network/enums') +const { SINGLE_CALL_BALANCES_ADDRESS, SINGLE_CALL_BALANCES_ADDRESS_RINKEBY, SINGLE_CALL_BALANCES_ADDRESS_ROPSTEN, SINGLE_CALL_BALANCES_ADDRESS_KOVAN } = require('../controllers/network/contract-addresses') class AccountTracker { @@ -50,6 +56,9 @@ class AccountTracker { }) // bind function for easier listener syntax this._updateForBlock = this._updateForBlock.bind(this) + this.network = opts.network + + this.web3 = new Web3(this._provider) } start () { @@ -116,7 +125,7 @@ class AccountTracker { this.store.updateState({ accounts }) // fetch balances for the accounts if there is block number ready if (!this._currentBlockNumber) return - addresses.forEach(address => this._updateAccount(address)) + this._updateAccounts() } /** @@ -161,7 +170,8 @@ class AccountTracker { } /** - * Calls this._updateAccount for each account in this.store + * balanceChecker is deployed on main eth (test)nets and requires a single call + * for all other networks, calls this._updateAccount for each account in this.store * * @returns {Promise} after all account balances updated * @@ -169,7 +179,28 @@ class AccountTracker { async _updateAccounts () { const accounts = this.store.getState().accounts const addresses = Object.keys(accounts) - await Promise.all(addresses.map(this._updateAccount.bind(this))) + const currentNetwork = parseInt(this.network.getNetworkState()) + + switch (currentNetwork) { + case MAINNET_CODE: + await this._updateAccountsViaBalanceChecker(addresses, SINGLE_CALL_BALANCES_ADDRESS) + break + + case RINKEYBY_CODE: + await this._updateAccountsViaBalanceChecker(addresses, SINGLE_CALL_BALANCES_ADDRESS_RINKEBY) + break + + case ROPSTEN_CODE: + await this._updateAccountsViaBalanceChecker(addresses, SINGLE_CALL_BALANCES_ADDRESS_ROPSTEN) + break + + case KOVAN_CODE: + await this._updateAccountsViaBalanceChecker(addresses, SINGLE_CALL_BALANCES_ADDRESS_KOVAN) + break + + default: + await Promise.all(addresses.map(this._updateAccount.bind(this))) + } } /** @@ -192,6 +223,30 @@ class AccountTracker { this.store.updateState({ accounts }) } + /** + * Updates current address balances from balanceChecker deployed contract instance + * @param {*} addresses + * @param {*} deployedContractAddress + */ + async _updateAccountsViaBalanceChecker (addresses, deployedContractAddress) { + const accounts = this.store.getState().accounts + this.web3.setProvider(this._provider) + const ethContract = this.web3.eth.contract(SINGLE_CALL_BALANCES_ABI).at(deployedContractAddress) + const ethBalance = ['0x0'] + + ethContract.balances(addresses, ethBalance, (error, result) => { + if (error) { + log.warn(`MetaMask - Account Tracker single call balance fetch failed`, error) + return Promise.all(addresses.map(this._updateAccount.bind(this))) + } + addresses.forEach((address, index) => { + const balance = bnToHex(result[index]) + accounts[address] = { address, balance } + }) + this.store.updateState({ accounts }) + }) + } + } module.exports = AccountTracker |