From 2117490d41a31eeb2d39383bfc5ae7751f445420 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 29 Aug 2017 11:36:53 -0700 Subject: [PATCH 01/13] Add test for trying to reproduce faq#67 Failed to reproduce this issue with the same inputs. --- test/unit/nonce-tracker-test.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/unit/nonce-tracker-test.js b/test/unit/nonce-tracker-test.js index 3312a3bd0..8970cf84d 100644 --- a/test/unit/nonce-tracker-test.js +++ b/test/unit/nonce-tracker-test.js @@ -162,6 +162,25 @@ describe('Nonce Tracker', function () { await nonceLock.releaseLock() }) }) + + describe('Faq issue 67', function () { + beforeEach(function () { + const txGen = new MockTxGen() + const confirmedTxs = txGen.generate({ status: 'confirmed' }, { count: 64 }) + const pendingTxs = txGen.generate({ + status: 'submitted', + }, { count: 10 }) + // 0x40 is 64 in hex: + nonceTracker = generateNonceTrackerWith(pendingTxs, [], '0x40') + }) + + it('should return nonce after network nonce', async function () { + this.timeout(15000) + const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926') + assert.equal(nonceLock.nextNonce, '74', `nonce should be 74 got ${nonceLock.nextNonce}`) + await nonceLock.releaseLock() + }) + }) }) }) From 64717726c40e46dc7decffbaf3db6da0f4b0dc11 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 7 Sep 2017 15:27:30 -0700 Subject: [PATCH 02/13] Reword forgot password to restore seed phrase This always confuses people, I just finally did it. --- ui/app/unlock.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/unlock.js b/ui/app/unlock.js index 9bacd5124..4180791c4 100644 --- a/ui/app/unlock.js +++ b/ui/app/unlock.js @@ -80,7 +80,7 @@ UnlockScreen.prototype.render = function () { color: 'rgb(247, 134, 28)', textDecoration: 'underline', }, - }, 'I forgot my password.'), + }, 'Restore from seed phrase'), ]), ]) ) From 8d7f78c1a543cbbeb9d6599be346fc99db866340 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 7 Sep 2017 16:18:32 -0700 Subject: [PATCH 03/13] Add caret to indicate network is dropdown. --- ui/app/components/network.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ui/app/components/network.js b/ui/app/components/network.js index 698a0bbb9..c7a28b363 100644 --- a/ui/app/components/network.js +++ b/ui/app/components/network.js @@ -74,6 +74,7 @@ Network.prototype.render = function () { color: '#039396', }}, 'Ethereum Main Net'), + h('i.fa.fa-caret-down.fa-lg'), ]) case 'ropsten-test-network': return h('.network-indicator', [ @@ -83,6 +84,7 @@ Network.prototype.render = function () { color: '#ff6666', }}, 'Ropsten Test Net'), + h('i.fa.fa-caret-down.fa-lg'), ]) case 'kovan-test-network': return h('.network-indicator', [ @@ -92,6 +94,7 @@ Network.prototype.render = function () { color: '#690496', }}, 'Kovan Test Net'), + h('i.fa.fa-caret-down.fa-lg'), ]) case 'rinkeby-test-network': return h('.network-indicator', [ @@ -101,6 +104,7 @@ Network.prototype.render = function () { color: '#e7a218', }}, 'Rinkeby Test Net'), + h('i.fa.fa-caret-down.fa-lg'), ]) default: return h('.network-indicator', [ @@ -116,6 +120,7 @@ Network.prototype.render = function () { color: '#AEAEAE', }}, 'Private Network'), + h('i.fa.fa-caret-down.fa-lg'), ]) } })(), From 54fb8e8cef9b2692d1ad1bac9efd5cbe6eadf823 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 7 Sep 2017 16:26:31 -0700 Subject: [PATCH 04/13] Add cursor on hover on loading. Change some wording. --- ui/app/components/network.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/app/components/network.js b/ui/app/components/network.js index c7a28b363..0dbe37cdd 100644 --- a/ui/app/components/network.js +++ b/ui/app/components/network.js @@ -22,7 +22,7 @@ Network.prototype.render = function () { let iconName, hoverText if (networkNumber === 'loading') { - return h('span', { + return h('span.pointer', { style: { display: 'flex', alignItems: 'center', @@ -37,7 +37,7 @@ Network.prototype.render = function () { }, src: 'images/loading.svg', }), - h('i.fa.fa-sort-desc'), + h('i.fa.fa-caret-down'), ]) } else if (providerName === 'mainnet') { hoverText = 'Main Ethereum Network' @@ -73,7 +73,7 @@ Network.prototype.render = function () { style: { color: '#039396', }}, - 'Ethereum Main Net'), + 'Main Network'), h('i.fa.fa-caret-down.fa-lg'), ]) case 'ropsten-test-network': From 6560a2c3af66940e9fbfcc9943655ca5c7282121 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 7 Sep 2017 17:55:34 -0700 Subject: [PATCH 05/13] Add front-end validation for own adddresses as a token contract address. Add information on token contract addresses. --- ui/app/add-token.js | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/ui/app/add-token.js b/ui/app/add-token.js index 15ef7a852..81894247b 100644 --- a/ui/app/add-token.js +++ b/ui/app/add-token.js @@ -3,6 +3,8 @@ const Component = require('react').Component const h = require('react-hyperscript') const connect = require('react-redux').connect const actions = require('./actions') +const Tooltip = require('./components/tooltip.js') + const ethUtil = require('ethereumjs-util') const abi = require('human-standard-token-abi') @@ -15,6 +17,7 @@ module.exports = connect(mapStateToProps)(AddTokenScreen) function mapStateToProps (state) { return { + identities: state.metamask.identities, } } @@ -64,15 +67,24 @@ AddTokenScreen.prototype.render = function () { }, [ h('div', [ - h('span', { - style: { fontWeight: 'bold', paddingRight: '10px'}, - }, 'Token Address'), + h(Tooltip, { + position: 'top', + title: 'The contract of the actual token contract. Click for more info.', + }, [ + h('a', { + style: { fontWeight: 'bold', paddingRight: '10px'}, + href: 'https://consensyssupport.happyfox.com/staff/kb/article/24-what-is-a-token-contract-address', + }, [ + h('span', 'Token Contract Address '), + h('i.fa.fa-question-circle'), + ]), + ]), ]), h('section.flex-row.flex-center', [ h('input#token-address', { name: 'address', - placeholder: 'Token Address', + placeholder: 'Token Contract Address', onChange: this.tokenAddressDidChange.bind(this), style: { width: 'inherit', @@ -171,7 +183,9 @@ AddTokenScreen.prototype.tokenAddressDidChange = function (event) { AddTokenScreen.prototype.validateInputs = function () { let msg = '' const state = this.state + const identitiesList = Object.keys(this.props.identities) const { address, symbol, decimals } = state + const standardAddress = ethUtil.addHexPrefix(address).toLowerCase() const validAddress = ethUtil.isValidAddress(address) if (!validAddress) { @@ -189,7 +203,12 @@ AddTokenScreen.prototype.validateInputs = function () { msg += 'Symbol must be between 0 and 10 characters.' } - const isValid = validAddress && validDecimals + const ownAddress = identitiesList.includes(standardAddress) + if (ownAddress) { + msg = 'Personal address detected. Input the token contact address.' + } + + const isValid = validAddress && validDecimals && !ownAddress if (!isValid) { this.setState({ @@ -216,4 +235,3 @@ AddTokenScreen.prototype.attemptToAutoFillTokenParams = async function (address) this.setState({ symbol: symbol[0], decimals: decimals[0].toString() }) } } - From 2200a1142ff609ec467edf8b78d70be79622588d Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 7 Sep 2017 17:55:49 -0700 Subject: [PATCH 06/13] Bump changelog. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c3aab200..a63a8604a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Current Master - Readded loose keyring label back into the account list. +- Add info on token contract addresses. +- Add validation preventing users from inputting their own addresses as token tracking addresses. ## 3.9.12 2017-9-6 From 54a5a117d55db826ac20059f70d748cd90516270 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 7 Sep 2017 18:00:45 -0700 Subject: [PATCH 07/13] Fix link to open new tab. --- ui/app/add-token.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/app/add-token.js b/ui/app/add-token.js index 81894247b..177adc572 100644 --- a/ui/app/add-token.js +++ b/ui/app/add-token.js @@ -74,6 +74,7 @@ AddTokenScreen.prototype.render = function () { h('a', { style: { fontWeight: 'bold', paddingRight: '10px'}, href: 'https://consensyssupport.happyfox.com/staff/kb/article/24-what-is-a-token-contract-address', + target: '_blank', }, [ h('span', 'Token Contract Address '), h('i.fa.fa-question-circle'), From 0e6c11a3b5e7677d8d37da4d41bf19b09f85cd88 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 7 Sep 2017 18:01:39 -0700 Subject: [PATCH 08/13] Fix typo. --- ui/app/add-token.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/add-token.js b/ui/app/add-token.js index 177adc572..18adc7eb5 100644 --- a/ui/app/add-token.js +++ b/ui/app/add-token.js @@ -206,7 +206,7 @@ AddTokenScreen.prototype.validateInputs = function () { const ownAddress = identitiesList.includes(standardAddress) if (ownAddress) { - msg = 'Personal address detected. Input the token contact address.' + msg = 'Personal address detected. Input the token contract address.' } const isValid = validAddress && validDecimals && !ownAddress From b7e24dcda7d67d0504ceb463ab1c1c1d77450bca Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 7 Sep 2017 18:17:43 -0700 Subject: [PATCH 09/13] Remove cryptonator from chrome permissions. --- app/manifest.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/manifest.json b/app/manifest.json index 256737c89..96d495178 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -57,9 +57,8 @@ "permissions": [ "storage", "clipboardWrite", - "http://localhost:8545/", - "https://api.cryptonator.com/" - ], + "http://localhost:8545/" + ], "web_accessible_resources": [ "scripts/inpage.js" ], From a7f0255085a1358e8ee314228f5d215dc47ea958 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 7 Sep 2017 18:18:14 -0700 Subject: [PATCH 10/13] Add to changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c3aab200..60e0e5674 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Current Master - Readded loose keyring label back into the account list. +- Remove cryptonator from chrome permissions. ## 3.9.12 2017-9-6 From 16957fa8ae90f940221f065e5aa7494efefc23da Mon Sep 17 00:00:00 2001 From: kumavis Date: Thu, 7 Sep 2017 22:49:53 -0700 Subject: [PATCH 11/13] ci - dont need global install of test utils --- circle.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/circle.yml b/circle.yml index 2ea60bb9d..e81e1bcaa 100644 --- a/circle.yml +++ b/circle.yml @@ -1,10 +1,6 @@ machine: node: version: 8.1.4 -dependencies: - pre: - - "npm i -g testem" - - "npm i -g mocha" test: override: - "npm run ci" \ No newline at end of file From d03b0547bb63c4d60fef9ba0d8ebbc88e3aa7b1e Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 8 Sep 2017 11:52:00 -0700 Subject: [PATCH 12/13] inpage provider - define sendAsync on the prototype --- app/scripts/lib/inpage-provider.js | 52 ++++++++++++++++-------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js index c63af06dc..13888dc67 100644 --- a/app/scripts/lib/inpage-provider.js +++ b/app/scripts/lib/inpage-provider.js @@ -40,31 +40,37 @@ function MetamaskInpageProvider (connectionStream) { // start and stop polling to unblock first block lock self.idMap = {} - // handle sendAsync requests via asyncProvider - self.sendAsync = function (payload, cb) { - // rewrite request ids - var request = eachJsonMessage(payload, (_message) => { - const message = Object.assign({}, _message) - const newId = createRandomId() - self.idMap[newId] = message.id - message.id = newId +} + +// handle sendAsync requests via asyncProvider +// also remap ids inbound and outbound +MetamaskInpageProvider.prototype.sendAsync = function (payload, cb) { + const self = this + + // rewrite request ids + const request = eachJsonMessage(payload, (_message) => { + const message = Object.assign({}, _message) + const newId = createRandomId() + self.idMap[newId] = message.id + message.id = newId + return message + }) + + // forward to asyncProvider + self.asyncProvider.sendAsync(request, (err, _res) => { + if (err) return cb(err) + // transform messages to original ids + const res = eachJsonMessage(_res, (message) => { + const oldId = self.idMap[message.id] + delete self.idMap[message.id] + message.id = oldId return message }) - // forward to asyncProvider - asyncProvider.sendAsync(request, function (err, res) { - if (err) return cb(err) - // transform messages to original ids - eachJsonMessage(res, (message) => { - var oldId = self.idMap[message.id] - delete self.idMap[message.id] - message.id = oldId - return message - }) - cb(null, res) - }) - } + cb(null, res) + }) } + MetamaskInpageProvider.prototype.send = function (payload) { const self = this @@ -110,10 +116,6 @@ MetamaskInpageProvider.prototype.send = function (payload) { } } -MetamaskInpageProvider.prototype.sendAsync = function () { - throw new Error('MetamaskInpageProvider - sendAsync not overwritten') -} - MetamaskInpageProvider.prototype.isConnected = function () { return true } From 585a32534d9415eec9f91b19732e121a4a4c3a79 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 8 Sep 2017 12:17:58 -0700 Subject: [PATCH 13/13] Version 3.9.13 --- CHANGELOG.md | 4 ++++ app/manifest.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c738ac375..9d528d253 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Current Master +## 3.9.13 2017-9-8 + +- Changed the way we initialize the inpage provider to fix a bug affecting some developers. + ## 3.9.12 2017-9-6 - Fix bug that prevented Web3 1.0 compatibility diff --git a/app/manifest.json b/app/manifest.json index 256737c89..51e82d6e3 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "MetaMask", "short_name": "Metamask", - "version": "3.9.12", + "version": "3.9.13", "manifest_version": 2, "author": "https://metamask.io", "description": "Ethereum Browser Extension",