aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'app/scripts')
-rw-r--r--app/scripts/background.js68
-rw-r--r--app/scripts/controllers/blacklist.js1
-rw-r--r--app/scripts/controllers/currency.js1
-rw-r--r--app/scripts/controllers/infura.js1
-rw-r--r--app/scripts/controllers/network.js1
-rw-r--r--app/scripts/controllers/recent-blocks.js1
-rw-r--r--app/scripts/controllers/shapeshift.js1
-rw-r--r--app/scripts/controllers/token-rates.js77
-rw-r--r--app/scripts/controllers/transactions.js1
-rw-r--r--app/scripts/inpage.js7
-rw-r--r--app/scripts/lib/ComposableObservableStore.js49
-rw-r--r--app/scripts/lib/createLoggerMiddleware.js2
-rw-r--r--app/scripts/lib/enums.js9
-rw-r--r--app/scripts/lib/environment-type.js10
-rw-r--r--app/scripts/lib/is-popup-or-notification.js12
-rw-r--r--app/scripts/lib/local-store.js1
-rw-r--r--app/scripts/lib/personal-message-manager.js1
-rw-r--r--app/scripts/lib/seed-phrase-verifier.js1
-rw-r--r--app/scripts/lib/typed-message-manager.js2
-rw-r--r--app/scripts/lib/util.js32
-rw-r--r--app/scripts/metamask-controller.js123
-rw-r--r--app/scripts/ui.js8
22 files changed, 279 insertions, 130 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 5878cd2e8..6550e8944 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -21,12 +21,16 @@ const setupMetamaskMeshMetrics = require('./lib/setupMetamaskMeshMetrics')
const EdgeEncryptor = require('./edge-encryptor')
const getFirstPreferredLangCode = require('./lib/get-first-preferred-lang-code')
const getObjStructure = require('./lib/getObjStructure')
+const {
+ ENVIRONMENT_TYPE_POPUP,
+ ENVIRONMENT_TYPE_NOTIFICATION,
+ ENVIRONMENT_TYPE_FULLSCREEN,
+} = require('./lib/enums')
const STORAGE_KEY = 'metamask-config'
const METAMASK_DEBUG = process.env.METAMASK_DEBUG
-window.log = log
-log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn')
+log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn')
const platform = new ExtensionPlatform()
const notificationManager = new NotificationManager()
@@ -44,7 +48,7 @@ const isEdge = !isIE && !!window.StyleMedia
let popupIsOpen = false
let notificationIsOpen = false
-let openMetamaskTabsIDs = {}
+const openMetamaskTabsIDs = {}
// state persistence
const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
@@ -173,7 +177,7 @@ function setupController (initState, initLangCode) {
return versionedData
}
- function persistData(state) {
+ function persistData (state) {
if (!state) {
throw new Error('MetaMask - updated state is missing', state)
}
@@ -192,30 +196,53 @@ function setupController (initState, initLangCode) {
//
// connect to other contexts
//
-
extension.runtime.onConnect.addListener(connectRemote)
+
+ const metamaskInternalProcessHash = {
+ [ENVIRONMENT_TYPE_POPUP]: true,
+ [ENVIRONMENT_TYPE_NOTIFICATION]: true,
+ [ENVIRONMENT_TYPE_FULLSCREEN]: true,
+ }
+
+ const isClientOpenStatus = () => {
+ return popupIsOpen || Boolean(Object.keys(openMetamaskTabsIDs).length) || notificationIsOpen
+ }
+
function connectRemote (remotePort) {
- const isMetaMaskInternalProcess = remotePort.name === 'popup' || remotePort.name === 'notification'
+ const processName = remotePort.name
+ const isMetaMaskInternalProcess = metamaskInternalProcessHash[processName]
const portStream = new PortStream(remotePort)
+
if (isMetaMaskInternalProcess) {
// communication with popup
- popupIsOpen = popupIsOpen || (remotePort.name === 'popup')
+ controller.isClientOpen = true
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') {
+
+ if (processName === ENVIRONMENT_TYPE_POPUP) {
+ popupIsOpen = true
+
endOfStream(portStream, () => {
popupIsOpen = false
- if (remotePort.sender.url.match(/home.html$/)) {
- openMetamaskTabsIDs[remotePort.sender.tab.id] = false
- }
+ controller.isClientOpen = isClientOpenStatus()
})
}
- if (remotePort.name === 'notification') {
+
+ if (processName === ENVIRONMENT_TYPE_NOTIFICATION) {
+ notificationIsOpen = true
+
endOfStream(portStream, () => {
notificationIsOpen = false
+ controller.isClientOpen = isClientOpenStatus()
+ })
+ }
+
+ if (processName === ENVIRONMENT_TYPE_FULLSCREEN) {
+ const tabId = remotePort.sender.tab.id
+ openMetamaskTabsIDs[tabId] = true
+
+ endOfStream(portStream, () => {
+ delete openMetamaskTabsIDs[tabId]
+ controller.isClientOpen = isClientOpenStatus()
})
}
} else {
@@ -258,10 +285,11 @@ function setupController (initState, initLangCode) {
// popup trigger
function triggerUi () {
- extension.tabs.query({ active: true }, (tabs) => {
- const currentlyActiveMetamaskTab = tabs.find(tab => openMetamaskTabsIDs[tab.id])
- if (!popupIsOpen && !currentlyActiveMetamaskTab && !notificationIsOpen) notificationManager.showPopup()
- notificationIsOpen = true
+ extension.tabs.query({ active: true }, tabs => {
+ const currentlyActiveMetamaskTab = Boolean(tabs.find(tab => openMetamaskTabsIDs[tab.id]))
+ if (!popupIsOpen && !currentlyActiveMetamaskTab && !notificationIsOpen) {
+ notificationManager.showPopup()
+ }
})
}
diff --git a/app/scripts/controllers/blacklist.js b/app/scripts/controllers/blacklist.js
index df41c90c0..d965f80b8 100644
--- a/app/scripts/controllers/blacklist.js
+++ b/app/scripts/controllers/blacklist.js
@@ -1,6 +1,7 @@
const ObservableStore = require('obs-store')
const extend = require('xtend')
const PhishingDetector = require('eth-phishing-detect/src/detector')
+const log = require('loglevel')
// compute phishing lists
const PHISHING_DETECTION_CONFIG = require('eth-phishing-detect/src/config.json')
diff --git a/app/scripts/controllers/currency.js b/app/scripts/controllers/currency.js
index 36b8808aa..d9e0a3e34 100644
--- a/app/scripts/controllers/currency.js
+++ b/app/scripts/controllers/currency.js
@@ -1,5 +1,6 @@
const ObservableStore = require('obs-store')
const extend = require('xtend')
+const log = require('loglevel')
// every ten minutes
const POLLING_INTERVAL = 600000
diff --git a/app/scripts/controllers/infura.js b/app/scripts/controllers/infura.js
index c6b4c9de2..8f6dd837e 100644
--- a/app/scripts/controllers/infura.js
+++ b/app/scripts/controllers/infura.js
@@ -1,5 +1,6 @@
const ObservableStore = require('obs-store')
const extend = require('xtend')
+const log = require('loglevel')
// every ten minutes
const POLLING_INTERVAL = 10 * 60 * 1000
diff --git a/app/scripts/controllers/network.js b/app/scripts/controllers/network.js
index 617456cd7..45574e673 100644
--- a/app/scripts/controllers/network.js
+++ b/app/scripts/controllers/network.js
@@ -9,6 +9,7 @@ const extend = require('xtend')
const EthQuery = require('eth-query')
const createEventEmitterProxy = require('../lib/events-proxy.js')
const networkConfig = require('../config.js')
+const log = require('loglevel')
const { OLD_UI_NETWORK_TYPE, DEFAULT_RPC } = networkConfig.enums
const INFURA_PROVIDER_TYPES = ['ropsten', 'rinkeby', 'kovan', 'mainnet']
diff --git a/app/scripts/controllers/recent-blocks.js b/app/scripts/controllers/recent-blocks.js
index 4ae3810eb..0c1ee4e38 100644
--- a/app/scripts/controllers/recent-blocks.js
+++ b/app/scripts/controllers/recent-blocks.js
@@ -2,6 +2,7 @@ const ObservableStore = require('obs-store')
const extend = require('xtend')
const BN = require('ethereumjs-util').BN
const EthQuery = require('eth-query')
+const log = require('loglevel')
class RecentBlocksController {
diff --git a/app/scripts/controllers/shapeshift.js b/app/scripts/controllers/shapeshift.js
index 3bbfaa1c5..b38b3812d 100644
--- a/app/scripts/controllers/shapeshift.js
+++ b/app/scripts/controllers/shapeshift.js
@@ -1,5 +1,6 @@
const ObservableStore = require('obs-store')
const extend = require('xtend')
+const log = require('loglevel')
// every three seconds when an incomplete tx is waiting
const POLLING_INTERVAL = 3000
diff --git a/app/scripts/controllers/token-rates.js b/app/scripts/controllers/token-rates.js
new file mode 100644
index 000000000..22e3e8154
--- /dev/null
+++ b/app/scripts/controllers/token-rates.js
@@ -0,0 +1,77 @@
+const ObservableStore = require('obs-store')
+
+// By default, poll every 3 minutes
+const DEFAULT_INTERVAL = 180 * 1000
+
+/**
+ * A controller that polls for token exchange
+ * rates based on a user's current token list
+ */
+class TokenRatesController {
+ /**
+ * Creates a TokenRatesController
+ *
+ * @param {Object} [config] - Options to configure controller
+ */
+ constructor ({ interval = DEFAULT_INTERVAL, preferences } = {}) {
+ this.store = new ObservableStore()
+ this.preferences = preferences
+ this.interval = interval
+ }
+
+ /**
+ * Updates exchange rates for all tokens
+ */
+ async updateExchangeRates () {
+ if (!this.isActive) { return }
+ const contractExchangeRates = {}
+ for (const i in this._tokens) {
+ const address = this._tokens[i].address
+ contractExchangeRates[address] = await this.fetchExchangeRate(address)
+ }
+ this.store.putState({ contractExchangeRates })
+ }
+
+ /**
+ * Fetches a token exchange rate by address
+ *
+ * @param {String} address - Token contract address
+ */
+ async fetchExchangeRate (address) {
+ try {
+ const response = await fetch(`https://exchanges.balanc3.net/prices?from=${address}&to=ETH&autoConversion=false&summaryOnly=true`)
+ const json = await response.json()
+ return json && json.length ? json[0].averagePrice : 0
+ } catch (error) { }
+ }
+
+ /**
+ * @type {Number} - Interval used to poll for exchange rates
+ */
+ set interval (interval) {
+ this._handle && clearInterval(this._handle)
+ if (!interval) { return }
+ this._handle = setInterval(() => { this.updateExchangeRates() }, interval)
+ }
+
+ /**
+ * @type {Object} - Preferences controller instance
+ */
+ set preferences (preferences) {
+ this._preferences && this._preferences.unsubscribe()
+ if (!preferences) { return }
+ this._preferences = preferences
+ this.tokens = preferences.getState().tokens
+ preferences.subscribe(({ tokens = [] }) => { this.tokens = tokens })
+ }
+
+ /**
+ * @type {Array} - Array of token objects with contract addresses
+ */
+ set tokens (tokens) {
+ this._tokens = tokens
+ this.updateExchangeRates()
+ }
+}
+
+module.exports = TokenRatesController
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index 336b0d8f7..c8211ebd7 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -7,6 +7,7 @@ const TransactionStateManager = require('../lib/tx-state-manager')
const TxGasUtil = require('../lib/tx-gas-utils')
const PendingTransactionTracker = require('../lib/pending-tx-tracker')
const NonceTracker = require('../lib/nonce-tracker')
+const log = require('loglevel')
/*
Transaction Controller is an aggregate of sub-controllers and trackers
diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js
index ec99bfc35..92c732813 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -3,16 +3,11 @@ cleanContextForImports()
require('web3/dist/web3.min.js')
const log = require('loglevel')
const LocalMessageDuplexStream = require('post-message-stream')
-// const PingStream = require('ping-pong-stream/ping')
-// const endOfStream = require('end-of-stream')
const setupDappAutoReload = require('./lib/auto-reload.js')
const MetamaskInpageProvider = require('./lib/inpage-provider.js')
restoreContextAfterImports()
-const METAMASK_DEBUG = process.env.METAMASK_DEBUG
-window.log = log
-log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn')
-
+log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn')
//
// setup plugin communication
diff --git a/app/scripts/lib/ComposableObservableStore.js b/app/scripts/lib/ComposableObservableStore.js
new file mode 100644
index 000000000..d5ee708a1
--- /dev/null
+++ b/app/scripts/lib/ComposableObservableStore.js
@@ -0,0 +1,49 @@
+const ObservableStore = require('obs-store')
+
+/**
+ * An ObservableStore that can composes a flat
+ * structure of child stores based on configuration
+ */
+class ComposableObservableStore extends ObservableStore {
+ /**
+ * Create a new store
+ *
+ * @param {Object} [initState] - The initial store state
+ * @param {Object} [config] - Map of internal state keys to child stores
+ */
+ constructor (initState, config) {
+ super(initState)
+ this.updateStructure(config)
+ }
+
+ /**
+ * Composes a new internal store subscription structure
+ *
+ * @param {Object} [config] - Map of internal state keys to child stores
+ */
+ updateStructure (config) {
+ this.config = config
+ this.removeAllListeners()
+ for (const key in config) {
+ config[key].subscribe((state) => {
+ this.updateState({ [key]: state })
+ })
+ }
+ }
+
+ /**
+ * Merges all child store state into a single object rather than
+ * returning an object keyed by child store class name
+ *
+ * @returns {Object} - Object containing merged child store state
+ */
+ getFlatState () {
+ let flatState = {}
+ for (const key in this.config) {
+ flatState = { ...flatState, ...this.config[key].getState() }
+ }
+ return flatState
+ }
+}
+
+module.exports = ComposableObservableStore
diff --git a/app/scripts/lib/createLoggerMiddleware.js b/app/scripts/lib/createLoggerMiddleware.js
index 2707cbd9e..fc6abf828 100644
--- a/app/scripts/lib/createLoggerMiddleware.js
+++ b/app/scripts/lib/createLoggerMiddleware.js
@@ -1,3 +1,5 @@
+const log = require('loglevel')
+
// log rpc activity
module.exports = createLoggerMiddleware
diff --git a/app/scripts/lib/enums.js b/app/scripts/lib/enums.js
new file mode 100644
index 000000000..0a3afca47
--- /dev/null
+++ b/app/scripts/lib/enums.js
@@ -0,0 +1,9 @@
+const ENVIRONMENT_TYPE_POPUP = 'popup'
+const ENVIRONMENT_TYPE_NOTIFICATION = 'notification'
+const ENVIRONMENT_TYPE_FULLSCREEN = 'fullscreen'
+
+module.exports = {
+ ENVIRONMENT_TYPE_POPUP,
+ ENVIRONMENT_TYPE_NOTIFICATION,
+ ENVIRONMENT_TYPE_FULLSCREEN,
+}
diff --git a/app/scripts/lib/environment-type.js b/app/scripts/lib/environment-type.js
deleted file mode 100644
index 7966926eb..000000000
--- a/app/scripts/lib/environment-type.js
+++ /dev/null
@@ -1,10 +0,0 @@
-module.exports = function environmentType () {
- const url = window.location.href
- if (url.match(/popup.html$/)) {
- return 'popup'
- } else if (url.match(/home.html$/)) {
- return 'responsive'
- } else {
- return 'notification'
- }
-}
diff --git a/app/scripts/lib/is-popup-or-notification.js b/app/scripts/lib/is-popup-or-notification.js
deleted file mode 100644
index ad3e825c0..000000000
--- a/app/scripts/lib/is-popup-or-notification.js
+++ /dev/null
@@ -1,12 +0,0 @@
-module.exports = function isPopupOrNotification () {
- const url = window.location.href
- // if (url.match(/popup.html$/) || url.match(/home.html$/)) {
- // Below regexes needed for feature toggles (e.g. see line ~340 in ui/app/app.js)
- // Revert below regexes to above commented out regexes before merge to master
- if (url.match(/popup.html(?:\?.+)*$/) ||
- url.match(/home.html(?:\?.+)*$/) || url.match(/home.html(?:#.*)*$/)) {
- return 'popup'
- } else {
- return 'notification'
- }
-}
diff --git a/app/scripts/lib/local-store.js b/app/scripts/lib/local-store.js
index 5b47985f6..2dda0ba1f 100644
--- a/app/scripts/lib/local-store.js
+++ b/app/scripts/lib/local-store.js
@@ -3,6 +3,7 @@
// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/local
const extension = require('extensionizer')
+const log = require('loglevel')
module.exports = class ExtensionStore {
constructor() {
diff --git a/app/scripts/lib/personal-message-manager.js b/app/scripts/lib/personal-message-manager.js
index 6602f5aa8..43a7d0b42 100644
--- a/app/scripts/lib/personal-message-manager.js
+++ b/app/scripts/lib/personal-message-manager.js
@@ -3,6 +3,7 @@ const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
const createId = require('./random-id')
const hexRe = /^[0-9A-Fa-f]+$/g
+const log = require('loglevel')
module.exports = class PersonalMessageManager extends EventEmitter {
diff --git a/app/scripts/lib/seed-phrase-verifier.js b/app/scripts/lib/seed-phrase-verifier.js
index 9cea22029..7ba712c0d 100644
--- a/app/scripts/lib/seed-phrase-verifier.js
+++ b/app/scripts/lib/seed-phrase-verifier.js
@@ -1,4 +1,5 @@
const KeyringController = require('eth-keyring-controller')
+const log = require('loglevel')
const seedPhraseVerifier = {
diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js
index 8b760790e..60042155e 100644
--- a/app/scripts/lib/typed-message-manager.js
+++ b/app/scripts/lib/typed-message-manager.js
@@ -3,7 +3,7 @@ const ObservableStore = require('obs-store')
const createId = require('./random-id')
const assert = require('assert')
const sigUtil = require('eth-sig-util')
-
+const log = require('loglevel')
module.exports = class TypedMessageManager extends EventEmitter {
constructor (opts) {
diff --git a/app/scripts/lib/util.js b/app/scripts/lib/util.js
index 6dee9edf0..df815906f 100644
--- a/app/scripts/lib/util.js
+++ b/app/scripts/lib/util.js
@@ -1,20 +1,27 @@
const ethUtil = require('ethereumjs-util')
const assert = require('assert')
const BN = require('bn.js')
-
-module.exports = {
- getStack,
- sufficientBalance,
- hexToBn,
- bnToHex,
- BnMultiplyByFraction,
-}
+const {
+ ENVIRONMENT_TYPE_POPUP,
+ ENVIRONMENT_TYPE_NOTIFICATION,
+ ENVIRONMENT_TYPE_FULLSCREEN,
+} = require('./enums')
function getStack () {
const stack = new Error('Stack trace generator - not an error').stack
return stack
}
+const getEnvironmentType = (url = window.location.href) => {
+ if (url.match(/popup.html(?:\?.+)*$/)) {
+ return ENVIRONMENT_TYPE_POPUP
+ } else if (url.match(/home.html(?:\?.+)*$/) || url.match(/home.html(?:#.*)*$/)) {
+ return ENVIRONMENT_TYPE_FULLSCREEN
+ } else {
+ return ENVIRONMENT_TYPE_NOTIFICATION
+ }
+}
+
function sufficientBalance (txParams, hexBalance) {
// validate hexBalance is a hex string
assert.equal(typeof hexBalance, 'string', 'sufficientBalance - hexBalance is not a hex string')
@@ -42,3 +49,12 @@ function BnMultiplyByFraction (targetBN, numerator, denominator) {
const denomBN = new BN(denominator)
return targetBN.mul(numBN).div(denomBN)
}
+
+module.exports = {
+ getStack,
+ getEnvironmentType,
+ sufficientBalance,
+ hexToBn,
+ bnToHex,
+ BnMultiplyByFraction,
+}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index b96acc9da..a12b6776e 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -5,10 +5,10 @@
*/
const EventEmitter = require('events')
-const extend = require('xtend')
const pump = require('pump')
const Dnode = require('dnode')
const ObservableStore = require('obs-store')
+const ComposableObservableStore = require('./lib/ComposableObservableStore')
const asStream = require('obs-store/lib/asStream')
const AccountTracker = require('./lib/account-tracker')
const RpcEngine = require('json-rpc-engine')
@@ -34,6 +34,7 @@ const PersonalMessageManager = require('./lib/personal-message-manager')
const TypedMessageManager = require('./lib/typed-message-manager')
const TransactionController = require('./controllers/transactions')
const BalancesController = require('./controllers/computed-balances')
+const TokenRatesController = require('./controllers/token-rates')
const ConfigManager = require('./lib/config-manager')
const nodeify = require('./lib/nodeify')
const accountImporter = require('./account-import-strategies')
@@ -44,6 +45,7 @@ const BN = require('ethereumjs-util').BN
const GWEI_BN = new BN('1000000000')
const percentile = require('percentile')
const seedPhraseVerifier = require('./lib/seed-phrase-verifier')
+const log = require('loglevel')
module.exports = class MetamaskController extends EventEmitter {
@@ -65,7 +67,7 @@ module.exports = class MetamaskController extends EventEmitter {
this.platform = opts.platform
// observable state store
- this.store = new ObservableStore(initState)
+ this.store = new ComposableObservableStore(initState)
// lock to ensure only one vault created at once
this.createVaultMutex = new Mutex()
@@ -104,6 +106,11 @@ module.exports = class MetamaskController extends EventEmitter {
this.provider = this.initializeProvider()
this.blockTracker = this.provider._blockTracker
+ // token exchange rate tracker
+ this.tokenRatesController = new TokenRatesController({
+ preferences: this.preferencesController.store,
+ })
+
this.recentBlocksController = new RecentBlocksController({
blockTracker: this.blockTracker,
provider: this.provider,
@@ -184,53 +191,37 @@ module.exports = class MetamaskController extends EventEmitter {
this.typedMessageManager = new TypedMessageManager()
this.publicConfigStore = this.initPublicConfigStore()
- // manual disk state subscriptions
- this.txController.store.subscribe((state) => {
- this.store.updateState({ TransactionController: state })
- })
- this.keyringController.store.subscribe((state) => {
- this.store.updateState({ KeyringController: state })
- })
- this.preferencesController.store.subscribe((state) => {
- this.store.updateState({ PreferencesController: state })
- })
- this.addressBookController.store.subscribe((state) => {
- this.store.updateState({ AddressBookController: state })
- })
- this.currencyController.store.subscribe((state) => {
- this.store.updateState({ CurrencyController: state })
- })
- this.noticeController.store.subscribe((state) => {
- this.store.updateState({ NoticeController: state })
- })
- this.shapeshiftController.store.subscribe((state) => {
- this.store.updateState({ ShapeShiftController: state })
- })
- this.networkController.store.subscribe((state) => {
- this.store.updateState({ NetworkController: state })
+ this.store.updateStructure({
+ TransactionController: this.txController.store,
+ KeyringController: this.keyringController.store,
+ PreferencesController: this.preferencesController.store,
+ AddressBookController: this.addressBookController.store,
+ CurrencyController: this.currencyController.store,
+ NoticeController: this.noticeController.store,
+ ShapeShiftController: this.shapeshiftController.store,
+ NetworkController: this.networkController.store,
+ InfuraController: this.infuraController.store,
})
- this.infuraController.store.subscribe((state) => {
- this.store.updateState({ InfuraController: state })
+ this.memStore = new ComposableObservableStore(null, {
+ NetworkController: this.networkController.store,
+ AccountTracker: this.accountTracker.store,
+ TxController: this.txController.memStore,
+ BalancesController: this.balancesController.store,
+ TokenRatesController: this.tokenRatesController.store,
+ MessageManager: this.messageManager.memStore,
+ PersonalMessageManager: this.personalMessageManager.memStore,
+ TypesMessageManager: this.typedMessageManager.memStore,
+ KeyringController: this.keyringController.memStore,
+ PreferencesController: this.preferencesController.store,
+ RecentBlocksController: this.recentBlocksController.store,
+ AddressBookController: this.addressBookController.store,
+ CurrencyController: this.currencyController.store,
+ NoticeController: this.noticeController.memStore,
+ ShapeshiftController: this.shapeshiftController.store,
+ InfuraController: this.infuraController.store,
})
-
- // manual mem state subscriptions
- const sendUpdate = this.sendUpdate.bind(this)
- this.networkController.store.subscribe(sendUpdate)
- this.accountTracker.store.subscribe(sendUpdate)
- this.txController.memStore.subscribe(sendUpdate)
- this.balancesController.store.subscribe(sendUpdate)
- this.messageManager.memStore.subscribe(sendUpdate)
- this.personalMessageManager.memStore.subscribe(sendUpdate)
- this.typedMessageManager.memStore.subscribe(sendUpdate)
- this.keyringController.memStore.subscribe(sendUpdate)
- this.preferencesController.store.subscribe(sendUpdate)
- this.recentBlocksController.store.subscribe(sendUpdate)
- this.addressBookController.store.subscribe(sendUpdate)
- this.currencyController.store.subscribe(sendUpdate)
- this.noticeController.memStore.subscribe(sendUpdate)
- this.shapeshiftController.store.subscribe(sendUpdate)
- this.infuraController.store.subscribe(sendUpdate)
+ this.memStore.subscribe(this.sendUpdate.bind(this))
}
/**
@@ -279,6 +270,7 @@ module.exports = class MetamaskController extends EventEmitter {
// memStore -> transform -> publicConfigStore
this.on('update', (memState) => {
+ this.isClientOpenAndUnlocked = memState.isUnlocked && this._isClientOpen
const publicState = selectPublicState(memState)
publicConfigStore.putState(publicState)
})
@@ -308,33 +300,16 @@ module.exports = class MetamaskController extends EventEmitter {
const vault = this.keyringController.store.getState().vault
const isInitialized = (!!wallet || !!vault)
- return extend(
- {
- isInitialized,
- },
- this.networkController.store.getState(),
- this.accountTracker.store.getState(),
- this.txController.memStore.getState(),
- this.messageManager.memStore.getState(),
- this.personalMessageManager.memStore.getState(),
- this.typedMessageManager.memStore.getState(),
- this.keyringController.memStore.getState(),
- this.balancesController.store.getState(),
- this.preferencesController.store.getState(),
- this.addressBookController.store.getState(),
- this.currencyController.store.getState(),
- this.noticeController.memStore.getState(),
- this.infuraController.store.getState(),
- this.recentBlocksController.store.getState(),
- // config manager
- this.configManager.getConfig(),
- this.shapeshiftController.store.getState(),
- {
+ return {
+ ...{ isInitialized },
+ ...this.memStore.getFlatState(),
+ ...this.configManager.getConfig(),
+ ...{
lostAccounts: this.configManager.getLostAccounts(),
seedWords: this.configManager.getSeedWords(),
forgottenPassword: this.configManager.getPasswordForgotten(),
- }
- )
+ },
+ }
}
/**
@@ -1057,4 +1032,12 @@ module.exports = class MetamaskController extends EventEmitter {
}
}
+ set isClientOpen (open) {
+ this._isClientOpen = open
+ this.isClientOpenAndUnlocked = this.getState().isUnlocked && open
+ }
+
+ set isClientOpenAndUnlocked (active) {
+ this.tokenRatesController.isActive = active
+ }
}
diff --git a/app/scripts/ui.js b/app/scripts/ui.js
index 13c7ac5ec..bdab29c1e 100644
--- a/app/scripts/ui.js
+++ b/app/scripts/ui.js
@@ -3,12 +3,14 @@ const OldMetaMaskUiCss = require('../../old-ui/css')
const NewMetaMaskUiCss = require('../../ui/css')
const startPopup = require('./popup-core')
const PortStream = require('./lib/port-stream.js')
-const isPopupOrNotification = require('./lib/is-popup-or-notification')
+const { getEnvironmentType } = require('./lib/util')
+const { ENVIRONMENT_TYPE_NOTIFICATION } = require('./lib/enums')
const extension = require('extensionizer')
const ExtensionPlatform = require('./platforms/extension')
const NotificationManager = require('./lib/notification-manager')
const notificationManager = new NotificationManager()
const setupRaven = require('./lib/setupRaven')
+const log = require('loglevel')
start().catch(log.error)
@@ -26,7 +28,7 @@ async function start() {
// injectCss(css)
// identify window type (popup, notification)
- const windowType = isPopupOrNotification()
+ const windowType = getEnvironmentType(window.location.href)
global.METAMASK_UI_TYPE = windowType
closePopupIfOpen(windowType)
@@ -68,7 +70,7 @@ async function start() {
function closePopupIfOpen (windowType) {
- if (windowType !== 'notification') {
+ if (windowType !== ENVIRONMENT_TYPE_NOTIFICATION) {
// should close only chrome popup
notificationManager.closePopup()
}