diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d5a1592d..b2d78b6b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Remove rejected transactions from transaction history - Add Trezor Support - Allow to remove accounts (Imported and Hardware Wallets) +- [#4840](https://github.com/MetaMask/metamask-extension/pull/4840): Now shows notifications when transactions are completed. ## 4.8.0 Thur Jun 14 2018 diff --git a/app/manifest.json b/app/manifest.json index b67cef025..52256c5b7 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -63,7 +63,8 @@ "activeTab", "webRequest", "*://*.eth/", - "*://*.test/" + "*://*.test/", + "notifications" ], "web_accessible_resources": [ "inpage.js" diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 6f5908414..e629d1359 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -175,6 +175,13 @@ module.exports = class MetamaskController extends EventEmitter { }) this.txController.on('newUnapprovedTx', opts.showUnapprovedTx.bind(opts)) + this.txController.on(`tx:status-update`, (txId, status) => { + if (status === 'confirmed' || status === 'failed') { + const txMeta = this.txController.txStateManager.getTx(txId) + this.platform.showTransactionNotification(txMeta) + } + }) + // computed balances (accounting for pending transactions) this.balancesController = new BalancesController({ accountTracker: this.accountTracker, diff --git a/app/scripts/platforms/extension.js b/app/scripts/platforms/extension.js index f8dd767dc..901c26cab 100644 --- a/app/scripts/platforms/extension.js +++ b/app/scripts/platforms/extension.js @@ -1,4 +1,5 @@ const extension = require('extensionizer') +const explorerLink = require('etherscan-link').createExplorerLink class ExtensionPlatform { @@ -34,6 +35,59 @@ class ExtensionPlatform { cb(e) } } + + showTransactionNotification (txMeta) { + + const status = txMeta.status + if (status === 'confirmed') { + this._showConfirmedTransaction(txMeta) + } else if (status === 'failed') { + this._showFailedTransaction(txMeta) + } + } + + _showConfirmedTransaction (txMeta) { + + this._subscribeToNotificationClicked() + + const url = explorerLink(txMeta.hash, parseInt(txMeta.metamaskNetworkId)) + const nonce = parseInt(txMeta.txParams.nonce, 16) + + const title = 'Confirmed transaction' + const message = `Transaction ${nonce} confirmed! View on EtherScan` + this._showNotification(title, message, url) + } + + _showFailedTransaction (txMeta) { + + const nonce = parseInt(txMeta.txParams.nonce, 16) + const title = 'Failed transaction' + const message = `Transaction ${nonce} failed! ${txMeta.err.message}` + this._showNotification(title, message) + } + + _showNotification (title, message, url) { + extension.notifications.create( + url, + { + 'type': 'basic', + 'title': title, + 'iconUrl': extension.extension.getURL('../../images/icon-64.png'), + 'message': message, + }) + } + + _subscribeToNotificationClicked () { + if (!extension.notifications.onClicked.hasListener(this._viewOnEtherScan)) { + extension.notifications.onClicked.addListener(this._viewOnEtherScan) + } + } + + _viewOnEtherScan (txId) { + if (txId.startsWith('http://')) { + global.metamaskController.platform.openWindow({ url: txId }) + } + } } module.exports = ExtensionPlatform