|
|
|
@ -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 |
|
|
|
|