mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
inpage - automatic dapp reload
This commit is contained in:
parent
b863fe16e8
commit
aa2816010d
@ -1,5 +1,7 @@
|
||||
const LocalMessageDuplexStream = require('./lib/local-message-stream.js')
|
||||
const PortStream = require('./lib/port-stream.js')
|
||||
const ObjectMultiplex = require('./lib/obj-multiplex')
|
||||
|
||||
|
||||
|
||||
// inject in-page script
|
||||
@ -15,13 +17,22 @@ var pageStream = new LocalMessageDuplexStream({
|
||||
name: 'contentscript',
|
||||
target: 'inpage',
|
||||
})
|
||||
pageStream.on('error', console.error.bind(console))
|
||||
var pluginPort = chrome.runtime.connect({name: 'contentscript'})
|
||||
var pluginStream = new PortStream(pluginPort)
|
||||
pluginStream.on('error', console.error.bind(console))
|
||||
|
||||
// forward communication across
|
||||
pageStream.pipe(pluginStream)
|
||||
pluginStream.pipe(pageStream)
|
||||
// forward communication plugin->inpage
|
||||
pageStream.pipe(pluginStream).pipe(pageStream)
|
||||
|
||||
// log errors
|
||||
pageStream.on('error', console.error.bind(console))
|
||||
pluginStream.on('error', console.error.bind(console))
|
||||
// connect contentscript->inpage control stream
|
||||
var mx = ObjectMultiplex()
|
||||
mx.on('error', console.error.bind(console))
|
||||
mx.pipe(pageStream)
|
||||
var controlStream = mx.createStream('control')
|
||||
controlStream.on('error', console.error.bind(console))
|
||||
|
||||
// if we lose connection with the plugin, trigger tab refresh
|
||||
pluginStream.on('close', function(){
|
||||
controlStream.write({ method: 'reset' })
|
||||
})
|
@ -5,6 +5,7 @@ const LocalMessageDuplexStream = require('./lib/local-message-stream.js')
|
||||
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
|
||||
const RemoteStore = require('./lib/remote-store.js').RemoteStore
|
||||
const Web3 = require('web3')
|
||||
const once = require('once')
|
||||
restoreContextAfterImports()
|
||||
|
||||
// rename on window
|
||||
@ -24,32 +25,61 @@ var pluginStream = new LocalMessageDuplexStream({
|
||||
target: 'contentscript',
|
||||
})
|
||||
var mx = setupMultiplex(pluginStream)
|
||||
// connect features
|
||||
|
||||
// connect to provider
|
||||
var remoteProvider = new StreamProvider()
|
||||
remoteProvider.pipe(mx.createStream('provider')).pipe(remoteProvider)
|
||||
remoteProvider.on('error', console.error.bind(console))
|
||||
|
||||
// subscribe to metamask public config
|
||||
var initState = JSON.parse(localStorage['MetaMask-Config'] || '{}')
|
||||
var publicConfigStore = new RemoteStore(initState)
|
||||
var storeStream = publicConfigStore.createStream()
|
||||
storeStream.pipe(mx.createStream('publicConfig')).pipe(storeStream)
|
||||
|
||||
publicConfigStore.subscribe(function(state){
|
||||
localStorage['MetaMask-Config'] = JSON.stringify(state)
|
||||
})
|
||||
|
||||
|
||||
//
|
||||
// global web3
|
||||
// setup web3
|
||||
//
|
||||
|
||||
var web3 = new Web3(remoteProvider)
|
||||
window.web3 = web3
|
||||
web3.setProvider = function(){
|
||||
console.log('MetaMask - overrode web3.setProvider')
|
||||
}
|
||||
console.log('MetaMask - injected web3')
|
||||
|
||||
//
|
||||
// automatic dapp reset
|
||||
//
|
||||
|
||||
// export web3 as a global, checking for usage
|
||||
var pageIsUsingWeb3 = false
|
||||
var resetWasRequested = false
|
||||
window.web3 = ensnare(web3, once(function(){
|
||||
// if web3 usage happened after a reset request, trigger reset late
|
||||
if (resetWasRequested) return triggerReset()
|
||||
// mark web3 as used
|
||||
pageIsUsingWeb3 = true
|
||||
// reset web3 reference
|
||||
window.web3 = web3
|
||||
}))
|
||||
|
||||
// listen for reset requests
|
||||
mx.createStream('control').once('data', function(){
|
||||
resetWasRequested = true
|
||||
// ignore if web3 was not used
|
||||
if (!pageIsUsingWeb3) return
|
||||
// reload after short timeout
|
||||
triggerReset()
|
||||
})
|
||||
|
||||
function triggerReset(){
|
||||
setTimeout(function(){
|
||||
window.location.reload()
|
||||
}, 500)
|
||||
}
|
||||
|
||||
//
|
||||
// handle synchronous requests
|
||||
@ -104,6 +134,34 @@ remoteProvider.send = function(payload){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// util
|
||||
//
|
||||
|
||||
// creates a proxy object that calls cb everytime the obj's properties/fns are accessed
|
||||
function ensnare(obj, cb){
|
||||
var proxy = {}
|
||||
Object.keys(obj).forEach(function(key){
|
||||
var val = obj[key]
|
||||
switch (typeof val) {
|
||||
case 'function':
|
||||
proxy[key] = function(){
|
||||
cb()
|
||||
val.apply(obj, arguments)
|
||||
}
|
||||
return
|
||||
default:
|
||||
Object.defineProperty(proxy, key, {
|
||||
get: function(){ cb(); return obj[key] },
|
||||
set: function(val){ cb(); return obj[key] = val },
|
||||
})
|
||||
return
|
||||
}
|
||||
})
|
||||
return proxy
|
||||
}
|
||||
|
||||
// need to make sure we aren't affected by overlapping namespaces
|
||||
// and that we dont affect the app with our namespace
|
||||
// mostly a fix for web3's BigNumber if AMD's "define" is defined...
|
||||
@ -116,4 +174,4 @@ function cleanContextForImports(){
|
||||
|
||||
function restoreContextAfterImports(){
|
||||
global.define = __define
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ function LocalMessageDuplexStream(opts){
|
||||
|
||||
LocalMessageDuplexStream.prototype._onMessage = function(event){
|
||||
var msg = event.data
|
||||
// console.log('LocalMessageDuplexStream ('+this._name+') - heard message...')
|
||||
// console.log('LocalMessageDuplexStream ('+this._name+') - heard message...', event)
|
||||
// validate message
|
||||
if (event.origin !== location.origin) return //console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (event.origin !== location.origin) ')
|
||||
if (typeof msg !== 'object') return //console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (typeof msg !== "object") ')
|
||||
@ -31,7 +31,11 @@ LocalMessageDuplexStream.prototype._onMessage = function(event){
|
||||
if (!msg.data) return //console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (!msg.data) ')
|
||||
// console.log('LocalMessageDuplexStream ('+this._name+') - accepted', msg.data)
|
||||
// forward message
|
||||
this.push(msg.data)
|
||||
try {
|
||||
this.push(msg.data)
|
||||
} catch(err) {
|
||||
this.emit('error', err)
|
||||
}
|
||||
}
|
||||
|
||||
// stream plumbing
|
||||
|
@ -31,7 +31,8 @@ PortDuplexStream.prototype._onMessage = function(msg){
|
||||
|
||||
PortDuplexStream.prototype._onDisconnect = function(){
|
||||
try {
|
||||
this.end()
|
||||
// this.end()
|
||||
this.emit('close')
|
||||
} catch(err){
|
||||
this.emit('error', err)
|
||||
}
|
||||
@ -54,6 +55,7 @@ PortDuplexStream.prototype._write = function(msg, encoding, cb){
|
||||
}
|
||||
cb()
|
||||
} catch(err){
|
||||
console.error(err)
|
||||
// this.emit('error', err)
|
||||
cb(new Error('PortDuplexStream - disconnected'))
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ function setupMultiplex(connectionStream){
|
||||
connectionStream.pipe(mx).pipe(connectionStream)
|
||||
mx.on('error', function(err) {
|
||||
console.error(err)
|
||||
// connectionStream.destroy()
|
||||
})
|
||||
connectionStream.on('error', function(err) {
|
||||
console.error(err)
|
||||
|
@ -38,6 +38,7 @@
|
||||
"inject-css": "^0.1.1",
|
||||
"metamask-logo": "^1.1.5",
|
||||
"multiplex": "^6.7.0",
|
||||
"once": "^1.3.3",
|
||||
"pojo-migrator": "^2.1.0",
|
||||
"polyfill-crypto.getrandomvalues": "^1.0.0",
|
||||
"pumpify": "^1.3.4",
|
||||
@ -46,7 +47,7 @@
|
||||
"react-dom": "^0.14.3",
|
||||
"react-hyperscript": "^2.2.2",
|
||||
"react-redux": "^4.0.3",
|
||||
"readable-stream": "^2.0.5",
|
||||
"readable-stream": "^2.1.2",
|
||||
"redux": "^3.0.5",
|
||||
"redux-logger": "^2.3.1",
|
||||
"redux-thunk": "^1.0.2",
|
||||
|
Loading…
Reference in New Issue
Block a user