diff options
Merge branch 'master' into retry-tx-refractor
Diffstat (limited to 'app/scripts')
-rw-r--r-- | app/scripts/background.js | 35 | ||||
-rw-r--r-- | app/scripts/lib/local-store.js | 38 | ||||
-rw-r--r-- | app/scripts/lib/tx-gas-utils.js | 6 |
3 files changed, 74 insertions, 5 deletions
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/app/scripts/lib/tx-gas-utils.js b/app/scripts/lib/tx-gas-utils.js index 6f6ff7852..0fa9dd8d4 100644 --- a/app/scripts/lib/tx-gas-utils.js +++ b/app/scripts/lib/tx-gas-utils.js @@ -4,7 +4,7 @@ const { BnMultiplyByFraction, bnToHex, } = require('./util') -const addHexPrefix = require('ethereumjs-util').addHexPrefix +const { addHexPrefix, isValidAddress } = require('ethereumjs-util') const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send. /* @@ -113,12 +113,14 @@ module.exports = class TxGasUtil { } } validateRecipient (txParams) { - if (txParams.to === '0x') { + if (txParams.to === '0x' || txParams.to === null ) { if (txParams.data) { delete txParams.to } else { throw new Error('Invalid recipient address') } + } else if ( txParams.to !== undefined && !isValidAddress(txParams.to) ) { + throw new Error('Invalid recipient address') } return txParams } |