aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/background.js
diff options
context:
space:
mode:
authorkumavis <aaron@kumavis.me>2017-01-12 17:17:05 +0800
committerkumavis <aaron@kumavis.me>2017-01-12 17:17:05 +0800
commitb33c51c0a6c7c8a7b0c0a9a6ca101f874f2db3d1 (patch)
tree7707ff23ae225ee2dd4eef17bfd67c688a817b43 /app/scripts/background.js
parent3bc996878b467e1fa5fd63656bd465377daa137d (diff)
downloadtangerine-wallet-browser-b33c51c0a6c7c8a7b0c0a9a6ca101f874f2db3d1.tar
tangerine-wallet-browser-b33c51c0a6c7c8a7b0c0a9a6ca101f874f2db3d1.tar.gz
tangerine-wallet-browser-b33c51c0a6c7c8a7b0c0a9a6ca101f874f2db3d1.tar.bz2
tangerine-wallet-browser-b33c51c0a6c7c8a7b0c0a9a6ca101f874f2db3d1.tar.lz
tangerine-wallet-browser-b33c51c0a6c7c8a7b0c0a9a6ca101f874f2db3d1.tar.xz
tangerine-wallet-browser-b33c51c0a6c7c8a7b0c0a9a6ca101f874f2db3d1.tar.zst
tangerine-wallet-browser-b33c51c0a6c7c8a7b0c0a9a6ca101f874f2db3d1.zip
migrations - introduce promise-based migrator
Diffstat (limited to 'app/scripts/background.js')
-rw-r--r--app/scripts/background.js212
1 files changed, 120 insertions, 92 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 8aa886594..697417fd2 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -1,7 +1,8 @@
const urlUtil = require('url')
const Dnode = require('dnode')
const eos = require('end-of-stream')
-const Migrator = require('pojo-migrator')
+const asyncQ = require('async-q')
+const Migrator = require('./lib/migrator/')
const migrations = require('./lib/migrations')
const LocalStorageStore = require('./lib/observable/local-storage')
const PortStream = require('./lib/port-stream.js')
@@ -16,101 +17,143 @@ const STORAGE_KEY = 'metamask-config'
const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
let popupIsOpen = false
+// state persistence
+const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
+
+// initialization flow
+asyncQ.waterfall([
+ () => loadStateFromPersistence(),
+ (initState) => setupController(initState),
+])
+.then(() => console.log('MetaMask initialization complete.'))
+.catch((err) => { console.error(err) })
//
// State and Persistence
//
-// state persistence
-
-let dataStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
-// initial state for first time users
-if (!dataStore.get()) {
- dataStore.put({ meta: { version: 0 }, data: firstTimeState })
+function loadStateFromPersistence() {
+ // migrations
+ let migrator = new Migrator({ migrations })
+ let initialState = {
+ meta: { version: migrator.defaultVersion },
+ data: firstTimeState,
+ }
+ return asyncQ.waterfall([
+ // read from disk
+ () => Promise.resolve(diskStore.get() || initialState),
+ // migrate data
+ (versionedData) => migrator.migrateData(versionedData),
+ // write to disk
+ (versionedData) => {
+ diskStore.put(versionedData)
+ return Promise.resolve(versionedData)
+ },
+ // resolve to just data
+ (versionedData) => Promise.resolve(versionedData.data),
+ ])
}
-// migrations
+function setupController (initState) {
-let migrator = new Migrator({
- migrations,
- // Data persistence methods
- loadData: () => dataStore.get(),
- setData: (newState) => dataStore.put(newState),
-})
+ //
+ // MetaMask Controller
+ //
-//
-// MetaMask Controller
-//
+ const controller = new MetamaskController({
+ // User confirmation callbacks:
+ showUnconfirmedMessage: triggerUi,
+ unlockAccountMessage: triggerUi,
+ showUnapprovedTx: triggerUi,
+ // initial state
+ initState,
+ })
-const controller = new MetamaskController({
- // User confirmation callbacks:
- showUnconfirmedMessage: triggerUi,
- unlockAccountMessage: triggerUi,
- showUnapprovedTx: triggerUi,
- // initial state
- initState: migrator.getData(),
-})
-// setup state persistence
-controller.store.subscribe((newState) => migrator.saveData(newState))
+ // setup state persistence
+ controller.store.subscribe((newState) => diskStore)
+
+ //
+ // connect to other contexts
+ //
+
+ extension.runtime.onConnect.addListener(connectRemote)
+ function connectRemote (remotePort) {
+ var isMetaMaskInternalProcess = remotePort.name === 'popup' || remotePort.name === 'notification'
+ var portStream = new PortStream(remotePort)
+ if (isMetaMaskInternalProcess) {
+ // communication with popup
+ popupIsOpen = remotePort.name === 'popup'
+ setupTrustedCommunication(portStream, 'MetaMask', remotePort.name)
+ } else {
+ // communication with page
+ var originDomain = urlUtil.parse(remotePort.sender.url).hostname
+ setupUntrustedCommunication(portStream, originDomain)
+ }
+ }
-//
-// connect to other contexts
-//
+ function setupUntrustedCommunication (connectionStream, originDomain) {
+ // setup multiplexing
+ var mx = setupMultiplex(connectionStream)
+ // connect features
+ controller.setupProviderConnection(mx.createStream('provider'), originDomain)
+ controller.setupPublicConfig(mx.createStream('publicConfig'))
+ }
-extension.runtime.onConnect.addListener(connectRemote)
-function connectRemote (remotePort) {
- var isMetaMaskInternalProcess = remotePort.name === 'popup' || remotePort.name === 'notification'
- var portStream = new PortStream(remotePort)
- if (isMetaMaskInternalProcess) {
- // communication with popup
- popupIsOpen = remotePort.name === 'popup'
- setupTrustedCommunication(portStream, 'MetaMask', remotePort.name)
- } else {
- // communication with page
- var originDomain = urlUtil.parse(remotePort.sender.url).hostname
- setupUntrustedCommunication(portStream, originDomain)
+ function setupTrustedCommunication (connectionStream, originDomain) {
+ // setup multiplexing
+ var mx = setupMultiplex(connectionStream)
+ // connect features
+ setupControllerConnection(mx.createStream('controller'))
+ controller.setupProviderConnection(mx.createStream('provider'), originDomain)
}
-}
-function setupUntrustedCommunication (connectionStream, originDomain) {
- // setup multiplexing
- var mx = setupMultiplex(connectionStream)
- // connect features
- controller.setupProviderConnection(mx.createStream('provider'), originDomain)
- controller.setupPublicConfig(mx.createStream('publicConfig'))
-}
+ //
+ // remote features
+ //
+
+ function setupControllerConnection (stream) {
+ controller.stream = stream
+ var api = controller.getApi()
+ var dnode = Dnode(api)
+ stream.pipe(dnode).pipe(stream)
+ dnode.on('remote', (remote) => {
+ // push updates to popup
+ var sendUpdate = remote.sendUpdate.bind(remote)
+ controller.on('update', sendUpdate)
+ // teardown on disconnect
+ eos(stream, () => {
+ controller.removeListener('update', sendUpdate)
+ popupIsOpen = false
+ })
+ })
+ }
-function setupTrustedCommunication (connectionStream, originDomain) {
- // setup multiplexing
- var mx = setupMultiplex(connectionStream)
- // connect features
- setupControllerConnection(mx.createStream('controller'))
- controller.setupProviderConnection(mx.createStream('provider'), originDomain)
-}
+ //
+ // User Interface setup
+ //
+
+ controller.txManager.on('updateBadge', updateBadge)
+
+ // plugin badge text
+ function updateBadge () {
+ var label = ''
+ var unapprovedTxCount = controller.txManager.unapprovedTxCount
+ var unconfMsgs = messageManager.unconfirmedMsgs()
+ var unconfMsgLen = Object.keys(unconfMsgs).length
+ var count = unapprovedTxCount + unconfMsgLen
+ if (count) {
+ label = String(count)
+ }
+ extension.browserAction.setBadgeText({ text: label })
+ extension.browserAction.setBadgeBackgroundColor({ color: '#506F8B' })
+ }
-//
-// remote features
-//
+ return Promise.resolve()
-function setupControllerConnection (stream) {
- controller.stream = stream
- var api = controller.getApi()
- var dnode = Dnode(api)
- stream.pipe(dnode).pipe(stream)
- dnode.on('remote', (remote) => {
- // push updates to popup
- var sendUpdate = remote.sendUpdate.bind(remote)
- controller.on('update', sendUpdate)
- // teardown on disconnect
- eos(stream, () => {
- controller.removeListener('update', sendUpdate)
- popupIsOpen = false
- })
- })
}
//
-// User Interface setup
+// Etc...
//
// popup trigger
@@ -123,19 +166,4 @@ extension.runtime.onInstalled.addListener(function (details) {
if ((details.reason === 'install') && (!METAMASK_DEBUG)) {
extension.tabs.create({url: 'https://metamask.io/#how-it-works'})
}
-})
-
-// plugin badge text
-controller.txManager.on('updateBadge', updateBadge)
-function updateBadge () {
- var label = ''
- var unapprovedTxCount = controller.txManager.unapprovedTxCount
- var unconfMsgs = messageManager.unconfirmedMsgs()
- var unconfMsgLen = Object.keys(unconfMsgs).length
- var count = unapprovedTxCount + unconfMsgLen
- if (count) {
- label = String(count)
- }
- extension.browserAction.setBadgeText({ text: label })
- extension.browserAction.setBadgeBackgroundColor({ color: '#506F8B' })
-}
+}) \ No newline at end of file