diff options
-rw-r--r-- | app/scripts/background.js | 34 | ||||
-rw-r--r-- | app/scripts/lib/idmgmt.js | 66 | ||||
-rw-r--r-- | app/scripts/lib/port-stream.js | 10 | ||||
-rw-r--r-- | app/scripts/popup.js | 10 | ||||
-rw-r--r-- | package.json | 1 |
5 files changed, 74 insertions, 47 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js index ca6b5abbc..3de152d0a 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -2,10 +2,11 @@ const Dnode = require('dnode') const PortStream = require('./lib/port-stream.js') const MetaMaskProvider = require('./lib/metamask-provider') const IdentityManager = require('./lib/idmgmt') +const eos = require('end-of-stream') console.log('ready to roll') -var wallet = IdentityManager() +var wallet = new IdentityManager() // setup provider var zeroClient = MetaMaskProvider({ @@ -35,8 +36,35 @@ function connectRemote(remotePort){ function handleInternalCommunication(remotePort){ var duplex = new PortStream(remotePort) - var remote = Dnode(wallet) - duplex.pipe(remote).pipe(duplex) + var connection = Dnode({ + // this is annoying, have to decompose wallet + getState: wallet.getState.bind(wallet), + submitPassword: wallet.submitPassword.bind(wallet), + setSelectedAddress: wallet.setSelectedAddress.bind(wallet), + signTransaction: wallet.signTransaction.bind(wallet), + setLocked: wallet.setLocked.bind(wallet), + getAccounts: wallet.getAccounts.bind(wallet), + confirmTransaction: wallet.confirmTransaction.bind(wallet), + newBlock: wallet.newBlock.bind(wallet), + setProvider: wallet.setProvider.bind(wallet), + }) + duplex.pipe(connection).pipe(duplex) + connection.on('remote', function(remote){ + + // push updates to popup + wallet.on('update', sendUpdate) + eos(duplex, function unsubscribe(){ + wallet.removeListener('update', sendUpdate) + }) + function sendUpdate(state){ + remote.sendUpdate(state) + } + + }) + + + + // sub to metamask store } function handleExternalCommunication(remotePort){ diff --git a/app/scripts/lib/idmgmt.js b/app/scripts/lib/idmgmt.js index 795418bb9..3d0303406 100644 --- a/app/scripts/lib/idmgmt.js +++ b/app/scripts/lib/idmgmt.js @@ -1,3 +1,4 @@ +const inherits = require('util').inherits const EventEmitter = require('events').EventEmitter const async = require('async') const KeyStore = require('eth-lightwallet').keystore @@ -11,34 +12,18 @@ module.exports = IdentityManager var provider = null var pubsub = new EventEmitter() -pubsub.on('block', function(){ - updateIdentities() -}) -function IdentityManager(opts){ - opts = opts || {} - providerEngine = opts.providerEngine - return { - // plugin popup - getState: getState, - subscribe: subscribe, - submitPassword: submitPassword, - setSelectedAddress: setSelectedAddress, - signTransaction: signTransaction, - setLocked: setLocked, - // eth rpc - getAccounts: getAccounts, - confirmTransaction: confirmTransaction, - // etc - newBlock: newBlock, - setProvider: setProvider, - } +inherits(IdentityManager, EventEmitter) +function IdentityManager(opts){ + const self = this + self.on('block', function(){ + self.updateIdentities() + }) } // plugin popup IdentityManager.prototype.getState = getState -IdentityManager.prototype.subscribe = subscribe IdentityManager.prototype.submitPassword = submitPassword IdentityManager.prototype.setSelectedAddress = setSelectedAddress IdentityManager.prototype.signTransaction = signTransaction @@ -57,21 +42,8 @@ function setProvider(_provider){ } function newBlock(block){ - pubsub.emit('block', block) -} - -// on new block, update our accounts (but only if we're unlocked) -function subscribe(cb){ - pubsub.on('block', sendUpdateState) - // we're not unsubbing - // this causes errors and potentially breaks shit - // we should emit on change instead - // and background should handle unsubbing - function sendUpdateState(){ - if (!isUnlocked()) return - var state = _getState() - cb(state) - } + var self = this + self.emit('block', block) } function getState(cb){ @@ -105,6 +77,7 @@ function setSelectedAddress(address, cb){ } function submitPassword(password, cb){ + const self = this console.log('submitPassword:', password) tryPassword(password, function(err){ if (err) console.log('bad password:', password, err) @@ -112,11 +85,12 @@ function submitPassword(password, cb){ console.log('good password:', password) window.sessionStorage['password'] = password // load identities before returning... - loadIdentities() + self.loadIdentities() var state = _getState() cb(null, state) // trigger an update but dont wait for it - updateIdentities() + console.log(self) + self.updateIdentities() }) } @@ -132,7 +106,8 @@ function getIdentities(){ } // load identities from keyStore -function loadIdentities(){ +IdentityManager.prototype.loadIdentities = function(){ + const self = this if (!isUnlocked()) throw new Error('not unlocked') var keyStore = getKeyStore() var addresses = keyStore.getAddresses().map(function(address){ return '0x'+address }) @@ -146,18 +121,21 @@ function loadIdentities(){ } identities[address] = identity }) + self.emit('update', _getState()) } // foreach in identities, update balance + nonce -function updateIdentities(cb){ +IdentityManager.prototype.updateIdentities = function(cb){ + var self = this cb = cb || function(){} if (!isUnlocked()) return cb(new Error('Not unlocked.')) var addresses = Object.keys(identities) - async.map(addresses, updateIdentity, cb) + async.map(addresses, self.updateIdentity.bind(self), cb) } // gets latest info from the network for the identity -function updateIdentity(address, cb){ +IdentityManager.prototype.updateIdentity = function(address, cb){ + var self = this async.parallel([ getAccountBalance.bind(null, address), getTxCount.bind(null, address), @@ -166,6 +144,8 @@ function updateIdentity(address, cb){ var identity = identities[address] identity.balance = result[0] identity.txCount = result[1] + console.log('updated!') + self.emit('update', _getState()) cb() }) } diff --git a/app/scripts/lib/port-stream.js b/app/scripts/lib/port-stream.js index d256efc9a..7f3e8072e 100644 --- a/app/scripts/lib/port-stream.js +++ b/app/scripts/lib/port-stream.js @@ -12,6 +12,7 @@ function PortDuplexStream(port){ }) this._port = port port.onMessage.addListener(this._onMessage.bind(this)) + port.onDisconnect.addListener(this._onDisconnect.bind(this)) } // private @@ -21,6 +22,15 @@ PortDuplexStream.prototype._onMessage = function(msg){ this.push(msg) } +PortDuplexStream.prototype._onDisconnect = function(msg){ + // console.log('PortDuplexStream - saw message', msg) + try { + this.end() + } catch(err){ + this.emit('error', err) + } +} + // stream plumbing PortDuplexStream.prototype._read = noop diff --git a/app/scripts/popup.js b/app/scripts/popup.js index a7e33e7ff..ca88f4fa7 100644 --- a/app/scripts/popup.js +++ b/app/scripts/popup.js @@ -1,3 +1,4 @@ +const EventEmitter = require('events').EventEmitter const Dnode = require('dnode') const MetaMaskUi = require('metamask-ui') const MetaMaskUiCss = require('metamask-ui/css') @@ -8,11 +9,18 @@ const PortStream = require('./lib/port-stream.js') // setup communication with background var pluginPort = chrome.runtime.connect({name: 'popup'}) var duplex = new PortStream(pluginPort) +var eventEmitter = new EventEmitter() var background = Dnode({ // setUnconfirmedTxs: setUnconfirmedTxs, + sendUpdate: function(state){ + eventEmitter.emit('update', state) + }, }) duplex.pipe(background).pipe(duplex) -background.once('remote', setupApp) +background.once('remote', function(accountManager){ + accountManager.on = eventEmitter.on.bind(eventEmitter) + setupApp(accountManager) +}) // setup app var css = MetaMaskUiCss() diff --git a/package.json b/package.json index d40353cbc..68356c8a6 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "dependencies": { "async": "^1.4.0", "dnode": "^1.2.2", + "end-of-stream": "^1.1.0", "eth-lightwallet": "^1.0.1", "ethereumjs-tx": "^0.6.7", "ethereumjs-util": "^1.3.5", |