diff --git a/app/scripts/background.js b/app/scripts/background.js index 2dd5c88c7..fbf80c7a3 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -1,53 +1,103 @@ const identitiesUrl = 'https://alpha.metamask.io/identities/' const messagingChannelName = 'metamask' -var pendingTxs = [] +var unconfirmedTxs = {} // setup badge click handler chrome.browserAction.onClicked.addListener(function(activeTab) { chrome.tabs.create({ url: identitiesUrl }) }) -// setup page<->plugin messaging +// setup content-background messaging chrome.runtime.onConnect.addListener(function(port) { - console.assert(port.name == messagingChannelName) - port.onMessage.addListener(function(msg) { - addTransaction(msg.payload) - }) + port.onMessage.addListener(handleMessage) }) // listen to storage changes -// chrome.storage.onChanged.addListener(function(changes, namespace) { -// for (key in changes) { -// var storageChange = changes[key] -// console.log('Storage key "%s" in namespace "%s" changed. ' + -// 'Old value was "%s", new value is "%s".', -// key, -// namespace, -// storageChange.oldValue, -// storageChange.newValue) -// } -// }) - -// // Save it using the Chrome extension storage API. -// chrome.storage.sync.set({'zzz': 22}, function() { -// // Notify that we saved. -// console.log('Settings saved') -// }) - -// update badge text +chrome.storage.onChanged.addListener(function(changes, namespace) { + for (key in changes) { + var storageChange = changes[key] + console.log('Storage key "%s" in namespace "%s" changed. ' + + 'Old value was "%s", new value is:', + key, + namespace, + storageChange.oldValue, + storageChange.newValue) + if (storageChange.oldValue && !storageChange.newValue) { + // was removed + removeTransaction(storageChange.oldValue) + } else if (!storageChange.oldValue && storageChange.newValue) { + // was added + addTransaction(deserializeTx(storageChange.newValue)) + } + } +}) + +// setup badge text updateBadge() +function handleMessage(msg){ + console.log('got message!', msg.type) + switch(msg.type){ + + case 'addUnconfirmedTx': + addTransaction(msg.payload) + return + + case 'removeUnconfirmedTx': + removeTransaction(msg.payload) + return + + } +} function addTransaction(tx){ - pendingTxs.push(tx) + var serialized = serializeTx(tx) + var hash = simpleHash(serialized) + console.log('add tx: ', tx.id, hash, serializeTx(tx), tx) + unconfirmedTxs[hash] = tx + var data = {} + data[hash] = serialized + chrome.storage.sync.set(data) + // trigger ui changes + updateBadge() +} + +function removeTransaction(serialized){ + var hash = simpleHash(serialized) + delete unconfirmedTxs[hash] + var data = {} + data[hash] = undefined + chrome.storage.sync.set(data) + // trigger ui changes updateBadge() } function updateBadge(){ var label = '' - if (pendingTxs.length) { - label = String(pendingTxs.length) + var count = Object.keys(unconfirmedTxs).length + if (count) { + label = String(count) } chrome.browserAction.setBadgeText({text: label}) + chrome.browserAction.setBadgeBackgroundColor({color: '#506F8B'}) +} + +function simpleHash(input) { + var hash = 0, i, chr, len + if (input.length == 0) return hash + for (i = 0, len = input.length; i < len; i++) { + chr = input.charCodeAt(i) + hash = ((hash << 5) - hash) + chr + hash |= 0 // Convert to 32bit integer + } + return hash +} + +function serializeTx(tx){ + return JSON.stringify(tx) +} + +function deserializeTx(tx){ + return JSON.parse(tx) } \ No newline at end of file diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index 53ec9eef5..0493921f0 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -1,4 +1,5 @@ -const messageType = 'metamaskMessage' +const allowedMessageTarget = 'metamask' +const allowedMessageType = 'addUnconfirmedTx' // inject in-page script @@ -8,18 +9,17 @@ scriptTag.onload = function() { this.parentNode.removeChild(this) } var container = document.head || document.documentElement container.appendChild(scriptTag) -// listen for messages +// setup connection with background var metamaskPlugin = chrome.runtime.connect({name: 'metamask'}) -// metamaskPlugin.onMessage.addListener(function(msg) { -// console.log(msg) -// }) +// forward messages from inpage to background window.addEventListener('message', receiveMessage, false); function receiveMessage(event){ var msg = event.data // validate message type if (typeof msg !== 'object') return - if (msg.type !== messageType) return + if (msg.to !== allowedMessageTarget) return + if (msg.type !== allowedMessageType) return // forward message metamaskPlugin.postMessage(msg) } \ No newline at end of file diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js index 006a8e0bb..1d264975e 100644 --- a/app/scripts/inpage.js +++ b/app/scripts/inpage.js @@ -2,8 +2,9 @@ const web3 = require('web3') const MetamaskProvider = require('./lib/metamask-provider.js') const rpcUrl = 'https://rpc.metamask.io' -const messageType = 'metamaskMessage' const documentOrigin = window.location.origin +const allowedMessageTarget = 'metamask' +const allowedMessageType = 'addUnconfirmedTx' var provider = new MetamaskProvider(forwardPayload, rpcUrl) @@ -15,7 +16,8 @@ window.web3 = web3 function forwardPayload(payload){ window.postMessage({ - type: messageType, + to: allowedMessageTarget, + type: allowedMessageType, payload: payload, }, documentOrigin) } \ No newline at end of file