From d8f5150aa5bf4b04310f887504428f1caa13cbf4 Mon Sep 17 00:00:00 2001
From: Lazaridis <info@lazaridis.com>
Date: Fri, 16 Mar 2018 00:27:10 +0200
Subject: adds initial documentation, re #3568

---
 app/scripts/metamask-controller.js | 178 ++++++++++++++++++++++++++++---------
 1 file changed, 138 insertions(+), 40 deletions(-)

(limited to 'app/scripts/metamask-controller.js')

diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 0a5c1d36f..31c0bed58 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -1,3 +1,9 @@
+/**
+ * @file      The central metamask controller. Aggregates other controllers and exports an api.
+ * @copyright Copyright (c) 2018 MetaMask
+ * @license   MIT
+ */
+
 const EventEmitter = require('events')
 const extend = require('xtend')
 const pump = require('pump')
@@ -41,7 +47,11 @@ const seedPhraseVerifier = require('./lib/seed-phrase-verifier')
 
 module.exports = class MetamaskController extends EventEmitter {
 
-  constructor (opts) {
+  /**
+   * @constructor
+   * @param {Object} opts 
+   */
+   constructor (opts) {
     super()
 
     this.defaultMaxListeners = 20
@@ -223,10 +233,9 @@ module.exports = class MetamaskController extends EventEmitter {
     this.infuraController.store.subscribe(sendUpdate)
   }
 
-  //
-  // Constructor helpers
-  //
-
+  /**
+   * Constructor helper: initialize a provider.
+   */
   initializeProvider () {
     const providerOpts = {
       static: {
@@ -257,6 +266,9 @@ module.exports = class MetamaskController extends EventEmitter {
     return providerProxy
   }
 
+  /**
+   * Constructor helper: initialize a public confi store.
+   */
   initPublicConfigStore () {
     // get init state
     const publicConfigStore = new ObservableStore()
@@ -282,6 +294,9 @@ module.exports = class MetamaskController extends EventEmitter {
   // State Management
   //
 
+  /**
+   * ?
+   */
   getState () {
     const wallet = this.configManager.getWallet()
     const vault = this.keyringController.store.getState().vault
@@ -319,7 +334,10 @@ module.exports = class MetamaskController extends EventEmitter {
   //
   // Remote Features
   //
-
+  
+  /**
+   * ?
+   */
   getApi () {
     const keyringController = this.keyringController
     const preferencesController = this.preferencesController
@@ -517,10 +535,22 @@ module.exports = class MetamaskController extends EventEmitter {
     return '0x' + percentileNumBn.mul(GWEI_BN).toString(16)
   }
 
-  //
-  // Vault Management
-  //
-
+//=============================================================================
+// VAULT / KEYRING RELATED METHODS
+//=============================================================================
+
+  /**
+   * Creates a new Vault(?) and create a new keychain(?)
+   * 
+   * A vault is ...
+   * 
+   * A keychain is ...
+   * 
+   *
+   * @param  {} password
+   * 
+   * @returns {} vault
+   */
   async createNewVaultAndKeychain (password) {
     const release = await this.createVaultMutex.acquire()
     let vault
@@ -544,6 +574,11 @@ module.exports = class MetamaskController extends EventEmitter {
     return vault
   }
 
+  /**
+   * Create a new Vault and restore an existent keychain
+   * @param  {} password
+   * @param  {} seed
+   */
   async createNewVaultAndRestore (password, seed) {
     const release = await this.createVaultMutex.acquire()
     try {
@@ -557,16 +592,28 @@ module.exports = class MetamaskController extends EventEmitter {
     }
   }
 
+  /**
+   * Retrieves the first Identiy from the passed Vault and selects the related address
+   * 
+   * An Identity is ...
+   * 
+   * @param  {} vault
+   */
   selectFirstIdentity (vault) {
     const { identities } = vault
     const address = Object.keys(identities)[0]
     this.preferencesController.setSelectedAddress(address)
   }
 
-  //
+  // ?
   // Opinionated Keyring Management
   //
 
+  /**
+   * Adds a new account to ... 
+   * 
+   * @returns {} keyState
+   */
   async addNewAccount () {
     const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0]
     if (!primaryKeyring) {
@@ -588,10 +635,12 @@ module.exports = class MetamaskController extends EventEmitter {
     return keyState
   }
 
-  // Adds the current vault's seed words to the UI's state tree.
-  //
-  // Used when creating a first vault, to allow confirmation.
-  // Also used when revealing the seed words in the confirmation view.
+  /**
+   * Adds the current vault's seed words to the UI's state tree.
+   * 
+   * Used when creating a first vault, to allow confirmation.
+   * Also used when revealing the seed words in the confirmation view.
+   */ 
   placeSeedWords (cb) {
 
     this.verifySeedPhrase()
@@ -604,10 +653,13 @@ module.exports = class MetamaskController extends EventEmitter {
       })
   }
 
-  // Verifies the current vault's seed words if they can restore the
-  // accounts belonging to the current vault.
-  //
-  // Called when the first account is created and on unlocking the vault.
+  /**
+   * Verifies the validity of the current vault's seed phrase.
+   * 
+   * Validity: seed phrase can restore the accounts belonging to the current vault.
+   *
+   * Called when the first account is created and on unlocking the vault.
+   */
   async verifySeedPhrase () {
 
     const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0]
@@ -632,22 +684,33 @@ module.exports = class MetamaskController extends EventEmitter {
     }
   }
 
-  // ClearSeedWordCache
-  //
-  // Removes the primary account's seed words from the UI's state tree,
-  // ensuring they are only ever available in the background process.
+  /**
+   * Remove the primary account seed phrase from the UI's state tree.
+   * 
+   * The seed phrase remains available in the background process.
+   * 
+   */
   clearSeedWordCache (cb) {
     this.configManager.setSeedWords(null)
     cb(null, this.preferencesController.getSelectedAddress())
   }
-
+  
+  /**
+   * ?
+   */
   resetAccount (cb) {
     const selectedAddress = this.preferencesController.getSelectedAddress()
     this.txController.wipeTransactions(selectedAddress)
     cb(null, selectedAddress)
   }
 
-
+  /**
+   * Imports an account ... ?
+   * 
+   * @param  {} strategy
+   * @param  {} args
+   * @param  {} cb
+   */
   importAccountWithStrategy (strategy, args, cb) {
     accountImporter.importAccount(strategy, args)
     .then((privateKey) => {
@@ -659,11 +722,15 @@ module.exports = class MetamaskController extends EventEmitter {
     .catch((reason) => { cb(reason) })
   }
 
+//============================================================================= 
+// END (VAULT / KEYRING RELATED METHODS)
+//=============================================================================
 
-  //
-  // Identity Management
-  //
-  //
+
+
+//=============================================================================
+// Identity Management
+//=============================================================================
 
   async retryTransaction (txId, cb) {
     await this.txController.retryTransaction(txId)
@@ -729,7 +796,11 @@ module.exports = class MetamaskController extends EventEmitter {
       }
     })
   }
-
+  
+  /**
+   * @param  {} msgParams
+   * @param  {} cb
+   */
   signMessage (msgParams, cb) {
     log.info('MetaMaskController - signMessage')
     const msgId = msgParams.metamaskId
@@ -758,6 +829,12 @@ module.exports = class MetamaskController extends EventEmitter {
   }
 
   // Prefixed Style Message Signing Methods:
+  
+  /**
+   * 
+   * @param  {} msgParams
+   * @param  {} cb
+   */
   approvePersonalMessage (msgParams, cb) {
     const msgId = this.personalMessageManager.addUnapprovedMessage(msgParams)
     this.sendUpdate()
@@ -773,7 +850,10 @@ module.exports = class MetamaskController extends EventEmitter {
       }
     })
   }
-
+  
+  /**
+   * @param  {} msgParams
+   */
   signPersonalMessage (msgParams) {
     log.info('MetaMaskController - signPersonalMessage')
     const msgId = msgParams.metamaskId
@@ -791,7 +871,10 @@ module.exports = class MetamaskController extends EventEmitter {
       return this.getState()
     })
   }
-
+  
+  /**
+   * @param  {} msgParams
+   */
   signTypedMessage (msgParams) {
     log.info('MetaMaskController - signTypedMessage')
     const msgId = msgParams.metamaskId
@@ -843,13 +926,23 @@ module.exports = class MetamaskController extends EventEmitter {
     this.sendUpdate()
     cb()
   }
-
+  
+  /**
+   * ?
+   * 
+   * @param  {} migratorOutput
+   */
   restoreOldVaultAccounts (migratorOutput) {
     const { serialized } = migratorOutput
     return this.keyringController.restoreKeyring(serialized)
     .then(() => migratorOutput)
   }
 
+  /**
+   * ?
+   * 
+   * @param  {} migratorOutput
+   */
   restoreOldLostAccounts (migratorOutput) {
     const { lostAccounts } = migratorOutput
     if (lostAccounts) {
@@ -859,10 +952,15 @@ module.exports = class MetamaskController extends EventEmitter {
     return Promise.resolve(migratorOutput)
   }
 
-  // IMPORT LOST ACCOUNTS
-  // @Object with key lostAccounts: @Array accounts <{ address, privateKey }>
-  // Uses the array's private keys to create a new Simple Key Pair keychain
-  // and add it to the keyring controller.
+
+  /**
+   * Import (lost) Accounts
+   * 
+   * @param  {Object} {lostAccounts} @Array accounts <{ address, privateKey }>
+   * 
+   * Uses the array's private keys to create a new Simple Key Pair keychain
+   * and add it to the keyring controller.
+   */
   importLostAccounts ({ lostAccounts }) {
     const privKeys = lostAccounts.map(acct => acct.privateKey)
     return this.keyringController.restoreKeyring({
@@ -871,9 +969,9 @@ module.exports = class MetamaskController extends EventEmitter {
     })
   }
 
-  //
-  // config
-  //
+//=============================================================================
+// CONFIG
+//=============================================================================
 
   // Log blocks
 
-- 
cgit 


From 904f00e8acf40a72d233d1776c8aa760026e1bd3 Mon Sep 17 00:00:00 2001
From: Lazaridis <info@lazaridis.com>
Date: Fri, 16 Mar 2018 02:29:53 +0200
Subject: group all vault/keyring related methods together, re #3568

---
 app/scripts/metamask-controller.js | 258 +++++++++++++++++++------------------
 1 file changed, 130 insertions(+), 128 deletions(-)

(limited to 'app/scripts/metamask-controller.js')

diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 31c0bed58..cbdf757c6 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -267,7 +267,7 @@ module.exports = class MetamaskController extends EventEmitter {
   }
 
   /**
-   * Constructor helper: initialize a public confi store.
+   * Constructor helper: initialize a public config store.
    */
   initPublicConfigStore () {
     // get init state
@@ -290,12 +290,11 @@ module.exports = class MetamaskController extends EventEmitter {
     return publicConfigStore
   }
 
-  //
-  // State Management
-  //
 
   /**
-   * ?
+   * The metamask-state of the various controllers, made available to the UI
+   * 
+   * @returns {Object} status 
    */
   getState () {
     const wallet = this.configManager.getWallet()
@@ -331,12 +330,10 @@ module.exports = class MetamaskController extends EventEmitter {
     )
   }
 
-  //
-  // Remote Features
-  //
-  
   /**
-   * ?
+   * Returns an api-object which is consumed by the UI
+   * 
+   * @returns {Object} 
    */
   getApi () {
     const keyringController = this.keyringController
@@ -656,7 +653,7 @@ module.exports = class MetamaskController extends EventEmitter {
   /**
    * Verifies the validity of the current vault's seed phrase.
    * 
-   * Validity: seed phrase can restore the accounts belonging to the current vault.
+   * Validity: seed phrase restores the accounts belonging to the current vault.
    *
    * Called when the first account is created and on unlocking the vault.
    */
@@ -722,81 +719,9 @@ module.exports = class MetamaskController extends EventEmitter {
     .catch((reason) => { cb(reason) })
   }
 
-//============================================================================= 
-// END (VAULT / KEYRING RELATED METHODS)
-//=============================================================================
-
-
-
-//=============================================================================
-// Identity Management
-//=============================================================================
-
-  async retryTransaction (txId, cb) {
-    await this.txController.retryTransaction(txId)
-    const state = await this.getState()
-    return state
-  }
-
-
-  newUnsignedMessage (msgParams, cb) {
-    const msgId = this.messageManager.addUnapprovedMessage(msgParams)
-    this.sendUpdate()
-    this.opts.showUnconfirmedMessage()
-    this.messageManager.once(`${msgId}:finished`, (data) => {
-      switch (data.status) {
-        case 'signed':
-          return cb(null, data.rawSig)
-        case 'rejected':
-          return cb(new Error('MetaMask Message Signature: User denied message signature.'))
-        default:
-          return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
-      }
-    })
-  }
-
-  newUnsignedPersonalMessage (msgParams, cb) {
-    if (!msgParams.from) {
-      return cb(new Error('MetaMask Message Signature: from field is required.'))
-    }
-
-    const msgId = this.personalMessageManager.addUnapprovedMessage(msgParams)
-    this.sendUpdate()
-    this.opts.showUnconfirmedMessage()
-    this.personalMessageManager.once(`${msgId}:finished`, (data) => {
-      switch (data.status) {
-        case 'signed':
-          return cb(null, data.rawSig)
-        case 'rejected':
-          return cb(new Error('MetaMask Message Signature: User denied message signature.'))
-        default:
-          return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
-      }
-    })
-  }
-
-  newUnsignedTypedMessage (msgParams, cb) {
-    let msgId
-    try {
-      msgId = this.typedMessageManager.addUnapprovedMessage(msgParams)
-      this.sendUpdate()
-      this.opts.showUnconfirmedMessage()
-    } catch (e) {
-      return cb(e)
-    }
+  // ---------------------------------------------------------------------------
+  // Identity Management (sign)
 
-    this.typedMessageManager.once(`${msgId}:finished`, (data) => {
-      switch (data.status) {
-        case 'signed':
-          return cb(null, data.rawSig)
-        case 'rejected':
-          return cb(new Error('MetaMask Message Signature: User denied message signature.'))
-        default:
-          return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
-      }
-    })
-  }
-  
   /**
    * @param  {} msgParams
    * @param  {} cb
@@ -820,14 +745,6 @@ module.exports = class MetamaskController extends EventEmitter {
     })
   }
 
-  cancelMessage (msgId, cb) {
-    const messageManager = this.messageManager
-    messageManager.rejectMsg(msgId)
-    if (cb && typeof cb === 'function') {
-      cb(null, this.getState())
-    }
-  }
-
   // Prefixed Style Message Signing Methods:
   
   /**
@@ -892,41 +809,10 @@ module.exports = class MetamaskController extends EventEmitter {
         return this.getState()
       })
   }
-
-  cancelPersonalMessage (msgId, cb) {
-    const messageManager = this.personalMessageManager
-    messageManager.rejectMsg(msgId)
-    if (cb && typeof cb === 'function') {
-      cb(null, this.getState())
-    }
-  }
-
-  cancelTypedMessage (msgId, cb) {
-    const messageManager = this.typedMessageManager
-    messageManager.rejectMsg(msgId)
-    if (cb && typeof cb === 'function') {
-      cb(null, this.getState())
-    }
-  }
-
-  markAccountsFound (cb) {
-    this.configManager.setLostAccounts([])
-    this.sendUpdate()
-    cb(null, this.getState())
-  }
-
-  markPasswordForgotten(cb) {
-    this.configManager.setPasswordForgotten(true)
-    this.sendUpdate()
-    cb()
-  }
-
-  unMarkPasswordForgotten(cb) {
-    this.configManager.setPasswordForgotten(false)
-    this.sendUpdate()
-    cb()
-  }
   
+  // ---------------------------------------------------------------------------
+  // Account Restauration
+
   /**
    * ?
    * 
@@ -952,7 +838,6 @@ module.exports = class MetamaskController extends EventEmitter {
     return Promise.resolve(migratorOutput)
   }
 
-
   /**
    * Import (lost) Accounts
    * 
@@ -969,6 +854,123 @@ module.exports = class MetamaskController extends EventEmitter {
     })
   }
 
+//=============================================================================
+// END (VAULT / KEYRING RELATED METHODS)
+//=============================================================================
+
+
+
+//============================================================================= 
+// MESSAGES
+//=============================================================================  
+
+  async retryTransaction (txId, cb) {
+    await this.txController.retryTransaction(txId)
+    const state = await this.getState()
+    return state
+  }
+
+
+  newUnsignedMessage (msgParams, cb) {
+    const msgId = this.messageManager.addUnapprovedMessage(msgParams)
+    this.sendUpdate()
+    this.opts.showUnconfirmedMessage()
+    this.messageManager.once(`${msgId}:finished`, (data) => {
+      switch (data.status) {
+        case 'signed':
+          return cb(null, data.rawSig)
+        case 'rejected':
+          return cb(new Error('MetaMask Message Signature: User denied message signature.'))
+        default:
+          return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
+      }
+    })
+  }
+
+  newUnsignedPersonalMessage (msgParams, cb) {
+    if (!msgParams.from) {
+      return cb(new Error('MetaMask Message Signature: from field is required.'))
+    }
+
+    const msgId = this.personalMessageManager.addUnapprovedMessage(msgParams)
+    this.sendUpdate()
+    this.opts.showUnconfirmedMessage()
+    this.personalMessageManager.once(`${msgId}:finished`, (data) => {
+      switch (data.status) {
+        case 'signed':
+          return cb(null, data.rawSig)
+        case 'rejected':
+          return cb(new Error('MetaMask Message Signature: User denied message signature.'))
+        default:
+          return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
+      }
+    })
+  }
+
+  newUnsignedTypedMessage (msgParams, cb) {
+    let msgId
+    try {
+      msgId = this.typedMessageManager.addUnapprovedMessage(msgParams)
+      this.sendUpdate()
+      this.opts.showUnconfirmedMessage()
+    } catch (e) {
+      return cb(e)
+    }
+
+    this.typedMessageManager.once(`${msgId}:finished`, (data) => {
+      switch (data.status) {
+        case 'signed':
+          return cb(null, data.rawSig)
+        case 'rejected':
+          return cb(new Error('MetaMask Message Signature: User denied message signature.'))
+        default:
+          return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
+      }
+    })
+  }
+
+  cancelMessage (msgId, cb) {
+    const messageManager = this.messageManager
+    messageManager.rejectMsg(msgId)
+    if (cb && typeof cb === 'function') {
+      cb(null, this.getState())
+    }
+  }  
+
+  cancelPersonalMessage (msgId, cb) {
+    const messageManager = this.personalMessageManager
+    messageManager.rejectMsg(msgId)
+    if (cb && typeof cb === 'function') {
+      cb(null, this.getState())
+    }
+  }
+
+  cancelTypedMessage (msgId, cb) {
+    const messageManager = this.typedMessageManager
+    messageManager.rejectMsg(msgId)
+    if (cb && typeof cb === 'function') {
+      cb(null, this.getState())
+    }
+  }
+
+  markAccountsFound (cb) {
+    this.configManager.setLostAccounts([])
+    this.sendUpdate()
+    cb(null, this.getState())
+  }
+
+  markPasswordForgotten(cb) {
+    this.configManager.setPasswordForgotten(true)
+    this.sendUpdate()
+    cb()
+  }
+
+  unMarkPasswordForgotten(cb) {
+    this.configManager.setPasswordForgotten(false)
+    this.sendUpdate()
+    cb()
+  }
+
 //=============================================================================
 // CONFIG
 //=============================================================================
-- 
cgit 


From bb6af25e20f723942a2b5770a8763bff3b6d6032 Mon Sep 17 00:00:00 2001
From: Lazaridis <info@lazaridis.com>
Date: Fri, 16 Mar 2018 03:22:10 +0200
Subject: add ESLint exceptions for //= and //-, re #3568

---
 app/scripts/metamask-controller.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'app/scripts/metamask-controller.js')

diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index cbdf757c6..953e22fc7 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -858,11 +858,11 @@ module.exports = class MetamaskController extends EventEmitter {
 // END (VAULT / KEYRING RELATED METHODS)
 //=============================================================================
 
+//
 
-
-//============================================================================= 
+//=============================================================================
 // MESSAGES
-//=============================================================================  
+//=============================================================================
 
   async retryTransaction (txId, cb) {
     await this.txController.retryTransaction(txId)
-- 
cgit 


From e1d6398b0fed39e579c0383e34236b30d3154295 Mon Sep 17 00:00:00 2001
From: Lazaridis <info@lazaridis.com>
Date: Fri, 16 Mar 2018 18:37:56 +0200
Subject: moves setup-related code towads end of file, re #3568

---
 app/scripts/metamask-controller.js | 239 +++++++++++++++++++------------------
 1 file changed, 124 insertions(+), 115 deletions(-)

(limited to 'app/scripts/metamask-controller.js')

diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 953e22fc7..18d71874a 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -290,6 +290,9 @@ module.exports = class MetamaskController extends EventEmitter {
     return publicConfigStore
   }
 
+//=============================================================================
+// EXPOSED TO THE UI SUBSYSTEM
+//=============================================================================
 
   /**
    * The metamask-state of the various controllers, made available to the UI
@@ -415,122 +418,7 @@ module.exports = class MetamaskController extends EventEmitter {
     }
   }
 
-  setupUntrustedCommunication (connectionStream, originDomain) {
-    // Check if new connection is blacklisted
-    if (this.blacklistController.checkForPhishing(originDomain)) {
-      log.debug('MetaMask - sending phishing warning for', originDomain)
-      this.sendPhishingWarning(connectionStream, originDomain)
-      return
-    }
-
-    // setup multiplexing
-    const mux = setupMultiplex(connectionStream)
-    // connect features
-    this.setupProviderConnection(mux.createStream('provider'), originDomain)
-    this.setupPublicConfig(mux.createStream('publicConfig'))
-  }
-
-  setupTrustedCommunication (connectionStream, originDomain) {
-    // setup multiplexing
-    const mux = setupMultiplex(connectionStream)
-    // connect features
-    this.setupControllerConnection(mux.createStream('controller'))
-    this.setupProviderConnection(mux.createStream('provider'), originDomain)
-  }
-
-  sendPhishingWarning (connectionStream, hostname) {
-    const mux = setupMultiplex(connectionStream)
-    const phishingStream = mux.createStream('phishing')
-    phishingStream.write({ hostname })
-  }
-
-  setupControllerConnection (outStream) {
-    const api = this.getApi()
-    const dnode = Dnode(api)
-    pump(
-      outStream,
-      dnode,
-      outStream,
-      (err) => {
-        if (err) log.error(err)
-      }
-    )
-    dnode.on('remote', (remote) => {
-      // push updates to popup
-      const sendUpdate = remote.sendUpdate.bind(remote)
-      this.on('update', sendUpdate)
-    })
-  }
-
-  setupProviderConnection (outStream, origin) {
-    // setup json rpc engine stack
-    const engine = new RpcEngine()
 
-    // create filter polyfill middleware
-    const filterMiddleware = createFilterMiddleware({
-      provider: this.provider,
-      blockTracker: this.provider._blockTracker,
-    })
-
-    engine.push(createOriginMiddleware({ origin }))
-    engine.push(createLoggerMiddleware({ origin }))
-    engine.push(filterMiddleware)
-    engine.push(createProviderMiddleware({ provider: this.provider }))
-
-    // setup connection
-    const providerStream = createEngineStream({ engine })
-    pump(
-      outStream,
-      providerStream,
-      outStream,
-      (err) => {
-        // cleanup filter polyfill middleware
-        filterMiddleware.destroy()
-        if (err) log.error(err)
-      }
-    )
-  }
-
-  setupPublicConfig (outStream) {
-    pump(
-      asStream(this.publicConfigStore),
-      outStream,
-      (err) => {
-        if (err) log.error(err)
-      }
-    )
-  }
-
-  privateSendUpdate () {
-    this.emit('update', this.getState())
-  }
-
-  getGasPrice () {
-    const { recentBlocksController } = this
-    const { recentBlocks } = recentBlocksController.store.getState()
-
-    // Return 1 gwei if no blocks have been observed:
-    if (recentBlocks.length === 0) {
-      return '0x' + GWEI_BN.toString(16)
-    }
-
-    const lowestPrices = recentBlocks.map((block) => {
-      if (!block.gasPrices || block.gasPrices.length < 1) {
-        return GWEI_BN
-      }
-      return block.gasPrices
-      .map(hexPrefix => hexPrefix.substr(2))
-      .map(hex => new BN(hex, 16))
-      .sort((a, b) => {
-        return a.gt(b) ? 1 : -1
-      })[0]
-    })
-    .map(number => number.div(GWEI_BN).toNumber())
-
-    const percentileNum = percentile(50, lowestPrices)
-    const percentileNumBn = new BN(percentileNum)
-    return '0x' + percentileNumBn.mul(GWEI_BN).toString(16)
-  }
 
 //=============================================================================
 // VAULT / KEYRING RELATED METHODS
@@ -971,6 +859,127 @@ module.exports = class MetamaskController extends EventEmitter {
     cb()
   }
 
+//=============================================================================
+// SETUP
+//=============================================================================
+
+  setupUntrustedCommunication (connectionStream, originDomain) {
+    // Check if new connection is blacklisted
+    if (this.blacklistController.checkForPhishing(originDomain)) {
+      log.debug('MetaMask - sending phishing warning for', originDomain)
+      this.sendPhishingWarning(connectionStream, originDomain)
+      return
+    }
+
+    // setup multiplexing
+    const mux = setupMultiplex(connectionStream)
+    // connect features
+    this.setupProviderConnection(mux.createStream('provider'), originDomain)
+    this.setupPublicConfig(mux.createStream('publicConfig'))
+  }
+
+  setupTrustedCommunication (connectionStream, originDomain) {
+    // setup multiplexing
+    const mux = setupMultiplex(connectionStream)
+    // connect features
+    this.setupControllerConnection(mux.createStream('controller'))
+    this.setupProviderConnection(mux.createStream('provider'), originDomain)
+  }
+
+  sendPhishingWarning (connectionStream, hostname) {
+    const mux = setupMultiplex(connectionStream)
+    const phishingStream = mux.createStream('phishing')
+    phishingStream.write({ hostname })
+  }
+
+  setupControllerConnection (outStream) {
+    const api = this.getApi()
+    const dnode = Dnode(api)
+    pump(
+      outStream,
+      dnode,
+      outStream,
+      (err) => {
+        if (err) log.error(err)
+      }
+    )
+    dnode.on('remote', (remote) => {
+      // push updates to popup
+      const sendUpdate = remote.sendUpdate.bind(remote)
+      this.on('update', sendUpdate)
+    })
+  }
+
+  setupProviderConnection (outStream, origin) {
+    // setup json rpc engine stack
+    const engine = new RpcEngine()
+
+    // create filter polyfill middleware
+    const filterMiddleware = createFilterMiddleware({
+      provider: this.provider,
+      blockTracker: this.provider._blockTracker,
+    })
+
+    engine.push(createOriginMiddleware({ origin }))
+    engine.push(createLoggerMiddleware({ origin }))
+    engine.push(filterMiddleware)
+    engine.push(createProviderMiddleware({ provider: this.provider }))
+
+    // setup connection
+    const providerStream = createEngineStream({ engine })
+    pump(
+      outStream,
+      providerStream,
+      outStream,
+      (err) => {
+        // cleanup filter polyfill middleware
+        filterMiddleware.destroy()
+        if (err) log.error(err)
+      }
+    )
+  }
+
+  setupPublicConfig (outStream) {
+    pump(
+      asStream(this.publicConfigStore),
+      outStream,
+      (err) => {
+        if (err) log.error(err)
+      }
+    )
+  }
+
+  privateSendUpdate () {
+    this.emit('update', this.getState())
+  }
+
+  getGasPrice () {
+    const { recentBlocksController } = this
+    const { recentBlocks } = recentBlocksController.store.getState()
+
+    // Return 1 gwei if no blocks have been observed:
+    if (recentBlocks.length === 0) {
+      return '0x' + GWEI_BN.toString(16)
+    }
+
+    const lowestPrices = recentBlocks.map((block) => {
+      if (!block.gasPrices || block.gasPrices.length < 1) {
+        return GWEI_BN
+      }
+      return block.gasPrices
+      .map(hexPrefix => hexPrefix.substr(2))
+      .map(hex => new BN(hex, 16))
+      .sort((a, b) => {
+        return a.gt(b) ? 1 : -1
+      })[0]
+    })
+    .map(number => number.div(GWEI_BN).toNumber())
+
+    const percentileNum = percentile(50, lowestPrices)
+    const percentileNumBn = new BN(percentileNum)
+    return '0x' + percentileNumBn.mul(GWEI_BN).toString(16)
+  }  
+
 //=============================================================================
 // CONFIG
 //=============================================================================
-- 
cgit