diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | app/manifest.json | 1 | ||||
-rw-r--r-- | app/scripts/background.js | 46 | ||||
-rw-r--r-- | app/scripts/lib/local-store.js | 24 | ||||
-rw-r--r-- | package.json | 1 |
5 files changed, 69 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index fdc7d7155..b02625deb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Current Master +- Fix bug that could cause MetaMask to lose all of its local data. - Allow adding custom tokens to classic ui when balance is 0 - Allow editing of symbol and decimal info when adding custom token in new-ui - NewUI shapeshift form can select all coins (not just BTC) diff --git a/app/manifest.json b/app/manifest.json index 2b3acf1b5..e53e87cdb 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -56,6 +56,7 @@ ], "permissions": [ "storage", + "unlimitedStorage", "clipboardWrite", "http://localhost:8545/", "https://*.infura.io/" diff --git a/app/scripts/background.js b/app/scripts/background.js index 601ae0372..464330708 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -1,9 +1,11 @@ const urlUtil = require('url') const endOfStream = require('end-of-stream') 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') @@ -44,6 +46,8 @@ let openMetamaskTabsIDs = {} // state persistence const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY }) +const localStore = new LocalStore() +let versionedData // initialization flow initialize().catch(log.error) @@ -65,11 +69,31 @@ async function loadStateFromPersistence () { // migrations const migrator = new Migrator({ migrations }) // read from disk - let versionedData = diskStore.getState() || migrator.generateInitialState(firstTimeState) + versionedData = diskStore.getState() || migrator.generateInitialState(firstTimeState) + // fetch from extension store and merge in data + + if (localStore.isSupported) { + let localData + try { + localData = await localStore.get() + } catch (err) { + log.error('error fetching state from local store:', err) + } + + if (Object.keys(localData).length > 0) { + versionedData = localData + } + } + // migrate data versionedData = await migrator.migrateData(versionedData) + // write to disk - diskStore.putState(versionedData) + localStore.set(versionedData) + .catch((reason) => { + log.error('Problem saving migrated data', versionedData) + }) + // return just the data return versionedData.data } @@ -102,16 +126,30 @@ function setupController (initState) { // setup state persistence pump( asStream(controller.store), + debounce(1000), storeTransform(versionifyData), - asStream(diskStore) + storeTransform(syncDataWithExtension), + (error) => { + log.error('pump hit error', error) + } ) function versionifyData (state) { - const versionedData = diskStore.getState() versionedData.data = state return versionedData } + async function syncDataWithExtension(state) { + if (localStore.isSupported) { + try { + await localStore.set(state) + } catch (err) { + log.error('error setting state in local store:', err) + } + } else { log.error('local store not supported') } + return state + } + // // connect to other contexts // diff --git a/app/scripts/lib/local-store.js b/app/scripts/lib/local-store.js new file mode 100644 index 000000000..9e8d8db37 --- /dev/null +++ b/app/scripts/lib/local-store.js @@ -0,0 +1,24 @@ +// We should not rely on local storage in an extension! +// We should use this instead! +// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/local + +const extension = require('extensionizer') + +module.exports = class ExtensionStore { + constructor() { + this.isSupported = !!(extension.storage.local) + if (!this.isSupported) { + log.error('Storage local API not available.') + } + } + get() { + return new Promise((resolve) => { + extension.storage.local.get(null, resolve) + }) + } + set(state) { + return new Promise((resolve) => { + extension.storage.local.set(state, resolve) + }) + } +} diff --git a/package.json b/package.json index 80949901a..e0b88e787 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "clone": "^2.1.1", "copy-to-clipboard": "^3.0.8", "debounce": "^1.0.0", + "debounce-stream": "^2.0.0", "deep-extend": "^0.5.0", "detect-node": "^2.0.3", "disc": "^1.3.2", |