diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e6bc5299..9d89c2438 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,37 @@ ## Current Master +- Fix bug where pending transactions from Test net (or other networks) show up In Main net. +- Add fiat conversion values to more views. +- On fresh install, open a new tab with the MetaMask Introduction video. Does not open on update. +- Block negative values from transactions. +- Fixed a memory leak. +- MetaMask logo now renders as super lightweight SVG, improving compatibility and performance. +- Now showing loading indication during vault unlocking, to clarify behavior for users who are experience slow unlocks. +- Now only initially creates one wallet when restoring a vault, to reduce some users' confusion. + +## 2.10.2 2016-09-02 + +- Fix bug where notification popup would not display. + +## 2.10.1 2016-09-02 + +- Fix bug where provider menu did not allow switching to custom network from a custom network. +- Sending a transaction from within MetaMask no longer triggers a popup. +- The ability to build without livereload features (such as for production) can be enabled with the gulp --disableLiveReload flag. +- Fix Ethereum JSON RPC Filters bug. + +## 2.10.0 2016-08-29 + +- Changed transaction approval from notifications system to popup system. +- Add a back button to locked screen to allow restoring vault from seed words when password is forgotten. +- Forms now retain their values even when closing the popup and reopening it. +- Fixed a spelling error in provider menu. + ## 2.9.2 2016-08-24 - Fixed shortcut bug from preventing installation. - ## 2.9.1 2016-08-24 - Added static image as fallback for when WebGL isn't supported. @@ -27,7 +53,7 @@ ## 2.8.0 2016-08-15 - Integrate ShapeShift -- Add a for for Coinbase to specify amount to buy +- Add a form for Coinbase to specify amount to buy - Fix various typos. - Make dapp-metamask connection more reliable - Remove Ethereum Classic from provider menu. diff --git a/README.md b/README.md index 4c348b56c..afdda4d97 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ # MetaMask Plugin [![Build Status](https://circleci.com/gh/MetaMask/metamask-plugin.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-plugin) +## Developing Compatible Dapps + +If you're a web dapp developer, we've got two types of guides for you: + +- If you've never built a Dapp before, we've got a gentle introduction on [Developing Dapps with Truffle and MetaMask](https://blog.metamask.io/developing-for-metamask-with-truffle/). +- If you have a Dapp, and you want to ensure compatibility, [here is our guide on building MetaMask-compatible Dapps](https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md) + ## Building locally - Install [Node.js](https://nodejs.org/en/) version 6.3.1 or later. diff --git a/app/manifest.json b/app/manifest.json index e5e08c4b6..0fee3f051 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,8 +1,9 @@ { "name": "MetaMask", "short_name": "Metamask", - "version": "2.9.2", + "version": "2.10.2", "manifest_version": 2, + "author": "https://metamask.io", "description": "Ethereum Browser Extension", "commands": { "_execute_browser_action": { @@ -28,7 +29,8 @@ "scripts": [ "scripts/chromereload.js", "scripts/background.js" - ] + ], + "persistent": true }, "browser_action": { "default_icon": { diff --git a/app/notification.html b/app/notification.html new file mode 100644 index 000000000..cc485da7f --- /dev/null +++ b/app/notification.html @@ -0,0 +1,16 @@ + + + + + MetaMask Notification + + + +
+ + + diff --git a/app/scripts/background.js b/app/scripts/background.js index e04309e74..58228a41a 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -3,9 +3,7 @@ const extend = require('xtend') const Dnode = require('dnode') const eos = require('end-of-stream') const PortStream = require('./lib/port-stream.js') -const createUnlockRequestNotification = require('./lib/notifications.js').createUnlockRequestNotification -const createTxNotification = require('./lib/notifications.js').createTxNotification -const createMsgNotification = require('./lib/notifications.js').createMsgNotification +const notification = require('./lib/notifications.js') const messageManager = require('./lib/message-manager') const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex const MetamaskController = require('./metamask-controller') @@ -26,50 +24,32 @@ const controller = new MetamaskController({ const idStore = controller.idStore function unlockAccountMessage () { - createUnlockRequestNotification({ - title: 'Account Unlock Request', - }) + notification.show() } function showUnconfirmedMessage (msgParams, msgId) { - var controllerState = controller.getState() - - 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), - }) + notification.show() } function showUnconfirmedTx (txParams, txData, onTxDoneCb) { - var controllerState = controller.getState() - - 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), - }) + notification.show() } +// On first install, open a window to MetaMask website to how-it-works. + +extension.runtime.onInstalled.addListener(function (details) { + if (details.reason === 'install') { + extension.tabs.create({url: 'https://metamask.io/#how-it-works'}) + } +}) + // // connect to other contexts // 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 @@ -109,7 +89,7 @@ function setupControllerConnection (stream) { dnode.on('remote', (remote) => { // push updates to popup controller.ethStore.on('update', controller.sendUpdate.bind(controller)) - controller.remote = remote + controller.listeners.push(remote) idStore.on('update', controller.sendUpdate.bind(controller)) // teardown on disconnect @@ -188,5 +168,3 @@ function getOldStyleData () { function setData (data) { window.localStorage[STORAGE_KEY] = JSON.stringify(data) } - -function noop () {} diff --git a/app/scripts/chromereload.js b/app/scripts/chromereload.js index 88333ba8a..f0bae403c 100644 --- a/app/scripts/chromereload.js +++ b/app/scripts/chromereload.js @@ -324,13 +324,13 @@ window.LiveReloadOptions = { host: 'localhost' }; this.pluginIdentifiers = {} this.console = this.window.console && this.window.console.log && this.window.console.error ? this.window.location.href.match(/LR-verbose/) ? this.window.console : { log: function () {}, - error: this.window.console.error.bind(this.window.console), + error: console.error, } : { log: function () {}, error: function () {}, } if (!(this.WebSocket = this.window.WebSocket || this.window.MozWebSocket)) { - this.console.error('LiveReload disabled because the browser does not seem to support web sockets') + console.error('LiveReload disabled because the browser does not seem to support web sockets') return } if ('LiveReloadOptions' in window) { @@ -344,7 +344,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } else { this.options = Options.extract(this.window.document) if (!this.options) { - this.console.error('LiveReload disabled because it could not find its own