aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml8
-rw-r--r--CHANGELOG.md21
-rw-r--r--app/_locales/cs/messages.json9
-rw-r--r--app/_locales/de/messages.json9
-rw-r--r--app/_locales/en/messages.json17
-rw-r--r--app/_locales/es/messages.json9
-rw-r--r--app/_locales/fr/messages.json9
-rw-r--r--app/_locales/hn/messages.json9
-rw-r--r--app/_locales/ht/messages.json9
-rw-r--r--app/_locales/it/messages.json9
-rw-r--r--app/_locales/ja/messages.json9
-rw-r--r--app/_locales/ko/messages.json9
-rw-r--r--app/_locales/nl/messages.json9
-rw-r--r--app/_locales/ph/messages.json9
-rw-r--r--app/_locales/pt/messages.json9
-rw-r--r--app/_locales/ru/messages.json9
-rw-r--r--app/_locales/sl/messages.json9
-rw-r--r--app/_locales/th/messages.json9
-rw-r--r--app/_locales/tml/messages.json9
-rw-r--r--app/_locales/tr/messages.json9
-rw-r--r--app/_locales/vi/messages.json9
-rw-r--r--app/_locales/zh_CN/messages.json9
-rw-r--r--app/_locales/zh_TW/messages.json9
-rw-r--r--app/images/coinswitch_logo.pngbin0 -> 3132 bytes
-rw-r--r--app/manifest.json2
-rw-r--r--app/scripts/background.js1
-rw-r--r--app/scripts/controllers/network/network.js12
-rw-r--r--app/scripts/controllers/preferences.js4
-rw-r--r--app/scripts/lib/buy-eth-url.js41
-rw-r--r--app/scripts/lib/nodeify.js15
-rw-r--r--app/scripts/metamask-controller.js15
-rw-r--r--app/scripts/migrations/033.js32
-rw-r--r--app/scripts/migrations/index.js2
-rw-r--r--app/scripts/notice-controller.js100
-rw-r--r--docs/publishing.md2
-rw-r--r--gulpfile.js55
-rw-r--r--mascara/src/app/buy-ether-widget/index.js198
-rw-r--r--mascara/src/app/shapeshift-form/index.js218
-rw-r--r--notices/README.md5
-rw-r--r--notices/archive/notice_0.md179
-rw-r--r--notices/archive/notice_2.md6
-rw-r--r--notices/archive/notice_3.md11
-rw-r--r--notices/archive/notice_4.md5
-rw-r--r--notices/notices.js35
-rw-r--r--package-lock.json487
-rw-r--r--package.json8
-rw-r--r--test/e2e/beta/from-import-beta-ui.spec.js19
-rw-r--r--test/e2e/beta/metamask-beta-responsive-ui.spec.js13
-rw-r--r--test/e2e/beta/metamask-beta-ui.spec.js111
-rwxr-xr-xtest/e2e/beta/run-all.sh3
-rw-r--r--test/unit/app/controllers/notice-controller-test.js67
-rw-r--r--test/unit/app/nodeify-test.js49
-rw-r--r--test/unit/migrations/033-test.js40
-rw-r--r--test/unit/ui/app/actions.spec.js65
-rw-r--r--test/unit/ui/app/reducers/app.spec.js9
-rw-r--r--test/unit/ui/app/reducers/metamask.spec.js43
-rw-r--r--ui/app/components/app/account-dropdowns.js338
-rw-r--r--ui/app/components/app/account-menu/account-menu.component.js4
-rw-r--r--ui/app/components/app/dropdowns/components/account-dropdowns.js473
-rw-r--r--ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js3
-rw-r--r--ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js2
-rw-r--r--ui/app/components/app/modals/deposit-ether-modal.js29
-rw-r--r--ui/app/components/app/notice.js138
-rw-r--r--ui/app/components/app/send/send-footer/send-footer.container.js3
-rw-r--r--ui/app/components/app/send/send-footer/send-footer.utils.js4
-rw-r--r--ui/app/components/app/send/tests/send-selectors-test-data.js1
-rw-r--r--ui/app/components/app/transaction-list-item/transaction-list-item.container.js4
-rw-r--r--ui/app/ducks/app/app.js6
-rw-r--r--ui/app/ducks/confirm-transaction/confirm-transaction.duck.js17
-rw-r--r--ui/app/ducks/gas/gas.duck.js2
-rw-r--r--ui/app/ducks/metamask/metamask.js14
-rw-r--r--ui/app/helpers/constants/routes.js4
-rw-r--r--ui/app/helpers/utils/confirm-tx.util.js4
-rw-r--r--ui/app/helpers/utils/transactions.util.js37
-rw-r--r--ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js4
-rw-r--r--ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.container.js6
-rw-r--r--ui/app/pages/home/home.container.js2
-rw-r--r--ui/app/pages/notice/notice.js203
-rw-r--r--ui/app/pages/routes/index.js10
-rw-r--r--ui/app/pages/settings/settings.component.js4
-rw-r--r--ui/app/pages/unlock-page/unlock-page.container.js2
-rw-r--r--ui/app/selectors/selectors.js3
-rw-r--r--ui/app/store/actions.js69
83 files changed, 854 insertions, 2610 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 807ed042c..686a996c1 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -23,11 +23,9 @@ workflows:
- test-e2e-chrome:
requires:
- prep-deps-npm
- - prep-build
- test-e2e-firefox:
requires:
- prep-deps-npm
- - prep-build
# - test-e2e-beta-drizzle:
# requires:
# - prep-deps-npm
@@ -191,7 +189,8 @@ jobs:
at: .
- run:
name: test:e2e:chrome
- command: npm run test:e2e:chrome
+ command: npm run build:test && npm run test:e2e:chrome
+ no_output_timeout: 20m
- store_artifacts:
path: test-artifacts
destination: test-artifacts
@@ -208,7 +207,8 @@ jobs:
at: .
- run:
name: test:e2e:firefox
- command: npm run test:e2e:firefox
+ command: npm run build:test && npm run test:e2e:chrome
+ no_output_timeout: 20m
- store_artifacts:
path: test-artifacts
destination: test-artifacts
diff --git a/CHANGELOG.md b/CHANGELOG.md
index abd1b4dc4..98ed6ac69 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,27 @@
## Current Develop Branch
+## 6.3.1 Fri Mar 26 2019
+
+- [#6353](https://github.com/MetaMask/metamask-extension/pull/6353): Open restore vault in full screen when clicked from popup
+- [#6372](https://github.com/MetaMask/metamask-extension/pull/6372): Prevents duplicates of account addresses from showing in send screen "To" dropdown
+- [#6374](https://github.com/MetaMask/metamask-extension/pull/6374): Ensures users are placed on correct confirm screens even when registry service fails
+
+## 6.3.0 Mon Mar 25 2019
+
+- [#6300](https://github.com/MetaMask/metamask-extension/pull/6300): Gas chart hidden on custom networks
+- [#6301](https://github.com/MetaMask/metamask-extension/pull/6301): Fix gas fee in the submitted step of the transaction details activity log
+- [#6302](https://github.com/MetaMask/metamask-extension/pull/6302): Replaces the coinbase link in the deposit modal with one for wyre
+- [#6307](https://github.com/MetaMask/metamask-extension/pull/6307): Centre the notification in the current window
+- [#6312](https://github.com/MetaMask/metamask-extension/pull/6312): Fixes popups not showing when screen size is odd
+- [#6326](https://github.com/MetaMask/metamask-extension/pull/6326): Fix oversized loading overlay on gas customization modal.
+- [#6330](https://github.com/MetaMask/metamask-extension/pull/6330): Stop reloading dapps on network change allowing dapps to decide if it should refresh or not
+- [#6332](https://github.com/MetaMask/metamask-extension/pull/6332): Enable mobile sync
+- [#6333](https://github.com/MetaMask/metamask-extension/pull/6333): Redesign of the settings screen
+- [#6340](https://github.com/MetaMask/metamask-extension/pull/6340): Cancel transactions and signature requests on the closing of notification windows
+- [#6341](https://github.com/MetaMask/metamask-extension/pull/6341): Disable transaction "Cancel" button when balance is insufficient
+- [#6347](https://github.com/MetaMask/metamask-extension/pull/6347): Enable privacy mode by default for first time users
+
## 6.2.2 Tue Mar 12 2019
- [#6271](https://github.com/MetaMask/metamask-extension/pull/6271): Centre all notification popups
diff --git a/app/_locales/cs/messages.json b/app/_locales/cs/messages.json
index 2bce52cd9..a28c4cb4a 100644
--- a/app/_locales/cs/messages.json
+++ b/app/_locales/cs/messages.json
@@ -131,6 +131,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase je světově nejoblíbenější místo k nákupu a prodeji bitcoinu, etherea nebo litecoinu."
},
+ "buyCoinSwitch": {
+ "message": "Nákup na CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch je jediným místem, kde můžete vyměňovat více než 300 kryptocurrencí za nejlepší cenu."
+ },
"ok": {
"message": "Ok"
},
@@ -164,6 +170,9 @@
"continueToCoinbase": {
"message": "Přejít na Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Přejít na CoinSwitch"
+ },
"contractDeployment": {
"message": "Nasazení kontraktu"
},
diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json
index 25ec628f0..b76f87772 100644
--- a/app/_locales/de/messages.json
+++ b/app/_locales/de/messages.json
@@ -131,6 +131,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase ist die weltweit bekannteste Art und Weise um Bitcoin, Ethereum und Litecoin zu kaufen und verkaufen."
},
+ "buyCoinSwitch": {
+ "message": "Auf CoinSwitch kaufen"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch ist die One-Stop-Destination, um mehr als 300 Kryptowährungen zum besten Preis zu tauschen."
+ },
"ok": {
"message": "Ok"
},
@@ -164,6 +170,9 @@
"continueToCoinbase": {
"message": "Zu Coinbase fortfahren"
},
+ "continueToCoinSwitch": {
+ "message": "Zu CoinSwitch fortfahren"
+ },
"contractDeployment": {
"message": "Smart Contract Ausführung"
},
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index eab243b8a..154925d1a 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -44,6 +44,12 @@
"providerRequestInfo": {
"message": "This site is requesting access to view your current account address. Always make sure you trust the sites you interact with."
},
+ "about": {
+ "message": "About"
+ },
+ "aboutSettingsDescription": {
+ "message": "Version, support center, and contact info."
+ },
"aboutUs": {
"message": "About Us"
},
@@ -201,7 +207,13 @@
"message": "Buy ETH with Wyre"
},
"buyWithWyreDescription": {
- "message": "Wyre lets you use aa credit card to deposit ETH right in to your MetaMask account. From the Airswap website, click \"Use Fiat\" in the top-right corner. You can also use Airswap to get started with ERC 20 tokens!"
+ "message": "Wyre lets you use a credit card to deposit ETH right in to your MetaMask account."
+ },
+ "buyCoinSwitch": {
+ "message": "Buy on CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch is the one-stop destination to exchange more than 300 cryptocurrencies at the best rate."
},
"bytes": {
"message": "Bytes"
@@ -314,6 +326,9 @@
"continueToWyre": {
"message": "Continue to Wyre"
},
+ "continueToCoinSwitch": {
+ "message": "Continue to CoinSwitch"
+ },
"contractDeployment": {
"message": "Contract Deployment"
},
diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json
index 8033b962c..3bdbfa852 100644
--- a/app/_locales/es/messages.json
+++ b/app/_locales/es/messages.json
@@ -131,6 +131,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase es la plataforma global más popular para comprar y vender Bitcoin, Ethereum y Litecoin"
},
+ "buyCoinSwitch": {
+ "message": "Comprar en CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch es el destino de una sola parada para intercambiar más de 300 criptomonedas al mejor precio."
+ },
"cancel": {
"message": "Cancelar"
},
@@ -176,6 +182,9 @@
"continueToCoinbase": {
"message": "Continuar a Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Continuar a CoinSwitch"
+ },
"contractDeployment": {
"message": "Desplegar (Deploy) contrato"
},
diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json
index 9018ef578..d2ba10009 100644
--- a/app/_locales/fr/messages.json
+++ b/app/_locales/fr/messages.json
@@ -152,6 +152,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase est le moyen le plus populaire d'acheter et de vendre des Ethers."
},
+ "buyCoinSwitch": {
+ "message": "Acheter sur CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch est la destination unique pour échanger plus de 300 crypto-devises au meilleur taux."
+ },
"bytes": {
"message": "Bytes"
},
@@ -233,6 +239,9 @@
"continueToCoinbase": {
"message": "Continuer vers Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Continuer vers CoinSwitch"
+ },
"contractDeployment": {
"message": "Déploiement de contrat"
},
diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json
index 4face7bd6..6c27ee1bc 100644
--- a/app/_locales/hn/messages.json
+++ b/app/_locales/hn/messages.json
@@ -128,6 +128,12 @@
"buyCoinbaseExplainer": {
"message": "बिल्टकोइन, इथीरियम और लाइटकोइन खरीदने और बेचने के लिए दुनिया का सबसे लोकप्रिय तरीका कॉइनबेस है।"
},
+ "buyCoinSwitch": {
+ "message": "कॉइनस्विच पर खरीदें"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "कॉइनस्विच 300 से अधिक क्रिप्टोक्रांसियों को सर्वोत्तम दर पर विनिमय करने का एक-स्टॉप गंतव्य है।"
+ },
"cancel": {
"message": "रद्द करें"
},
@@ -155,6 +161,9 @@
"continueToCoinbase": {
"message": "कॉइनबेस को ब्हेजना जारी रखें"
},
+ "continueToCoinSwitch": {
+ "message": "कॉइनस्विच को ब्हेजना जारी रखें"
+ },
"contractDeployment": {
"message": "अनुबंध परिनियोजन व तैनाती"
},
diff --git a/app/_locales/ht/messages.json b/app/_locales/ht/messages.json
index c94ddc8d2..4a4c92f3a 100644
--- a/app/_locales/ht/messages.json
+++ b/app/_locales/ht/messages.json
@@ -155,6 +155,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase se fason ki pi popilè nan mond lan yo achte ak vann Bitcoin, Ethereum, ak Litecoin."
},
+ "buyCoinSwitch": {
+ "message": "Achte sou CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch se destinasyon nan yon sèl-Stop nan echanj plis pase 300 kriptoksèr nan pousantaj la pi byen."
+ },
"bytes": {
"message": "Bytes"
},
@@ -239,6 +245,9 @@
"continueToCoinbase": {
"message": "Kontinye Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Kontinye CoinSwitch"
+ },
"contractDeployment": {
"message": "Kontra Deplwaman"
},
diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json
index 999bb8ec4..9e0f1f06d 100644
--- a/app/_locales/it/messages.json
+++ b/app/_locales/it/messages.json
@@ -179,6 +179,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase è il servizio più popolare al mondo per comprare e vendere Bitcoin, Ethereum e Litecoin."
},
+ "buyCoinSwitch": {
+ "message": "Compra su CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch è la destinazione one-stop per lo scambio di oltre 300 criptovalute alla migliore tariffa."
+ },
"bytes": {
"message": "Bytes"
},
@@ -281,6 +287,9 @@
"continueToCoinbase": {
"message": "Continua su Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Continua su CoinSwitch"
+ },
"contractDeployment": {
"message": "Distribuzione Contratto"
},
diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json
index 93b5447d7..fcac67894 100644
--- a/app/_locales/ja/messages.json
+++ b/app/_locales/ja/messages.json
@@ -122,6 +122,12 @@
"buyCoinbaseExplainer": {
"message": "Etherを購入できます。Coinbaseは、世界的なBitcoin、Ethereum、そしてLitecoinの取引所です。"
},
+ "buyCoinSwitch": {
+ "message": "CoinSwitchのサイトで購入"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitchは、最高のレートで300以上の暗号化交換を行うワンストップの宛先です。"
+ },
"cancel": {
"message": "キャンセル"
},
@@ -149,6 +155,9 @@
"continueToCoinbase": {
"message": "Coinbaseを開く"
},
+ "continueToCoinSwitch": {
+ "message": "CoinSwitchを開く"
+ },
"contractDeployment": {
"message": "コントラクトのデプロイ"
},
diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json
index b824cd72f..bf11640e2 100644
--- a/app/_locales/ko/messages.json
+++ b/app/_locales/ko/messages.json
@@ -182,6 +182,12 @@
"buyCoinbaseExplainer": {
"message": "코인베이스는 비트코인, 이더리움, 라이트코인을 거래할 수 있는 유명한 거래소입니다."
},
+ "buyCoinSwitch": {
+ "message": "코인 스위치 구입"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "코인 스위치는 최상의 속도로 300 개 이상의 크립토 카드를 교환하는 원 스톱 목적지입니다."
+ },
"bytes": {
"message": "바이트"
},
@@ -287,6 +293,9 @@
"continueToCoinbase": {
"message": "코인베이스로 계속하기"
},
+ "continueToCoinSwitch": {
+ "message": "코인 스위치 계속하기"
+ },
"contractDeployment": {
"message": "컨트랙트 배포"
},
diff --git a/app/_locales/nl/messages.json b/app/_locales/nl/messages.json
index b7b06e075..12bde6585 100644
--- a/app/_locales/nl/messages.json
+++ b/app/_locales/nl/messages.json
@@ -128,6 +128,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase is 's werelds populairste manier om Bitcoin, Ethereum en Litecoin te kopen en verkopen."
},
+ "buyCoinSwitch": {
+ "message": "Koop op CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch is de one-stop-bestemming om meer dan 300 cryptocurrencies tegen de beste prijs in te wisselen."
+ },
"cancel": {
"message": "Annuleer"
},
@@ -155,6 +161,9 @@
"continueToCoinbase": {
"message": "Ga verder naar Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Ga verder naar CoinSwitch"
+ },
"contractDeployment": {
"message": "Contractimplementatie"
},
diff --git a/app/_locales/ph/messages.json b/app/_locales/ph/messages.json
index cef686868..da3cf266d 100644
--- a/app/_locales/ph/messages.json
+++ b/app/_locales/ph/messages.json
@@ -110,6 +110,12 @@
"buyCoinbaseExplainer": {
"message": "Ang Coinbase ang pinakasikat na paraan upang bumili at magbenta ng Bitcoin, Ethereum, at Litecoin sa buong mundo."
},
+ "buyCoinSwitch": {
+ "message": "Bumili sa CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "Ang CoinSwitch ay isang one-stop destination upang makipagpalitan ng higit sa 300 mga cryptocurrency sa pinakamahusay na rate."
+ },
"cancel": {
"message": "Kanselahin"
},
@@ -131,6 +137,9 @@
"continueToCoinbase": {
"message": "Magpatuloy sa Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Magpatuloy sa CoinSwitch"
+ },
"contractDeployment": {
"message": "Pag-deploy ng Contract"
},
diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json
index 08af4b2a6..e51b1f72e 100644
--- a/app/_locales/pt/messages.json
+++ b/app/_locales/pt/messages.json
@@ -128,6 +128,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase é a forma mais conhecida para comprar e vender Bitcoin, Ethereum, e Litecoin."
},
+ "buyCoinSwitch": {
+ "message": "Comprar no CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch é o destino único para trocar mais de 300 moedas criptográficas com a melhor taxa."
+ },
"cancel": {
"message": "Cancelar"
},
@@ -155,6 +161,9 @@
"continueToCoinbase": {
"message": "Continuar para o Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Continuar para o CoinSwitch"
+ },
"contractDeployment": {
"message": "Distribuição do Contrato"
},
diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json
index 9568c64e6..f80efcc56 100644
--- a/app/_locales/ru/messages.json
+++ b/app/_locales/ru/messages.json
@@ -131,6 +131,12 @@
"buyCoinbaseExplainer": {
"message": "Биржа Coinbase – это наиболее популярный способ купить или продать Bitcoin, Ethereum и Litecoin."
},
+ "buyCoinSwitch": {
+ "message": "Купить на CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch - это однонаправленное место для обмена более 300 криптоконверсий по наилучшей цене."
+ },
"ok": {
"message": "ОК"
},
@@ -164,6 +170,9 @@
"continueToCoinbase": {
"message": "Продолжить в Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Продолжить в CoinSwitch"
+ },
"contractDeployment": {
"message": "Развертывание контракта"
},
diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json
index 857c37021..2f3616dee 100644
--- a/app/_locales/sl/messages.json
+++ b/app/_locales/sl/messages.json
@@ -218,6 +218,12 @@
"ok": {
"message": "V redu"
},
+ "buyCoinSwitch": {
+ "message": "Kupi na CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch je destinacija na enem mestu za izmenjavo več kot 300 kriptokotovitev po najboljši hitrosti."
+ },
"cancel": {
"message": "Prekliči"
},
@@ -305,6 +311,9 @@
"continueToCoinbase": {
"message": "Nadaljuj na Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Nadaljuj na CoinSwitch"
+ },
"contractDeployment": {
"message": "Ustvarjanje pogodbe"
},
diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json
index b80c39b98..d851d325f 100644
--- a/app/_locales/th/messages.json
+++ b/app/_locales/th/messages.json
@@ -128,6 +128,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase เป็นแหล่งซื้อขายบิตคอยน์ไลท์คอยน์และอีเธอเรียมที่ได้รับความนิยมสูงสุดในโลก"
},
+ "buyCoinSwitch": {
+ "message": "ซื้อด้วย CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch เป็นจุดหมายปลายทางแบบครบวงจรในการแลกเปลี่ยนสกุลเงินมากกว่า 300 ครั้งในอัตราที่ดีที่สุด"
+ },
"cancel": {
"message": "ยกเลิก"
},
@@ -155,6 +161,9 @@
"continueToCoinbase": {
"message": "ไปที่ Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "ไปที่ CoinSwitch"
+ },
"contractDeployment": {
"message": "การติดตั้งสัญญา"
},
diff --git a/app/_locales/tml/messages.json b/app/_locales/tml/messages.json
index 03ae4b7ff..e1ef45138 100644
--- a/app/_locales/tml/messages.json
+++ b/app/_locales/tml/messages.json
@@ -131,6 +131,12 @@
"buyCoinbaseExplainer": {
"message": "கோஇன்பசே பிறகாய்ன் , எதெரியும் மற்றும் ளிட்டசோன் வாங்க மற்றும் விற்க உலகின் மிகவும் பிரபலமான வழி"
},
+ "buyCoinSwitch": {
+ "message": "நாணயம் ஸ்விட்சில் வாங்கவும்"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "சிறந்த விகிதத்தில் 300 க்கும் அதிகமான cryptocurrencies ஐ பரிமாறிக்கொள்ள ஒரு நாணயமாற்று இலக்கு நாணயம் ஸ்விட்ச் ஆகும்."
+ },
"ok": {
"message": "சரி"
},
@@ -164,6 +170,9 @@
"continueToCoinbase": {
"message": "கோஇன்பசே ஐத் தொடரவும்"
},
+ "continueToCoinSwitch": {
+ "message": "நாணயம் மாறாமல் தொடர்க"
+ },
"contractDeployment": {
"message": "ஒப்பந்த வரிசைப்படுத்தல்"
},
diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json
index b085828a2..bcf96dece 100644
--- a/app/_locales/tr/messages.json
+++ b/app/_locales/tr/messages.json
@@ -131,6 +131,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase Bitcoin, Ethereum, and Litecoin alıp satmanın dünyadaki en popüler yolu"
},
+ "buyCoinSwitch": {
+ "message": "CoinSwitch'de satın al"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "Cairnswich, 300'den fazla kriptona en iyi oranda eşlik eden tek durak noktasıdır."
+ },
"ok": {
"message": "Tamam"
},
@@ -164,6 +170,9 @@
"continueToCoinbase": {
"message": "Coinbase'e devam et"
},
+ "continueToCoinSwitch": {
+ "message": "CoinSwitch'e devam et"
+ },
"contractDeployment": {
"message": "Sözleşme kurulumu"
},
diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json
index f0837ba98..857f78597 100644
--- a/app/_locales/vi/messages.json
+++ b/app/_locales/vi/messages.json
@@ -110,6 +110,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase là dịch vụ ví điện tử thông dụng nhất thế giới để mua bán Bitcoin, Ethereum, và Litecoin"
},
+ "buyCoinSwitch": {
+ "message": "Mua trên CoinSwitch"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch là điểm đến duy nhất để trao đổi hơn 300 tiền điện tử với tốc độ tốt nhất."
+ },
"cancel": {
"message": "Hủy"
},
@@ -131,6 +137,9 @@
"continueToCoinbase": {
"message": "Tiếp tục đến Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "Tiếp tục đến CoinSwitch"
+ },
"contractDeployment": {
"message": "Triển khai hợp đồng"
},
diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json
index 9d929d9a3..0d3727703 100644
--- a/app/_locales/zh_CN/messages.json
+++ b/app/_locales/zh_CN/messages.json
@@ -134,6 +134,12 @@
"buyCoinbaseExplainer": {
"message": "Coinbase 是世界上最流行的买卖比特币,以太币和莱特币的交易所。"
},
+ "buyCoinSwitch": {
+ "message": "在CoinSwitch上购买"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch是以最优惠的价格交换超过300种加密货币的一站式目的地。"
+ },
"ok": {
"message": "确认"
},
@@ -173,6 +179,9 @@
"continueToCoinbase": {
"message": "继续访问 Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "继续访问 CoinSwitch"
+ },
"contractDeployment": {
"message": "合约部署"
},
diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json
index d9d84b173..c645f2af1 100644
--- a/app/_locales/zh_TW/messages.json
+++ b/app/_locales/zh_TW/messages.json
@@ -188,6 +188,12 @@
"bytes": {
"message": "位元組"
},
+ "buyCoinSwitch": {
+ "message": "在CoinSwitch上购买"
+ },
+ "buyCoinSwitchExplainer": {
+ "message": "CoinSwitch是以最优惠的价格交换超过300种加密货币的一站式目的地。"
+ },
"ok": {
"message": "Ok"
},
@@ -272,6 +278,9 @@
"continueToCoinbase": {
"message": "繼續前往 Coinbase"
},
+ "continueToCoinSwitch": {
+ "message": "繼續前往 CoinSwitch"
+ },
"contractDeployment": {
"message": "部署合約"
},
diff --git a/app/images/coinswitch_logo.png b/app/images/coinswitch_logo.png
new file mode 100644
index 000000000..445ecf02e
--- /dev/null
+++ b/app/images/coinswitch_logo.png
Binary files differ
diff --git a/app/manifest.json b/app/manifest.json
index df5b67bb9..941842636 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "__MSG_appName__",
"short_name": "__MSG_appName__",
- "version": "6.2.2",
+ "version": "6.3.1",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "__MSG_appDescription__",
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 7fea3c8c6..cca0d4709 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -106,7 +106,6 @@ setupMetamaskMeshMetrics()
* @property {string} rpcTarget - DEPRECATED - The URL of the current RPC provider.
* @property {Object} identities - An object matching lower-case hex addresses to Identity objects with "address" and "name" (nickname) keys.
* @property {Object} unapprovedTxs - An object mapping transaction hashes to unapproved transactions.
- * @property {boolean} noActiveNotices - False if there are notices the user should confirm before using the application.
* @property {Array} frequentRpcList - A list of frequently used RPCs, including custom user-provided ones.
* @property {Array} addressBook - A list of previously sent to addresses.
* @property {address} selectedTokenAddress - Used to indicate if a token is globally selected. Should be deprecated in favor of UI-centric token selection.
diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js
index 0c6327f6e..47432c1e2 100644
--- a/app/scripts/controllers/network/network.js
+++ b/app/scripts/controllers/network/network.js
@@ -25,10 +25,18 @@ const INFURA_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET]
const env = process.env.METAMASK_ENV
const METAMASK_DEBUG = process.env.METAMASK_DEBUG
-const testMode = (METAMASK_DEBUG || env === 'test')
+
+let defaultProviderConfigType
+if (process.env.IN_TEST === 'true') {
+ defaultProviderConfigType = LOCALHOST
+} else if (METAMASK_DEBUG || env === 'test') {
+ defaultProviderConfigType = RINKEBY
+} else {
+ defaultProviderConfigType = MAINNET
+}
const defaultProviderConfig = {
- type: testMode ? RINKEBY : MAINNET,
+ type: defaultProviderConfigType,
}
const defaultNetworkConfig = {
diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js
index f92341353..737411890 100644
--- a/app/scripts/controllers/preferences.js
+++ b/app/scripts/controllers/preferences.js
@@ -40,7 +40,9 @@ class PreferencesController {
// Feature flag toggling is available in the global namespace
// for convenient testing of pre-release features, and should never
// perform sensitive operations.
- featureFlags: {},
+ featureFlags: {
+ privacyMode: true,
+ },
knownMethodData: {},
participateInMetaMetrics: null,
firstTimeFlowType: null,
diff --git a/app/scripts/lib/buy-eth-url.js b/app/scripts/lib/buy-eth-url.js
index 040b5695b..fbe6c6c9e 100644
--- a/app/scripts/lib/buy-eth-url.js
+++ b/app/scripts/lib/buy-eth-url.js
@@ -11,24 +11,37 @@ module.exports = getBuyEthUrl
* network does not match any of the specified cases, or if no network is given, returns undefined.
*
*/
-function getBuyEthUrl ({ network, amount, address }) {
- let url
+function getBuyEthUrl ({ network, amount, address, service }) {
+ // default service by network if not specified
+ if (!service) service = getDefaultServiceForNetwork(network)
+
+ switch (service) {
+ case 'wyre':
+ return `https://dash.sendwyre.com/sign-up`
+ case 'coinswitch':
+ return `https://metamask.coinswitch.co/?address=${address}&to=eth`
+ case 'coinbase':
+ return `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`
+ case 'metamask-faucet':
+ return 'https://faucet.metamask.io/'
+ case 'rinkeby-faucet':
+ return 'https://www.rinkeby.io/'
+ case 'kovan-faucet':
+ return 'https://github.com/kovan-testnet/faucet'
+ }
+ throw new Error(`Unknown cryptocurrency exchange or faucet: "${service}"`)
+}
+
+function getDefaultServiceForNetwork (network) {
switch (network) {
case '1':
- url = `https://dash.sendwyre.com/sign-up`
- break
-
+ return 'wyre'
case '3':
- url = 'https://faucet.metamask.io/'
- break
-
+ return 'metamask-faucet'
case '4':
- url = 'https://www.rinkeby.io/'
- break
-
+ return 'rinkeby-faucet'
case '42':
- url = 'https://github.com/kovan-testnet/faucet'
- break
+ return 'kovan-faucet'
}
- return url
+ throw new Error(`No default cryptocurrency exchange or faucet for networkId: "${network}"`)
}
diff --git a/app/scripts/lib/nodeify.js b/app/scripts/lib/nodeify.js
index 25be6537b..a813ae679 100644
--- a/app/scripts/lib/nodeify.js
+++ b/app/scripts/lib/nodeify.js
@@ -1,5 +1,5 @@
const promiseToCallback = require('promise-to-callback')
-const noop = function () {}
+const callbackNoop = function (err) { if (err) throw err }
/**
* A generator that returns a function which, when passed a promise, can treat that promise as a node style callback.
@@ -11,6 +11,7 @@ const noop = function () {}
*/
module.exports = function nodeify (fn, context) {
return function () {
+ // parse arguments
const args = [].slice.call(arguments)
const lastArg = args[args.length - 1]
const lastArgIsCallback = typeof lastArg === 'function'
@@ -19,8 +20,16 @@ module.exports = function nodeify (fn, context) {
callback = lastArg
args.pop()
} else {
- callback = noop
+ callback = callbackNoop
}
- promiseToCallback(fn.apply(context, args))(callback)
+ // call the provided function and ensure result is a promise
+ let result
+ try {
+ result = Promise.resolve(fn.apply(context, args))
+ } catch (err) {
+ result = Promise.reject(err)
+ }
+ // wire up promise resolution to callback
+ promiseToCallback(result)(callback)
}
}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 540aee936..4108ed4c0 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -24,7 +24,6 @@ const KeyringController = require('eth-keyring-controller')
const NetworkController = require('./controllers/network')
const PreferencesController = require('./controllers/preferences')
const CurrencyController = require('./controllers/currency')
-const NoticeController = require('./notice-controller')
const ShapeShiftController = require('./controllers/shapeshift')
const InfuraController = require('./controllers/infura')
const BlacklistController = require('./controllers/blacklist')
@@ -211,13 +210,6 @@ module.exports = class MetamaskController extends EventEmitter {
})
this.balancesController.updateAllBalances()
- // notices
- this.noticeController = new NoticeController({
- initState: initState.NoticeController,
- version,
- firstVersion: initState.firstTimeInfo.version,
- })
-
this.shapeshiftController = new ShapeShiftController({
initState: initState.ShapeShiftController,
})
@@ -243,7 +235,6 @@ module.exports = class MetamaskController extends EventEmitter {
PreferencesController: this.preferencesController.store,
AddressBookController: this.addressBookController,
CurrencyController: this.currencyController.store,
- NoticeController: this.noticeController.store,
ShapeShiftController: this.shapeshiftController.store,
NetworkController: this.networkController.store,
InfuraController: this.infuraController.store,
@@ -265,7 +256,6 @@ module.exports = class MetamaskController extends EventEmitter {
RecentBlocksController: this.recentBlocksController.store,
AddressBookController: this.addressBookController,
CurrencyController: this.currencyController.store,
- NoticeController: this.noticeController.memStore,
ShapeshiftController: this.shapeshiftController.store,
InfuraController: this.infuraController.store,
ProviderApprovalController: this.providerApprovalController.store,
@@ -371,7 +361,6 @@ module.exports = class MetamaskController extends EventEmitter {
const keyringController = this.keyringController
const preferencesController = this.preferencesController
const txController = this.txController
- const noticeController = this.noticeController
const networkController = this.networkController
const providerApprovalController = this.providerApprovalController
@@ -470,10 +459,6 @@ module.exports = class MetamaskController extends EventEmitter {
signTypedMessage: nodeify(this.signTypedMessage, this),
cancelTypedMessage: this.cancelTypedMessage.bind(this),
- // notices
- checkNotices: noticeController.updateNoticesList.bind(noticeController),
- markNoticeRead: noticeController.markNoticeRead.bind(noticeController),
-
approveProviderRequest: providerApprovalController.approveProviderRequest.bind(providerApprovalController),
clearApprovedOrigins: providerApprovalController.clearApprovedOrigins.bind(providerApprovalController),
rejectProviderRequest: providerApprovalController.rejectProviderRequest.bind(providerApprovalController),
diff --git a/app/scripts/migrations/033.js b/app/scripts/migrations/033.js
new file mode 100644
index 000000000..3abb2593e
--- /dev/null
+++ b/app/scripts/migrations/033.js
@@ -0,0 +1,32 @@
+// next version number
+const version = 33
+
+/*
+
+Cleans up notices and assocated notice controller code
+
+*/
+
+const clone = require('clone')
+
+module.exports = {
+ version,
+
+ migrate: async function (originalVersionedData) {
+ const versionedData = clone(originalVersionedData)
+ versionedData.meta.version = version
+ const state = versionedData.data
+ const newState = transformState(state)
+ versionedData.data = newState
+ return versionedData
+ },
+}
+
+function transformState (state) {
+ const newState = state
+ // transform state here
+ if (state.NoticeController) {
+ delete newState.NoticeController
+ }
+ return newState
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index eb1b51685..be3328bad 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -42,4 +42,6 @@ module.exports = [
require('./029'),
require('./030'),
require('./031'),
+ require('./032'),
+ require('./033'),
]
diff --git a/app/scripts/notice-controller.js b/app/scripts/notice-controller.js
deleted file mode 100644
index 6fe8b8cf0..000000000
--- a/app/scripts/notice-controller.js
+++ /dev/null
@@ -1,100 +0,0 @@
-const {EventEmitter} = require('events')
-const semver = require('semver')
-const extend = require('xtend')
-const ObservableStore = require('obs-store')
-const hardCodedNotices = require('../../notices/notices.js')
-const uniqBy = require('lodash.uniqby')
-
-module.exports = class NoticeController extends EventEmitter {
-
- constructor (opts = {}) {
- super()
- this.noticePoller = null
- this.firstVersion = opts.firstVersion
- this.version = opts.version
- const initState = extend({
- noticesList: [],
- }, opts.initState)
- this.store = new ObservableStore(initState)
- // setup memStore
- this.memStore = new ObservableStore({})
- this.store.subscribe(() => this._updateMemstore())
- this._updateMemstore()
- // pull in latest notices
- this.updateNoticesList()
- }
-
- getNoticesList () {
- return this.store.getState().noticesList
- }
-
- getUnreadNotices () {
- const notices = this.getNoticesList()
- return notices.filter((notice) => notice.read === false)
- }
-
- getNextUnreadNotice () {
- const unreadNotices = this.getUnreadNotices()
- return unreadNotices[0]
- }
-
- async setNoticesList (noticesList) {
- this.store.updateState({ noticesList })
- return true
- }
-
- markNoticeRead (noticeToMark, cb) {
- cb = cb || function (err) { if (err) throw err }
- try {
- const notices = this.getNoticesList()
- const index = notices.findIndex((currentNotice) => currentNotice.id === noticeToMark.id)
- notices[index].read = true
- notices[index].body = ''
- this.setNoticesList(notices)
- const latestNotice = this.getNextUnreadNotice()
- cb(null, latestNotice)
- } catch (err) {
- cb(err)
- }
- }
-
- async updateNoticesList () {
- const newNotices = await this._retrieveNoticeData()
- const oldNotices = this.getNoticesList()
- const combinedNotices = this._mergeNotices(oldNotices, newNotices)
- const filteredNotices = this._filterNotices(combinedNotices)
- const result = this.setNoticesList(filteredNotices)
- this._updateMemstore()
- return result
- }
-
- _mergeNotices (oldNotices, newNotices) {
- return uniqBy(oldNotices.concat(newNotices), 'id')
- }
-
- _filterNotices (notices) {
- return notices.filter((newNotice) => {
- if ('version' in newNotice) {
- const satisfied = semver.satisfies(this.version, newNotice.version)
- return satisfied
- }
- if ('firstVersion' in newNotice) {
- const satisfied = semver.satisfies(this.firstVersion, newNotice.firstVersion)
- return satisfied
- }
- return true
- })
- }
-
- async _retrieveNoticeData () {
- // Placeholder for remote notice API.
- return hardCodedNotices
- }
-
- _updateMemstore () {
- const nextUnreadNotice = this.getNextUnreadNotice()
- const noActiveNotices = !nextUnreadNotice
- this.memStore.updateState({ nextUnreadNotice, noActiveNotices })
- }
-
-}
diff --git a/docs/publishing.md b/docs/publishing.md
index 132c28d9b..1668afe1e 100644
--- a/docs/publishing.md
+++ b/docs/publishing.md
@@ -15,7 +15,7 @@ We try to ensure certain criteria are met before deploying:
Version can be automatically incremented [using our bump script](./bumping-version.md).
-npm run version:bump $BUMP_TYPE` where `$BUMP_TYPE` is one of `major`, `minor`, or `patch`.
+npm run version:bump `$BUMP_TYPE` where `$BUMP_TYPE` is one of `major`, `minor`, or `patch`.
## Preparing for Sensitive Changes
diff --git a/gulpfile.js b/gulpfile.js
index c1012d5aa..caddb620a 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -195,6 +195,21 @@ gulp.task('manifest:production', function () {
.pipe(gulp.dest('./dist/', { overwrite: true }))
})
+gulp.task('manifest:testing', function () {
+ return gulp.src([
+ './dist/firefox/manifest.json',
+ './dist/chrome/manifest.json',
+ ], {base: './dist/'})
+
+ // Exclude chromereload script in production:
+ .pipe(jsoneditor(function (json) {
+ json.permissions = [...json.permissions, 'webRequestBlocking']
+ return json
+ }))
+
+ .pipe(gulp.dest('./dist/', { overwrite: true }))
+})
+
gulp.task('copy',
gulp.series(
gulp.parallel(...copyTaskNames),
@@ -212,6 +227,15 @@ gulp.task('dev:copy',
)
)
+gulp.task('test:copy',
+ gulp.series(
+ gulp.parallel(...copyDevTaskNames),
+ 'manifest:chrome',
+ 'manifest:opera',
+ 'manifest:testing'
+ )
+)
+
// scss compilation and autoprefixing tasks
gulp.task('build:scss', createScssBuildTask({
@@ -287,7 +311,9 @@ const buildJsFiles = [
// bundle tasks
createTasksForBuildJsUIDeps({ dependenciesToBundle: uiDependenciesToBundle, filename: 'libs' })
createTasksForBuildJsExtension({ buildJsFiles, taskPrefix: 'dev:extension:js', devMode: true })
+createTasksForBuildJsExtension({ buildJsFiles, taskPrefix: 'dev:test-extension:js', devMode: true, testing: 'true' })
createTasksForBuildJsExtension({ buildJsFiles, taskPrefix: 'build:extension:js' })
+createTasksForBuildJsExtension({ buildJsFiles, taskPrefix: 'build:test:extension:js', testing: 'true' })
function createTasksForBuildJsUIDeps ({ dependenciesToBundle, filename }) {
const destinations = browserPlatforms.map(platform => `./dist/${platform}`)
@@ -310,7 +336,7 @@ function createTasksForBuildJsUIDeps ({ dependenciesToBundle, filename }) {
}
-function createTasksForBuildJsExtension ({ buildJsFiles, taskPrefix, devMode, bundleTaskOpts = {} }) {
+function createTasksForBuildJsExtension ({ buildJsFiles, taskPrefix, devMode, testing, bundleTaskOpts = {} }) {
// inpage must be built before all other scripts:
const rootDir = './app/scripts'
const nonInpageFiles = buildJsFiles.filter(file => file !== 'inpage')
@@ -324,6 +350,7 @@ function createTasksForBuildJsExtension ({ buildJsFiles, taskPrefix, devMode, bu
buildWithFullPaths: devMode,
watch: devMode,
devMode,
+ testing,
}, bundleTaskOpts)
createTasksForBuildJs({ rootDir, taskPrefix, bundleTaskOpts, destinations, buildPhase1, buildPhase2 })
}
@@ -383,6 +410,18 @@ gulp.task('dev',
)
)
+gulp.task('dev:test',
+ gulp.series(
+ 'clean',
+ 'dev:scss',
+ gulp.parallel(
+ 'dev:test-extension:js',
+ 'test:copy',
+ 'dev:reload'
+ )
+ )
+)
+
gulp.task('dev:extension',
gulp.series(
'clean',
@@ -407,6 +446,19 @@ gulp.task('build',
)
)
+gulp.task('build:test',
+ gulp.series(
+ 'clean',
+ 'build:scss',
+ gulpParallel(
+ 'build:extension:js:uideps',
+ 'build:test:extension:js',
+ 'copy'
+ ),
+ 'manifest:testing'
+ )
+)
+
gulp.task('build:extension',
gulp.series(
'clean',
@@ -460,6 +512,7 @@ function generateBundler (opts, performBundle) {
bundler.transform(envify({
METAMASK_DEBUG: opts.devMode,
NODE_ENV: opts.devMode ? 'development' : 'production',
+ IN_TEST: opts.testing,
PUBNUB_SUB_KEY: process.env.PUBNUB_SUB_KEY || '',
PUBNUB_PUB_KEY: process.env.PUBNUB_PUB_KEY || '',
}), {
diff --git a/mascara/src/app/buy-ether-widget/index.js b/mascara/src/app/buy-ether-widget/index.js
deleted file mode 100644
index d0d6ff343..000000000
--- a/mascara/src/app/buy-ether-widget/index.js
+++ /dev/null
@@ -1,198 +0,0 @@
-import React, { Component } from 'react'
-import PropTypes from 'prop-types'
-import classnames from 'classnames'
-import {connect} from 'react-redux'
-import {qrcode} from 'qrcode-generator'
-import copyToClipboard from 'copy-to-clipboard'
-import ShapeShiftForm from '../shapeshift-form'
-import {buyEth, showAccountDetail} from '../../../../ui/app/store/actions'
-
-const OPTION_VALUES = {
- COINBASE: 'coinbase',
- SHAPESHIFT: 'shapeshift',
- QR_CODE: 'qr_code',
-}
-
-const OPTIONS = [
- {
- name: 'Direct Deposit',
- value: OPTION_VALUES.QR_CODE,
- },
- {
- name: 'Buy with Dollars',
- value: OPTION_VALUES.COINBASE,
- },
- {
- name: 'Buy with Cryptos',
- value: OPTION_VALUES.SHAPESHIFT,
- },
-]
-
-class BuyEtherWidget extends Component {
-
- static propTypes = {
- address: PropTypes.string,
- skipText: PropTypes.string,
- className: PropTypes.string,
- onSkip: PropTypes.func,
- goToCoinbase: PropTypes.func,
- showAccountDetail: PropTypes.func,
- };
-
- state = {
- selectedOption: OPTION_VALUES.QR_CODE,
- };
-
-
- copyToClipboard = () => {
- const { address } = this.props
-
- this.setState({ justCopied: true }, () => copyToClipboard(address))
-
- setTimeout(() => this.setState({ justCopied: false }), 1000)
- }
-
- renderSkip () {
- const {showAccountDetail, address, skipText, onSkip} = this.props
-
- return (
- <div
- className="buy-ether__do-it-later"
- onClick={() => {
- if (onSkip) return onSkip()
- showAccountDetail(address)
- }}
- >
- {skipText || 'Do it later'}
- </div>
- )
- }
-
- renderCoinbaseLogo () {
- return (
- <svg width="140px" height="49px" viewBox="0 0 579 126" version="1.1">
- <g id="Page-1" stroke="none" strokeWidth={1} fill="none" fillRule="evenodd">
- <g id="Imported-Layers" fill="#0081C9">
- <path d="M37.752,125.873 C18.824,125.873 0.369,112.307 0.369,81.549 C0.369,50.79 18.824,37.382 37.752,37.382 C47.059,37.382 54.315,39.749 59.52,43.219 L53.841,55.68 C50.371,53.156 45.166,51.579 39.961,51.579 C28.604,51.579 18.193,60.57 18.193,81.391 C18.193,102.212 28.919,111.361 39.961,111.361 C45.166,111.361 50.371,109.783 53.841,107.26 L59.52,120.036 C54.157,123.664 47.059,125.873 37.752,125.873" id="Fill-1" />
- <path d="M102.898,125.873 C78.765,125.873 65.515,106.786 65.515,81.549 C65.515,56.311 78.765,37.382 102.898,37.382 C127.032,37.382 140.282,56.311 140.282,81.549 C140.282,106.786 127.032,125.873 102.898,125.873 L102.898,125.873 Z M102.898,51.105 C89.491,51.105 82.866,63.093 82.866,81.391 C82.866,99.688 89.491,111.834 102.898,111.834 C116.306,111.834 122.931,99.688 122.931,81.391 C122.931,63.093 116.306,51.105 102.898,51.105 L102.898,51.105 Z" id="Fill-2" />
- <path d="M163.468,23.659 C157.79,23.659 153.215,19.243 153.215,13.88 C153.215,8.517 157.79,4.1 163.468,4.1 C169.146,4.1 173.721,8.517 173.721,13.88 C173.721,19.243 169.146,23.659 163.468,23.659 L163.468,23.659 Z M154.793,39.118 L172.144,39.118 L172.144,124.138 L154.793,124.138 L154.793,39.118 Z" id="Fill-3" />
- <path d="M240.443,124.137 L240.443,67.352 C240.443,57.415 234.449,51.263 222.619,51.263 C216.31,51.263 210.473,52.367 207.003,53.787 L207.003,124.137 L189.81,124.137 L189.81,43.376 C198.328,39.906 209.212,37.382 222.461,37.382 C246.28,37.382 257.794,47.793 257.794,65.775 L257.794,124.137 L240.443,124.137" id="Fill-4" />
- <path d="M303.536,125.873 C292.494,125.873 281.611,123.191 274.986,119.879 L274.986,0.314 L292.179,0.314 L292.179,41.326 C296.28,39.433 302.905,37.856 308.741,37.856 C330.667,37.856 345.494,53.629 345.494,79.656 C345.494,111.676 328.931,125.873 303.536,125.873 L303.536,125.873 Z M305.744,51.263 C301.012,51.263 295.491,52.367 292.179,54.103 L292.179,109.941 C294.703,111.045 299.593,112.149 304.482,112.149 C318.205,112.149 328.301,102.685 328.301,80.918 C328.301,62.305 319.467,51.263 305.744,51.263 L305.744,51.263 Z" id="Fill-5" />
- <path d="M392.341,125.873 C367.892,125.873 355.589,115.935 355.589,99.215 C355.589,75.555 380.826,71.296 406.537,69.876 L406.537,64.513 C406.537,53.787 399.439,50.001 388.555,50.001 C380.511,50.001 370.731,52.525 365.053,55.207 L360.636,43.376 C367.419,40.379 378.933,37.382 390.29,37.382 C410.638,37.382 422.942,45.269 422.942,66.248 L422.942,119.879 C416.79,123.191 404.329,125.873 392.341,125.873 L392.341,125.873 Z M406.537,81.391 C389.186,82.337 371.835,83.757 371.835,98.9 C371.835,107.89 378.776,113.411 391.868,113.411 C397.389,113.411 403.856,112.465 406.537,111.203 L406.537,81.391 L406.537,81.391 Z" id="Fill-6" />
- <path d="M461.743,125.873 C451.806,125.873 441.395,123.191 435.244,119.879 L441.08,106.629 C445.496,109.31 454.803,112.149 461.27,112.149 C470.576,112.149 476.728,107.575 476.728,100.477 C476.728,92.748 470.261,89.751 461.586,86.596 C450.228,82.337 437.452,77.132 437.452,61.201 C437.452,47.162 448.336,37.382 467.264,37.382 C477.517,37.382 486.035,39.906 492.029,43.376 L486.665,55.364 C482.88,52.998 475.309,50.317 469.157,50.317 C460.166,50.317 455.118,55.049 455.118,61.201 C455.118,68.93 461.428,71.611 469.788,74.766 C481.618,79.183 494.71,84.072 494.71,100.635 C494.71,115.935 483.038,125.873 461.743,125.873" id="Fill-7" />
- <path d="M578.625,81.233 L522.155,89.12 C523.89,104.42 533.828,112.149 548.182,112.149 C556.699,112.149 565.848,110.099 571.684,106.944 L576.732,119.879 C570.107,123.349 558.75,125.873 547.078,125.873 C520.262,125.873 505.277,108.679 505.277,81.549 C505.277,55.522 519.789,37.382 543.607,37.382 C565.69,37.382 578.782,51.894 578.782,74.766 C578.782,76.816 578.782,79.025 578.625,81.233 L578.625,81.233 Z M543.292,50.001 C530.042,50.001 521.367,60.097 521.051,77.763 L562.22,72.084 C562.062,57.257 554.649,50.001 543.292,50.001 L543.292,50.001 Z" id="Fill-8" />
- </g>
- </g>
- </svg>
- )
- }
-
- renderCoinbaseForm () {
- const {goToCoinbase, address} = this.props
-
- return (
- <div className="buy-ether__action-content-wrapper">
- <div>{this.renderCoinbaseLogo()}</div>
- <div className="buy-ether__body-text">Coinbase is the world’s most popular way to buy and sell bitcoin, ethereum, and litecoin.</div>
- <a className="first-time-flow__link buy-ether__faq-link">What is Ethereum?</a>
- <div className="buy-ether__buttons">
- <button
- className="first-time-flow__button"
- onClick={() => goToCoinbase(address)}
- >
- Buy
- </button>
- </div>
- </div>
- )
- }
-
- renderContent () {
- const { address } = this.props
- const { justCopied } = this.state
- const qrImage = qrcode(4, 'M')
- qrImage.addData(address)
- qrImage.make()
-
- switch (this.state.selectedOption) {
- case OPTION_VALUES.COINBASE:
- return this.renderCoinbaseForm()
- case OPTION_VALUES.SHAPESHIFT:
- return (
- <div className="buy-ether__action-content-wrapper">
- <div className="shapeshift-logo" />
- <div className="buy-ether__body-text">
- Trade any leading blockchain asset for any other. Protection by Design. No Account Needed.
- </div>
- <ShapeShiftForm btnClass="first-time-flow__button" />
- </div>
- )
- case OPTION_VALUES.QR_CODE:
- return (
- <div className="buy-ether__action-content-wrapper">
- <div dangerouslySetInnerHTML={{ __html: qrImage.createTableTag(4) }} />
- <div className="buy-ether__body-text">Deposit Ether directly into your account.</div>
- <div className="buy-ether__small-body-text">(This is the account address that MetaMask created for you to recieve funds.)</div>
- <div className="buy-ether__buttons">
- <button
- className="first-time-flow__button"
- onClick={this.copyToClipboard}
- disabled={justCopied}
- >
- { justCopied ? 'Copied' : 'Copy' }
- </button>
- </div>
- </div>
- )
- default:
- return null
- }
- }
-
- render () {
- const { className = '' } = this.props
- const { selectedOption } = this.state
-
- return (
- <div className={`${className} buy-ether__content-wrapper`}>
- <div className="buy-ether__content-headline-wrapper">
- <div className="buy-ether__content-headline">Deposit Options</div>
- {this.renderSkip()}
- </div>
- <div className="buy-ether__content">
- <div className="buy-ether__side-panel">
- {OPTIONS.map(({ name, value }) => (
- <div
- key={value}
- className={classnames('buy-ether__side-panel-item', {
- 'buy-ether__side-panel-item--selected': value === selectedOption,
- })}
- onClick={() => this.setState({ selectedOption: value })}
- >
- <div className="buy-ether__side-panel-item-name">{name}</div>
- {value === selectedOption && (
- <svg viewBox="0 0 574 1024" id="si-ant-right" width="15px" height="15px">
- <path d="M10 9Q0 19 0 32t10 23l482 457L10 969Q0 979 0 992t10 23q10 9 24 9t24-9l506-480q10-10 10-23t-10-23L58 9Q48 0 34 0T10 9z" />
- </svg>
- )}
- </div>
- ))}
- </div>
- <div className="buy-ether__action-content">
- {this.renderContent()}
- </div>
- </div>
- </div>
- )
- }
-}
-
-export default connect(
- ({ metamask: { selectedAddress } }) => ({
- address: selectedAddress,
- }),
- dispatch => ({
- goToCoinbase: address => dispatch(buyEth({ network: '1', address, amount: 0 })),
- showAccountDetail: address => dispatch(showAccountDetail(address)),
- })
-)(BuyEtherWidget)
diff --git a/mascara/src/app/shapeshift-form/index.js b/mascara/src/app/shapeshift-form/index.js
deleted file mode 100644
index c044f9ecc..000000000
--- a/mascara/src/app/shapeshift-form/index.js
+++ /dev/null
@@ -1,218 +0,0 @@
-import React, { Component } from 'react'
-import PropTypes from 'prop-types'
-import classnames from 'classnames'
-import qrcode from 'qrcode-generator'
-import {connect} from 'react-redux'
-import {shapeShiftSubview, pairUpdate, buyWithShapeShift} from '../../../../ui/app/store/actions'
-import {isValidAddress} from '../../../../ui/app/helpers/utils/util'
-
-export class ShapeShiftForm extends Component {
- static propTypes = {
- selectedAddress: PropTypes.string.isRequired,
- btnClass: PropTypes.string.isRequired,
- tokenExchangeRates: PropTypes.object.isRequired,
- coinOptions: PropTypes.object.isRequired,
- shapeShiftSubview: PropTypes.func.isRequired,
- pairUpdate: PropTypes.func.isRequired,
- buyWithShapeShift: PropTypes.func.isRequired,
- };
-
- state = {
- depositCoin: 'btc',
- refundAddress: '',
- showQrCode: false,
- depositAddress: '',
- errorMessage: '',
- isLoading: false,
- };
-
- componentWillMount () {
- this.props.shapeShiftSubview()
- }
-
- onCoinChange = e => {
- const coin = e.target.value
- this.setState({
- depositCoin: coin,
- errorMessage: '',
- })
- this.props.pairUpdate(coin)
- }
-
- onBuyWithShapeShift = () => {
- 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: 'Invalid Request',
- isLoading: false,
- }))
- }
- }
-
- renderMetadata (label, value) {
- return (
- <div className="shapeshift-form__metadata-wrapper">
- <div className="shapeshift-form__metadata-label">
- {label}:
- </div>
- <div className="shapeshift-form__metadata-value">
- {value}
- </div>
- </div>
- )
- }
-
- renderMarketInfo () {
- const { depositCoin } = this.state
- const coinPair = `${depositCoin}_eth`
- const { tokenExchangeRates } = this.props
- const {
- limit,
- rate,
- minimum,
- } = tokenExchangeRates[coinPair] || {}
-
- return (
- <div className="shapeshift-form__metadata">
- {this.renderMetadata('Status', limit ? 'Available' : 'Unavailable')}
- {this.renderMetadata('Limit', limit)}
- {this.renderMetadata('Exchange Rate', rate)}
- {this.renderMetadata('Minimum', minimum)}
- </div>
- )
- }
-
- renderQrCode () {
- const { depositAddress, isLoading } = this.state
- const qrImage = qrcode(4, 'M')
- qrImage.addData(depositAddress)
- qrImage.make()
-
- return (
- <div className="shapeshift-form">
- <div className="shapeshift-form__deposit-instruction">
- Deposit your BTC to the address bellow:
- </div>
- <div className="shapeshift-form__qr-code">
- {isLoading
- ? <img src="images/loading.svg" style={{ width: '60px' }} />
- : <div dangerouslySetInnerHTML={{ __html: qrImage.createTableTag(4) }} />
- }
- </div>
- {this.renderMarketInfo()}
- </div>
- )
- }
-
- render () {
- const { coinOptions, btnClass } = this.props
- const { depositCoin, errorMessage, showQrCode } = this.state
- const coinPair = `${depositCoin}_eth`
- const { tokenExchangeRates } = this.props
- const token = tokenExchangeRates[coinPair]
-
- return showQrCode ? this.renderQrCode() : (
- <div>
- <div className="shapeshift-form">
- <div className="shapeshift-form__selectors">
- <div className="shapeshift-form__selector">
- <div className="shapeshift-form__selector-label">
- Deposit
- </div>
- <select
- className="shapeshift-form__selector-input"
- value={this.state.depositCoin}
- onChange={this.onCoinChange}
- >
- {Object.entries(coinOptions).map(([coin]) => (
- <option key={coin} value={coin.toLowerCase()}>
- {coin}
- </option>
- ))}
- </select>
- </div>
- <div
- className="icon shapeshift-form__caret"
- style={{ backgroundImage: 'url(images/caret-right.svg)'}}
- />
- <div className="shapeshift-form__selector">
- <div className="shapeshift-form__selector-label">
- Receive
- </div>
- <div className="shapeshift-form__selector-input">
- ETH
- </div>
- </div>
- </div>
- <div
- className={classnames('shapeshift-form__address-input-wrapper', {
- 'shapeshift-form__address-input-wrapper--error': errorMessage,
- })}
- >
- <div className="shapeshift-form__address-input-label">
- Your Refund Address
- </div>
- <input
- type="text"
- className="shapeshift-form__address-input"
- onChange={e => this.setState({
- refundAddress: e.target.value,
- errorMessage: '',
- })}
- />
- <div className="shapeshift-form__address-input-error-message">
- {errorMessage}
- </div>
- </div>
- {this.renderMarketInfo()}
- </div>
- <button
- className={btnClass}
- disabled={!token}
- onClick={this.onBuyWithShapeShift}
- >
- Buy
- </button>
- </div>
- )
- }
-}
-
-export default connect(
- ({ metamask: { coinOptions, tokenExchangeRates, selectedAddress } }) => ({
- coinOptions, tokenExchangeRates, selectedAddress,
- }),
- dispatch => ({
- shapeShiftSubview: () => dispatch(shapeShiftSubview()),
- pairUpdate: coin => dispatch(pairUpdate(coin)),
- buyWithShapeShift: data => dispatch(buyWithShapeShift(data)),
- })
-)(ShapeShiftForm)
diff --git a/notices/README.md b/notices/README.md
deleted file mode 100644
index 9362769c2..000000000
--- a/notices/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Notices
-
-Those notices are of legal nature. They are displayed to the users of MetaMask.
-
-Any changes or additions must be reviewed by the product management. \ No newline at end of file
diff --git a/notices/archive/notice_0.md b/notices/archive/notice_0.md
deleted file mode 100644
index c485edd1d..000000000
--- a/notices/archive/notice_0.md
+++ /dev/null
@@ -1,179 +0,0 @@
-# Terms of Use #
-
-**THIS AGREEMENT IS SUBJECT TO BINDING ARBITRATION AND A WAIVER OF CLASS ACTION RIGHTS AS DETAILED IN SECTION 13. PLEASE READ THE AGREEMENT CAREFULLY.**
-
-_Our Terms of Use have been updated as of September 5, 2016_
-
-## 1. Acceptance of Terms ##
-
-MetaMask provides a platform for managing Ethereum (or "ETH") accounts, and allowing ordinary websites to interact with the Ethereum blockchain, while keeping the user in control over what transactions they approve, through our website located at[ ](http://metamask.io)[https://metamask.io/](https://metamask.io/) and browser plugin (the "Site") — which includes text, images, audio, code and other materials (collectively, the “Content”) and all of the features, and services provided. The Site, and any other features, tools, materials, or other services offered from time to time by MetaMask are referred to here as the “Service.” Please read these Terms of Use (the “Terms” or “Terms of Use”) carefully before using the Service. By using or otherwise accessing the Services, or clicking to accept or agree to these Terms where that option is made available, you (1) accept and agree to these Terms (2) consent to the collection, use, disclosure and other handling of information as described in our Privacy Policy and (3) any additional terms, rules and conditions of participation issued by MetaMask from time to time. If you do not agree to the Terms, then you may not access or use the Content or Services.
-
-## 2. Modification of Terms of Use ##
-
-Except for Section 13, providing for binding arbitration and waiver of class action rights, MetaMask reserves the right, at its sole discretion, to modify or replace the Terms of Use at any time. The most current version of these Terms will be posted on our Site. You shall be responsible for reviewing and becoming familiar with any such modifications. Use of the Services by you after any modification to the Terms constitutes your acceptance of the Terms of Use as modified.
-
-
-
-## 3. Eligibility ##
-
-You hereby represent and warrant that you are fully able and competent to enter into the terms, conditions, obligations, affirmations, representations and warranties set forth in these Terms and to abide by and comply with these Terms.
-
-MetaMask is a global platform and by accessing the Content or Services, you are representing and warranting that, you are of the legal age of majority in your jurisdiction as is required to access such Services and Content and enter into arrangements as provided by the Service. You further represent that you are otherwise legally permitted to use the service in your jurisdiction including owning cryptographic tokens of value, and interacting with the Services or Content in any way. You further represent you are responsible for ensuring compliance with the laws of your jurisdiction and acknowledge that MetaMask is not liable for your compliance with such laws.
-
-## 4 Account Password and Security ##
-
-When setting up an account within MetaMask, you will be responsible for keeping your own account secrets, which may be a twelve-word seed phrase, an account file, or other locally stored secret information. MetaMask encrypts this information locally with a password you provide, that we never send to our servers. You agree to (a) never use the same password for MetaMask that you have ever used outside of this service; (b) keep your secret information and password confidential and do not share them with anyone else; (c) immediately notify MetaMask of any unauthorized use of your account or breach of security. MetaMask cannot and will not be liable for any loss or damage arising from your failure to comply with this section.
-
-## 5. Representations, Warranties, and Risks ##
-
-### 5.1. Warranty Disclaimer ###
-
-You expressly understand and agree that your use of the Service is at your sole risk. The Service (including the Service and the Content) are provided on an "AS IS" and "as available" basis, without warranties of any kind, either express or implied, including, without limitation, implied warranties of merchantability, fitness for a particular purpose or non-infringement. You acknowledge that MetaMask has no control over, and no duty to take any action regarding: which users gain access to or use the Service; what effects the Content may have on you; how you may interpret or use the Content; or what actions you may take as a result of having been exposed to the Content. You release MetaMask from all liability for you having acquired or not acquired Content through the Service. MetaMask makes no representations concerning any Content contained in or accessed through the Service, and MetaMask will not be responsible or liable for the accuracy, copyright compliance, legality or decency of material contained in or accessed through the Service.
-
-### 5.2 Sophistication and Risk of Cryptographic Systems ###
-
-By utilizing the Service or interacting with the Content or platform in any way, you represent that you understand the inherent risks associated with cryptographic systems; and warrant that you have an understanding of the usage and intricacies of native cryptographic tokens, like Ether (ETH) and Bitcoin (BTC), smart contract based tokens such as those that follow the Ethereum Token Standard (https://github.com/ethereum/EIPs/issues/20), and blockchain-based software systems.
-
-### 5.3 Risk of Regulatory Actions in One or More Jurisdictions ###
-
-MetaMask and ETH could be impacted by one or more regulatory inquiries or regulatory action, which could impede or limit the ability of MetaMask to continue to develop, or which could impede or limit your ability to access or use the Service or Ethereum blockchain.
-
-### 5.4 Risk of Weaknesses or Exploits in the Field of Cryptography ###
-
-You acknowledge and understand that Cryptography is a progressing field. Advances in code cracking or technical advances such as the development of quantum computers may present risks to cryptocurrencies and Services of Content, which could result in the theft or loss of your cryptographic tokens or property. To the extent possible, MetaMask intends to update the protocol underlying Services to account for any advances in cryptography and to incorporate additional security measures, but does not guarantee or otherwise represent full security of the system. By using the Service or accessing Content, you acknowledge these inherent risks.
-
-### 5.5 Volatility of Crypto Currencies ###
-
-You understand that Ethereum and other blockchain technologies and associated currencies or tokens are highly volatile due to many factors including but not limited to adoption, speculation, technology and security risks. You also acknowledge that the cost of transacting on such technologies is variable and may increase at any time causing impact to any activities taking place on the Ethereum blockchain. You acknowledge these risks and represent that MetaMask cannot be held liable for such fluctuations or increased costs.
-
-### 5.6 Application Security ###
-
-You acknowledge that Ethereum applications are code subject to flaws and acknowledge that you are solely responsible for evaluating any code provided by the Services or Content and the trustworthiness of any third-party websites, products, smart-contracts, or Content you access or use through the Service. You further expressly acknowledge and represent that Ethereum applications can be written maliciously or negligently, that MetaMask cannot be held liable for your interaction with such applications and that such applications may cause the loss of property or even identity. This warning and others later provided by MetaMask in no way evidence or represent an on-going duty to alert you to all of the potential risks of utilizing the Service or Content.
-
-## 6. Indemnity ##
-
-You agree to release and to indemnify, defend and hold harmless MetaMask and its parents, subsidiaries, affiliates and agencies, as well as the officers, directors, employees, shareholders and representatives of any of the foregoing entities, from and against any and all losses, liabilities, expenses, damages, costs (including attorneys’ fees and court costs) claims or actions of any kind whatsoever arising or resulting from your use of the Service, your violation of these Terms of Use, and any of your acts or omissions that implicate publicity rights, defamation or invasion of privacy. MetaMask reserves the right, at its own expense, to assume exclusive defense and control of any matter otherwise subject to indemnification by you and, in such case, you agree to cooperate with MetaMask in the defense of such matter.
-
-## 7. Limitation on liability ##
-
-YOU ACKNOWLEDGE AND AGREE THAT YOU ASSUME FULL RESPONSIBILITY FOR YOUR USE OF THE SITE AND SERVICE. YOU ACKNOWLEDGE AND AGREE THAT ANY INFORMATION YOU SEND OR RECEIVE DURING YOUR USE OF THE SITE AND SERVICE MAY NOT BE SECURE AND MAY BE INTERCEPTED OR LATER ACQUIRED BY UNAUTHORIZED PARTIES. YOU ACKNOWLEDGE AND AGREE THAT YOUR USE OF THE SITE AND SERVICE IS AT YOUR OWN RISK. RECOGNIZING SUCH, YOU UNDERSTAND AND AGREE THAT, TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, NEITHER METAMASK NOR ITS SUPPLIERS OR LICENSORS WILL BE LIABLE TO YOU FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY OR OTHER DAMAGES OF ANY KIND, INCLUDING WITHOUT LIMITATION DAMAGES FOR LOSS OF PROFITS, GOODWILL, USE, DATA OR OTHER TANGIBLE OR INTANGIBLE LOSSES OR ANY OTHER DAMAGES BASED ON CONTRACT, TORT, STRICT LIABILITY OR ANY OTHER THEORY (EVEN IF METAMASK HAD BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES), RESULTING FROM THE SITE OR SERVICE; THE USE OR THE INABILITY TO USE THE SITE OR SERVICE; UNAUTHORIZED ACCESS TO OR ALTERATION OF YOUR TRANSMISSIONS OR DATA; STATEMENTS OR CONDUCT OF ANY THIRD PARTY ON THE SITE OR SERVICE; ANY ACTIONS WE TAKE OR FAIL TO TAKE AS A RESULT OF COMMUNICATIONS YOU SEND TO US; HUMAN ERRORS; TECHNICAL MALFUNCTIONS; FAILURES, INCLUDING PUBLIC UTILITY OR TELEPHONE OUTAGES; OMISSIONS, INTERRUPTIONS, LATENCY, DELETIONS OR DEFECTS OF ANY DEVICE OR NETWORK, PROVIDERS, OR SOFTWARE (INCLUDING, BUT NOT LIMITED TO, THOSE THAT DO NOT PERMIT PARTICIPATION IN THE SERVICE); ANY INJURY OR DAMAGE TO COMPUTER EQUIPMENT; INABILITY TO FULLY ACCESS THE SITE OR SERVICE OR ANY OTHER WEBSITE; THEFT, TAMPERING, DESTRUCTION, OR UNAUTHORIZED ACCESS TO, IMAGES OR OTHER CONTENT OF ANY KIND; DATA THAT IS PROCESSED LATE OR INCORRECTLY OR IS INCOMPLETE OR LOST; TYPOGRAPHICAL, PRINTING OR OTHER ERRORS, OR ANY COMBINATION THEREOF; OR ANY OTHER MATTER RELATING TO THE SITE OR SERVICE.
-
-SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR THE LIMITATION OR EXCLUSION OF LIABILITY FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES. ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
-
-## 8. Our Proprietary Rights ##
-
-All title, ownership and intellectual property rights in and to the Service are owned by MetaMask or its licensors. You acknowledge and agree that the Service contains proprietary and confidential information that is protected by applicable intellectual property and other laws. Except as expressly authorized by MetaMask, you agree not to copy, modify, rent, lease, loan, sell, distribute, perform, display or create derivative works based on the Service, in whole or in part. MetaMask issues a license for MetaMask, found [here](https://github.com/MetaMask/metamask-plugin/blob/master/LICENSE). For information on other licenses utilized in the development of MetaMask, please see our attribution page at: [https://metamask.io/attributions.html](https://metamask.io/attributions.html)
-
-## 9. Links ##
-
-The Service provides, or third parties may provide, links to other World Wide Web or accessible sites, applications or resources. Because MetaMask has no control over such sites, applications and resources, you acknowledge and agree that MetaMask is not responsible for the availability of such external sites, applications or resources, and does not endorse and is not responsible or liable for any content, advertising, products or other materials on or available from such sites or resources. You further acknowledge and agree that MetaMask shall not be responsible or liable, directly or indirectly, for any damage or loss caused or alleged to be caused by or in connection with use of or reliance on any such content, goods or services available on or through any such site or resource.
-
-## 10. Termination and Suspension ##
-
-MetaMask may terminate or suspend all or part of the Service and your MetaMask access immediately, without prior notice or liability, if you breach any of the terms or conditions of the Terms. Upon termination of your access, your right to use the Service will immediately cease.
-
-The following provisions of the Terms survive any termination of these Terms: INDEMNITY; WARRANTY DISCLAIMERS; LIMITATION ON LIABILITY; OUR PROPRIETARY RIGHTS; LINKS; TERMINATION; NO THIRD PARTY BENEFICIARIES; BINDING ARBITRATION AND CLASS ACTION WAIVER; GENERAL INFORMATION.
-
-## 11. No Third Party Beneficiaries ##
-
-You agree that, except as otherwise expressly provided in these Terms, there shall be no third party beneficiaries to the Terms.
-
-## 12. Notice and Procedure For Making Claims of Copyright Infringement ##
-
-If you believe that your copyright or the copyright of a person on whose behalf you are authorized to act has been infringed, please provide MetaMask’s Copyright Agent a written Notice containing the following information:
-
-· an electronic or physical signature of the person authorized to act on behalf of the owner of the copyright or other intellectual property interest;
-
-· a description of the copyrighted work or other intellectual property that you claim has been infringed;
-
-· a description of where the material that you claim is infringing is located on the Service;
-
-· your address, telephone number, and email address;
-
-· a statement by you that you have a good faith belief that the disputed use is not authorized by the copyright owner, its agent, or the law;
-
-· a statement by you, made under penalty of perjury, that the above information in your Notice is accurate and that you are the copyright or intellectual property owner or authorized to act on the copyright or intellectual property owner's behalf.
-
-MetaMask’s Copyright Agent can be reached at:
-
-Email: copyright [at] metamask [dot] io
-
-Mail:
-
-Attention:
-
-MetaMask Copyright ℅ ConsenSys
-
-49 Bogart Street
-
-Brooklyn, NY 11206
-
-## 13. Binding Arbitration and Class Action Waiver ##
-
-PLEASE READ THIS SECTION CAREFULLY – IT MAY SIGNIFICANTLY AFFECT YOUR LEGAL RIGHTS, INCLUDING YOUR RIGHT TO FILE A LAWSUIT IN COURT
-
-### 13.1 Initial Dispute Resolution ###
-
-The parties shall use their best efforts to engage directly to settle any dispute, claim, question, or disagreement and engage in good faith negotiations which shall be a condition to either party initiating a lawsuit or arbitration.
-
-### 13.2 Binding Arbitration ###
-
-If the parties do not reach an agreed upon solution within a period of 30 days from the time informal dispute resolution under the Initial Dispute Resolution provision begins, then either party may initiate binding arbitration as the sole means to resolve claims, subject to the terms set forth below. Specifically, all claims arising out of or relating to these Terms (including their formation, performance and breach), the parties’ relationship with each other and/or your use of the Service shall be finally settled by binding arbitration administered by the American Arbitration Association in accordance with the provisions of its Commercial Arbitration Rules and the supplementary procedures for consumer related disputes of the American Arbitration Association (the "AAA"), excluding any rules or procedures governing or permitting class actions.
-
-The arbitrator, and not any federal, state or local court or agency, shall have exclusive authority to resolve all disputes arising out of or relating to the interpretation, applicability, enforceability or formation of these Terms, including, but not limited to any claim that all or any part of these Terms are void or voidable, or whether a claim is subject to arbitration. The arbitrator shall be empowered to grant whatever relief would be available in a court under law or in equity. The arbitrator’s award shall be written, and binding on the parties and may be entered as a judgment in any court of competent jurisdiction.
-
-The parties understand that, absent this mandatory provision, they would have the right to sue in court and have a jury trial. They further understand that, in some instances, the costs of arbitration could exceed the costs of litigation and the right to discovery may be more limited in arbitration than in court.
-
-### 13.3 Location ###
-
-Binding arbitration shall take place in New York. You agree to submit to the personal jurisdiction of any federal or state court in New York County, New York, in order to compel arbitration, to stay proceedings pending arbitration, or to confirm, modify, vacate or enter judgment on the award entered by the arbitrator.
-
-### 13.4 Class Action Waiver ###
-
-The parties further agree that any arbitration shall be conducted in their individual capacities only and not as a class action or other representative action, and the parties expressly waive their right to file a class action or seek relief on a class basis. YOU AND METAMASK AGREE THAT EACH MAY BRING CLAIMS AGAINST THE OTHER ONLY IN YOUR OR ITS INDIVIDUAL CAPACITY, AND NOT AS A PLAINTIFF OR CLASS MEMBER IN ANY PURPORTED CLASS OR REPRESENTATIVE PROCEEDING. If any court or arbitrator determines that the class action waiver set forth in this paragraph is void or unenforceable for any reason or that an arbitration can proceed on a class basis, then the arbitration provision set forth above shall be deemed null and void in its entirety and the parties shall be deemed to have not agreed to arbitrate disputes.
-
-### 13.5 Exception - Litigation of Intellectual Property and Small Claims Court Claims ###
-
-Notwithstanding the parties' decision to resolve all disputes through arbitration, either party may bring an action in state or federal court to protect its intellectual property rights ("intellectual property rights" means patents, copyrights, moral rights, trademarks, and trade secrets, but not privacy or publicity rights). Either party may also seek relief in a small claims court for disputes or claims within the scope of that court’s jurisdiction.
-
-### 13.6 30-Day Right to Opt Out ###
-
-You have the right to opt-out and not be bound by the arbitration and class action waiver provisions set forth above by sending written notice of your decision to opt-out to the following address: MetaMask ℅ ConsenSys, 49 Bogart Street, Brooklyn NY 11206 and via email at support@metamask.io. The notice must be sent within 30 days of September 6, 2016 or your first use of the Service, whichever is later, otherwise you shall be bound to arbitrate disputes in accordance with the terms of those paragraphs. If you opt-out of these arbitration provisions, MetaMask also will not be bound by them.
-
-### 13.7 Changes to This Section ###
-
-MetaMask will provide 60-days’ notice of any changes to this section. Changes will become effective on the 60th day, and will apply prospectively only to any claims arising after the 60th day.
-
-For any dispute not subject to arbitration you and MetaMask agree to submit to the personal and exclusive jurisdiction of and venue in the federal and state courts located in New York, New York. You further agree to accept service of process by mail, and hereby waive any and all jurisdictional and venue defenses otherwise available.
-
-The Terms and the relationship between you and MetaMask shall be governed by the laws of the State of New York without regard to conflict of law provisions.
-
-## 14. General Information ##
-
-### 14.1 Entire Agreement ###
-
-These Terms (and any additional terms, rules and conditions of participation that MetaMask may post on the Service) constitute the entire agreement between you and MetaMask with respect to the Service and supersedes any prior agreements, oral or written, between you and MetaMask. In the event of a conflict between these Terms and the additional terms, rules and conditions of participation, the latter will prevail over the Terms to the extent of the conflict.
-
-### 14.2 Waiver and Severability of Terms ###
-
-The failure of MetaMask to exercise or enforce any right or provision of the Terms shall not constitute a waiver of such right or provision. If any provision of the Terms is found by an arbitrator or court of competent jurisdiction to be invalid, the parties nevertheless agree that the arbitrator or court should endeavor to give effect to the parties' intentions as reflected in the provision, and the other provisions of the Terms remain in full force and effect.
-
-### 14.3 Statute of Limitations ###
-
-You agree that regardless of any statute or law to the contrary, any claim or cause of action arising out of or related to the use of the Service or the Terms must be filed within one (1) year after such claim or cause of action arose or be forever barred.
-
-### 14.4 Section Titles ###
-
-The section titles in the Terms are for convenience only and have no legal or contractual effect.
-
-### 14.5 Communications ###
-
-Users with questions, complaints or claims with respect to the Service may contact us using the relevant contact information set forth above and at communications@metamask.io.
-
-## 15 Related Links ##
-
-**[Terms of Use](https://metamask.io/terms.html)**
-
-**[Privacy](https://metamask.io/privacy.html)**
-
-**[Attributions](https://metamask.io/attributions.html)**
diff --git a/notices/archive/notice_2.md b/notices/archive/notice_2.md
deleted file mode 100644
index 8370f2ce2..000000000
--- a/notices/archive/notice_2.md
+++ /dev/null
@@ -1,6 +0,0 @@
-MetaMask is beta software.
-
-When you log in to MetaMask and approve account access, your current account's address is visible to the site you're currently viewing. This can be used to look up your account balances of Ether and other tokens.
-
-For your privacy, take caution when approving account access and sign out of MetaMask when you're done using a site.
-
diff --git a/notices/archive/notice_3.md b/notices/archive/notice_3.md
deleted file mode 100644
index 59dd0f5c7..000000000
--- a/notices/archive/notice_3.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Please take a moment to [back up your seed phrase again](https://support.metamask.io/kb/article/28-abbu-always-be-backed-up-how-to-make-sure-your-12-word-metamask-seed-phrase-is-backed-up).
-
-MetaMask has become aware of a previous issue where a very small number of users were shown the wrong seed phrase to back up. The only way to protect yourself from this issue, is to back up your seed phrase again now.
-
-You can follow the guide at this link:
-
-[https://support.metamask.io/kb/article/28-abbu-always-be-backed-up-how-to-make-sure-your-12-word-metamask-seed-phrase-is-backed-up](https://support.metamask.io/kb/article/28-abbu-always-be-backed-up-how-to-make-sure-your-12-word-metamask-seed-phrase-is-backed-up)
-
-We have fixed the known issue, but will be issuing ongoing bug bounties to help prevent this kind of problem in the future.
-
-For more information on this issue, [see this blog post](https://medium.com/metamask/seed-phrase-issue-bounty-awarded-e1986e811021)
diff --git a/notices/archive/notice_4.md b/notices/archive/notice_4.md
deleted file mode 100644
index 6493237cf..000000000
--- a/notices/archive/notice_4.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Dear MetaMask Users,
-
-There have been several instances of high-profile legitimate websites such as BTC Manager and Games Workshop that have had their websites temporarily compromised. This involves showing a fake MetaMask window on the page asking for user's seed phrases. MetaMask will never open itself to ask you for your seed phrase, and users are encouraged to report these instances immediately to either [our phishing blacklist](https://github.com/MetaMask/eth-phishing-detect/issues) or our support email at [support@metamask.io](mailto:support@metamask.io).
-
-[Please read our full article on this ongoing issue over at Medium.](https://medium.com/metamask/new-phishing-strategy-becoming-common-1b1123837168)
diff --git a/notices/notices.js b/notices/notices.js
deleted file mode 100644
index 6392b6381..000000000
--- a/notices/notices.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// fs.readFileSync is inlined by browserify transform "brfs"
-const fs = require('fs')
-const path = require('path')
-
-module.exports = [
- {
- id: 0,
- read: false,
- date: 'Thu Feb 09 2017',
- title: 'Terms of Use',
- body: fs.readFileSync(path.join(__dirname, '/archive', 'notice_0.md'), 'utf8'),
- },
- {
- id: 2,
- read: false,
- date: 'Mon May 08 2017',
- title: 'Privacy Notice',
- body: fs.readFileSync(path.join(__dirname, '/archive', 'notice_2.md'), 'utf8'),
- },
- {
- id: 3,
- read: false,
- date: 'Tue Nov 28 2017',
- title: 'Seed Phrase Alert',
- firstVersion: '<=3.12.0',
- body: fs.readFileSync(path.join(__dirname, '/archive', 'notice_3.md'), 'utf8'),
- },
- {
- id: 4,
- read: false,
- date: 'Wed Jun 13 2018',
- title: 'Phishing Warning',
- body: fs.readFileSync(path.join(__dirname, '/archive', 'notice_4.md'), 'utf8'),
- },
-]
diff --git a/package-lock.json b/package-lock.json
index d753a1e9e..11eab5718 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9759,8 +9759,8 @@
}
},
"eth-contract-metadata": {
- "version": "github:MetaMask/eth-contract-metadata#4d855fea9a5c899059134e03986be9d98e844270",
- "from": "github:MetaMask/eth-contract-metadata#master"
+ "version": "github:MetaMask/eth-contract-metadata#92e7d1442c7585bfd24e50a0fda78df11dedadfe",
+ "from": "github:MetaMask/eth-contract-metadata#92e7d1442c7585bfd24e50a0fda78df11dedadfe"
},
"eth-ens-namehash": {
"version": "2.0.8",
@@ -9796,7 +9796,7 @@
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"ethereumjs-util": "^5.1.1"
},
"dependencies": {
@@ -9849,7 +9849,7 @@
"dependencies": {
"babelify": {
"version": "7.3.0",
- "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
"integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
"requires": {
"babel-core": "^6.0.14",
@@ -9886,7 +9886,7 @@
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"ethereumjs-util": "^5.1.1"
},
"dependencies": {
@@ -9901,7 +9901,7 @@
}
},
"ethereumjs-abi": {
- "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
+ "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"requires": {
"bn.js": "^4.11.8",
@@ -10065,7 +10065,7 @@
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"dev": true,
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"ethereumjs-util": "^5.1.1"
},
"dependencies": {
@@ -10189,7 +10189,7 @@
}
},
"ethereumjs-abi": {
- "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
+ "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"requires": {
"bn.js": "^4.11.8",
@@ -10225,9 +10225,9 @@
}
},
"eth-ledger-bridge-keyring": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/eth-ledger-bridge-keyring/-/eth-ledger-bridge-keyring-0.1.1.tgz",
- "integrity": "sha512-EhClGSy5ixcd55yHGXoA3C7I8iFFi6kgSqvKOSj+5URtg5PYpHP8kv+KemFPOT1Px6se/IFHI9OIelUS8kN3lw==",
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eth-ledger-bridge-keyring/-/eth-ledger-bridge-keyring-0.2.0.tgz",
+ "integrity": "sha512-js8jhe5fIwnOib3ja8Nk8BWpwVYQreh+Hrq/0ry7iO26TH+SdH/gaBIJD2toyICIUYPYU9wpUw9RABsarxbNiQ==",
"requires": {
"eth-sig-util": "^1.4.2",
"ethereumjs-tx": "^1.3.4",
@@ -10241,18 +10241,8 @@
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#572d4bafe08a8a231137e1f9daeb0f8a23f197d2",
"ethereumjs-util": "^5.1.1"
- },
- "dependencies": {
- "ethereumjs-abi": {
- "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
- "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
- "requires": {
- "bn.js": "^4.10.0",
- "ethereumjs-util": "^5.0.0"
- }
- }
}
},
"ethereum-common": {
@@ -10261,11 +10251,27 @@
"integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8="
},
"ethereumjs-abi": {
- "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
+ "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#572d4bafe08a8a231137e1f9daeb0f8a23f197d2",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"requires": {
"bn.js": "^4.11.8",
"ethereumjs-util": "^6.0.0"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz",
+ "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "ethjs-util": "0.1.6",
+ "keccak": "^1.0.2",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1",
+ "secp256k1": "^3.0.1"
+ }
+ }
}
},
"ethereumjs-tx": {
@@ -10291,6 +10297,15 @@
"secp256k1": "^3.0.1"
}
},
+ "ethjs-util": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
+ "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+ "requires": {
+ "is-hex-prefixed": "1.0.0",
+ "strip-hex-prefix": "1.0.0"
+ }
+ },
"events": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
@@ -10484,7 +10499,7 @@
}
},
"ethereumjs-abi": {
- "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
+ "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"requires": {
"bn.js": "^4.11.8",
@@ -10661,9 +10676,9 @@
}
},
"eth-trezor-keyring": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/eth-trezor-keyring/-/eth-trezor-keyring-0.3.0.tgz",
- "integrity": "sha512-5mWY7A+52MAaUmMpciIET9lxdrYleFPFeVYCC7LWsA6Z/fT8+YPnKFRr6gmxF3yVk2Xk8YjSBN54/ujBv15Ogg==",
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/eth-trezor-keyring/-/eth-trezor-keyring-0.4.0.tgz",
+ "integrity": "sha512-7F+C1ztxZStLzmG6r/2/MxjSuxw0aU9T26unJ03fQslktKG9izP+dU2IAJUnWxnyej2ZkfcgcH9M1t32LFbK2A==",
"requires": {
"eth-sig-util": "^1.4.2",
"ethereumjs-tx": "^1.3.4",
@@ -10678,18 +10693,8 @@
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#572d4bafe08a8a231137e1f9daeb0f8a23f197d2",
"ethereumjs-util": "^5.1.1"
- },
- "dependencies": {
- "ethereumjs-abi": {
- "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
- "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
- "requires": {
- "bn.js": "^4.11.8",
- "ethereumjs-util": "^6.0.0"
- }
- }
}
},
"ethereum-common": {
@@ -10698,11 +10703,27 @@
"integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8="
},
"ethereumjs-abi": {
- "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
+ "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#572d4bafe08a8a231137e1f9daeb0f8a23f197d2",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"requires": {
"bn.js": "^4.11.8",
"ethereumjs-util": "^6.0.0"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz",
+ "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "ethjs-util": "0.1.6",
+ "keccak": "^1.0.2",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1",
+ "secp256k1": "^3.0.1"
+ }
+ }
}
},
"ethereumjs-tx": {
@@ -10728,6 +10749,15 @@
"secp256k1": "^3.0.1"
}
},
+ "ethjs-util": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
+ "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+ "requires": {
+ "is-hex-prefixed": "1.0.0",
+ "strip-hex-prefix": "1.0.0"
+ }
+ },
"events": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
@@ -10812,6 +10842,39 @@
}
}
},
+ "ethereumjs-abi": {
+ "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#572d4bafe08a8a231137e1f9daeb0f8a23f197d2",
+ "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "requires": {
+ "bn.js": "^4.11.8",
+ "ethereumjs-util": "^6.0.0"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz",
+ "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "ethjs-util": "0.1.6",
+ "keccak": "^1.0.2",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1",
+ "secp256k1": "^3.0.1"
+ }
+ },
+ "ethjs-util": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
+ "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+ "requires": {
+ "is-hex-prefixed": "1.0.0",
+ "strip-hex-prefix": "1.0.0"
+ }
+ }
+ }
+ },
"ethereumjs-util": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
@@ -10909,18 +10972,8 @@
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#572d4bafe08a8a231137e1f9daeb0f8a23f197d2",
"ethereumjs-util": "^5.1.1"
- },
- "dependencies": {
- "ethereumjs-abi": {
- "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
- "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
- "requires": {
- "bn.js": "^4.10.0",
- "ethereumjs-util": "^5.0.0"
- }
- }
}
},
"ethereumjs-util": {
@@ -13057,7 +13110,7 @@
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"dev": true,
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#572d4bafe08a8a231137e1f9daeb0f8a23f197d2",
"ethereumjs-util": "^5.1.1"
}
},
@@ -13209,7 +13262,7 @@
"integrity": "sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ==",
"dev": true,
"requires": {
- "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git",
+ "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934",
"crypto-js": "^3.1.4",
"utf8": "^2.1.1",
"xhr2-cookies": "^1.1.0",
@@ -13301,7 +13354,6 @@
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
"integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
"dev": true,
- "optional": true,
"requires": {
"mime-types": "~2.1.18",
"negotiator": "0.6.1"
@@ -13342,15 +13394,13 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
- "dev": true,
- "optional": true
+ "dev": true
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
- "dev": true,
- "optional": true
+ "dev": true
},
"asn1": {
"version": "0.2.4",
@@ -13366,7 +13416,6 @@
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
"integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
"dev": true,
- "optional": true,
"requires": {
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
@@ -14132,8 +14181,7 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
"integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
- "dev": true,
- "optional": true
+ "dev": true
},
"bcrypt-pbkdf": {
"version": "1.0.2",
@@ -14180,7 +14228,6 @@
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"dev": true,
- "optional": true,
"requires": {
"readable-stream": "^2.3.5",
"safe-buffer": "^5.1.1"
@@ -14214,7 +14261,6 @@
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
"integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
"dev": true,
- "optional": true,
"requires": {
"bytes": "3.0.0",
"content-type": "~1.0.4",
@@ -14233,7 +14279,6 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
- "optional": true,
"requires": {
"ms": "2.0.0"
}
@@ -14300,7 +14345,6 @@
"resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"dev": true,
- "optional": true,
"requires": {
"bn.js": "^4.1.0",
"randombytes": "^2.0.1"
@@ -14369,7 +14413,6 @@
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
"integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
"dev": true,
- "optional": true,
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
@@ -14380,7 +14423,6 @@
"resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
"integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
"dev": true,
- "optional": true,
"requires": {
"buffer-alloc-unsafe": "^1.1.0",
"buffer-fill": "^1.0.0"
@@ -14390,8 +14432,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
"integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
- "dev": true,
- "optional": true
+ "dev": true
},
"buffer-crc32": {
"version": "0.2.13",
@@ -14404,8 +14445,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
"integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
- "dev": true,
- "optional": true
+ "dev": true
},
"buffer-from": {
"version": "1.1.1",
@@ -14417,8 +14457,7 @@
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
"integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=",
- "dev": true,
- "optional": true
+ "dev": true
},
"buffer-xor": {
"version": "1.0.3",
@@ -14430,8 +14469,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
- "dev": true,
- "optional": true
+ "dev": true
},
"bytewise": {
"version": "1.1.0",
@@ -14580,7 +14618,6 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
"dev": true,
- "optional": true,
"requires": {
"graceful-readlink": ">= 1.0.0"
}
@@ -14607,15 +14644,13 @@
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
- "dev": true,
- "optional": true
+ "dev": true
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
- "dev": true,
- "optional": true
+ "dev": true
},
"convert-source-map": {
"version": "1.6.0",
@@ -14630,22 +14665,19 @@
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
- "dev": true,
- "optional": true
+ "dev": true
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
- "dev": true,
- "optional": true
+ "dev": true
},
"cookiejar": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
"integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
- "dev": true,
- "optional": true
+ "dev": true
},
"core-js": {
"version": "2.6.5",
@@ -14664,7 +14696,6 @@
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"dev": true,
- "optional": true,
"requires": {
"object-assign": "^4",
"vary": "^1"
@@ -14766,8 +14797,7 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
- "dev": true,
- "optional": true
+ "dev": true
},
"decompress": {
"version": "4.2.0",
@@ -14800,7 +14830,6 @@
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
"dev": true,
- "optional": true,
"requires": {
"mimic-response": "^1.0.0"
}
@@ -14810,7 +14839,6 @@
"resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
"integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
"dev": true,
- "optional": true,
"requires": {
"file-type": "^5.2.0",
"is-stream": "^1.1.0",
@@ -14951,8 +14979,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
- "dev": true,
- "optional": true
+ "dev": true
},
"des.js": {
"version": "1.0.0",
@@ -14969,8 +14996,7 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
- "dev": true,
- "optional": true
+ "dev": true
},
"detect-indent": {
"version": "4.0.0",
@@ -15014,8 +15040,7 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
- "dev": true,
- "optional": true
+ "dev": true
},
"ecc-jsbn": {
"version": "0.1.2",
@@ -15031,8 +15056,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
- "dev": true,
- "optional": true
+ "dev": true
},
"electron-to-chromium": {
"version": "1.3.113",
@@ -15059,8 +15083,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
- "dev": true,
- "optional": true
+ "dev": true
},
"encoding": {
"version": "0.1.12",
@@ -15159,8 +15182,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
- "dev": true,
- "optional": true
+ "dev": true
},
"escape-string-regexp": {
"version": "1.0.5",
@@ -15178,8 +15200,7 @@
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
- "dev": true,
- "optional": true
+ "dev": true
},
"eth-block-tracker": {
"version": "3.0.1",
@@ -15264,7 +15285,6 @@
"resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz",
"integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==",
"dev": true,
- "optional": true,
"requires": {
"bn.js": "^4.11.6",
"elliptic": "^6.4.0",
@@ -15348,7 +15368,7 @@
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"dev": true,
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"ethereumjs-util": "^5.1.1"
}
},
@@ -15715,7 +15735,6 @@
"resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
"integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
"dev": true,
- "optional": true,
"requires": {
"bn.js": "4.11.6",
"number-to-bn": "1.7.0"
@@ -15725,8 +15744,7 @@
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -15744,8 +15762,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz",
"integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA=",
- "dev": true,
- "optional": true
+ "dev": true
},
"events": {
"version": "3.0.0",
@@ -15768,7 +15785,6 @@
"resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
"integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
"dev": true,
- "optional": true,
"requires": {
"accepts": "~1.3.5",
"array-flatten": "1.1.1",
@@ -15807,7 +15823,6 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
- "optional": true,
"requires": {
"ms": "2.0.0"
}
@@ -15816,8 +15831,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -15889,8 +15903,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
"integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
- "dev": true,
- "optional": true
+ "dev": true
},
"file-uri-to-path": {
"version": "1.0.0",
@@ -15903,7 +15916,6 @@
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"dev": true,
- "optional": true,
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
@@ -15919,7 +15931,6 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
- "optional": true,
"requires": {
"ms": "2.0.0"
}
@@ -15928,8 +15939,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -15973,29 +15983,25 @@
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
- "dev": true,
- "optional": true
+ "dev": true
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
- "dev": true,
- "optional": true
+ "dev": true
},
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
- "dev": true,
- "optional": true
+ "dev": true
},
"fs-extra": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz",
"integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=",
"dev": true,
- "optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^2.1.0"
@@ -16504,7 +16510,6 @@
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
"integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
"dev": true,
- "optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
@@ -16534,8 +16539,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
- "dev": true,
- "optional": true
+ "dev": true
},
"getpass": {
"version": "0.1.7",
@@ -16581,7 +16585,6 @@
"resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
"integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
"dev": true,
- "optional": true,
"requires": {
"decompress-response": "^3.2.0",
"duplexer3": "^0.1.4",
@@ -16609,8 +16612,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
- "dev": true,
- "optional": true
+ "dev": true
},
"har-schema": {
"version": "2.0.0",
@@ -16650,8 +16652,7 @@
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
"integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
- "dev": true,
- "optional": true
+ "dev": true
},
"has-symbols": {
"version": "1.0.0",
@@ -16664,7 +16665,6 @@
"resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
"integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
"dev": true,
- "optional": true,
"requires": {
"has-symbol-support-x": "^1.4.1"
}
@@ -16739,7 +16739,6 @@
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"dev": true,
- "optional": true,
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
@@ -16751,8 +16750,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
"integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=",
- "dev": true,
- "optional": true
+ "dev": true
},
"http-signature": {
"version": "1.2.0",
@@ -16778,8 +16776,7 @@
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz",
"integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==",
- "dev": true,
- "optional": true
+ "dev": true
},
"immediate": {
"version": "3.2.3",
@@ -16822,8 +16819,7 @@
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
"integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=",
- "dev": true,
- "optional": true
+ "dev": true
},
"is-arrayish": {
"version": "0.2.1",
@@ -16890,15 +16886,13 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
"integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
- "dev": true,
- "optional": true
+ "dev": true
},
"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=",
- "dev": true,
- "optional": true
+ "dev": true
},
"is-regex": {
"version": "1.0.4",
@@ -16913,8 +16907,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
"integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
- "dev": true,
- "optional": true
+ "dev": true
},
"is-stream": {
"version": "1.1.0",
@@ -16960,7 +16953,6 @@
"resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
"integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
"dev": true,
- "optional": true,
"requires": {
"has-to-string-tag-x": "^1.2.0",
"is-object": "^1.0.1"
@@ -17344,8 +17336,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
- "dev": true,
- "optional": true
+ "dev": true
},
"lru-cache": {
"version": "3.2.0",
@@ -17396,8 +17387,7 @@
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
- "dev": true,
- "optional": true
+ "dev": true
},
"memdown": {
"version": "1.4.1",
@@ -17434,8 +17424,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
- "dev": true,
- "optional": true
+ "dev": true
},
"merkle-patricia-tree": {
"version": "2.3.1",
@@ -17495,8 +17484,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
- "dev": true,
- "optional": true
+ "dev": true
},
"miller-rabin": {
"version": "4.0.1",
@@ -17513,8 +17501,7 @@
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
- "dev": true,
- "optional": true
+ "dev": true
},
"mime-db": {
"version": "1.38.0",
@@ -17535,8 +17522,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
- "dev": true,
- "optional": true
+ "dev": true
},
"min-document": {
"version": "2.19.0",
@@ -17634,15 +17620,13 @@
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
"integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=",
- "dev": true,
- "optional": true
+ "dev": true
},
"negotiator": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
- "dev": true,
- "optional": true
+ "dev": true
},
"node-fetch": {
"version": "2.1.2",
@@ -17673,7 +17657,6 @@
"resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
"integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
"dev": true,
- "optional": true,
"requires": {
"bn.js": "4.11.6",
"strip-hex-prefix": "1.0.0"
@@ -17683,8 +17666,7 @@
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -17717,7 +17699,6 @@
"resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz",
"integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=",
"dev": true,
- "optional": true,
"requires": {
"http-https": "^1.0.0"
}
@@ -17727,7 +17708,6 @@
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"dev": true,
- "optional": true,
"requires": {
"ee-first": "1.1.1"
}
@@ -17766,22 +17746,19 @@
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
"integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
- "dev": true,
- "optional": true
+ "dev": true
},
"p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
- "dev": true,
- "optional": true
+ "dev": true
},
"p-timeout": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
"integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
"dev": true,
- "optional": true,
"requires": {
"p-finally": "^1.0.0"
}
@@ -17791,7 +17768,6 @@
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz",
"integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==",
"dev": true,
- "optional": true,
"requires": {
"asn1.js": "^4.0.0",
"browserify-aes": "^1.0.0",
@@ -17824,8 +17800,7 @@
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
- "dev": true,
- "optional": true
+ "dev": true
},
"path-exists": {
"version": "2.1.0",
@@ -17852,8 +17827,7 @@
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
- "dev": true,
- "optional": true
+ "dev": true
},
"path-type": {
"version": "1.1.0",
@@ -17925,8 +17899,7 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
- "dev": true,
- "optional": true
+ "dev": true
},
"private": {
"version": "0.1.8",
@@ -17961,7 +17934,6 @@
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
"integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
"dev": true,
- "optional": true,
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.8.0"
@@ -18075,7 +18047,6 @@
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
"integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
"dev": true,
- "optional": true,
"requires": {
"decode-uri-component": "^0.2.0",
"object-assign": "^4.1.0",
@@ -18106,22 +18077,19 @@
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz",
"integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=",
- "dev": true,
- "optional": true
+ "dev": true
},
"range-parser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
- "dev": true,
- "optional": true
+ "dev": true
},
"raw-body": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
"integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
"dev": true,
- "optional": true,
"requires": {
"bytes": "3.0.0",
"http-errors": "1.6.3",
@@ -18439,7 +18407,6 @@
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
"integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
"dev": true,
- "optional": true,
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
@@ -18461,7 +18428,6 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
- "optional": true,
"requires": {
"ms": "2.0.0"
}
@@ -18470,8 +18436,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -18480,7 +18445,6 @@
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
"integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
"dev": true,
- "optional": true,
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
@@ -18493,7 +18457,6 @@
"resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
"integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
"dev": true,
- "optional": true,
"requires": {
"body-parser": "^1.16.0",
"cors": "^2.8.1",
@@ -18525,8 +18488,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
- "dev": true,
- "optional": true
+ "dev": true
},
"sha.js": {
"version": "2.4.11",
@@ -18551,15 +18513,13 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
"integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=",
- "dev": true,
- "optional": true
+ "dev": true
},
"simple-get": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
"integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
"dev": true,
- "optional": true,
"requires": {
"decompress-response": "^3.3.0",
"once": "^1.3.1",
@@ -18641,8 +18601,7 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
- "dev": true,
- "optional": true
+ "dev": true
},
"stream-to-pull-stream": {
"version": "1.7.2",
@@ -18666,8 +18625,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
- "dev": true,
- "optional": true
+ "dev": true
},
"string-width": {
"version": "1.0.2",
@@ -18808,7 +18766,6 @@
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
"integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
"dev": true,
- "optional": true,
"requires": {
"bl": "^1.0.0",
"buffer-alloc": "^1.2.0",
@@ -18847,7 +18804,6 @@
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz",
"integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=",
"dev": true,
- "optional": true,
"requires": {
"any-promise": "^1.0.0"
}
@@ -18857,7 +18813,6 @@
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
"integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
"dev": true,
- "optional": true,
"requires": {
"thenify": ">= 3.1.0 < 4"
}
@@ -18882,8 +18837,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
"integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
- "dev": true,
- "optional": true
+ "dev": true
},
"tmp": {
"version": "0.0.33",
@@ -18898,8 +18852,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
"integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
- "dev": true,
- "optional": true
+ "dev": true
},
"to-fast-properties": {
"version": "1.0.3",
@@ -18957,7 +18910,6 @@
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
"dev": true,
- "optional": true,
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.18"
@@ -19003,8 +18955,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
- "dev": true,
- "optional": true
+ "dev": true
},
"unbzip2-stream": {
"version": "1.3.3",
@@ -19021,8 +18972,7 @@
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=",
- "dev": true,
- "optional": true
+ "dev": true
},
"unorm": {
"version": "1.5.0",
@@ -19034,8 +18984,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
- "dev": true,
- "optional": true
+ "dev": true
},
"uri-js": {
"version": "4.2.2",
@@ -19051,7 +19000,6 @@
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
"integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
"dev": true,
- "optional": true,
"requires": {
"prepend-http": "^1.0.1"
}
@@ -19060,15 +19008,13 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
"integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=",
- "dev": true,
- "optional": true
+ "dev": true
},
"url-to-options": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
"integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
- "dev": true,
- "optional": true
+ "dev": true
},
"utf8": {
"version": "3.0.0",
@@ -19087,8 +19033,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
- "dev": true,
- "optional": true
+ "dev": true
},
"uuid": {
"version": "3.3.2",
@@ -19110,8 +19055,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
- "dev": true,
- "optional": true
+ "dev": true
},
"verror": {
"version": "1.10.0",
@@ -19157,7 +19101,6 @@
"resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.35.tgz",
"integrity": "sha512-ayGavbgVk4KL9Y88Uv411fBJ0SVgVfKhKEBweKYzmP0zOqneMzWt6YsyD1n6kRvjAbqA0AfUPEOKyMNjcx2tjw==",
"dev": true,
- "optional": true,
"requires": {
"web3-core-helpers": "1.0.0-beta.35",
"web3-core-method": "1.0.0-beta.35",
@@ -19170,7 +19113,6 @@
"resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.35.tgz",
"integrity": "sha512-APOu3sEsamyqWt//8o4yq9KF25/uqGm+pQShson/sC4gKzmfJB07fLo2ond0X30E8fIqAPeVCotPXQxGciGUmA==",
"dev": true,
- "optional": true,
"requires": {
"underscore": "1.8.3",
"web3-eth-iban": "1.0.0-beta.35",
@@ -19182,7 +19124,6 @@
"resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.35.tgz",
"integrity": "sha512-jidImCide8q0GpfsO4L73qoHrbkeWgwU3uOH5DKtJtv0ccmG086knNMRgryb/o9ZgetDWLmDEsJnHjBSoIwcbA==",
"dev": true,
- "optional": true,
"requires": {
"underscore": "1.8.3",
"web3-core-helpers": "1.0.0-beta.35",
@@ -19196,7 +19137,6 @@
"resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.35.tgz",
"integrity": "sha512-GvqXqKq07OmHuVi5uNRg6k79a1/CI0ViCC+EtNv4CORHtDRmYEt5Bvdv6z6FJEiaaQkD0lKbFwNhLxutx7HItw==",
"dev": true,
- "optional": true,
"requires": {
"any-promise": "1.3.0",
"eventemitter3": "1.1.1"
@@ -19207,7 +19147,6 @@
"resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.35.tgz",
"integrity": "sha512-S+zW2h17ZZQU9oe3yaCJE0E7aJS4C3Kf4kGPDv+nXjW0gKhQQhgVhw1Doq/aYQGqNSWJp7f1VHkz5gQWwg6RRg==",
"dev": true,
- "optional": true,
"requires": {
"underscore": "1.8.3",
"web3-core-helpers": "1.0.0-beta.35",
@@ -19221,7 +19160,6 @@
"resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.35.tgz",
"integrity": "sha512-gXzLrWvcGkGiWq1y33Z4Y80XI8XMrwowiQJkrPSjQ81K5PBKquOGwcMffLaKcwdmEy/NpsOXDeFo3eLE1Ghvvw==",
"dev": true,
- "optional": true,
"requires": {
"eventemitter3": "1.1.1",
"underscore": "1.8.3",
@@ -19254,7 +19192,6 @@
"resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.35.tgz",
"integrity": "sha512-KUDC+EtFFYG8z01ZleKrASdjj327/rtWHzEt6RWsEj7bBa0bGp9nEh+nqdZx/Sdgz1O8tnfFzJlrRcXpfr1vGg==",
"dev": true,
- "optional": true,
"requires": {
"bn.js": "4.11.6",
"underscore": "1.8.3",
@@ -19266,8 +19203,7 @@
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -19344,7 +19280,6 @@
"resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.35.tgz",
"integrity": "sha512-H5wkcNcAIc+h/WoDIKv7ZYmrM2Xqu3O7jBQl1IWo73EDVQji+AoB2i3J8tuwI1yZRInRwrfpI3Zuwuf54hXHmQ==",
"dev": true,
- "optional": true,
"requires": {
"bn.js": "4.11.6",
"web3-utils": "1.0.0-beta.35"
@@ -19354,8 +19289,7 @@
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -19364,7 +19298,6 @@
"resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.35.tgz",
"integrity": "sha512-AcM9nnlxu7ZRRxPvkrFB9eLxMM4A2cPfj2aCg21Wb2EpMnhR+b/O1cT33k7ApRowoMpM+T9M8vx2oPNwXfaCOQ==",
"dev": true,
- "optional": true,
"requires": {
"web3-core": "1.0.0-beta.35",
"web3-core-helpers": "1.0.0-beta.35",
@@ -19378,7 +19311,6 @@
"resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.35.tgz",
"integrity": "sha512-bbwaQ/KohGjIJ6HAKbZ6KrklCAaG6/B7hIbAbVLSFLxF+Yz9lmAgQYaDInpidpC/NLb3WOmcbRF+P77J4qMVIA==",
"dev": true,
- "optional": true,
"requires": {
"web3-core": "1.0.0-beta.35",
"web3-core-method": "1.0.0-beta.35",
@@ -19419,7 +19351,7 @@
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"dev": true,
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"ethereumjs-util": "^5.1.1"
}
},
@@ -19467,7 +19399,6 @@
"resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.0.0-beta.35.tgz",
"integrity": "sha512-DcIMFq52Fb08UpWyZ3ZlES6NsNqJnco4hBS/Ej6eOcASfuUayPI+GLkYVZsnF3cBYqlH+DOKuArcKSuIxK7jIA==",
"dev": true,
- "optional": true,
"requires": {
"web3-core-helpers": "1.0.0-beta.35",
"xhr2-cookies": "1.1.0"
@@ -19478,7 +19409,6 @@
"resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.35.tgz",
"integrity": "sha512-iB0FG0HcpUnayfa8pn4guqEQ4Y1nrroi/jffdtQgFkrNt0sD3fMSwwC0AbmECqj3tDLl0e1slBR0RENll+ZF0g==",
"dev": true,
- "optional": true,
"requires": {
"oboe": "2.1.3",
"underscore": "1.8.3",
@@ -19490,11 +19420,10 @@
"resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.35.tgz",
"integrity": "sha512-Cx64NgDStynKaUGDIIOfaCd0fZusL8h5avKTkdTjUu2aHhFJhZoVBGVLhoDtUaqZGWIZGcBJOoVf2JkGUOjDRQ==",
"dev": true,
- "optional": true,
"requires": {
"underscore": "1.8.3",
"web3-core-helpers": "1.0.0-beta.35",
- "websocket": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible"
+ "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2"
},
"dependencies": {
"debug": {
@@ -19502,7 +19431,6 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
- "optional": true,
"requires": {
"ms": "2.0.0"
}
@@ -19511,7 +19439,6 @@
"version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2",
"from": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible",
"dev": true,
- "optional": true,
"requires": {
"debug": "^2.2.0",
"nan": "^2.3.3",
@@ -19539,7 +19466,6 @@
"resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.35.tgz",
"integrity": "sha512-Dq6f0SOKj3BDFRgOPnE6ALbzBDCKVIW8mKWVf7tGVhTDHf+wQaWwQSC3aArFSqdExB75BPBPyDpuMTNszhljpA==",
"dev": true,
- "optional": true,
"requires": {
"bn.js": "4.11.6",
"eth-lib": "0.1.27",
@@ -19554,15 +19480,13 @@
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
- "dev": true,
- "optional": true
+ "dev": true
},
"utf8": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz",
"integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -19628,7 +19552,6 @@
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
"dev": true,
- "optional": true,
"requires": {
"async-limiter": "~1.0.0",
"safe-buffer": "~5.1.0",
@@ -19652,7 +19575,6 @@
"resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
"integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
"dev": true,
- "optional": true,
"requires": {
"buffer-to-arraybuffer": "^0.0.5",
"object-assign": "^4.1.1",
@@ -19668,7 +19590,6 @@
"resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz",
"integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=",
"dev": true,
- "optional": true,
"requires": {
"xhr-request": "^1.0.1"
}
@@ -19678,7 +19599,6 @@
"resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz",
"integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=",
"dev": true,
- "optional": true,
"requires": {
"cookiejar": "^2.1.1"
}
@@ -24076,7 +23996,7 @@
"dependencies": {
"babelify": {
"version": "7.3.0",
- "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
"integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
"requires": {
"babel-core": "^6.0.14",
@@ -24115,7 +24035,7 @@
},
"babelify": {
"version": "7.3.0",
- "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
"integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
"requires": {
"babel-core": "^6.0.14",
@@ -26541,7 +26461,7 @@
"dependencies": {
"babelify": {
"version": "7.3.0",
- "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
"integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
"requires": {
"babel-core": "^6.0.14",
@@ -27467,8 +27387,7 @@
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "optional": true
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"tar": {
"version": "4.4.6",
@@ -27488,8 +27407,7 @@
"yallist": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
- "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
- "optional": true
+ "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k="
}
}
},
@@ -27736,7 +27654,6 @@
"resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
"integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
"dev": true,
- "optional": true,
"requires": {
"kind-of": "^3.0.2",
"longest": "^1.0.1",
@@ -28115,8 +28032,7 @@
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true,
- "optional": true
+ "dev": true
},
"is-builtin-module": {
"version": "1.0.0",
@@ -28212,7 +28128,6 @@
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
- "optional": true,
"requires": {
"is-buffer": "^1.1.5"
}
@@ -28255,8 +28170,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
"integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
- "dev": true,
- "optional": true
+ "dev": true
},
"lru-cache": {
"version": "4.1.3",
@@ -28486,8 +28400,7 @@
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
- "dev": true,
- "optional": true
+ "dev": true
},
"require-directory": {
"version": "2.1.1",
@@ -37697,9 +37610,9 @@
"integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A=="
},
"trezor-connect": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/trezor-connect/-/trezor-connect-7.0.1.tgz",
- "integrity": "sha512-cMPwSGMfBpp4z5AZvpRwbYNOJU/X+WaxPm+O1Bl1qsdtpl1P4mX81KDtImY6GBk0xC8aKyOd/ZIqYWXZF9tCRQ==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/trezor-connect/-/trezor-connect-7.0.2.tgz",
+ "integrity": "sha512-KAFOqxEHHaFvrG8NGLFlM/QxHcwIa3gwfXcgTjCYM0g0zRpwIQBwe35AKsjAQO5yiTJQGa0Cu5MZufGJRGYjjw==",
"requires": {
"@babel/runtime": "^7.3.1",
"events": "^3.0.0",
@@ -37707,11 +37620,11 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.3.4",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.4.tgz",
- "integrity": "sha512-IvfvnMdSaLBateu0jfsYIpZTxAc2cKEXEMiezGGN75QcBcecDUKd3PgLAncT0oOgxKy8dd8hrJKj9MfzgfZd6g==",
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.3.tgz",
+ "integrity": "sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==",
"requires": {
- "regenerator-runtime": "^0.12.0"
+ "regenerator-runtime": "^0.13.2"
}
},
"events": {
@@ -37720,9 +37633,9 @@
"integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA=="
},
"regenerator-runtime": {
- "version": "0.12.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
- "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
+ "version": "0.13.2",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz",
+ "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA=="
},
"whatwg-fetch": {
"version": "3.0.0",
@@ -38858,7 +38771,7 @@
"resolved": "https://registry.npmjs.org/web3/-/web3-0.20.3.tgz",
"integrity": "sha1-yqRDc9yIFayHZ73ba6cwc5ZMqos=",
"requires": {
- "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git",
+ "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934",
"crypto-js": "^3.1.4",
"utf8": "^2.1.1",
"xhr2": "*",
@@ -38929,12 +38842,12 @@
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"dev": true,
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"ethereumjs-util": "^5.1.1"
}
},
"ethereumjs-abi": {
- "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#572d4bafe08a8a231137e1f9daeb0f8a23f197d2",
+ "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"dev": true,
"requires": {
diff --git a/package.json b/package.json
index 873d53222..884c77387 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,8 @@
"dist": "gulp dist",
"doc": "jsdoc -c development/tools/.jsdoc.json",
"publish-docs": "gh-pages -d docs/jsdocs",
+ "start:test": "gulp dev:test",
+ "build:test": "gulp build:test",
"test": "npm run test:unit && npm run test:integration && npm run lint",
"watch:test:unit": "nodemon --exec \"npm run test:unit\" ./test ./app ./ui",
"test:unit": "cross-env METAMASK_ENV=test mocha --exit --require test/setup.js --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\"",
@@ -80,19 +82,19 @@
"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#master",
+ "eth-contract-metadata": "github:MetaMask/eth-contract-metadata#92e7d1442c7585bfd24e50a0fda78df11dedadfe",
"eth-ens-namehash": "^2.0.8",
"eth-hd-keyring": "^1.2.2",
"eth-json-rpc-filters": "^3.0.1",
"eth-json-rpc-infura": "^3.0.0",
"eth-keyring-controller": "^3.3.1",
- "eth-ledger-bridge-keyring": "^0.1.1",
+ "eth-ledger-bridge-keyring": "^0.2.0",
"eth-method-registry": "^1.0.0",
"eth-phishing-detect": "^1.1.4",
"eth-query": "^2.1.2",
"eth-sig-util": "^2.0.2",
"eth-token-tracker": "^1.1.5",
- "eth-trezor-keyring": "^0.3.0",
+ "eth-trezor-keyring": "^0.4.0",
"ethereumjs-abi": "^0.6.4",
"ethereumjs-tx": "^1.3.0",
"ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
diff --git a/test/e2e/beta/from-import-beta-ui.spec.js b/test/e2e/beta/from-import-beta-ui.spec.js
index 8aa0fb628..a913caa79 100644
--- a/test/e2e/beta/from-import-beta-ui.spec.js
+++ b/test/e2e/beta/from-import-beta-ui.spec.js
@@ -24,8 +24,8 @@ describe('Using MetaMask with an existing account', function () {
let extensionId
let driver
- const testSeedPhrase = 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent'
- const testAddress = '0xE18035BF8712672935FDB4e5e431b1a0183d2DFC'
+ const testSeedPhrase = 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress'
+ const testAddress = '0x0Cc5261AB8cE458dc977078A3623E2BaDD27afD3'
const testPrivateKey2 = '14abe6f4aab7f9f626fe981c864d0adeb5685f289ac9270c27b8fd790b4235d6'
const regularDelayMs = 1000
const largeDelayMs = regularDelayMs * 2
@@ -76,7 +76,18 @@ describe('Using MetaMask with an existing account', function () {
'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.metametrics + '\')) }); } else if ' +
'(args[0] === "https://dev.blockscale.net/api/gasexpress.json") { return ' +
'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.gasExpress + '\')) }); } ' +
- 'return window.origFetch(...args); }'
+ 'return window.origFetch(...args); };' +
+ 'function cancelInfuraRequest(requestDetails) {' +
+ 'console.log("Canceling: " + requestDetails.url);' +
+ 'return {' +
+ 'cancel: true' +
+ '};' +
+ ' }' +
+ 'window.chrome && window.chrome.webRequest && window.chrome.webRequest.onBeforeRequest.addListener(' +
+ 'cancelInfuraRequest,' +
+ '{urls: ["https://*.infura.io/*"]},' +
+ '["blocking"]' +
+ ');'
)
})
@@ -301,7 +312,7 @@ describe('Using MetaMask with an existing account', function () {
it('should show the correct account name', async () => {
const [accountName] = await findElements(driver, By.css('.account-name'))
- assert.equal(await accountName.getText(), 'Account 3')
+ assert.equal(await accountName.getText(), 'Account 4')
await delay(regularDelayMs)
})
diff --git a/test/e2e/beta/metamask-beta-responsive-ui.spec.js b/test/e2e/beta/metamask-beta-responsive-ui.spec.js
index 6df1da051..b1ed8536e 100644
--- a/test/e2e/beta/metamask-beta-responsive-ui.spec.js
+++ b/test/e2e/beta/metamask-beta-responsive-ui.spec.js
@@ -75,7 +75,18 @@ describe('MetaMask', function () {
'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.metametrics + '\')) }); } else if ' +
'(args[0] === "https://dev.blockscale.net/api/gasexpress.json") { return ' +
'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.gasExpress + '\')) }); } ' +
- 'return window.origFetch(...args); }'
+ 'return window.origFetch(...args); };' +
+ 'function cancelInfuraRequest(requestDetails) {' +
+ 'console.log("Canceling: " + requestDetails.url);' +
+ 'return {' +
+ 'cancel: true' +
+ '};' +
+ ' }' +
+ 'window.chrome && window.chrome.webRequest && window.chrome.webRequest.onBeforeRequest.addListener(' +
+ 'cancelInfuraRequest,' +
+ '{urls: ["https://*.infura.io/*"]},' +
+ '["blocking"]' +
+ ');'
)
})
diff --git a/test/e2e/beta/metamask-beta-ui.spec.js b/test/e2e/beta/metamask-beta-ui.spec.js
index e25b7edf1..05ad84f24 100644
--- a/test/e2e/beta/metamask-beta-ui.spec.js
+++ b/test/e2e/beta/metamask-beta-ui.spec.js
@@ -80,7 +80,18 @@ describe('MetaMask', function () {
'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.metametrics + '\')) }); } else if ' +
'(args[0] === "https://dev.blockscale.net/api/gasexpress.json") { return ' +
'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.gasExpress + '\')) }); } ' +
- 'return window.origFetch(...args); }'
+ 'return window.origFetch(...args); };' +
+ 'function cancelInfuraRequest(requestDetails) {' +
+ 'console.log("Canceling: " + requestDetails.url);' +
+ 'return {' +
+ 'cancel: true' +
+ '};' +
+ ' }' +
+ 'window.chrome && window.chrome.webRequest && window.chrome.webRequest.onBeforeRequest.addListener(' +
+ 'cancelInfuraRequest,' +
+ '{urls: ["https://*.infura.io/*"]},' +
+ '["blocking"]' +
+ ');'
)
})
@@ -223,26 +234,6 @@ describe('MetaMask', function () {
})
})
- describe('Enable privacy mode', () => {
- it('enables privacy mode', async () => {
- const networkDropdown = await findElement(driver, By.css('.network-name'))
- await networkDropdown.click()
- await delay(regularDelayMs)
-
- const customRpcButton = await findElement(driver, By.xpath(`//span[contains(text(), 'Custom RPC')]`))
- await customRpcButton.click()
- await delay(regularDelayMs)
-
- const securityTab = await findElement(driver, By.xpath(`//div[contains(text(), 'Security & Privacy')]`))
- await securityTab.click()
- await delay(regularDelayMs)
-
- const privacyToggle = await findElement(driver, By.css('.settings-page__content-row:nth-of-type(1) .settings-page__content-item-col > div'))
- await privacyToggle.click()
- await delay(largeDelayMs * 2)
- })
- })
-
describe('Log out an log back in', () => {
it('logs out of the account', async () => {
await driver.findElement(By.css('.account-menu__icon')).click()
@@ -318,16 +309,6 @@ describe('MetaMask', function () {
await delay(regularDelayMs)
})
- it('switches to localhost', async () => {
- const networkDropdown = await findElement(driver, By.css('.network-name'))
- await networkDropdown.click()
- await delay(regularDelayMs)
-
- const [localhost] = await findElements(driver, By.xpath(`//span[contains(text(), 'Localhost')]`))
- await localhost.click()
- await delay(largeDelayMs * 2)
- })
-
it('balance renders', async () => {
const balance = await findElement(driver, By.css('.balance-display .token-amount'))
await driver.wait(until.elementTextMatches(balance, /100\s*ETH/))
@@ -531,14 +512,22 @@ describe('MetaMask', function () {
await assertElementNotPresent(webdriver, driver, By.xpath(`//li[contains(text(), 'Data')]`))
const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-gas-inputs__gas-edit-row__input'))
- await gasPriceInput.clear()
- await delay(tinyDelayMs)
+ await gasPriceInput.sendKeys(Key.chord(Key.CONTROL, 'a'))
+ await delay(50)
+
await gasPriceInput.sendKeys(Key.BACK_SPACE)
+ await delay(50)
await gasPriceInput.sendKeys(Key.BACK_SPACE)
+ await delay(50)
await gasPriceInput.sendKeys('10')
+ await delay(50)
await delay(tinyDelayMs)
- await gasLimitInput.sendKeys('5')
+ await delay(50)
+ await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'a'))
+ await delay(50)
+
+ await gasLimitInput.sendKeys('25000')
await delay(tinyDelayMs)
const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`), 10000)
@@ -553,8 +542,10 @@ describe('MetaMask', function () {
let txValues
it('finds the transaction in the transactions list', async function () {
- const transactions = await findElements(driver, By.css('.transaction-list-item'))
- assert.equal(transactions.length, 4)
+ await driver.wait(async () => {
+ const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item'))
+ return confirmedTxes.length === 4
+ }, 10000)
txValues = await findElements(driver, By.css('.transaction-list-item__amount--primary'))
await driver.wait(until.elementTextMatches(txValues[0], /-3\s*ETH/), 10000)
@@ -611,9 +602,16 @@ describe('MetaMask', function () {
await driver.switchTo().window(extension)
await delay(regularDelayMs)
- const transactions = await findElements(driver, By.css('.transaction-list-item'))
+ let transactions = await findElements(driver, By.css('.transaction-list-item'))
await transactions[3].click()
await delay(regularDelayMs)
+ try {
+ transactions = await findElements(driver, By.css('.transaction-list-item'), 1000)
+ await transactions[3].click()
+ } catch (e) {
+ console.log(e)
+ }
+ await delay(regularDelayMs)
})
it('navigates the transactions', async () => {
@@ -1019,7 +1017,9 @@ describe('MetaMask', function () {
const confirmDataDiv = await findElement(driver, By.css('.confirm-page-container-content__data-box'))
const confirmDataText = await confirmDataDiv.getText()
- assert.equal(confirmDataText.match(/0xa9059cbb0000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97/))
+
+ await delay(regularDelayMs)
+ assert(confirmDataText.match(/0xa9059cbb0000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97/))
const detailsTab = await findElement(driver, By.xpath(`//li[contains(text(), 'Details')]`))
detailsTab.click()
@@ -1050,8 +1050,7 @@ describe('MetaMask', function () {
return confirmedTxes.length === 1
}, 10000)
const txStatuses = await findElements(driver, By.css('.transaction-list-item__action'))
- const tx = await driver.wait(until.elementTextMatches(txStatuses[0], /Sent\sToken|Failed/), 10000)
- assert.equal(await tx.getText(), 'Sent Tokens')
+ await driver.wait(until.elementTextMatches(txStatuses[0], /Sent\sToken/i), 10000)
})
})
@@ -1061,7 +1060,6 @@ describe('MetaMask', function () {
const windowHandles = await driver.getAllWindowHandles()
const extension = windowHandles[0]
const dapp = await switchToWindowWithTitle(driver, 'E2E Test Dapp', windowHandles)
- await closeAllWindowHandlesExcept(driver, [extension, dapp])
await delay(regularDelayMs)
await driver.switchTo().window(dapp)
@@ -1070,7 +1068,6 @@ describe('MetaMask', function () {
const transferTokens = await findElement(driver, By.xpath(`//button[contains(text(), 'Transfer Tokens')]`))
await transferTokens.click()
- await closeAllWindowHandlesExcept(driver, [extension, dapp])
await driver.switchTo().window(extension)
await delay(largeDelayMs)
@@ -1094,23 +1091,31 @@ describe('MetaMask', function () {
await delay(regularDelayMs)
const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-tab__gas-edit-row__input'))
- await gasPriceInput.clear()
- await delay(tinyDelayMs)
+ await gasPriceInput.sendKeys(Key.chord(Key.CONTROL, 'a'))
+ await delay(50)
await gasPriceInput.sendKeys(Key.BACK_SPACE)
+ await delay(50)
await gasPriceInput.sendKeys(Key.BACK_SPACE)
+ await delay(50)
await gasPriceInput.sendKeys('10')
- await delay(tinyDelayMs)
- await gasLimitInput.clear()
- await delay(tinyDelayMs)
+ await delay(50)
await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'a'))
+ await delay(50)
await gasLimitInput.sendKeys(Key.BACK_SPACE)
+ await delay(50)
await gasLimitInput.sendKeys(Key.BACK_SPACE)
+ await delay(50)
await gasLimitInput.sendKeys(Key.BACK_SPACE)
+ await delay(50)
await gasLimitInput.sendKeys(Key.BACK_SPACE)
+ await delay(50)
await gasLimitInput.sendKeys(Key.BACK_SPACE)
+ await delay(50)
await gasLimitInput.sendKeys('60000')
+ await delay(50)
await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'e'))
+ await delay(50)
const save = await findElement(driver, By.css('.page-container__footer-button'))
await save.click()
@@ -1197,7 +1202,7 @@ describe('MetaMask', function () {
const confirmDataDiv = await findElement(driver, By.css('.confirm-page-container-content__data-box'))
const confirmDataText = await confirmDataDiv.getText()
- assert.equal(confirmDataText.match(/0x095ea7b30000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97/))
+ assert(confirmDataText.match(/0x095ea7b30000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97/))
const detailsTab = await findElement(driver, By.xpath(`//li[contains(text(), 'Details')]`))
detailsTab.click()
@@ -1320,10 +1325,10 @@ describe('MetaMask', function () {
describe('Stores custom RPC history', () => {
const customRpcUrls = [
- 'https://mainnet.infura.io/1',
- 'https://mainnet.infura.io/2',
- 'https://mainnet.infura.io/3',
- 'https://mainnet.infura.io/4',
+ 'http://127.0.0.1:8545/1',
+ 'http://127.0.0.1:8545/2',
+ 'http://127.0.0.1:8545/3',
+ 'http://127.0.0.1:8545/4',
]
customRpcUrls.forEach(customRpcUrl => {
@@ -1362,7 +1367,7 @@ describe('MetaMask', function () {
await delay(regularDelayMs)
// only recent 3 are found and in correct order (most recent at the top)
- const customRpcs = await findElements(driver, By.xpath(`//span[contains(text(), 'https://mainnet.infura.io/')]`))
+ const customRpcs = await findElements(driver, By.xpath(`//span[contains(text(), 'http://127.0.0.1:8545/')]`))
assert.equal(customRpcs.length, customRpcUrls.length)
})
diff --git a/test/e2e/beta/run-all.sh b/test/e2e/beta/run-all.sh
index f2705da4c..685feab00 100755
--- a/test/e2e/beta/run-all.sh
+++ b/test/e2e/beta/run-all.sh
@@ -8,4 +8,5 @@ export PATH="$PATH:./node_modules/.bin"
shell-parallel -s 'npm run ganache:start -- -b 2' -x 'sleep 5 && static-server test/e2e/beta/contract-test --port 8080' -x 'sleep 5 && mocha test/e2e/beta/metamask-beta-ui.spec'
shell-parallel -s 'npm run ganache:start -- -b 2' -x 'sleep 5 && static-server test/e2e/beta/contract-test --port 8080' -x 'sleep 5 && mocha test/e2e/beta/metamask-beta-responsive-ui.spec'
-shell-parallel -s 'npm run ganache:start -- -d -b 2' -x 'sleep 5 && mocha test/e2e/beta/from-import-beta-ui.spec'
+shell-parallel -s 'npm run ganache:start -- -d -b 2 --account=0x53CB0AB5226EEBF4D872113D98332C1555DC304443BEE1CF759D15798D3C55A9,25000000000000000000' \
+ -x 'sleep 5 && mocha test/e2e/beta/from-import-beta-ui.spec'
diff --git a/test/unit/app/controllers/notice-controller-test.js b/test/unit/app/controllers/notice-controller-test.js
deleted file mode 100644
index 834c88f7b..000000000
--- a/test/unit/app/controllers/notice-controller-test.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const assert = require('assert')
-const NoticeController = require('../../../../app/scripts/notice-controller')
-
-describe('notice-controller', function () {
- var noticeController
-
- beforeEach(function () {
- noticeController = new NoticeController()
- })
-
- describe('notices', function () {
-
- describe('#setNoticesList', function () {
- it('should set data appropriately', function (done) {
- var testList = [{
- id: 0,
- read: false,
- title: 'Futuristic Notice',
- }]
- noticeController.setNoticesList(testList)
- var testListId = noticeController.getNoticesList()[0].id
- assert.equal(testListId, 0)
- done()
- })
- })
-
- describe('#markNoticeRead', function () {
- it('should mark a notice as read', function (done) {
- var testList = [{
- id: 0,
- read: false,
- title: 'Futuristic Notice',
- }]
- noticeController.setNoticesList(testList)
- noticeController.markNoticeRead(testList[0])
- var newList = noticeController.getNoticesList()
- assert.ok(newList[0].read)
- done()
- })
- })
-
- describe('#getNextUnreadNotice', function () {
- it('should retrieve the latest unread notice', function (done) {
- var testList = [
- {id: 0, read: true, title: 'Past Notice'},
- {id: 1, read: false, title: 'Current Notice'},
- {id: 2, read: false, title: 'Future Notice'},
- ]
- noticeController.setNoticesList(testList)
- var latestUnread = noticeController.getNextUnreadNotice()
- assert.equal(latestUnread.id, 1)
- done()
- })
- it('should return undefined if no unread notices exist.', function (done) {
- var testList = [
- {id: 0, read: true, title: 'Past Notice'},
- {id: 1, read: true, title: 'Current Notice'},
- {id: 2, read: true, title: 'Future Notice'},
- ]
- noticeController.setNoticesList(testList)
- var latestUnread = noticeController.getNextUnreadNotice()
- assert.ok(!latestUnread)
- done()
- })
- })
- })
-})
diff --git a/test/unit/app/nodeify-test.js b/test/unit/app/nodeify-test.js
index 938b76c68..fa5e49fb2 100644
--- a/test/unit/app/nodeify-test.js
+++ b/test/unit/app/nodeify-test.js
@@ -2,16 +2,16 @@ const assert = require('assert')
const nodeify = require('../../../app/scripts/lib/nodeify')
describe('nodeify', function () {
- var obj = {
+ const obj = {
foo: 'bar',
promiseFunc: function (a) {
- var solution = this.foo + a
+ const solution = this.foo + a
return Promise.resolve(solution)
},
}
it('should retain original context', function (done) {
- var nodified = nodeify(obj.promiseFunc, obj)
+ const nodified = nodeify(obj.promiseFunc, obj)
nodified('baz', function (err, res) {
if (!err) {
assert.equal(res, 'barbaz')
@@ -22,7 +22,7 @@ describe('nodeify', function () {
})
})
- it('should allow the last argument to not be a function', function (done) {
+ it('no callback - should allow the last argument to not be a function', function (done) {
const nodified = nodeify(obj.promiseFunc, obj)
try {
nodified('baz')
@@ -31,4 +31,45 @@ describe('nodeify', function () {
done(new Error('should not have thrown if the last argument is not a function'))
}
})
+
+ it('no callback - should asyncly throw an error if underlying function does', function (done) {
+ const nodified = nodeify(async () => { throw new Error('boom!') }, obj)
+ process.prependOnceListener('uncaughtException', function (err) {
+ assert.ok(err, 'got expected error')
+ assert.ok(err.message.includes('boom!'), 'got expected error message')
+ done()
+ })
+ try {
+ nodified('baz')
+ } catch (err) {
+ done(new Error('should not have thrown an error synchronously'))
+ }
+ })
+
+ it('sync functions - returns value', function (done) {
+ const nodified = nodeify(() => 42)
+ try {
+ nodified((err, result) => {
+ if (err) return done(new Error(`should not have thrown any error: ${err.message}`))
+ assert.equal(42, result, 'got expected result')
+ })
+ done()
+ } catch (err) {
+ done(new Error(`should not have thrown any error: ${err.message}`))
+ }
+ })
+
+ it('sync functions - handles errors', function (done) {
+ const nodified = nodeify(() => { throw new Error('boom!') })
+ try {
+ nodified((err, result) => {
+ if (result) return done(new Error('should not have returned any result'))
+ assert.ok(err, 'got expected error')
+ assert.ok(err.message.includes('boom!'), 'got expected error message')
+ })
+ done()
+ } catch (err) {
+ done(new Error(`should not have thrown any error: ${err.message}`))
+ }
+ })
})
diff --git a/test/unit/migrations/033-test.js b/test/unit/migrations/033-test.js
new file mode 100644
index 000000000..b111198fd
--- /dev/null
+++ b/test/unit/migrations/033-test.js
@@ -0,0 +1,40 @@
+const assert = require('assert')
+const migration33 = require('../../../app/scripts/migrations/033')
+
+describe('Migration to delete notice controller', () => {
+ const oldStorage = {
+ 'meta': {},
+ 'data': {
+ 'NoticeController': {
+ 'noticesList': [
+ {
+ id: 0,
+ read: false,
+ date: 'Thu Feb 09 2017',
+ title: 'Terms of Use',
+ body: 'notice body',
+ },
+ {
+ id: 2,
+ read: false,
+ title: 'Privacy Notice',
+ body: 'notice body',
+ },
+ {
+ id: 4,
+ read: false,
+ title: 'Phishing Warning',
+ body: 'notice body',
+ },
+ ],
+ },
+ },
+ }
+
+ it('removes notice controller from state', () => {
+ migration33.migrate(oldStorage)
+ .then(newStorage => {
+ assert.equal(newStorage.data.NoticeController, undefined)
+ })
+ })
+})
diff --git a/test/unit/ui/app/actions.spec.js b/test/unit/ui/app/actions.spec.js
index 46e94bb32..86c3f8aff 100644
--- a/test/unit/ui/app/actions.spec.js
+++ b/test/unit/ui/app/actions.spec.js
@@ -1031,52 +1031,6 @@ describe('Actions', () => {
})
})
- describe('#markNoticeRead', () => {
- let markNoticeReadSpy
- const notice = {
- id: 0,
- read: false,
- date: 'test date',
- title: 'test title',
- body: 'test body',
- }
-
- beforeEach(() => {
- markNoticeReadSpy = sinon.stub(background, 'markNoticeRead')
- })
-
- afterEach(() => {
- markNoticeReadSpy.restore()
- })
-
- it('calls markNoticeRead in background', () => {
- const store = mockStore()
-
- store.dispatch(actions.markNoticeRead(notice))
- .then(() => {
- assert(markNoticeReadSpy.calledOnce)
- })
-
- })
-
- it('errors when markNoticeRead in background throws', () => {
- const store = mockStore()
- const expectedActions = [
- { type: 'SHOW_LOADING_INDICATION', value: undefined },
- { type: 'HIDE_LOADING_INDICATION' },
- { type: 'DISPLAY_WARNING', value: 'error' },
- ]
- markNoticeReadSpy.callsFake((notice, callback) => {
- callback(new Error('error'))
- })
-
- store.dispatch(actions.markNoticeRead())
- .catch(() => {
- assert.deepEqual(store.getActions(), expectedActions)
- })
- })
- })
-
describe('#setProviderType', () => {
let setProviderTypeSpy
let store
@@ -1308,6 +1262,25 @@ describe('Actions', () => {
})
})
+ describe('#setCompletedOnboarding', () => {
+ let completeOnboardingSpy
+
+ beforeEach(() => {
+ completeOnboardingSpy = sinon.stub(background, 'completeOnboarding')
+ completeOnboardingSpy.callsFake(cb => cb())
+ })
+
+ after(() => {
+ completeOnboardingSpy.restore()
+ })
+
+ it('completes onboarding', async () => {
+ const store = mockStore()
+ await store.dispatch(actions.setCompletedOnboarding())
+ assert.equal(completeOnboardingSpy.callCount, 1)
+ })
+ })
+
describe('#updateNetworkNonce', () => {
let getTransactionCountSpy
diff --git a/test/unit/ui/app/reducers/app.spec.js b/test/unit/ui/app/reducers/app.spec.js
index 6c77e0ef9..09cf3dbf0 100644
--- a/test/unit/ui/app/reducers/app.spec.js
+++ b/test/unit/ui/app/reducers/app.spec.js
@@ -445,15 +445,6 @@ describe('App State', () => {
assert.equal(state.forgottenPassword, false)
})
- it('shows notice', () => {
- const state = reduceApp(metamaskState, {
- type: actions.SHOW_NOTICE,
- })
-
- assert.equal(state.transForward, true)
- assert.equal(state.isLoading, false)
- })
-
it('reveals account', () => {
const state = reduceApp(metamaskState, {
type: actions.REVEAL_ACCOUNT,
diff --git a/test/unit/ui/app/reducers/metamask.spec.js b/test/unit/ui/app/reducers/metamask.spec.js
index 388c67c76..d7876bf39 100644
--- a/test/unit/ui/app/reducers/metamask.spec.js
+++ b/test/unit/ui/app/reducers/metamask.spec.js
@@ -35,49 +35,6 @@ describe('MetaMask Reducers', () => {
assert.equal(state.isRevealingSeedWords, false)
})
- it('shows notice', () => {
- const notice = {
- id: 0,
- read: false,
- date: 'Date',
- title: 'Title',
- body: 'Body',
- }
-
- const state = reduceMetamask({}, {
- type: actions.SHOW_NOTICE,
- value: notice,
- })
-
- assert.equal(state.noActiveNotices, false)
- assert.equal(state.nextUnreadNotice, notice)
- })
-
- it('clears notice', () => {
-
- const notice = {
- id: 0,
- read: false,
- date: 'Date',
- title: 'Title',
- body: 'Body',
- }
-
- const noticesState = {
- metamask: {
- noActiveNotices: false,
- nextUnreadNotice: notice,
- },
- }
-
- const state = reduceMetamask(noticesState, {
- type: actions.CLEAR_NOTICES,
- })
-
- assert.equal(state.noActiveNotices, true)
- assert.equal(state.nextUnreadNotice, null)
- })
-
it('unlocks MetaMask', () => {
const state = reduceMetamask({}, {
type: actions.UNLOCK_METAMASK,
diff --git a/ui/app/components/app/account-dropdowns.js b/ui/app/components/app/account-dropdowns.js
deleted file mode 100644
index e02d17e54..000000000
--- a/ui/app/components/app/account-dropdowns.js
+++ /dev/null
@@ -1,338 +0,0 @@
-const Component = require('react').Component
-const PropTypes = require('prop-types')
-const h = require('react-hyperscript')
-const actions = require('../../store/actions')
-const genAccountLink = require('etherscan-link').createAccountLink
-const connect = require('react-redux').connect
-const Dropdown = require('./dropdown').Dropdown
-const DropdownMenuItem = require('./dropdown').DropdownMenuItem
-const copyToClipboard = require('copy-to-clipboard')
-const { checksumAddress } = require('../../helpers/utils/util')
-
-import Identicon from '../ui/identicon'
-
-class AccountDropdowns extends Component {
- constructor (props) {
- super(props)
- this.state = {
- accountSelectorActive: false,
- optionsMenuActive: false,
- }
- this.accountSelectorToggleClassName = 'accounts-selector'
- this.optionsMenuToggleClassName = 'fa-ellipsis-h'
- }
-
- renderAccounts () {
- const { identities, selected, keyrings } = this.props
-
- return Object.keys(identities).map((key, index) => {
- const identity = identities[key]
- const isSelected = identity.address === selected
-
- const simpleAddress = identity.address.substring(2).toLowerCase()
-
- const keyring = keyrings.find((kr) => {
- return kr.accounts.includes(simpleAddress) ||
- kr.accounts.includes(identity.address)
- })
-
- return h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => {
- this.props.actions.showAccountDetail(identity.address)
- },
- style: {
- marginTop: index === 0 ? '5px' : '',
- fontSize: '24px',
- },
- },
- [
- h(
- Identicon,
- {
- address: identity.address,
- diameter: 32,
- style: {
- marginLeft: '10px',
- },
- },
- ),
- this.indicateIfLoose(keyring),
- h('span', {
- style: {
- marginLeft: '20px',
- fontSize: '24px',
- maxWidth: '145px',
- whiteSpace: 'nowrap',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- },
- }, identity.name || ''),
- h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, isSelected ? h('.check', '✓') : null),
- ]
- )
- })
- }
-
- indicateIfLoose (keyring) {
- try { // Sometimes keyrings aren't loaded yet:
- const type = keyring.type
- const isLoose = type !== 'HD Key Tree'
- return isLoose ? h('.keyring-label.allcaps', this.context.t('loose')) : null
- } catch (e) { return }
- }
-
- renderAccountSelector () {
- const { actions } = this.props
- const { accountSelectorActive } = this.state
-
- return h(
- Dropdown,
- {
- useCssTransition: true, // Hardcoded because account selector is temporarily in app-header
- style: {
- marginLeft: '-238px',
- marginTop: '38px',
- minWidth: '180px',
- overflowY: 'auto',
- maxHeight: '300px',
- width: '300px',
- },
- innerStyle: {
- padding: '8px 25px',
- },
- isOpen: accountSelectorActive,
- onClickOutside: (event) => {
- const { classList } = event.target
- const isNotToggleElement = !classList.contains(this.accountSelectorToggleClassName)
- if (accountSelectorActive && isNotToggleElement) {
- this.setState({ accountSelectorActive: false })
- }
- },
- },
- [
- ...this.renderAccounts(),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => actions.addNewAccount(),
- },
- [
- h(
- Identicon,
- {
- style: {
- marginLeft: '10px',
- },
- diameter: 32,
- },
- ),
- h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, this.context.t('createAccount')),
- ],
- ),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => actions.showImportPage(),
- },
- [
- h(
- Identicon,
- {
- style: {
- marginLeft: '10px',
- },
- diameter: 32,
- },
- ),
- h('span', {
- style: {
- marginLeft: '20px',
- fontSize: '24px',
- marginBottom: '5px',
- },
- }, this.context.t('importAccount')),
- ]
- ),
- ]
- )
- }
-
- renderAccountOptions () {
- const { actions } = this.props
- const { optionsMenuActive } = this.state
-
- return h(
- Dropdown,
- {
- style: {
- marginLeft: '-215px',
- minWidth: '180px',
- },
- isOpen: optionsMenuActive,
- onClickOutside: (event) => {
- const { classList } = event.target
- const isNotToggleElement = !classList.contains(this.optionsMenuToggleClassName)
- if (optionsMenuActive && isNotToggleElement) {
- this.setState({ optionsMenuActive: false })
- }
- },
- },
- [
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => {
- const { selected, network } = this.props
- const url = genAccountLink(selected, network)
- global.platform.openWindow({ url })
- },
- },
- this.context.t('etherscanView'),
- ),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => {
- const { selected, identities } = this.props
- var identity = identities[selected]
- actions.showQrView(selected, identity ? identity.name : '')
- },
- },
- this.context.t('showQRCode'),
- ),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => {
- const { selected } = this.props
- copyToClipboard(checksumAddress(selected))
- },
- },
- this.context.t('copyAddress'),
- ),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => {
- actions.requestAccountExport()
- },
- },
- this.context.t('exportPrivateKey'),
- ),
- ]
- )
- }
-
- render () {
- const { metricsEvent } = this.context
- const { style, enableAccountsSelector, enableAccountOptions } = this.props
- const { optionsMenuActive, accountSelectorActive } = this.state
-
- return h(
- 'span',
- {
- style: style,
- },
- [
- enableAccountsSelector && h(
- // 'i.fa.fa-angle-down',
- 'div.cursor-pointer.color-orange.accounts-selector',
- {
- style: {
- // fontSize: '1.8em',
- background: 'url(images/switch_acc.svg) white center center no-repeat',
- height: '25px',
- width: '25px',
- transform: 'scale(0.75)',
- marginRight: '3px',
- },
- onClick: (event) => {
- event.stopPropagation()
- this.setState({
- accountSelectorActive: !accountSelectorActive,
- optionsMenuActive: false,
- })
- },
- },
- this.renderAccountSelector(),
- ),
- enableAccountOptions && h(
- 'i.fa.fa-ellipsis-h',
- {
- style: {
- marginRight: '0.5em',
- fontSize: '1.8em',
- },
- onClick: (event) => {
- metricsEvent({
- eventOpts: {
- category: 'Accounts',
- action: 'userClick',
- name: 'accountsOpenedMenu',
- },
- pageOpts: {
- section: 'header',
- component: 'accountDropdownIcon',
- },
- })
- event.stopPropagation()
- this.setState({
- accountSelectorActive: false,
- optionsMenuActive: !optionsMenuActive,
- })
- },
- },
- this.renderAccountOptions()
- ),
- ]
- )
- }
-}
-
-AccountDropdowns.defaultProps = {
- enableAccountsSelector: false,
- enableAccountOptions: false,
-}
-
-AccountDropdowns.propTypes = {
- identities: PropTypes.objectOf(PropTypes.object),
- selected: PropTypes.string,
- keyrings: PropTypes.array,
- actions: PropTypes.objectOf(PropTypes.func),
- network: PropTypes.string,
- style: PropTypes.object,
- enableAccountOptions: PropTypes.bool,
- enableAccountsSelector: PropTypes.bool,
- t: PropTypes.func,
-}
-
-const mapDispatchToProps = (dispatch) => {
- return {
- actions: {
- showConfigPage: () => dispatch(actions.showConfigPage()),
- requestAccountExport: () => dispatch(actions.requestExportAccount()),
- showAccountDetail: (address) => dispatch(actions.showAccountDetail(address)),
- addNewAccount: () => dispatch(actions.addNewAccount()),
- showImportPage: () => dispatch(actions.showImportPage()),
- showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
- },
- }
-}
-
-AccountDropdowns.contextTypes = {
- t: PropTypes.func,
- metricsEvent: PropTypes.func,
-}
-
-module.exports = {
- AccountDropdowns: connect(null, mapDispatchToProps)(AccountDropdowns),
-}
diff --git a/ui/app/components/app/account-menu/account-menu.component.js b/ui/app/components/app/account-menu/account-menu.component.js
index 972ea492e..1b81e33a2 100644
--- a/ui/app/components/app/account-menu/account-menu.component.js
+++ b/ui/app/components/app/account-menu/account-menu.component.js
@@ -10,7 +10,7 @@ import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display
import { PRIMARY } from '../../../helpers/constants/common'
import {
SETTINGS_ROUTE,
- INFO_ROUTE,
+ ABOUT_US_ROUTE,
NEW_ACCOUNT_ROUTE,
IMPORT_ACCOUNT_ROUTE,
CONNECT_HARDWARE_ROUTE,
@@ -307,7 +307,7 @@ export default class AccountMenu extends PureComponent {
<Item
onClick={() => {
toggleAccountMenu()
- history.push(INFO_ROUTE)
+ history.push(ABOUT_US_ROUTE)
}}
icon={
<img src="images/mm-info-icon.svg" />
diff --git a/ui/app/components/app/dropdowns/components/account-dropdowns.js b/ui/app/components/app/dropdowns/components/account-dropdowns.js
deleted file mode 100644
index c603a9a9f..000000000
--- a/ui/app/components/app/dropdowns/components/account-dropdowns.js
+++ /dev/null
@@ -1,473 +0,0 @@
-const Component = require('react').Component
-const PropTypes = require('prop-types')
-const h = require('react-hyperscript')
-const actions = require('../../../../store/actions')
-const genAccountLink = require('../../../../../lib/account-link.js')
-const connect = require('react-redux').connect
-const Dropdown = require('./dropdown').Dropdown
-const DropdownMenuItem = require('./dropdown').DropdownMenuItem
-import Identicon from '../../../ui/identicon'
-const { checksumAddress } = require('../../../../helpers/utils/util')
-const copyToClipboard = require('copy-to-clipboard')
-const { formatBalance } = require('../../../../helpers/utils/util')
-
-
-class AccountDropdowns extends Component {
- constructor (props) {
- super(props)
- this.state = {
- accountSelectorActive: false,
- optionsMenuActive: false,
- }
- // Used for orangeaccount selector icon
- // this.accountSelectorToggleClassName = 'accounts-selector'
- this.accountSelectorToggleClassName = 'fa-angle-down'
- this.optionsMenuToggleClassName = 'fa-ellipsis-h'
- }
-
- renderAccounts () {
- const { identities, accounts, selected, menuItemStyles, actions, keyrings, ticker } = this.props
-
- return Object.keys(identities).map((key, index) => {
- const identity = identities[key]
- const isSelected = identity.address === selected
-
- const balanceValue = accounts[key].balance
- const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, true, ticker) : '...'
- const simpleAddress = identity.address.substring(2).toLowerCase()
-
- const keyring = keyrings.find((kr) => {
- return kr.accounts.includes(simpleAddress) ||
- kr.accounts.includes(identity.address)
- })
-
- return h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => {
- this.props.actions.showAccountDetail(identity.address)
- },
- style: Object.assign(
- {
- marginTop: index === 0 ? '5px' : '',
- fontSize: '24px',
- width: '260px',
- },
- menuItemStyles,
- ),
- },
- [
- h('div.flex-row.flex-center', {}, [
-
- h('span', {
- style: {
- flex: '1 1 0',
- minWidth: '20px',
- minHeight: '30px',
- },
- }, [
- h('span', {
- style: {
- flex: '1 1 auto',
- fontSize: '14px',
- },
- }, isSelected ? h('i.fa.fa-check') : null),
- ]),
-
- h(
- Identicon,
- {
- address: identity.address,
- diameter: 24,
- style: {
- flex: '1 1 auto',
- marginLeft: '10px',
- },
- },
- ),
-
- h('span.flex-column', {
- style: {
- flex: '10 10 auto',
- width: '175px',
- alignItems: 'flex-start',
- justifyContent: 'center',
- marginLeft: '10px',
- position: 'relative',
- },
- }, [
- this.indicateIfLoose(keyring),
- h('span.account-dropdown-name', {
- style: {
- fontSize: '18px',
- maxWidth: '145px',
- whiteSpace: 'nowrap',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- },
- }, identity.name || ''),
-
- h('span.account-dropdown-balance', {
- style: {
- fontSize: '14px',
- fontFamily: 'Avenir',
- fontWeight: 500,
- },
- }, formattedBalance),
- ]),
-
- h('span', {
- style: {
- flex: '3 3 auto',
- },
- }, [
- h('span.account-dropdown-edit-button.allcaps', {
- style: {
- fontSize: '16px',
- },
- onClick: () => {
- actions.showEditAccountModal(identity)
- },
- }, [
- this.context.t('edit'),
- ]),
- ]),
-
- ]),
- ]
- )
- })
- }
-
- indicateIfLoose (keyring) {
- try { // Sometimes keyrings aren't loaded yet:
- const type = keyring.type
- const isLoose = type !== 'HD Key Tree'
- return isLoose ? h('.keyring-label.allcaps', this.context.t('loose')) : null
- } catch (e) { return }
- }
-
- renderAccountSelector () {
- const { actions, useCssTransition, innerStyle, sidebarOpen } = this.props
- const { accountSelectorActive, menuItemStyles } = this.state
-
- return h(
- Dropdown,
- {
- useCssTransition,
- style: {
- marginLeft: '-185px',
- marginTop: '50px',
- minWidth: '180px',
- overflowY: 'auto',
- maxHeight: '300px',
- width: '300px',
- },
- innerStyle,
- isOpen: accountSelectorActive,
- onClickOutside: (event) => {
- const { classList } = event.target
- const isNotToggleElement = !classList.contains(this.accountSelectorToggleClassName)
- if (accountSelectorActive && isNotToggleElement) {
- this.setState({ accountSelectorActive: false })
- }
- },
- },
- [
- ...this.renderAccounts(),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- style: Object.assign(
- {},
- menuItemStyles,
- ),
- onClick: () => actions.showNewAccountPageCreateForm(),
- },
- [
- h(
- 'i.fa.fa-plus.fa-lg',
- {
- style: {
- marginLeft: '8px',
- },
- }
- ),
- h('span', {
- style: {
- marginLeft: '14px',
- fontFamily: 'DIN OT',
- fontSize: '16px',
- lineHeight: '23px',
- },
- }, this.context.t('createAccount')),
- ],
- ),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {
- if (sidebarOpen) {
- actions.hideSidebar()
- }
- },
- onClick: () => actions.showNewAccountPageImportForm(),
- style: Object.assign(
- {},
- menuItemStyles,
- ),
- },
- [
- h(
- 'i.fa.fa-download.fa-lg',
- {
- style: {
- marginLeft: '8px',
- },
- }
- ),
- h('span', {
- style: {
- marginLeft: '20px',
- marginBottom: '5px',
- fontFamily: 'DIN OT',
- fontSize: '16px',
- lineHeight: '23px',
- },
- }, this.context.t('importAccount')),
- ]
- ),
- ]
- )
- }
-
- renderAccountOptions () {
- const { actions, dropdownWrapperStyle, useCssTransition } = this.props
- const { optionsMenuActive, menuItemStyles } = this.state
- const dropdownMenuItemStyle = {
- fontFamily: 'DIN OT',
- fontSize: 16,
- lineHeight: '24px',
- padding: '8px',
- }
-
- return h(
- Dropdown,
- {
- useCssTransition,
- style: Object.assign(
- {
- marginLeft: '-10px',
- position: 'absolute',
- width: '29vh', // affects both mobile and laptop views
- },
- dropdownWrapperStyle,
- ),
- isOpen: optionsMenuActive,
- onClickOutside: (event) => {
- const { classList } = event.target
- const isNotToggleElement = !classList.contains(this.optionsMenuToggleClassName)
- if (optionsMenuActive && isNotToggleElement) {
- this.setState({ optionsMenuActive: false })
- }
- },
- },
- [
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => {
- this.props.actions.showAccountDetailModal()
- },
- style: Object.assign(
- dropdownMenuItemStyle,
- menuItemStyles,
- ),
- },
- this.context.t('accountDetails'),
- ),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => {
- const { selected, network } = this.props
- const url = genAccountLink(selected, network)
- global.platform.openWindow({ url })
- },
- style: Object.assign(
- dropdownMenuItemStyle,
- menuItemStyles,
- ),
- },
- this.context.t('etherscanView'),
- ),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => {
- const { selected } = this.props
- copyToClipboard(checksumAddress(selected))
- },
- style: Object.assign(
- dropdownMenuItemStyle,
- menuItemStyles,
- ),
- },
- this.context.t('copyAddress'),
- ),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => this.props.actions.showExportPrivateKeyModal(),
- style: Object.assign(
- dropdownMenuItemStyle,
- menuItemStyles,
- ),
- },
- this.context.t('exportPrivateKey'),
- ),
- h(
- DropdownMenuItem,
- {
- closeMenu: () => {},
- onClick: () => {
- actions.hideSidebar()
- actions.showAddTokenPage()
- },
- style: Object.assign(
- dropdownMenuItemStyle,
- menuItemStyles,
- ),
- },
- this.context.t('addToken'),
- ),
-
- ]
- )
- }
-
- render () {
- const { style, enableAccountsSelector, enableAccountOptions } = this.props
- const { optionsMenuActive, accountSelectorActive } = this.state
-
- return h(
- 'span',
- {
- style: style,
- },
- [
- enableAccountsSelector && h(
- 'i.fa.fa-angle-down',
- {
- style: {
- cursor: 'pointer',
- },
- onClick: (event) => {
- event.stopPropagation()
- this.setState({
- accountSelectorActive: !accountSelectorActive,
- optionsMenuActive: false,
- })
- },
- },
- this.renderAccountSelector(),
- ),
- enableAccountOptions && h(
- 'i.fa.fa-ellipsis-h',
- {
- style: {
- fontSize: '135%',
- cursor: 'pointer',
- },
- onClick: (event) => {
- event.stopPropagation()
- this.setState({
- accountSelectorActive: false,
- optionsMenuActive: !optionsMenuActive,
- })
- },
- },
- this.renderAccountOptions()
- ),
- ]
- )
- }
-}
-
-AccountDropdowns.defaultProps = {
- enableAccountsSelector: false,
- enableAccountOptions: false,
-}
-
-AccountDropdowns.propTypes = {
- identities: PropTypes.objectOf(PropTypes.object),
- selected: PropTypes.string,
- keyrings: PropTypes.array,
- accounts: PropTypes.object,
- menuItemStyles: PropTypes.object,
- actions: PropTypes.object,
- // actions.showAccountDetail: ,
- useCssTransition: PropTypes.bool,
- innerStyle: PropTypes.object,
- sidebarOpen: PropTypes.bool,
- dropdownWrapperStyle: PropTypes.string,
- // actions.showAccountDetailModal: ,
- network: PropTypes.number,
- // actions.showExportPrivateKeyModal: ,
- style: PropTypes.object,
- ticker: PropTypes.string,
- enableAccountsSelector: PropTypes.bool,
- enableAccountOption: PropTypes.bool,
- enableAccountOptions: PropTypes.bool,
- t: PropTypes.func,
-}
-
-const mapDispatchToProps = (dispatch) => {
- return {
- actions: {
- hideSidebar: () => dispatch(actions.hideSidebar()),
- showConfigPage: () => dispatch(actions.showConfigPage()),
- showAccountDetail: (address) => dispatch(actions.showAccountDetail(address)),
- showAccountDetailModal: () => {
- dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' }))
- },
- showEditAccountModal: (identity) => {
- dispatch(actions.showModal({
- name: 'EDIT_ACCOUNT_NAME',
- identity,
- }))
- },
- showNewAccountPageCreateForm: () => dispatch(actions.showNewAccountPage({ form: 'CREATE' })),
- showExportPrivateKeyModal: () => {
- dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
- },
- showAddTokenPage: () => {
- dispatch(actions.showAddTokenPage())
- },
- addNewAccount: () => dispatch(actions.addNewAccount()),
- showNewAccountPageImportForm: () => dispatch(actions.showNewAccountPage({ form: 'IMPORT' })),
- showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
- },
- }
-}
-
-function mapStateToProps (state) {
- return {
- ticker: state.metamask.ticker,
- keyrings: state.metamask.keyrings,
- sidebarOpen: state.appState.sidebar.isOpen,
- }
-}
-
-AccountDropdowns.contextTypes = {
- t: PropTypes.func,
-}
-
-module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDropdowns)
-
diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js
index d242f59f5..8aaccafd5 100644
--- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js
+++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js
@@ -38,6 +38,7 @@ export default class GasModalPageContainer extends Component {
customPriceIsSafe: PropTypes.bool,
isSpeedUp: PropTypes.bool,
disableSave: PropTypes.bool,
+ isEthereumNetwork: PropTypes.bool,
}
state = {}
@@ -75,6 +76,7 @@ export default class GasModalPageContainer extends Component {
customPriceIsSafe,
isSpeedUp,
transactionFee,
+ isEthereumNetwork,
}) {
return (
<AdvancedTabContent
@@ -90,6 +92,7 @@ export default class GasModalPageContainer extends Component {
gasEstimatesLoading={gasEstimatesLoading}
customPriceIsSafe={customPriceIsSafe}
isSpeedUp={isSpeedUp}
+ isEthereumNetwork={isEthereumNetwork}
/>
)
}
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 b9eb67d2b..ab24b9c0e 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
@@ -140,7 +140,7 @@ describe('gas-modal-page-container container', () => {
insufficientBalance: true,
isSpeedUp: false,
txId: 34,
- isEthereumNetwork: false,
+ isEthereumNetwork: true,
isMainnet: true,
}
const baseMockOwnProps = { transaction: { id: 34 } }
diff --git a/ui/app/components/app/modals/deposit-ether-modal.js b/ui/app/components/app/modals/deposit-ether-modal.js
index 082ff76a9..6f622a17c 100644
--- a/ui/app/components/app/modals/deposit-ether-modal.js
+++ b/ui/app/components/app/modals/deposit-ether-modal.js
@@ -16,6 +16,8 @@ let WYRE_ROW_TEXT
let SHAPESHIFT_ROW_TITLE
let SHAPESHIFT_ROW_TEXT
let FAUCET_ROW_TITLE
+let COINSWITCH_ROW_TITLE
+let COINSWITCH_ROW_TEXT
function mapStateToProps (state) {
return {
@@ -26,8 +28,11 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
- toCoinbase: (address) => {
- dispatch(actions.buyEth({ network: '1', address, amount: 0 }))
+ toWyre: (address) => {
+ dispatch(actions.buyEth({ service: 'wyre', address, amount: 0 }))
+ },
+ toCoinSwitch: (address) => {
+ dispatch(actions.buyEth({ service: 'coinswitch', address }))
},
hideModal: () => {
dispatch(actions.hideModal())
@@ -54,6 +59,8 @@ function DepositEtherModal (props, context) {
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,
@@ -123,7 +130,7 @@ DepositEtherModal.prototype.renderRow = function ({
}
DepositEtherModal.prototype.render = function () {
- const { network, toCoinbase, address, toFaucet } = this.props
+ const { network, toWyre, toCoinSwitch, address, toFaucet } = this.props
const { buyingWithShapeshift } = this.state
const isTestNetwork = ['3', '4', '42'].find(n => n === network)
@@ -183,7 +190,21 @@ DepositEtherModal.prototype.render = function () {
title: WYRE_ROW_TITLE,
text: WYRE_ROW_TEXT,
buttonLabel: this.context.t('continueToWyre'),
- onButtonClick: () => toCoinbase(address),
+ onButtonClick: () => toWyre(address),
+ hide: isTestNetwork || buyingWithShapeshift,
+ }),
+
+ this.renderRow({
+ logo: h('div.deposit-ether-modal__logo', {
+ style: {
+ backgroundImage: 'url(\'./images/coinswitch_logo.png\')',
+ height: '40px',
+ },
+ }),
+ title: COINSWITCH_ROW_TITLE,
+ text: COINSWITCH_ROW_TEXT,
+ buttonLabel: this.context.t('continueToCoinSwitch'),
+ onButtonClick: () => toCoinSwitch(address),
hide: isTestNetwork || buyingWithShapeshift,
}),
diff --git a/ui/app/components/app/notice.js b/ui/app/components/app/notice.js
deleted file mode 100644
index bb7e0814c..000000000
--- a/ui/app/components/app/notice.js
+++ /dev/null
@@ -1,138 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const PropTypes = require('prop-types')
-const h = require('react-hyperscript')
-const ReactMarkdown = require('react-markdown')
-const linker = require('extension-link-enabler')
-const findDOMNode = require('react-dom').findDOMNode
-const connect = require('react-redux').connect
-
-Notice.contextTypes = {
- t: PropTypes.func,
-}
-
-module.exports = connect()(Notice)
-
-
-inherits(Notice, Component)
-function Notice () {
- Component.call(this)
-}
-
-Notice.prototype.render = function () {
- const { notice, onConfirm } = this.props
- const { title, date, body } = notice
- const state = this.state || { disclaimerDisabled: true }
- const disabled = state.disclaimerDisabled
-
- return (
- h('.flex-column.flex-center.flex-grow', {
- style: {
- width: '100%',
- },
- }, [
- h('h3.flex-center.text-transform-uppercase.terms-header', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- width: '100%',
- fontSize: '20px',
- textAlign: 'center',
- padding: 6,
- },
- }, [
- title,
- ]),
-
- h('h5.flex-center.text-transform-uppercase.terms-header', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginBottom: 24,
- width: '100%',
- fontSize: '20px',
- textAlign: 'center',
- padding: 6,
- },
- }, [
- date,
- ]),
-
- h('style', `
-
- .markdown {
- overflow-x: hidden;
- }
-
- .markdown h1, .markdown h2, .markdown h3 {
- margin: 10px 0;
- font-weight: bold;
- }
-
- .markdown strong {
- font-weight: bold;
- }
- .markdown em {
- font-style: italic;
- }
-
- .markdown p {
- margin: 10px 0;
- }
-
- .markdown a {
- color: #df6b0e;
- }
-
- `),
-
- h('div.markdown', {
- onScroll: (e) => {
- var object = e.currentTarget
- if (object.offsetHeight + object.scrollTop + 100 >= object.scrollHeight) {
- this.setState({disclaimerDisabled: false})
- }
- },
- style: {
- background: 'rgb(235, 235, 235)',
- height: '310px',
- padding: '6px',
- width: '90%',
- overflowY: 'scroll',
- scroll: 'auto',
- },
- }, [
- h(ReactMarkdown, {
- className: 'notice-box',
- source: body,
- skipHtml: true,
- }),
- ]),
-
- h('button.primary', {
- disabled,
- onClick: () => {
- this.setState({disclaimerDisabled: true}, () => onConfirm())
- },
- style: {
- marginTop: '18px',
- },
- }, this.context.t('accept')),
- ])
- )
-}
-
-Notice.prototype.componentDidMount = function () {
- // eslint-disable-next-line react/no-find-dom-node
- var node = findDOMNode(this)
- linker.setupListener(node)
- if (document.getElementsByClassName('notice-box')[0].clientHeight < 310) {
- this.setState({disclaimerDisabled: false})
- }
-}
-
-Notice.prototype.componentWillUnmount = function () {
- // eslint-disable-next-line react/no-find-dom-node
- var node = findDOMNode(this)
- linker.teardownListener(node)
-}
diff --git a/ui/app/components/app/send/send-footer/send-footer.container.js b/ui/app/components/app/send/send-footer/send-footer.container.js
index 502159a81..ea3fd7ee4 100644
--- a/ui/app/components/app/send/send-footer/send-footer.container.js
+++ b/ui/app/components/app/send/send-footer/send-footer.container.js
@@ -96,9 +96,10 @@ function mapDispatchToProps (dispatch) {
return dispatch(updateTransaction(editingTx))
},
+
addToAddressBookIfNew: (newAddress, toAccounts, nickname = '') => {
const hexPrefixedAddress = ethUtil.addHexPrefix(newAddress)
- if (addressIsNew(toAccounts)) {
+ if (addressIsNew(toAccounts, hexPrefixedAddress)) {
// TODO: nickname, i.e. addToAddressBook(recipient, nickname)
dispatch(addToAddressBook(hexPrefixedAddress, nickname))
}
diff --git a/ui/app/components/app/send/send-footer/send-footer.utils.js b/ui/app/components/app/send/send-footer/send-footer.utils.js
index f82ff1e9b..abb2ebc77 100644
--- a/ui/app/components/app/send/send-footer/send-footer.utils.js
+++ b/ui/app/components/app/send/send-footer/send-footer.utils.js
@@ -74,7 +74,9 @@ function constructUpdatedTx ({
}
function addressIsNew (toAccounts, newAddress) {
- return !toAccounts.find(({ address }) => newAddress === address)
+ const newAddressNormalized = newAddress.toLowerCase()
+ const foundMatching = toAccounts.some(({ address }) => address === newAddressNormalized)
+ return !foundMatching
}
module.exports = {
diff --git a/ui/app/components/app/send/tests/send-selectors-test-data.js b/ui/app/components/app/send/tests/send-selectors-test-data.js
index d43d7c650..cff26a191 100644
--- a/ui/app/components/app/send/tests/send-selectors-test-data.js
+++ b/ui/app/components/app/send/tests/send-selectors-test-data.js
@@ -28,7 +28,6 @@ module.exports = {
'conversionRate': 1200.88200327,
'conversionDate': 1489013762,
'nativeCurrency': 'ETH',
- 'noActiveNotices': true,
'frequentRpcList': [],
'network': '3',
'accounts': {
diff --git a/ui/app/components/app/transaction-list-item/transaction-list-item.container.js b/ui/app/components/app/transaction-list-item/transaction-list-item.container.js
index 73ec91e73..de8a3bbba 100644
--- a/ui/app/components/app/transaction-list-item/transaction-list-item.container.js
+++ b/ui/app/components/app/transaction-list-item/transaction-list-item.container.js
@@ -22,11 +22,11 @@ const mapStateToProps = (state, ownProps) => {
const { showFiatInTestnets } = preferencesSelector(state)
const isMainnet = getIsMainnet(state)
const { transactionGroup: { primaryTransaction } = {} } = ownProps
- const { txParams: { gas: gasLimit, gasPrice, value } = {} } = primaryTransaction
+ const { txParams: { gas: gasLimit, gasPrice } = {} } = primaryTransaction
const selectedAccountBalance = accounts[getSelectedAddress(state)].balance
const hasEnoughCancelGas = primaryTransaction.txParams && isBalanceSufficient({
- amount: value,
+ amount: '0x0',
gasTotal: getHexGasTotal({
gasPrice: increaseLastGasPrice(gasPrice),
gasLimit,
diff --git a/ui/app/ducks/app/app.js b/ui/app/ducks/app/app.js
index acbb5c989..295507d70 100644
--- a/ui/app/ducks/app/app.js
+++ b/ui/app/ducks/app/app.js
@@ -435,12 +435,6 @@ function reduceApp (state, action) {
forgottenPassword: false,
})
- case actions.SHOW_NOTICE:
- return extend(appState, {
- transForward: true,
- isLoading: false,
- })
-
case actions.REVEAL_ACCOUNT:
return extend(appState, {
scrollToBottom: true,
diff --git a/ui/app/ducks/confirm-transaction/confirm-transaction.duck.js b/ui/app/ducks/confirm-transaction/confirm-transaction.duck.js
index 4edf8a70c..169c9d543 100644
--- a/ui/app/ducks/confirm-transaction/confirm-transaction.duck.js
+++ b/ui/app/ducks/confirm-transaction/confirm-transaction.duck.js
@@ -1,3 +1,4 @@
+import log from 'loglevel'
import {
conversionRateSelector,
currentCurrencySelector,
@@ -369,23 +370,17 @@ export function setTransactionToConfirm (transactionId) {
const { tokens: existingTokens } = state
const { data, to: tokenAddress } = txParams
- try {
- dispatch(setFetchingData(true))
- const methodData = await getMethodData(data)
-
- dispatch(updateMethodData(methodData))
- } catch (error) {
- dispatch(updateMethodData({}))
- dispatch(setFetchingData(false))
- }
+ dispatch(setFetchingData(true))
+ const methodData = await getMethodData(data)
+ dispatch(updateMethodData(methodData))
try {
const toSmartContract = await isSmartContractAddress(to)
dispatch(updateToSmartContract(toSmartContract))
- dispatch(setFetchingData(false))
} catch (error) {
- dispatch(setFetchingData(false))
+ log.error(error)
}
+ dispatch(setFetchingData(false))
const tokenData = getTokenData(data)
dispatch(updateTokenData(tokenData))
diff --git a/ui/app/ducks/gas/gas.duck.js b/ui/app/ducks/gas/gas.duck.js
index 8eb68f846..5a0a236e6 100644
--- a/ui/app/ducks/gas/gas.duck.js
+++ b/ui/app/ducks/gas/gas.duck.js
@@ -361,7 +361,7 @@ export function fetchGasEstimates (blockTime) {
return (dispatch, getState) => {
const state = getState()
- if (isEthereumNetwork(state)) {
+ if (!isEthereumNetwork(state)) {
return Promise.resolve(null)
}
diff --git a/ui/app/ducks/metamask/metamask.js b/ui/app/ducks/metamask/metamask.js
index 864229e83..47c767d68 100644
--- a/ui/app/ducks/metamask/metamask.js
+++ b/ui/app/ducks/metamask/metamask.js
@@ -18,8 +18,6 @@ function reduceMetamask (state, action) {
rpcTarget: 'https://rawtestrpc.metamask.io/',
identities: {},
unapprovedTxs: {},
- noActiveNotices: true,
- nextUnreadNotice: undefined,
frequentRpcList: [],
addressBook: [],
selectedTokenAddress: null,
@@ -69,18 +67,6 @@ function reduceMetamask (state, action) {
delete newState.seedWords
return newState
- case actions.SHOW_NOTICE:
- return extend(metamaskState, {
- noActiveNotices: false,
- nextUnreadNotice: action.value,
- })
-
- case actions.CLEAR_NOTICES:
- return extend(metamaskState, {
- noActiveNotices: true,
- nextUnreadNotice: undefined,
- })
-
case actions.UPDATE_METAMASK_STATE:
return extend(metamaskState, action.value)
diff --git a/ui/app/helpers/constants/routes.js b/ui/app/helpers/constants/routes.js
index c15027ff4..df35112d1 100644
--- a/ui/app/helpers/constants/routes.js
+++ b/ui/app/helpers/constants/routes.js
@@ -19,7 +19,6 @@ const NEW_ACCOUNT_ROUTE = '/new-account'
const IMPORT_ACCOUNT_ROUTE = '/new-account/import'
const CONNECT_HARDWARE_ROUTE = '/new-account/connect'
const SEND_ROUTE = '/send'
-const NOTICE_ROUTE = '/notice'
const WELCOME_ROUTE = '/welcome'
const INITIALIZE_ROUTE = '/initialize'
@@ -29,7 +28,6 @@ const INITIALIZE_CREATE_PASSWORD_ROUTE = '/initialize/create-password'
const INITIALIZE_IMPORT_ACCOUNT_ROUTE = '/initialize/create-password/import-account'
const INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE = '/initialize/create-password/import-with-seed-phrase'
const INITIALIZE_UNIQUE_IMAGE_ROUTE = '/initialize/create-password/unique-image'
-const INITIALIZE_NOTICE_ROUTE = '/initialize/notice'
const INITIALIZE_SELECT_ACTION_ROUTE = '/initialize/select-action'
const INITIALIZE_SEED_PHRASE_ROUTE = '/initialize/seed-phrase'
const INITIALIZE_END_OF_FLOW_ROUTE = '/initialize/end-of-flow'
@@ -62,7 +60,6 @@ module.exports = {
IMPORT_ACCOUNT_ROUTE,
CONNECT_HARDWARE_ROUTE,
SEND_ROUTE,
- NOTICE_ROUTE,
WELCOME_ROUTE,
INITIALIZE_ROUTE,
INITIALIZE_WELCOME_ROUTE,
@@ -71,7 +68,6 @@ module.exports = {
INITIALIZE_IMPORT_ACCOUNT_ROUTE,
INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
INITIALIZE_UNIQUE_IMAGE_ROUTE,
- INITIALIZE_NOTICE_ROUTE,
INITIALIZE_SELECT_ACTION_ROUTE,
INITIALIZE_SEED_PHRASE_ROUTE,
INITIALIZE_CONFIRM_SEED_PHRASE_ROUTE,
diff --git a/ui/app/helpers/utils/confirm-tx.util.js b/ui/app/helpers/utils/confirm-tx.util.js
index f843db118..853427b31 100644
--- a/ui/app/helpers/utils/confirm-tx.util.js
+++ b/ui/app/helpers/utils/confirm-tx.util.js
@@ -13,7 +13,7 @@ import {
import { unconfirmedTransactionsCountSelector } from '../../selectors/confirm-transaction'
export function increaseLastGasPrice (lastGasPrice) {
- return ethUtil.addHexPrefix(multiplyCurrencies(lastGasPrice, 1.1, {
+ return ethUtil.addHexPrefix(multiplyCurrencies(lastGasPrice || '0x0', 1.1, {
multiplicandBase: 16,
multiplierBase: 10,
toNumericBase: 'hex',
@@ -28,7 +28,7 @@ export function hexGreaterThan (a, b) {
}
export function getHexGasTotal ({ gasLimit, gasPrice }) {
- return ethUtil.addHexPrefix(multiplyCurrencies(gasLimit, gasPrice, {
+ return ethUtil.addHexPrefix(multiplyCurrencies(gasLimit || '0x0', gasPrice || '0x0', {
toNumericBase: 'hex',
multiplicandBase: 16,
multiplierBase: 16,
diff --git a/ui/app/helpers/utils/transactions.util.js b/ui/app/helpers/utils/transactions.util.js
index edf2e24f6..cb6c9536c 100644
--- a/ui/app/helpers/utils/transactions.util.js
+++ b/ui/app/helpers/utils/transactions.util.js
@@ -21,6 +21,7 @@ import {
CANCEL_ATTEMPT_ACTION_KEY,
} from '../constants/transactions'
+import log from 'loglevel'
import { addCurrencies } from './conversion-util'
abiDecoder.addABI(abi)
@@ -37,21 +38,31 @@ const registry = new MethodRegistry({ provider: global.ethereumProvider })
* @param {string} data - The hex data (@code txParams.data) of a transaction
* @returns {Object}
*/
-export async function getMethodData (data = '') {
- const prefixedData = ethUtil.addHexPrefix(data)
- const fourBytePrefix = prefixedData.slice(0, 10)
- const sig = await registry.lookup(fourBytePrefix)
-
- if (!sig) {
- return {}
- }
+ export async function getMethodData (data = '') {
+ const prefixedData = ethUtil.addHexPrefix(data)
+ const fourBytePrefix = prefixedData.slice(0, 10)
+
+ try {
+ const sig = await registry.lookup(fourBytePrefix)
+
+ if (!sig) {
+ return {}
+ }
+
+ const parsedResult = registry.parse(sig)
+
+ return {
+ name: parsedResult.name,
+ params: parsedResult.args,
+ }
+ } catch (error) {
+ log.error(error)
+ const contractData = getTokenData(data)
+ const { name } = contractData || {}
+ return { name }
+ }
- const parsedResult = registry.parse(sig)
- return {
- name: parsedResult.name,
- params: parsedResult.args,
- }
}
export function isConfirmDeployContract (txData = {}) {
diff --git a/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js b/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js
index cd471b822..25f2402f1 100644
--- a/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js
+++ b/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js
@@ -25,6 +25,7 @@ export default class ConfirmTransactionSwitch extends Component {
methodData: PropTypes.object,
fetchingData: PropTypes.bool,
isEtherTransaction: PropTypes.bool,
+ isTokenMethod: PropTypes.bool,
}
redirectToTransaction () {
@@ -33,6 +34,7 @@ export default class ConfirmTransactionSwitch extends Component {
methodData: { name },
fetchingData,
isEtherTransaction,
+ isTokenMethod,
} = this.props
const { id, txParams: { data } = {} } = txData
@@ -45,7 +47,7 @@ export default class ConfirmTransactionSwitch extends Component {
return <Redirect to={{ pathname }} />
}
- if (isEtherTransaction) {
+ if (isEtherTransaction && !isTokenMethod) {
const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_SEND_ETHER_PATH}`
return <Redirect to={{ pathname }} />
}
diff --git a/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.container.js b/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.container.js
index 7f2c36af2..8213f0964 100644
--- a/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.container.js
+++ b/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.container.js
@@ -1,5 +1,10 @@
import { connect } from 'react-redux'
import ConfirmTransactionSwitch from './confirm-transaction-switch.component'
+import {
+ TOKEN_METHOD_TRANSFER,
+ TOKEN_METHOD_APPROVE,
+ TOKEN_METHOD_TRANSFER_FROM,
+} from '../../helpers/constants/transactions'
const mapStateToProps = state => {
const {
@@ -16,6 +21,7 @@ const mapStateToProps = state => {
methodData,
fetchingData,
isEtherTransaction: !toSmartContract,
+ isTokenMethod: [TOKEN_METHOD_APPROVE, TOKEN_METHOD_TRANSFER, TOKEN_METHOD_TRANSFER_FROM].includes(methodData.name && methodData.name.toLowerCase()),
}
}
diff --git a/ui/app/pages/home/home.container.js b/ui/app/pages/home/home.container.js
index 02ec4b9c6..7508654dc 100644
--- a/ui/app/pages/home/home.container.js
+++ b/ui/app/pages/home/home.container.js
@@ -7,7 +7,6 @@ import { unconfirmedTransactionsCountSelector } from '../../selectors/confirm-tr
const mapStateToProps = state => {
const { metamask, appState } = state
const {
- noActiveNotices,
lostAccounts,
seedWords,
suggestedTokens,
@@ -16,7 +15,6 @@ const mapStateToProps = state => {
const { forgottenPassword } = appState
return {
- noActiveNotices,
lostAccounts,
forgottenPassword,
seedWords,
diff --git a/ui/app/pages/notice/notice.js b/ui/app/pages/notice/notice.js
deleted file mode 100644
index d8274dfcb..000000000
--- a/ui/app/pages/notice/notice.js
+++ /dev/null
@@ -1,203 +0,0 @@
-const { Component } = require('react')
-const h = require('react-hyperscript')
-const { connect } = require('react-redux')
-const PropTypes = require('prop-types')
-const ReactMarkdown = require('react-markdown')
-const linker = require('extension-link-enabler')
-const generateLostAccountsNotice = require('../../../lib/lost-accounts-notice')
-const findDOMNode = require('react-dom').findDOMNode
-const actions = require('../../store/actions')
-const { DEFAULT_ROUTE } = require('../../helpers/constants/routes')
-
-class Notice extends Component {
- constructor (props) {
- super(props)
-
- this.state = {
- disclaimerDisabled: true,
- }
- }
-
- componentWillMount () {
- if (!this.props.notice) {
- this.props.history.push(DEFAULT_ROUTE)
- }
- }
-
- componentDidMount () {
- // eslint-disable-next-line react/no-find-dom-node
- var node = findDOMNode(this)
- linker.setupListener(node)
- if (document.getElementsByClassName('notice-box')[0].clientHeight < 310) {
- this.setState({ disclaimerDisabled: false })
- }
- }
-
- componentWillReceiveProps (nextProps) {
- if (!nextProps.notice) {
- this.props.history.push(DEFAULT_ROUTE)
- }
- }
-
- componentWillUnmount () {
- // eslint-disable-next-line react/no-find-dom-node
- var node = findDOMNode(this)
- linker.teardownListener(node)
- }
-
- handleAccept () {
- this.setState({ disclaimerDisabled: true })
- this.props.onConfirm()
- }
-
- render () {
- const { notice = {} } = this.props
- const { title, date, body } = notice
- const { disclaimerDisabled } = this.state
-
- return (
- h('.flex-column.flex-center.flex-grow', {
- style: {
- width: '100%',
- },
- }, [
- h('h3.flex-center.text-transform-uppercase.terms-header', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- width: '100%',
- fontSize: '20px',
- textAlign: 'center',
- padding: 6,
- },
- }, [
- title,
- ]),
-
- h('h5.flex-center.text-transform-uppercase.terms-header', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginBottom: 24,
- width: '100%',
- fontSize: '20px',
- textAlign: 'center',
- padding: 6,
- },
- }, [
- date,
- ]),
-
- h('style', `
-
- .markdown {
- overflow-x: hidden;
- }
-
- .markdown h1, .markdown h2, .markdown h3 {
- margin: 10px 0;
- font-weight: bold;
- }
-
- .markdown strong {
- font-weight: bold;
- }
- .markdown em {
- font-style: italic;
- }
-
- .markdown p {
- margin: 10px 0;
- }
-
- .markdown a {
- color: #df6b0e;
- }
-
- `),
-
- h('div.markdown', {
- onScroll: (e) => {
- var object = e.currentTarget
- if (object.offsetHeight + object.scrollTop + 100 >= object.scrollHeight) {
- this.setState({ disclaimerDisabled: false })
- }
- },
- style: {
- background: 'rgb(235, 235, 235)',
- height: '310px',
- padding: '6px',
- width: '90%',
- overflowY: 'scroll',
- scroll: 'auto',
- },
- }, [
- h(ReactMarkdown, {
- className: 'notice-box',
- source: body,
- skipHtml: true,
- }),
- ]),
-
- h('button.primary', {
- disabled: disclaimerDisabled,
- onClick: () => this.handleAccept(),
- style: {
- marginTop: '18px',
- },
- }, 'Accept'),
- ])
- )
- }
-
-}
-
-const mapStateToProps = state => {
- const { metamask } = state
- const { noActiveNotices, nextUnreadNotice, lostAccounts } = metamask
-
- return {
- noActiveNotices,
- nextUnreadNotice,
- lostAccounts,
- }
-}
-
-Notice.propTypes = {
- notice: PropTypes.object,
- onConfirm: PropTypes.func,
- history: PropTypes.object,
-}
-
-const mapDispatchToProps = dispatch => {
- return {
- markNoticeRead: nextUnreadNotice => dispatch(actions.markNoticeRead(nextUnreadNotice)),
- markAccountsFound: () => dispatch(actions.markAccountsFound()),
- }
-}
-
-const mergeProps = (stateProps, dispatchProps, ownProps) => {
- const { noActiveNotices, nextUnreadNotice, lostAccounts } = stateProps
- const { markNoticeRead, markAccountsFound } = dispatchProps
-
- let notice
- let onConfirm
-
- if (!noActiveNotices) {
- notice = nextUnreadNotice
- onConfirm = () => markNoticeRead(nextUnreadNotice)
- } else if (lostAccounts && lostAccounts.length > 0) {
- notice = generateLostAccountsNotice(lostAccounts)
- onConfirm = () => markAccountsFound()
- }
-
- return {
- ...stateProps,
- ...dispatchProps,
- ...ownProps,
- notice,
- onConfirm,
- }
-}
-
-module.exports = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Notice)
diff --git a/ui/app/pages/routes/index.js b/ui/app/pages/routes/index.js
index 460cec958..e06d88c90 100644
--- a/ui/app/pages/routes/index.js
+++ b/ui/app/pages/routes/index.js
@@ -31,7 +31,6 @@ const AddTokenPage = require('../add-token')
const ConfirmAddTokenPage = require('../confirm-add-token')
const ConfirmAddSuggestedTokenPage = require('../confirm-add-suggested-token')
const CreateAccountPage = require('../create-account')
-const NoticeScreen = require('../notice/notice')
const Loading = require('../../components/ui/loading-screen')
const LoadingNetwork = require('../../components/app/loading-network-screen').default
@@ -67,7 +66,6 @@ import {
CONFIRM_TRANSACTION_ROUTE,
INITIALIZE_ROUTE,
INITIALIZE_UNLOCK_ROUTE,
- NOTICE_ROUTE,
} from '../../helpers/constants/routes'
// enums
@@ -109,7 +107,6 @@ class Routes extends Component {
<Authenticated path={REVEAL_SEED_ROUTE} component={RevealSeedConfirmation} exact />
<Authenticated path={MOBILE_SYNC_ROUTE} component={MobileSyncPage} exact />
<Authenticated path={SETTINGS_ROUTE} component={Settings} />
- <Authenticated path={NOTICE_ROUTE} component={NoticeScreen} exact />
<Authenticated path={`${CONFIRM_TRANSACTION_ROUTE}/:id?`} component={ConfirmTransaction} />
<Authenticated path={SEND_ROUTE} component={SendTransactionScreen} exact />
<Authenticated path={ADD_TOKEN_ROUTE} component={AddTokenPage} exact />
@@ -322,7 +319,6 @@ Routes.propTypes = {
dispatch: PropTypes.func,
toggleAccountMenu: PropTypes.func,
selectedAddress: PropTypes.string,
- noActiveNotices: PropTypes.bool,
lostAccounts: PropTypes.array,
isInitialized: PropTypes.bool,
forgottenPassword: PropTypes.bool,
@@ -360,10 +356,8 @@ function mapStateToProps (state) {
address,
keyrings,
isInitialized,
- noActiveNotices,
seedWords,
unapprovedTxs,
- nextUnreadNotice,
lostAccounts,
unapprovedMsgCount,
unapprovedPersonalMsgCount,
@@ -380,14 +374,13 @@ function mapStateToProps (state) {
alertMessage,
isLoading,
loadingMessage,
- noActiveNotices,
isInitialized,
isUnlocked: state.metamask.isUnlocked,
selectedAddress: state.metamask.selectedAddress,
currentView: state.appState.currentView,
activeAddress: state.appState.activeAddress,
transForward: state.appState.transForward,
- isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
+ isOnboarding: Boolean(seedWords || !isInitialized),
isPopup: state.metamask.isPopup,
seedWords: state.metamask.seedWords,
submittedPendingTransactions: submittedPendingTransactionsSelector(state),
@@ -400,7 +393,6 @@ function mapStateToProps (state) {
network: state.metamask.network,
provider: state.metamask.provider,
forgottenPassword: state.appState.forgottenPassword,
- nextUnreadNotice,
lostAccounts,
frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
currentCurrency: state.metamask.currentCurrency,
diff --git a/ui/app/pages/settings/settings.component.js b/ui/app/pages/settings/settings.component.js
index 3d415c6b8..061e65060 100644
--- a/ui/app/pages/settings/settings.component.js
+++ b/ui/app/pages/settings/settings.component.js
@@ -22,7 +22,7 @@ const ROUTES_TO_I18N_KEYS = {
[GENERAL_ROUTE]: 'general',
[ADVANCED_ROUTE]: 'advanced',
[SECURITY_ROUTE]: 'securityAndPrivacy',
- [ABOUT_US_ROUTE]: 'aboutUs',
+ [ABOUT_US_ROUTE]: 'about',
}
export default class SettingsPage extends PureComponent {
@@ -92,7 +92,7 @@ export default class SettingsPage extends PureComponent {
{ content: t('general'), description: t('generalSettingsDescription'), key: GENERAL_ROUTE },
{ content: t('advanced'), description: t('advancedSettingsDescription'), key: ADVANCED_ROUTE },
{ content: t('securityAndPrivacy'), description: t('securitySettingsDescription'), key: SECURITY_ROUTE },
- { content: t('aboutUs'), key: ABOUT_US_ROUTE },
+ { content: t('about'), description: t('aboutSettingsDescription'), key: ABOUT_US_ROUTE },
]}
isActive={key => {
if (key === GENERAL_ROUTE && this.isCurrentPath(SETTINGS_ROUTE)) {
diff --git a/ui/app/pages/unlock-page/unlock-page.container.js b/ui/app/pages/unlock-page/unlock-page.container.js
index bd43666fc..b89392ab5 100644
--- a/ui/app/pages/unlock-page/unlock-page.container.js
+++ b/ui/app/pages/unlock-page/unlock-page.container.js
@@ -39,7 +39,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
history.push(RESTORE_VAULT_ROUTE)
if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP) {
- global.platform.openExtensionInBrowser()
+ global.platform.openExtensionInBrowser(RESTORE_VAULT_ROUTE)
}
}
diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js
index bea2cea33..554232f7b 100644
--- a/ui/app/selectors/selectors.js
+++ b/ui/app/selectors/selectors.js
@@ -301,7 +301,8 @@ function isEthereumNetwork (state) {
RINKEBY,
ROPSTEN,
} = NETWORK_TYPES
- return [ KOVAN, MAINNET, RINKEBY, ROPSTEN].includes(type => type === networkType)
+
+ return [ KOVAN, MAINNET, RINKEBY, ROPSTEN].includes(networkType)
}
function preferencesSelector ({ metamask }) {
diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js
index b2aa28c93..7d369fdb9 100644
--- a/ui/app/store/actions.js
+++ b/ui/app/store/actions.js
@@ -51,13 +51,6 @@ var actions = {
// remote state
UPDATE_METAMASK_STATE: 'UPDATE_METAMASK_STATE',
updateMetamaskState: updateMetamaskState,
- // notices
- MARK_NOTICE_READ: 'MARK_NOTICE_READ',
- markNoticeRead: markNoticeRead,
- SHOW_NOTICE: 'SHOW_NOTICE',
- showNotice: showNotice,
- CLEAR_NOTICES: 'CLEAR_NOTICES',
- clearNotices: clearNotices,
markAccountsFound,
// intialize screen
CREATE_NEW_VAULT_IN_PROGRESS: 'CREATE_NEW_VAULT_IN_PROGRESS',
@@ -1857,47 +1850,6 @@ function goBackToInitView () {
}
}
-//
-// notice
-//
-
-function markNoticeRead (notice) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- log.debug(`background.markNoticeRead`)
- return new Promise((resolve, reject) => {
- background.markNoticeRead(notice, (err, notice) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- dispatch(actions.displayWarning(err.message))
- return reject(err)
- }
-
- if (notice) {
- dispatch(actions.showNotice(notice))
- resolve(true)
- } else {
- dispatch(actions.clearNotices())
- resolve(false)
- }
- })
- })
- }
-}
-
-function showNotice (notice) {
- return {
- type: actions.SHOW_NOTICE,
- value: notice,
- }
-}
-
-function clearNotices () {
- return {
- type: actions.CLEAR_NOTICES,
- }
-}
-
function markAccountsFound () {
log.debug(`background.markAccountsFound`)
return callBackgroundThenUpdate(background.markAccountsFound)
@@ -2488,21 +2440,18 @@ function setShowFiatConversionOnTestnetsPreference (value) {
}
function setCompletedOnboarding () {
- return dispatch => {
+ return async dispatch => {
dispatch(actions.showLoadingIndication())
- return new Promise((resolve, reject) => {
- background.completeOnboarding(err => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- dispatch(actions.displayWarning(err.message))
- return reject(err)
- }
+ try {
+ await pify(background.completeOnboarding).call(background)
+ } catch (err) {
+ dispatch(actions.displayWarning(err.message))
+ throw err
+ }
- dispatch(actions.completeOnboarding())
- resolve()
- })
- })
+ dispatch(actions.completeOnboarding())
+ dispatch(actions.hideLoadingIndication())
}
}