From db48f8984f8e16b2831aab36cd538d241cb41402 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Tue, 21 Feb 2017 12:32:13 -0800 Subject: [PATCH 01/52] Basic infrasture for RPC list added. --- app/scripts/lib/controllers/preferences.js | 26 +++++++++++++++++++--- app/scripts/metamask-controller.js | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/app/scripts/lib/controllers/preferences.js b/app/scripts/lib/controllers/preferences.js index dc9464c4e..2d5a1addd 100644 --- a/app/scripts/lib/controllers/preferences.js +++ b/app/scripts/lib/controllers/preferences.js @@ -4,7 +4,7 @@ const normalizeAddress = require('../sig-util').normalize class PreferencesController { constructor (opts = {}) { - const initState = opts.initState || {} + const initState = opts.initState || { frequentRPCList: [] } this.store = new ObservableStore(initState) } @@ -12,7 +12,7 @@ class PreferencesController { // PUBLIC METHODS // - setSelectedAddress(_address) { + setSelectedAddress (_address) { return new Promise((resolve, reject) => { const address = normalizeAddress(_address) this.store.updateState({ selectedAddress: address }) @@ -20,10 +20,30 @@ class PreferencesController { }) } - getSelectedAddress(_address) { + getSelectedAddress (_address) { return this.store.getState().selectedAddress } + addToFrequentRPCList (_url) { + return new Promise((resolve, reject) => { + let rpcList = this.getFrequentRPCList() + let index = rpcList.findIndex((element) => { element === _url }) + if (index) { + rpcList.splice(index, 1) + } + if (rpcList.length >= 3) { + rpcList.shift() + } + rpcList.push(_url) + this.store.updateState({ frequentRPCList: rpcList }) + resolve() + }) + } + + getFrequentRPCList () { + return this.store.getState().frequentRPCList + } + // // PRIVATE METHODS // diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 29b13dc62..54c2ebb2c 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -259,6 +259,7 @@ module.exports = class MetamaskController extends EventEmitter { // PreferencesController setSelectedAddress: nodeify(preferencesController.setSelectedAddress).bind(preferencesController), + setFrequentRPCList: nodeify(preferencesController.setFrequentRPCList).bind(preferencesController), // KeyringController setLocked: nodeify(keyringController.setLocked).bind(keyringController), From 026e0e3383cedf290b2cb55e663f158e7f1c1a68 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Tue, 21 Feb 2017 12:51:46 -0800 Subject: [PATCH 02/52] Fix naming --- app/scripts/lib/controllers/preferences.js | 4 ++-- app/scripts/metamask-controller.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/scripts/lib/controllers/preferences.js b/app/scripts/lib/controllers/preferences.js index 2d5a1addd..b28f31b4b 100644 --- a/app/scripts/lib/controllers/preferences.js +++ b/app/scripts/lib/controllers/preferences.js @@ -24,7 +24,7 @@ class PreferencesController { return this.store.getState().selectedAddress } - addToFrequentRPCList (_url) { + addToFrequentRpcList (_url) { return new Promise((resolve, reject) => { let rpcList = this.getFrequentRPCList() let index = rpcList.findIndex((element) => { element === _url }) @@ -40,7 +40,7 @@ class PreferencesController { }) } - getFrequentRPCList () { + getFrequentRpcList () { return this.store.getState().frequentRPCList } diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 54c2ebb2c..da186d958 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -259,7 +259,7 @@ module.exports = class MetamaskController extends EventEmitter { // PreferencesController setSelectedAddress: nodeify(preferencesController.setSelectedAddress).bind(preferencesController), - setFrequentRPCList: nodeify(preferencesController.setFrequentRPCList).bind(preferencesController), + addToFrequentRpcList: nodeify(preferencesController.addToFrequentRpcList).bind(preferencesController), // KeyringController setLocked: nodeify(keyringController.setLocked).bind(keyringController), From 17a7436602191d11bb02771a87bd74f7baeb49ea Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Tue, 21 Feb 2017 12:51:56 -0800 Subject: [PATCH 03/52] Connect to actions. --- ui/app/actions.js | 1 + ui/app/config.js | 1 + 2 files changed, 2 insertions(+) diff --git a/ui/app/actions.js b/ui/app/actions.js index 6552e7f5c..a39646f33 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -628,6 +628,7 @@ function markAccountsFound() { function setRpcTarget (newRpc) { if (global.METAMASK_DEBUG) console.log(`background.setRpcTarget`) background.setRpcTarget(newRpc) + background.addToFrequentRpcList(newRpc) return { type: actions.SET_RPC_TARGET, value: newRpc, diff --git a/ui/app/config.js b/ui/app/config.js index 65b1ed712..00a4cba88 100644 --- a/ui/app/config.js +++ b/ui/app/config.js @@ -5,6 +5,7 @@ const connect = require('react-redux').connect const actions = require('./actions') const currencies = require('./conversion.json').rows const validUrl = require('valid-url') + module.exports = connect(mapStateToProps)(ConfigScreen) function mapStateToProps (state) { From 7a0ce31bd31a3d6f1a92bbaded71b040ca765065 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 22 Feb 2017 15:12:56 -0800 Subject: [PATCH 04/52] Implemented functionality for displaying recent custom RPCs --- app/scripts/lib/controllers/preferences.js | 29 +++++++++++----------- ui/app/actions.js | 5 ++-- ui/app/app.js | 23 +++++++++++++++++ 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/app/scripts/lib/controllers/preferences.js b/app/scripts/lib/controllers/preferences.js index b28f31b4b..8cc320179 100644 --- a/app/scripts/lib/controllers/preferences.js +++ b/app/scripts/lib/controllers/preferences.js @@ -1,10 +1,11 @@ const ObservableStore = require('obs-store') const normalizeAddress = require('../sig-util').normalize +const extend = require('xtend') class PreferencesController { constructor (opts = {}) { - const initState = opts.initState || { frequentRPCList: [] } + const initState = extend({ frequentRpcList: [] }, opts.initState) this.store = new ObservableStore(initState) } @@ -25,23 +26,23 @@ class PreferencesController { } addToFrequentRpcList (_url) { - return new Promise((resolve, reject) => { - let rpcList = this.getFrequentRPCList() - let index = rpcList.findIndex((element) => { element === _url }) - if (index) { - rpcList.splice(index, 1) - } - if (rpcList.length >= 3) { - rpcList.shift() - } + let rpcList = this.getFrequentRpcList() + let index = rpcList.findIndex((element) => { return element === _url }) + if (index !== -1) { + rpcList.splice(index, 1) + } + if (_url !== 'http://localhost:8545') { rpcList.push(_url) - this.store.updateState({ frequentRPCList: rpcList }) - resolve() - }) + } + if (rpcList.length > 2) { + rpcList.shift() + } + this.store.updateState({ frequentRpcList: rpcList }) + return Promise.resolve() } getFrequentRpcList () { - return this.store.getState().frequentRPCList + return this.store.getState().frequentRpcList } // diff --git a/ui/app/actions.js b/ui/app/actions.js index a39646f33..86638fc91 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -627,8 +627,9 @@ function markAccountsFound() { function setRpcTarget (newRpc) { if (global.METAMASK_DEBUG) console.log(`background.setRpcTarget`) - background.setRpcTarget(newRpc) - background.addToFrequentRpcList(newRpc) + background.addToFrequentRpcList(newRpc, () => { + background.setRpcTarget(newRpc) + }) return { type: actions.SET_RPC_TARGET, value: newRpc, diff --git a/ui/app/app.js b/ui/app/app.js index 6e249b09e..08a4326fe 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -58,6 +58,7 @@ function mapStateToProps (state) { forgottenPassword: state.appState.forgottenPassword, lastUnreadNotice: state.metamask.lastUnreadNotice, lostAccounts: state.metamask.lostAccounts, + frequentRpcList: state.metamask.frequentRpcList } } @@ -210,6 +211,7 @@ App.prototype.renderAppBar = function () { App.prototype.renderNetworkDropdown = function () { const props = this.props + const rpcList = props.frequentRpcList const state = this.state || {} const isOpen = state.isNetworkMenuOpen @@ -261,6 +263,7 @@ App.prototype.renderNetworkDropdown = function () { }), this.renderCustomOption(props.provider), + this.renderCommonRpc(rpcList, props.provider), props.isUnlocked && h(DropMenuItem, { label: 'Custom RPC', @@ -508,3 +511,23 @@ App.prototype.renderCustomOption = function (provider) { }) } } + +App.prototype.renderCommonRpc = function (rpcList, provider) { + const { rpcTarget } = provider + const props = this.props + + return rpcList.map((rpc) => { + if ((rpc === 'http://localhost:8545') || (rpc === rpcTarget)) { + return null + } else { + return h(DropMenuItem, { + label: rpc, + closeMenu: () => this.setState({ isNetworkMenuOpen: false }), + action: () => props.dispatch(actions.setRpcTarget(rpc)), + icon: h('i.fa.fa-question-circle.fa-lg'), + activeNetworkRender: rpc, + }) + } + }) + +} From 761eb49586664f8abc62ee89271a6cea95cd23f5 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 22 Feb 2017 15:13:29 -0800 Subject: [PATCH 05/52] Changelog. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d347d2333..c98fa69c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Current Master +- Add two most recently used custom RPCs to network dropdown menu. + ## 3.3.0 2017-2-20 - Add personal_sign and personal_ecRecover support. From 1d0f5fb51c355e6833d2e935a63d4957f0971f1e Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 22 Feb 2017 15:13:59 -0800 Subject: [PATCH 06/52] Linto --- ui/app/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/app.js b/ui/app/app.js index 08a4326fe..c1358f50f 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -58,7 +58,7 @@ function mapStateToProps (state) { forgottenPassword: state.appState.forgottenPassword, lastUnreadNotice: state.metamask.lastUnreadNotice, lostAccounts: state.metamask.lostAccounts, - frequentRpcList: state.metamask.frequentRpcList + frequentRpcList: state.metamask.frequentRpcList, } } From 3be6ee5f6cc5e7b79a8eeea182f91a15eb9ed989 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 22 Feb 2017 15:32:01 -0800 Subject: [PATCH 07/52] Make the UI play nice with empty RPC lists. --- development/states/first-time.json | 1 + ui/app/app.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/development/states/first-time.json b/development/states/first-time.json index 108af9117..3554ee911 100644 --- a/development/states/first-time.json +++ b/development/states/first-time.json @@ -4,6 +4,7 @@ "isUnlocked": false, "rpcTarget": "https://rawtestrpc.metamask.io/", "identities": {}, + "frequentRpcList": [], "unapprovedTxs": {}, "currentFiat": "USD", "conversionRate": 12.7527416, diff --git a/ui/app/app.js b/ui/app/app.js index c1358f50f..d61f93dd2 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -58,7 +58,7 @@ function mapStateToProps (state) { forgottenPassword: state.appState.forgottenPassword, lastUnreadNotice: state.metamask.lastUnreadNotice, lostAccounts: state.metamask.lostAccounts, - frequentRpcList: state.metamask.frequentRpcList, + frequentRpcList: state.metamask.frequentRpcList || [], } } From 62854398f1d3c72a82ae9d4feb03d9a1a947534e Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 23 Feb 2017 13:56:58 -0800 Subject: [PATCH 08/52] Tested against code to play nice with unit tests. --- app/scripts/lib/controllers/preferences.js | 13 ++++++++-- app/scripts/metamask-controller.js | 2 +- test/unit/actions/config_test.js | 28 +++++++++++++++++++--- ui/app/actions.js | 18 +++++++++----- ui/app/app.js | 4 +++- ui/app/reducers/metamask.js | 3 ++- 6 files changed, 54 insertions(+), 14 deletions(-) diff --git a/app/scripts/lib/controllers/preferences.js b/app/scripts/lib/controllers/preferences.js index 8cc320179..7bd2e5631 100644 --- a/app/scripts/lib/controllers/preferences.js +++ b/app/scripts/lib/controllers/preferences.js @@ -25,6 +25,14 @@ class PreferencesController { return this.store.getState().selectedAddress } + updateFrequentRpcList (_url) { + return this.addToFrequentRpcList(_url) + .then((rpcList) => { + this.store.updateState({ frequentRpcList: rpcList }) + return rpcList + }) + } + addToFrequentRpcList (_url) { let rpcList = this.getFrequentRpcList() let index = rpcList.findIndex((element) => { return element === _url }) @@ -37,8 +45,7 @@ class PreferencesController { if (rpcList.length > 2) { rpcList.shift() } - this.store.updateState({ frequentRpcList: rpcList }) - return Promise.resolve() + return Promise.resolve(rpcList) } getFrequentRpcList () { @@ -49,6 +56,8 @@ class PreferencesController { // PRIVATE METHODS // + + } module.exports = PreferencesController diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index da186d958..ad67a5875 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -259,7 +259,7 @@ module.exports = class MetamaskController extends EventEmitter { // PreferencesController setSelectedAddress: nodeify(preferencesController.setSelectedAddress).bind(preferencesController), - addToFrequentRpcList: nodeify(preferencesController.addToFrequentRpcList).bind(preferencesController), + updateFrequentRpcList: nodeify(preferencesController.updateFrequentRpcList).bind(preferencesController), // KeyringController setLocked: nodeify(keyringController.setLocked).bind(keyringController), diff --git a/test/unit/actions/config_test.js b/test/unit/actions/config_test.js index f851e4102..fea0cf0ba 100644 --- a/test/unit/actions/config_test.js +++ b/test/unit/actions/config_test.js @@ -11,6 +11,7 @@ describe ('config view actions', function() { var initialState = { metamask: { rpcTarget: 'foo', + frequentRpcList: [] }, appState: { currentView: { @@ -30,15 +31,36 @@ describe ('config view actions', function() { describe('SET_RPC_TARGET', function() { it('sets the state.metamask.rpcTarget property of the state to the action.value', function() { + const value = { + rpcTarget: 'foo', + frequentRpcList: ['foo'] + } const action = { type: actions.SET_RPC_TARGET, - value: 'bar', + value, } var result = reducers(initialState, action) assert.equal(result.metamask.provider.type, 'rpc') - assert.equal(result.metamask.provider.rpcTarget, action.value) + assert.equal(result.metamask.provider.rpcTarget, value.rpcTarget) + assert.equal(result.metamask.frequentRpcList[0], value.frequentRpcList[0]) + }) + + it('should handle multiple requests to change the rpc gracefully', function() { + const value = { + rpcTarget: 'foo', + frequentRpcList: ['foo'] + } + + const action = { + type: actions.SET_RPC_TARGET, + value, + } + + var result = reducers(initialState, action) + var secondResult = reducers(result, action) + assert.equal(secondResult.metamask.frequentRpcList.length, 1) }) }) -}) +}) diff --git a/ui/app/actions.js b/ui/app/actions.js index 86638fc91..7e5add1d0 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -626,13 +626,19 @@ function markAccountsFound() { // function setRpcTarget (newRpc) { - if (global.METAMASK_DEBUG) console.log(`background.setRpcTarget`) - background.addToFrequentRpcList(newRpc, () => { + return (dispatch) => { + if (global.METAMASK_DEBUG) console.log(`background.setRpcTarget`) background.setRpcTarget(newRpc) - }) - return { - type: actions.SET_RPC_TARGET, - value: newRpc, + background.updateFrequentRpcList(newRpc, (frequentRpcList) => { + const value = { + rpcTarget: newRpc, + frequentRpcList, + } + dispatch({ + type: actions.SET_RPC_TARGET, + value, + }) + }) } } diff --git a/ui/app/app.js b/ui/app/app.js index d61f93dd2..cf865f23f 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -257,7 +257,9 @@ App.prototype.renderNetworkDropdown = function () { h(DropMenuItem, { label: 'Localhost 8545', closeMenu: () => this.setState({ isNetworkMenuOpen: false }), - action: () => props.dispatch(actions.setRpcTarget('http://localhost:8545')), + action: () => { + props.dispatch(actions.setRpcTarget('http://localhost:8545')) + }, icon: h('i.fa.fa-question-circle.fa-lg'), activeNetworkRender: props.provider.rpcTarget, }), diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index 3875cf6d1..7bf2969e7 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -55,9 +55,10 @@ function reduceMetamask (state, action) { case actions.SET_RPC_TARGET: return extend(metamaskState, { + frequentRpcList: action.value.frequentRpcList, provider: { type: 'rpc', - rpcTarget: action.value, + rpcTarget: action.value.rpcTarget, }, }) From 930dafc4b0648353f847c529cdc19e2d762553ad Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Fri, 24 Feb 2017 15:30:18 -0800 Subject: [PATCH 09/52] Fix spelling error. --- test/unit/notice-controller-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/notice-controller-test.js b/test/unit/notice-controller-test.js index cf00daeba..73fdb2f2e 100644 --- a/test/unit/notice-controller-test.js +++ b/test/unit/notice-controller-test.js @@ -4,7 +4,7 @@ const rp = require('request-promise') const nock = require('nock') const configManagerGen = require('../lib/mock-config-manager') const NoticeController = require('../../app/scripts/notice-controller') -const STORAGE_KEY = 'metamask-persistance-key' +const STORAGE_KEY = 'metamask-persistence-key' describe('notice-controller', function() { var noticeController From ca5cf06ae9e3e417dd3488bb0d94cdeec74ca18c Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 27 Feb 2017 10:25:10 -0800 Subject: [PATCH 10/52] Concatenate custom RPC labels that are too long --- ui/app/app.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ui/app/app.js b/ui/app/app.js index cf865f23f..a05a42516 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -499,6 +499,12 @@ App.prototype.renderCustomOption = function (provider) { const { rpcTarget, type } = provider if (type !== 'rpc') return null + // Concatenate long URLs + let label = rpcTarget + if (rpcTarget.length > 31) { + label = label.substr(0, 34) + '...' + } + switch (rpcTarget) { case 'http://localhost:8545': @@ -506,7 +512,8 @@ App.prototype.renderCustomOption = function (provider) { default: return h(DropMenuItem, { - label: `${rpcTarget}`, + label, + key: rpcTarget, closeMenu: () => this.setState({ isNetworkMenuOpen: false }), icon: h('i.fa.fa-question-circle.fa-lg'), activeNetworkRender: 'custom', @@ -524,6 +531,7 @@ App.prototype.renderCommonRpc = function (rpcList, provider) { } else { return h(DropMenuItem, { label: rpc, + key: rpc, closeMenu: () => this.setState({ isNetworkMenuOpen: false }), action: () => props.dispatch(actions.setRpcTarget(rpc)), icon: h('i.fa.fa-question-circle.fa-lg'), From b5d03cd52418cfd09ce51a23c01e78262d3ffc9b Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 27 Feb 2017 10:39:48 -0800 Subject: [PATCH 11/52] add controllers to root scripts folder --- app/scripts/{lib => }/controllers/currency.js | 0 app/scripts/{lib => }/controllers/preferences.js | 0 app/scripts/{lib => }/controllers/shapeshift.js | 0 app/scripts/metamask-controller.js | 6 +++--- 4 files changed, 3 insertions(+), 3 deletions(-) rename app/scripts/{lib => }/controllers/currency.js (100%) rename app/scripts/{lib => }/controllers/preferences.js (100%) rename app/scripts/{lib => }/controllers/shapeshift.js (100%) diff --git a/app/scripts/lib/controllers/currency.js b/app/scripts/controllers/currency.js similarity index 100% rename from app/scripts/lib/controllers/currency.js rename to app/scripts/controllers/currency.js diff --git a/app/scripts/lib/controllers/preferences.js b/app/scripts/controllers/preferences.js similarity index 100% rename from app/scripts/lib/controllers/preferences.js rename to app/scripts/controllers/preferences.js diff --git a/app/scripts/lib/controllers/shapeshift.js b/app/scripts/controllers/shapeshift.js similarity index 100% rename from app/scripts/lib/controllers/shapeshift.js rename to app/scripts/controllers/shapeshift.js diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index d8136667f..bdffc87ac 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -11,10 +11,10 @@ const streamIntoProvider = require('web3-stream-provider/handler') const MetaMaskProvider = require('web3-provider-engine/zero.js') const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex const KeyringController = require('./keyring-controller') -const PreferencesController = require('./lib/controllers/preferences') -const CurrencyController = require('./lib/controllers/currency') +const PreferencesController = require('./controllers/preferences') +const CurrencyController = require('./controllers/currency') const NoticeController = require('./notice-controller') -const ShapeShiftController = require('./lib/controllers/shapeshift') +const ShapeShiftController = require('./controllers/shapeshift') const MessageManager = require('./lib/message-manager') const PersonalMessageManager = require('./lib/personal-message-manager') const TxManager = require('./transaction-manager') From 6fb33853f2ceeb6ef48988a7ee9334dfc87a8223 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 27 Feb 2017 10:53:36 -0800 Subject: [PATCH 12/52] Fix test reference --- test/unit/currency-controller-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/currency-controller-test.js b/test/unit/currency-controller-test.js index c57b522c7..dd7fa91e0 100644 --- a/test/unit/currency-controller-test.js +++ b/test/unit/currency-controller-test.js @@ -5,7 +5,7 @@ const assert = require('assert') const extend = require('xtend') const rp = require('request-promise') const nock = require('nock') -const CurrencyController = require('../../app/scripts/lib/controllers/currency') +const CurrencyController = require('../../app/scripts/controllers/currency') describe('config-manager', function() { var currencyController From 5f378d382e008ef577223055c9674c25e2e6bba4 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 1 Mar 2017 13:01:23 -0800 Subject: [PATCH 13/52] Only allow numbers in gas inputs --- ui/app/components/hex-as-decimal-input.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/app/components/hex-as-decimal-input.js b/ui/app/components/hex-as-decimal-input.js index 523c1264b..ecf232640 100644 --- a/ui/app/components/hex-as-decimal-input.js +++ b/ui/app/components/hex-as-decimal-input.js @@ -44,6 +44,7 @@ HexAsDecimalInput.prototype.render = function () { textAlign: 'right', backgroundColor: 'transparent', border: '1px solid #bdbdbd', + type: 'number', }, style), value: decimalValue, onChange: (event) => { From 0ac1f749fd68244682d0f2c763028cdf6aa29486 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 1 Mar 2017 14:37:51 -0800 Subject: [PATCH 14/52] Various improvements to gas input. --- ui/app/components/hex-as-decimal-input.js | 15 ++++++++++----- ui/app/components/pending-tx-details.js | 18 ++++-------------- ui/app/components/pending-tx.js | 16 ++++++++-------- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/ui/app/components/hex-as-decimal-input.js b/ui/app/components/hex-as-decimal-input.js index ecf232640..c89ed0416 100644 --- a/ui/app/components/hex-as-decimal-input.js +++ b/ui/app/components/hex-as-decimal-input.js @@ -39,16 +39,17 @@ HexAsDecimalInput.prototype.render = function () { }, }, [ h('input.ether-balance.ether-balance-amount', { + type: 'number', style: extend({ display: 'block', textAlign: 'right', backgroundColor: 'transparent', border: '1px solid #bdbdbd', - type: 'number', + }, style), value: decimalValue, onChange: (event) => { - const hexString = hexify(event.target.value) + const hexString = (event.target.value === '') ? '' : hexify(event.target.value) onChange(hexString) }, }), @@ -71,7 +72,11 @@ function hexify (decimalString) { } function decimalize (input, toEth) { - const strippedInput = ethUtil.stripHexPrefix(input) - const inputBN = new BN(strippedInput, 'hex') - return inputBN.toString(10) + if (input === '') { + return '' + } else { + const strippedInput = ethUtil.stripHexPrefix(input) + const inputBN = new BN(strippedInput, 'hex') + return inputBN.toString(10) + } } diff --git a/ui/app/components/pending-tx-details.js b/ui/app/components/pending-tx-details.js index b1ab9576b..fc8d65454 100644 --- a/ui/app/components/pending-tx-details.js +++ b/ui/app/components/pending-tx-details.js @@ -32,10 +32,8 @@ PTXP.render = function () { var account = props.accounts[address] var balance = account ? account.balance : '0x0' - const gas = state.gas || txParams.gas - const gasPrice = state.gasPrice || txData.gasPrice - const gasDefault = txParams.gas - const gasPriceDefault = txData.gasPrice + const gas = (state.gas === undefined) ? txParams.gas : state.gas + const gasPrice = (state.gasPrice === undefined) ? txData.gasPrice : state.gasPrice var txFee = state.txFee || txData.txFee || '' var maxCost = state.maxCost || txData.maxCost || '' @@ -131,11 +129,7 @@ PTXP.render = function () { }, onChange: (newHex) => { log.info(`Gas limit changed to ${newHex}`) - if (newHex === '0x0') { - this.setState({gas: gasDefault}) - } else { - this.setState({ gas: newHex }) - } + this.setState({ gas: newHex }) }, }), ]), @@ -155,11 +149,7 @@ PTXP.render = function () { }, onChange: (newHex) => { log.info(`Gas price changed to: ${newHex}`) - if (newHex === '0x0') { - this.setState({gasPrice: gasPriceDefault}) - } else { - this.setState({ gasPrice: newHex }) - } + this.setState({ gasPrice: newHex }) }, }), ]), diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index d39cbc0f8..ed366aa45 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -60,12 +60,18 @@ PendingTx.prototype.render = function () { }, [ props.insufficientBalance ? - h('button.btn-green', { + h('button', { onClick: props.buyEth, }, 'Buy Ether') : null, - h('button.confirm', { + h('button', { + onClick: () => { + this.refs.details.resetGasFields() + }, + }, 'Reset'), + + h('button.confirm.btn-green', { disabled: props.insufficientBalance, onClick: props.sendTransaction, }, 'Accept'), @@ -73,12 +79,6 @@ PendingTx.prototype.render = function () { h('button.cancel.btn-red', { onClick: props.cancelTransaction, }, 'Reject'), - - h('button', { - onClick: () => { - this.refs.details.resetGasFields() - }, - }, 'Reset'), ]), ]) ) From 72932bdcba10bd9d47724f271d0c14f84d12b759 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 1 Mar 2017 17:03:55 -0800 Subject: [PATCH 15/52] Prevent submission of invalid gas parameters. --- ui/app/components/pending-tx-details.js | 11 ++++++++++- ui/app/components/pending-tx.js | 18 ++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ui/app/components/pending-tx-details.js b/ui/app/components/pending-tx-details.js index fc8d65454..e92ce575f 100644 --- a/ui/app/components/pending-tx-details.js +++ b/ui/app/components/pending-tx-details.js @@ -306,7 +306,6 @@ PTXP.gatherParams = function () { const state = this.state || {} const txData = state.txData || props.txData const txParams = txData.txParams - const gas = state.gas || txParams.gas const gasPrice = state.gasPrice || txParams.gasPrice const resultTx = extend(txParams, { @@ -320,6 +319,16 @@ PTXP.gatherParams = function () { return resultTxMeta } +PTXP.verifyGasParams = function () { + // We call this in case the gas has not been modified at all + if (!this.state) { return true } + return this._notZeroOrEmptyString(this.state.gas) && this._notZeroOrEmptyString(this.state.gasPrice) +} + +PTXP._notZeroOrEmptyString = function (obj) { + return obj !== '' && obj !== '0x0' +} + function forwardCarrat () { return ( diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index ed366aa45..2ab6f25a9 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -1,10 +1,18 @@ const Component = require('react').Component +const connect = require('react-redux').connect const h = require('react-hyperscript') const inherits = require('util').inherits const PendingTxDetails = require('./pending-tx-details') const extend = require('xtend') +const actions = require('../actions') -module.exports = PendingTx +module.exports = connect(mapStateToProps)(PendingTx) + +function mapStateToProps (state) { + return { + + } +} inherits(PendingTx, Component) function PendingTx () { @@ -73,7 +81,13 @@ PendingTx.prototype.render = function () { h('button.confirm.btn-green', { disabled: props.insufficientBalance, - onClick: props.sendTransaction, + onClick: (txData, event) => { + if (this.refs.details.verifyGasParams()) { + props.sendTransaction(txData, event) + } else { + this.props.dispatch(actions.displayWarning('Invalid Gas Parameters')) + } + }, }, 'Accept'), h('button.cancel.btn-red', { From 7d2019eac9706bc208c6aa5ea0ef3c4b4ee66e4b Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 6 Mar 2017 13:45:19 -0800 Subject: [PATCH 16/52] Fix personal sign for loose accounts Fix was written, but not published to npm. Now fixing semver at the correct version. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1542853ad..0c4ca9096 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "eth-lightwallet": "^2.3.3", "eth-query": "^1.0.3", "eth-sig-util": "^1.1.1", - "eth-simple-keyring": "^1.1.0", + "eth-simple-keyring": "^1.1.1", "ethereumjs-tx": "^1.0.0", "ethereumjs-util": "ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9", "ethereumjs-wallet": "^0.6.0", From 9bd8c5f723abef25b8864457df7207eb361be8e3 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 6 Mar 2017 15:03:49 -0800 Subject: [PATCH 17/52] Render personal_sign messages as utf-8 text Calls to `personal_sign` are now: - When hex encoded, preserved as hex encoded, but displayed as utf-8 text. - When not hex encoded, decoded as utf-8 text as hex for signing. - The messages proposed for signing are displayed as UTF-8 text. - When the message cannot be rendered as UTF-8 text, it is displayed as hexadecimal. Fixes #1173 --- app/scripts/lib/personal-message-manager.js | 22 ++++++---- test/unit/components/binary-renderer-test.js | 25 +++++++++++ test/unit/personal-message-manager-test.js | 23 +++++++++- ui/app/components/binary-renderer.js | 43 +++++++++++++++++++ .../pending-personal-msg-details.js | 15 ++----- 5 files changed, 107 insertions(+), 21 deletions(-) create mode 100644 test/unit/components/binary-renderer-test.js create mode 100644 ui/app/components/binary-renderer.js diff --git a/app/scripts/lib/personal-message-manager.js b/app/scripts/lib/personal-message-manager.js index 3b8510767..04dba4a90 100644 --- a/app/scripts/lib/personal-message-manager.js +++ b/app/scripts/lib/personal-message-manager.js @@ -2,6 +2,7 @@ const EventEmitter = require('events') const ObservableStore = require('obs-store') const ethUtil = require('ethereumjs-util') const createId = require('./random-id') +const hexRe = /^[0-9A-Fa-f]+$/g module.exports = class PersonalMessageManager extends EventEmitter{ @@ -24,7 +25,8 @@ module.exports = class PersonalMessageManager extends EventEmitter{ } addUnapprovedMessage (msgParams) { - msgParams.data = normalizeMsgData(msgParams.data) + log.debug(`PersonalMessageManager addUnapprovedMessage: ${JSON.stringify(msgParams)}`) + msgParams.data = this.normalizeMsgData(msgParams.data) // create txData obj with parameters and meta data var time = (new Date()).getTime() var msgId = createId() @@ -106,14 +108,18 @@ module.exports = class PersonalMessageManager extends EventEmitter{ this.emit('updateBadge') } -} + normalizeMsgData(data) { + try { + const stripped = ethUtil.stripHexPrefix(data) + if (stripped.match(hexRe)) { + return stripped + } + } catch (e) { + log.debug(`Message was not hex encoded, interpreting as utf8.`) + } -function normalizeMsgData(data) { - if (data.slice(0, 2) === '0x') { - // data is already hex - return data - } else { - // data is unicode, convert to hex return ethUtil.bufferToHex(new Buffer(data, 'utf8')) } + } + diff --git a/test/unit/components/binary-renderer-test.js b/test/unit/components/binary-renderer-test.js new file mode 100644 index 000000000..3264faddc --- /dev/null +++ b/test/unit/components/binary-renderer-test.js @@ -0,0 +1,25 @@ +var assert = require('assert') +var BinaryRenderer = require('../../../ui/app/components/binary-renderer') + +describe('BinaryRenderer', function() { + + let binaryRenderer + const message = 'Hello, world!' + const buffer = new Buffer(message, 'utf8') + const hex = buffer.toString('hex') + + beforeEach(function() { + binaryRenderer = new BinaryRenderer() + }) + + it('recovers message', function() { + const result = binaryRenderer.hexToText(hex) + assert.equal(result, message) + }) + + + it('recovers message with hex prefix', function() { + const result = binaryRenderer.hexToText('0x' + hex) + assert.equal(result, message) + }) +}) diff --git a/test/unit/personal-message-manager-test.js b/test/unit/personal-message-manager-test.js index 657d5e675..69d373ed3 100644 --- a/test/unit/personal-message-manager-test.js +++ b/test/unit/personal-message-manager-test.js @@ -4,7 +4,7 @@ const EventEmitter = require('events') const PersonalMessageManager = require('../../app/scripts/lib/personal-message-manager') -describe('Transaction Manager', function() { +describe('Personal Message Manager', function() { let messageManager beforeEach(function() { @@ -86,4 +86,25 @@ describe('Transaction Manager', function() { assert.equal(messageManager.getMsg('2').status, 'approved') }) }) + + describe('#normalizeMsgData', function() { + it('converts text to a utf8 buffer', function() { + var input = 'hello' + var output = messageManager.normalizeMsgdata(input) + assert.equal(output, '68656c6c6f', 'predictably hex encoded') + }) + + it('tolerates a hex prefix', function() { + var input = '0x12' + var output = messageManager.normalizeMsgdata(input) + assert.equal(output, '12', 'prefix stripped') + }) + + it('tolerates normal hex', function() { + var input = '12' + var output = messageManager.normalizeMsgdata(input) + assert.equal(output, '12', 'not modified') + }) + }) + }) diff --git a/ui/app/components/binary-renderer.js b/ui/app/components/binary-renderer.js new file mode 100644 index 000000000..a9d49b128 --- /dev/null +++ b/ui/app/components/binary-renderer.js @@ -0,0 +1,43 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits +const ethUtil = require('ethereumjs-util') + +module.exports = BinaryRenderer + +inherits(BinaryRenderer, Component) +function BinaryRenderer () { + Component.call(this) +} + +BinaryRenderer.prototype.render = function () { + const props = this.props + const { value } = props + const text = this.hexToText(value) + + return ( + h('textarea.font-small', { + readOnly: true, + style: { + width: '315px', + maxHeight: '210px', + resize: 'none', + border: 'none', + background: 'white', + padding: '3px', + }, + defaultValue: text, + }) + ) +} + +BinaryRenderer.prototype.hexToText = function (hex) { + try { + const stripped = ethUtil.stripHexPrefix(hex) + const buff = Buffer.from(stripped, 'hex') + return buff.toString('utf8') + } catch (e) { + return hex + } +} + diff --git a/ui/app/components/pending-personal-msg-details.js b/ui/app/components/pending-personal-msg-details.js index ffd11ca0b..afd04fc51 100644 --- a/ui/app/components/pending-personal-msg-details.js +++ b/ui/app/components/pending-personal-msg-details.js @@ -3,6 +3,7 @@ const h = require('react-hyperscript') const inherits = require('util').inherits const AccountPanel = require('./account-panel') +const BinaryRenderer = require('./binary-renderer') module.exports = PendingMsgDetails @@ -21,6 +22,7 @@ PendingMsgDetails.prototype.render = function () { var account = state.accounts[address] || { address: address } var { data } = msgParams + console.dir({ msgParams }) return ( h('div', { @@ -41,18 +43,7 @@ PendingMsgDetails.prototype.render = function () { // message data h('div', [ h('label.font-small', { style: { display: 'block' } }, 'MESSAGE'), - h('textarea.font-small', { - readOnly: true, - style: { - width: '315px', - maxHeight: '210px', - resize: 'none', - border: 'none', - background: 'white', - padding: '3px', - }, - defaultValue: data, - }), + h(BinaryRenderer, { value: data }), ]), ]) From af337dfae556cc3ac8739dc8337970147d74bb69 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 6 Mar 2017 15:17:45 -0800 Subject: [PATCH 18/52] Fix function names --- test/unit/personal-message-manager-test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/unit/personal-message-manager-test.js b/test/unit/personal-message-manager-test.js index 69d373ed3..5ee03726f 100644 --- a/test/unit/personal-message-manager-test.js +++ b/test/unit/personal-message-manager-test.js @@ -90,20 +90,20 @@ describe('Personal Message Manager', function() { describe('#normalizeMsgData', function() { it('converts text to a utf8 buffer', function() { var input = 'hello' - var output = messageManager.normalizeMsgdata(input) - assert.equal(output, '68656c6c6f', 'predictably hex encoded') + var output = messageManager.normalizeMsgData(input) + assert.equal(output, '0x68656c6c6f', 'predictably hex encoded') }) it('tolerates a hex prefix', function() { var input = '0x12' - var output = messageManager.normalizeMsgdata(input) - assert.equal(output, '12', 'prefix stripped') + var output = messageManager.normalizeMsgData(input) + assert.equal(output, '12', 'un modified') }) it('tolerates normal hex', function() { var input = '12' - var output = messageManager.normalizeMsgdata(input) - assert.equal(output, '12', 'not modified') + var output = messageManager.normalizeMsgData(input) + assert.equal(output, '12', 'adds prefix') }) }) From 26ea5993a9dffa687b50446bbffd0d2310a796bc Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 6 Mar 2017 15:36:16 -0800 Subject: [PATCH 19/52] Remove log --- ui/app/components/pending-personal-msg-details.js | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/app/components/pending-personal-msg-details.js b/ui/app/components/pending-personal-msg-details.js index afd04fc51..fa2c6416c 100644 --- a/ui/app/components/pending-personal-msg-details.js +++ b/ui/app/components/pending-personal-msg-details.js @@ -22,7 +22,6 @@ PendingMsgDetails.prototype.render = function () { var account = state.accounts[address] || { address: address } var { data } = msgParams - console.dir({ msgParams }) return ( h('div', { From b84f1b053265fdabc0aaec4fa8aa3145b6fb7f51 Mon Sep 17 00:00:00 2001 From: Frankie Date: Mon, 6 Mar 2017 15:41:11 -0800 Subject: [PATCH 20/52] Fix issue where old txMeta object was being used to pass the txHash to the cb --- app/scripts/metamask-controller.js | 8 ++++---- app/scripts/transaction-manager.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index bd01a260d..3dddf7065 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -414,14 +414,14 @@ module.exports = class MetamaskController extends EventEmitter { self.sendUpdate() self.opts.showUnapprovedTx(txMeta) // listen for tx completion (success, fail) - self.txManager.once(`${txMeta.id}:finished`, (status) => { - switch (status) { + self.txManager.once(`${txMeta.id}:finished`, (completedTx) => { + switch (completedTx.status) { case 'submitted': - return cb(null, txMeta.hash) + return cb(null, completedTx.hash) case 'rejected': return cb(new Error('MetaMask Tx Signature: User denied transaction signature.')) default: - return cb(new Error(`MetaMask Tx Signature: Unknown problem: ${JSON.stringify(txMeta.txParams)}`)) + return cb(new Error(`MetaMask Tx Signature: Unknown problem: ${JSON.stringify(completedTx.txParams)}`)) } }) }) diff --git a/app/scripts/transaction-manager.js b/app/scripts/transaction-manager.js index 07c90af7e..c6cfdf11d 100644 --- a/app/scripts/transaction-manager.js +++ b/app/scripts/transaction-manager.js @@ -353,7 +353,7 @@ module.exports = class TransactionManager extends EventEmitter { txMeta.status = status this.emit(`${txMeta.id}:${status}`, txId) if (status === 'submitted' || status === 'rejected') { - this.emit(`${txMeta.id}:finished`, status) + this.emit(`${txMeta.id}:finished`, txMeta) } this.updateTx(txMeta) this.emit('updateBadge') From e66e755766ef318c38277c184d2670cc2179d37a Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 6 Mar 2017 16:33:33 -0800 Subject: [PATCH 21/52] Fix normalizeMsgData function to always return hex prefixed --- app/scripts/lib/personal-message-manager.js | 2 +- test/unit/personal-message-manager-test.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/scripts/lib/personal-message-manager.js b/app/scripts/lib/personal-message-manager.js index 04dba4a90..bbc978446 100644 --- a/app/scripts/lib/personal-message-manager.js +++ b/app/scripts/lib/personal-message-manager.js @@ -112,7 +112,7 @@ module.exports = class PersonalMessageManager extends EventEmitter{ try { const stripped = ethUtil.stripHexPrefix(data) if (stripped.match(hexRe)) { - return stripped + return ethUtil.addHexPrefix(stripped) } } catch (e) { log.debug(`Message was not hex encoded, interpreting as utf8.`) diff --git a/test/unit/personal-message-manager-test.js b/test/unit/personal-message-manager-test.js index 5ee03726f..77e1656c5 100644 --- a/test/unit/personal-message-manager-test.js +++ b/test/unit/personal-message-manager-test.js @@ -97,13 +97,13 @@ describe('Personal Message Manager', function() { it('tolerates a hex prefix', function() { var input = '0x12' var output = messageManager.normalizeMsgData(input) - assert.equal(output, '12', 'un modified') + assert.equal(output, '0x12', 'un modified') }) it('tolerates normal hex', function() { var input = '12' var output = messageManager.normalizeMsgData(input) - assert.equal(output, '12', 'adds prefix') + assert.equal(output, '0x12', 'adds prefix') }) }) From cdcd1b1e8b9219ad2f5b6f029e3f0bc48e879455 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 6 Mar 2017 17:19:36 -0800 Subject: [PATCH 22/52] Fix hex encoding of message to create valid hex strings --- app/scripts/lib/personal-message-manager.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/scripts/lib/personal-message-manager.js b/app/scripts/lib/personal-message-manager.js index bbc978446..17c9739de 100644 --- a/app/scripts/lib/personal-message-manager.js +++ b/app/scripts/lib/personal-message-manager.js @@ -118,8 +118,21 @@ module.exports = class PersonalMessageManager extends EventEmitter{ log.debug(`Message was not hex encoded, interpreting as utf8.`) } - return ethUtil.bufferToHex(new Buffer(data, 'utf8')) + return hexEncode(data) + } + + hexEncode(text){ + var hex, i + + var result = '' + for (i = 0; i < text.length; i++) { + hex = text.charCodeAt(i).toString(16) + result += ('000'+hex).slice(-4) + } + return '0x' + result } } + + From 32c767fbe8a8dc8854333318563d5def368cf85f Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 6 Mar 2017 17:24:04 -0800 Subject: [PATCH 23/52] Linted --- app/scripts/lib/personal-message-manager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/scripts/lib/personal-message-manager.js b/app/scripts/lib/personal-message-manager.js index 17c9739de..ddc3ee39c 100644 --- a/app/scripts/lib/personal-message-manager.js +++ b/app/scripts/lib/personal-message-manager.js @@ -118,7 +118,7 @@ module.exports = class PersonalMessageManager extends EventEmitter{ log.debug(`Message was not hex encoded, interpreting as utf8.`) } - return hexEncode(data) + return this.hexEncode(data) } hexEncode(text){ @@ -127,7 +127,7 @@ module.exports = class PersonalMessageManager extends EventEmitter{ var result = '' for (i = 0; i < text.length; i++) { hex = text.charCodeAt(i).toString(16) - result += ('000'+hex).slice(-4) + result += ('000' + hex).slice(-4) } return '0x' + result } From 70e14b8a6f050d0304d81067893a32ccd391c404 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 6 Mar 2017 17:36:08 -0800 Subject: [PATCH 24/52] Fixed internal encoding test case --- test/unit/personal-message-manager-test.js | 2 +- test/unit/tx-utils-test.js | 38 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 test/unit/tx-utils-test.js diff --git a/test/unit/personal-message-manager-test.js b/test/unit/personal-message-manager-test.js index 77e1656c5..20481af40 100644 --- a/test/unit/personal-message-manager-test.js +++ b/test/unit/personal-message-manager-test.js @@ -91,7 +91,7 @@ describe('Personal Message Manager', function() { it('converts text to a utf8 buffer', function() { var input = 'hello' var output = messageManager.normalizeMsgData(input) - assert.equal(output, '0x68656c6c6f', 'predictably hex encoded') + assert.equal(output, '0x00680065006c006c006f', 'predictably hex encoded') }) it('tolerates a hex prefix', function() { diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js new file mode 100644 index 000000000..44d8e13e9 --- /dev/null +++ b/test/unit/tx-utils-test.js @@ -0,0 +1,38 @@ +const assert = require('assert') +const ethUtil = require('ethereumjs-util') +const BN = ethUtil.BN + +const TxUtils = require('../../app/scripts/lib/tx-utils') + + +describe('txUtils', function() { + let txUtils + + before(function() { + txUtils = new TxUtils() + }) + + describe('addGasBuffer', function() { + describe('adds a flat value', function() { + it('over an empty value', function() { + const input = '0x0' + const output = txUtils.addGasBuffer(input) + assert.notEqual(output, input, 'changed the value') + + const inputBn = new BN(input, 'hex') + const outputBn = new BN(output, 'hex') + assert(outputBn.gt(inputBn), 'returns a greater value') + }) + + it('over an value', function() { + const input = '0x123fad' + const output = txUtils.addGasBuffer(input) + assert.notEqual(output, input, 'changed the value') + + const inputBn = new BN(input, 'hex') + const outputBn = new BN(output, 'hex') + assert(outputBn.gt(inputBn), 'returns a greater value') + }) + }) + }) +}) From 99b49b11f61314eee372c6679db3ad7217c7f4f2 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 6 Mar 2017 17:36:37 -0800 Subject: [PATCH 25/52] Fix test name --- test/unit/personal-message-manager-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/personal-message-manager-test.js b/test/unit/personal-message-manager-test.js index 20481af40..41ac3db87 100644 --- a/test/unit/personal-message-manager-test.js +++ b/test/unit/personal-message-manager-test.js @@ -88,7 +88,7 @@ describe('Personal Message Manager', function() { }) describe('#normalizeMsgData', function() { - it('converts text to a utf8 buffer', function() { + it('converts text to a utf8 hex string', function() { var input = 'hello' var output = messageManager.normalizeMsgData(input) assert.equal(output, '0x00680065006c006c006f', 'predictably hex encoded') From 993a1cef64f78b9c0a3960c256bf1f76c7d60b95 Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 7 Mar 2017 10:15:34 -0800 Subject: [PATCH 26/52] deps - bump web3-provider-engine include fix for https://github.com/MetaMask/provider-engine/pull/122 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0c4ca9096..f9656e446 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "valid-url": "^1.0.9", "vreme": "^3.0.2", "web3": "0.18.2", - "web3-provider-engine": "^9.1.0", + "web3-provider-engine": "^9.2.1", "web3-stream-provider": "^2.0.6", "xtend": "^4.0.1" }, From 2a98beb87877619ad123281facab3e22dec64fab Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Tue, 7 Mar 2017 10:25:50 -0800 Subject: [PATCH 27/52] Break out rpc update and rpclist into two reducers. --- ui/app/actions.js | 30 ++++++++++++++++++++++++------ ui/app/app.js | 4 +--- ui/app/reducers/metamask.js | 8 ++++++-- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/ui/app/actions.js b/ui/app/actions.js index cda987cad..4172ea5df 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -112,11 +112,13 @@ var actions = { // config screen SHOW_CONFIG_PAGE: 'SHOW_CONFIG_PAGE', SET_RPC_TARGET: 'SET_RPC_TARGET', + SET_DEFAULT_RPC_TARGET: 'SET_DEFAULT_RPC_TARGET', SET_PROVIDER_TYPE: 'SET_PROVIDER_TYPE', USE_ETHERSCAN_PROVIDER: 'USE_ETHERSCAN_PROVIDER', useEtherscanProvider: useEtherscanProvider, showConfigPage: showConfigPage, setRpcTarget: setRpcTarget, + setDefaultRpcTarget: setDefaultRpcTarget, setProviderType: setProviderType, // loading overlay SHOW_LOADING: 'SHOW_LOADING_INDICATION', @@ -669,18 +671,34 @@ function markAccountsFound() { // config // +// default rpc target refers to localhost:8545 in this instance. +function setDefaultRpcTarget (rpcList) { + log.debug(`background.setDefaultRpcTarget`) + background.setRpcTarget('http://localhost:8545') + return (dispatch) => { + dispatch({ + type: actions.SET_RPC_TARGET, + value: 'http://localhost:8545', + }) + dispatch({ + type: actions.SET_RPC_LIST, + value: rpcList, + }) + } +} + function setRpcTarget (newRpc) { return (dispatch) => { log.debug(`background.setRpcTarget`) background.setRpcTarget(newRpc) - background.updateFrequentRpcList(newRpc, (frequentRpcList) => { - const value = { - rpcTarget: newRpc, - frequentRpcList, - } + background.updateFrequentRpcList(newRpc, (rpcList) => { dispatch({ type: actions.SET_RPC_TARGET, - value, + value: newRpc, + }) + dispatch({ + type: actions.SET_RPC_LIST, + value: rpcList, }) }) } diff --git a/ui/app/app.js b/ui/app/app.js index 20f948770..2bc92b54c 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -258,9 +258,7 @@ App.prototype.renderNetworkDropdown = function () { h(DropMenuItem, { label: 'Localhost 8545', closeMenu: () => this.setState({ isNetworkMenuOpen: false }), - action: () => { - props.dispatch(actions.setRpcTarget('http://localhost:8545')) - }, + action: () => props.dispatch(actions.setDefaultRpcTarget(rpcList)), icon: h('i.fa.fa-question-circle.fa-lg'), activeNetworkRender: props.provider.rpcTarget, }), diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index 7bf2969e7..c09556c91 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -53,12 +53,16 @@ function reduceMetamask (state, action) { isUnlocked: false, }) + case actions.SET_RPC_LIST: + return extend(metamaskState, { + frequentRpcList: action.value, + }) + case actions.SET_RPC_TARGET: return extend(metamaskState, { - frequentRpcList: action.value.frequentRpcList, provider: { type: 'rpc', - rpcTarget: action.value.rpcTarget, + rpcTarget: action.value, }, }) From 01f2ec4823e83d986e7ecfd268f6b293f38a13e8 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Tue, 7 Mar 2017 10:37:01 -0800 Subject: [PATCH 28/52] Modify tests.' --- test/unit/actions/config_test.js | 34 ++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/test/unit/actions/config_test.js b/test/unit/actions/config_test.js index fea0cf0ba..eca2f7c8f 100644 --- a/test/unit/actions/config_test.js +++ b/test/unit/actions/config_test.js @@ -31,35 +31,39 @@ describe ('config view actions', function() { describe('SET_RPC_TARGET', function() { it('sets the state.metamask.rpcTarget property of the state to the action.value', function() { - const value = { - rpcTarget: 'foo', - frequentRpcList: ['foo'] - } const action = { type: actions.SET_RPC_TARGET, - value, + value: 'foo', + } + + const secondAction = { + type: actions.SET_RPC_LIST, + value: ['foo'], } var result = reducers(initialState, action) + result = reducers(result, secondAction) assert.equal(result.metamask.provider.type, 'rpc') - assert.equal(result.metamask.provider.rpcTarget, value.rpcTarget) - assert.equal(result.metamask.frequentRpcList[0], value.frequentRpcList[0]) + assert.equal(result.metamask.provider.rpcTarget, 'foo') + assert.equal(result.metamask.frequentRpcList[0], 'foo') }) it('should handle multiple requests to change the rpc gracefully', function() { - const value = { - rpcTarget: 'foo', - frequentRpcList: ['foo'] - } - const action = { type: actions.SET_RPC_TARGET, - value, + value: 'foo', + } + + const secondAction = { + type: actions.SET_RPC_LIST, + value: ['foo'], } var result = reducers(initialState, action) - var secondResult = reducers(result, action) - assert.equal(secondResult.metamask.frequentRpcList.length, 1) + var secondResult = reducers(result, secondAction) + var thirdResult = reducers(secondResult, action) + var fourthResult = reducers(thirdResult, secondAction) + assert.equal(fourthResult.metamask.frequentRpcList.length, 1) }) }) From e78e642eef21c0219eb025f859edea5817363b3f Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 7 Mar 2017 11:34:11 -0800 Subject: [PATCH 29/52] Add gas buffer test --- test/unit/tx-utils-test.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 test/unit/tx-utils-test.js diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js new file mode 100644 index 000000000..6131ed73f --- /dev/null +++ b/test/unit/tx-utils-test.js @@ -0,0 +1,38 @@ +const assert = require('assert') +const ethUtil = require('ethereumjs-util') +const BN = ethUtil.BN + +const TxUtils = require('../../app/scripts/lib/tx-utils') + + +describe('txUtils', function() { + let txUtils + + before(function() { + txUtils = new TxUtils() + }) + + describe('addGasBuffer', function() { + describe('adds a flat value', function() { + it('over an empty value', function() { + const input = '0x0' + const output = txUtils.addGasBuffer(input) + assert.notEqual(output, input, 'changed the value') + + const inputBn = new BN(input, 'hex') + const outputBn = new BN(output, 'hex') + assert(outputBn.gt(inputBn), 'returns a greater value') + }) + + it('over an value', function() { + const input = '0x123fad' + const output = txUtils.addGasBuffer(input) + assert.notEqual(output, input, 'changed the value') + + const inputBn = new BN(input, 'hex') + const outputBn = new BN(output, 'hex') + assert(outputBn.gt(inputBn), 'returns a greater value') + }) + }) + }) +}) \ No newline at end of file From 6253885e286a554736e2e51736a742d39a377727 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 7 Mar 2017 11:36:13 -0800 Subject: [PATCH 30/52] Remove unrelated test file --- test/unit/tx-utils-test.js | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 test/unit/tx-utils-test.js diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js deleted file mode 100644 index 44d8e13e9..000000000 --- a/test/unit/tx-utils-test.js +++ /dev/null @@ -1,38 +0,0 @@ -const assert = require('assert') -const ethUtil = require('ethereumjs-util') -const BN = ethUtil.BN - -const TxUtils = require('../../app/scripts/lib/tx-utils') - - -describe('txUtils', function() { - let txUtils - - before(function() { - txUtils = new TxUtils() - }) - - describe('addGasBuffer', function() { - describe('adds a flat value', function() { - it('over an empty value', function() { - const input = '0x0' - const output = txUtils.addGasBuffer(input) - assert.notEqual(output, input, 'changed the value') - - const inputBn = new BN(input, 'hex') - const outputBn = new BN(output, 'hex') - assert(outputBn.gt(inputBn), 'returns a greater value') - }) - - it('over an value', function() { - const input = '0x123fad' - const output = txUtils.addGasBuffer(input) - assert.notEqual(output, input, 'changed the value') - - const inputBn = new BN(input, 'hex') - const outputBn = new BN(output, 'hex') - assert(outputBn.gt(inputBn), 'returns a greater value') - }) - }) - }) -}) From fba7a50e1bad007a94badf990e5ad661d4049409 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 7 Mar 2017 11:43:59 -0800 Subject: [PATCH 31/52] Fixed encoding --- app/scripts/lib/personal-message-manager.js | 15 +-------------- test/unit/personal-message-manager-test.js | 2 +- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/app/scripts/lib/personal-message-manager.js b/app/scripts/lib/personal-message-manager.js index ddc3ee39c..bbc978446 100644 --- a/app/scripts/lib/personal-message-manager.js +++ b/app/scripts/lib/personal-message-manager.js @@ -118,21 +118,8 @@ module.exports = class PersonalMessageManager extends EventEmitter{ log.debug(`Message was not hex encoded, interpreting as utf8.`) } - return this.hexEncode(data) - } - - hexEncode(text){ - var hex, i - - var result = '' - for (i = 0; i < text.length; i++) { - hex = text.charCodeAt(i).toString(16) - result += ('000' + hex).slice(-4) - } - return '0x' + result + return ethUtil.bufferToHex(new Buffer(data, 'utf8')) } } - - diff --git a/test/unit/personal-message-manager-test.js b/test/unit/personal-message-manager-test.js index 41ac3db87..f2c01392c 100644 --- a/test/unit/personal-message-manager-test.js +++ b/test/unit/personal-message-manager-test.js @@ -91,7 +91,7 @@ describe('Personal Message Manager', function() { it('converts text to a utf8 hex string', function() { var input = 'hello' var output = messageManager.normalizeMsgData(input) - assert.equal(output, '0x00680065006c006c006f', 'predictably hex encoded') + assert.equal(output, '0x68656c6c6f', 'predictably hex encoded') }) it('tolerates a hex prefix', function() { From be8267edf76747f5bb82b7624393fb845a5a0e2b Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 7 Mar 2017 15:21:39 -0800 Subject: [PATCH 32/52] deps - bump web3-provider-engine resolves https://github.com/MetaMask/metamask-plugin/issues/1159 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f9656e446..839f7bcd2 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "valid-url": "^1.0.9", "vreme": "^3.0.2", "web3": "0.18.2", - "web3-provider-engine": "^9.2.1", + "web3-provider-engine": "^10.0.0", "web3-stream-provider": "^2.0.6", "xtend": "^4.0.1" }, From e7e024bcdd2c93b34a0baf8bc27e6c571c098476 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Tue, 7 Mar 2017 16:01:51 -0800 Subject: [PATCH 33/52] Refactor of code into separate reducers and actions. --- app/scripts/controllers/preferences.js | 2 +- app/scripts/metamask-controller.js | 17 +++++++++++---- test/unit/actions/config_test.js | 12 ++--------- ui/app/actions.js | 30 ++++++++------------------ ui/app/reducers/metamask.js | 1 + 5 files changed, 26 insertions(+), 36 deletions(-) diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 8fd5fb8a0..18fccf11b 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -29,7 +29,7 @@ class PreferencesController { return this.addToFrequentRpcList(_url) .then((rpcList) => { this.store.updateState({ frequentRpcList: rpcList }) - return rpcList + return Promise.resolve() }) } diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index f6dbf899d..3b3329b58 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -244,7 +244,8 @@ module.exports = class MetamaskController extends EventEmitter { return { // etc getState: (cb) => cb(null, this.getState()), - setRpcTarget: this.setRpcTarget.bind(this), + setDefaultRpc: this.setDefaultRpc.bind(this), + setCustomRpc: this.setCustomRpc.bind(this), setProviderType: this.setProviderType.bind(this), useEtherscanProvider: this.useEtherscanProvider.bind(this), setCurrentCurrency: this.setCurrentCurrency.bind(this), @@ -265,7 +266,6 @@ module.exports = class MetamaskController extends EventEmitter { // PreferencesController setSelectedAddress: nodeify(preferencesController.setSelectedAddress).bind(preferencesController), - updateFrequentRpcList: nodeify(preferencesController.updateFrequentRpcList).bind(preferencesController), // KeyringController setLocked: nodeify(keyringController.setLocked).bind(keyringController), @@ -662,12 +662,21 @@ module.exports = class MetamaskController extends EventEmitter { if (this.isNetworkLoading()) this.lookupNetwork() } - setRpcTarget (rpcTarget) { - this.configManager.setRpcTarget(rpcTarget) + setDefaultRpc () { + this.configManager.setRpcTarget('http://localhost:8545') extension.runtime.reload() this.lookupNetwork() } + setCustomRpc (rpcTarget, rpcList) { + this.configManager.setRpcTarget(rpcTarget) + return this.preferencesController.updateFrequentRpcList(rpcTarget) + .then(() => { + extension.runtime.reload() + this.lookupNetwork() + }) + } + setProviderType (type) { this.configManager.setProviderType(type) extension.runtime.reload() diff --git a/test/unit/actions/config_test.js b/test/unit/actions/config_test.js index eca2f7c8f..02704cb42 100644 --- a/test/unit/actions/config_test.js +++ b/test/unit/actions/config_test.js @@ -36,16 +36,10 @@ describe ('config view actions', function() { value: 'foo', } - const secondAction = { - type: actions.SET_RPC_LIST, - value: ['foo'], - } - var result = reducers(initialState, action) result = reducers(result, secondAction) assert.equal(result.metamask.provider.type, 'rpc') assert.equal(result.metamask.provider.rpcTarget, 'foo') - assert.equal(result.metamask.frequentRpcList[0], 'foo') }) it('should handle multiple requests to change the rpc gracefully', function() { @@ -60,10 +54,8 @@ describe ('config view actions', function() { } var result = reducers(initialState, action) - var secondResult = reducers(result, secondAction) - var thirdResult = reducers(secondResult, action) - var fourthResult = reducers(thirdResult, secondAction) - assert.equal(fourthResult.metamask.frequentRpcList.length, 1) + var secondResult = reducers(result, action) + assert.equal(secondResult.metamask.frequentRpcList.length, 1) }) }) diff --git a/ui/app/actions.js b/ui/app/actions.js index 4172ea5df..2fc0d3523 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -674,33 +674,21 @@ function markAccountsFound() { // default rpc target refers to localhost:8545 in this instance. function setDefaultRpcTarget (rpcList) { log.debug(`background.setDefaultRpcTarget`) - background.setRpcTarget('http://localhost:8545') - return (dispatch) => { - dispatch({ - type: actions.SET_RPC_TARGET, - value: 'http://localhost:8545', - }) - dispatch({ - type: actions.SET_RPC_LIST, - value: rpcList, - }) + background.setDefaultRpc() + return { + type: actions.SET_RPC_TARGET, + value: 'http://localhost:8545', } } function setRpcTarget (newRpc) { return (dispatch) => { log.debug(`background.setRpcTarget`) - background.setRpcTarget(newRpc) - background.updateFrequentRpcList(newRpc, (rpcList) => { - dispatch({ - type: actions.SET_RPC_TARGET, - value: newRpc, - }) - dispatch({ - type: actions.SET_RPC_LIST, - value: rpcList, - }) - }) + background.setCustomRpc(newRpc) + return { + type: actions.SET_RPC_TARGET, + value: newRpc, + } } } diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index c09556c91..a3c07d977 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -18,6 +18,7 @@ function reduceMetamask (state, action) { conversionDate: 'N/A', noActiveNotices: true, lastUnreadNotice: undefined, + frequentRpcList: [], }, state.metamask) switch (action.type) { From 4562e41d33dfe81e305c20583983fba528ee1a9d Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Tue, 7 Mar 2017 16:10:06 -0800 Subject: [PATCH 34/52] Fix tests until new ones to-be-written. --- test/unit/actions/config_test.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/test/unit/actions/config_test.js b/test/unit/actions/config_test.js index 02704cb42..14198fa8a 100644 --- a/test/unit/actions/config_test.js +++ b/test/unit/actions/config_test.js @@ -37,26 +37,9 @@ describe ('config view actions', function() { } var result = reducers(initialState, action) - result = reducers(result, secondAction) assert.equal(result.metamask.provider.type, 'rpc') assert.equal(result.metamask.provider.rpcTarget, 'foo') }) - - it('should handle multiple requests to change the rpc gracefully', function() { - const action = { - type: actions.SET_RPC_TARGET, - value: 'foo', - } - - const secondAction = { - type: actions.SET_RPC_LIST, - value: ['foo'], - } - - var result = reducers(initialState, action) - var secondResult = reducers(result, action) - assert.equal(secondResult.metamask.frequentRpcList.length, 1) - }) }) }) From 147ac416ba5184b914cdc6ed6a1a9b8b94446765 Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 7 Mar 2017 16:16:26 -0800 Subject: [PATCH 35/52] deps - bump web3-provider-engine to 10.0.1 Fixes https://github.com/MetaMask/metamask-plugin/issues/1163 Fixes https://github.com/MetaMask/provider-engine/issues/121 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 839f7bcd2..475cdb2b3 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "valid-url": "^1.0.9", "vreme": "^3.0.2", "web3": "0.18.2", - "web3-provider-engine": "^10.0.0", + "web3-provider-engine": "^10.0.1", "web3-stream-provider": "^2.0.6", "xtend": "^4.0.1" }, From 4256e631a6174f04d338412f419ceb0c08d724f1 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Tue, 7 Mar 2017 19:57:57 -0500 Subject: [PATCH 36/52] remove constant buffer and add multiplier --- app/scripts/lib/tx-utils.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index 19a2d430e..15cbb5b68 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -55,7 +55,7 @@ module.exports = class txProviderUtils { // try adding an additional gas buffer to our estimation for safety const estimatedGasBn = new BN(ethUtil.stripHexPrefix(txData.estimatedGas), 16) const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16) - const estimationWithBuffer = new BN(this.addGasBuffer(estimatedGasBn), 16) + const estimationWithBuffer = new BN(this.addGasBuffer(estimatedGasBn, blockGasLimitHex), 16) // added gas buffer is too high if (estimationWithBuffer.gt(blockGasLimitBn)) { txParams.gas = txData.estimatedGas @@ -68,11 +68,14 @@ module.exports = class txProviderUtils { return } - addGasBuffer (gas) { - const gasBuffer = new BN('100000', 10) + addGasBuffer (gas, blockGasLimitHex) { + const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16) const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16) - const correct = bnGas.add(gasBuffer) - return ethUtil.addHexPrefix(correct.toString(16)) + const bufferedGas = bnGas.mul(1.5) + + if (bnGas.gt(blockGasLimitBn)) return gas + if (bufferedGas.lt(blockGasLimitBn)) return ethUtil.addHexPrefix(bufferedGas.toString(16)) + return ethUtil.addHexPrefix(blockGasLimitBn.toString(16)) } fillInTxParams (txParams, cb) { From de44cd9ba46e562471d64e6cfc56cf8518f45113 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Tue, 7 Mar 2017 20:49:40 -0500 Subject: [PATCH 37/52] add gas buffer multiply test --- test/unit/tx-utils-test.js | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js index 6131ed73f..a7f2094c4 100644 --- a/test/unit/tx-utils-test.js +++ b/test/unit/tx-utils-test.js @@ -13,26 +13,16 @@ describe('txUtils', function() { }) describe('addGasBuffer', function() { - describe('adds a flat value', function() { - it('over an empty value', function() { - const input = '0x0' - const output = txUtils.addGasBuffer(input) - assert.notEqual(output, input, 'changed the value') - - const inputBn = new BN(input, 'hex') - const outputBn = new BN(output, 'hex') - assert(outputBn.gt(inputBn), 'returns a greater value') - }) - - it('over an value', function() { + describe('multiplies by 1.5', function() { + it('over a value', function() { const input = '0x123fad' - const output = txUtils.addGasBuffer(input) - assert.notEqual(output, input, 'changed the value') + const output = txUtils.addGasBuffer(input, '0x3d4c52') //0x3d4c52 is 4mil for dummy gas limit const inputBn = new BN(input, 'hex') const outputBn = new BN(output, 'hex') - assert(outputBn.gt(inputBn), 'returns a greater value') + const expectedBn = inputBn.mul(1.5) + assert(outputBn.eq(expectedBn), 'returns 1.5 the input value') }) }) }) -}) \ No newline at end of file +}) From 3e8b584c9811b06526e69203a5e03f8eb82e8211 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 7 Mar 2017 17:59:03 -0800 Subject: [PATCH 38/52] fix issue where account import allows for duplicates --- app/scripts/keyring-controller.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js index e1b1c4335..7669b9f8f 100644 --- a/app/scripts/keyring-controller.js +++ b/app/scripts/keyring-controller.js @@ -164,8 +164,11 @@ class KeyringController extends EventEmitter { return keyring.getAccounts() }) .then((accounts) => { + return this.checkForDuplicate(type, accounts) + }) + .then((checkedAccounts) => { this.keyrings.push(keyring) - return this.setupAccounts(accounts) + return this.setupAccounts(checkedAccounts) }) .then(() => this.persistAllKeyrings()) .then(() => this.fullUpdate()) @@ -175,6 +178,24 @@ class KeyringController extends EventEmitter { }) } + // For now just checks for simple key pairs + // but in the future + // should possibly add HD and other types + // + checkForDuplicate (type, newAccount) { + return this.getAccounts() + .then((accounts) => { + switch (type) { + case 'Simple Key Pair': + let isNotIncluded = !accounts.find((key) => key === newAccount[0] || key === ethUtil.stripHexPrefix(newAccount[0])) + return (isNotIncluded) ? Promise.resolve(newAccount) : Promise.reject(new Error('The account your are trying to import is a duplicate')) + default: + return Promise.resolve(newAccount) + } + }) + } + + // Add New Account // @number keyRingNum // From 2f7a95c25765ec040eddb8f3103bfe60d4760a26 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 7 Mar 2017 18:56:38 -0800 Subject: [PATCH 39/52] Fix grammar in erro message --- app/scripts/keyring-controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js index 7669b9f8f..72f613641 100644 --- a/app/scripts/keyring-controller.js +++ b/app/scripts/keyring-controller.js @@ -188,7 +188,7 @@ class KeyringController extends EventEmitter { switch (type) { case 'Simple Key Pair': let isNotIncluded = !accounts.find((key) => key === newAccount[0] || key === ethUtil.stripHexPrefix(newAccount[0])) - return (isNotIncluded) ? Promise.resolve(newAccount) : Promise.reject(new Error('The account your are trying to import is a duplicate')) + return (isNotIncluded) ? Promise.resolve(newAccount) : Promise.reject(new Error('The account you\'re are trying to import is a duplicate')) default: return Promise.resolve(newAccount) } From 4916331c530896bbcef13a71a8f6dc0164b43c01 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Tue, 7 Mar 2017 22:42:16 -0500 Subject: [PATCH 40/52] change BN.mul to BN.muln --- app/scripts/lib/tx-utils.js | 2 +- test/unit/tx-utils-test.js | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index 15cbb5b68..f5051eb8f 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -71,7 +71,7 @@ module.exports = class txProviderUtils { addGasBuffer (gas, blockGasLimitHex) { const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16) const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16) - const bufferedGas = bnGas.mul(1.5) + const bufferedGas = bnGas.muln(1.5) if (bnGas.gt(blockGasLimitBn)) return gas if (bufferedGas.lt(blockGasLimitBn)) return ethUtil.addHexPrefix(bufferedGas.toString(16)) diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js index a7f2094c4..65233e1d9 100644 --- a/test/unit/tx-utils-test.js +++ b/test/unit/tx-utils-test.js @@ -13,16 +13,14 @@ describe('txUtils', function() { }) describe('addGasBuffer', function() { - describe('multiplies by 1.5', function() { - it('over a value', function() { - const input = '0x123fad' - const output = txUtils.addGasBuffer(input, '0x3d4c52') //0x3d4c52 is 4mil for dummy gas limit + it('multiplies by 1.5', function() { + const input = '0x123fad' + const output = txUtils.addGasBuffer(input, '0x3d4c52') //0x3d4c52 is 4mil for dummy gas limit - const inputBn = new BN(input, 'hex') - const outputBn = new BN(output, 'hex') - const expectedBn = inputBn.mul(1.5) - assert(outputBn.eq(expectedBn), 'returns 1.5 the input value') - }) + const inputBn = new BN(ethUtil.stripHexPrefix(input), 'hex') + const outputBn = new BN(ethUtil.stripHexPrefix(output), 'hex') + const expectedBn = inputBn.muln(1.5) + assert(outputBn.eq(expectedBn), 'returns 1.5 the input value') }) }) }) From 1f0a4dd0331cbcc210ab9c8fc2a323af84fe4bf5 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 7 Mar 2017 21:30:27 -0800 Subject: [PATCH 41/52] Bump changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d07154bdf..603a92df5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Add personal_sign method support. - Add ability to customize gas and gasPrice on the transaction approval screen. +- Increase default gas buffer to 1.5x estimated gas value. ## 3.3.0 2017-2-20 From 17b805c76ea3ea160bcb2560d2043581b54c4834 Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 7 Mar 2017 22:18:14 -0800 Subject: [PATCH 42/52] tx-utils - clean and comment --- app/scripts/lib/tx-utils.js | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index f5051eb8f..32a8a012a 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -55,26 +55,22 @@ module.exports = class txProviderUtils { // try adding an additional gas buffer to our estimation for safety const estimatedGasBn = new BN(ethUtil.stripHexPrefix(txData.estimatedGas), 16) const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16) - const estimationWithBuffer = new BN(this.addGasBuffer(estimatedGasBn, blockGasLimitHex), 16) - // added gas buffer is too high - if (estimationWithBuffer.gt(blockGasLimitBn)) { - txParams.gas = txData.estimatedGas - // added gas buffer is safe - } else { - const gasWithBufferHex = ethUtil.intToHex(estimationWithBuffer) - txParams.gas = gasWithBufferHex - } + const finalRecommendedGasBn = new BN(this.addGasBuffer(estimatedGasBn, blockGasLimitHex), 16) + txParams.gas = ethUtil.intToHex(finalRecommendedGasBn) cb() return } - addGasBuffer (gas, blockGasLimitHex) { + addGasBuffer (initialGasLimitHex, blockGasLimitHex) { const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16) - const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16) - const bufferedGas = bnGas.muln(1.5) - - if (bnGas.gt(blockGasLimitBn)) return gas - if (bufferedGas.lt(blockGasLimitBn)) return ethUtil.addHexPrefix(bufferedGas.toString(16)) + const initialGasLimitBn = new BN(ethUtil.stripHexPrefix(initialGasLimitHex), 16) + const bufferedGasLimitBn = initialGasLimitBn.muln(1.5) + + // if initialGasLimit is above blockGasLimit, dont modify it + if (initialGasLimitBn.gt(blockGasLimitBn)) return initialGasLimitHex + // if bufferedGasLimit is below blockGasLimit, use bufferedGasLimit + if (bufferedGasLimitBn.lt(blockGasLimitBn)) return ethUtil.addHexPrefix(bufferedGasLimitBn.toString(16)) + // otherwise use blockGasLimit return ethUtil.addHexPrefix(blockGasLimitBn.toString(16)) } From 68b99dfb086c282fa3f2e76fbaf93673e92f097d Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 7 Mar 2017 22:28:02 -0800 Subject: [PATCH 43/52] test - tx-utils add tests for `addGasBuffer` --- test/unit/tx-utils-test.js | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js index 65233e1d9..c0ed9addd 100644 --- a/test/unit/tx-utils-test.js +++ b/test/unit/tx-utils-test.js @@ -13,14 +13,40 @@ describe('txUtils', function() { }) describe('addGasBuffer', function() { - it('multiplies by 1.5', function() { + it('multiplies by 1.5, when within block gas limit', function() { + // naive estimatedGas: 0x123fad (~1.2 mil) const input = '0x123fad' - const output = txUtils.addGasBuffer(input, '0x3d4c52') //0x3d4c52 is 4mil for dummy gas limit - + // dummy gas limit: 0x3d4c52 (4 mil) + const blockGasLimit = '0x3d4c52' + const output = txUtils.addGasBuffer(input, blockGasLimit) const inputBn = new BN(ethUtil.stripHexPrefix(input), 'hex') const outputBn = new BN(ethUtil.stripHexPrefix(output), 'hex') const expectedBn = inputBn.muln(1.5) assert(outputBn.eq(expectedBn), 'returns 1.5 the input value') }) + + it('uses original estimatedGas, when above block gas limit', function() { + // naive estimatedGas: 0x123fad (~1.2 mil) + const input = '0x123fad' + // dummy gas limit: 0x0f4240 (1 mil) + const blockGasLimit = '0x0f4240' + const output = txUtils.addGasBuffer(input, blockGasLimit) + const inputBn = new BN(ethUtil.stripHexPrefix(input), 'hex') + const outputBn = new BN(ethUtil.stripHexPrefix(output), 'hex') + const expectedBn = new BN(ethUtil.stripHexPrefix(input), 'hex') + assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value') + }) + + it('buffers up to block gas limit', function() { + // naive estimatedGas: 0x123fad (~1.2 mil) + const input = '0x1e8480' + // dummy gas limit: 0x1e8480 (2 mil) + const blockGasLimit = '0x1e8480' + const output = txUtils.addGasBuffer(input, blockGasLimit) + const inputBn = new BN(ethUtil.stripHexPrefix(input), 'hex') + const outputBn = new BN(ethUtil.stripHexPrefix(output), 'hex') + const expectedBn = new BN(ethUtil.stripHexPrefix(blockGasLimit), 'hex') + assert(outputBn.eq(expectedBn), 'returns the block gas limit value') + }) }) }) From c063fab9932c6b90414fd7db7849012d6594afb7 Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 7 Mar 2017 22:47:35 -0800 Subject: [PATCH 44/52] tx-utils - stricter naming type-based convention --- app/scripts/lib/tx-utils.js | 24 +++++++++++++++--------- test/unit/tx-utils-test.js | 28 ++++++++++++++-------------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index 32a8a012a..f1171851c 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -53,25 +53,23 @@ module.exports = class txProviderUtils { } // if gasLimit not originally specified, // try adding an additional gas buffer to our estimation for safety - const estimatedGasBn = new BN(ethUtil.stripHexPrefix(txData.estimatedGas), 16) - const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16) - const finalRecommendedGasBn = new BN(this.addGasBuffer(estimatedGasBn, blockGasLimitHex), 16) - txParams.gas = ethUtil.intToHex(finalRecommendedGasBn) + const recommendedGasHex = this.addGasBuffer(txData.estimatedGas, blockGasLimitHex) + txParams.gas = recommendedGasHex cb() return } addGasBuffer (initialGasLimitHex, blockGasLimitHex) { - const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16) - const initialGasLimitBn = new BN(ethUtil.stripHexPrefix(initialGasLimitHex), 16) + const initialGasLimitBn = hexToBn(initialGasLimitHex) + const blockGasLimitBn = hexToBn(blockGasLimitHex) const bufferedGasLimitBn = initialGasLimitBn.muln(1.5) // if initialGasLimit is above blockGasLimit, dont modify it - if (initialGasLimitBn.gt(blockGasLimitBn)) return initialGasLimitHex + if (initialGasLimitBn.gt(blockGasLimitBn)) return bnToHex(initialGasLimitBn) // if bufferedGasLimit is below blockGasLimit, use bufferedGasLimit - if (bufferedGasLimitBn.lt(blockGasLimitBn)) return ethUtil.addHexPrefix(bufferedGasLimitBn.toString(16)) + if (bufferedGasLimitBn.lt(blockGasLimitBn)) return bnToHex(bufferedGasLimitBn) // otherwise use blockGasLimit - return ethUtil.addHexPrefix(blockGasLimitBn.toString(16)) + return bnToHex(blockGasLimitBn) } fillInTxParams (txParams, cb) { @@ -129,3 +127,11 @@ module.exports = class txProviderUtils { function isUndef(value) { return value === undefined } + +function bnToHex(inputBn) { + return ethUtil.addHexPrefix(inputBn.toString(16)) +} + +function hexToBn(inputHex) { + return new BN(ethUtil.stripHexPrefix(inputHex), 16) +} \ No newline at end of file diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js index c0ed9addd..641b4942f 100644 --- a/test/unit/tx-utils-test.js +++ b/test/unit/tx-utils-test.js @@ -15,11 +15,11 @@ describe('txUtils', function() { describe('addGasBuffer', function() { it('multiplies by 1.5, when within block gas limit', function() { // naive estimatedGas: 0x123fad (~1.2 mil) - const input = '0x123fad' + const inputHex = '0x123fad' // dummy gas limit: 0x3d4c52 (4 mil) - const blockGasLimit = '0x3d4c52' - const output = txUtils.addGasBuffer(input, blockGasLimit) - const inputBn = new BN(ethUtil.stripHexPrefix(input), 'hex') + const blockGasLimitHex = '0x3d4c52' + const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) + const inputBn = new BN(ethUtil.stripHexPrefix(inputHex), 'hex') const outputBn = new BN(ethUtil.stripHexPrefix(output), 'hex') const expectedBn = inputBn.muln(1.5) assert(outputBn.eq(expectedBn), 'returns 1.5 the input value') @@ -27,25 +27,25 @@ describe('txUtils', function() { it('uses original estimatedGas, when above block gas limit', function() { // naive estimatedGas: 0x123fad (~1.2 mil) - const input = '0x123fad' + const inputHex = '0x123fad' // dummy gas limit: 0x0f4240 (1 mil) - const blockGasLimit = '0x0f4240' - const output = txUtils.addGasBuffer(input, blockGasLimit) - const inputBn = new BN(ethUtil.stripHexPrefix(input), 'hex') + const blockGasLimitHex = '0x0f4240' + const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) + const inputBn = new BN(ethUtil.stripHexPrefix(inputHex), 'hex') const outputBn = new BN(ethUtil.stripHexPrefix(output), 'hex') - const expectedBn = new BN(ethUtil.stripHexPrefix(input), 'hex') + const expectedBn = new BN(ethUtil.stripHexPrefix(inputHex), 'hex') assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value') }) it('buffers up to block gas limit', function() { // naive estimatedGas: 0x123fad (~1.2 mil) - const input = '0x1e8480' + const inputHex = '0x1e8480' // dummy gas limit: 0x1e8480 (2 mil) - const blockGasLimit = '0x1e8480' - const output = txUtils.addGasBuffer(input, blockGasLimit) - const inputBn = new BN(ethUtil.stripHexPrefix(input), 'hex') + const blockGasLimitHex = '0x1e8480' + const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) + const inputBn = new BN(ethUtil.stripHexPrefix(inputHex), 'hex') const outputBn = new BN(ethUtil.stripHexPrefix(output), 'hex') - const expectedBn = new BN(ethUtil.stripHexPrefix(blockGasLimit), 'hex') + const expectedBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 'hex') assert(outputBn.eq(expectedBn), 'returns the block gas limit value') }) }) From 92b8443824bffca219b146028d5685e6aa1ffabf Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 7 Mar 2017 22:51:39 -0800 Subject: [PATCH 45/52] tx-utils - add encoding utils --- app/scripts/lib/tx-utils.js | 2 +- test/unit/tx-utils-test.js | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index f1171851c..c6814c05f 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -91,7 +91,7 @@ module.exports = class txProviderUtils { // builds ethTx from txParams object buildEthTxFromParams (txParams) { // apply gas multiplyer - let gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice), 16) + let gasPrice = hexToBn(txParams.gasPrice) // multiply and divide by 100 so as to add percision to integer mul txParams.gasPrice = ethUtil.intToHex(gasPrice.toNumber()) // normalize values diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js index 641b4942f..e57b25e83 100644 --- a/test/unit/tx-utils-test.js +++ b/test/unit/tx-utils-test.js @@ -19,8 +19,8 @@ describe('txUtils', function() { // dummy gas limit: 0x3d4c52 (4 mil) const blockGasLimitHex = '0x3d4c52' const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) - const inputBn = new BN(ethUtil.stripHexPrefix(inputHex), 'hex') - const outputBn = new BN(ethUtil.stripHexPrefix(output), 'hex') + const inputBn = hexToBn(inputHex) + const outputBn = hexToBn(output) const expectedBn = inputBn.muln(1.5) assert(outputBn.eq(expectedBn), 'returns 1.5 the input value') }) @@ -31,9 +31,9 @@ describe('txUtils', function() { // dummy gas limit: 0x0f4240 (1 mil) const blockGasLimitHex = '0x0f4240' const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) - const inputBn = new BN(ethUtil.stripHexPrefix(inputHex), 'hex') - const outputBn = new BN(ethUtil.stripHexPrefix(output), 'hex') - const expectedBn = new BN(ethUtil.stripHexPrefix(inputHex), 'hex') + const inputBn = hexToBn(inputHex) + const outputBn = hexToBn(output) + const expectedBn = hexToBn(inputHex) assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value') }) @@ -43,10 +43,16 @@ describe('txUtils', function() { // dummy gas limit: 0x1e8480 (2 mil) const blockGasLimitHex = '0x1e8480' const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) - const inputBn = new BN(ethUtil.stripHexPrefix(inputHex), 'hex') - const outputBn = new BN(ethUtil.stripHexPrefix(output), 'hex') - const expectedBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 'hex') + const inputBn = hexToBn(inputHex) + const outputBn = hexToBn(output) + const expectedBn = hexToBn(blockGasLimitHex) assert(outputBn.eq(expectedBn), 'returns the block gas limit value') }) }) }) + +// util + +function hexToBn(inputHex) { + return new BN(ethUtil.stripHexPrefix(inputHex), 16) +} \ No newline at end of file From cf2268c3d29d97afa22cd11663bb6e3e74c09b5a Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 8 Mar 2017 09:06:41 -0800 Subject: [PATCH 46/52] Nodeify and promisify calls to background. --- app/scripts/metamask-controller.js | 6 ++++-- ui/app/actions.js | 34 ++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 3b3329b58..536891dc6 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -244,8 +244,6 @@ module.exports = class MetamaskController extends EventEmitter { return { // etc getState: (cb) => cb(null, this.getState()), - setDefaultRpc: this.setDefaultRpc.bind(this), - setCustomRpc: this.setCustomRpc.bind(this), setProviderType: this.setProviderType.bind(this), useEtherscanProvider: this.useEtherscanProvider.bind(this), setCurrentCurrency: this.setCurrentCurrency.bind(this), @@ -266,6 +264,8 @@ module.exports = class MetamaskController extends EventEmitter { // PreferencesController setSelectedAddress: nodeify(preferencesController.setSelectedAddress).bind(preferencesController), + setDefaultRpc: nodeify(this.setDefaultRpc).bind(this), + setCustomRpc: nodeify(this.setCustomRpc).bind(this), // KeyringController setLocked: nodeify(keyringController.setLocked).bind(keyringController), @@ -666,6 +666,7 @@ module.exports = class MetamaskController extends EventEmitter { this.configManager.setRpcTarget('http://localhost:8545') extension.runtime.reload() this.lookupNetwork() + return Promise.resolve('http://localhost:8545') } setCustomRpc (rpcTarget, rpcList) { @@ -674,6 +675,7 @@ module.exports = class MetamaskController extends EventEmitter { .then(() => { extension.runtime.reload() this.lookupNetwork() + return Promise.resolve(rpcTarget) }) } diff --git a/ui/app/actions.js b/ui/app/actions.js index 2fc0d3523..062a691e2 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -674,21 +674,37 @@ function markAccountsFound() { // default rpc target refers to localhost:8545 in this instance. function setDefaultRpcTarget (rpcList) { log.debug(`background.setDefaultRpcTarget`) - background.setDefaultRpc() - return { - type: actions.SET_RPC_TARGET, - value: 'http://localhost:8545', + return (dispatch) => { + background.setDefaultRpc((err, result) => { + if (err) { + console.error(err) + return dispatch(self.displayWarning('Had a problem changing networks.')) + } + dispatch(self.setRpc(result)) + }) } + } function setRpcTarget (newRpc) { - return (dispatch) => { log.debug(`background.setRpcTarget`) - background.setCustomRpc(newRpc) - return { - type: actions.SET_RPC_TARGET, - value: newRpc, + return (dispatch) => { + background.setCustomRpc(newRpc, (err, result) => { + if (err) { + console.err(err) + return dispatch(self.displayWarning('Had a problem changing networks!')) + } + dispatch(self.setRpc(result)) + }) } + + +} + +function setRpc (newRpc) { + return { + type: actions.SET_RPC_TARGET, + value: 'http://localhost:8545', } } From 0ee8ca178e9240ab25454bafc88c58ebef6b69c3 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 8 Mar 2017 09:08:28 -0800 Subject: [PATCH 47/52] Remove unneeded setrpc method. --- ui/app/actions.js | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/ui/app/actions.js b/ui/app/actions.js index 062a691e2..82b6fac18 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -680,31 +680,19 @@ function setDefaultRpcTarget (rpcList) { console.error(err) return dispatch(self.displayWarning('Had a problem changing networks.')) } - dispatch(self.setRpc(result)) }) } - } function setRpcTarget (newRpc) { - log.debug(`background.setRpcTarget`) - return (dispatch) => { - background.setCustomRpc(newRpc, (err, result) => { - if (err) { - console.err(err) - return dispatch(self.displayWarning('Had a problem changing networks!')) - } - dispatch(self.setRpc(result)) - }) - } - - -} - -function setRpc (newRpc) { - return { - type: actions.SET_RPC_TARGET, - value: 'http://localhost:8545', + log.debug(`background.setRpcTarget`) + return (dispatch) => { + background.setCustomRpc(newRpc, (err, result) => { + if (err) { + console.err(err) + return dispatch(self.displayWarning('Had a problem changing networks!')) + } + }) } } From 21769a008ccc5fdc2ac5d23a37d401a1d2a20694 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 8 Mar 2017 09:35:31 -0800 Subject: [PATCH 48/52] Fix typo, switch to log.error --- ui/app/actions.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/app/actions.js b/ui/app/actions.js index 82b6fac18..d4fd7553b 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -677,7 +677,7 @@ function setDefaultRpcTarget (rpcList) { return (dispatch) => { background.setDefaultRpc((err, result) => { if (err) { - console.error(err) + log.error(err) return dispatch(self.displayWarning('Had a problem changing networks.')) } }) @@ -689,7 +689,7 @@ function setRpcTarget (newRpc) { return (dispatch) => { background.setCustomRpc(newRpc, (err, result) => { if (err) { - console.err(err) + log.error(err) return dispatch(self.displayWarning('Had a problem changing networks!')) } }) @@ -768,7 +768,7 @@ function exportAccount (address) { dispatch(self.hideLoadingIndication()) if (err) { - console.error(err) + log.error(err) return dispatch(self.displayWarning('Had a problem exporting the account.')) } From 529eb25ced3337aadafd44bcf43e3ae6f192614a Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 8 Mar 2017 10:13:45 -0800 Subject: [PATCH 49/52] Convert alert to a log.error --- app/scripts/popup-core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js index 0c97a5d19..ae8539a30 100644 --- a/app/scripts/popup-core.js +++ b/app/scripts/popup-core.js @@ -50,7 +50,7 @@ function setupControllerConnection (connectionStream, cb) { function setupApp (err, accountManager) { if (err) { - alert(err.stack) + log.error(err.stack) throw err } From 6f980cfe10d32ddc276b737df42005ef7cf4cd96 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 8 Mar 2017 10:46:17 -0800 Subject: [PATCH 50/52] Add more informative message --- app/scripts/popup-core.js | 4 +++- ui/app/css/lib.css | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js index ae8539a30..e093d06f4 100644 --- a/app/scripts/popup-core.js +++ b/app/scripts/popup-core.js @@ -49,12 +49,14 @@ function setupControllerConnection (connectionStream, cb) { } function setupApp (err, accountManager) { + var container = document.getElementById('app-content') if (err) { + container.innerHTML = '
The MetaMask app failed to load: please restart MetaMask
' + container.style.height = '80px' log.error(err.stack) throw err } - var container = document.getElementById('app-content') MetaMaskUi({ container: container, diff --git a/ui/app/css/lib.css b/ui/app/css/lib.css index a8df1d115..99c6f1b9d 100644 --- a/ui/app/css/lib.css +++ b/ui/app/css/lib.css @@ -256,3 +256,9 @@ hr.horizontal-line { text-overflow: ellipsis; white-space: nowrap; } + +.critical-error { + text-align: center; + margin-top: 20px; + color: red; +} From acc9a2a9d05269511efe26bd790cbc256533c19e Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 8 Mar 2017 10:53:11 -0800 Subject: [PATCH 51/52] Modify message. --- app/scripts/popup-core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js index e093d06f4..b1e521a7a 100644 --- a/app/scripts/popup-core.js +++ b/app/scripts/popup-core.js @@ -51,7 +51,7 @@ function setupControllerConnection (connectionStream, cb) { function setupApp (err, accountManager) { var container = document.getElementById('app-content') if (err) { - container.innerHTML = '
The MetaMask app failed to load: please restart MetaMask
' + container.innerHTML = '
The MetaMask app failed to load: please open and close MetaMask again to restart.
' container.style.height = '80px' log.error(err.stack) throw err From 05346ec3c343a3c7116c2989c623128739d658e0 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 8 Mar 2017 13:38:55 -0800 Subject: [PATCH 52/52] Version 3.4.0 --- CHANGELOG.md | 2 ++ app/manifest.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf03cf41e..c0ba9b0b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,11 @@ ## Current Master +## 3.4.0 2017-3-8 - Add two most recently used custom RPCs to network dropdown menu. - Add personal_sign method support. +- Add personal_ecRecover method support. - Add ability to customize gas and gasPrice on the transaction approval screen. - Increase default gas buffer to 1.5x estimated gas value. diff --git a/app/manifest.json b/app/manifest.json index f8a08363b..910a5701e 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "MetaMask", "short_name": "Metamask", - "version": "3.3.0", + "version": "3.4.0", "manifest_version": 2, "author": "https://metamask.io", "description": "Ethereum Browser Extension",