aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Finlay <dan@danfinlay.com>2016-09-07 06:29:36 +0800
committerDan Finlay <dan@danfinlay.com>2016-09-07 06:29:36 +0800
commit58a8f02294eb1079d92cdf1e6d05a74a224029c3 (patch)
treefb723445e877bc316b060edcbe76284edf05f889
parentb2ebb6032d3f99eb0e9eb90364a0cd95c7775bde (diff)
parent095a40e33d40bc02ef6a6b7379eb6c90e0b4c3d8 (diff)
downloadtangerine-wallet-browser-58a8f02294eb1079d92cdf1e6d05a74a224029c3.tar.gz
tangerine-wallet-browser-58a8f02294eb1079d92cdf1e6d05a74a224029c3.tar.zst
tangerine-wallet-browser-58a8f02294eb1079d92cdf1e6d05a74a224029c3.zip
Merge branch 'master' into ModularFiatBalance
-rw-r--r--CHANGELOG.md8
-rw-r--r--app/manifest.json2
-rw-r--r--app/scripts/lib/inpage-provider.js5
-rw-r--r--app/scripts/lib/notifications.js42
-rw-r--r--app/scripts/metamask-controller.js10
-rw-r--r--gulpfile.js49
-rw-r--r--package.json2
-rw-r--r--test/unit/metamask-controller-test.js97
8 files changed, 187 insertions, 28 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0e705adef..178879e8a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,8 +2,16 @@
## Current Master
+## 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
diff --git a/app/manifest.json b/app/manifest.json
index 5444007fa..0fee3f051 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "MetaMask",
"short_name": "Metamask",
- "version": "2.10.0",
+ "version": "2.10.2",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "Ethereum Browser Extension",
diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js
index 3b7d76c7d..4f9fa1a7d 100644
--- a/app/scripts/lib/inpage-provider.js
+++ b/app/scripts/lib/inpage-provider.js
@@ -80,7 +80,8 @@ MetamaskInpageProvider.prototype.send = function (payload) {
// throw not-supported Error
default:
- var message = 'The MetaMask Web3 object does not support synchronous methods. See https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#all-async---think-of-metamask-as-a-light-client for details.'
+ var message = 'The MetaMask Web3 object does not support synchronous methods like ' + payload.method +
+ '. See https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#all-async---think-of-metamask-as-a-light-client for details.'
throw new Error(message)
}
@@ -131,4 +132,4 @@ function eachJsonMessage(payload, transformFn){
} else {
return transformFn(payload)
}
-} \ No newline at end of file
+}
diff --git a/app/scripts/lib/notifications.js b/app/scripts/lib/notifications.js
index df4fe73dd..4e3f7558c 100644
--- a/app/scripts/lib/notifications.js
+++ b/app/scripts/lib/notifications.js
@@ -9,20 +9,26 @@ module.exports = notifications
window.METAMASK_NOTIFIER = notifications
function show () {
- getWindows((windows) => {
+ getPopup((err, popup) => {
+ if (err) throw err
- if (windows.length > 0) {
- const win = windows[0]
- return extension.windows.update(win.id, { focused: true })
- }
+ if (popup) {
+
+ // bring focus to existing popup
+ extension.windows.update(popup.id, { focused: true })
+
+ } else {
- extension.windows.create({
- url: 'notification.html',
- type: 'popup',
- focused: true,
- width: 360,
- height: 500,
- })
+ // create new popup
+ extension.windows.create({
+ url: 'notification.html',
+ type: 'popup',
+ focused: true,
+ width: 360,
+ height: 500,
+ })
+
+ }
})
}
@@ -38,19 +44,19 @@ function getWindows(cb) {
}
function getPopup(cb) {
- getWindows((windows) => {
- cb(getPopupIn(windows))
+ getWindows((err, windows) => {
+ if (err) throw err
+ cb(null, getPopupIn(windows))
})
}
function getPopupIn(windows) {
- return windows ? windows.find((win) => {
- return win.type === 'popup'
- }) : null
+ return windows ? windows.find((win) => win.type === 'popup') : null
}
function closePopup() {
- getPopup((popup) => {
+ getPopup((err, popup) => {
+ if (err) throw err
if (!popup) return
extension.windows.remove(popup.id, console.error)
})
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index e94db2dfd..83827ec76 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -199,6 +199,9 @@ module.exports = class MetamaskController {
const idStore = this.idStore
var state = idStore.getState()
+ let err = this.enforceTxValidations(txParams)
+ if (err) return onTxDoneCb(err)
+
// It's locked
if (!state.isUnlocked) {
@@ -216,6 +219,13 @@ module.exports = class MetamaskController {
}
}
+ enforceTxValidations (txParams) {
+ if (txParams.value.indexOf('-') === 0) {
+ const msg = `Invalid transaction value of ${txParams.value} not a positive number.`
+ return new Error(msg)
+ }
+ }
+
newUnsignedMessage (msgParams, cb) {
var state = this.idStore.getState()
if (!state.isUnlocked) {
diff --git a/gulpfile.js b/gulpfile.js
index dac6cce3e..9f1acbf67 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -16,6 +16,10 @@ var eslint = require('gulp-eslint')
var fs = require('fs')
var path = require('path')
var manifest = require('./app/manifest.json')
+var gulpif = require('gulp-if')
+var replace = require('gulp-replace')
+
+var disableLiveReload = gutil.env.disableLiveReload
// browser reload
@@ -72,8 +76,8 @@ gulp.task('copy:root', copyTask({
pattern: '/*',
}))
-gulp.task('manifest:cleanup', function() {
- return gulp.src('./dist/firefox/manifest.json')
+gulp.task('manifest:chrome', function() {
+ return gulp.src('./dist/chrome/manifest.json')
.pipe(jsoneditor(function(json) {
delete json.applications
return json
@@ -81,7 +85,33 @@ gulp.task('manifest:cleanup', function() {
.pipe(gulp.dest('./dist/chrome', { overwrite: true }))
})
-gulp.task('copy', gulp.series(gulp.parallel('copy:locales','copy:images','copy:fonts','copy:reload','copy:root'), 'manifest:cleanup'))
+gulp.task('manifest:production', function() {
+ return gulp.src([
+ './dist/firefox/manifest.json',
+ './dist/chrome/manifest.json',
+ './dist/edge/manifest.json',
+ ],{base: './dist/'})
+ .pipe(gulpif(disableLiveReload,jsoneditor(function(json) {
+ json.background.scripts = ["scripts/background.js"]
+ return json
+ })))
+ .pipe(gulp.dest('./dist/', { overwrite: true }))
+})
+
+const staticFiles = [
+ 'locales',
+ 'images',
+ 'fonts',
+ 'root'
+]
+
+var copyStrings = staticFiles.map(staticFile => `copy:${staticFile}`)
+
+if (!disableLiveReload) {
+ copyStrings.push('copy:reload')
+}
+
+gulp.task('copy', gulp.series(gulp.parallel(...copyStrings), 'manifest:production', 'manifest:chrome'))
gulp.task('copy:watch', function(){
gulp.watch(['./app/{_locales,images}/*', './app/scripts/chromereload.js', './app/*.{html,json}'], gulp.series('copy'))
})
@@ -115,14 +145,18 @@ const jsFiles = [
'popup',
]
+var jsDevStrings = jsFiles.map(jsFile => `dev:js:${jsFile}`)
+var jsBuildStrings = jsFiles.map(jsFile => `build:js:${jsFile}`)
+
jsFiles.forEach((jsFile) => {
gulp.task(`dev:js:${jsFile}`, bundleTask({ watch: true, filename: `${jsFile}.js` }))
gulp.task(`build:js:${jsFile}`, bundleTask({ watch: false, filename: `${jsFile}.js` }))
})
-gulp.task('dev:js', gulp.parallel('dev:js:inpage','dev:js:contentscript','dev:js:background','dev:js:popup'))
+gulp.task('dev:js', gulp.parallel(...jsDevStrings))
+
+gulp.task('build:js', gulp.parallel(...jsBuildStrings))
-gulp.task('build:js', gulp.parallel('build:js:inpage','build:js:contentscript','build:js:background','build:js:popup'))
// clean dist
@@ -152,6 +186,7 @@ gulp.task('zip', gulp.parallel('zip:chrome', 'zip:firefox', 'zip:edge'))
// high level tasks
gulp.task('dev', gulp.series('dev:js', 'copy', gulp.parallel('copy:watch', 'dev:reload')))
+
gulp.task('build', gulp.series('clean', gulp.parallel('build:js', 'copy')))
gulp.task('dist', gulp.series('build', 'zip'))
@@ -170,7 +205,7 @@ function copyTask(opts){
destinations.forEach(function(destination) {
stream = stream.pipe(gulp.dest(destination))
})
- stream.pipe(livereload())
+ stream.pipe(gulpif(!disableLiveReload,livereload()))
return stream
}
@@ -211,7 +246,7 @@ function bundleTask(opts) {
.pipe(gulp.dest('./dist/firefox/scripts'))
.pipe(gulp.dest('./dist/chrome/scripts'))
.pipe(gulp.dest('./dist/edge/scripts'))
- .pipe(livereload())
+ .pipe(gulpif(!disableLiveReload,livereload()))
)
}
diff --git a/package.json b/package.json
index fdf6c822e..63754f417 100644
--- a/package.json
+++ b/package.json
@@ -94,8 +94,10 @@
"del": "^2.2.0",
"gulp": "github:gulpjs/gulp#4.0",
"gulp-brfs": "^0.1.0",
+ "gulp-if": "^2.0.1",
"gulp-json-editor": "^2.2.1",
"gulp-livereload": "^3.8.1",
+ "gulp-replace": "^0.5.4",
"gulp-sourcemaps": "^1.6.0",
"gulp-util": "^3.0.7",
"gulp-watch": "^4.3.5",
diff --git a/test/unit/metamask-controller-test.js b/test/unit/metamask-controller-test.js
new file mode 100644
index 000000000..b87169ca2
--- /dev/null
+++ b/test/unit/metamask-controller-test.js
@@ -0,0 +1,97 @@
+var assert = require('assert')
+var MetaMaskController = require('../../app/scripts/metamask-controller')
+var sinon = require('sinon')
+var extend = require('xtend')
+const STORAGE_KEY = 'metamask-config'
+
+describe('MetaMaskController', function() {
+ const noop = () => {}
+ let controller = new MetaMaskController({
+ showUnconfirmedMessage: noop,
+ unlockAccountMessage: noop,
+ showUnconfirmedTx: noop,
+ setData,
+ loadData,
+ })
+
+ beforeEach(function() {
+ // sinon allows stubbing methods that are easily verified
+ this.sinon = sinon.sandbox.create()
+ window.localStorage = {} // Hacking localStorage support into JSDom
+ })
+
+ afterEach(function() {
+ // sinon requires cleanup otherwise it will overwrite context
+ this.sinon.restore()
+ })
+
+ describe('#enforceTxValidations', function () {
+ it('returns null for positive values', function() {
+ var sample = {
+ value: '0x01'
+ }
+ var res = controller.enforceTxValidations(sample)
+ assert.equal(res, null, 'no error')
+ })
+
+
+ it('returns error for negative values', function() {
+ var sample = {
+ value: '-0x01'
+ }
+ var res = controller.enforceTxValidations(sample)
+ assert.ok(res, 'error')
+ })
+ })
+})
+
+
+function loadData () {
+ var oldData = getOldStyleData()
+ var newData
+ try {
+ newData = JSON.parse(window.localStorage[STORAGE_KEY])
+ } catch (e) {}
+
+ var data = extend({
+ meta: {
+ version: 0,
+ },
+ data: {
+ config: {
+ provider: {
+ type: 'testnet',
+ },
+ },
+ },
+ }, oldData || null, newData || null)
+ return data
+}
+
+function getOldStyleData () {
+ var config, wallet, seedWords
+
+ var result = {
+ meta: { version: 0 },
+ data: {},
+ }
+
+ try {
+ config = JSON.parse(window.localStorage['config'])
+ result.data.config = config
+ } catch (e) {}
+ try {
+ wallet = JSON.parse(window.localStorage['lightwallet'])
+ result.data.wallet = wallet
+ } catch (e) {}
+ try {
+ seedWords = window.localStorage['seedWords']
+ result.data.seedWords = seedWords
+ } catch (e) {}
+
+ return result
+}
+
+function setData (data) {
+ window.localStorage[STORAGE_KEY] = JSON.stringify(data)
+}