diff options
Diffstat (limited to 'app/scripts/lib')
-rw-r--r-- | app/scripts/lib/ComposableObservableStore.js | 4 | ||||
-rw-r--r-- | app/scripts/lib/account-tracker.js | 61 | ||||
-rw-r--r-- | app/scripts/lib/auto-reload.js | 4 | ||||
-rw-r--r-- | app/scripts/lib/buy-eth-url.js | 4 | ||||
-rw-r--r-- | app/scripts/lib/ens-ipfs/resolver.js | 2 | ||||
-rw-r--r-- | app/scripts/lib/ens-ipfs/setup.js | 6 | ||||
-rw-r--r-- | app/scripts/lib/get-first-preferred-lang-code.js | 15 | ||||
-rw-r--r-- | app/scripts/lib/notification-manager.js | 14 | ||||
-rw-r--r-- | app/scripts/lib/setupFetchDebugging.js | 8 | ||||
-rw-r--r-- | app/scripts/lib/setupSentry.js | 2 |
10 files changed, 97 insertions, 23 deletions
diff --git a/app/scripts/lib/ComposableObservableStore.js b/app/scripts/lib/ComposableObservableStore.js index d5ee708a1..abb779672 100644 --- a/app/scripts/lib/ComposableObservableStore.js +++ b/app/scripts/lib/ComposableObservableStore.js @@ -40,7 +40,9 @@ class ComposableObservableStore extends ObservableStore { getFlatState () { let flatState = {} for (const key in this.config) { - flatState = { ...flatState, ...this.config[key].getState() } + const controller = this.config[key] + const state = controller.getState ? controller.getState() : controller.state + flatState = { ...flatState, ...state } } return flatState } 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 diff --git a/app/scripts/lib/auto-reload.js b/app/scripts/lib/auto-reload.js index 558391a06..44fbe847c 100644 --- a/app/scripts/lib/auto-reload.js +++ b/app/scripts/lib/auto-reload.js @@ -20,6 +20,10 @@ function setupDappAutoReload (web3, observable) { }) observable.subscribe(function (state) { + // if the auto refresh on network change is false do not + // do anything + if (!window.ethereum.autoRefreshOnNetworkChange) return + // if reload in progress, no need to check reload logic if (reloadInProgress) return diff --git a/app/scripts/lib/buy-eth-url.js b/app/scripts/lib/buy-eth-url.js index 46710a16f..d9d5155c2 100644 --- a/app/scripts/lib/buy-eth-url.js +++ b/app/scripts/lib/buy-eth-url.js @@ -16,6 +16,8 @@ function getBuyEthUrl({ network, amount, address, service }) { if (!service) service = getDefaultServiceForNetwork(network) switch (service) { + case 'wyre': + return `https://dash.sendwyre.com/sign-up` case 'coinswitch': return `https://metamask.coinswitch.co/?address=${address}&to=eth` case 'coinbase': @@ -33,7 +35,7 @@ function getBuyEthUrl({ network, amount, address, service }) { function getDefaultServiceForNetwork (networkId) { switch (network) { case '1': - return 'coinbase' + return 'wyre' case '3': return 'metamask-faucet' case '4': diff --git a/app/scripts/lib/ens-ipfs/resolver.js b/app/scripts/lib/ens-ipfs/resolver.js index fe2dc1134..b98566190 100644 --- a/app/scripts/lib/ens-ipfs/resolver.js +++ b/app/scripts/lib/ens-ipfs/resolver.js @@ -38,7 +38,7 @@ async function resolveEnsToIpfsContentId ({ provider, name }) { return contentId } -function hexValueIsEmpty(value) { +function hexValueIsEmpty (value) { return [undefined, null, '0x', '0x0', '0x0000000000000000000000000000000000000000000000000000000000000000'].includes(value) } diff --git a/app/scripts/lib/ens-ipfs/setup.js b/app/scripts/lib/ens-ipfs/setup.js index 45eb1ce14..df756d0f7 100644 --- a/app/scripts/lib/ens-ipfs/setup.js +++ b/app/scripts/lib/ens-ipfs/setup.js @@ -6,7 +6,7 @@ const supportedTopLevelDomains = ['eth'] module.exports = setupEnsIpfsResolver -function setupEnsIpfsResolver({ provider }) { +function setupEnsIpfsResolver ({ provider }) { // install listener const urlPatterns = supportedTopLevelDomains.map(tld => `*://*.${tld}/*`) @@ -35,11 +35,11 @@ function setupEnsIpfsResolver({ provider }) { attemptResolve({ tabId, name, path, search }) } - async function attemptResolve({ tabId, name, path, search }) { + async function attemptResolve ({ tabId, name, path, search }) { extension.tabs.update(tabId, { url: `loading.html` }) try { const ipfsContentId = await resolveEnsToIpfsContentId({ provider, name }) - let url = `https://gateway.ipfs.io/ipfs/${ipfsContentId}${path}${search || ''}` + const url = `https://gateway.ipfs.io/ipfs/${ipfsContentId}${path}${search || ''}` try { // check if ipfs gateway has result const response = await fetch(url, { method: 'HEAD' }) diff --git a/app/scripts/lib/get-first-preferred-lang-code.js b/app/scripts/lib/get-first-preferred-lang-code.js index 170d508c1..469235357 100644 --- a/app/scripts/lib/get-first-preferred-lang-code.js +++ b/app/scripts/lib/get-first-preferred-lang-code.js @@ -7,7 +7,13 @@ const getPreferredLocales = extension.i18n ? promisify( { errorFirst: false } ) : async () => [] -const existingLocaleCodes = allLocales.map(locale => locale.code.toLowerCase().replace('_', '-')) +// mapping some browsers return hyphen instead underscore in locale codes (e.g. zh_TW -> zh-tw) +const existingLocaleCodes = {} +allLocales.forEach(locale => { + if (locale && locale.code) { + existingLocaleCodes[locale.code.toLowerCase().replace('_', '-')] = locale.code + } +}) /** * Returns a preferred language code, based on settings within the user's browser. If we have no translations for the @@ -33,9 +39,10 @@ async function getFirstPreferredLangCode () { } const firstPreferredLangCode = userPreferredLocaleCodes - .map(code => code.toLowerCase()) - .find(code => existingLocaleCodes.includes(code)) - return firstPreferredLangCode || 'en' + .map(code => code.toLowerCase().replace('_', '-')) + .find(code => existingLocaleCodes.hasOwnProperty(code)) + + return existingLocaleCodes[firstPreferredLangCode] || 'en' } module.exports = getFirstPreferredLangCode diff --git a/app/scripts/lib/notification-manager.js b/app/scripts/lib/notification-manager.js index 969a9459a..721d109a1 100644 --- a/app/scripts/lib/notification-manager.js +++ b/app/scripts/lib/notification-manager.js @@ -1,7 +1,6 @@ const extension = require('extensionizer') -const height = 620 -const width = 360 - +const NOTIFICATION_HEIGHT = 620 +const NOTIFICATION_WIDTH = 360 class NotificationManager { @@ -26,13 +25,18 @@ class NotificationManager { // bring focus to existing chrome popup extension.windows.update(popup.id, { focused: true }) } else { + const {screenX, screenY, outerWidth, outerHeight} = window + const notificationTop = Math.round(screenY + (outerHeight / 2) - (NOTIFICATION_HEIGHT / 2)) + const notificationLeft = Math.round(screenX + (outerWidth / 2) - (NOTIFICATION_WIDTH / 2)) const cb = (currentPopup) => { this._popupId = currentPopup.id } // create new notification popup const creation = extension.windows.create({ url: 'notification.html', type: 'popup', - width, - height, + width: NOTIFICATION_WIDTH, + height: NOTIFICATION_HEIGHT, + top: Math.max(notificationTop, 0), + left: Math.max(notificationLeft, 0), }, cb) creation && creation.then && creation.then(cb) } diff --git a/app/scripts/lib/setupFetchDebugging.js b/app/scripts/lib/setupFetchDebugging.js index c1ef22d21..431340e2b 100644 --- a/app/scripts/lib/setupFetchDebugging.js +++ b/app/scripts/lib/setupFetchDebugging.js @@ -6,13 +6,13 @@ module.exports = setupFetchDebugging // https://github.com/getsentry/sentry-javascript/pull/1293 // -function setupFetchDebugging() { +function setupFetchDebugging () { if (!global.fetch) return const originalFetch = global.fetch global.fetch = wrappedFetch - async function wrappedFetch(...args) { + async function wrappedFetch (...args) { const initialStack = getCurrentStack() try { return await originalFetch.call(window, ...args) @@ -20,14 +20,14 @@ function setupFetchDebugging() { if (!err.stack) { console.warn('FetchDebugger - fetch encountered an Error without a stack', err) console.warn('FetchDebugger - overriding stack to point of original call') - err.stack = initialStack + err.stack = initialStack } throw err } } } -function getCurrentStack() { +function getCurrentStack () { try { throw new Error('Fake error for generating stack trace') } catch (err) { diff --git a/app/scripts/lib/setupSentry.js b/app/scripts/lib/setupSentry.js index 69042bc19..ba0e17df0 100644 --- a/app/scripts/lib/setupSentry.js +++ b/app/scripts/lib/setupSentry.js @@ -32,7 +32,7 @@ function setupSentry (opts) { scope.setExtra('isBrave', isBrave) }) - function rewriteReport(report) { + function rewriteReport (report) { try { // simplify certain complex error messages (e.g. Ethjs) simplifyErrorMessages(report) |