diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js
index fd032a673..de6e8b811 100644
--- a/app/scripts/lib/inpage-provider.js
+++ b/app/scripts/lib/inpage-provider.js
@@ -1,8 +1,8 @@
 const pipe = require('pump')
-const StreamProvider = require('web3-stream-provider')
+const RpcEngine = require('json-rpc-engine')
+const createStreamMiddleware = require('json-rpc-middleware-stream')
 const LocalStorageStore = require('obs-store')
 const ObjectMultiplex = require('./obj-multiplex')
-const createRandomId = require('./random-id')
 
 module.exports = MetamaskInpageProvider
 
@@ -30,38 +30,20 @@ function MetamaskInpageProvider (connectionStream) {
   multiStream.ignoreStream('phishing') 
 
   // connect to async provider
-  const asyncProvider = self.asyncProvider = new StreamProvider()
+  const streamMiddleware = createStreamMiddleware()
   pipe(
-    asyncProvider,
+    streamMiddleware.stream,
     multiStream.createStream('provider'),
-    asyncProvider,
+    streamMiddleware.stream,
     (err) => logStreamDisconnectWarning('MetaMask RpcProvider', err)
   )
   // start and stop polling to unblock first block lock
 
-  self.idMap = {}
-  // handle sendAsync requests via asyncProvider
-  self.sendAsync = function (payload, cb) {
-    // rewrite request ids
-    var request = eachJsonMessage(payload, (message) => {
-      var newId = createRandomId()
-      self.idMap[newId] = message.id
-      message.id = newId
-      return message
-    })
-    // forward to asyncProvider
-    asyncProvider.sendAsync(request, function (err, res) {
-      if (err) return cb(err)
-      // transform messages to original ids
-      eachJsonMessage(res, (message) => {
-        var oldId = self.idMap[message.id]
-        delete self.idMap[message.id]
-        message.id = oldId
-        return message
-      })
-      cb(null, res)
-    })
-  }
+  // handle sendAsync requests via dapp-side rpc engine
+  const engine = new RpcEngine()
+  engine.push(streamMiddleware)
+
+  self.sendAsync = engine.handle.bind(engine)
 }
 
 MetamaskInpageProvider.prototype.send = function (payload) {
@@ -121,14 +103,6 @@ MetamaskInpageProvider.prototype.isMetaMask = true
 
 // util
 
-function eachJsonMessage (payload, transformFn) {
-  if (Array.isArray(payload)) {
-    return payload.map(transformFn)
-  } else {
-    return transformFn(payload)
-  }
-}
-
 function logStreamDisconnectWarning (remoteLabel, err) {
   let warningMsg = `MetamaskInpageProvider - lost connection to ${remoteLabel}`
   if (err) warningMsg += '\n' + err.stack
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index a007d6fc5..e4b1b5975 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -6,7 +6,8 @@ const Dnode = require('dnode')
 const ObservableStore = require('obs-store')
 const EthStore = require('./lib/eth-store')
 const EthQuery = require('eth-query')
-const streamIntoProvider = require('web3-stream-provider/handler')
+const RpcEngine = require('json-rpc-engine')
+const createEngineStream = require('json-rpc-middleware-stream/engineStream')
 const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
 const KeyringController = require('./keyring-controller')
 const NetworkController = require('./controllers/network')
@@ -375,19 +376,40 @@ module.exports = class MetamaskController extends EventEmitter {
   }
 
   setupProviderConnection (outStream, originDomain) {
-    streamIntoProvider(outStream, this.provider, onRequest, onResponse)
+    const engine = new RpcEngine()
+    engine.push(originMiddleware)
+    engine.push(loggerMiddleware)
+    engine.push(createProviderMiddleware({ provider: this.provider }))
+    
+    // setup connection
+    const providerStream = createEngineStream({ engine })
+    outStream.pipe(providerStream).pipe(outStream)
+    
     // append dapp origin domain to request
-    function onRequest (request) {
-      request.origin = originDomain
+    function originMiddleware (req, res, next, end) {
+      req.origin = originDomain
+      next()
     }
     // log rpc activity
-    function onResponse (err, request, response) {
-      if (err) return console.error(err)
-      if (response.error) {
-        console.error('Error in RPC response:\n', response)
+    function loggerMiddleware (req, res, next, end) {
+      next((cb) => {
+        if (res.error) {
+          console.error('Error in RPC response:\n', res)
+        }
+        if (req.isMetamaskInternal) return
+        log.info(`RPC (${originDomain}):`, req, '->', res)
+        cb()
+      })
+    }
+    // forward requests to provider
+    function createProviderMiddleware({ provider }) {
+      return (req, res, next, end) => {
+        provider.sendAsync(req, (err, _res) => {
+          if (err) return end(err)
+          res.result = _res.result
+          end()
+        })
       }
-      if (request.isMetamaskInternal) return
-      log.info(`RPC (${originDomain}):`, request, '->', response)
     }
   }
 
diff --git a/package.json b/package.json
index 9a09e6305..a0d241341 100644
--- a/package.json
+++ b/package.json
@@ -93,6 +93,7 @@
     "iframe-stream": "^3.0.0",
     "inject-css": "^0.1.1",
     "jazzicon": "^1.2.0",
+    "json-rpc-middleware-stream": "^1.0.0",
     "loglevel": "^1.4.1",
     "metamask-logo": "^2.1.2",
     "mississippi": "^1.2.0",