diff options
author | brunobar79 <brunobar79@gmail.com> | 2018-11-14 06:21:15 +0800 |
---|---|---|
committer | brunobar79 <brunobar79@gmail.com> | 2018-11-14 06:21:15 +0800 |
commit | 484aa6801ea50fb08253fd08559710c53e0c189d (patch) | |
tree | 2a7876d3800e57aafab39a6beebe00abf7fc26ba /app/scripts | |
parent | c651212025ab7cd0309d96be6687c1eba35ab9fa (diff) | |
parent | 0549782595335e8257d1b4abf7d6220020e2c8db (diff) | |
download | tangerine-wallet-browser-484aa6801ea50fb08253fd08559710c53e0c189d.tar tangerine-wallet-browser-484aa6801ea50fb08253fd08559710c53e0c189d.tar.gz tangerine-wallet-browser-484aa6801ea50fb08253fd08559710c53e0c189d.tar.bz2 tangerine-wallet-browser-484aa6801ea50fb08253fd08559710c53e0c189d.tar.lz tangerine-wallet-browser-484aa6801ea50fb08253fd08559710c53e0c189d.tar.xz tangerine-wallet-browser-484aa6801ea50fb08253fd08559710c53e0c189d.tar.zst tangerine-wallet-browser-484aa6801ea50fb08253fd08559710c53e0c189d.zip |
Merge branch 'develop' into trezor-v5
Diffstat (limited to 'app/scripts')
-rw-r--r-- | app/scripts/background.js | 1 | ||||
-rw-r--r-- | app/scripts/contentscript.js | 16 | ||||
-rw-r--r-- | app/scripts/controllers/provider-approval.js | 10 | ||||
-rw-r--r-- | app/scripts/controllers/token-rates.js | 38 | ||||
-rw-r--r-- | app/scripts/inpage.js | 101 | ||||
-rw-r--r-- | app/scripts/metamask-controller.js | 1 |
6 files changed, 80 insertions, 87 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js index 2dcb79bef..d577ead41 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -448,6 +448,7 @@ function triggerUi () { const currentlyActiveMetamaskTab = Boolean(tabs.find(tab => openMetamaskTabsIDs[tab.id])) if (!popupIsOpen && !currentlyActiveMetamaskTab && !notificationIsOpen) { notificationManager.showPopup() + notificationIsOpen = true } }) } diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index 1a10cdb34..ee38ee3ab 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -147,24 +147,28 @@ function listenForProviderRequest () { } }) - extension.runtime.onMessage.addListener(({ action = '', isApproved, caching, isUnlocked }) => { + extension.runtime.onMessage.addListener(({ action = '', isApproved, caching, isUnlocked, selectedAddress }) => { switch (action) { case 'approve-provider-request': isEnabled = true - injectScript(`window.dispatchEvent(new CustomEvent('ethereumprovider', { detail: {}}))`) + window.postMessage({ type: 'ethereumprovider', selectedAddress }, '*') + break + case 'approve-legacy-provider-request': + isEnabled = true + window.postMessage({ type: 'ethereumproviderlegacy', selectedAddress }, '*') break case 'reject-provider-request': - injectScript(`window.dispatchEvent(new CustomEvent('ethereumprovider', { detail: { error: 'User rejected provider access' }}))`) + window.postMessage({ type: 'ethereumprovider', error: 'User rejected provider access' }, '*') break case 'answer-is-approved': - injectScript(`window.dispatchEvent(new CustomEvent('ethereumisapproved', { detail: { isApproved: ${isApproved}, caching: ${caching}}}))`) + window.postMessage({ type: 'ethereumisapproved', isApproved, caching }, '*') break case 'answer-is-unlocked': - injectScript(`window.dispatchEvent(new CustomEvent('metamaskisunlocked', { detail: { isUnlocked: ${isUnlocked}}}))`) + window.postMessage({ type: 'metamaskisunlocked', isUnlocked }, '*') break case 'metamask-set-locked': isEnabled = false - injectScript(`window.dispatchEvent(new CustomEvent('metamasksetlocked', { detail: {}}))`) + window.postMessage({ type: 'metamasksetlocked' }, '*') break } }) diff --git a/app/scripts/controllers/provider-approval.js b/app/scripts/controllers/provider-approval.js index d3b7f6dff..21d7fd22e 100644 --- a/app/scripts/controllers/provider-approval.js +++ b/app/scripts/controllers/provider-approval.js @@ -88,7 +88,10 @@ class ProviderApprovalController { _handlePrivacyRequest () { const privacyMode = this.preferencesController.getFeatureFlags().privacyMode if (!privacyMode) { - this.platform && this.platform.sendMessage({ action: 'approve-provider-request' }, { active: true }) + this.platform && this.platform.sendMessage({ + action: 'approve-legacy-provider-request', + selectedAddress: this.publicConfigStore.getState().selectedAddress, + }, { active: true }) this.publicConfigStore.emit('update', this.publicConfigStore.getState()) } } @@ -101,7 +104,10 @@ class ProviderApprovalController { approveProviderRequest (origin) { this.closePopup && this.closePopup() const requests = this.store.getState().providerRequests || [] - this.platform && this.platform.sendMessage({ action: 'approve-provider-request' }, { active: true }) + this.platform && this.platform.sendMessage({ + action: 'approve-provider-request', + selectedAddress: this.publicConfigStore.getState().selectedAddress, + }, { active: true }) this.publicConfigStore.emit('update', this.publicConfigStore.getState()) const providerRequests = requests.filter(request => request.origin !== origin) this.store.updateState({ providerRequests }) diff --git a/app/scripts/controllers/token-rates.js b/app/scripts/controllers/token-rates.js index b6f084841..a8936f13b 100644 --- a/app/scripts/controllers/token-rates.js +++ b/app/scripts/controllers/token-rates.js @@ -14,8 +14,9 @@ class TokenRatesController { * * @param {Object} [config] - Options to configure controller */ - constructor ({ interval = DEFAULT_INTERVAL, preferences } = {}) { + constructor ({ interval = DEFAULT_INTERVAL, currency, preferences } = {}) { this.store = new ObservableStore() + this.currency = currency this.preferences = preferences this.interval = interval } @@ -26,33 +27,24 @@ class TokenRatesController { async updateExchangeRates () { if (!this.isActive) { return } const contractExchangeRates = {} - // copy array to ensure its not modified during iteration - const tokens = this._tokens.slice() - for (const token of tokens) { - if (!token) return log.error(`TokenRatesController - invalid tokens state:\n${JSON.stringify(tokens, null, 2)}`) - const address = token.address - contractExchangeRates[address] = await this.fetchExchangeRate(address) + const nativeCurrency = this.currency ? this.currency.getState().nativeCurrency.toUpperCase() : 'ETH' + const pairs = this._tokens.map(token => `pairs[]=${token.address}/${nativeCurrency}`) + const query = pairs.join('&') + if (this._tokens.length > 0) { + try { + const response = await fetch(`https://exchanges.balanc3.net/pie?${query}&autoConversion=true`) + const { prices = [] } = await response.json() + prices.forEach(({ pair, price }) => { + contractExchangeRates[pair.split('/')[0]] = typeof price === 'number' ? price : 0 + }) + } catch (error) { + log.warn(`MetaMask - TokenRatesController exchange rate fetch failed.`, error) + } } this.store.putState({ contractExchangeRates }) } /** - * Fetches a token exchange rate by address - * - * @param {String} address - Token contract address - */ - async fetchExchangeRate (address) { - try { - const response = await fetch(`https://metamask.balanc3.net/prices?from=${address}&to=ETH&autoConversion=false&summaryOnly=true`) - const json = await response.json() - return json && json.length ? json[0].averagePrice : 0 - } catch (error) { - log.warn(`MetaMask - TokenRatesController exchange rate fetch failed for ${address}.`, error) - return 0 - } - } - - /** * @type {Number} */ set interval (interval) { diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js index 327e25042..83392761e 100644 --- a/app/scripts/inpage.js +++ b/app/scripts/inpage.js @@ -22,6 +22,21 @@ console.warn('ATTENTION: In an effort to improve user privacy, MetaMask ' + 'accounts. Please see https://bit.ly/2QQHXvF for complete information and up-to-date ' + 'example code.') +/** + * Adds a postMessage listener for a specific message type + * + * @param {string} messageType - postMessage type to listen for + * @param {Function} handler - event handler + * @param {boolean} remove - removes this handler after being triggered + */ +function onMessage(messageType, handler, remove) { + window.addEventListener('message', function ({ data }) { + if (!data || data.type !== messageType) { return } + remove && window.removeEventListener('message', handler) + handler.apply(window, arguments) + }) +} + // // setup plugin communication // @@ -39,52 +54,36 @@ var inpageProvider = new MetamaskInpageProvider(metamaskStream) inpageProvider.setMaxListeners(100) // set up a listener for when MetaMask is locked -window.addEventListener('metamasksetlocked', () => { - isEnabled = false -}) +onMessage('metamasksetlocked', () => { isEnabled = false }) + +// set up a listener for privacy mode responses +onMessage('ethereumproviderlegacy', ({ data: { selectedAddress } }) => { + isEnabled = true + inpageProvider.publicConfigStore.updateState({ selectedAddress }) +}, true) // augment the provider with its enable method inpageProvider.enable = function ({ force } = {}) { return new Promise((resolve, reject) => { - window.removeEventListener('ethereumprovider', providerHandle) - providerHandle = ({ detail }) => { - if (typeof detail.error !== 'undefined') { - reject(detail.error) + providerHandle = ({ data: { error, selectedAddress } }) => { + if (typeof error !== 'undefined') { + reject(error) } else { - // wait for the publicConfig store to populate with an account - const publicConfig = new Promise((resolve) => { - const { selectedAddress } = inpageProvider.publicConfigStore.getState() - inpageProvider._metamask.isUnlocked().then(unlocked => { - if (!unlocked || selectedAddress) { - resolve() - } else { - inpageProvider.publicConfigStore.on('update', ({ selectedAddress }) => { - selectedAddress && resolve() - }) - } - }) - }) + window.removeEventListener('message', providerHandle) + inpageProvider.publicConfigStore.updateState({ selectedAddress }) // wait for the background to update with an account - const ethAccounts = new Promise((resolveAccounts, rejectAccounts) => { - inpageProvider.sendAsync({ method: 'eth_accounts', params: [] }, (error, response) => { - if (error) { - rejectAccounts(error) - } else { - resolveAccounts(response.result) - } - }) - }) - - Promise.all([ethAccounts, publicConfig]) - .then(([selectedAddress]) => { + inpageProvider.sendAsync({ method: 'eth_accounts', params: [] }, (error, response) => { + if (error) { + reject(error) + } else { isEnabled = true - resolve(selectedAddress) - }) - .catch(reject) + resolve(response.result) + } + }) } } - window.addEventListener('ethereumprovider', providerHandle) + onMessage('ethereumprovider', providerHandle, true) window.postMessage({ type: 'ETHEREUM_ENABLE_PROVIDER', force }, '*') }) } @@ -106,20 +105,15 @@ inpageProvider._metamask = new Proxy({ * @returns {Promise<boolean>} - Promise resolving to true if this domain has been previously approved */ isApproved: function() { - return new Promise((resolve, reject) => { - window.removeEventListener('ethereumisapproved', isApprovedHandle) - isApprovedHandle = ({ detail }) => { - if (typeof detail.error !== 'undefined') { - reject(detail.error) + return new Promise((resolve) => { + isApprovedHandle = ({ data: { caching, isApproved } }) => { + if (caching) { + resolve(!!isApproved) } else { - if (detail.caching) { - resolve(!!detail.isApproved) - } else { - resolve(false) - } + resolve(false) } } - window.addEventListener('ethereumisapproved', isApprovedHandle) + onMessage('ethereumisapproved', isApprovedHandle, true) window.postMessage({ type: 'ETHEREUM_IS_APPROVED' }, '*') }) }, @@ -130,16 +124,11 @@ inpageProvider._metamask = new Proxy({ * @returns {Promise<boolean>} - Promise resolving to true if MetaMask is currently unlocked */ isUnlocked: function () { - return new Promise((resolve, reject) => { - window.removeEventListener('metamaskisunlocked', isUnlockedHandle) - isUnlockedHandle = ({ detail }) => { - if (typeof detail.error !== 'undefined') { - reject(detail.error) - } else { - resolve(!!detail.isUnlocked) - } + return new Promise((resolve) => { + isUnlockedHandle = ({ data: { isUnlocked } }) => { + resolve(!!isUnlocked) } - window.addEventListener('metamaskisunlocked', isUnlockedHandle) + onMessage('metamaskisunlocked', isUnlockedHandle, true) window.postMessage({ type: 'METAMASK_IS_UNLOCKED' }, '*') }) }, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 5ae0f608d..641a7ef3f 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -117,6 +117,7 @@ module.exports = class MetamaskController extends EventEmitter { // token exchange rate tracker this.tokenRatesController = new TokenRatesController({ + currency: this.currencyController.store, preferences: this.preferencesController.store, }) |