aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/lib/account-tracker.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/scripts/lib/account-tracker.js')
-rw-r--r--app/scripts/lib/account-tracker.js61
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