diff options
Diffstat (limited to 'app/scripts/background.js')
-rw-r--r-- | app/scripts/background.js | 80 |
1 files changed, 73 insertions, 7 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js index 3e560d302..ef5513ec7 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -1,10 +1,13 @@ const urlUtil = require('url') const endOfStream = require('end-of-stream') -const pipe = require('pump') +const pump = require('pump') +const debounce = require('debounce-stream') const log = require('loglevel') const extension = require('extensionizer') const LocalStorageStore = require('obs-store/lib/localStorage') +const LocalStore = require('./lib/local-store') const storeTransform = require('obs-store/lib/transform') +const asStream = require('obs-store/lib/asStream') const ExtensionPlatform = require('./platforms/extension') const Migrator = require('./lib/migrator/') const migrations = require('./migrations/') @@ -12,6 +15,11 @@ const PortStream = require('./lib/port-stream.js') const NotificationManager = require('./lib/notification-manager.js') const MetamaskController = require('./metamask-controller') const firstTimeState = require('./first-time-state') +const setupRaven = require('./lib/setupRaven') +const reportFailedTxToSentry = require('./lib/reportFailedTxToSentry') +const setupMetamaskMeshMetrics = require('./lib/setupMetamaskMeshMetrics') +const EdgeEncryptor = require('./edge-encryptor') + const STORAGE_KEY = 'metamask-config' const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' @@ -23,14 +31,30 @@ const platform = new ExtensionPlatform() const notificationManager = new NotificationManager() global.METAMASK_NOTIFIER = notificationManager +// setup sentry error reporting +const release = platform.getVersion() +const raven = setupRaven({ release }) + +// browser check if it is Edge - https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser +// Internet Explorer 6-11 +const isIE = !!document.documentMode +// Edge 20+ +const isEdge = !isIE && !!window.StyleMedia + let popupIsOpen = false +let openMetamaskTabsIDs = {} // state persistence const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY }) +const localStore = new LocalStore() +let versionedData // initialization flow initialize().catch(log.error) +// setup metamask mesh testing container +setupMetamaskMeshMetrics() + async function initialize () { const initState = await loadStateFromPersistence() await setupController(initState) @@ -44,12 +68,23 @@ async function initialize () { async function loadStateFromPersistence () { // migrations const migrator = new Migrator({ migrations }) + // read from disk - let versionedData = diskStore.getState() || migrator.generateInitialState(firstTimeState) + // first from preferred, async API: + versionedData = (await localStore.get()) || + diskStore.getState() || + migrator.generateInitialState(firstTimeState) + // migrate data versionedData = await migrator.migrateData(versionedData) + if (!versionedData) { + throw new Error('MetaMask - migrator returned undefined') + } + // write to disk + if (localStore.isSupported) localStore.set(versionedData) diskStore.putState(versionedData) + // return just the data return versionedData.data } @@ -68,22 +103,44 @@ function setupController (initState) { initState, // platform specific api platform, + encryptor: isEdge ? new EdgeEncryptor() : undefined, }) global.metamaskController = controller + // report failed transactions to Sentry + controller.txController.on(`tx:status-update`, (txId, status) => { + if (status !== 'failed') return + const txMeta = controller.txController.txStateManager.getTx(txId) + reportFailedTxToSentry({ raven, txMeta }) + }) + // setup state persistence - pipe( - controller.store, + pump( + asStream(controller.store), + debounce(1000), storeTransform(versionifyData), - diskStore + storeTransform(syncDataWithExtension), + asStream(diskStore), + (error) => { + log.error('pump hit error', error) + } ) function versionifyData (state) { - const versionedData = diskStore.getState() versionedData.data = state return versionedData } + function syncDataWithExtension(state) { + if (localStore.isSupported) { + localStore.set(state) + .catch((err) => { + log.error('error setting state in local store:', err) + }) + } + return state + } + // // connect to other contexts // @@ -97,9 +154,15 @@ function setupController (initState) { popupIsOpen = popupIsOpen || (remotePort.name === 'popup') controller.setupTrustedCommunication(portStream, 'MetaMask') // record popup as closed + if (remotePort.sender.url.match(/home.html$/)) { + openMetamaskTabsIDs[remotePort.sender.tab.id] = true + } if (remotePort.name === 'popup') { endOfStream(portStream, () => { popupIsOpen = false + if (remotePort.sender.url.match(/home.html$/)) { + openMetamaskTabsIDs[remotePort.sender.tab.id] = false + } }) } } else { @@ -142,7 +205,10 @@ function setupController (initState) { // popup trigger function triggerUi () { - if (!popupIsOpen) notificationManager.showPopup() + extension.tabs.query({ active: true }, (tabs) => { + const currentlyActiveMetamaskTab = tabs.find(tab => openMetamaskTabsIDs[tab.id]) + if (!popupIsOpen && !currentlyActiveMetamaskTab) notificationManager.showPopup() + }) } // On first install, open a window to MetaMask website to how-it-works. |