Emit updates to all listeners on pending tx updates

Previously the metamask controller only supported a single UI event listener, which wasn't useful for having a separate notification UI open at the same time.

Also reduced the notification's complexity down to a single method, which is heavily re-used.

Still has an outstanding bug where if the plugin ui dismisses the last tx, it does not close the notification popup.
feature/default_network_editable
Dan Finlay 8 years ago
parent 49ab51d825
commit e5ca83d2bf
  1. 38
      app/scripts/background.js
  2. 16
      app/scripts/lib/notifications.js
  3. 22
      app/scripts/metamask-controller.js

@ -3,9 +3,7 @@ const extend = require('xtend')
const Dnode = require('dnode') const Dnode = require('dnode')
const eos = require('end-of-stream') const eos = require('end-of-stream')
const PortStream = require('./lib/port-stream.js') const PortStream = require('./lib/port-stream.js')
const createUnlockRequestNotification = require('./lib/notifications.js').createUnlockRequestNotification const notification = require('./lib/notifications.js')
const createTxNotification = require('./lib/notifications.js').createTxNotification
const createMsgNotification = require('./lib/notifications.js').createMsgNotification
const messageManager = require('./lib/message-manager') const messageManager = require('./lib/message-manager')
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
const MetamaskController = require('./metamask-controller') const MetamaskController = require('./metamask-controller')
@ -26,41 +24,15 @@ const controller = new MetamaskController({
const idStore = controller.idStore const idStore = controller.idStore
function unlockAccountMessage () { function unlockAccountMessage () {
createUnlockRequestNotification({ notification.show()
title: 'Account Unlock Request',
})
} }
function showUnconfirmedMessage (msgParams, msgId) { function showUnconfirmedMessage (msgParams, msgId) {
var controllerState = controller.getState() notification.show()
createMsgNotification({
imageifyIdenticons: false,
txData: {
msgParams: msgParams,
time: (new Date()).getTime(),
},
identities: controllerState.identities,
accounts: controllerState.accounts,
onConfirm: idStore.approveMessage.bind(idStore, msgId, noop),
onCancel: idStore.cancelMessage.bind(idStore, msgId),
})
} }
function showUnconfirmedTx (txParams, txData, onTxDoneCb) { function showUnconfirmedTx (txParams, txData, onTxDoneCb) {
var controllerState = controller.getState() notification.show()
createTxNotification({
imageifyIdenticons: false,
txData: {
txParams: txParams,
time: (new Date()).getTime(),
},
identities: controllerState.identities,
accounts: controllerState.accounts,
onConfirm: idStore.approveTransaction.bind(idStore, txData.id, noop),
onCancel: idStore.cancelTransaction.bind(idStore, txData.id),
})
} }
// //
@ -109,7 +81,7 @@ function setupControllerConnection (stream) {
dnode.on('remote', (remote) => { dnode.on('remote', (remote) => {
// push updates to popup // push updates to popup
controller.ethStore.on('update', controller.sendUpdate.bind(controller)) controller.ethStore.on('update', controller.sendUpdate.bind(controller))
controller.remote = remote controller.listeners.push(remote)
idStore.on('update', controller.sendUpdate.bind(controller)) idStore.on('update', controller.sendUpdate.bind(controller))
// teardown on disconnect // teardown on disconnect

@ -1,25 +1,11 @@
const extension = require('./extension') const extension = require('./extension')
const notifications = { const notifications = {
createUnlockRequestNotification: createUnlockRequestNotification, show: showNotification,
createTxNotification: createTxNotification,
createMsgNotification: createMsgNotification,
} }
module.exports = notifications module.exports = notifications
window.METAMASK_NOTIFIER = notifications window.METAMASK_NOTIFIER = notifications
function createUnlockRequestNotification (opts) {
showNotification()
}
function createTxNotification (state) {
showNotification()
}
function createMsgNotification (state) {
showNotification()
}
function showNotification() { function showNotification() {
extension.windows.getAll({}, (windows) => { extension.windows.getAll({}, (windows) => {

@ -12,6 +12,7 @@ module.exports = class MetamaskController {
constructor (opts) { constructor (opts) {
this.opts = opts this.opts = opts
this.listeners = []
this.configManager = new ConfigManager(opts) this.configManager = new ConfigManager(opts)
this.idStore = new IdentityStore({ this.idStore = new IdentityStore({
configManager: this.configManager, configManager: this.configManager,
@ -112,9 +113,9 @@ module.exports = class MetamaskController {
} }
sendUpdate () { sendUpdate () {
if (this.remote) { this.listeners.forEach((remote) => {
this.remote.sendUpdate(this.getState()) remote.sendUpdate(this.getState())
} })
} }
initializeProvider (opts) { initializeProvider (opts) {
@ -130,10 +131,17 @@ module.exports = class MetamaskController {
}, },
// tx signing // tx signing
approveTransaction: this.newUnsignedTransaction.bind(this), approveTransaction: this.newUnsignedTransaction.bind(this),
signTransaction: idStore.signTransaction.bind(idStore), signTransaction: (...args) => {
idStore.signTransaction(...args)
this.sendUpdate()
},
// msg signing // msg signing
approveMessage: this.newUnsignedMessage.bind(this), approveMessage: this.newUnsignedMessage.bind(this),
signMessage: idStore.signMessage.bind(idStore), signMessage: (...args) => {
idStore.signMessage(...args)
this.sendUpdate()
},
} }
var provider = MetaMaskProvider(providerOpts) var provider = MetaMaskProvider(providerOpts)
@ -193,6 +201,8 @@ module.exports = class MetamaskController {
// It's locked // It's locked
if (!state.isUnlocked) { if (!state.isUnlocked) {
// Allow the environment to define an unlock message.
this.opts.unlockAccountMessage() this.opts.unlockAccountMessage()
idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, noop) idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, noop)
@ -200,6 +210,7 @@ module.exports = class MetamaskController {
} else { } else {
idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, (err, txData) => { idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, (err, txData) => {
if (err) return onTxDoneCb(err) if (err) return onTxDoneCb(err)
this.sendUpdate()
this.opts.showUnconfirmedTx(txParams, txData, onTxDoneCb) this.opts.showUnconfirmedTx(txParams, txData, onTxDoneCb)
}) })
} }
@ -211,6 +222,7 @@ module.exports = class MetamaskController {
this.opts.unlockAccountMessage() this.opts.unlockAccountMessage()
} else { } else {
this.addUnconfirmedMessage(msgParams, cb) this.addUnconfirmedMessage(msgParams, cb)
this.sendUpdate()
} }
} }

Loading…
Cancel
Save