nifty-wallet/app/scripts/lib/inpage-provider.js

135 lines
3.7 KiB
JavaScript
Raw Normal View History

2017-01-24 19:47:00 -08:00
const pipe = require('pump')
2016-05-22 18:02:27 -07:00
const StreamProvider = require('web3-stream-provider')
2017-01-24 19:47:00 -08:00
const LocalStorageStore = require('obs-store')
const ObjectMultiplex = require('./obj-multiplex')
const createRandomId = require('./random-id')
2016-05-22 15:23:16 -07:00
module.exports = MetamaskInpageProvider
2016-06-21 13:18:32 -07:00
function MetamaskInpageProvider (connectionStream) {
2016-05-22 15:23:16 -07:00
const self = this
2016-06-21 13:18:32 -07:00
// setup connectionStream multiplexing
2017-01-24 19:47:00 -08:00
var multiStream = self.multiStream = ObjectMultiplex()
pipe(
connectionStream,
multiStream,
connectionStream,
(err) => logStreamDisconnectWarning('MetaMask', err)
)
// subscribe to metamask public config (one-way)
self.publicConfigStore = new LocalStorageStore({ storageKey: 'MetaMask-Config' })
pipe(
multiStream.createStream('publicConfig'),
self.publicConfigStore,
(err) => logStreamDisconnectWarning('MetaMask PublicConfigStore', err)
)
2016-05-22 15:23:16 -07:00
// connect to async provider
2017-01-24 19:47:00 -08:00
const asyncProvider = self.asyncProvider = new StreamProvider()
pipe(
asyncProvider,
multiStream.createStream('provider'),
asyncProvider,
(err) => logStreamDisconnectWarning('MetaMask RpcProvider', err)
)
2016-10-05 11:10:39 -07:00
2016-08-31 15:40:05 -07:00
self.idMap = {}
// handle sendAsync requests via asyncProvider
2016-11-11 10:26:12 -08:00
self.sendAsync = function (payload, cb) {
// rewrite request ids
2016-08-31 15:40:05 -07:00
var request = eachJsonMessage(payload, (message) => {
var newId = createRandomId()
self.idMap[newId] = message.id
message.id = newId
return message
})
// forward to asyncProvider
2016-11-11 10:26:12 -08:00
asyncProvider.sendAsync(request, function (err, res) {
2016-08-31 15:40:05 -07:00
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)
})
}
2016-05-22 15:23:16 -07:00
}
2016-06-21 13:18:32 -07:00
MetamaskInpageProvider.prototype.send = function (payload) {
2016-05-22 15:23:16 -07:00
const self = this
2016-10-05 11:10:39 -07:00
let selectedAddress
2016-08-11 13:31:00 -07:00
let result = null
2016-05-22 15:23:16 -07:00
switch (payload.method) {
case 'eth_accounts':
// read from localStorage
selectedAddress = self.publicConfigStore.getState().selectedAddress
result = selectedAddress ? [selectedAddress] : []
2016-05-22 15:23:16 -07:00
break
case 'eth_coinbase':
// read from localStorage
selectedAddress = self.publicConfigStore.getState().selectedAddress
result = selectedAddress
2016-05-22 15:23:16 -07:00
break
2016-11-23 10:48:20 -08:00
case 'eth_uninstallFilter':
self.sendAsync(payload, noop)
result = true
break
case 'net_version':
let networkVersion = self.publicConfigStore.getState().networkVersion
result = networkVersion
break
// throw not-supported Error
2016-05-22 15:23:16 -07:00
default:
2016-10-05 11:10:39 -07:00
var link = 'https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#dizzy-all-async---think-of-metamask-as-a-light-client'
var message = `The MetaMask Web3 object does not support synchronous methods like ${payload.method} without a callback parameter. See ${link} for details.`
throw new Error(message)
2016-05-22 15:23:16 -07:00
}
// return the result
return {
id: payload.id,
jsonrpc: payload.jsonrpc,
result: result,
}
}
2016-06-21 13:18:32 -07:00
MetamaskInpageProvider.prototype.sendAsync = function () {
2016-05-22 15:23:16 -07:00
throw new Error('MetamaskInpageProvider - sendAsync not overwritten')
}
2016-06-21 13:18:32 -07:00
MetamaskInpageProvider.prototype.isConnected = function () {
2016-05-22 15:23:16 -07:00
return true
}
MetamaskInpageProvider.prototype.isMetaMask = true
2016-05-22 15:23:16 -07:00
// util
2016-11-18 16:27:26 -08:00
function eachJsonMessage (payload, transformFn) {
if (Array.isArray(payload)) {
return payload.map(transformFn)
} else {
return transformFn(payload)
}
2016-09-05 20:20:22 -07:00
}
2016-11-23 10:48:20 -08:00
2017-01-24 19:47:00 -08:00
function logStreamDisconnectWarning(remoteLabel, err){
let warningMsg = `MetamaskInpageProvider - lost connection to ${remoteLabel}`
if (err) warningMsg += '\n' + err.stack
console.warn(warningMsg)
}
2016-11-23 10:48:20 -08:00
function noop () {}