aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Finlay <542863+danfinlay@users.noreply.github.com>2019-07-04 05:31:04 +0800
committerGitHub <noreply@github.com>2019-07-04 05:31:04 +0800
commitac8f3cb310338d92db057fcfbdd8cd6282e6d3de (patch)
tree243bef17d80479046e0f6fdcb16d22b0e98162bb
parent743afd4e9d0c229001519e1370945d640946fd2c (diff)
parent632c9b21e297f3255ecbb4a70812aa53c87b2ff4 (diff)
downloadtangerine-wallet-browser-ac8f3cb310338d92db057fcfbdd8cd6282e6d3de.tar
tangerine-wallet-browser-ac8f3cb310338d92db057fcfbdd8cd6282e6d3de.tar.gz
tangerine-wallet-browser-ac8f3cb310338d92db057fcfbdd8cd6282e6d3de.tar.bz2
tangerine-wallet-browser-ac8f3cb310338d92db057fcfbdd8cd6282e6d3de.tar.lz
tangerine-wallet-browser-ac8f3cb310338d92db057fcfbdd8cd6282e6d3de.tar.xz
tangerine-wallet-browser-ac8f3cb310338d92db057fcfbdd8cd6282e6d3de.tar.zst
tangerine-wallet-browser-ac8f3cb310338d92db057fcfbdd8cd6282e6d3de.zip
Merge pull request #6780 from MetaMask/Version-6.7.2
Version 6.7.2 Release Candidate
-rw-r--r--.circleci/config.yml32
-rw-r--r--.github/CODEOWNERS1
-rw-r--r--.nvmrc2
-rw-r--r--CHANGELOG.md15
-rw-r--r--README.md18
-rw-r--r--app/_locales/cs/messages.json4
-rw-r--r--app/_locales/de/messages.json4
-rw-r--r--app/_locales/en/messages.json4
-rw-r--r--app/_locales/es/messages.json4
-rw-r--r--app/_locales/fr/messages.json4
-rw-r--r--app/_locales/hn/messages.json4
-rw-r--r--app/_locales/ht/messages.json4
-rw-r--r--app/_locales/it/messages.json4
-rw-r--r--app/_locales/ja/messages.json4
-rw-r--r--app/_locales/ko/messages.json4
-rw-r--r--app/_locales/nl/messages.json4
-rw-r--r--app/_locales/ph/messages.json4
-rw-r--r--app/_locales/pl/messages.json4
-rw-r--r--app/_locales/pt/messages.json4
-rw-r--r--app/_locales/ru/messages.json4
-rw-r--r--app/_locales/sk/messages.json4
-rw-r--r--app/_locales/sl/messages.json4
-rw-r--r--app/_locales/th/messages.json4
-rw-r--r--app/_locales/tml/messages.json4
-rw-r--r--app/_locales/tr/messages.json4
-rw-r--r--app/_locales/vi/messages.json4
-rw-r--r--app/_locales/zh_CN/messages.json4
-rw-r--r--app/_locales/zh_TW/messages.json4
-rw-r--r--app/images/spinner.gifbin0 -> 80392 bytes
-rw-r--r--app/manifest.json2
-rw-r--r--app/notification.html25
-rw-r--r--app/scripts/controllers/network/createLocalhostClient.js18
-rw-r--r--app/scripts/controllers/transactions/lib/util.js8
-rw-r--r--app/scripts/controllers/transactions/tx-state-manager.js30
-rw-r--r--development/states/send-edit.json22
-rw-r--r--docs/publishing.md13
-rw-r--r--gulpfile.js17
-rw-r--r--package-lock.json525
-rw-r--r--package.json26
-rw-r--r--test/e2e/beta/metamask-beta-ui.spec.js26
-rw-r--r--test/unit/app/controllers/transactions/tx-state-manager-test.js62
-rw-r--r--ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js63
-rw-r--r--ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js41
-rw-r--r--ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js23
-rw-r--r--ui/app/components/app/modals/account-details-modal.js107
-rw-r--r--ui/app/components/app/modals/account-details-modal/account-details-modal.component.js87
-rw-r--r--ui/app/components/app/modals/account-details-modal/account-details-modal.container.js27
-rw-r--r--ui/app/components/app/modals/account-details-modal/index.js1
-rw-r--r--ui/app/components/app/modals/deposit-ether-modal.js36
-rw-r--r--ui/app/components/app/modals/modal.js10
-rw-r--r--ui/app/components/app/modals/shapeshift-deposit-tx-modal.js40
-rw-r--r--ui/app/components/app/shapeshift-form.js256
-rw-r--r--ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js24
-rw-r--r--ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js81
-rw-r--r--ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js19
-rw-r--r--ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js78
-rw-r--r--ui/app/pages/first-time-flow/first-time-flow.component.js2
-rw-r--r--ui/app/pages/keychains/restore-vault.js1
-rw-r--r--ui/app/selectors/confirm-transaction.js60
-rw-r--r--ui/app/store/actions.js4
60 files changed, 742 insertions, 1152 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 68cd4f7a9..a69903373 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -80,7 +80,7 @@ workflows:
jobs:
prep-deps-npm:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- run:
@@ -94,7 +94,7 @@ jobs:
prep-build:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -113,7 +113,7 @@ jobs:
prep-docs:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -128,7 +128,7 @@ jobs:
prep-scss:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -147,7 +147,7 @@ jobs:
test-lint:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -158,7 +158,7 @@ jobs:
test-deps:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -182,7 +182,7 @@ jobs:
# destination: test-artifacts
test-e2e-chrome:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -197,7 +197,7 @@ jobs:
test-e2e-firefox:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- run:
@@ -215,7 +215,7 @@ jobs:
job-screens:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -230,7 +230,7 @@ jobs:
job-publish-prerelease:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -250,7 +250,7 @@ jobs:
job-publish-release:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -267,7 +267,7 @@ jobs:
test-unit:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -277,7 +277,7 @@ jobs:
command: npm run test:coverage
test-mozilla-lint:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -288,7 +288,7 @@ jobs:
test-integration-flat-firefox:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -304,7 +304,7 @@ jobs:
environment:
browsers: '["Chrome"]'
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- checkout
- attach_workspace:
@@ -315,7 +315,7 @@ jobs:
all-tests-pass:
docker:
- - image: circleci/node:8.15.1-browsers
+ - image: circleci/node:10.16-browsers
steps:
- run:
name: All Tests Passed
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 7a7d51936..5ee6fac12 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,6 +1,7 @@
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners.
+package*.json @whymarrh
ui/ @danjm @whymarrh
app/scripts/controllers/transactions @frankiebee
diff --git a/.nvmrc b/.nvmrc
index 9235dd0ad..f0da09441 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v8.15
+v10.16.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6960385ba..0bd3ccc7f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,21 @@
## Current Develop Branch
+## 6.7.2 Mon Jul 01 2019
+
+- [#6713](https://github.com/MetaMask/metamask-extension/pull/6713): * Normalize and Validate txParams in TransactionStateManager.addTx too
+- [#6759](https://github.com/MetaMask/metamask-extension/pull/6759): Update to Node.js v10
+- [#Fixes #6694 ](https://github.com/MetaMask/metamask-extension/pull/Fixes #6694 ): Fixes #6694
+- [#6743](https://github.com/MetaMask/metamask-extension/pull/6743): * Add tests for ImportWithSeedPhrase#parseSeedPhrase
+- [#Fixes #6740](https://github.com/MetaMask/metamask-extension/pull/Fixes #6740): Fixes #6740
+- [#Fixes #6741](https://github.com/MetaMask/metamask-extension/pull/Fixes #6741): Fixes #6741
+- [#6761](https://github.com/MetaMask/metamask-extension/pull/6761): Fixes #6760, correct PropTypes for nextRoute
+- [#6754](https://github.com/MetaMask/metamask-extension/pull/6754): There is currently a bug in chrome that prevents reading source maps
+- [#6589](https://github.com/MetaMask/metamask-extension/pull/6589): Document hotfix protocol
+- [#6738](https://github.com/MetaMask/metamask-extension/pull/6738): Add codeowner for package-lock-old.json package-lock.json package.json packagelock-old.json files
+- [#6648](https://github.com/MetaMask/metamask-extension/pull/6648): Add loading view to notification.html
+- [#6731](https://github.com/MetaMask/metamask-extension/pull/6731): Add brave as a platform type for MetaMask
+
## 6.7.1 Fri Jun 28 2019
- [#6764](https://github.com/MetaMask/metamask-extension/pull/6764): Fix display of token amount on confirm transaction screen
diff --git a/README.md b/README.md
index b742e1868..055d9053b 100644
--- a/README.md
+++ b/README.md
@@ -11,18 +11,16 @@ To learn how to contribute to the MetaMask project itself, visit our [Internal D
## Building locally
-- Install [Node.js](https://nodejs.org) version 8 and the latest available npm@6
+- Install [Node.js](https://nodejs.org) version 10 and the latest available npm@6
- If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you.
- If you install Node.js manually, ensure you're using npm@6
- Install npm@6 using `npm install -g npm@6`
-- Install dependencies: `npm install`
+- Install dependencies: `npm ci`
- If you have issues with node-sass compilation, try `npm rebuild node-sass`
-- Install gulp globally with `npm install -g gulp-cli`.
-- Build the project to the `./dist/` folder with `gulp build`.
-- Optionally, to rebuild on file changes, run `gulp dev`.
-- To package .zip files for distribution, run `gulp zip`, or run the full build & zip with `gulp dist`.
+- Build the project to the `./dist/` folder with `npm run dist`.
+- Optionally, to start a development build (e.g. with logging and file watching) run `npm start` instead.
- Uncompressed builds can be found in `/dist`, compressed builds can be found in `/builds` once they're built.
+Uncompressed builds can be found in `/dist`, compressed builds can be found in `/builds` once they're built.
## Contributing
@@ -32,13 +30,11 @@ You can re-generate the docs locally by running `npm run doc`, and contributors
### Running Tests
-Requires `mocha` installed. Run `npm install -g mocha`.
-
-Then just run `npm test`.
+Run tests with `npm test`.
You can also test with a continuously watching process, via `npm run watch`.
-You can run the linter by itself with `gulp lint`.
+You can run the linter by itself with `npm run lint`.
## Architecture
diff --git a/app/_locales/cs/messages.json b/app/_locales/cs/messages.json
index a28c4cb4a..187ffd95f 100644
--- a/app/_locales/cs/messages.json
+++ b/app/_locales/cs/messages.json
@@ -252,10 +252,6 @@
"depositBTC": {
"message": "Vložte BTC na níže uvedenou adresu:"
},
- "depositCoin": {
- "message": "Vložte $1 na níže uvedenou adresu",
- "description": "Tells the user what coin they have selected to deposit with shapeshift"
- },
"depositEth": {
"message": "Vložit Eth"
},
diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json
index b76f87772..98a8bf972 100644
--- a/app/_locales/de/messages.json
+++ b/app/_locales/de/messages.json
@@ -249,10 +249,6 @@
"depositBTC": {
"message": "Zahle dein BTC in die unten stehende Adresse ein:"
},
- "depositCoin": {
- "message": "Zahle deine $1 in die unten stehende Adresse ein",
- "description": "Teilt dem Benutzer mit welchen Token er beim Einzahlen mit Shapeshift ausgewählt hat"
- },
"depositEth": {
"message": "Eth kaufen"
},
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index 774ae4c85..cc087867a 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -466,10 +466,6 @@
"depositBTC": {
"message": "Deposit your BTC to the address below:"
},
- "depositCoin": {
- "message": "Deposit your $1 to the address below",
- "description": "Tells the user what coin they have selected to deposit with shapeshift"
- },
"depositEth": {
"message": "Deposit Eth"
},
diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json
index 3bdbfa852..06531b1dc 100644
--- a/app/_locales/es/messages.json
+++ b/app/_locales/es/messages.json
@@ -264,10 +264,6 @@
"depositBTC": {
"message": "Deposita tus BTC a la dirección de abajo:"
},
- "depositCoin": {
- "message": "Deposita tu $1 a la dirección de abajo",
- "description": "Informa al usuario que moneda ha elegido para depositar en shapeshift"
- },
"depositEth": {
"message": "Depositar Ether"
},
diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json
index d2ba10009..70effb3ea 100644
--- a/app/_locales/fr/messages.json
+++ b/app/_locales/fr/messages.json
@@ -330,10 +330,6 @@
"depositBTC": {
"message": "Déposez vos BTC à l'adresse ci-dessous:"
},
- "depositCoin": {
- "message": "Déposer votre $1 à l'adresse ci-dessous",
- "description": "Indique à l'utilisateur quelle monnaie il a choisi de déposer avec Shapeshift"
- },
"depositEth": {
"message": "Déposer Eth"
},
diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json
index 6c27ee1bc..54ddcc02b 100644
--- a/app/_locales/hn/messages.json
+++ b/app/_locales/hn/messages.json
@@ -240,10 +240,6 @@
"depositBTC": {
"message": "नीचे दिए गए पते पर अपना बीटीसी जमा करें:"
},
- "depositCoin": {
- "message": "नीचे दिए गए पते पर अपना $1 जमा करें",
- "description": "उपयोगकर्ता को बताता है कि उन्होंने सिक्का के साथ जमा करने के लिए किस सिक्का का चयन किया है"
- },
"depositEth": {
"message": "Eth जमाआर्थ"
},
diff --git a/app/_locales/ht/messages.json b/app/_locales/ht/messages.json
index 4a4c92f3a..720c35889 100644
--- a/app/_locales/ht/messages.json
+++ b/app/_locales/ht/messages.json
@@ -336,10 +336,6 @@
"depositBTC": {
"message": "Depoze BTC ou nan adrès ki anba a:"
},
- "depositCoin": {
- "message": "Depoze $1 ou nan adrès ki anba a",
- "description": "Tells the user what coin they have selected to deposit with shapeshift"
- },
"depositEth": {
"message": "Depo Eth"
},
diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json
index 09ba045b9..c79f22b71 100644
--- a/app/_locales/it/messages.json
+++ b/app/_locales/it/messages.json
@@ -463,10 +463,6 @@
"depositBTC": {
"message": "Deposita i tuoi BTC all'indirizzo sotto:"
},
- "depositCoin": {
- "message": "Deposita $1 all'indirizzo sotto",
- "description": "Dice all'utente quale moneta ha selezionato per depositare con Shapeshift"
- },
"depositEth": {
"message": "Deposita Eth"
},
diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json
index fcac67894..49b033997 100644
--- a/app/_locales/ja/messages.json
+++ b/app/_locales/ja/messages.json
@@ -228,10 +228,6 @@
"depositBTC": {
"message": "BTCを下記のアドレスへ振込んでください:"
},
- "depositCoin": {
- "message": "$1を下記のアドレスへ振込んでください",
- "description": "Tells the user what coin they have selected to deposit with shapeshift"
- },
"depositEth": {
"message": "ETHを入金"
},
diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json
index bf11640e2..541d9dd5c 100644
--- a/app/_locales/ko/messages.json
+++ b/app/_locales/ko/messages.json
@@ -402,10 +402,6 @@
"depositBTC": {
"message": "다음 주소로 BTC를 입금해주세요."
},
- "depositCoin": {
- "message": "다음 주소로 $1 만큼 입금해주세요.",
- "description": "사용자에게 shapeshift에서 어떤 코인을 선택해 입금했는지 알려줍니다"
- },
"depositEth": {
"message": "이더 입금하기"
},
diff --git a/app/_locales/nl/messages.json b/app/_locales/nl/messages.json
index 12bde6585..ade7327de 100644
--- a/app/_locales/nl/messages.json
+++ b/app/_locales/nl/messages.json
@@ -240,10 +240,6 @@
"depositBTC": {
"message": "Stort uw BTC op het onderstaande adres:"
},
- "depositCoin": {
- "message": "Stort uw $1 op het onderstaande adres",
- "description": "Laat de gebruiker weten welk muntje ze hebben geselecteerd om te deponeren met shapeshift"
- },
"depositEth": {
"message": "Aanbetaling Eth"
},
diff --git a/app/_locales/ph/messages.json b/app/_locales/ph/messages.json
index da3cf266d..c8cde27f6 100644
--- a/app/_locales/ph/messages.json
+++ b/app/_locales/ph/messages.json
@@ -201,10 +201,6 @@
"depositBTC": {
"message": "I-deposito ang iyong BTC sa address na ito:"
},
- "depositCoin": {
- "message": "I-deposito ang iyong $1 sa address na ito",
- "description": "Sinasabihan ang user kung ano ang coin na kanilang pinili para I-deposito gamit ang shapeshift"
- },
"depositEth": {
"message": "I-deposito ang Eth"
},
diff --git a/app/_locales/pl/messages.json b/app/_locales/pl/messages.json
index 026f4b3ec..868ab0cae 100644
--- a/app/_locales/pl/messages.json
+++ b/app/_locales/pl/messages.json
@@ -249,10 +249,6 @@
"depositBTC": {
"message": "Zdeponuj swoje BTC na poniższy adres:"
},
- "depositCoin": {
- "message": "Zdeponuj $1 na poniższy adres",
- "description": "Pokazuje użytkownikowi jakie waluty wybrał do zdeponowania w ShapeShift"
- },
"depositEth": {
"message": "Zdeponuj Eth"
},
diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json
index e51b1f72e..5724bce88 100644
--- a/app/_locales/pt/messages.json
+++ b/app/_locales/pt/messages.json
@@ -240,10 +240,6 @@
"depositBTC": {
"message": "Deposite as suas BTC no endereço abaixo:"
},
- "depositCoin": {
- "message": "Deposite $1 no endereço abaixo",
- "description": "Diz ao usuário que moeda selecionou para depositar com shapeshift"
- },
"depositEth": {
"message": "Depositar Eth"
},
diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json
index f80efcc56..e56441186 100644
--- a/app/_locales/ru/messages.json
+++ b/app/_locales/ru/messages.json
@@ -252,10 +252,6 @@
"depositBTC": {
"message": "Отправьте ваш BTC на адрес ниже:"
},
- "depositCoin": {
- "message": "Отправьте ваш $1 на адрес ниже",
- "description": "Tells the user what coin they have selected to deposit with shapeshift"
- },
"depositEth": {
"message": "Пополнить Eth"
},
diff --git a/app/_locales/sk/messages.json b/app/_locales/sk/messages.json
index febcc9141..f98de674b 100644
--- a/app/_locales/sk/messages.json
+++ b/app/_locales/sk/messages.json
@@ -243,10 +243,6 @@
"depositBTC": {
"message": "Vložte BTC na níže uvedenou adresu:"
},
- "depositCoin": {
- "message": "Vložte $1 na níže uvedenou adresu",
- "description": "Tells the user what coin they have selected to deposit with shapeshift"
- },
"depositEth": {
"message": "Vložit Eth"
},
diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json
index 2f3616dee..d04ba1ee7 100644
--- a/app/_locales/sl/messages.json
+++ b/app/_locales/sl/messages.json
@@ -408,10 +408,6 @@
"depositBTC": {
"message": "Vplačajte vaš BTC na spodnji naslov:"
},
- "depositCoin": {
- "message": "Vplačajte vaš $1 na spodnji naslov",
- "description": "Tells the user what coin they have selected to deposit with shapeshift"
- },
"depositEth": {
"message": "Vplačilo ETH"
},
diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json
index d851d325f..a49cf31ad 100644
--- a/app/_locales/th/messages.json
+++ b/app/_locales/th/messages.json
@@ -240,10 +240,6 @@
"depositBTC": {
"message": "ฝากบิตคอยน์ของคุณไปที่แอดเดรสด้านล่างนี้:"
},
- "depositCoin": {
- "message": "ฝาก $1 ของคุณไปที่แอดเดรสด้านล่างนี้:",
- "description": "Tells the user what coin they have selected to deposit with shapeshift"
- },
"depositEth": {
"message": "การฝากอีเธอร์"
},
diff --git a/app/_locales/tml/messages.json b/app/_locales/tml/messages.json
index e1ef45138..2f883b26b 100644
--- a/app/_locales/tml/messages.json
+++ b/app/_locales/tml/messages.json
@@ -252,10 +252,6 @@
"depositBTC": {
"message": "கீழே உங்கள் முகவரிக்கு உங்கள் BTC வைப்போம்:"
},
- "depositCoin": {
- "message": "உங்கள் முகவரிக்கு $ 1 ஐ கீழே உள்ளிடவும்",
- "description": "சேபஷிபிட் உடன் வைப்புக்குத் தேர்ந்தெடுக்கப்பட்ட நாணயத்தை பயனரிடம் கூறுகிறார்"
- },
"depositEth": {
"message": "வைப்புத்தொகை எது "
},
diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json
index bcf96dece..726024764 100644
--- a/app/_locales/tr/messages.json
+++ b/app/_locales/tr/messages.json
@@ -252,10 +252,6 @@
"depositBTC": {
"message": "BTC'inizi aşağıdaki adrese yatırın:"
},
- "depositCoin": {
- "message": "$1'nızı aşağıdaki adrese yatırın",
- "description": "Kullanıcıya hangi jetonu seçtiyse onu yatırmasını shapeshift ile söyler."
- },
"depositEth": {
"message": "Eth yatır"
},
diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json
index 857f78597..aee6474b6 100644
--- a/app/_locales/vi/messages.json
+++ b/app/_locales/vi/messages.json
@@ -201,10 +201,6 @@
"depositBTC": {
"message": "Ký gửi BTC đến địa chỉ sau:"
},
- "depositCoin": {
- "description": "Báo cho người dùng biết đồng tiền nào họ đã chọn để ký gửi với ShapeShift",
- "message": "Ký gửi $1 đến địa chỉ sau:"
- },
"depositEth": {
"message": "Ký gửi Eth"
},
diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json
index 0d3727703..d14b99acb 100644
--- a/app/_locales/zh_CN/messages.json
+++ b/app/_locales/zh_CN/messages.json
@@ -261,10 +261,6 @@
"depositBTC": {
"message": "将你的 BTC 存入到下面的地址:"
},
- "depositCoin": {
- "message": "将你的 $1 存入到下面的地址",
- "description": "Tells the user what coin they have selected to deposit with shapeshift"
- },
"depositEth": {
"message": "存入 Eth"
},
diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json
index 4df95f72f..18e30188e 100644
--- a/app/_locales/zh_TW/messages.json
+++ b/app/_locales/zh_TW/messages.json
@@ -378,10 +378,6 @@
"depositBTC": {
"message": "將您的 BTC 存入到下面的位址:"
},
- "depositCoin": {
- "message": "將您的 $1 存入到下面的位址",
- "description": "Tells the user what coin they have selected to deposit with shapeshift"
- },
"depositEth": {
"message": "存入乙太幣"
},
diff --git a/app/images/spinner.gif b/app/images/spinner.gif
new file mode 100644
index 000000000..8891f9596
--- /dev/null
+++ b/app/images/spinner.gif
Binary files differ
diff --git a/app/manifest.json b/app/manifest.json
index d09407373..8639577bb 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "__MSG_appName__",
"short_name": "__MSG_appName__",
- "version": "6.7.1",
+ "version": "6.7.2",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "__MSG_appDescription__",
diff --git a/app/notification.html b/app/notification.html
index 042ffa6b8..82bf95ada 100644
--- a/app/notification.html
+++ b/app/notification.html
@@ -1,16 +1,39 @@
<!doctype html>
<html style="height:600px;">
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8">
<title>MetaMask Notification</title>
<style>
body {
overflow: hidden;
}
+
+ #app-content {
+ display: flex;
+ flex-flow: column;
+ }
+
+ #loading__logo {
+ width: 10rem;
+ height: 10rem;
+ align-self: center;
+ margin: 10rem 0 0 0;
+ }
+
+ #loading__spinner {
+ width: 2rem;
+ height: 2rem;
+ align-self: center;
+ margin-top: 1rem;
+ }
</style>
</head>
<body class="notification" style="height:600px;">
- <div id="app-content"></div>
+ <div id="app-content">
+ <img id="loading__logo" src="./images/logo/metamask-fox.svg" />
+ <img id="loading__spinner" src="./images/spinner.gif" />
+ </div>
<script src="./libs.js" type="text/javascript" charset="utf-8"></script>
<script src="./ui.js" type="text/javascript" charset="utf-8"></script>
</body>
diff --git a/app/scripts/controllers/network/createLocalhostClient.js b/app/scripts/controllers/network/createLocalhostClient.js
index 09b1d3c1c..3a435e5d0 100644
--- a/app/scripts/controllers/network/createLocalhostClient.js
+++ b/app/scripts/controllers/network/createLocalhostClient.js
@@ -2,9 +2,12 @@ const mergeMiddleware = require('json-rpc-engine/src/mergeMiddleware')
const createFetchMiddleware = require('eth-json-rpc-middleware/fetch')
const createBlockRefRewriteMiddleware = require('eth-json-rpc-middleware/block-ref-rewrite')
const createBlockTrackerInspectorMiddleware = require('eth-json-rpc-middleware/block-tracker-inspector')
+const createAsyncMiddleware = require('json-rpc-engine/src/createAsyncMiddleware')
const providerFromMiddleware = require('eth-json-rpc-middleware/providerFromMiddleware')
const BlockTracker = require('eth-block-tracker')
+const inTest = process.env.IN_TEST === 'true'
+
module.exports = createLocalhostClient
function createLocalhostClient () {
@@ -13,9 +16,24 @@ function createLocalhostClient () {
const blockTracker = new BlockTracker({ provider: blockProvider, pollingInterval: 1000 })
const networkMiddleware = mergeMiddleware([
+ createEstimateGasMiddleware(),
createBlockRefRewriteMiddleware({ blockTracker }),
createBlockTrackerInspectorMiddleware({ blockTracker }),
fetchMiddleware,
])
return { networkMiddleware, blockTracker }
}
+
+function delay (time) {
+ return new Promise(resolve => setTimeout(resolve, time))
+}
+
+
+function createEstimateGasMiddleware () {
+ return createAsyncMiddleware(async (req, _, next) => {
+ if (req.method === 'eth_estimateGas' && inTest) {
+ await delay(2000)
+ }
+ return next()
+ })
+}
diff --git a/app/scripts/controllers/transactions/lib/util.js b/app/scripts/controllers/transactions/lib/util.js
index 84f7592a0..5a8a0cefe 100644
--- a/app/scripts/controllers/transactions/lib/util.js
+++ b/app/scripts/controllers/transactions/lib/util.js
@@ -17,8 +17,8 @@ module.exports = {
// functions that handle normalizing of that key in txParams
const normalizers = {
- from: from => addHexPrefix(from).toLowerCase(),
- to: to => addHexPrefix(to).toLowerCase(),
+ from: (from, LowerCase = true) => LowerCase ? addHexPrefix(from).toLowerCase() : addHexPrefix(from),
+ to: (to, LowerCase = true) => LowerCase ? addHexPrefix(to).toLowerCase() : addHexPrefix(to),
nonce: nonce => addHexPrefix(nonce),
value: value => addHexPrefix(value),
data: data => addHexPrefix(data),
@@ -31,11 +31,11 @@ const normalizers = {
@param txParams {object}
@returns {object} normalized txParams
*/
-function normalizeTxParams (txParams) {
+function normalizeTxParams (txParams, LowerCase) {
// apply only keys in the normalizers
const normalizedTxParams = {}
for (const key in normalizers) {
- if (txParams[key]) normalizedTxParams[key] = normalizers[key](txParams[key])
+ if (txParams[key]) normalizedTxParams[key] = normalizers[key](txParams[key], LowerCase)
}
return normalizedTxParams
}
diff --git a/app/scripts/controllers/transactions/tx-state-manager.js b/app/scripts/controllers/transactions/tx-state-manager.js
index 1a2cb5dee..2aa28c270 100644
--- a/app/scripts/controllers/transactions/tx-state-manager.js
+++ b/app/scripts/controllers/transactions/tx-state-manager.js
@@ -1,11 +1,10 @@
const extend = require('xtend')
const EventEmitter = require('safe-event-emitter')
const ObservableStore = require('obs-store')
-const ethUtil = require('ethereumjs-util')
const log = require('loglevel')
const txStateHistoryHelper = require('./lib/tx-state-history-helper')
const createId = require('../../lib/random-id')
-const { getFinalStates } = require('./lib/util')
+const { getFinalStates, normalizeTxParams } = require('./lib/util')
/**
TransactionStateManager is responsible for the state of a transaction and
storing the transaction
@@ -126,6 +125,11 @@ class TransactionStateManager extends EventEmitter {
@returns {object} the txMeta
*/
addTx (txMeta) {
+ // normalize and validate txParams if present
+ if (txMeta.txParams) {
+ txMeta.txParams = this.normalizeAndValidateTxParams(txMeta.txParams)
+ }
+
this.once(`${txMeta.id}:signed`, function () {
this.removeAllListeners(`${txMeta.id}:rejected`)
})
@@ -175,13 +179,9 @@ class TransactionStateManager extends EventEmitter {
@param [note] {string} - a note about the update for history
*/
updateTx (txMeta, note) {
- // validate txParams
+ // normalize and validate txParams if present
if (txMeta.txParams) {
- if (typeof txMeta.txParams.data === 'undefined') {
- delete txMeta.txParams.data
- }
-
- this.validateTxParams(txMeta.txParams)
+ txMeta.txParams = this.normalizeAndValidateTxParams(txMeta.txParams)
}
// create txMeta snapshot for history
@@ -214,6 +214,19 @@ class TransactionStateManager extends EventEmitter {
}
/**
+ * normalize and validate txParams members
+ * @param txParams {object} - txParams
+ */
+ normalizeAndValidateTxParams (txParams) {
+ if (typeof txParams.data === 'undefined') {
+ delete txParams.data
+ }
+ txParams = normalizeTxParams(txParams, false)
+ this.validateTxParams(txParams)
+ return txParams
+ }
+
+ /**
validates txParams members by type
@param txParams {object} - txParams to validate
*/
@@ -227,7 +240,6 @@ class TransactionStateManager extends EventEmitter {
break
default:
if (typeof value !== 'string') throw new Error(`${key} in txParams is not a string. got: (${value})`)
- if (!ethUtil.isHexPrefixed(value)) throw new Error(`${key} in txParams is not hex prefixed. got: (${value})`)
break
}
})
diff --git a/development/states/send-edit.json b/development/states/send-edit.json
index 7c7e8f097..c83968ae8 100644
--- a/development/states/send-edit.json
+++ b/development/states/send-edit.json
@@ -1,4 +1,9 @@
{
+ "confirmTransaction": {
+ "txData": {
+ "id": 4768706228115573
+ }
+ },
"metamask": {
"completedOnboarding": true,
"isInitialized": true,
@@ -66,7 +71,22 @@
],
"tokens": [],
"transactions": {},
- "selectedAddressTxList": [],
+ "selectedAddressTxList": [{
+ "id": 4768706228115573,
+ "time": 1487363153561,
+ "status": "unapproved",
+ "gasMultiplier": 1,
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "to": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "value": "0x1bc16d674ec80000",
+ "metamaskId": 4768706228115573,
+ "metamaskNetworkId": "3",
+ "gas": "0xea60",
+ "gasPrice": "0xba43b7400"
+ }
+ }],
"unapprovedTxs": {
"4768706228115573": {
"id": 4768706228115573,
diff --git a/docs/publishing.md b/docs/publishing.md
index 392e20955..8d50e6869 100644
--- a/docs/publishing.md
+++ b/docs/publishing.md
@@ -42,3 +42,16 @@ With each pull request, the @MetaMaskBot will comment with a build of that new p
4. Publish to [Opera store](https://addons.opera.com/en/extensions/details/metamask/).
5. Post on [Github releases](https://github.com/MetaMask/metamask-extension/releases) page.
6. Run the `npm run announce` script, and post that announcement in our public places.
+
+## Hotfix Differences
+
+Our `develop` branch is usually not yet fully tested for quality assurance, and so should be treated as if it is in an unstable state.
+
+For this reason, when an urgent change is needed in production, its pull request should:
+
+- Describe it as a hotfix.
+- Use a hotfix tag.
+- Should be proposed against the `master` branch.
+
+The version and changelog bump should then be made off the `master` branch, and then merged to `develop` to bring the two branches back into sync. Further time can be saved by incorporating the version/changelog bump into the PR against `master`, since we rely on @MetaMaskBot to run tests before merging.
+
diff --git a/gulpfile.js b/gulpfile.js
index 35c6331e8..6ea02c52c 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -47,6 +47,7 @@ function gulpParallel (...args) {
const browserPlatforms = [
'firefox',
'chrome',
+ 'brave',
'edge',
'opera',
]
@@ -180,6 +181,7 @@ gulp.task('manifest:production', function () {
return gulp.src([
'./dist/firefox/manifest.json',
'./dist/chrome/manifest.json',
+ './dist/brave/manifest.json',
'./dist/edge/manifest.json',
'./dist/opera/manifest.json',
], {base: './dist/'})
@@ -345,7 +347,7 @@ function createTasksForBuildJsExtension ({ buildJsFiles, taskPrefix, devMode, te
const destinations = browserPlatforms.map(platform => `./dist/${platform}`)
bundleTaskOpts = Object.assign({
buildSourceMaps: true,
- sourceMapDir: devMode ? './' : '../sourcemaps',
+ sourceMapDir: '../sourcemaps',
minifyBuild: !devMode,
buildWithFullPaths: devMode,
watch: devMode,
@@ -602,10 +604,17 @@ function bundleTask (opts) {
}))
}
- // Finalize Source Maps (writes .map file)
+ // Finalize Source Maps
if (opts.buildSourceMaps) {
- buildStream = buildStream
- .pipe(sourcemaps.write(opts.sourceMapDir))
+ if (opts.devMode) {
+ // Use inline source maps for development due to Chrome DevTools bug
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=931675
+ buildStream = buildStream
+ .pipe(sourcemaps.write())
+ } else {
+ buildStream = buildStream
+ .pipe(sourcemaps.write(opts.sourceMapDir))
+ }
}
// write completed bundles
diff --git a/package-lock.json b/package-lock.json
index 73b748f1b..777cf424e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9974,7 +9974,8 @@
"bail": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bail/-/bail-1.0.2.tgz",
- "integrity": "sha1-99bBcxYwqfnw1NNe0fli4gdKF2Q="
+ "integrity": "sha1-99bBcxYwqfnw1NNe0fli4gdKF2Q=",
+ "dev": true
},
"balanced-match": {
"version": "1.0.0",
@@ -11163,17 +11164,20 @@
"character-entities": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.1.tgz",
- "integrity": "sha1-92hxvl72bdt/j440eOzDdMJ9bco="
+ "integrity": "sha1-92hxvl72bdt/j440eOzDdMJ9bco=",
+ "dev": true
},
"character-entities-legacy": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.1.tgz",
- "integrity": "sha1-9Ad53xoQGHK7UQo9KV4fzPFHIC8="
+ "integrity": "sha1-9Ad53xoQGHK7UQo9KV4fzPFHIC8=",
+ "dev": true
},
"character-reference-invalid": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.1.tgz",
- "integrity": "sha1-lCg191Dk7GGjCOYMLvjMEBEgLvw="
+ "integrity": "sha1-lCg191Dk7GGjCOYMLvjMEBEgLvw=",
+ "dev": true
},
"chardet": {
"version": "0.4.2",
@@ -12043,11 +12047,6 @@
}
}
},
- "collapse-white-space": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.3.tgz",
- "integrity": "sha1-S5BvZw5aljqHt2sOFolkM0G2Ajw="
- },
"collection-map": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
@@ -13166,7 +13165,8 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
"integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"cyclist": {
"version": "0.2.2",
@@ -14731,6 +14731,7 @@
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz",
"integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==",
+ "dev": true,
"requires": {
"end-of-stream": "^1.0.0",
"inherits": "^2.0.1",
@@ -14989,14 +14990,6 @@
"tapable": "^1.0.0"
}
},
- "ensnare": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/ensnare/-/ensnare-1.0.0.tgz",
- "integrity": "sha1-ctK/fvSKuiH2at8p0AoJBO3bYcc=",
- "requires": {
- "tape": "^4.6.0"
- }
- },
"ensure-posix-path": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.0.2.tgz",
@@ -15816,15 +15809,6 @@
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
"dev": true
},
- "eth-bin-to-ops": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/eth-bin-to-ops/-/eth-bin-to-ops-1.0.1.tgz",
- "integrity": "sha1-TScDuYeIJbw4xiWZEOkLTbAFx94=",
- "requires": {
- "ethereumjs-vm": "^2.0.0",
- "tape": "^4.6.2"
- }
- },
"eth-block-tracker": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-4.1.0.tgz",
@@ -18401,14 +18385,6 @@
"is-extendable": "^0.1.0"
}
},
- "extension-link-enabler": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/extension-link-enabler/-/extension-link-enabler-1.0.0.tgz",
- "integrity": "sha1-V7kZru7fOL6XJwuYmM7nimN+RvM=",
- "requires": {
- "extensionizer": "^1.0.0"
- }
- },
"extension-port-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/extension-port-stream/-/extension-port-stream-1.0.0.tgz",
@@ -18521,7 +18497,8 @@
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
"integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"fake-merkle-patricia-tree": {
"version": "1.0.1",
@@ -22801,6 +22778,7 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "dev": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
@@ -22822,6 +22800,7 @@
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
"integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
+ "dev": true,
"requires": {
"safe-buffer": "^5.0.1"
}
@@ -24060,6 +24039,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz",
"integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
+ "dev": true,
"requires": {
"browserify-aes": "^1.0.6",
"create-hash": "^1.1.2",
@@ -24775,6 +24755,7 @@
"ethereumjs-abi": {
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
+ "dev": true,
"requires": {
"bn.js": "^4.10.0",
"ethereumjs-util": "^5.0.0"
@@ -24969,6 +24950,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
"integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
+ "dev": true,
"requires": {
"bn.js": "^4.11.0",
"create-hash": "^1.1.2",
@@ -25226,6 +25208,7 @@
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
"integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+ "dev": true,
"requires": {
"is-hex-prefixed": "1.0.0",
"strip-hex-prefix": "1.0.0"
@@ -25559,7 +25542,8 @@
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "dev": true
},
"filesize": {
"version": "3.6.1",
@@ -27048,7 +27032,8 @@
"is-hex-prefixed": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz",
- "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ="
+ "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
+ "dev": true
},
"is-natural-number": {
"version": "4.0.1",
@@ -27374,6 +27359,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz",
"integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
+ "dev": true,
"requires": {
"bindings": "^1.2.1",
"inherits": "^2.0.3",
@@ -30474,6 +30460,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/rlp/-/rlp-2.1.0.tgz",
"integrity": "sha512-93U7IKH5j7nmXFVg19MeNBGzQW5uXW1pmCuKY8veeKIhYTE32C2d0mOegfiIAfXcHOKJjjPlJisn8iHDF5AezA==",
+ "dev": true,
"requires": {
"safe-buffer": "^5.1.1"
}
@@ -30589,6 +30576,7 @@
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.6.2.tgz",
"integrity": "sha512-90nYt7yb0LmI4A2jJs1grglkTAXrBwxYAjP9bpeKjvJKOjG2fOeH/YI/lchDMIvjrOasd5QXwvV2jwN168xNng==",
+ "dev": true,
"requires": {
"bindings": "^1.2.1",
"bip66": "^1.1.3",
@@ -30752,15 +30740,6 @@
"safe-buffer": "^5.0.1"
}
},
- "sha3": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz",
- "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=",
- "dev": true,
- "requires": {
- "nan": "2.10.0"
- }
- },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -31254,6 +31233,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
"integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+ "dev": true,
"requires": {
"is-hex-prefixed": "1.0.0"
}
@@ -31637,6 +31617,7 @@
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
"integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
"requires": {
"is-typedarray": "^1.0.0"
}
@@ -32252,6 +32233,7 @@
"ethereumjs-abi": {
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
+ "dev": true,
"requires": {
"bn.js": "^4.10.0",
"ethereumjs-util": "^5.0.0"
@@ -32331,6 +32313,7 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
"requires": {
"ms": "2.0.0"
}
@@ -32338,6 +32321,7 @@
"websocket": {
"version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2",
"from": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2",
+ "dev": true,
"requires": {
"debug": "^2.2.0",
"nan": "^2.3.3",
@@ -32790,7 +32774,8 @@
"yaeti": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
- "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc="
+ "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=",
+ "dev": true
},
"yallist": {
"version": "2.1.2",
@@ -35804,11 +35789,6 @@
"space-separated-tokens": "^1.0.0"
}
},
- "hat": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz",
- "integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo="
- },
"hdkey": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz",
@@ -36186,12 +36166,6 @@
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz",
"integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es="
},
- "i": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz",
- "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=",
- "dev": true
- },
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
@@ -36277,11 +36251,6 @@
}
}
},
- "identicon.js": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/identicon.js/-/identicon.js-2.3.1.tgz",
- "integrity": "sha512-PsxOTpq2Mwj2dgpHW50vcBdSebozcL9xKLIqRVkh2c4lqbCB75pkpdDKoKkVtTfpha/rl4BubXm3Q90vxlmUxQ=="
- },
"idna-uts46": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/idna-uts46/-/idna-uts46-1.1.0.tgz",
@@ -36724,12 +36693,14 @@
"is-alphabetical": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.1.tgz",
- "integrity": "sha1-x3B5zJHU76x3W+EDS/LSQ/lebwg="
+ "integrity": "sha1-x3B5zJHU76x3W+EDS/LSQ/lebwg=",
+ "dev": true
},
"is-alphanumerical": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.1.tgz",
"integrity": "sha1-37SqTRCF4zvbYcLe6cgOnGwZ9Ts=",
+ "dev": true,
"requires": {
"is-alphabetical": "^1.0.0",
"is-decimal": "^1.0.0"
@@ -36758,7 +36729,8 @@
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
},
"is-builtin-module": {
"version": "1.0.0",
@@ -36807,7 +36779,8 @@
"is-decimal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.1.tgz",
- "integrity": "sha1-9ftqlJlq2ejjdh+/vQkfH8qMToI="
+ "integrity": "sha1-9ftqlJlq2ejjdh+/vQkfH8qMToI=",
+ "dev": true
},
"is-descriptor": {
"version": "1.0.2",
@@ -36909,7 +36882,8 @@
"is-hexadecimal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz",
- "integrity": "sha1-bghLvJIGH7sJcexYts5tQE4k2mk="
+ "integrity": "sha1-bghLvJIGH7sJcexYts5tQE4k2mk=",
+ "dev": true
},
"is-in-browser": {
"version": "1.1.3",
@@ -37034,7 +37008,8 @@
"is-plain-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
- "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+ "dev": true
},
"is-plain-object": {
"version": "2.0.4",
@@ -37193,22 +37168,12 @@
"integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=",
"dev": true
},
- "is-whitespace-character": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.1.tgz",
- "integrity": "sha1-muAXbzKCtlRXoZks2whPil+DPjs="
- },
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
"dev": true
},
- "is-word-character": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.1.tgz",
- "integrity": "sha1-WgP6HqkazopusMfNdw64bWXIvvs="
- },
"is-wsl": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
@@ -37785,20 +37750,6 @@
}
}
},
- "jshint-stylish": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/jshint-stylish/-/jshint-stylish-2.2.1.tgz",
- "integrity": "sha1-JCCCosA1rgP9gQROBXDMQgjPbmE=",
- "dev": true,
- "requires": {
- "beeper": "^1.1.0",
- "chalk": "^1.0.0",
- "log-symbols": "^1.0.0",
- "plur": "^2.1.0",
- "string-length": "^1.0.0",
- "text-table": "^0.2.0"
- }
- },
"json-merge-patch": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-merge-patch/-/json-merge-patch-0.2.3.tgz",
@@ -39020,7 +38971,8 @@
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
- "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
+ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+ "dev": true
},
"lodash.restparam": {
"version": "3.6.1",
@@ -39093,7 +39045,8 @@
"lodash.uniqby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz",
- "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI="
+ "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=",
+ "dev": true
},
"log-driver": {
"version": "1.2.5",
@@ -39329,11 +39282,6 @@
"object-visit": "^1.0.0"
}
},
- "markdown-escapes": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.1.tgz",
- "integrity": "sha1-GZTfLTr0gR3lmmcUk0wrIpJzRRg="
- },
"markdown-it": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
@@ -40591,18 +40539,6 @@
"duplexer2": "0.0.2"
}
},
- "multiplex": {
- "version": "6.7.0",
- "resolved": "https://registry.npmjs.org/multiplex/-/multiplex-6.7.0.tgz",
- "integrity": "sha1-/3Pk5AB5FwxEQtFgllZY+N75YMI=",
- "requires": {
- "duplexify": "^3.4.2",
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.2",
- "varint": "^4.0.0",
- "xtend": "^4.0.0"
- }
- },
"mustache": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz",
@@ -40779,12 +40715,6 @@
}
}
},
- "ncp": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz",
- "integrity": "sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=",
- "dev": true
- },
"nearley": {
"version": "2.15.1",
"resolved": "https://registry.npmjs.org/nearley/-/nearley-2.15.1.tgz",
@@ -43223,19 +43153,6 @@
"pbkdf2": "^3.0.3"
}
},
- "parse-entities": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.1.tgz",
- "integrity": "sha1-gRLYhHExnyerrk1klksSL+ThuJA=",
- "requires": {
- "character-entities": "^1.0.0",
- "character-entities-legacy": "^1.0.0",
- "character-reference-invalid": "^1.0.0",
- "is-alphanumerical": "^1.0.0",
- "is-decimal": "^1.0.0",
- "is-hexadecimal": "^1.0.0"
- }
- },
"parse-filepath": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
@@ -43703,12 +43620,6 @@
}
}
},
- "pkginfo": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz",
- "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=",
- "dev": true
- },
"plucker": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/plucker/-/plucker-0.0.0.tgz",
@@ -43906,11 +43817,6 @@
}
}
},
- "pojo-migrator": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/pojo-migrator/-/pojo-migrator-2.1.0.tgz",
- "integrity": "sha1-PCo7n4C6Wp+367kh0zRNtO+l9mk="
- },
"polished": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/polished/-/polished-3.4.0.tgz",
@@ -45051,28 +44957,6 @@
"function-bind": "^1.1.1"
}
},
- "prompt": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/prompt/-/prompt-1.0.0.tgz",
- "integrity": "sha1-jlcSPDlquYiJf7Mn/Trtw+c15P4=",
- "dev": true,
- "requires": {
- "colors": "^1.1.2",
- "pkginfo": "0.x.x",
- "read": "1.0.x",
- "revalidator": "0.1.x",
- "utile": "0.3.x",
- "winston": "2.1.x"
- },
- "dependencies": {
- "colors": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
- "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
- "dev": true
- }
- }
- },
"prop-types": {
"version": "15.6.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
@@ -45248,6 +45132,7 @@
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.3.5.tgz",
"integrity": "sha1-G2ccYZlAq8rqwK0OOjwWS+dgmTs=",
+ "dev": true,
"requires": {
"duplexify": "^3.1.2",
"inherits": "^2.0.1",
@@ -45258,6 +45143,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
+ "dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@@ -45714,12 +45600,6 @@
}
}
},
- "react-addons-test-utils": {
- "version": "15.6.2",
- "resolved": "https://registry.npmjs.org/react-addons-test-utils/-/react-addons-test-utils-15.6.2.tgz",
- "integrity": "sha1-wStu/cIkfBDae4dw0YUICnsEcVY=",
- "dev": true
- },
"react-clientside-effect": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.0.tgz",
@@ -46524,18 +46404,6 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.2.tgz",
"integrity": "sha512-pbZOSMVVkvppW7XRn9fcHK5OgEDnYLwMva7P6TgS44/SN9uGGjfh3Z1c8tomO+y4IsHQ6Fsz2EGwmE7sMeNZgQ=="
},
- "react-markdown": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-3.1.4.tgz",
- "integrity": "sha512-i8WueytRXbYzyJ2GemIOTMRx/NigPo8r4m3R/KvWD7r+PxPyc9ke66cI3DR7MBRSS+nVG82VWEgRDE1VaZUCqA==",
- "requires": {
- "prop-types": "^15.6.0",
- "remark-parse": "^4.0.0",
- "unified": "^6.1.5",
- "unist-util-visit": "^1.1.3",
- "xtend": "^4.0.1"
- }
- },
"react-media": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/react-media/-/react-media-1.8.0.tgz",
@@ -46805,24 +46673,6 @@
"object-assign": "^4.1.0"
}
},
- "react-testutils-additions": {
- "version": "15.3.0",
- "resolved": "https://registry.npmjs.org/react-testutils-additions/-/react-testutils-additions-15.3.0.tgz",
- "integrity": "sha1-DulqWZj1TivaLPCjQwo0XfBLf2Q=",
- "dev": true,
- "requires": {
- "object-assign": "3.0.0",
- "sizzle": "2.3.3"
- },
- "dependencies": {
- "object-assign": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
- "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=",
- "dev": true
- }
- }
- },
"react-textarea-autosize": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-5.2.1.tgz",
@@ -46899,15 +46749,6 @@
"through": "~2.3.4"
}
},
- "read": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
- "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
- "dev": true,
- "requires": {
- "mute-stream": "~0.0.4"
- }
- },
"read-all-stream": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
@@ -47331,28 +47172,6 @@
}
}
},
- "remark-parse": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz",
- "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==",
- "requires": {
- "collapse-white-space": "^1.0.2",
- "is-alphabetical": "^1.0.0",
- "is-decimal": "^1.0.0",
- "is-whitespace-character": "^1.0.0",
- "is-word-character": "^1.0.0",
- "markdown-escapes": "^1.0.0",
- "parse-entities": "^1.0.2",
- "repeat-string": "^1.5.4",
- "state-toggle": "^1.0.0",
- "trim": "0.0.1",
- "trim-trailing-lines": "^1.0.0",
- "unherit": "^1.0.4",
- "unist-util-remove-position": "^1.0.0",
- "vfile-location": "^2.0.0",
- "xtend": "^4.0.1"
- }
- },
"remove-bom-buffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
@@ -47402,7 +47221,8 @@
"repeat-string": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
},
"repeating": {
"version": "2.0.1",
@@ -47415,7 +47235,8 @@
"replace-ext": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
- "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs="
+ "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+ "dev": true
},
"replace-homedir": {
"version": "1.0.0",
@@ -47686,12 +47507,6 @@
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
"dev": true
},
- "revalidator": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz",
- "integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=",
- "dev": true
- },
"rework": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz",
@@ -47861,49 +47676,6 @@
"integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==",
"dev": true
},
- "sandwich-expando": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/sandwich-expando/-/sandwich-expando-1.1.3.tgz",
- "integrity": "sha1-a6eNA0wy+L9atZNMIU+DhGFKiKU=",
- "requires": {
- "babel-preset-es2015": "^6.6.0",
- "babelify": "^7.3.0",
- "react": "^15.0.2",
- "react-dom": "^15.0.2",
- "react-hyperscript": "^2.4.0"
- },
- "dependencies": {
- "babelify": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
- "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
- "requires": {
- "babel-core": "^6.0.14",
- "object-assign": "^4.0.0"
- }
- },
- "react": {
- "version": "15.6.2",
- "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz",
- "integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=",
- "requires": {
- "create-react-class": "^15.6.0",
- "fbjs": "^0.8.9",
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.0",
- "prop-types": "^15.5.10"
- }
- },
- "react-hyperscript": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/react-hyperscript/-/react-hyperscript-2.4.2.tgz",
- "integrity": "sha1-wZsfWhYcot8QvM5t0imehUepgv4=",
- "requires": {
- "react": ">= 0.12.0 < 16.0.0"
- }
- }
- }
- },
"sass-graph": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
@@ -48338,11 +48110,18 @@
}
},
"sha3": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.0.tgz",
- "integrity": "sha1-aYnxtwpJhwWHajc+LGKs6WqpOZo=",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.3.tgz",
+ "integrity": "sha512-sOWDZi8cDBRkLfWOw18wvJyNblXDHzwMGnRWut8zNNeIeLnmMRO17bjpLc7OzMuj1ASUgx2IyohzUCAl+Kx5vA==",
"requires": {
- "nan": "^2.0.5"
+ "nan": "2.13.2"
+ },
+ "dependencies": {
+ "nan": {
+ "version": "2.13.2",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz",
+ "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw=="
+ }
}
},
"shallow-clone": {
@@ -48367,7 +48146,8 @@
"shallow-copy": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz",
- "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA="
+ "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=",
+ "dev": true
},
"shallow-equal": {
"version": "1.1.0",
@@ -48655,12 +48435,6 @@
}
}
},
- "sizzle": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/sizzle/-/sizzle-2.3.3.tgz",
- "integrity": "sha1-TrB4w3IxpWtS5Bk/cB5++JN+YGs=",
- "dev": true
- },
"slash": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
@@ -50136,11 +49910,6 @@
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
"dev": true
},
- "state-toggle": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.0.tgz",
- "integrity": "sha1-0g+aYWu08MO5i5GSLSW2QKorxCU="
- },
"static-eval": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz",
@@ -50454,7 +50223,8 @@
"stream-shift": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
- "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI="
+ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+ "dev": true
},
"streamroller": {
"version": "1.0.5",
@@ -50526,15 +50296,6 @@
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
"integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c="
},
- "string-length": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
- "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=",
- "dev": true,
- "requires": {
- "strip-ansi": "^3.0.0"
- }
- },
"string-template": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
@@ -52417,15 +52178,11 @@
"resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM="
},
- "trim-trailing-lines": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.0.tgz",
- "integrity": "sha1-eu+7eAjfnWafbaLkOMrIxGradoQ="
- },
"trough": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/trough/-/trough-1.0.1.tgz",
- "integrity": "sha1-qf2LA5Swro//guBjOgo2zK1bX4Y="
+ "integrity": "sha1-qf2LA5Swro//guBjOgo2zK1bX4Y=",
+ "dev": true
},
"true-case-path": {
"version": "1.0.2",
@@ -52621,15 +52378,6 @@
"integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=",
"dev": true
},
- "unherit": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.0.tgz",
- "integrity": "sha1-a5qu379z3xdWrZ4xbdmBiFhAzX0=",
- "requires": {
- "inherits": "^2.0.1",
- "xtend": "^4.0.1"
- }
- },
"unicode-5.2.0": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/unicode-5.2.0/-/unicode-5.2.0-0.7.5.tgz",
@@ -52664,20 +52412,6 @@
"integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==",
"dev": true
},
- "unified": {
- "version": "6.1.6",
- "resolved": "https://registry.npmjs.org/unified/-/unified-6.1.6.tgz",
- "integrity": "sha512-pW2f82bCIo2ifuIGYcV12fL96kMMYgw7JKVEgh7ODlrM9rj6vXSY3BV+H6lCcv1ksxynFf582hwWLnA1qRFy4w==",
- "requires": {
- "bail": "^1.0.0",
- "extend": "^3.0.0",
- "is-plain-obj": "^1.1.0",
- "trough": "^1.0.0",
- "vfile": "^2.0.0",
- "x-is-function": "^1.0.4",
- "x-is-string": "^0.1.0"
- }
- },
"union": {
"version": "0.4.6",
"resolved": "https://registry.npmjs.org/union/-/union-0.4.6.tgz",
@@ -52763,31 +52497,11 @@
"crypto-random-string": "^1.0.0"
}
},
- "unist-util-is": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.1.tgz",
- "integrity": "sha1-DDEmKeP5YMZukx6BLT2A53AQlHs="
- },
- "unist-util-remove-position": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.1.tgz",
- "integrity": "sha1-WoXBVV/BugwQG4ZwfRXlD6TIcbs=",
- "requires": {
- "unist-util-visit": "^1.1.0"
- }
- },
"unist-util-stringify-position": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz",
- "integrity": "sha1-PMvcU2ee7W7PN3fdf14yKcG2qjw="
- },
- "unist-util-visit": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.3.0.tgz",
- "integrity": "sha512-9ntYcxPFtl44gnwXrQKZ5bMqXMY0ZHzUpqMFiU4zcc8mmf/jzYm8GhYgezuUlX4cJIM1zIDYaO6fG/fI+L6iiQ==",
- "requires": {
- "unist-util-is": "^2.1.1"
- }
+ "integrity": "sha1-PMvcU2ee7W7PN3fdf14yKcG2qjw=",
+ "dev": true
},
"universalify": {
"version": "0.1.1",
@@ -53131,34 +52845,6 @@
"integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=",
"dev": true
},
- "utile": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/utile/-/utile-0.3.0.tgz",
- "integrity": "sha1-E1LDQOuCDk2N26A5pPv6oy7U7zo=",
- "dev": true,
- "requires": {
- "async": "~0.9.0",
- "deep-equal": "~0.2.1",
- "i": "0.3.x",
- "mkdirp": "0.x.x",
- "ncp": "1.0.x",
- "rimraf": "2.x.x"
- },
- "dependencies": {
- "async": {
- "version": "0.9.2",
- "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
- "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
- "dev": true
- },
- "deep-equal": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz",
- "integrity": "sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0=",
- "dev": true
- }
- }
- },
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -53204,11 +52890,6 @@
"integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=",
"dev": true
},
- "varint": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/varint/-/varint-4.0.1.tgz",
- "integrity": "sha1-SQgpuULSSEY7KzUJeZXDv3NxmOk="
- },
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -53225,26 +52906,11 @@
"extsprintf": "^1.2.0"
}
},
- "vfile": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz",
- "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==",
- "requires": {
- "is-buffer": "^1.1.4",
- "replace-ext": "1.0.0",
- "unist-util-stringify-position": "^1.0.0",
- "vfile-message": "^1.0.0"
- }
- },
- "vfile-location": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.2.tgz",
- "integrity": "sha1-02dcWch3SY5JK0dW/2Xkrxp1IlU="
- },
"vfile-message": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.0.0.tgz",
"integrity": "sha512-HPREhzTOB/sNDc9/Mxf8w0FmHnThg5CRSJdR9VRFkD2riqYWs+fuXlj5z8mIpv2LrD7uU41+oPWFOL4Mjlf+dw==",
+ "dev": true,
"requires": {
"unist-util-stringify-position": "^1.1.1"
}
@@ -54684,41 +54350,6 @@
"execa": "^1.0.0"
}
},
- "winston": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/winston/-/winston-2.1.1.tgz",
- "integrity": "sha1-PJNJ0ZYgf9G9/51LxD73JRDjoS4=",
- "dev": true,
- "requires": {
- "async": "~1.0.0",
- "colors": "1.0.x",
- "cycle": "1.0.x",
- "eyes": "0.1.x",
- "isstream": "0.1.x",
- "pkginfo": "0.3.x",
- "stack-trace": "0.0.x"
- },
- "dependencies": {
- "async": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz",
- "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=",
- "dev": true
- },
- "colors": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
- "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
- "dev": true
- },
- "pkginfo": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz",
- "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=",
- "dev": true
- }
- }
- },
"wordwrap": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
@@ -54804,15 +54435,11 @@
"ultron": "~1.1.0"
}
},
- "x-is-function": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/x-is-function/-/x-is-function-1.0.4.tgz",
- "integrity": "sha1-XSlNw9Joy90GJYDgxd93o5HR+h4="
- },
"x-is-string": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz",
- "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI="
+ "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=",
+ "dev": true
},
"xdg-basedir": {
"version": "3.0.0",
diff --git a/package.json b/package.json
index c9c3bd633..af4c83af5 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,7 @@
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"mozilla-lint": "addons-linter dist/firefox",
- "watch": "mocha watch --recursive \"test/unit/**/*.js\"",
+ "watch": "cross-env METAMASK_ENV=test mocha --watch --require test/setup.js --reporter min --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\"",
"disc": "gulp disc --debug",
"announce": "node development/announcer.js",
"version:bump": "node development/run-version-bump.js",
@@ -48,7 +48,6 @@
"browserify": {
"transform": [
"babelify",
- "reactify",
"brfs"
]
},
@@ -84,12 +83,9 @@
"disc": "^1.3.2",
"dnode": "^1.2.2",
"end-of-stream": "^1.1.0",
- "ensnare": "^1.0.0",
- "eth-bin-to-ops": "^1.0.1",
"eth-block-tracker": "^4.1.0",
"eth-contract-metadata": "github:MetaMask/eth-contract-metadata#dc68506221859bc90792bc5e0279a6835f2484d8",
"eth-ens-namehash": "^2.0.8",
- "eth-hd-keyring": "^1.2.2",
"eth-json-rpc-filters": "^3.0.4",
"eth-json-rpc-infura": "^3.2.0",
"eth-keyring-controller": "^3.3.1",
@@ -109,39 +105,31 @@
"ethjs-contract": "^0.2.3",
"ethjs-ens": "^2.0.0",
"ethjs-query": "^0.3.4",
- "extension-link-enabler": "^1.0.0",
"extension-port-stream": "^1.0.0",
"extensionizer": "^1.0.1",
"fast-json-patch": "^2.0.4",
- "fast-levenshtein": "^2.0.6",
"fuse.js": "^3.2.0",
"gaba": "^1.3.0",
- "hat": "0.0.3",
"human-standard-token-abi": "^2.0.0",
- "identicon.js": "^2.3.1",
"inject-css": "^0.1.1",
"jazzicon": "^1.2.0",
"json-rpc-engine": "^4.0.0",
"json-rpc-middleware-stream": "^2.1.1",
"jsonschema": "^1.2.4",
"lodash.debounce": "^4.0.8",
- "lodash.memoize": "^4.1.2",
"lodash.shuffle": "^4.2.0",
- "lodash.uniqby": "^4.7.0",
"loglevel": "^1.4.1",
"luxon": "^1.8.2",
"metamask-inpage-provider": "^1.3.0",
"metamask-logo": "^2.1.4",
"mkdirp": "^0.5.1",
"multihashes": "^0.4.12",
- "multiplex": "^6.7.0",
"nonce-tracker": "^1.0.0",
"number-to-bn": "^1.7.0",
"obj-multiplex": "^1.0.0",
"obs-store": "^3.0.2",
"percentile": "^1.2.0",
"pify": "^3.0.0",
- "pojo-migrator": "^2.1.0",
"polyfill-crypto.getrandomvalues": "^1.0.0",
"post-message-stream": "^3.0.0",
"promise-filter": "^1.1.0",
@@ -149,7 +137,6 @@
"prop-types": "^15.6.1",
"pubnub": "^4.21.5",
"pump": "^3.0.0",
- "pumpify": "^1.3.4",
"qrcode-generator": "1.4.1",
"ramda": "^0.24.1",
"react": "^15.6.2",
@@ -160,7 +147,6 @@
"react-hyperscript": "^3.0.0",
"react-idle-timer": "^4.2.5",
"react-inspector": "^2.3.0",
- "react-markdown": "^3.0.0",
"react-media": "^1.8.0",
"react-redux": "^5.0.5",
"react-router-dom": "^4.2.2",
@@ -180,10 +166,6 @@
"request-promise": "^4.2.1",
"reselect": "^3.0.1",
"safe-event-emitter": "^1.0.1",
- "sandwich-expando": "^1.1.3",
- "semaphore": "^1.0.5",
- "semver": "^5.4.1",
- "shallow-copy": "0.0.1",
"single-call-balance-checker-abi": "^1.0.0",
"swappable-obj-proxy": "^1.1.0",
"textarea-caret": "^3.0.1",
@@ -198,9 +180,9 @@
"@storybook/addon-info": "^5.1.1",
"@storybook/addon-knobs": "^3.4.2",
"@storybook/react": "^5.1.1",
+ "abortcontroller-polyfill": "^1.3.0",
"addons-linter": "^1.10.0",
"babel-core": "^6.26.3",
- "abortcontroller-polyfill": "^1.3.0",
"babel-eslint": "^8.0.0",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
@@ -261,7 +243,6 @@
"jsdoc": "^3.6.2",
"jsdom": "^11.2.0",
"jsdom-global": "^3.0.2",
- "jshint-stylish": "~2.2.1",
"karma": "^4.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-cli": "^1.0.1",
@@ -278,14 +259,11 @@
"path": "^0.12.7",
"png-file-stream": "^1.1.0",
"prepend-file": "^1.3.1",
- "prompt": "^1.0.0",
"proxyquire": "2.0.1",
"qs": "^6.2.0",
"qunitjs": "^2.4.1",
"radgrad-jsdoc-template": "^1.1.3",
- "react-addons-test-utils": "^15.5.1",
"react-test-renderer": "^15.6.2",
- "react-testutils-additions": "^15.2.0",
"redux-mock-store": "^1.5.3",
"redux-test-utils": "^0.2.2",
"resolve-url-loader": "^2.3.0",
diff --git a/test/e2e/beta/metamask-beta-ui.spec.js b/test/e2e/beta/metamask-beta-ui.spec.js
index 7aa386637..b0ec25cd9 100644
--- a/test/e2e/beta/metamask-beta-ui.spec.js
+++ b/test/e2e/beta/metamask-beta-ui.spec.js
@@ -340,7 +340,7 @@ describe('MetaMask', function () {
it('confirms the transaction', async function () {
const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`))
await confirmButton.click()
- await delay(largeDelayMs)
+ await delay(largeDelayMs * 2)
})
it('finds the transaction in the transactions list', async function () {
@@ -428,6 +428,10 @@ describe('MetaMask', function () {
})
it('confirms the transaction', async function () {
+ const transactionAmounts = await findElements(driver, By.css('.currency-display-component__text'))
+ const transactionAmount = transactionAmounts[0]
+ assert.equal(await transactionAmount.getText(), '1')
+
const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`))
await confirmButton.click()
await delay(largeDelayMs)
@@ -528,7 +532,7 @@ describe('MetaMask', function () {
await delay(50)
await gasLimitInput.sendKeys('25000')
- await delay(tinyDelayMs)
+ await delay(largeDelayMs * 2)
const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`), 10000)
await confirmButton.click()
@@ -685,11 +689,13 @@ describe('MetaMask', function () {
})
it('confirms a transaction', async () => {
+ await delay(tinyDelayMs)
const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`), 10000)
await confirmButton.click()
- await delay(regularDelayMs)
+ await delay(largeDelayMs * 2)
const navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation'))
+ await delay(tinyDelayMs)
const navigationText = await navigationElement.getText()
assert.equal(navigationText.includes('4'), true, 'transaction confirmed')
})
@@ -792,7 +798,7 @@ describe('MetaMask', function () {
await driver.wait(until.elementTextMatches(contractStatus, /Deposit\sinitiated/), 10000)
await driver.switchTo().window(extension)
- await delay(largeDelayMs)
+ await delay(largeDelayMs * 2)
await findElements(driver, By.css('.transaction-list-item'))
const [txListValue] = await findElements(driver, By.css('.transaction-list-item__amount--primary'))
@@ -812,6 +818,8 @@ describe('MetaMask', function () {
await delay(regularDelayMs)
const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-tab__gas-edit-row__input'))
+ const gasLimitValue = await gasLimitInput.getAttribute('value')
+ assert(Number(gasLimitValue) < 100000, 'Gas Limit too high')
await gasPriceInput.sendKeys(Key.chord(Key.CONTROL, 'a'))
await delay(50)
@@ -870,7 +878,7 @@ describe('MetaMask', function () {
await delay(regularDelayMs)
await driver.switchTo().window(extension)
- await delay(regularDelayMs)
+ await delay(largeDelayMs * 2)
const txListItem = await findElement(driver, By.css('.transaction-list-item'))
await txListItem.click()
@@ -1102,6 +1110,10 @@ describe('MetaMask', function () {
await txListValue.click()
await delay(regularDelayMs)
+ const transactionAmounts = await findElements(driver, By.css('.currency-display-component__text'))
+ const transactionAmount = transactionAmounts[0]
+ assert(await transactionAmount.getText(), '1.5 TST')
+
// Set the gas limit
const configureGas = await driver.wait(until.elementLocated(By.css('.confirm-detail-row__header-text--edit')), 10000)
await configureGas.click()
@@ -1340,10 +1352,10 @@ describe('MetaMask', function () {
})
it('submits the transaction', async function () {
- await delay(regularDelayMs)
+ await delay(largeDelayMs * 2)
const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`))
await confirmButton.click()
- await delay(regularDelayMs)
+ await delay(largeDelayMs * 2)
})
it('finds the transaction in the transactions list', async function () {
diff --git a/test/unit/app/controllers/transactions/tx-state-manager-test.js b/test/unit/app/controllers/transactions/tx-state-manager-test.js
index 4ccade2aa..72dbbc4a1 100644
--- a/test/unit/app/controllers/transactions/tx-state-manager-test.js
+++ b/test/unit/app/controllers/transactions/tx-state-manager-test.js
@@ -93,6 +93,37 @@ describe('TransactionStateManager', function () {
assert.equal(result[0].id, 1)
})
+ it('throws error and does not add tx if txParams are invalid', function () {
+ const validTxParams = {
+ from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
+ to: '0x0039f22efb07a647557c7c5d17854cfd6d489ef3',
+ nonce: '0x3',
+ gas: '0x77359400',
+ gasPrice: '0x77359400',
+ value: '0x0',
+ data: '0x0',
+ }
+ const invalidValues = [1, true, {}, Symbol('1')]
+
+ for (const key in validTxParams) {
+ for (const value of invalidValues) {
+ const tx = {
+ id: 1,
+ status: 'unapproved',
+ metamaskNetworkId: currentNetworkId,
+ txParams: {
+ ...validTxParams,
+ [key]: value,
+ },
+ }
+ assert.throws(txStateManager.addTx.bind(txStateManager, tx), 'addTx should throw error')
+ const result = txStateManager.getTxList()
+ assert.ok(Array.isArray(result), 'txList should be an array')
+ assert.equal(result.length, 0, 'txList should be empty')
+ }
+ }
+ })
+
it('does not override txs from other networks', function () {
const tx = { id: 1, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }
const tx2 = { id: 2, status: 'confirmed', metamaskNetworkId: otherNetworkId, txParams: {} }
@@ -153,6 +184,37 @@ describe('TransactionStateManager', function () {
assert.equal(result.hash, 'foo')
})
+ it('throws error and does not update tx if txParams are invalid', function () {
+ const validTxParams = {
+ from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
+ to: '0x0039f22efb07a647557c7c5d17854cfd6d489ef3',
+ nonce: '0x3',
+ gas: '0x77359400',
+ gasPrice: '0x77359400',
+ value: '0x0',
+ data: '0x0',
+ }
+ const invalidValues = [1, true, {}, Symbol('1')]
+
+ txStateManager.addTx({ id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: validTxParams })
+
+ for (const key in validTxParams) {
+ for (const value of invalidValues) {
+ const originalTx = txStateManager.getTx(1)
+ const newTx = {
+ ...originalTx,
+ txParams: {
+ ...originalTx.txParams,
+ [key]: value,
+ },
+ }
+ assert.throws(txStateManager.updateTx.bind(txStateManager, newTx), 'updateTx should throw an error')
+ const result = txStateManager.getTx(1)
+ assert.deepEqual(result, originalTx, 'tx should not be updated')
+ }
+ }
+ })
+
it('updates gas price and adds history items', function () {
const originalGasPrice = '0x01'
const desiredGasPrice = '0x02'
diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js
index d6c259033..d942fd150 100644
--- a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js
+++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js
@@ -8,6 +8,17 @@ export default class AdvancedTabContent extends Component {
t: PropTypes.func,
}
+ constructor (props) {
+ super(props)
+ this.state = {
+ gasPrice: this.props.customGasPrice,
+ gasLimit: this.props.customGasLimit,
+ }
+ this.changeGasPrice = debounce(this.changeGasPrice, 500)
+ this.changeGasLimit = debounce(this.changeGasLimit, 500)
+ }
+
+
static propTypes = {
updateCustomGasPrice: PropTypes.func,
updateCustomGasLimit: PropTypes.func,
@@ -20,15 +31,40 @@ export default class AdvancedTabContent extends Component {
showGasLimitInfoModal: PropTypes.func,
}
- debouncedGasLimitReset = debounce((dVal) => {
- if (dVal < 21000) {
+ componentDidUpdate (prevProps) {
+ const { customGasPrice: prevCustomGasPrice, customGasLimit: prevCustomGasLimit } = prevProps
+ const { customGasPrice, customGasLimit } = this.props
+ const { gasPrice, gasLimit } = this.state
+
+ if (customGasPrice !== prevCustomGasPrice && customGasPrice !== gasPrice) {
+ this.setState({ gasPrice: customGasPrice })
+ }
+ if (customGasLimit !== prevCustomGasLimit && customGasLimit !== gasLimit) {
+ this.setState({ gasLimit: customGasLimit })
+ }
+ }
+
+ onChangeGasLimit = (e) => {
+ this.setState({ gasLimit: e.target.value })
+ this.changeGasLimit({ target: { value: e.target.value } })
+ }
+
+ changeGasLimit = (e) => {
+ if (e.target.value < 21000) {
+ this.setState({ gasLimit: 21000 })
this.props.updateCustomGasLimit(21000)
+ } else {
+ this.props.updateCustomGasLimit(Number(e.target.value))
}
- }, 1000, { trailing: true })
+ }
+
+ onChangeGasPrice = (e) => {
+ this.setState({ gasPrice: e.target.value })
+ this.changeGasPrice({ target: { value: e.target.value } })
+ }
- onChangeGasLimit = (val) => {
- this.props.updateCustomGasLimit(val)
- this.debouncedGasLimitReset(val)
+ changeGasPrice = (e) => {
+ this.props.updateCustomGasPrice(Number(e.target.value))
}
gasInputError ({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) {
@@ -74,7 +110,7 @@ export default class AdvancedTabContent extends Component {
})}
type="number"
value={value}
- onChange={event => onChange(Number(event.target.value))}
+ onChange={onChange}
/>
<div className={classnames('advanced-gas-inputs__gas-edit-row__input-arrows', {
'advanced-gas-inputs__gas-edit-row__input--error': isInError && errorType === 'error',
@@ -82,13 +118,13 @@ export default class AdvancedTabContent extends Component {
})}>
<div
className="advanced-gas-inputs__gas-edit-row__input-arrows__i-wrap"
- onClick={() => onChange(value + 1)}
+ onClick={() => onChange({ target: { value: value + 1 } })}
>
<i className="fa fa-sm fa-angle-up" />
</div>
<div
className="advanced-gas-inputs__gas-edit-row__input-arrows__i-wrap"
- onClick={() => onChange(Math.max(value - 1, 0))}
+ onClick={() => onChange({ target: { value: Math.max(value - 1, 0) } })}
>
<i className="fa fa-sm fa-angle-down" />
</div>
@@ -120,9 +156,6 @@ export default class AdvancedTabContent extends Component {
render () {
const {
- customGasPrice,
- updateCustomGasPrice,
- customGasLimit,
insufficientBalance,
customPriceIsSafe,
isSpeedUp,
@@ -134,8 +167,8 @@ export default class AdvancedTabContent extends Component {
<div className="advanced-gas-inputs__gas-edit-rows">
{ this.renderGasEditRow({
labelKey: 'gasPrice',
- value: customGasPrice,
- onChange: updateCustomGasPrice,
+ value: this.state.gasPrice,
+ onChange: this.onChangeGasPrice,
insufficientBalance,
customPriceIsSafe,
showGWEI: true,
@@ -144,7 +177,7 @@ export default class AdvancedTabContent extends Component {
}) }
{ this.renderGasEditRow({
labelKey: 'gasLimit',
- value: customGasLimit,
+ value: this.state.gasLimit,
onChange: this.onChangeGasLimit,
insufficientBalance,
customPriceIsSafe,
diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js
index 9da9a2ef6..c260d6798 100644
--- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js
+++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js
@@ -9,6 +9,7 @@ import {
hideSidebar,
updateSendAmount,
setGasTotal,
+ updateTransaction,
} from '../../../../store/actions'
import {
setCustomGasPrice,
@@ -23,9 +24,6 @@ import {
updateSendErrors,
} from '../../../../ducks/send/send.duck'
import {
- updateGasAndCalculate,
-} from '../../../../ducks/confirm-transaction/confirm-transaction.duck'
-import {
conversionRateSelector as getConversionRate,
getCurrentCurrency,
getCurrentEthBalance,
@@ -52,9 +50,6 @@ import {
getTokenBalance,
} from '../../../../pages/send/send.selectors'
import {
- submittedPendingTransactionsSelector,
-} from '../../../../selectors/transactions'
-import {
formatCurrency,
} from '../../../../helpers/utils/confirm-tx.util'
import {
@@ -77,11 +72,16 @@ import { getMaxModeOn } from '../../../../pages/send/send-content/send-amount-ro
import { calcMaxAmount } from '../../../../pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils'
const mapStateToProps = (state, ownProps) => {
+ const { selectedAddressTxList } = state.metamask
+ const { modalState: { props: modalProps } = {} } = state.appState.modal || {}
+ const { txData = {} } = modalProps || {}
const { transaction = {} } = ownProps
+ const selectedTransaction = selectedAddressTxList.find(({ id }) => id === (transaction.id || txData.id))
+
const buttonDataLoading = getBasicGasEstimateLoadingStatus(state)
const gasEstimatesLoading = getGasEstimatesLoadingStatus(state)
- const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state, transaction.id)
+ const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state, selectedTransaction)
const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice
const customModalGasLimitInHex = getCustomGasLimit(state) || currentGasLimit
const customGasTotal = calcGasTotal(customModalGasLimitInHex, customModalGasPriceInHex)
@@ -118,6 +118,7 @@ const mapStateToProps = (state, ownProps) => {
conversionRate,
})
+
return {
hideBasic,
isConfirm: isConfirm(state),
@@ -151,6 +152,7 @@ const mapStateToProps = (state, ownProps) => {
transactionFee: addHexWEIsToRenderableEth('0x0', customGasTotal),
sendAmount,
},
+ transaction: txData || transaction,
isSpeedUp: transaction.status === 'submitted',
txId: transaction.id,
insufficientBalance,
@@ -179,10 +181,10 @@ const mapDispatchToProps = dispatch => {
dispatch(setGasLimit(newLimit))
dispatch(setGasPrice(newPrice))
},
- updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => {
+ updateConfirmTxGasAndCalculate: (gasLimit, gasPrice, updatedTx) => {
updateCustomGasPrice(gasPrice)
dispatch(setCustomGasLimit(addHexPrefix(gasLimit.toString(16))))
- return dispatch(updateGasAndCalculate({ gasLimit, gasPrice }))
+ return dispatch(updateTransaction(updatedTx))
},
createSpeedUpTransaction: (txId, gasPrice) => {
return dispatch(createSpeedUpTransaction(txId, gasPrice))
@@ -214,6 +216,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
selectedToken,
tokenBalance,
customGasLimit,
+ transaction,
} = stateProps
const {
updateCustomGasPrice: dispatchUpdateCustomGasPrice,
@@ -234,7 +237,15 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
...ownProps,
onSubmit: (gasLimit, gasPrice) => {
if (isConfirm) {
- dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice)
+ const updatedTx = {
+ ...transaction,
+ txParams: {
+ ...transaction.txParams,
+ gas: gasLimit,
+ gasPrice,
+ },
+ }
+ dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice, updatedTx)
dispatchHideModal()
} else if (isSpeedUp) {
dispatchCreateSpeedUpTransaction(txId, gasPrice)
@@ -282,12 +293,10 @@ function calcCustomGasLimit (customGasLimitInHex) {
return parseInt(customGasLimitInHex, 16)
}
-function getTxParams (state, transactionId) {
- const { confirmTransaction: { txData }, metamask: { send } } = state
- const pendingTransactions = submittedPendingTransactionsSelector(state)
- const pendingTransaction = pendingTransactions.find(({ id }) => id === transactionId)
- const { txParams: pendingTxParams } = pendingTransaction || {}
- return txData.txParams || pendingTxParams || {
+function getTxParams (state, selectedTransaction = {}) {
+ const { metamask: { send } } = state
+ const { txParams } = selectedTransaction
+ return txParams || {
from: send.from,
gas: send.gasLimit || '0x5208',
gasPrice: send.gasPrice || getFastPriceEstimateInHexWEI(state, true),
diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js
index dbe61d5cf..03d254eee 100644
--- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js
+++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js
@@ -63,6 +63,9 @@ describe('gas-modal-page-container container', () => {
modalState: {
props: {
hideBasic: true,
+ txData: {
+ id: 34,
+ },
},
},
},
@@ -82,6 +85,14 @@ describe('gas-modal-page-container container', () => {
provider: {
type: 'mainnet',
},
+ selectedAddressTxList: [{
+ id: 34,
+ txParams: {
+ gas: '0x1600000',
+ gasPrice: '0x3200000',
+ value: '0x640000000000000',
+ },
+ }],
},
gas: {
basicEstimates: {
@@ -152,6 +163,9 @@ describe('gas-modal-page-container container', () => {
maxModeOn: false,
selectedToken: null,
tokenBalance: '0x0',
+ transaction: {
+ id: 34,
+ },
}
const baseMockOwnProps = { transaction: { id: 34 } }
const tests = [
@@ -168,7 +182,7 @@ describe('gas-modal-page-container container', () => {
mockOwnProps: Object.assign({}, baseMockOwnProps, {
transaction: { id: 34, status: 'submitted' },
}),
- expectedResult: Object.assign({}, baseExpectedResult, { isSpeedUp: true }),
+ expectedResult: Object.assign({}, baseExpectedResult, { isSpeedUp: true, transaction: { id: 34 } }),
},
{
mockState: Object.assign({}, baseMockState, {
@@ -317,8 +331,10 @@ describe('gas-modal-page-container container', () => {
it('should dispatch a updateGasAndCalculate action with the correct props', () => {
mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa')
assert.equal(dispatchSpy.callCount, 3)
- assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce)
- assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' })
+ assert(actionSpies.setGasPrice.calledOnce)
+ assert(actionSpies.setGasLimit.calledOnce)
+ assert.equal(actionSpies.setGasLimit.getCall(0).args[0], 'ffff')
+ assert.equal(actionSpies.setGasPrice.getCall(0).args[0], 'aaaa')
})
})
@@ -337,6 +353,7 @@ describe('gas-modal-page-container container', () => {
},
isConfirm: true,
someOtherStateProp: 'baz',
+ transaction: {},
}
dispatchProps = {
updateCustomGasPrice: sinon.spy(),
diff --git a/ui/app/components/app/modals/account-details-modal.js b/ui/app/components/app/modals/account-details-modal.js
deleted file mode 100644
index 6cffc918b..000000000
--- a/ui/app/components/app/modals/account-details-modal.js
+++ /dev/null
@@ -1,107 +0,0 @@
-const Component = require('react').Component
-const PropTypes = require('prop-types')
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-const actions = require('../../../store/actions')
-const AccountModalContainer = require('./account-modal-container')
-const { getSelectedIdentity, getRpcPrefsForCurrentProvider } = require('../../../selectors/selectors')
-const genAccountLink = require('../../../../lib/account-link.js')
-const QrView = require('../../ui/qr-code')
-const EditableLabel = require('../../ui/editable-label')
-
-import Button from '../../ui/button'
-
-function mapStateToProps (state) {
- return {
- network: state.metamask.network,
- selectedIdentity: getSelectedIdentity(state),
- keyrings: state.metamask.keyrings,
- rpcPrefs: getRpcPrefsForCurrentProvider(state),
- }
-}
-
-function mapDispatchToProps (dispatch) {
- return {
- // Is this supposed to be used somewhere?
- showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
- showExportPrivateKeyModal: () => {
- dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
- },
- hideModal: () => dispatch(actions.hideModal()),
- setAccountLabel: (address, label) => dispatch(actions.setAccountLabel(address, label)),
- }
-}
-
-inherits(AccountDetailsModal, Component)
-function AccountDetailsModal () {
- Component.call(this)
-}
-
-AccountDetailsModal.contextTypes = {
- t: PropTypes.func,
-}
-
-module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal)
-
-
-// Not yet pixel perfect todos:
- // fonts of qr-header
-
-AccountDetailsModal.prototype.render = function () {
- const {
- selectedIdentity,
- network,
- showExportPrivateKeyModal,
- setAccountLabel,
- keyrings,
- rpcPrefs,
- } = this.props
- const { name, address } = selectedIdentity
-
- const keyring = keyrings.find((kr) => {
- return kr.accounts.includes(address)
- })
-
- let exportPrivateKeyFeatureEnabled = true
- // This feature is disabled for hardware wallets
- if (keyring && keyring.type.search('Hardware') !== -1) {
- exportPrivateKeyFeatureEnabled = false
- }
-
- return h(AccountModalContainer, {}, [
- h(EditableLabel, {
- className: 'account-modal__name',
- defaultValue: name,
- onSubmit: label => setAccountLabel(address, label),
- }),
-
- h(QrView, {
- Qr: {
- data: address,
- network: network,
- },
- }),
-
- h('div.account-modal-divider'),
-
- h(Button, {
- type: 'secondary',
- className: 'account-modal__button',
- onClick: () => {
- global.platform.openWindow({ url: genAccountLink(address, network, rpcPrefs) })
- },
- }, (rpcPrefs.blockExplorerUrl
- ? this.context.t('blockExplorerView', [rpcPrefs.blockExplorerUrl.match(/^https?:\/\/(.+)/)[1]])
- : this.context.t('viewOnEtherscan'))),
-
- // Holding on redesign for Export Private Key functionality
-
- exportPrivateKeyFeatureEnabled ? h(Button, {
- type: 'secondary',
- className: 'account-modal__button',
- onClick: () => showExportPrivateKeyModal(),
- }, this.context.t('exportPrivateKey')) : null,
-
- ])
-}
diff --git a/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js
new file mode 100644
index 000000000..e3919edcf
--- /dev/null
+++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js
@@ -0,0 +1,87 @@
+import React, { Component} from 'react'
+import PropTypes from 'prop-types'
+import AccountModalContainer from '../account-modal-container'
+import genAccountLink from '../../../../../lib/account-link.js'
+import QrView from '../../../ui/qr-code'
+import EditableLabel from '../../../ui/editable-label'
+import Button from '../../../ui/button'
+
+export default class AccountDetailsModal extends Component {
+ static propTypes = {
+ selectedIdentity: PropTypes.object,
+ network: PropTypes.string,
+ showExportPrivateKeyModal: PropTypes.func,
+ setAccountLabel: PropTypes.func,
+ keyrings: PropTypes.array,
+ rpcPrefs: PropTypes.object,
+ }
+
+ static contextTypes = {
+ t: PropTypes.func,
+ }
+
+ render () {
+ const {
+ selectedIdentity,
+ network,
+ showExportPrivateKeyModal,
+ setAccountLabel,
+ keyrings,
+ rpcPrefs,
+ } = this.props
+ const { name, address } = selectedIdentity
+
+ const keyring = keyrings.find((kr) => {
+ return kr.accounts.includes(address)
+ })
+
+ let exportPrivateKeyFeatureEnabled = true
+ // This feature is disabled for hardware wallets
+ if (keyring && keyring.type.search('Hardware') !== -1) {
+ exportPrivateKeyFeatureEnabled = false
+ }
+
+ return (
+ <AccountModalContainer>
+ <EditableLabel
+ className="account-modal__name"
+ defaultValue={name}
+ onSubmit={label => setAccountLabel(address, label)}
+ />
+
+ <QrView
+ Qr={{
+ data: address,
+ network: network,
+ }}
+ />
+
+ <div className="account-modal-divider"/>
+
+ <Button
+ type="secondary"
+ className="account-modal__button"
+ onClick={() => {
+ global.platform.openWindow({ url: genAccountLink(address, network, rpcPrefs) })
+ }}
+ >
+ {rpcPrefs.blockExplorerUrl
+ ? this.context.t('blockExplorerView', [rpcPrefs.blockExplorerUrl.match(/^https?:\/\/(.+)/)[1]])
+ : this.context.t('viewOnEtherscan')
+ }
+ </Button>
+
+ {exportPrivateKeyFeatureEnabled
+ ? <Button
+ type="secondary"
+ className="account-modal__button"
+ onClick={() => showExportPrivateKeyModal()}
+ >
+ {this.context.t('exportPrivateKey')}
+ </Button>
+ : null
+ }
+ </AccountModalContainer>
+ )
+ }
+}
diff --git a/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js
new file mode 100644
index 000000000..4b2283ced
--- /dev/null
+++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js
@@ -0,0 +1,27 @@
+import { connect } from 'react-redux'
+import actions from '../../../../store/actions'
+import { getSelectedIdentity, getRpcPrefsForCurrentProvider } from '../../../../selectors/selectors'
+import AccountDetailsModal from './account-details-modal.component'
+
+const mapStateToProps = (state) => {
+ return {
+ network: state.metamask.network,
+ selectedIdentity: getSelectedIdentity(state),
+ keyrings: state.metamask.keyrings,
+ rpcPrefs: getRpcPrefsForCurrentProvider(state),
+ }
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ // Is this supposed to be used somewhere?
+ showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
+ showExportPrivateKeyModal: () => {
+ dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
+ },
+ hideModal: () => dispatch(actions.hideModal()),
+ setAccountLabel: (address, label) => dispatch(actions.setAccountLabel(address, label)),
+ }
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal)
diff --git a/ui/app/components/app/modals/account-details-modal/index.js b/ui/app/components/app/modals/account-details-modal/index.js
new file mode 100644
index 000000000..433f4d170
--- /dev/null
+++ b/ui/app/components/app/modals/account-details-modal/index.js
@@ -0,0 +1 @@
+export { default } from './account-details-modal.container'
diff --git a/ui/app/components/app/modals/deposit-ether-modal.js b/ui/app/components/app/modals/deposit-ether-modal.js
index f56069d65..20c4d018c 100644
--- a/ui/app/components/app/modals/deposit-ether-modal.js
+++ b/ui/app/components/app/modals/deposit-ether-modal.js
@@ -5,7 +5,6 @@ const inherits = require('util').inherits
const connect = require('react-redux').connect
const actions = require('../../../store/actions')
const { getNetworkDisplayName } = require('../../../../../app/scripts/controllers/network/util')
-const ShapeshiftForm = require('../shapeshift-form')
import Button from '../../ui/button'
@@ -13,8 +12,6 @@ let DIRECT_DEPOSIT_ROW_TITLE
let DIRECT_DEPOSIT_ROW_TEXT
let WYRE_ROW_TITLE
let WYRE_ROW_TEXT
-let SHAPESHIFT_ROW_TITLE
-let SHAPESHIFT_ROW_TEXT
let FAUCET_ROW_TITLE
let COINSWITCH_ROW_TITLE
let COINSWITCH_ROW_TEXT
@@ -56,15 +53,9 @@ function DepositEtherModal (_, context) {
DIRECT_DEPOSIT_ROW_TEXT = context.t('directDepositEtherExplainer')
WYRE_ROW_TITLE = context.t('buyWithWyre')
WYRE_ROW_TEXT = context.t('buyWithWyreDescription')
- SHAPESHIFT_ROW_TITLE = context.t('depositShapeShift')
- SHAPESHIFT_ROW_TEXT = context.t('depositShapeShiftExplainer')
FAUCET_ROW_TITLE = context.t('testFaucet')
COINSWITCH_ROW_TITLE = context.t('buyCoinSwitch')
COINSWITCH_ROW_TEXT = context.t('buyCoinSwitchExplainer')
-
- this.state = {
- buyingWithShapeshift: false,
- }
}
DepositEtherModal.contextTypes = {
@@ -131,7 +122,6 @@ DepositEtherModal.prototype.renderRow = function ({
DepositEtherModal.prototype.render = function () {
const { network, toWyre, toCoinSwitch, address, toFaucet } = this.props
- const { buyingWithShapeshift } = this.state
const isTestNetwork = ['3', '4', '5', '42'].find(n => n === network)
const networkName = getNetworkDisplayName(network)
@@ -148,7 +138,6 @@ DepositEtherModal.prototype.render = function () {
h('div.page-container__header-close', {
onClick: () => {
- this.setState({ buyingWithShapeshift: false })
this.props.hideWarning()
this.props.hideModal()
},
@@ -168,7 +157,6 @@ DepositEtherModal.prototype.render = function () {
text: DIRECT_DEPOSIT_ROW_TEXT,
buttonLabel: this.context.t('viewAccount'),
onButtonClick: () => this.goToAccountDetailsModal(),
- hide: buyingWithShapeshift,
}),
this.renderRow({
@@ -177,7 +165,7 @@ DepositEtherModal.prototype.render = function () {
text: this.facuetRowText(networkName),
buttonLabel: this.context.t('getEther'),
onButtonClick: () => toFaucet(network),
- hide: !isTestNetwork || buyingWithShapeshift,
+ hide: !isTestNetwork,
}),
this.renderRow({
@@ -191,7 +179,7 @@ DepositEtherModal.prototype.render = function () {
text: WYRE_ROW_TEXT,
buttonLabel: this.context.t('continueToWyre'),
onButtonClick: () => toWyre(address),
- hide: isTestNetwork || buyingWithShapeshift,
+ hide: isTestNetwork,
}),
this.renderRow({
@@ -205,29 +193,9 @@ DepositEtherModal.prototype.render = function () {
text: COINSWITCH_ROW_TEXT,
buttonLabel: this.context.t('continueToCoinSwitch'),
onButtonClick: () => toCoinSwitch(address),
- hide: isTestNetwork || buyingWithShapeshift,
- }),
-
- this.renderRow({
- logo: h('div.deposit-ether-modal__logo', {
- style: {
- backgroundImage: 'url(\'./images/shapeshift logo.png\')',
- },
- }),
- title: SHAPESHIFT_ROW_TITLE,
- text: SHAPESHIFT_ROW_TEXT,
- buttonLabel: this.context.t('shapeshiftBuy'),
- onButtonClick: () => this.setState({ buyingWithShapeshift: true }),
hide: isTestNetwork,
- hideButton: buyingWithShapeshift,
- hideTitle: buyingWithShapeshift,
- onBackClick: () => this.setState({ buyingWithShapeshift: false }),
- showBackButton: this.state.buyingWithShapeshift,
- className: buyingWithShapeshift && 'deposit-ether-modal__buy-row__shapeshift-buy',
}),
- buyingWithShapeshift && h(ShapeshiftForm),
-
]),
]),
diff --git a/ui/app/components/app/modals/modal.js b/ui/app/components/app/modals/modal.js
index 717f623af..394367c46 100644
--- a/ui/app/components/app/modals/modal.js
+++ b/ui/app/components/app/modals/modal.js
@@ -12,11 +12,10 @@ const { ENVIRONMENT_TYPE_POPUP } = require('../../../../../app/scripts/lib/enums
// Modal Components
const BuyOptions = require('./buy-options-modal')
const DepositEtherModal = require('./deposit-ether-modal')
-const AccountDetailsModal = require('./account-details-modal')
+import AccountDetailsModal from './account-details-modal'
const EditAccountNameModal = require('./edit-account-name-modal')
const ExportPrivateKeyModal = require('./export-private-key-modal')
const NewAccountModal = require('./new-account-modal')
-const ShapeshiftDepositTxModal = require('./shapeshift-deposit-tx-modal.js')
const HideTokenConfirmationModal = require('./hide-token-confirmation-modal')
const NotifcationModal = require('./notification-modal')
const QRScanner = require('./qr-scanner')
@@ -181,13 +180,6 @@ const MODALS = {
...accountModalStyle,
},
- SHAPESHIFT_DEPOSIT_TX: {
- contents: [
- h(ShapeshiftDepositTxModal),
- ],
- ...accountModalStyle,
- },
-
HIDE_TOKEN_CONFIRMATION: {
contents: [
h(HideTokenConfirmationModal, {}, []),
diff --git a/ui/app/components/app/modals/shapeshift-deposit-tx-modal.js b/ui/app/components/app/modals/shapeshift-deposit-tx-modal.js
deleted file mode 100644
index ada9430f7..000000000
--- a/ui/app/components/app/modals/shapeshift-deposit-tx-modal.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-const actions = require('../../../store/actions')
-const QrView = require('../../ui/qr-code')
-const AccountModalContainer = require('./account-modal-container')
-
-function mapStateToProps (state) {
- return {
- Qr: state.appState.modal.modalState.props.Qr,
- }
-}
-
-function mapDispatchToProps (dispatch) {
- return {
- hideModal: () => {
- dispatch(actions.hideModal())
- },
- }
-}
-
-inherits(ShapeshiftDepositTxModal, Component)
-function ShapeshiftDepositTxModal () {
- Component.call(this)
-
-}
-
-module.exports = connect(mapStateToProps, mapDispatchToProps)(ShapeshiftDepositTxModal)
-
-ShapeshiftDepositTxModal.prototype.render = function () {
- const { Qr } = this.props
-
- return h(AccountModalContainer, {
- }, [
- h('div', {}, [
- h(QrView, {key: 'qr', Qr}),
- ]),
- ])
-}
diff --git a/ui/app/components/app/shapeshift-form.js b/ui/app/components/app/shapeshift-form.js
deleted file mode 100644
index 34a6f3acd..000000000
--- a/ui/app/components/app/shapeshift-form.js
+++ /dev/null
@@ -1,256 +0,0 @@
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const PropTypes = require('prop-types')
-const Component = require('react').Component
-const connect = require('react-redux').connect
-const classnames = require('classnames')
-const qrcode = require('qrcode-generator')
-const { shapeShiftSubview, pairUpdate, buyWithShapeShift } = require('../../store/actions')
-const { isValidAddress } = require('../../helpers/utils/util')
-const SimpleDropdown = require('./dropdowns/simple-dropdown')
-
-import Button from '../ui/button'
-
-function mapStateToProps (state) {
- const {
- coinOptions,
- tokenExchangeRates,
- selectedAddress,
- } = state.metamask
- const { warning } = state.appState
-
- return {
- coinOptions,
- tokenExchangeRates,
- selectedAddress,
- warning,
- }
-}
-
-function mapDispatchToProps (dispatch) {
- return {
- shapeShiftSubview: () => dispatch(shapeShiftSubview()),
- pairUpdate: coin => dispatch(pairUpdate(coin)),
- buyWithShapeShift: data => dispatch(buyWithShapeShift(data)),
- }
-}
-
-ShapeshiftForm.contextTypes = {
- t: PropTypes.func,
-}
-
-module.exports = connect(mapStateToProps, mapDispatchToProps)(ShapeshiftForm)
-
-
-inherits(ShapeshiftForm, Component)
-function ShapeshiftForm () {
- Component.call(this)
-
- this.state = {
- depositCoin: 'btc',
- refundAddress: '',
- showQrCode: false,
- depositAddress: '',
- errorMessage: '',
- isLoading: false,
- bought: false,
- }
-}
-
-ShapeshiftForm.prototype.getCoinPair = function () {
- return `${this.state.depositCoin.toUpperCase()}_ETH`
-}
-
-ShapeshiftForm.prototype.componentWillMount = function () {
- this.props.shapeShiftSubview()
-}
-
-ShapeshiftForm.prototype.onCoinChange = function (coin) {
- this.setState({
- depositCoin: coin,
- errorMessage: '',
- })
- this.props.pairUpdate(coin)
-}
-
-ShapeshiftForm.prototype.onBuyWithShapeShift = function () {
- this.setState({
- isLoading: true,
- showQrCode: true,
- })
-
- const {
- buyWithShapeShift,
- selectedAddress: withdrawal,
- } = this.props
- const {
- refundAddress: returnAddress,
- depositCoin,
- } = this.state
- const pair = `${depositCoin}_eth`
- const data = {
- withdrawal,
- pair,
- returnAddress,
- // Public api key
- 'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6',
- }
-
- if (isValidAddress(withdrawal)) {
- buyWithShapeShift(data)
- .then(d => this.setState({
- showQrCode: true,
- depositAddress: d.deposit,
- isLoading: false,
- }))
- .catch(() => this.setState({
- showQrCode: false,
- errorMessage: this.context.t('invalidRequest'),
- isLoading: false,
- }))
- }
-}
-
-ShapeshiftForm.prototype.renderMetadata = function (label, value) {
- return h('div', {className: 'shapeshift-form__metadata-wrapper'}, [
-
- h('div.shapeshift-form__metadata-label', {}, [
- h('span', `${label}:`),
- ]),
-
- h('div.shapeshift-form__metadata-value', {}, [
- h('span', value),
- ]),
-
- ])
-}
-
-ShapeshiftForm.prototype.renderMarketInfo = function () {
- const { tokenExchangeRates } = this.props
- const {
- limit,
- rate,
- minimum,
- } = tokenExchangeRates[this.getCoinPair()] || {}
-
- return h('div.shapeshift-form__metadata', {}, [
-
- this.renderMetadata(this.context.t('status'), limit ? this.context.t('available') : this.context.t('unavailable')),
- this.renderMetadata(this.context.t('limit'), limit),
- this.renderMetadata(this.context.t('exchangeRate'), rate),
- this.renderMetadata(this.context.t('min'), minimum),
-
- ])
-}
-
-ShapeshiftForm.prototype.renderQrCode = function () {
- const { depositAddress, isLoading, depositCoin } = this.state
- const qrImage = qrcode(4, 'M')
- qrImage.addData(depositAddress)
- qrImage.make()
-
- return h('div.shapeshift-form', {}, [
-
- h('div.shapeshift-form__deposit-instruction', [
- this.context.t('depositCoin', [depositCoin.toUpperCase()]),
- ]),
-
- h('div', depositAddress),
-
- h('div.shapeshift-form__qr-code', [
- isLoading
- ? h('img', {
- src: 'images/loading.svg',
- style: { width: '60px'},
- })
- : h('div', {
- dangerouslySetInnerHTML: { __html: qrImage.createTableTag(4) },
- }),
- ]),
-
- this.renderMarketInfo(),
-
- ])
-}
-
-
-ShapeshiftForm.prototype.render = function () {
- const { coinOptions, btnClass, warning } = this.props
- const { errorMessage, showQrCode, depositAddress } = this.state
- const { tokenExchangeRates } = this.props
- const token = tokenExchangeRates[this.getCoinPair()]
-
- return h('div.shapeshift-form-wrapper', [
- showQrCode
- ? this.renderQrCode()
- : h('div.modal-shapeshift-form', [
- h('div.shapeshift-form__selectors', [
-
- h('div.shapeshift-form__selector', [
-
- h('div.shapeshift-form__selector-label', this.context.t('deposit')),
-
- h(SimpleDropdown, {
- selectedOption: this.state.depositCoin,
- onSelect: (coin) => this.onCoinChange(coin),
- options: Object.entries(coinOptions).map(([coin]) => ({
- value: coin.toLowerCase(),
- displayValue: coin,
- })),
- }),
-
- ]),
-
- h('div.icon.shapeshift-form__caret', {
- style: { backgroundImage: 'url(images/caret-right.svg)'},
- }),
-
- h('div.shapeshift-form__selector', [
-
- h('div.shapeshift-form__selector-label', [
- this.context.t('receive'),
- ]),
-
- h('div.shapeshift-form__selector-input', ['ETH']),
-
- ]),
-
- ]),
-
- warning && h('div.shapeshift-form__address-input-label', warning),
-
- !warning && h('div', {
- className: classnames('shapeshift-form__address-input-wrapper', {
- 'shapeshift-form__address-input-wrapper--error': errorMessage,
- }),
- }, [
-
- h('div.shapeshift-form__address-input-label', [
- this.context.t('refundAddress'),
- ]),
-
- h('input.shapeshift-form__address-input', {
- type: 'text',
- onChange: e => this.setState({
- refundAddress: e.target.value,
- errorMessage: '',
- }),
- }),
-
- h('divshapeshift-form__address-input-error-message', [errorMessage]),
- ]),
-
- !warning && this.renderMarketInfo(),
-
- ]),
-
- !depositAddress && h(Button, {
- type: 'secondary',
- large: true,
- className: `${btnClass} shapeshift-form__shapeshift-buy-btn`,
- disabled: !token,
- onClick: () => this.onBuyWithShapeShift(),
- }, [this.context.t('buy')]),
-
- ])
-}
diff --git a/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js b/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js
index fc5e2f90d..5d2ccb083 100644
--- a/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js
+++ b/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js
@@ -1,7 +1,10 @@
import { connect } from 'react-redux'
+import { compose } from 'recompose'
+import { withRouter } from 'react-router-dom'
import ConfirmTokenTransactionBase from './confirm-token-transaction-base.component'
import {
contractExchangeRateSelector,
+ transactionFeeSelector,
} from '../../selectors/confirm-transaction'
import { tokenSelector } from '../../selectors/tokens'
import {
@@ -14,15 +17,21 @@ import {
} from '../../helpers/utils/token-util'
-const mapStateToProps = (state) => {
- const { confirmTransaction, metamask: { currentCurrency, conversionRate } } = state
+const mapStateToProps = (state, ownProps) => {
+ const { match: { params = {} } } = ownProps
+ const { id: paramsTransactionId } = params
+ const { confirmTransaction, metamask: { currentCurrency, conversionRate, selectedAddressTxList } } = state
+
const {
- txData: { txParams: { to: tokenAddress, data } = {} } = {},
- fiatTransactionTotal,
- ethTransactionTotal,
+ txData: { id: transactionId, txParams: { to: tokenAddress, data } = {} } = {},
} = confirmTransaction
+ const transaction = selectedAddressTxList.find(({ id }) => id === (Number(paramsTransactionId) || transactionId)) || {}
+ const {
+ ethTransactionTotal,
+ fiatTransactionTotal,
+ } = transactionFeeSelector(state, transaction)
const tokens = tokenSelector(state)
const currentToken = tokens && tokens.find(({ address }) => tokenAddress === address)
const { decimals, symbol: tokenSymbol } = currentToken || {}
@@ -46,4 +55,7 @@ const mapStateToProps = (state) => {
}
}
-export default connect(mapStateToProps)(ConfirmTokenTransactionBase)
+export default compose(
+ withRouter,
+ connect(mapStateToProps)
+)(ConfirmTokenTransactionBase)
diff --git a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js
index e769d8974..2a1b78a8e 100644
--- a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js
+++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js
@@ -6,9 +6,9 @@ import contractMap from 'eth-contract-metadata'
import ConfirmTransactionBase from './confirm-transaction-base.component'
import {
clearConfirmTransaction,
- updateGasAndCalculate,
} from '../../ducks/confirm-transaction/confirm-transaction.duck'
-import { clearSend, cancelTx, cancelTxs, updateAndApproveTx, showModal, setMetaMetricsSendCount } from '../../store/actions'
+
+import { clearSend, cancelTx, cancelTxs, updateAndApproveTx, showModal, setMetaMetricsSendCount, updateTransaction } from '../../store/actions'
import {
INSUFFICIENT_FUNDS_ERROR_KEY,
GAS_LIMIT_TOO_LOW_ERROR_KEY,
@@ -19,6 +19,7 @@ import { conversionGreaterThan } from '../../helpers/utils/conversion-util'
import { MIN_GAS_LIMIT_DEC } from '../send/send.constants'
import { checksumAddress, addressSlicer, valuesFor } from '../../helpers/utils/util'
import { getMetaMaskAccounts, getAdvancedInlineGasShown, preferencesSelector, getIsMainnet, getKnownMethodData } from '../../selectors/selectors'
+import { transactionFeeSelector } from '../../selectors/confirm-transaction'
const casedContractMap = Object.keys(contractMap).reduce((acc, base) => {
return {
@@ -32,23 +33,26 @@ const mapStateToProps = (state, ownProps) => {
const { id: paramsTransactionId } = params
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
- const { confirmTransaction, metamask, gas } = state
+ const { confirmTransaction, metamask } = state
+ const {
+ conversionRate,
+ identities,
+ currentCurrency,
+ selectedAddress,
+ selectedAddressTxList,
+ assetImages,
+ network,
+ unapprovedTxs,
+ metaMetricsSendCount,
+ } = metamask
const {
- ethTransactionAmount,
- ethTransactionFee,
- ethTransactionTotal,
- fiatTransactionAmount,
- fiatTransactionFee,
- fiatTransactionTotal,
- hexTransactionAmount,
- hexTransactionFee,
- hexTransactionTotal,
tokenData,
txData,
tokenProps,
nonce,
} = confirmTransaction
const { txParams = {}, lastGasPrice, id: transactionId, transactionCategory } = txData
+ const transaction = R.find(({ id }) => id === (transactionId || Number(paramsTransactionId)))(selectedAddressTxList) || {}
const {
from: fromAddress,
to: txParamsToAddress,
@@ -56,26 +60,10 @@ const mapStateToProps = (state, ownProps) => {
gas: gasLimit,
value: amount,
data,
- } = txParams
+ } = transaction && transaction.txParams || txParams
const accounts = getMetaMaskAccounts(state)
- const {
- conversionRate,
- identities,
- currentCurrency,
- selectedAddress,
- selectedAddressTxList,
- assetImages,
- network,
- unapprovedTxs,
- metaMetricsSendCount,
- } = metamask
const assetImage = assetImages[txParamsToAddress]
- const {
- customGasLimit,
- customGasPrice,
- } = gas
-
const { balance } = accounts[selectedAddress]
const { name: fromName } = identities[selectedAddress]
const toAddress = propsToAddress || txParamsToAddress
@@ -88,9 +76,20 @@ const mapStateToProps = (state, ownProps) => {
)
const isTxReprice = Boolean(lastGasPrice)
- const transaction = R.find(({ id }) => id === (transactionId || Number(paramsTransactionId)))(selectedAddressTxList)
const transactionStatus = transaction ? transaction.status : ''
+ const {
+ ethTransactionAmount,
+ ethTransactionFee,
+ ethTransactionTotal,
+ fiatTransactionAmount,
+ fiatTransactionFee,
+ fiatTransactionTotal,
+ hexTransactionAmount,
+ hexTransactionFee,
+ hexTransactionTotal,
+ } = transactionFeeSelector(state, transaction)
+
if (transaction && transaction.simulationFails) {
txData.simulationFails = transaction.simulationFails
}
@@ -125,7 +124,7 @@ const mapStateToProps = (state, ownProps) => {
hexTransactionAmount,
hexTransactionFee,
hexTransactionTotal,
- txData: Object.keys(txData).length ? txData : transaction || {},
+ txData: { ...txData, ...transaction },
tokenData,
methodData,
tokenProps,
@@ -139,8 +138,8 @@ const mapStateToProps = (state, ownProps) => {
unapprovedTxCount,
currentNetworkUnapprovedTxs,
customGas: {
- gasLimit: customGasLimit || gasLimit,
- gasPrice: customGasPrice || gasPrice,
+ gasLimit,
+ gasPrice,
},
advancedInlineGasShown: getAdvancedInlineGasShown(state),
insufficientBalance,
@@ -161,8 +160,8 @@ const mapDispatchToProps = dispatch => {
showCustomizeGasModal: ({ txData, onSubmit, validate }) => {
return dispatch(showModal({ name: 'CUSTOMIZE_GAS', txData, onSubmit, validate }))
},
- updateGasAndCalculate: ({ gasLimit, gasPrice }) => {
- return dispatch(updateGasAndCalculate({ gasLimit, gasPrice }))
+ updateGasAndCalculate: (updatedTx) => {
+ return dispatch(updateTransaction(updatedTx))
},
showRejectTransactionsConfirmationModal: ({ onSubmit, unapprovedTxCount }) => {
return dispatch(showModal({ name: 'REJECT_TRANSACTIONS', onSubmit, unapprovedTxCount }))
@@ -239,7 +238,17 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
validate: validateEditGas,
}),
cancelAllTransactions: () => dispatchCancelAllTransactions(valuesFor(unapprovedTxs)),
- updateGasAndCalculate: dispatchUpdateGasAndCalculate,
+ updateGasAndCalculate: ({ gasLimit, gasPrice }) => {
+ const updatedTx = {
+ ...txData,
+ txParams: {
+ ...txData.txParams,
+ gas: gasLimit,
+ gasPrice,
+ },
+ }
+ dispatchUpdateGasAndCalculate(updatedTx)
+ },
}
}
diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js
index 5092d277e..a2fb5a3bf 100644
--- a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js
+++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js
@@ -30,10 +30,21 @@ export default class ImportWithSeedPhrase extends PureComponent {
}
parseSeedPhrase = (seedPhrase) => {
- return seedPhrase
- .trim()
- .match(/\w+/g)
- .join(' ')
+ if (!seedPhrase) {
+ return ''
+ }
+
+ const trimmed = seedPhrase.trim()
+ if (!trimmed) {
+ return ''
+ }
+
+ const words = trimmed.match(/\w+/g)
+ if (!words) {
+ return ''
+ }
+
+ return words.join(' ')
}
componentWillMount () {
diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js
new file mode 100644
index 000000000..7960d17b2
--- /dev/null
+++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js
@@ -0,0 +1,78 @@
+import React from 'react'
+import assert from 'assert'
+import { shallow } from 'enzyme'
+import sinon from 'sinon'
+import ImportWithSeedPhrase from '../import-with-seed-phrase.component'
+
+function shallowRender (props = {}, context = {}) {
+ return shallow(<ImportWithSeedPhrase {...props} />, {
+ context: {
+ t: str => str + '_t',
+ metricsEvent: sinon.spy(),
+ ...context,
+ },
+ })
+}
+
+describe('ImportWithSeedPhrase Component', () => {
+ it('should render without error', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+ const textareaCount = root.find('.first-time-flow__textarea').length
+ assert.equal(textareaCount, 1, 'should render 12 seed phrases')
+ })
+
+ describe('parseSeedPhrase', () => {
+ it('should handle a regular seed phrase', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+
+ const {parseSeedPhrase} = root.instance()
+
+ assert.deepEqual(parseSeedPhrase('foo bar baz'), 'foo bar baz')
+ })
+
+ it('should trim extraneous whitespace from the given seed phrase', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+
+ const {parseSeedPhrase} = root.instance()
+
+ assert.deepEqual(parseSeedPhrase(' foo bar baz '), 'foo bar baz')
+ })
+
+ it('should return an empty string when given a whitespace-only string', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+
+ const {parseSeedPhrase} = root.instance()
+
+ assert.deepEqual(parseSeedPhrase(' '), '')
+ })
+
+ it('should return an empty string when given a string with only symbols', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+
+ const {parseSeedPhrase} = root.instance()
+
+ assert.deepEqual(parseSeedPhrase('$'), '')
+ })
+
+ it('should return an empty string for both null and undefined', () => {
+ const root = shallowRender({
+ onSubmit: sinon.spy(),
+ })
+
+ const {parseSeedPhrase} = root.instance()
+
+ assert.deepEqual(parseSeedPhrase(undefined), '')
+ assert.deepEqual(parseSeedPhrase(null), '')
+ })
+ })
+})
diff --git a/ui/app/pages/first-time-flow/first-time-flow.component.js b/ui/app/pages/first-time-flow/first-time-flow.component.js
index bf6e80ca9..0d206bf42 100644
--- a/ui/app/pages/first-time-flow/first-time-flow.component.js
+++ b/ui/app/pages/first-time-flow/first-time-flow.component.js
@@ -29,7 +29,7 @@ export default class FirstTimeFlow extends PureComponent {
isInitialized: PropTypes.bool,
isUnlocked: PropTypes.bool,
unlockAccount: PropTypes.func,
- nextRoute: PropTypes.func,
+ nextRoute: PropTypes.string,
}
state = {
diff --git a/ui/app/pages/keychains/restore-vault.js b/ui/app/pages/keychains/restore-vault.js
index 574949258..08164fd9f 100644
--- a/ui/app/pages/keychains/restore-vault.js
+++ b/ui/app/pages/keychains/restore-vault.js
@@ -123,6 +123,7 @@ class RestoreVaultPage extends Component {
className="import-account__back-button"
onClick={e => {
e.preventDefault()
+ this.props.leaveImportSeedScreenState()
this.props.history.goBack()
}}
href="#"
diff --git a/ui/app/selectors/confirm-transaction.js b/ui/app/selectors/confirm-transaction.js
index 9b5eda82f..82df4e776 100644
--- a/ui/app/selectors/confirm-transaction.js
+++ b/ui/app/selectors/confirm-transaction.js
@@ -1,7 +1,17 @@
import { createSelector } from 'reselect'
import txHelper from '../../lib/tx-helper'
import { calcTokenAmount } from '../helpers/utils/token-util'
-import { roundExponential } from '../helpers/utils/confirm-tx.util'
+import {
+ roundExponential,
+ getValueFromWeiHex,
+ getHexGasTotal,
+ getTransactionFee,
+ addFiat,
+ addEth,
+} from '../helpers/utils/confirm-tx.util'
+import {
+ sumHexes,
+} from '../helpers/utils/transactions.util'
const unapprovedTxsSelector = state => state.metamask.unapprovedTxs
const unapprovedMsgsSelector = state => state.metamask.unapprovedMsgs
@@ -207,3 +217,51 @@ export const contractExchangeRateSelector = createSelector(
tokenAddressSelector,
(contractExchangeRates, tokenAddress) => contractExchangeRates[tokenAddress]
)
+
+export const transactionFeeSelector = function (state, txData) {
+ const currentCurrency = currentCurrencySelector(state)
+ const conversionRate = conversionRateSelector(state)
+ const nativeCurrency = getNativeCurrency(state)
+
+ const { txParams: { value = '0x0', gas: gasLimit = '0x0', gasPrice = '0x0' } = {} } = txData
+
+ const fiatTransactionAmount = getValueFromWeiHex({
+ value, fromCurrency: nativeCurrency, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2,
+ })
+ const ethTransactionAmount = getValueFromWeiHex({
+ value, fromCurrency: nativeCurrency, toCurrency: nativeCurrency, conversionRate, numberOfDecimals: 6,
+ })
+
+ const hexTransactionFee = getHexGasTotal({ gasLimit, gasPrice })
+
+ const fiatTransactionFee = getTransactionFee({
+ value: hexTransactionFee,
+ fromCurrency: nativeCurrency,
+ toCurrency: currentCurrency,
+ numberOfDecimals: 2,
+ conversionRate,
+ })
+ const ethTransactionFee = getTransactionFee({
+ value: hexTransactionFee,
+ fromCurrency: nativeCurrency,
+ toCurrency: nativeCurrency,
+ numberOfDecimals: 6,
+ conversionRate,
+ })
+
+ const fiatTransactionTotal = addFiat(fiatTransactionFee, fiatTransactionAmount)
+ const ethTransactionTotal = addEth(ethTransactionFee, ethTransactionAmount)
+ const hexTransactionTotal = sumHexes(value, hexTransactionFee)
+
+ return {
+ hexTransactionAmount: value,
+ fiatTransactionAmount,
+ ethTransactionAmount,
+ hexTransactionFee,
+ fiatTransactionFee,
+ ethTransactionFee,
+ fiatTransactionTotal,
+ ethTransactionTotal,
+ hexTransactionTotal,
+ }
+}
diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js
index d3cc7efca..3ed82044d 100644
--- a/ui/app/store/actions.js
+++ b/ui/app/store/actions.js
@@ -2391,10 +2391,6 @@ function reshowQrCode (data, coin) {
dispatch(actions.hideLoadingIndication())
return dispatch(actions.showQrView(data, message))
- // return dispatch(actions.showModal({
- // name: 'SHAPESHIFT_DEPOSIT_TX',
- // Qr: { data, message },
- // }))
})
}
}