aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CHANGELOG.md3
-rw-r--r--app/manifest.json1
-rw-r--r--app/scripts/background.js35
-rw-r--r--app/scripts/lib/local-store.js38
-rw-r--r--package.json1
6 files changed, 75 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index 5f2d2f551..2bf38cad4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
npm-debug.log
node_modules
+yarn.lock
app/bower_components
test/bower_components
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 80bef88b1..e7d4a09fe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
## Current Master
+- Add ability for internationalization.
- Will now throw an error if the `to` field in txParams is not valid.
- Will strip null values from the `to` field.
- Fix flashing to Log in screen after logging in or restoring from seed phrase.
@@ -10,7 +11,7 @@
- Add a welcome screen to new-ui onboarding flow
- Make new-ui create password screen responsive
- Hide network dropdown before account is initialized
-- Add ability for internationalization.
+- Fix bug that could prevent MetaMask from saving the latest vault.
## 4.2.0 Tue Mar 06 2018
diff --git a/app/manifest.json b/app/manifest.json
index 6c5ed686b..6fcf6cd7c 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..ef5513ec7 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)
@@ -64,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
}
@@ -102,16 +117,30 @@ function setupController (initState) {
// setup state persistence
pump(
asStream(controller.store),
+ debounce(1000),
storeTransform(versionifyData),
- asStream(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
//
diff --git a/app/scripts/lib/local-store.js b/app/scripts/lib/local-store.js
new file mode 100644
index 000000000..781aea17e
--- /dev/null
+++ b/app/scripts/lib/local-store.js
@@ -0,0 +1,38 @@
+// 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')
+const { promisify } = require('util').promisify
+
+module.exports = class ExtensionStore {
+ constructor() {
+ this.isSupported = !!(extension.storage.local)
+ if (!this.isSupported) {
+ log.error('Storage local API not available.')
+ }
+ const local = extension.storage.local
+ this._get = promisify(local.get).bind(local)
+ this._set = promisify(local.set).bind(local)
+ }
+
+ async get() {
+ if (!this.isSupported) return undefined
+ const result = await this._get()
+ // extension.storage.local always returns an obj
+ // if the object is empty, treat it as undefined
+ if (isEmpty(result)) {
+ return undefined
+ } else {
+ return result
+ }
+ }
+
+ async set(state) {
+ return this._set(state)
+ }
+}
+
+function isEmpty(obj) {
+ return Object.keys(obj).length === 0
+}
diff --git a/package.json b/package.json
index a80b7e28e..00587ece6 100644
--- a/package.json
+++ b/package.json
@@ -72,6 +72,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",