From 23a144fb8b0b214b9c352ee523405d5ecd03046e Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 26 Aug 2016 11:08:23 -0700 Subject: [PATCH 01/15] library - popup handler demo --- library/example.sh | 4 +++ library/example/README.md | 5 +++ library/example/index.html | 17 +++++++++ library/example/index.js | 42 ++++++++++++++++++++++ library/frame.js | 67 +++++++++++++++++++++++++++++++++++ library/index.html | 20 +++++++++++ library/index.js | 42 ++++++++++++++++++++++ library/lib/setup-iframe.js | 18 ++++++++++ library/lib/setup-provider.js | 24 +++++++++++++ package.json | 2 ++ 10 files changed, 241 insertions(+) create mode 100755 library/example.sh create mode 100644 library/example/README.md create mode 100644 library/example/index.html create mode 100644 library/example/index.js create mode 100644 library/frame.js create mode 100644 library/index.html create mode 100644 library/index.js create mode 100644 library/lib/setup-iframe.js create mode 100644 library/lib/setup-provider.js diff --git a/library/example.sh b/library/example.sh new file mode 100755 index 000000000..73f9cd20c --- /dev/null +++ b/library/example.sh @@ -0,0 +1,4 @@ +# run 2 servers and make sure they close together + +beefy frame.js:bundle.js 9001 --live & +beefy example/index.js:bundle.js index.js:zero.js --cwd example/ 9002 --live --open \ No newline at end of file diff --git a/library/example/README.md b/library/example/README.md new file mode 100644 index 000000000..2a5a1cce0 --- /dev/null +++ b/library/example/README.md @@ -0,0 +1,5 @@ +``` +trap 'kill %1' SIGINT +beefy frame.js:bundle.js 9001 --live & \ +beefy example/index.js:bundle.js index.js:zero.js --cwd example/ 9002 --live --open +``` \ No newline at end of file diff --git a/library/example/index.html b/library/example/index.html new file mode 100644 index 000000000..aa15a4523 --- /dev/null +++ b/library/example/index.html @@ -0,0 +1,17 @@ + + + + + + + MetaMask ZeroClient Example + + + + + + + + + + \ No newline at end of file diff --git a/library/example/index.js b/library/example/index.js new file mode 100644 index 000000000..d24c26f87 --- /dev/null +++ b/library/example/index.js @@ -0,0 +1,42 @@ + +window.addEventListener('load', web3Detect) + +function web3Detect() { + if (global.web3) { + document.body.innerHTML += 'web3 detected!' + } else { + document.body.innerHTML += 'no web3 detected!' + } + startApp() +} + +var primaryAccount = null +web3.eth.getAccounts(function(err, addresses){ + if (err) throw err + primaryAccount = addresses[0] +}) + + +function startApp(){ + document.querySelector('.action-button-1').addEventListener('click', function(){ + web3.eth.sendTransaction({ + from: primaryAccount, + value: 0, + }, function(err, txHash){ + if (err) throw err + console.log('sendTransaction result:', err || txHash) + }) + }) + document.querySelector('.action-button-2').addEventListener('click', function(){ + setTimeout(function(){ + web3.eth.sendTransaction({ + from: primaryAccount, + value: 0, + }, function(err, txHash){ + if (err) throw err + console.log('sendTransaction result:', err || txHash) + }) + }) + }) + +} diff --git a/library/frame.js b/library/frame.js new file mode 100644 index 000000000..db5baf36a --- /dev/null +++ b/library/frame.js @@ -0,0 +1,67 @@ +const ZeroClientProvider = require('web3-provider-engine/zero') +const ParentStream = require('iframe-stream').ParentStream +const handleRequestsFromStream = require('web3-stream-provider/handler') +const Streams = require('mississippi') +const ObjectMultiplex = require('../app/scripts/lib/obj-multiplex') + +console.log('yes, this is iframe') + +initializeZeroClient() + + +function initializeZeroClient() { + + var provider = ZeroClientProvider({ + // rpcUrl: configManager.getCurrentRpcAddress(), + rpcUrl: 'https://morden.infura.io/', + // account mgmt + // getAccounts: function(cb){ + // var selectedAddress = idStore.getSelectedAddress() + // var result = selectedAddress ? [selectedAddress] : [] + // cb(null, result) + // }, + getAccounts: function(cb){ + cb(null, ['0x8F331A98aC5C9431d04A5d6Bf8Fa84ed7Ed439f3'.toLowerCase()]) + }, + // tx signing + // approveTransaction: addUnconfirmedTx, + // signTransaction: idStore.signTransaction.bind(idStore), + signTransaction: function(txParams, cb){ + var privKey = new Buffer('7ef33e339ba5a5af0e57fa900ad0ae53deaa978c21ef30a0947532135eb639a8', 'hex') + var Transaction = require('ethereumjs-tx') + console.log('signing tx:', txParams) + txParams.gasLimit = txParams.gas + var tx = new Transaction(txParams) + tx.sign(privKey) + var serialiedTx = '0x'+tx.serialize().toString('hex') + cb(null, serialiedTx) + }, + // msg signing + // approveMessage: addUnconfirmedMsg, + // signMessage: idStore.signMessage.bind(idStore), + }) + + provider.on('block', function(block){ + console.log('BLOCK CHANGED:', '#'+block.number.toString('hex'), '0x'+block.hash.toString('hex')) + }) + + var connectionStream = new ParentStream() + // setup connectionStream multiplexing + var multiStream = ObjectMultiplex() + Streams.pipe(connectionStream, multiStream, connectionStream, function(err){ + console.warn('MetamaskIframe - lost connection to Dapp') + if (err) throw err + }) + + var providerStream = multiStream.createStream('provider') + handleRequestsFromStream(providerStream, provider, logger) + + function logger(err, request, response){ + if (err) return console.error(err.stack) + if (!request.isMetamaskInternal) { + console.log('MetaMaskIframe - RPC complete:', request, '->', response) + if (response.error) console.error('Error in RPC response:\n'+response.error.message) + } + } + +} \ No newline at end of file diff --git a/library/index.html b/library/index.html new file mode 100644 index 000000000..5a4c66544 --- /dev/null +++ b/library/index.html @@ -0,0 +1,20 @@ + + + + + + + MetaMask ZeroClient Iframe + + + + + + + + Hello! I am the MetaMask iframe. + + + \ No newline at end of file diff --git a/library/index.js b/library/index.js new file mode 100644 index 000000000..9991462ab --- /dev/null +++ b/library/index.js @@ -0,0 +1,42 @@ +const Web3 = require('web3') +const setupProvider = require('./lib/setup-provider.js') + +// +// setup web3 +// + +var provider = setupProvider() +hijackProvider(provider) +var web3 = new Web3(provider) +web3.setProvider = function(){ + console.log('MetaMask - overrode web3.setProvider') +} + +// +// export web3 +// + +global.web3 = web3 + +// +// ui stuff +// + +var shouldPop = false +window.addEventListener('click', function(){ + if (!shouldPop) return + shouldPop = false + window.open('popup.html', '', 'width=1000') + console.log('opening window...') +}) + + +function hijackProvider(provider){ + var _super = provider.sendAsync.bind(provider) + provider.sendAsync = function(payload, cb){ + if (payload.method === 'eth_sendTransaction') { + shouldPop = true + } + _super(payload, cb) + } +} \ No newline at end of file diff --git a/library/lib/setup-iframe.js b/library/lib/setup-iframe.js new file mode 100644 index 000000000..dfb51c676 --- /dev/null +++ b/library/lib/setup-iframe.js @@ -0,0 +1,18 @@ +const Iframe = require('iframe') +const IframeStream = require('iframe-stream').IframeStream + +module.exports = setupIframe + + +function setupIframe(opts) { + opts = opts || {} + var frame = Iframe({ + src: opts.zeroClientProvider || 'https://zero.metamask.io/', + container: document.head, + sandboxAttributes: opts.sandboxAttributes || ['allow-scripts', 'allow-popups'], + }) + var iframe = frame.iframe + var iframeStream = new IframeStream(iframe) + + return iframeStream +} diff --git a/library/lib/setup-provider.js b/library/lib/setup-provider.js new file mode 100644 index 000000000..ced07e0f0 --- /dev/null +++ b/library/lib/setup-provider.js @@ -0,0 +1,24 @@ +const setupIframe = require('./setup-iframe.js') +const MetamaskInpageProvider = require('../../app/scripts/lib/inpage-provider.js') + +module.exports = getProvider + + +function getProvider(){ + + if (global.web3) { + console.log('MetaMask ZeroClient - using environmental web3 provider') + return global.web3.currentProvider + } + + console.log('MetaMask ZeroClient - injecting zero-client iframe!') + var iframeStream = setupIframe({ + zeroClientProvider: 'http://localhost:9001', + sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], + }) + + var inpageProvider = new MetamaskInpageProvider(iframeStream) + return inpageProvider + +} + diff --git a/package.json b/package.json index fdf6c822e..4c30db1a1 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,8 @@ "gulp-eslint": "^2.0.0", "hat": "0.0.3", "identicon.js": "^1.2.1", + "iframe": "^1.0.0", + "iframe-stream": "^1.0.2", "inject-css": "^0.1.1", "jazzicon": "^1.1.3", "menu-droppo": "^1.1.0", From b7aab955196a7cef2705e8546814b5c6c1830da7 Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 26 Aug 2016 17:39:19 -0700 Subject: [PATCH 02/15] library - basic test server + partial safari fixes --- library/{frame.js => controller.js} | 2 + library/example.sh | 4 +- library/example/index.html | 2 +- library/example/index.js | 9 +++ library/index.js | 4 ++ library/lib/setup-iframe.js | 3 +- library/lib/setup-provider.js | 3 +- library/server.js | 88 +++++++++++++++++++++++++++++ library/{ => server}/index.html | 2 +- package.json | 5 +- 10 files changed, 114 insertions(+), 8 deletions(-) rename library/{frame.js => controller.js} (97%) create mode 100644 library/server.js rename library/{ => server}/index.html (88%) diff --git a/library/frame.js b/library/controller.js similarity index 97% rename from library/frame.js rename to library/controller.js index db5baf36a..90d849d20 100644 --- a/library/frame.js +++ b/library/controller.js @@ -53,6 +53,8 @@ function initializeZeroClient() { if (err) throw err }) + multiStream.on('data', function(chunk){ console.log(chunk) }) + var providerStream = multiStream.createStream('provider') handleRequestsFromStream(providerStream, provider, logger) diff --git a/library/example.sh b/library/example.sh index 73f9cd20c..09389d404 100755 --- a/library/example.sh +++ b/library/example.sh @@ -1,4 +1,4 @@ # run 2 servers and make sure they close together -beefy frame.js:bundle.js 9001 --live & -beefy example/index.js:bundle.js index.js:zero.js --cwd example/ 9002 --live --open \ No newline at end of file +beefy frame.js:bundle.js 9001 --live -- -t [ babelify --global --presets [ es2015 ] ] & +beefy example/index.js:bundle.js index.js:zero.js --cwd example/ 9002 --live --open -- -t [ babelify --global --presets [ es2015 ] ] \ No newline at end of file diff --git a/library/example/index.html b/library/example/index.html index aa15a4523..47d6da34f 100644 --- a/library/example/index.html +++ b/library/example/index.html @@ -12,6 +12,6 @@ - + \ No newline at end of file diff --git a/library/example/index.js b/library/example/index.js index d24c26f87..bdde2b47f 100644 --- a/library/example/index.js +++ b/library/example/index.js @@ -4,8 +4,10 @@ window.addEventListener('load', web3Detect) function web3Detect() { if (global.web3) { document.body.innerHTML += 'web3 detected!' + console.log('web3 detected!') } else { document.body.innerHTML += 'no web3 detected!' + console.log('no web3 detected!') } startApp() } @@ -13,12 +15,17 @@ function web3Detect() { var primaryAccount = null web3.eth.getAccounts(function(err, addresses){ if (err) throw err + console.log('set address') primaryAccount = addresses[0] }) function startApp(){ + console.log('app started') + document.querySelector('.action-button-1').addEventListener('click', function(){ + console.log('saw click') + console.log('sending tx') web3.eth.sendTransaction({ from: primaryAccount, value: 0, @@ -28,7 +35,9 @@ function startApp(){ }) }) document.querySelector('.action-button-2').addEventListener('click', function(){ + console.log('saw click') setTimeout(function(){ + console.log('sending tx') web3.eth.sendTransaction({ from: primaryAccount, value: 0, diff --git a/library/index.js b/library/index.js index 9991462ab..c98035106 100644 --- a/library/index.js +++ b/library/index.js @@ -6,11 +6,14 @@ const setupProvider = require('./lib/setup-provider.js') // var provider = setupProvider() +console.log('debugger point A') hijackProvider(provider) +console.log('debugger point B') var web3 = new Web3(provider) web3.setProvider = function(){ console.log('MetaMask - overrode web3.setProvider') } +console.log('metamask lib hijacked provider') // // export web3 @@ -35,6 +38,7 @@ function hijackProvider(provider){ var _super = provider.sendAsync.bind(provider) provider.sendAsync = function(payload, cb){ if (payload.method === 'eth_sendTransaction') { + console.log('saw send') shouldPop = true } _super(payload, cb) diff --git a/library/lib/setup-iframe.js b/library/lib/setup-iframe.js index dfb51c676..db67163df 100644 --- a/library/lib/setup-iframe.js +++ b/library/lib/setup-iframe.js @@ -8,10 +8,11 @@ function setupIframe(opts) { opts = opts || {} var frame = Iframe({ src: opts.zeroClientProvider || 'https://zero.metamask.io/', - container: document.head, + container: opts.container || document.head, sandboxAttributes: opts.sandboxAttributes || ['allow-scripts', 'allow-popups'], }) var iframe = frame.iframe + iframe.style.setProperty('display', 'none') var iframeStream = new IframeStream(iframe) return iframeStream diff --git a/library/lib/setup-provider.js b/library/lib/setup-provider.js index ced07e0f0..9efd209cb 100644 --- a/library/lib/setup-provider.js +++ b/library/lib/setup-provider.js @@ -13,8 +13,9 @@ function getProvider(){ console.log('MetaMask ZeroClient - injecting zero-client iframe!') var iframeStream = setupIframe({ - zeroClientProvider: 'http://localhost:9001', + zeroClientProvider: 'http://127.0.0.1:9001', sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], + container: document.body, }) var inpageProvider = new MetamaskInpageProvider(iframeStream) diff --git a/library/server.js b/library/server.js new file mode 100644 index 000000000..c7fea085f --- /dev/null +++ b/library/server.js @@ -0,0 +1,88 @@ +const express = require('express') +const browserify = require('browserify') +const watchify = require('watchify') +const babelify = require('babelify') +const path = require('path') + +const zeroBundle = createBundle('./index.js') +const controllerBundle = createBundle('./controller.js') +const appBundle = createBundle('./example/index.js') + +// +// Iframe Server +// + +// beefy frame.js:bundle.js 9001 --live -- -t [ babelify --global --presets [ es2015 ] ] + +const iframeServer = express() + +// serve controller bundle +iframeServer.get('/controller.js', function(req, res){ + res.send(controllerBundle.latest) +}) + +// serve static +iframeServer.use(express.static('./server')) + +iframeServer.listen('9001') + + +// +// Dapp Server +// + +// beefy example/index.js:bundle.js index.js:zero.js --cwd example/ 9002 --live --open -- -t [ babelify --global --presets [ es2015 ] ] + +const dappServer = express() + + +// serve metamask-lib bundle +dappServer.get('/zero.js', function(req, res){ + res.send(zeroBundle.latest) +}) + +// serve dapp bundle +dappServer.get('/app.js', function(req, res){ + res.send(appBundle.latest) +}) + +// serve static +dappServer.use(express.static('./example')) + + +dappServer.listen('9002') + + +function createBundle(entryPoint){ + + var bundleContainer = {} + + var bundler = browserify({ + entries: [entryPoint], + cache: {}, + packageCache: {}, + plugin: [watchify], + }) + + var bablePreset = path.resolve(__dirname, '../node_modules/babel-preset-es2015') + + bundler.transform(babelify, { + global: true, + presets: [bablePreset], + }) + + + bundler.on('update', bundle) + bundle() + + return bundleContainer + + function bundle() { + bundler.bundle(function(err, result){ + if (err) throw err + console.log(`Bundle updated! (${entryPoint})`) + bundleContainer.latest = result.toString() + }) + } + +} \ No newline at end of file diff --git a/library/index.html b/library/server/index.html similarity index 88% rename from library/index.html rename to library/server/index.html index 5a4c66544..2308dd98b 100644 --- a/library/index.html +++ b/library/server/index.html @@ -15,6 +15,6 @@ Hello! I am the MetaMask iframe. - + \ No newline at end of file diff --git a/package.json b/package.json index 4c30db1a1..45ddc3dec 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "lint": "gulp lint", "dev": "gulp dev", "dist": "gulp dist", - "test": "npm run fastTest && npm run ci", + "test": "npm run fastTest && npm run ci && npm run lint", "fastTest": "mocha --require test/helper.js --compilers js:babel-register --recursive \"test/unit/**/*.js\"", "watch": "mocha watch --compilers js:babel-register --recursive \"test/unit/**/*.js\"", "ui": "node development/genStates.js && beefy ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", @@ -45,6 +45,7 @@ "eth-store": "^1.1.0", "ethereumjs-tx": "^1.0.0", "ethereumjs-util": "^4.4.0", + "express": "^4.14.0", "gulp-eslint": "^2.0.0", "hat": "0.0.3", "identicon.js": "^1.2.1", @@ -78,7 +79,7 @@ "three.js": "^0.73.2", "through2": "^2.0.1", "vreme": "^3.0.2", - "web3": "^0.17.0-alpha", + "web3": "ethereum/web3.js#260ac6e78a8ce4b2e13f5bb0fdb65f4088585876", "web3-provider-engine": "^8.0.2", "web3-stream-provider": "^2.0.6", "xtend": "^4.0.1" From 81da958761ab7ae3976c7444528ba8d9bb0744c6 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 26 Aug 2016 19:15:20 -0700 Subject: [PATCH 03/15] Add a port log to server start --- library/server.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/server.js b/library/server.js index c7fea085f..16143e72b 100644 --- a/library/server.js +++ b/library/server.js @@ -49,9 +49,9 @@ dappServer.get('/app.js', function(req, res){ // serve static dappServer.use(express.static('./example')) - -dappServer.listen('9002') - +const dappPort = '9002' +dappServer.listen(dappPort) +console.log(`Dapp listening on port ${dappPort}`) function createBundle(entryPoint){ @@ -70,7 +70,7 @@ function createBundle(entryPoint){ global: true, presets: [bablePreset], }) - + bundler.on('update', bundle) bundle() @@ -85,4 +85,4 @@ function createBundle(entryPoint){ }) } -} \ No newline at end of file +} From a3330568d9aa68e2609ce875a96e784c2e77c20c Mon Sep 17 00:00:00 2001 From: kumavis Date: Wed, 31 Aug 2016 15:33:24 -0700 Subject: [PATCH 04/15] various things --- library/controller.js | 2 -- library/example.sh | 4 ---- library/example/index.js | 18 +++++++++--------- library/index.js | 2 -- library/server.js | 5 +---- 5 files changed, 10 insertions(+), 21 deletions(-) delete mode 100755 library/example.sh diff --git a/library/controller.js b/library/controller.js index 90d849d20..24b841f5e 100644 --- a/library/controller.js +++ b/library/controller.js @@ -4,11 +4,9 @@ const handleRequestsFromStream = require('web3-stream-provider/handler') const Streams = require('mississippi') const ObjectMultiplex = require('../app/scripts/lib/obj-multiplex') -console.log('yes, this is iframe') initializeZeroClient() - function initializeZeroClient() { var provider = ZeroClientProvider({ diff --git a/library/example.sh b/library/example.sh deleted file mode 100755 index 09389d404..000000000 --- a/library/example.sh +++ /dev/null @@ -1,4 +0,0 @@ -# run 2 servers and make sure they close together - -beefy frame.js:bundle.js 9001 --live -- -t [ babelify --global --presets [ es2015 ] ] & -beefy example/index.js:bundle.js index.js:zero.js --cwd example/ 9002 --live --open -- -t [ babelify --global --presets [ es2015 ] ] \ No newline at end of file diff --git a/library/example/index.js b/library/example/index.js index bdde2b47f..91d2237c2 100644 --- a/library/example/index.js +++ b/library/example/index.js @@ -5,24 +5,24 @@ function web3Detect() { if (global.web3) { document.body.innerHTML += 'web3 detected!' console.log('web3 detected!') + startApp() } else { document.body.innerHTML += 'no web3 detected!' console.log('no web3 detected!') } - startApp() } -var primaryAccount = null -web3.eth.getAccounts(function(err, addresses){ - if (err) throw err - console.log('set address') - primaryAccount = addresses[0] -}) - - function startApp(){ console.log('app started') + var primaryAccount = null + console.log('getting main account...') + web3.eth.getAccounts(function(err, addresses){ + if (err) throw err + console.log('set address') + primaryAccount = addresses[0] + }) + document.querySelector('.action-button-1').addEventListener('click', function(){ console.log('saw click') console.log('sending tx') diff --git a/library/index.js b/library/index.js index c98035106..6e43181c9 100644 --- a/library/index.js +++ b/library/index.js @@ -6,9 +6,7 @@ const setupProvider = require('./lib/setup-provider.js') // var provider = setupProvider() -console.log('debugger point A') hijackProvider(provider) -console.log('debugger point B') var web3 = new Web3(provider) web3.setProvider = function(){ console.log('MetaMask - overrode web3.setProvider') diff --git a/library/server.js b/library/server.js index c7fea085f..6da9b2e0b 100644 --- a/library/server.js +++ b/library/server.js @@ -12,8 +12,6 @@ const appBundle = createBundle('./example/index.js') // Iframe Server // -// beefy frame.js:bundle.js 9001 --live -- -t [ babelify --global --presets [ es2015 ] ] - const iframeServer = express() // serve controller bundle @@ -31,8 +29,6 @@ iframeServer.listen('9001') // Dapp Server // -// beefy example/index.js:bundle.js index.js:zero.js --cwd example/ 9002 --live --open -- -t [ babelify --global --presets [ es2015 ] ] - const dappServer = express() @@ -64,6 +60,7 @@ function createBundle(entryPoint){ plugin: [watchify], }) + // global transpile var bablePreset = path.resolve(__dirname, '../node_modules/babel-preset-es2015') bundler.transform(babelify, { From 4cfcb4452a3278cfa775e247271053e82f238fb5 Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 12 Sep 2016 18:30:45 -0700 Subject: [PATCH 05/15] bugfix - prevent iframe restart restart --- library/controller.js | 3 ++- library/example/index.js | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/library/controller.js b/library/controller.js index 24b841f5e..d5cd0525e 100644 --- a/library/controller.js +++ b/library/controller.js @@ -51,7 +51,8 @@ function initializeZeroClient() { if (err) throw err }) - multiStream.on('data', function(chunk){ console.log(chunk) }) + // connectionStream.on('data', function(chunk){ console.log('connectionStream chuck', chunk) }) + // multiStream.on('data', function(chunk){ console.log('multiStream chuck', chunk) }) var providerStream = multiStream.createStream('provider') handleRequestsFromStream(providerStream, provider, logger) diff --git a/library/example/index.js b/library/example/index.js index 91d2237c2..a3f4b9859 100644 --- a/library/example/index.js +++ b/library/example/index.js @@ -3,12 +3,10 @@ window.addEventListener('load', web3Detect) function web3Detect() { if (global.web3) { - document.body.innerHTML += 'web3 detected!' - console.log('web3 detected!') + logToDom('web3 detected!') startApp() } else { - document.body.innerHTML += 'no web3 detected!' - console.log('no web3 detected!') + logToDom('no web3 detected!') } } @@ -49,3 +47,8 @@ function startApp(){ }) } + +function logToDom(message){ + document.body.appendChild(document.createTextNode(message)) + console.log(message) +} \ No newline at end of file From 5126ddaf0c25d243c625adff82dc95273acf1291 Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 12 Sep 2016 19:48:39 -0700 Subject: [PATCH 06/15] mascara - server - prepare to serve popup --- library/server.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/server.js b/library/server.js index 7c764a4a7..495aba914 100644 --- a/library/server.js +++ b/library/server.js @@ -19,8 +19,10 @@ iframeServer.get('/controller.js', function(req, res){ res.send(controllerBundle.latest) }) -// serve static +// serve background controller iframeServer.use(express.static('./server')) +// serve popup window +// iframeServer.use('/popup', express.static('../dist/chrome')) iframeServer.listen('9001') From 8a5007a396cff02b15fb85c3ed910e14cf71d59c Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 12 Sep 2016 21:30:04 -0700 Subject: [PATCH 07/15] ui - remove unused currentDomain prop --- app/scripts/popup.js | 19 ++----------------- ui/app/accounts/index.js | 1 - ui/app/reducers/app.js | 1 - ui/app/reducers/metamask.js | 1 - ui/index.js | 4 +--- 5 files changed, 3 insertions(+), 23 deletions(-) diff --git a/app/scripts/popup.js b/app/scripts/popup.js index 096b56115..c7145bdd8 100644 --- a/app/scripts/popup.js +++ b/app/scripts/popup.js @@ -1,4 +1,3 @@ -const url = require('url') const EventEmitter = require('events').EventEmitter const async = require('async') const Dnode = require('dnode') @@ -18,7 +17,6 @@ var css = MetaMaskUiCss() injectCss(css) async.parallel({ - currentDomain: getCurrentDomain, accountManager: connectToAccountManager, }, setupApp) @@ -46,6 +44,8 @@ function setupWeb3Connection (stream) { } function setupControllerConnection (stream, cb) { + // this is a really sneaky way of adding EventEmitter api + // to a bi-directional dnode instance var eventEmitter = new EventEmitter() var background = Dnode({ sendUpdate: function (state) { @@ -60,20 +60,6 @@ function setupControllerConnection (stream, cb) { }) } -function getCurrentDomain (cb) { - const unknown = '' - if (!extension.tabs) return cb(null, unknown) - extension.tabs.query({active: true, currentWindow: true}, function (results) { - var activeTab = results[0] - var currentUrl = activeTab && activeTab.url - var currentDomain = url.parse(currentUrl).host - if (!currentUrl) { - return cb(null, unknown) - } - cb(null, currentDomain) - }) -} - function setupApp (err, opts) { if (err) { alert(err.stack) @@ -85,7 +71,6 @@ function setupApp (err, opts) { MetaMaskUi({ container: container, accountManager: opts.accountManager, - currentDomain: opts.currentDomain, networkVersion: opts.networkVersion, }) } diff --git a/ui/app/accounts/index.js b/ui/app/accounts/index.js index c20900c1e..3af8267b5 100644 --- a/ui/app/accounts/index.js +++ b/ui/app/accounts/index.js @@ -20,7 +20,6 @@ function mapStateToProps (state) { identities: state.metamask.identities, unconfTxs: state.metamask.unconfTxs, selectedAddress: state.metamask.selectedAddress, - currentDomain: state.appState.currentDomain, scrollToBottom: state.appState.scrollToBottom, pending, } diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index a6cd9ca1b..c39d89a4d 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -39,7 +39,6 @@ function reduceApp (state, action) { accountDetail: { subview: 'transactions', }, - currentDomain: 'example.com', transForward: true, // Used to render transition direction isLoading: false, // Used to display loading indicator warning: null, // Used to display error text diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index 7f18480cb..84953d734 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -11,7 +11,6 @@ function reduceMetamask (state, action) { isInitialized: false, isUnlocked: false, isEthConfirmed: false, - currentDomain: 'example.com', rpcTarget: 'https://rawtestrpc.metamask.io/', identities: {}, unconfTxs: {}, diff --git a/ui/index.js b/ui/index.js index 0e69b00d6..a6905b639 100644 --- a/ui/index.js +++ b/ui/index.js @@ -25,9 +25,7 @@ function startApp (metamaskState, accountManager, opts) { metamask: metamaskState, // appState represents the current tab's popup state - appState: { - currentDomain: opts.currentDomain, - }, + appState: {}, // Which blockchain we are using: networkVersion: opts.networkVersion, From ed11ab6d18d798896db1f991ec80105c22074d0a Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 12 Sep 2016 21:43:14 -0700 Subject: [PATCH 08/15] popup - further clean and comment --- app/scripts/popup.js | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/app/scripts/popup.js b/app/scripts/popup.js index c7145bdd8..012ced951 100644 --- a/app/scripts/popup.js +++ b/app/scripts/popup.js @@ -1,5 +1,4 @@ const EventEmitter = require('events').EventEmitter -const async = require('async') const Dnode = require('dnode') const Web3 = require('web3') const MetaMaskUi = require('../../ui') @@ -16,9 +15,7 @@ const notification = require('./lib/notifications') var css = MetaMaskUiCss() injectCss(css) -async.parallel({ - accountManager: connectToAccountManager, -}, setupApp) +connectToAccountManager(setupApp) function connectToAccountManager (cb) { // setup communication with background @@ -35,32 +32,32 @@ function connectToAccountManager (cb) { setupWeb3Connection(mx.createStream('provider')) } -function setupWeb3Connection (stream) { - var remoteProvider = new StreamProvider() - remoteProvider.pipe(stream).pipe(remoteProvider) - stream.on('error', console.error.bind(console)) - remoteProvider.on('error', console.error.bind(console)) - global.web3 = new Web3(remoteProvider) +function setupWeb3Connection (connectionStream) { + var providerStream = new StreamProvider() + providerStream.pipe(connectionStream).pipe(providerStream) + connectionStream.on('error', console.error.bind(console)) + providerStream.on('error', console.error.bind(console)) + global.web3 = new Web3(providerStream) } -function setupControllerConnection (stream, cb) { +function setupControllerConnection (connectionStream, cb) { // this is a really sneaky way of adding EventEmitter api // to a bi-directional dnode instance var eventEmitter = new EventEmitter() - var background = Dnode({ + var accountManagerDnode = Dnode({ sendUpdate: function (state) { eventEmitter.emit('update', state) }, }) - stream.pipe(background).pipe(stream) - background.once('remote', function (accountManager) { + connectionStream.pipe(accountManagerDnode).pipe(connectionStream) + accountManagerDnode.once('remote', function (accountManager) { // setup push events accountManager.on = eventEmitter.on.bind(eventEmitter) cb(null, accountManager) }) } -function setupApp (err, opts) { +function setupApp (err, accountManager) { if (err) { alert(err.stack) throw err @@ -70,8 +67,7 @@ function setupApp (err, opts) { MetaMaskUi({ container: container, - accountManager: opts.accountManager, - networkVersion: opts.networkVersion, + accountManager: accountManager, }) } From b508541935b5cbd8202e3d6cfc4d0584e6518b46 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 12 Sep 2016 22:13:52 -0700 Subject: [PATCH 09/15] Fix cache clearing reference for Opera For some reason Chrome didn't mind this awful bug, but Opera caught it. --- CHANGELOG.md | 4 ++++ app/manifest.json | 2 +- app/scripts/lib/idStore.js | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fb24f3ca..453823f88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Current Master +## 2.11.1 2016-09-12 + +- Fix bug that prevented caches from being cleared in Opera. + ## 2.11.0 2016-09-12 - Fix bug where pending transactions from Test net (or other networks) show up In Main net. diff --git a/app/manifest.json b/app/manifest.json index 9b66260cd..a21e0612a 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "MetaMask", "short_name": "Metamask", - "version": "2.11.0", + "version": "2.11.1", "manifest_version": 2, "author": "https://metamask.io", "description": "Ethereum Browser Extension", diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js index b5b13a57a..89c0c3abc 100644 --- a/app/scripts/lib/idStore.js +++ b/app/scripts/lib/idStore.js @@ -505,7 +505,7 @@ IdentityStore.prototype.purgeCache = function () { this._currentState.identities = {} let accounts try { - Object.keys(this._ethStore._currentState.accounts) + accounts = Object.keys(this._ethStore._currentState.accounts) } catch (e) { accounts = [] } From b4e3b83f0467ebd1610c18d318b5d1b54d8863bb Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 12 Sep 2016 23:28:07 -0700 Subject: [PATCH 10/15] popup - breakout popup-core --- app/scripts/popup-core.js | 63 +++++++++++++++++++++++++++++++++++ app/scripts/popup.js | 69 +++++---------------------------------- 2 files changed, 71 insertions(+), 61 deletions(-) create mode 100644 app/scripts/popup-core.js diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js new file mode 100644 index 000000000..94413a1c4 --- /dev/null +++ b/app/scripts/popup-core.js @@ -0,0 +1,63 @@ +const EventEmitter = require('events').EventEmitter +const Dnode = require('dnode') +const Web3 = require('web3') +const MetaMaskUi = require('../../ui') +const StreamProvider = require('web3-stream-provider') +const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex + + +module.exports = initializePopup + + +function initializePopup(connectionStream){ + // setup app + connectToAccountManager(connectionStream, setupApp) +} + +function connectToAccountManager (connectionStream, cb) { + // setup communication with background + // setup multiplexing + var mx = setupMultiplex(connectionStream) + // connect features + setupControllerConnection(mx.createStream('controller'), cb) + setupWeb3Connection(mx.createStream('provider')) +} + +function setupWeb3Connection (connectionStream) { + var providerStream = new StreamProvider() + providerStream.pipe(connectionStream).pipe(providerStream) + connectionStream.on('error', console.error.bind(console)) + providerStream.on('error', console.error.bind(console)) + global.web3 = new Web3(providerStream) +} + +function setupControllerConnection (connectionStream, cb) { + // this is a really sneaky way of adding EventEmitter api + // to a bi-directional dnode instance + var eventEmitter = new EventEmitter() + var accountManagerDnode = Dnode({ + sendUpdate: function (state) { + eventEmitter.emit('update', state) + }, + }) + connectionStream.pipe(accountManagerDnode).pipe(connectionStream) + accountManagerDnode.once('remote', function (accountManager) { + // setup push events + accountManager.on = eventEmitter.on.bind(eventEmitter) + cb(null, accountManager) + }) +} + +function setupApp (err, accountManager) { + if (err) { + alert(err.stack) + throw err + } + + var container = document.getElementById('app-content') + + MetaMaskUi({ + container: container, + accountManager: accountManager, + }) +} diff --git a/app/scripts/popup.js b/app/scripts/popup.js index 012ced951..8485b5081 100644 --- a/app/scripts/popup.js +++ b/app/scripts/popup.js @@ -1,75 +1,22 @@ -const EventEmitter = require('events').EventEmitter -const Dnode = require('dnode') -const Web3 = require('web3') -const MetaMaskUi = require('../../ui') -const MetaMaskUiCss = require('../../ui/css') const injectCss = require('inject-css') +const MetaMaskUiCss = require('../../ui/css') const PortStream = require('./lib/port-stream.js') -const StreamProvider = require('web3-stream-provider') -const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex +const startPopup = require('./popup-core') const isPopupOrNotification = require('./lib/is-popup-or-notification') const extension = require('./lib/extension') const notification = require('./lib/notifications') -// setup app var css = MetaMaskUiCss() injectCss(css) -connectToAccountManager(setupApp) - -function connectToAccountManager (cb) { - // setup communication with background - - var name = isPopupOrNotification() - closePopupIfOpen(name) - window.METAMASK_UI_TYPE = name - var pluginPort = extension.runtime.connect({ name }) - var portStream = new PortStream(pluginPort) - // setup multiplexing - var mx = setupMultiplex(portStream) - // connect features - setupControllerConnection(mx.createStream('controller'), cb) - setupWeb3Connection(mx.createStream('provider')) -} - -function setupWeb3Connection (connectionStream) { - var providerStream = new StreamProvider() - providerStream.pipe(connectionStream).pipe(providerStream) - connectionStream.on('error', console.error.bind(console)) - providerStream.on('error', console.error.bind(console)) - global.web3 = new Web3(providerStream) -} - -function setupControllerConnection (connectionStream, cb) { - // this is a really sneaky way of adding EventEmitter api - // to a bi-directional dnode instance - var eventEmitter = new EventEmitter() - var accountManagerDnode = Dnode({ - sendUpdate: function (state) { - eventEmitter.emit('update', state) - }, - }) - connectionStream.pipe(accountManagerDnode).pipe(connectionStream) - accountManagerDnode.once('remote', function (accountManager) { - // setup push events - accountManager.on = eventEmitter.on.bind(eventEmitter) - cb(null, accountManager) - }) -} +var name = isPopupOrNotification() +closePopupIfOpen(name) +window.METAMASK_UI_TYPE = name -function setupApp (err, accountManager) { - if (err) { - alert(err.stack) - throw err - } - - var container = document.getElementById('app-content') +var pluginPort = extension.runtime.connect({ name }) +var portStream = new PortStream(pluginPort) - MetaMaskUi({ - container: container, - accountManager: accountManager, - }) -} +startPopup(portStream) function closePopupIfOpen(name) { if (name !== 'notification') { From a4cdd198438816b99630adf7c30d28a8ec2a18bb Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 13 Sep 2016 00:31:04 -0700 Subject: [PATCH 11/15] mascara - everything but the popup bundle --- app/scripts/popup.js | 2 +- library/index.js | 2 +- library/popup.js | 19 +++++++++++++++++++ library/server.js | 10 ++++++++-- 4 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 library/popup.js diff --git a/app/scripts/popup.js b/app/scripts/popup.js index 8485b5081..e6f149f96 100644 --- a/app/scripts/popup.js +++ b/app/scripts/popup.js @@ -1,7 +1,7 @@ const injectCss = require('inject-css') const MetaMaskUiCss = require('../../ui/css') -const PortStream = require('./lib/port-stream.js') const startPopup = require('./popup-core') +const PortStream = require('./lib/port-stream.js') const isPopupOrNotification = require('./lib/is-popup-or-notification') const extension = require('./lib/extension') const notification = require('./lib/notifications') diff --git a/library/index.js b/library/index.js index 6e43181c9..ded588967 100644 --- a/library/index.js +++ b/library/index.js @@ -27,7 +27,7 @@ var shouldPop = false window.addEventListener('click', function(){ if (!shouldPop) return shouldPop = false - window.open('popup.html', '', 'width=1000') + window.open('http://localhost:9001/popup/popup.html', '', 'width=1000') console.log('opening window...') }) diff --git a/library/popup.js b/library/popup.js new file mode 100644 index 000000000..667b13371 --- /dev/null +++ b/library/popup.js @@ -0,0 +1,19 @@ +const injectCss = require('inject-css') +const MetaMaskUiCss = require('../ui/css') +const startPopup = require('../app/scripts/popup-core') +const setupIframe = require('./lib/setup-iframe.js') + + +var css = MetaMaskUiCss() +injectCss(css) + +var name = 'popup' +window.METAMASK_UI_TYPE = name + +var iframeStream = setupIframe({ + zeroClientProvider: 'http://127.0.0.1:9001', + sandboxAttributes: ['allow-scripts', 'allow-popups', 'allow-same-origin'], + container: document.body, +}) + +startPopup(iframeStream) diff --git a/library/server.js b/library/server.js index 495aba914..033c65358 100644 --- a/library/server.js +++ b/library/server.js @@ -6,6 +6,7 @@ const path = require('path') const zeroBundle = createBundle('./index.js') const controllerBundle = createBundle('./controller.js') +// const popupBundle = createBundle('./popup.js') const appBundle = createBundle('./example/index.js') // @@ -14,6 +15,12 @@ const appBundle = createBundle('./example/index.js') const iframeServer = express() +// serve popup window +// iframeServer.get('/popup/scripts/popup.js', function(req, res){ +// res.send(popupBundle.latest) +// }) +iframeServer.use('/popup', express.static('../dist/chrome')) + // serve controller bundle iframeServer.get('/controller.js', function(req, res){ res.send(controllerBundle.latest) @@ -21,8 +28,7 @@ iframeServer.get('/controller.js', function(req, res){ // serve background controller iframeServer.use(express.static('./server')) -// serve popup window -// iframeServer.use('/popup', express.static('../dist/chrome')) + iframeServer.listen('9001') From 93c703d0ef73ac51aa57af668ac0eee645ded782 Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 13 Sep 2016 00:37:22 -0700 Subject: [PATCH 12/15] mascara - add readme --- library/README.md | 6 ++++++ library/example/README.md | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 library/README.md delete mode 100644 library/example/README.md diff --git a/library/README.md b/library/README.md new file mode 100644 index 000000000..7dc291564 --- /dev/null +++ b/library/README.md @@ -0,0 +1,6 @@ +start the dual servers (dapp + mascara) +``` +node server.js +``` + +open the example dapp at `http://localhost:9002/` \ No newline at end of file diff --git a/library/example/README.md b/library/example/README.md deleted file mode 100644 index 2a5a1cce0..000000000 --- a/library/example/README.md +++ /dev/null @@ -1,5 +0,0 @@ -``` -trap 'kill %1' SIGINT -beefy frame.js:bundle.js 9001 --live & \ -beefy example/index.js:bundle.js index.js:zero.js --cwd example/ 9002 --live --open -``` \ No newline at end of file From f7794d9949a0470ccb6c872925ca0b575806b507 Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 13 Sep 2016 10:18:57 -0700 Subject: [PATCH 13/15] PendingTxDetails - partially remove imagify support --- ui/app/components/pending-tx-details.js | 37 ++++++++----------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/ui/app/components/pending-tx-details.js b/ui/app/components/pending-tx-details.js index c2e39a1ca..148b5c6df 100644 --- a/ui/app/components/pending-tx-details.js +++ b/ui/app/components/pending-tx-details.js @@ -1,7 +1,6 @@ const Component = require('react').Component const h = require('react-hyperscript') const inherits = require('util').inherits -const carratInline = require('fs').readFileSync('./images/forward-carrat.svg', 'utf8') const MiniAccountPanel = require('./mini-account-panel') const EthBalance = require('./eth-balance') @@ -78,7 +77,7 @@ PTXP.render = function () { ]), - forwardCarrat(imageify), + forwardCarrat(), this.miniAccountPanelForRecipient(), ]), @@ -223,30 +222,16 @@ PTXP.warnIfNeeded = function () { } -function forwardCarrat (imageify) { - if (imageify) { - return ( - - h('img', { - src: 'images/forward-carrat.svg', - style: { - padding: '5px 6px 0px 10px', - height: '37px', - }, - }) - - ) - } else { - return ( +function forwardCarrat () { + return ( - h('div', { - dangerouslySetInnerHTML: { __html: carratInline }, - style: { - padding: '0px 6px 0px 10px', - height: '45px', - }, - }) + h('img', { + src: 'images/forward-carrat.svg', + style: { + padding: '5px 6px 0px 10px', + height: '37px', + }, + }) - ) - } + ) } From 81d25d560f4920ee7a357881931e674bea97176c Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 13 Sep 2016 10:19:40 -0700 Subject: [PATCH 14/15] mascara - serve popup bundle --- library/server.js | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/library/server.js b/library/server.js index 033c65358..bb0b24e50 100644 --- a/library/server.js +++ b/library/server.js @@ -2,11 +2,10 @@ const express = require('express') const browserify = require('browserify') const watchify = require('watchify') const babelify = require('babelify') -const path = require('path') const zeroBundle = createBundle('./index.js') const controllerBundle = createBundle('./controller.js') -// const popupBundle = createBundle('./popup.js') +const popupBundle = createBundle('./popup.js') const appBundle = createBundle('./example/index.js') // @@ -16,9 +15,9 @@ const appBundle = createBundle('./example/index.js') const iframeServer = express() // serve popup window -// iframeServer.get('/popup/scripts/popup.js', function(req, res){ -// res.send(popupBundle.latest) -// }) +iframeServer.get('/popup/scripts/popup.js', function(req, res){ + res.send(popupBundle.latest) +}) iframeServer.use('/popup', express.static('../dist/chrome')) // serve controller bundle @@ -29,8 +28,10 @@ iframeServer.get('/controller.js', function(req, res){ // serve background controller iframeServer.use(express.static('./server')) - -iframeServer.listen('9001') +// start the server +const mascaraPort = 9001 +iframeServer.listen(mascaraPort) +console.log(`Mascara service listening on port ${mascaraPort}`) // @@ -39,7 +40,6 @@ iframeServer.listen('9001') const dappServer = express() - // serve metamask-lib bundle dappServer.get('/zero.js', function(req, res){ res.send(zeroBundle.latest) @@ -53,10 +53,22 @@ dappServer.get('/app.js', function(req, res){ // serve static dappServer.use(express.static('./example')) +// start the server const dappPort = '9002' dappServer.listen(dappPort) console.log(`Dapp listening on port ${dappPort}`) +// +// util +// + +function serveBundle(entryPoint){ + const bundle = createBundle(entryPoint) + return function(req, res){ + res.send(bundle.latest) + } +} + function createBundle(entryPoint){ var bundleContainer = {} @@ -69,14 +81,14 @@ function createBundle(entryPoint){ }) // global transpile - var bablePreset = path.resolve(__dirname, '../node_modules/babel-preset-es2015') + var bablePreset = require.resolve('babel-preset-es2015') bundler.transform(babelify, { global: true, presets: [bablePreset], + babelrc: false, }) - bundler.on('update', bundle) bundle() From e10c651db05c4d2c69618e49db0f24280e93f5ff Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 13 Sep 2016 12:07:29 -0700 Subject: [PATCH 15/15] Fix port stream end bug Emitting `end` or `close` was not ending the stream. Pushing a null packet also closes a stream, so I did that instead. Fixes #616 --- app/scripts/lib/port-stream.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/scripts/lib/port-stream.js b/app/scripts/lib/port-stream.js index 1889e3c04..6f59d4485 100644 --- a/app/scripts/lib/port-stream.js +++ b/app/scripts/lib/port-stream.js @@ -30,8 +30,7 @@ PortDuplexStream.prototype._onMessage = function (msg) { PortDuplexStream.prototype._onDisconnect = function () { try { - // this.end() - this.emit('close') + this.push(null) } catch (err) { this.emit('error', err) }