aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorDan Finlay <dan@danfinlay.com>2016-08-17 06:39:40 +0800
committerDan Finlay <dan@danfinlay.com>2016-08-17 06:39:40 +0800
commit5479509618e601391586d0851acee4e408523c4f (patch)
tree68a26e9fe5589f7d5ad8b9b649a88f87d7e26585 /app
parentf1986d7a3757aea50fba798b295397e69739b891 (diff)
downloadtangerine-wallet-browser-5479509618e601391586d0851acee4e408523c4f.tar
tangerine-wallet-browser-5479509618e601391586d0851acee4e408523c4f.tar.gz
tangerine-wallet-browser-5479509618e601391586d0851acee4e408523c4f.tar.bz2
tangerine-wallet-browser-5479509618e601391586d0851acee4e408523c4f.tar.lz
tangerine-wallet-browser-5479509618e601391586d0851acee4e408523c4f.tar.xz
tangerine-wallet-browser-5479509618e601391586d0851acee4e408523c4f.tar.zst
tangerine-wallet-browser-5479509618e601391586d0851acee4e408523c4f.zip
Set up MVP for popup-based notifications.
Diffstat (limited to 'app')
-rw-r--r--app/notification.html11
-rw-r--r--app/scripts/background.js2
-rw-r--r--app/scripts/lib/notifications.js136
-rw-r--r--app/scripts/notification.js85
4 files changed, 106 insertions, 128 deletions
diff --git a/app/notification.html b/app/notification.html
new file mode 100644
index 000000000..927f1634c
--- /dev/null
+++ b/app/notification.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>MetaMask Notification</title>
+ </head>
+ <body>
+ <div id="app-content"></div>
+ <script src="./scripts/notification.js" type="text/javascript" charset="utf-8"></script>
+ </body>
+</html>
diff --git a/app/scripts/background.js b/app/scripts/background.js
index e04309e74..79f8f9fd9 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -69,7 +69,7 @@ function showUnconfirmedTx (txParams, txData, onTxDoneCb) {
extension.runtime.onConnect.addListener(connectRemote)
function connectRemote (remotePort) {
- var isMetaMaskInternalProcess = (remotePort.name === 'popup')
+ var isMetaMaskInternalProcess = remotePort.name === 'popup' || remotePort.name === 'notification'
var portStream = new PortStream(remotePort)
if (isMetaMaskInternalProcess) {
// communication with popup
diff --git a/app/scripts/lib/notifications.js b/app/scripts/lib/notifications.js
index 6c1601df1..75fb60dd0 100644
--- a/app/scripts/lib/notifications.js
+++ b/app/scripts/lib/notifications.js
@@ -18,142 +18,24 @@ const notifications = {
module.exports = notifications
window.METAMASK_NOTIFIER = notifications
-setupListeners()
-
-function setupListeners () {
- // guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
- if (!extension.notifications) return console.error('Chrome notifications API missing...')
-
- // notification button press
- extension.notifications.onButtonClicked.addListener(function (notificationId, buttonIndex) {
- var handlers = notificationHandlers[notificationId]
- if (buttonIndex === 0) {
- handlers.confirm()
- } else {
- handlers.cancel()
- }
- extension.notifications.clear(notificationId)
- })
-
- // notification teardown
- extension.notifications.onClosed.addListener(function (notificationId) {
- delete notificationHandlers[notificationId]
- })
-}
-
-// creation helper
function createUnlockRequestNotification (opts) {
- // guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
- if (!extension.notifications) return console.error('Chrome notifications API missing...')
- var message = 'An Ethereum app has requested a signature. Please unlock your account.'
-
- var id = createId()
- extension.notifications.create(id, {
- type: 'basic',
- iconUrl: '/images/icon-128.png',
- title: opts.title,
- message: message,
- })
+ showNotification()
}
function createTxNotification (state) {
- // guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
- if (!extension.notifications) return console.error('Chrome notifications API missing...')
-
- renderTxNotificationSVG(state, function (err, notificationSvgSource) {
- if (err) throw err
-
- showNotification(extend(state, {
- title: 'New Unsigned Transaction',
- imageUrl: toSvgUri(notificationSvgSource),
- }))
- })
+ showNotification()
}
function createMsgNotification (state) {
- // guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
- if (!extension.notifications) return console.error('Chrome notifications API missing...')
-
- renderMsgNotificationSVG(state, function (err, notificationSvgSource) {
- if (err) throw err
-
- showNotification(extend(state, {
- title: 'New Unsigned Message',
- imageUrl: toSvgUri(notificationSvgSource),
- }))
- })
+ showNotification()
}
-function showNotification (state) {
- // guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
- if (!extension.notifications) return console.error('Chrome notifications API missing...')
-
- var id = createId()
- extension.notifications.create(id, {
- type: 'image',
- requireInteraction: true,
- iconUrl: '/images/icon-128.png',
- imageUrl: state.imageUrl,
- title: state.title,
- message: '',
- buttons: [{
- title: 'Approve',
- }, {
- title: 'Reject',
- }],
+function showNotification() {
+ chrome.windows.create({
+ url:"notification.html",
+ type:"panel",
+ width:360,
+ height:500,
})
- notificationHandlers[id] = {
- confirm: state.onConfirm,
- cancel: state.onCancel,
- }
-}
-
-function renderTxNotificationSVG (state, cb) {
- var content = h(PendingTxDetails, state)
- renderNotificationSVG(content, cb)
}
-function renderMsgNotificationSVG (state, cb) {
- var content = h(PendingMsgDetails, state)
- renderNotificationSVG(content, cb)
-}
-
-function renderNotificationSVG (content, cb) {
- var container = document.createElement('div')
- var confirmView = h('div.app-primary', {
- style: {
- width: '360px',
- height: '240px',
- padding: '16px',
- // background: '#F7F7F7',
- background: 'white',
- },
- }, [
- h('style', MetaMaskUiCss()),
- content,
- ])
-
- render(confirmView, container, function ready() {
- var rootElement = findDOMNode(this)
- var viewSource = rootElement.outerHTML
- unmountComponentAtNode(container)
- var svgSource = svgWrapper(viewSource)
- // insert content into svg wrapper
- cb(null, svgSource)
- })
-}
-
-function svgWrapper (content) {
- var wrapperSource = `
- <svg xmlns="http://www.w3.org/2000/svg" width="360" height="240">
- <foreignObject x="0" y="0" width="100%" height="100%">
- <body xmlns="http://www.w3.org/1999/xhtml" height="100%">{{content}}</body>
- </foreignObject>
- </svg>
- `
- return wrapperSource.split('{{content}}').join(content)
-}
-
-function toSvgUri (content) {
- return 'data:image/svg+xml;utf8,' + encodeURIComponent(content)
-}
diff --git a/app/scripts/notification.js b/app/scripts/notification.js
new file mode 100644
index 000000000..90c00b32d
--- /dev/null
+++ b/app/scripts/notification.js
@@ -0,0 +1,85 @@
+const url = require('url')
+const EventEmitter = require('events').EventEmitter
+const async = require('async')
+const Dnode = require('dnode')
+const Web3 = require('web3')
+const MetaMaskNotification = require('../../ui/notification')
+const MetaMaskUiCss = require('../../ui/css')
+const injectCss = require('inject-css')
+const PortStream = require('./lib/port-stream.js')
+const StreamProvider = require('web3-stream-provider')
+const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
+const extension = require('./lib/extension')
+
+// setup app
+var css = MetaMaskUiCss()
+injectCss(css)
+
+async.parallel({
+ currentDomain: getCurrentDomain,
+ accountManager: connectToAccountManager,
+}, setupApp)
+
+function connectToAccountManager (cb) {
+ // setup communication with background
+ var pluginPort = extension.runtime.connect({name: 'notification'})
+ var portStream = new PortStream(pluginPort)
+ // setup multiplexing
+ var mx = setupMultiplex(portStream)
+ // connect features
+ setupControllerConnection(mx.createStream('controller'), 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 setupControllerConnection (stream, cb) {
+ var eventEmitter = new EventEmitter()
+ var background = Dnode({
+ sendUpdate: function (state) {
+ eventEmitter.emit('update', state)
+ },
+ })
+ stream.pipe(background).pipe(stream)
+ background.once('remote', function (accountManager) {
+ // setup push events
+ accountManager.on = eventEmitter.on.bind(eventEmitter)
+ cb(null, accountManager)
+ })
+}
+
+function getCurrentDomain (cb) {
+ const unknown = '<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)
+ throw err
+ }
+
+ var container = document.getElementById('app-content')
+
+ MetaMaskNotification({
+ container: container,
+ accountManager: opts.accountManager,
+ currentDomain: opts.currentDomain,
+ networkVersion: opts.networkVersion,
+ })
+}