aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/lib
diff options
context:
space:
mode:
Diffstat (limited to 'app/scripts/lib')
-rw-r--r--app/scripts/lib/ComposableObservableStore.js4
-rw-r--r--app/scripts/lib/account-tracker.js61
-rw-r--r--app/scripts/lib/auto-reload.js4
-rw-r--r--app/scripts/lib/buy-eth-url.js4
-rw-r--r--app/scripts/lib/ens-ipfs/resolver.js2
-rw-r--r--app/scripts/lib/ens-ipfs/setup.js6
-rw-r--r--app/scripts/lib/get-first-preferred-lang-code.js15
-rw-r--r--app/scripts/lib/notification-manager.js14
-rw-r--r--app/scripts/lib/setupFetchDebugging.js8
-rw-r--r--app/scripts/lib/setupSentry.js2
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)