aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorkumavis <aaron@kumavis.me>2016-05-06 07:04:43 +0800
committerkumavis <aaron@kumavis.me>2016-05-06 07:04:43 +0800
commitaa2816010dc724e3976dc3e639179221cdce7d66 (patch)
tree11bf4022de245eb8f48668bf7e6f666ba06dbeb5 /app
parentb863fe16e885e8548f371898532c914a6540ebed (diff)
downloadtangerine-wallet-browser-aa2816010dc724e3976dc3e639179221cdce7d66.tar
tangerine-wallet-browser-aa2816010dc724e3976dc3e639179221cdce7d66.tar.gz
tangerine-wallet-browser-aa2816010dc724e3976dc3e639179221cdce7d66.tar.bz2
tangerine-wallet-browser-aa2816010dc724e3976dc3e639179221cdce7d66.tar.lz
tangerine-wallet-browser-aa2816010dc724e3976dc3e639179221cdce7d66.tar.xz
tangerine-wallet-browser-aa2816010dc724e3976dc3e639179221cdce7d66.tar.zst
tangerine-wallet-browser-aa2816010dc724e3976dc3e639179221cdce7d66.zip
inpage - automatic dapp reload
Diffstat (limited to 'app')
-rw-r--r--app/scripts/contentscript.js23
-rw-r--r--app/scripts/inpage.js70
-rw-r--r--app/scripts/lib/local-message-stream.js8
-rw-r--r--app/scripts/lib/port-stream.js4
-rw-r--r--app/scripts/lib/stream-utils.js1
5 files changed, 90 insertions, 16 deletions
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index a256a3f5b..1b7b98ec9 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -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)) \ No newline at end of file
+// 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' })
+}) \ No newline at end of file
diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js
index 54470220f..33e2c9358 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -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
-} \ No newline at end of file
+}
diff --git a/app/scripts/lib/local-message-stream.js b/app/scripts/lib/local-message-stream.js
index 42d193e04..76fedd9df 100644
--- a/app/scripts/lib/local-message-stream.js
+++ b/app/scripts/lib/local-message-stream.js
@@ -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
diff --git a/app/scripts/lib/port-stream.js b/app/scripts/lib/port-stream.js
index a6c974d6d..2644741fc 100644
--- a/app/scripts/lib/port-stream.js
+++ b/app/scripts/lib/port-stream.js
@@ -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'))
}
diff --git a/app/scripts/lib/stream-utils.js b/app/scripts/lib/stream-utils.js
index fd4417d94..ca245ca9a 100644
--- a/app/scripts/lib/stream-utils.js
+++ b/app/scripts/lib/stream-utils.js
@@ -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)