aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml32
-rw-r--r--.github/CODEOWNERS1
-rw-r--r--.nvmrc2
-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/notification.html25
-rw-r--r--app/scripts/controllers/transactions/lib/util.js8
-rw-r--r--app/scripts/controllers/transactions/tx-state-manager.js30
-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/unit/app/controllers/transactions/tx-state-manager-test.js62
-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/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/store/actions.js4
49 files changed, 453 insertions, 1066 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/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/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/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/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/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/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/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/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 },
- // }))
})
}
}