aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkumavis <kumavis@users.noreply.github.com>2018-04-10 04:56:59 +0800
committerGitHub <noreply@github.com>2018-04-10 04:56:59 +0800
commitdf1f891585dc41a7d725d592902a84e432e66dc4 (patch)
treee450c931e8d6d4a1277fd57e330fa8882d7cc93f
parent931ce120737210cbbf6736b454580ac0610f527a (diff)
parent305f5f0034f347ee3eacbc4e6ef41817c1de9ab2 (diff)
downloadtangerine-wallet-browser-df1f891585dc41a7d725d592902a84e432e66dc4.tar
tangerine-wallet-browser-df1f891585dc41a7d725d592902a84e432e66dc4.tar.gz
tangerine-wallet-browser-df1f891585dc41a7d725d592902a84e432e66dc4.tar.bz2
tangerine-wallet-browser-df1f891585dc41a7d725d592902a84e432e66dc4.tar.lz
tangerine-wallet-browser-df1f891585dc41a7d725d592902a84e432e66dc4.tar.xz
tangerine-wallet-browser-df1f891585dc41a7d725d592902a84e432e66dc4.tar.zst
tangerine-wallet-browser-df1f891585dc41a7d725d592902a84e432e66dc4.zip
Merge branch 'master' into i3621-LogoPerformance
-rw-r--r--CHANGELOG.md29
-rw-r--r--app/_locales/en/messages.json2
-rw-r--r--app/_locales/index.json1
-rw-r--r--app/_locales/tr/messages.json912
-rw-r--r--app/manifest.json2
-rw-r--r--app/scripts/background.js54
-rw-r--r--app/scripts/contentscript.js6
-rw-r--r--app/scripts/controllers/transactions.js60
-rw-r--r--app/scripts/lib/get-first-preferred-lang-code.js6
-rw-r--r--app/scripts/lib/getObjStructure.js33
-rw-r--r--app/scripts/lib/is-popup-or-notification.js3
-rw-r--r--app/scripts/lib/migrator/index.js27
-rw-r--r--app/scripts/lib/tx-gas-utils.js35
-rw-r--r--app/scripts/lib/tx-state-manager.js22
-rw-r--r--app/scripts/migrations/013.js7
-rw-r--r--app/scripts/migrations/015.js15
-rw-r--r--app/scripts/migrations/016.js22
-rw-r--r--app/scripts/migrations/017.js21
-rw-r--r--app/scripts/migrations/018.js39
-rw-r--r--app/scripts/migrations/019.js44
-rw-r--r--app/scripts/migrations/022.js17
-rw-r--r--app/scripts/migrations/023.js38
-rw-r--r--app/scripts/migrations/024.js41
-rw-r--r--app/scripts/migrations/025.js61
-rw-r--r--app/scripts/migrations/index.js2
-rw-r--r--app/scripts/migrations/template.js29
-rw-r--r--development/mock-dev.js21
-rw-r--r--development/states/tx-list-items.json (renamed from development/states/tx-list-items.js)0
-rw-r--r--docs/QA_Guide.md48
-rw-r--r--mascara/src/app/first-time/confirm-seed-screen.js151
-rw-r--r--mascara/src/app/first-time/create-password-screen.js279
-rw-r--r--mascara/src/app/first-time/import-seed-phrase-screen.js10
-rw-r--r--mascara/src/app/first-time/index.js187
-rw-r--r--mascara/src/app/first-time/notice-screen.js105
-rw-r--r--mascara/src/app/first-time/seed-screen.js (renamed from mascara/src/app/first-time/backup-phrase-screen.js)147
-rw-r--r--mascara/src/app/first-time/unique-image-screen.js18
-rw-r--r--old-ui/app/util.js1
-rw-r--r--package-lock.json98
-rw-r--r--package.json6
-rw-r--r--test/integration/lib/add-token.js2
-rw-r--r--test/integration/lib/confirm-sig-requests.js18
-rw-r--r--test/integration/lib/mascara-first-time.js3
-rw-r--r--test/integration/lib/send-new-ui.js30
-rw-r--r--test/unit/migrations/024-test.js49
-rw-r--r--test/unit/migrations/025-test.js49
-rw-r--r--test/unit/migrations/template-test.js17
-rw-r--r--test/unit/migrator-test.js33
-rw-r--r--test/unit/tx-controller-test.js90
-rw-r--r--test/unit/tx-gas-util-test.js42
-rw-r--r--ui/app/actions.js182
-rw-r--r--ui/app/app.js930
-rw-r--r--ui/app/components/account-menu/index.js54
-rw-r--r--ui/app/components/ens-input.js4
-rw-r--r--ui/app/components/pages/add-token.js (renamed from ui/app/add-token.js)44
-rw-r--r--ui/app/components/pages/authenticated.js34
-rw-r--r--ui/app/components/pages/create-account/import-account/index.js (renamed from ui/app/accounts/import/index.js)0
-rw-r--r--ui/app/components/pages/create-account/import-account/json.js (renamed from ui/app/accounts/import/json.js)16
-rw-r--r--ui/app/components/pages/create-account/import-account/private-key.js (renamed from ui/app/accounts/import/private-key.js)24
-rw-r--r--ui/app/components/pages/create-account/import-account/seed.js (renamed from ui/app/accounts/import/seed.js)0
-rw-r--r--ui/app/components/pages/create-account/index.js81
-rw-r--r--ui/app/components/pages/create-account/new-account.js (renamed from ui/app/accounts/new-account/create-form.js)30
-rw-r--r--ui/app/components/pages/home.js332
-rw-r--r--ui/app/components/pages/initialized.js25
-rw-r--r--ui/app/components/pages/keychains/restore-vault.js177
-rw-r--r--ui/app/components/pages/keychains/reveal-seed.js195
-rw-r--r--ui/app/components/pages/metamask-route.js28
-rw-r--r--ui/app/components/pages/notice.js203
-rw-r--r--ui/app/components/pages/settings/index.js59
-rw-r--r--ui/app/components/pages/settings/info.js112
-rw-r--r--ui/app/components/pages/settings/settings.js (renamed from ui/app/settings.js)163
-rw-r--r--ui/app/components/pages/unlock.js193
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js28
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js22
-rw-r--r--ui/app/components/send/send-v2-container.js8
-rw-r--r--ui/app/components/signature-request.js17
-rw-r--r--ui/app/components/tab-bar.js26
-rw-r--r--ui/app/components/tx-list.js18
-rw-r--r--ui/app/components/tx-view.js17
-rw-r--r--ui/app/components/wallet-view.js18
-rw-r--r--ui/app/conf-tx.js74
-rw-r--r--ui/app/css/index.scss6
-rw-r--r--ui/app/css/itcss/components/add-token.scss29
-rw-r--r--ui/app/css/itcss/components/index.scss2
-rw-r--r--ui/app/css/itcss/components/new-account.scss5
-rw-r--r--ui/app/css/itcss/components/pages/index.scss1
-rw-r--r--ui/app/css/itcss/components/pages/unlock.scss9
-rw-r--r--ui/app/css/itcss/components/sections.scss6
-rw-r--r--ui/app/first-time/init-menu.js343
-rw-r--r--ui/app/i18n-provider.js7
-rw-r--r--ui/app/keychains/hd/recover-seed/confirmation.js14
-rw-r--r--ui/app/main-container.js4
-rw-r--r--ui/app/root.js33
-rw-r--r--ui/app/routes.js49
-rw-r--r--ui/app/select-app.js10
-rw-r--r--ui/app/send-v2.js22
-rw-r--r--ui/app/util.js1
-rw-r--r--ui/app/welcome-screen.js35
-rw-r--r--yarn.lock1896
98 files changed, 6507 insertions, 2011 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ac63ff61..7f8c1c6b8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,35 @@
- Improved performance of 3D fox logo.
+## 4.5.5 Fri Apr 06 2018
+
+- Graceful handling of unknown keys in txParams
+- Fixes buggy handling of historical transactions with unknown keys in txParams
+- Fix link for 'Learn More' in the Add Token Screen to open to a new tab.
+- Fix Download State Logs button [#3791](https://github.com/MetaMask/metamask-extension/issues/3791)
+- Enhanced migration error handling + reporting
+
+## 4.5.4 (aborted) Thu Apr 05 2018
+
+- Graceful handling of unknown keys in txParams
+- Fix link for 'Learn More' in the Add Token Screen to open to a new tab.
+- Fix Download State Logs button [#3791](https://github.com/MetaMask/metamask-extension/issues/3791)
+- Fix migration error reporting
+
+## 4.5.3 Wed Apr 04 2018
+
+- Fix bug where checksum address are messing with balance issue [#3843](https://github.com/MetaMask/metamask-extension/issues/3843)
+- new ui: fix the confirm transaction screen
+
+## 4.5.2 Wed Apr 04 2018
+
+- Fix overly strict validation where transactions were rejected with hex encoded "chainId"
+
+## 4.5.1 Tue Apr 03 2018
+
+- Fix default network (should be mainnet not Rinkeby)
+- Fix Sentry automated error reporting endpoint
+
## 4.5.0 Mon Apr 02 2018
- (beta ui) Internationalization: Select your preferred language in the settings screen
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index 34575b4dd..b372326ee 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -56,7 +56,7 @@
"message": "Balance:"
},
"balances": {
- "message": "Your balances"
+ "message": "Token balance(s)"
},
"balanceIsInsufficientGas": {
"message": "Insufficient balance for current gas total"
diff --git a/app/_locales/index.json b/app/_locales/index.json
index c085deb72..727504bda 100644
--- a/app/_locales/index.json
+++ b/app/_locales/index.json
@@ -13,6 +13,7 @@
{ "code": "ru", "name": "Russian" },
{ "code": "sl", "name": "Slovenian" },
{ "code": "th", "name": "Thai" },
+ { "code": "tr", "name": "Turkish" },
{ "code": "vi", "name": "Vietnamese" },
{ "code": "zh_CN", "name": "Mandarin" },
{ "code": "zh_TW", "name": "Taiwanese" }
diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json
new file mode 100644
index 000000000..c2c09bc91
--- /dev/null
+++ b/app/_locales/tr/messages.json
@@ -0,0 +1,912 @@
+{
+ "accept": {
+ "message": "Kabul et"
+ },
+ "account": {
+ "message": "Hesap"
+ },
+ "accountDetails": {
+ "message": "Hesap Detayları"
+ },
+ "accountName": {
+ "message": "Hesap İsmi"
+ },
+ "address": {
+ "message": "Adres"
+ },
+ "addCustomToken": {
+ "message": "Özel jeton ekle"
+ },
+ "addToken": {
+ "message": "Jeton ekle"
+ },
+ "addTokens": {
+ "message": "Jetonlar ekle"
+ },
+ "amount": {
+ "message": "Tutar"
+ },
+ "amountPlusGas": {
+ "message": "Tutar + Gas"
+ },
+ "appDescription": {
+ "message": "Ethereum Tarayıcı Uzantısı",
+ "description": "Uygulama açıklaması"
+ },
+ "appName": {
+ "message": "MetaMask",
+ "description": "Uygulama ismi"
+ },
+ "approved": {
+ "message": "Onaylandı"
+ },
+ "attemptingConnect": {
+ "message": "Blockchain'e bağlanmayı deniyor"
+ },
+ "attributions": {
+ "message": "Atıflar"
+ },
+ "available": {
+ "message": "Müsait"
+ },
+ "back": {
+ "message": "Geri"
+ },
+ "balance": {
+ "message": "Bakiye:"
+ },
+ "balances": {
+ "message": "Jeton bakiyesi"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "Toplam gas için yetersiz bakiye"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "$1'e eşit veya daha büyük olmalı ve $2'den küçük veya eşit olmalı",
+ "description": "Onaltılık sayının ondalık sayı olarak girişi için yardımcı"
+ },
+ "blockiesIdenticon": {
+ "message": "Blockies Identicon kullan"
+ },
+ "borrowDharma": {
+ "message": "Dharma (Beta) ile ödünç al"
+ },
+ "builtInCalifornia": {
+ "message": "MetaMask California'da tasarlandı ve yaratıldı"
+ },
+ "buy": {
+ "message": "Satın al"
+ },
+ "buyCoinbase": {
+ "message": "Coinbase'de satın al"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase bitcoin, ethereum, and litecoin alıp satmanın dünyadaki en popüler yolu"
+ },
+ "ok": {
+ "message": "Tamam"
+ },
+ "cancel": {
+ "message": "Vazgeç"
+ },
+ "classicInterface": {
+ "message": "Klasik arayüzü kullan"
+ },
+ "clickCopy": {
+ "message": "Kopyalamak için tıkla"
+ },
+ "confirm": {
+ "message": "Onayla"
+ },
+ "confirmed": {
+ "message": "Onaylandı"
+ },
+ "confirmContract": {
+ "message": "Sözleşmeyi onayla"
+ },
+ "confirmPassword": {
+ "message": "Şifreyi onayla"
+ },
+ "confirmTransaction": {
+ "message": "İşlemi onayla"
+ },
+ "continue": {
+ "message": "Devam et"
+ },
+ "continueToCoinbase": {
+ "message": "Coinbase'e devam et"
+ },
+ "contractDeployment": {
+ "message": "Sözleşme kurulumu"
+ },
+ "conversionProgress": {
+ "message": "Çevirim devam ediyor"
+ },
+ "copiedButton": {
+ "message": "Kopyalandı"
+ },
+ "copiedClipboard": {
+ "message": "Panoya kopyalandı"
+ },
+ "copiedExclamation": {
+ "message": "Kopyalandı!"
+ },
+ "copiedSafe": {
+ "message": "Güvenli bir yere kopyaladım"
+ },
+ "copy": {
+ "message": "Kopyala"
+ },
+ "copyToClipboard": {
+ "message": "Panoya kopyala"
+ },
+ "copyButton": {
+ "message": " Kopyala "
+ },
+ "copyPrivateKey": {
+ "message": "Bu sizin özel anahtarınız (kopyalamak için tıklayın)"
+ },
+ "create": {
+ "message": "Yarat"
+ },
+ "createAccount": {
+ "message": "Hesap Oluştur"
+ },
+ "createDen": {
+ "message": "Yarat"
+ },
+ "crypto": {
+ "message": "Kripto",
+ "description": "Kambiyo tipi (kripto para)"
+ },
+ "currentConversion": {
+ "message": "Geçerli çevirme"
+ },
+ "currentNetwork": {
+ "message": "Geçerli Ağ"
+ },
+ "customGas": {
+ "message": "Gas'i özelleştir"
+ },
+ "customToken": {
+ "message": "Özel Jeton"
+ },
+ "customize": {
+ "message": "Özelleştir"
+ },
+ "customRPC": {
+ "message": "Özel RPC"
+ },
+ "decimalsMustZerotoTen": {
+ "message": "Ondalıklar en azından 0 olmalı ve 36'dan büyük olmamalı."
+ },
+ "decimal": {
+ "message": "Ondalık hassasiyeti"
+ },
+ "defaultNetwork": {
+ "message": "Ether işlemleri için varsayılan ağ Main Net."
+ },
+ "denExplainer": {
+ "message": "DEN'iniz MetaMask içersinde parola-şifrelenmiş deponuzdur."
+ },
+ "deposit": {
+ "message": "Yatır"
+ },
+ "depositBTC": {
+ "message": "BTC'inizi aşağıdaki adrese yatırın:"
+ },
+ "depositCoin": {
+ "message": "$1'nızı aşağıdaki adrese yatırın",
+ "description": "Kullanıcıya hangi jetonu seçtiyse onu yatırmasını shapeshift ile söyler."
+ },
+ "depositEth": {
+ "message": "Eth yatır"
+ },
+ "depositEther": {
+ "message": "Ether yatır"
+ },
+ "depositFiat": {
+ "message": "Para yatır"
+ },
+ "depositFromAccount": {
+ "message": "Başka bir hesaptan yatır"
+ },
+ "depositShapeShift": {
+ "message": "ShapeShift ile yatır"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "Eğer başka kripto paralara sahipseniz, MetaMask cüzdanınıza direk olarak Ether yatırabilirsiniz. Hesaba gerek yoktur."
+ },
+ "details": {
+ "message": "Ayrıntılar"
+ },
+ "directDeposit": {
+ "message": "Direk Yatırma"
+ },
+ "directDepositEther": {
+ "message": "Direk Ether Yatırma"
+ },
+ "directDepositEtherExplainer": {
+ "message": "Eğer çoktan Etheriniz varsa, yeni hesabınıza Ether aktarmanın en kolay yolu direk yatırmadır."
+ },
+ "done": {
+ "message": "Bitti"
+ },
+ "downloadStateLogs": {
+ "message": "Durum kayıtlarını indir"
+ },
+ "dropped": {
+ "message": "Bırakıldı"
+ },
+ "edit": {
+ "message": "Düzenle"
+ },
+ "editAccountName": {
+ "message": "Hesap ismini düzenle"
+ },
+ "emailUs": {
+ "message": "Bize e-posta atın!"
+ },
+ "encryptNewDen": {
+ "message": "Yeni DEN'inizi şifreleyin"
+ },
+ "enterPassword": {
+ "message": "Parolanızı girin"
+ },
+ "enterPasswordConfirm": {
+ "message": "Onaylamak için parolanızı girin"
+ },
+ "passwordNotLongEnough": {
+ "message": "Parola yeterince uzun değil"
+ },
+ "passwordsDontMatch": {
+ "message": "Parolalar eşleşmiyor"
+ },
+ "etherscanView": {
+ "message": "Hesabı Etherscan üzerinde izle"
+ },
+ "exchangeRate": {
+ "message": "Döviz kuru"
+ },
+ "exportPrivateKey": {
+ "message": "Özel anahtarı ver"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "Özel anahtarınızı vermek sizin sorumluluğunuzdadır."
+ },
+ "failed": {
+ "message": "Başarısız oldu"
+ },
+ "fiat": {
+ "message": "Para",
+ "description": "Döviz türü"
+ },
+ "fileImportFail": {
+ "message": "Dosya alma çalışmıyor mu? Buraya tıklayın!",
+ "description": "Kullanıcıların hesaplarını JSON dosyasından almalarına yardım eder"
+ },
+ "followTwitter": {
+ "message": "Bizi twitter'da takip edin"
+ },
+ "from": {
+ "message": "Kimden"
+ },
+ "fromToSame": {
+ "message": "Kimden ve kime adresi aynı olamaz"
+ },
+ "fromShapeShift": {
+ "message": "ShapeShift'den"
+ },
+ "gas": {
+ "message": "Gas",
+ "description": "Gas maliyetinin kısa indikatörü"
+ },
+ "gasFee": {
+ "message": "Gas Ücreti"
+ },
+ "gasLimit": {
+ "message": "Gas Limiti"
+ },
+ "gasLimitCalculation": {
+ "message": "Önerilen gas limitini ağ başarı oranını baz alarak hesaplıyoruz."
+ },
+ "gasLimitRequired": {
+ "message": "Gas limiti gereklidir"
+ },
+ "gasLimitTooLow": {
+ "message": "Gas limiti en az 21000 olmalıdır"
+ },
+ "generatingSeed": {
+ "message": "Kaynak Oluşturuyor..."
+ },
+ "gasPrice": {
+ "message": "Gas Fiyatı (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "Önerilen gas fiyatını ağ başarı oranını baz alarak hesaplıyoruz."
+ },
+ "gasPriceRequired": {
+ "message": "Gas Fiyatı Gereklidir"
+ },
+ "getEther": {
+ "message": "Ether Al"
+ },
+ "getEtherFromFaucet": {
+ "message": "Musluktan $1 karşılığı Ether alın",
+ "description": "Ether musluğunun ağ ismini gösterir"
+ },
+ "greaterThanMin": {
+ "message": "must be greater than or equal to $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "here": {
+ "message": "burada",
+ "description": "daha fazla bilgi için -buraya tıklayın- (troubleTokenBalances ile gidiyor)"
+ },
+ "hereList": {
+ "message": "İşte bir liste!!!!"
+ },
+ "hide": {
+ "message": "Gizle"
+ },
+ "hideToken": {
+ "message": "Jetonu gizle"
+ },
+ "hideTokenPrompt": {
+ "message": "Jetonu gizle?"
+ },
+ "howToDeposit": {
+ "message": "Ether'i nasıl yatırmak istersiniz?"
+ },
+ "holdEther": {
+ "message": "Ether ve jeton tutmanızı sağlar ve merkezi olmayan uygulamalar ve sizin aranızda köprü vazifesi görür."
+ },
+ "import": {
+ "message": "Al",
+ "description": "Seçilen dosyadan hesap alma düğmesi. "
+ },
+ "importAccount": {
+ "message": "Hesap Al"
+ },
+ "importAccountMsg": {
+ "message":" Alınan hesaplar orjinal kaynakifadenizle yarattığınız MetaMask hesabınızla ilişkilendirilmez. Alınan hesaplar ile ilgili daha fazla bilgi edinin "
+ },
+ "importAnAccount": {
+ "message": "Hesap al"
+ },
+ "importDen": {
+ "message": "Varolan DEN al"
+ },
+ "imported": {
+ "message": "Alındı",
+ "description": "Hesabın keyringe başarı ile alındığını gösteren durum"
+ },
+ "infoHelp": {
+ "message": "Bilgi ve yardım"
+ },
+ "insufficientFunds": {
+ "message": "Yetersiz kaynak."
+ },
+ "insufficientTokens": {
+ "message": "Yetersiz Jeton."
+ },
+ "invalidAddress": {
+ "message": "Geçersiz adres"
+ },
+ "invalidAddressRecipient": {
+ "message": "Alıcı adresi geçersiz"
+ },
+ "invalidGasParams": {
+ "message": "Geçersiz gas parametreleri"
+ },
+ "invalidInput": {
+ "message": "Geçersiz giriş."
+ },
+ "invalidRequest": {
+ "message": "Geçersiz istek"
+ },
+ "invalidRPC": {
+ "message": "Geçersiz RPC URI"
+ },
+ "jsonFail": {
+ "message": "Birşeyler yanlış gitti. JSON dosyanızın düzgün derlendiğinden emin olun."
+ },
+ "jsonFile": {
+ "message": "JSON Dosyası",
+ "description": "Hesap alımı için düzenle"
+ },
+ "keepTrackTokens": {
+ "message": "MetaMask hesabınızla satın aldığınız jetonların kaydını tutun."
+ },
+ "kovan": {
+ "message": "Kovan Test Ağı"
+ },
+ "knowledgeDataBase": {
+ "message": "Bilgi veritabanımızı ziyaret edin"
+ },
+ "max": {
+ "message": "Maksimum"
+ },
+ "learnMore": {
+ "message": "Daha fazla bilgi."
+ },
+ "lessThanMax": {
+ "message": "$1'den az veya eşit olmalıdır.",
+ "description": "Onaltılık sayıyı ondalık olarak girmek için yardımcı"
+ },
+ "likeToAddTokens": {
+ "message": "Bu jetonlara adres eklemek ister misiniz?"
+ },
+ "links": {
+ "message": "Bağlantılar"
+ },
+ "limit": {
+ "message": "Limit"
+ },
+ "loading": {
+ "message": "Yükleniyor..."
+ },
+ "loadingTokens": {
+ "message": "Jetonlar yükleniyor..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "login": {
+ "message": "Giriş yap"
+ },
+ "logout": {
+ "message": "Çıkış"
+ },
+ "loose": {
+ "message": "Gevşek"
+ },
+ "loweCaseWords": {
+ "message": "kaynak kelimeleri sadece küçük harflerden oluşabilir."
+ },
+ "mainnet": {
+ "message": "Main Ethereum Ağı"
+ },
+ "message": {
+ "message": "Mesaj"
+ },
+ "metamaskDescription": {
+ "message": "MetaMask Ethereum için güvenli bir kimlik kasasıdır."
+ },
+ "min": {
+ "message": "Minimum"
+ },
+ "myAccounts": {
+ "message": "Hesaplarım"
+ },
+ "mustSelectOne": {
+ "message": "En az bir jeton seçilmeli"
+ },
+ "needEtherInWallet": {
+ "message": "MetaMask kullanarak merkezi olamayan uygulamalarla etkileşmek için cüzdanınızda Ether bulunmalıdır."
+ },
+ "needImportFile": {
+ "message": "Almak için bir dosya seçmelisiniz.",
+ "description": "Kullanıcı bir hesap alır ve devam etmek içinbir dosya seçmelidir."
+ },
+ "needImportPassword": {
+ "message": "Seçilen dosya için bir parola girmelisiniz.",
+ "description": "Hesap almak için parola ve dosya gerekiyor."
+ },
+ "negativeETH": {
+ "message": "Negatif ETH miktarları gönderilemez."
+ },
+ "networks": {
+ "message": "Ağlar"
+ },
+ "newAccount": {
+ "message": "Yeni Hesap"
+ },
+ "newAccountNumberName": {
+ "message": "Hesap $1",
+ "description": "Hesap yaratma ekranındaki bir sonraki hesabın varsayılan ismi"
+ },
+ "newContract": {
+ "message": "Yeni Sözleşme"
+ },
+ "newPassword": {
+ "message": "Yeni Parola (min 8 karakter)"
+ },
+ "newRecipient": {
+ "message": "Yeni alıcı"
+ },
+ "newRPC": {
+ "message": "Yeni RPC URL"
+ },
+ "next": {
+ "message": "Sonraki"
+ },
+ "noAddressForName": {
+ "message": "Bu isim için bir adres tanımlanmamış."
+ },
+ "noDeposits": {
+ "message": "Yatırma alınmadı"
+ },
+ "noTransactionHistory": {
+ "message": "İşlem geçmişi yok."
+ },
+ "noTransactions": {
+ "message": "İşlem yok"
+ },
+ "notStarted": {
+ "message": "Başlamadı"
+ },
+ "oldUI": {
+ "message": "Eski UI"
+ },
+ "oldUIMessage": {
+ "message": "Eski UI'a döndünüz. Yeni UI'a üst sağ sekme menüsündeki seçenek ile dönebilirsiniz."
+ },
+ "or": {
+ "message": "veya",
+ "description": "Yeni bir hesap yaratmak veya almak arasındaki seçim"
+ },
+ "passwordCorrect": {
+ "message": "Lütfen parolanın doğru olduğuna emin olun."
+ },
+ "passwordMismatch": {
+ "message": "parolalar eşleşmiyor",
+ "description": "parola yaratma işleminde, iki yeni parola alanı eşleşmiyor."
+ },
+ "passwordShort": {
+ "message": "parola yeterince uzun değil",
+ "description": "parola yaratma işleminde, parola güvenli olacak kadar uzun değil."
+ },
+ "pastePrivateKey": {
+ "message": "Özel anahtar dizinizi buraya yapıştırın:",
+ "description": "Özel anahtardan hesap almak için"
+ },
+ "pasteSeed": {
+ "message": "Kaynak ifadenizi buraya yapıştırın!"
+ },
+ "personalAddressDetected": {
+ "message": "Kişisel adres tespit edilidi. Jeton sözleşme adresini girin."
+ },
+ "pleaseReviewTransaction": {
+ "message": "Lütfen işleminizi gözden geçirin."
+ },
+ "popularTokens": {
+ "message": "Popüler Jetonlar"
+ },
+ "privacyMsg": {
+ "message": "Gizlilik Şartları"
+ },
+ "privateKey": {
+ "message": "Özel Anahtar",
+ "description": "Hesap alırken bu tip bir dosya seçin"
+ },
+ "privateKeyWarning": {
+ "message": "Uyarı: Bu anahtarı kimse ile paylaşmayın. Özel anahtarlarınıza sahip herkes hesaplarınızıdaki tüm varlığınızı çalabilir."
+ },
+ "privateNetwork": {
+ "message": "Özel Ağ"
+ },
+ "qrCode": {
+ "message": "QR Kodunu göster"
+ },
+ "readdToken": {
+ "message": "Gelecekte Bu jetonu hesap seçenekleri menüsünde “Jeton ekle”'ye giderek geri ekleyebilirsiniz."
+ },
+ "readMore": {
+ "message": "Burada daha fazla okuyun."
+ },
+ "readMore2": {
+ "message": "Daha fazla okuyun."
+ },
+ "receive": {
+ "message": "Al"
+ },
+ "recipientAddress": {
+ "message": "Alıcı adresi"
+ },
+ "refundAddress": {
+ "message": "İade adresiniz"
+ },
+ "rejected": {
+ "message": "Rededildi"
+ },
+ "resetAccount": {
+ "message": "Hesabı sıfıla"
+ },
+ "restoreFromSeed": {
+ "message": "Kaynak ifadeden geri getir. Restore from seed phrase"
+ },
+ "restoreVault": {
+ "message": "Kasayı geri getir"
+ },
+ "required": {
+ "message": "Gerekli"
+ },
+ "retryWithMoreGas": {
+ "message": "Daha yüksek bir gas fiyatı ile tekrar dene"
+ },
+ "walletSeed": {
+ "message": "Cüzdan Kaynağı"
+ },
+ "revealSeedWords": {
+ "message": "Kaynak kelimelerini göster"
+ },
+ "revealSeedWordsWarning": {
+ "message": "Açık bir yerde kaynak kelimeliriniz geri getirmeyin! Bu kelimeler tüm hesaplarınızı çalmak için kullanılabilir."
+ },
+ "revert": {
+ "message": "Geri döndür"
+ },
+ "rinkeby": {
+ "message": "Rinkeby Test Ağı"
+ },
+ "ropsten": {
+ "message": "Ropsten Test Ağı"
+ },
+ "currentRpc": {
+ "message": "Geçerli RPC"
+ },
+ "connectingToMainnet": {
+ "message": "Main Ethereum Ağına bağlanıyor"
+ },
+ "connectingToRopsten": {
+ "message": "Ropsten Test Ağına bağlanıyor"
+ },
+ "connectingToKovan": {
+ "message": "Kovan Test Ağına bağlanıyor"
+ },
+ "connectingToRinkeby": {
+ "message": "Rinkeby Test Ağına bağlanıyor"
+ },
+ "connectingToUnknown": {
+ "message": "Bilinmeyen Ağa bağlanıyor"
+ },
+ "sampleAccountName": {
+ "message": "E.g. Yeni hesabım",
+ "description": "Kullanıcının hesabına okunabilir isim ekleme konseptini anlamasına yardımcı olmak."
+ },
+ "save": {
+ "message": "Kaydet"
+ },
+ "reprice_title": {
+ "message": "İşlemi Yeniden Fiyatlandır"
+ },
+ "reprice_subtitle": {
+ "message": "İşlemizi hızlandırmayı denemek için gas fiyatınızı yükseltin."
+ },
+ "saveAsFile": {
+ "message": "Dosya olarak kaydet",
+ "description": "Hesap verme işlemi"
+ },
+ "saveSeedAsFile": {
+ "message": "Kaynak Kelimelerini Dosya olarak Kaydet"
+ },
+ "search": {
+ "message": "Ara"
+ },
+ "secretPhrase": {
+ "message": "Kasanızı geri getirmek için gizli 12 kelimelik ifadenizi giriniz."
+ },
+ "newPassword8Chars": {
+ "message": "Yeni Parola (minumum 8 karakter)"
+ },
+ "seedPhraseReq": {
+ "message": "Kaynak ifadeleri 12 kelimedir."
+ },
+ "select": {
+ "message": "Seç"
+ },
+ "selectCurrency": {
+ "message": "Döviz Seç"
+ },
+ "selectService": {
+ "message": "Servis Seç"
+ },
+ "selectType": {
+ "message": "Tip Seç"
+ },
+ "send": {
+ "message": "Gönder"
+ },
+ "sendETH": {
+ "message": "ETH Gönder"
+ },
+ "sendTokens": {
+ "message": "Jeton Gönder"
+ },
+ "onlySendToEtherAddress": {
+ "message": "Ethereum adresine sadece ETH gönder."
+ },
+ "searchTokens": {
+ "message": "Jeton ara"
+ },
+ "sendTokensAnywhere": {
+ "message": "Ethereum hesabı olan birine Jeton gönder"
+ },
+ "settings": {
+ "message": "Ayarlar"
+ },
+ "info": {
+ "message": "Bilgi"
+ },
+ "shapeshiftBuy": {
+ "message": "Shapeshift ile satın al"
+ },
+ "showPrivateKeys": {
+ "message": "Özel anahtarları göster"
+ },
+ "showQRCode": {
+ "message": "QR Kodu göster"
+ },
+ "sign": {
+ "message": "İmza"
+ },
+ "signed": {
+ "message": "İmzalandı"
+ },
+ "signMessage": {
+ "message": "Mesajı İmzala"
+ },
+ "signNotice": {
+ "message": "Bu mesajı imzalamanın tehlikeli \nyan etkileri olabilir. Tamamen güvendiğiniz sitelerden \ngelen mesajları hesabınızla imzalayınız.\n Bu tehlikeli metod gelecek versiyonlarda çıkarılacaktır. "
+ },
+ "sigRequest": {
+ "message": "İmza isteği"
+ },
+ "sigRequested": {
+ "message": "İmza isteniyor"
+ },
+ "spaceBetween": {
+ "message": "Kelimeler arası sadece bir boşluk olabilir."
+ },
+ "status": {
+ "message": "Durum"
+ },
+ "stateLogs": {
+ "message": "Durum Kayıtları"
+ },
+ "stateLogsDescription": {
+ "message": "Durum kayıtları açık hesap adresinizi ve gönderilen işlemleri içerir."
+ },
+ "stateLogError": {
+ "message": "Durum kayıtlarını alma hatası"
+ },
+ "submit": {
+ "message": "Gönder"
+ },
+ "submitted": {
+ "message": "Gönderildi"
+ },
+ "supportCenter": {
+ "message": "Destek merkezimizi ziyaret edin"
+ },
+ "symbolBetweenZeroTen": {
+ "message": "Sembol 0 ve 10 karakter aralığında olmalıdır."
+ },
+ "takesTooLong": {
+ "message": "Çok mu uzun sürüyor?"
+ },
+ "terms": {
+ "message": "Kullanım şartları"
+ },
+ "testFaucet": {
+ "message": "Test Musluğu"
+ },
+ "to": {
+ "message": "Kime: "
+ },
+ "toETHviaShapeShift": {
+ "message": "ShapeShift üstünden $1'dan ETH'e",
+ "description": "system will fill in deposit type in start of message"
+ },
+ "tokenAddress": {
+ "message": "Jeton Adresi"
+ },
+ "tokenAlreadyAdded": {
+ "message": "Jeton çoktan eklenmiş."
+ },
+ "tokenBalance": {
+ "message": "Jeton bakiyeniz:"
+ },
+ "tokenSelection": {
+ "message": "Jeton arayın veya popüler jeton listemizden seçin."
+ },
+ "tokenSymbol": {
+ "message": "Jeton Sembolü"
+ },
+ "tokenWarning1": {
+ "message": "MetaMask hesabınızla aldığınız jetonların kaydını tutun. Başka bir hesapla jetonlar satın aldıysanız, o jetonlar burada gözükmeyecektir."
+ },
+ "total": {
+ "message": "Toplam"
+ },
+ "transactions": {
+ "message": "işlemler"
+ },
+ "transactionError": {
+ "message": "İşlem Hatası. Sözleşme kodundan kural dışı durum fırlatıldı."
+ },
+ "transactionMemo": {
+ "message": "İşlem notu (opsiyonel)"
+ },
+ "transactionNumber": {
+ "message": "İşlem numarası"
+ },
+ "transfers": {
+ "message": "Transferler"
+ },
+ "troubleTokenBalances": {
+ "message": "Jeton bakiyelerinizi yüklerken sorun yaşadık. Buradan izleyebilirsiniz ",
+ "description": "Jeton bakiyelerini görmek için bir link (burası) ile takip ediliyor"
+ },
+ "twelveWords": {
+ "message": "MetaMask hesaplarınızı geri getirmenin tek yolu bu 12 kelimedir.\nBu kelimeleri güvenli ve gizli bir yerde saklayın."
+ },
+ "typePassword": {
+ "message": "Parolanızı girin"
+ },
+ "uiWelcome": {
+ "message": "Yeni UI (Beta)'ya hoşgeldiniz"
+ },
+ "uiWelcomeMessage": {
+ "message": "Şu anda yeni Metamask UI kullanmaktasınız. Gözatın, jeton gönderme gibi yeni özellikleri deneyin ve herhangi bir sorunlar karşılaşırsanız bize haber verin"
+ },
+ "unapproved": {
+ "message": "Onaylanmadı"
+ },
+ "unavailable": {
+ "message": "Mevcut değil"
+ },
+ "unknown": {
+ "message": "Bilinmeyen"
+ },
+ "unknownNetwork": {
+ "message": "Bilinmeyen özel ağ"
+ },
+ "unknownNetworkId": {
+ "message": "Bilinmeyen ağ IDsi"
+ },
+ "uriErrorMsg": {
+ "message": "URIler için HTTP/HTTPS öneki gerekmektedir."
+ },
+ "usaOnly": {
+ "message": "Sadece ABD",
+ "description": "Bu dövizi sadece ABD ikamet edenler kullanabilir"
+ },
+ "usedByClients": {
+ "message": "Farklı istemciler tarafından kullanılmakta"
+ },
+ "useOldUI": {
+ "message": "Eski UI kullan"
+ },
+ "validFileImport": {
+ "message": "Almak için geçerli bir dosya seçmelisiniz"
+ },
+ "vaultCreated": {
+ "message": "Kasa Yaratıldı"
+ },
+ "viewAccount": {
+ "message": "Hesabı İncele"
+ },
+ "visitWebSite": {
+ "message": "Web sitemizi ziyaret edin"
+ },
+ "warning": {
+ "message": "Uyarı"
+ },
+ "welcomeBeta": {
+ "message": "MetaMask Beta'ya Hoşgeldiniz"
+ },
+ "whatsThis": {
+ "message": "Bu nedir?"
+ },
+ "yourSigRequested": {
+ "message": "İmzanız isteniyor"
+ },
+ "youSign": {
+ "message": "İmzalıyorsunuz"
+ }
+} \ No newline at end of file
diff --git a/app/manifest.json b/app/manifest.json
index 73496adfa..dc46f1ca4 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "__MSG_appName__",
"short_name": "__MSG_appName__",
- "version": "4.5.0",
+ "version": "4.5.5",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "__MSG_appDescription__",
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 3ad0a7863..5878cd2e8 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -20,6 +20,7 @@ const reportFailedTxToSentry = require('./lib/reportFailedTxToSentry')
const setupMetamaskMeshMetrics = require('./lib/setupMetamaskMeshMetrics')
const EdgeEncryptor = require('./edge-encryptor')
const getFirstPreferredLangCode = require('./lib/get-first-preferred-lang-code')
+const getObjStructure = require('./lib/getObjStructure')
const STORAGE_KEY = 'metamask-config'
const METAMASK_DEBUG = process.env.METAMASK_DEBUG
@@ -77,6 +78,38 @@ async function loadStateFromPersistence () {
diskStore.getState() ||
migrator.generateInitialState(firstTimeState)
+ // check if somehow state is empty
+ // this should never happen but new error reporting suggests that it has
+ // for a small number of users
+ // https://github.com/metamask/metamask-extension/issues/3919
+ if (versionedData && !versionedData.data) {
+ // try to recover from diskStore incase only localStore is bad
+ const diskStoreState = diskStore.getState()
+ if (diskStoreState && diskStoreState.data) {
+ // we were able to recover (though it might be old)
+ versionedData = diskStoreState
+ const vaultStructure = getObjStructure(versionedData)
+ raven.captureMessage('MetaMask - Empty vault found - recovered from diskStore', {
+ // "extra" key is required by Sentry
+ extra: { vaultStructure },
+ })
+ } else {
+ // unable to recover, clear state
+ versionedData = migrator.generateInitialState(firstTimeState)
+ raven.captureMessage('MetaMask - Empty vault found - unable to recover')
+ }
+ }
+
+ // report migration errors to sentry
+ migrator.on('error', (err) => {
+ // get vault structure without secrets
+ const vaultStructure = getObjStructure(versionedData)
+ raven.captureException(err, {
+ // "extra" key is required by Sentry
+ extra: { vaultStructure },
+ })
+ })
+
// migrate data
versionedData = await migrator.migrateData(versionedData)
if (!versionedData) {
@@ -84,7 +117,14 @@ async function loadStateFromPersistence () {
}
// write to disk
- if (localStore.isSupported) localStore.set(versionedData)
+ if (localStore.isSupported) {
+ localStore.set(versionedData)
+ } else {
+ // throw in setTimeout so as to not block boot
+ setTimeout(() => {
+ throw new Error('MetaMask - Localstore not supported')
+ })
+ }
// return just the data
return versionedData.data
@@ -122,9 +162,9 @@ function setupController (initState, initLangCode) {
asStream(controller.store),
debounce(1000),
storeTransform(versionifyData),
- storeTransform(syncDataWithExtension),
+ storeTransform(persistData),
(error) => {
- log.error('pump hit error', error)
+ log.error('MetaMask - Persistence pipeline failed', error)
}
)
@@ -133,7 +173,13 @@ function setupController (initState, initLangCode) {
return versionedData
}
- function syncDataWithExtension(state) {
+ function persistData(state) {
+ if (!state) {
+ throw new Error('MetaMask - updated state is missing', state)
+ }
+ if (!state.data) {
+ throw new Error('MetaMask - updated state does not have data', state)
+ }
if (localStore.isSupported) {
localStore.set(state)
.catch((err) => {
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index 2098fae27..fe1766273 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -131,7 +131,11 @@ function documentElementCheck () {
}
function blacklistedDomainCheck () {
- var blacklistedDomains = ['uscourts.gov', 'dropbox.com']
+ var blacklistedDomains = [
+ 'uscourts.gov',
+ 'dropbox.com',
+ 'webbyawards.com',
+ ]
var currentUrl = window.location.href
var currentRegex
for (let i = 0; i < blacklistedDomains.length; i++) {
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index 31e53554d..336b0d8f7 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -185,9 +185,10 @@ module.exports = class TransactionController extends EventEmitter {
async addUnapprovedTransaction (txParams) {
// validate
- await this.txGasUtil.validateTxParams(txParams)
+ const normalizedTxParams = this._normalizeTxParams(txParams)
+ this._validateTxParams(normalizedTxParams)
// construct txMeta
- let txMeta = this.txStateManager.generateTxMeta({txParams})
+ let txMeta = this.txStateManager.generateTxMeta({ txParams: normalizedTxParams })
this.addTx(txMeta)
this.emit('newUnapprovedTx', txMeta)
// add default tx params
@@ -215,7 +216,6 @@ module.exports = class TransactionController extends EventEmitter {
}
txParams.gasPrice = ethUtil.addHexPrefix(gasPrice.toString(16))
txParams.value = txParams.value || '0x0'
- if (txParams.to === null) delete txParams.to
// set gasLimit
return await this.txGasUtil.analyzeGasUsage(txMeta)
}
@@ -314,6 +314,60 @@ module.exports = class TransactionController extends EventEmitter {
// PRIVATE METHODS
//
+ _normalizeTxParams (txParams) {
+ // functions that handle normalizing of that key in txParams
+ const whiteList = {
+ from: from => ethUtil.addHexPrefix(from).toLowerCase(),
+ to: to => ethUtil.addHexPrefix(txParams.to).toLowerCase(),
+ nonce: nonce => ethUtil.addHexPrefix(nonce),
+ value: value => ethUtil.addHexPrefix(value),
+ data: data => ethUtil.addHexPrefix(data),
+ gas: gas => ethUtil.addHexPrefix(gas),
+ gasPrice: gasPrice => ethUtil.addHexPrefix(gasPrice),
+ }
+
+ // apply only keys in the whiteList
+ const normalizedTxParams = {}
+ Object.keys(whiteList).forEach((key) => {
+ if (txParams[key]) normalizedTxParams[key] = whiteList[key](txParams[key])
+ })
+
+ return normalizedTxParams
+ }
+
+ _validateTxParams (txParams) {
+ this._validateFrom(txParams)
+ this._validateRecipient(txParams)
+ if ('value' in txParams) {
+ const value = txParams.value.toString()
+ if (value.includes('-')) {
+ throw new Error(`Invalid transaction value of ${txParams.value} not a positive number.`)
+ }
+
+ if (value.includes('.')) {
+ throw new Error(`Invalid transaction value of ${txParams.value} number must be in wei`)
+ }
+ }
+ }
+
+ _validateFrom (txParams) {
+ if ( !(typeof txParams.from === 'string') ) throw new Error(`Invalid from address ${txParams.from} not a string`)
+ if (!ethUtil.isValidAddress(txParams.from)) throw new Error('Invalid from address')
+ }
+
+ _validateRecipient (txParams) {
+ if (txParams.to === '0x' || txParams.to === null ) {
+ if (txParams.data) {
+ delete txParams.to
+ } else {
+ throw new Error('Invalid recipient address')
+ }
+ } else if ( txParams.to !== undefined && !ethUtil.isValidAddress(txParams.to) ) {
+ throw new Error('Invalid recipient address')
+ }
+ return txParams
+ }
+
_markNonceDuplicatesDropped (txId) {
this.txStateManager.setTxStatusConfirmed(txId)
// get the confirmed transactions nonce and from address
diff --git a/app/scripts/lib/get-first-preferred-lang-code.js b/app/scripts/lib/get-first-preferred-lang-code.js
index 28612f763..e3635434e 100644
--- a/app/scripts/lib/get-first-preferred-lang-code.js
+++ b/app/scripts/lib/get-first-preferred-lang-code.js
@@ -2,14 +2,16 @@ const extension = require('extensionizer')
const promisify = require('pify')
const allLocales = require('../../_locales/index.json')
-const existingLocaleCodes = allLocales.map(locale => locale.code)
+const existingLocaleCodes = allLocales.map(locale => locale.code.toLowerCase().replace('_', '-'))
async function getFirstPreferredLangCode () {
const userPreferredLocaleCodes = await promisify(
extension.i18n.getAcceptLanguages,
{ errorFirst: false }
)()
- const firstPreferredLangCode = userPreferredLocaleCodes.find(code => existingLocaleCodes.includes(code))
+ const firstPreferredLangCode = userPreferredLocaleCodes
+ .map(code => code.toLowerCase())
+ .find(code => existingLocaleCodes.includes(code))
return firstPreferredLangCode || 'en'
}
diff --git a/app/scripts/lib/getObjStructure.js b/app/scripts/lib/getObjStructure.js
new file mode 100644
index 000000000..3db389507
--- /dev/null
+++ b/app/scripts/lib/getObjStructure.js
@@ -0,0 +1,33 @@
+const clone = require('clone')
+
+module.exports = getObjStructure
+
+// This will create an object that represents the structure of the given object
+// it replaces all values with the result of their type
+
+// {
+// "data": {
+// "CurrencyController": {
+// "conversionDate": "number",
+// "conversionRate": "number",
+// "currentCurrency": "string"
+// }
+// }
+
+function getObjStructure(obj) {
+ const structure = clone(obj)
+ return deepMap(structure, (value) => {
+ return value === null ? 'null' : typeof value
+ })
+}
+
+function deepMap(target = {}, visit) {
+ Object.entries(target).forEach(([key, value]) => {
+ if (typeof value === 'object' && value !== null) {
+ target[key] = deepMap(value, visit)
+ } else {
+ target[key] = visit(value)
+ }
+ })
+ return target
+}
diff --git a/app/scripts/lib/is-popup-or-notification.js b/app/scripts/lib/is-popup-or-notification.js
index e2999411f..ad3e825c0 100644
--- a/app/scripts/lib/is-popup-or-notification.js
+++ b/app/scripts/lib/is-popup-or-notification.js
@@ -3,7 +3,8 @@ module.exports = function isPopupOrNotification () {
// if (url.match(/popup.html$/) || url.match(/home.html$/)) {
// Below regexes needed for feature toggles (e.g. see line ~340 in ui/app/app.js)
// Revert below regexes to above commented out regexes before merge to master
- if (url.match(/popup.html(?:\?.+)*$/) || url.match(/home.html(?:\?.+)*$/)) {
+ if (url.match(/popup.html(?:\?.+)*$/) ||
+ url.match(/home.html(?:\?.+)*$/) || url.match(/home.html(?:#.*)*$/)) {
return 'popup'
} else {
return 'notification'
diff --git a/app/scripts/lib/migrator/index.js b/app/scripts/lib/migrator/index.js
index 4fd2cae92..85c2717ea 100644
--- a/app/scripts/lib/migrator/index.js
+++ b/app/scripts/lib/migrator/index.js
@@ -1,6 +1,9 @@
-class Migrator {
+const EventEmitter = require('events')
+
+class Migrator extends EventEmitter {
constructor (opts = {}) {
+ super()
const migrations = opts.migrations || []
// sort migrations by version
this.migrations = migrations.sort((a, b) => a.version - b.version)
@@ -12,13 +15,29 @@ class Migrator {
// run all pending migrations on meta in place
async migrateData (versionedData = this.generateInitialState()) {
+ // get all migrations that have not yet been run
const pendingMigrations = this.migrations.filter(migrationIsPending)
+ // perform each migration
for (const index in pendingMigrations) {
const migration = pendingMigrations[index]
- versionedData = await migration.migrate(versionedData)
- if (!versionedData.data) throw new Error('Migrator - migration returned empty data')
- if (versionedData.version !== undefined && versionedData.meta.version !== migration.version) throw new Error('Migrator - Migration did not update version number correctly')
+ try {
+ // attempt migration and validate
+ const migratedData = await migration.migrate(versionedData)
+ if (!migratedData.data) throw new Error('Migrator - migration returned empty data')
+ if (migratedData.version !== undefined && migratedData.meta.version !== migration.version) throw new Error('Migrator - Migration did not update version number correctly')
+ // accept the migration as good
+ versionedData = migratedData
+ } catch (err) {
+ // rewrite error message to add context without clobbering stack
+ const originalErrorMessage = err.message
+ err.message = `MetaMask Migration Error #${migration.version}: ${originalErrorMessage}`
+ console.warn(err.stack)
+ // emit error instead of throw so as to not break the run (gracefully fail)
+ this.emit('error', err)
+ // stop migrating and use state as is
+ return versionedData
+ }
}
return versionedData
diff --git a/app/scripts/lib/tx-gas-utils.js b/app/scripts/lib/tx-gas-utils.js
index 829b4c421..c579e462a 100644
--- a/app/scripts/lib/tx-gas-utils.js
+++ b/app/scripts/lib/tx-gas-utils.js
@@ -4,7 +4,7 @@ const {
BnMultiplyByFraction,
bnToHex,
} = require('./util')
-const { addHexPrefix, isValidAddress } = require('ethereumjs-util')
+const { addHexPrefix } = require('ethereumjs-util')
const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send.
/*
@@ -100,37 +100,4 @@ module.exports = class TxGasUtil {
// otherwise use blockGasLimit
return bnToHex(upperGasLimitBn)
}
-
- async validateTxParams (txParams) {
- this.validateFrom(txParams)
- this.validateRecipient(txParams)
- if ('value' in txParams) {
- const value = txParams.value.toString()
- if (value.includes('-')) {
- throw new Error(`Invalid transaction value of ${txParams.value} not a positive number.`)
- }
-
- if (value.includes('.')) {
- throw new Error(`Invalid transaction value of ${txParams.value} number must be in wei`)
- }
- }
- }
-
- validateFrom (txParams) {
- if ( !(typeof txParams.from === 'string') ) throw new Error(`Invalid from address ${txParams.from} not a string`)
- if (!isValidAddress(txParams.from)) throw new Error('Invalid from address')
- }
-
- validateRecipient (txParams) {
- if (txParams.to === '0x' || txParams.to === null ) {
- if (txParams.data) {
- delete txParams.to
- } else {
- throw new Error('Invalid recipient address')
- }
- } else if ( txParams.to !== undefined && !isValidAddress(txParams.to) ) {
- throw new Error('Invalid recipient address')
- }
- return txParams
- }
} \ No newline at end of file
diff --git a/app/scripts/lib/tx-state-manager.js b/app/scripts/lib/tx-state-manager.js
index 23c915a61..c6d10ee62 100644
--- a/app/scripts/lib/tx-state-manager.js
+++ b/app/scripts/lib/tx-state-manager.js
@@ -92,8 +92,10 @@ module.exports = class TransactionStateManager extends EventEmitter {
// or rejected tx's.
// not tx's that are pending or unapproved
if (txCount > txHistoryLimit - 1) {
- const index = transactions.findIndex((metaTx) => metaTx.status === 'confirmed' || metaTx.status === 'rejected')
- transactions.splice(index, 1)
+ let index = transactions.findIndex((metaTx) => metaTx.status === 'confirmed' || metaTx.status === 'rejected')
+ if (index !== -1) {
+ transactions.splice(index, 1)
+ }
}
transactions.push(txMeta)
this._saveTxList(transactions)
@@ -108,6 +110,10 @@ module.exports = class TransactionStateManager extends EventEmitter {
updateTx (txMeta, note) {
// validate txParams
if (txMeta.txParams) {
+ if (typeof txMeta.txParams.data === 'undefined') {
+ delete txMeta.txParams.data
+ }
+
this.validateTxParams(txMeta.txParams)
}
@@ -140,8 +146,16 @@ module.exports = class TransactionStateManager extends EventEmitter {
validateTxParams(txParams) {
Object.keys(txParams).forEach((key) => {
const value = txParams[key]
- if (typeof value !== 'string') throw new Error(`${key}: ${value} in txParams is not a string`)
- if (!ethUtil.isHexPrefixed(value)) throw new Error('is not hex prefixed, everything on txParams must be hex prefixed')
+ // validate types
+ switch (key) {
+ case 'chainId':
+ if (typeof value !== 'number' && typeof value !== 'string') throw new Error(`${key} in txParams is not a Number or hex string. got: (${value})`)
+ break
+ default:
+ if (typeof value !== 'string') throw new Error(`${key} in txParams is not a string. got: (${value})`)
+ if (!ethUtil.isHexPrefixed(value)) throw new Error(`${key} in txParams is not hex prefixed. got: (${value})`)
+ break
+ }
})
}
diff --git a/app/scripts/migrations/013.js b/app/scripts/migrations/013.js
index 8f11e510e..15a9b28d4 100644
--- a/app/scripts/migrations/013.js
+++ b/app/scripts/migrations/013.js
@@ -27,8 +27,11 @@ module.exports = {
function transformState (state) {
const newState = state
- if (newState.config.provider.type === 'testnet') {
- newState.config.provider.type = 'ropsten'
+ const { config } = newState
+ if ( config && config.provider ) {
+ if (config.provider.type === 'testnet') {
+ newState.config.provider.type = 'ropsten'
+ }
}
return newState
}
diff --git a/app/scripts/migrations/015.js b/app/scripts/migrations/015.js
index 4b839580b..5e2f9e63b 100644
--- a/app/scripts/migrations/015.js
+++ b/app/scripts/migrations/015.js
@@ -28,11 +28,14 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
- newState.TransactionController.transactions = transactions.map((txMeta) => {
- if (!txMeta.err) return txMeta
- else if (txMeta.err.message === 'Gave up submitting tx.') txMeta.status = 'failed'
- return txMeta
- })
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ if (!txMeta.err) return txMeta
+ else if (txMeta.err.message === 'Gave up submitting tx.') txMeta.status = 'failed'
+ return txMeta
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/016.js b/app/scripts/migrations/016.js
index 4fc534f1c..048c7a40e 100644
--- a/app/scripts/migrations/016.js
+++ b/app/scripts/migrations/016.js
@@ -28,14 +28,18 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
- newState.TransactionController.transactions = transactions.map((txMeta) => {
- if (!txMeta.err) return txMeta
- if (txMeta.err === 'transaction with the same hash was already imported.') {
- txMeta.status = 'submitted'
- delete txMeta.err
- }
- return txMeta
- })
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ if (!txMeta.err) return txMeta
+ if (txMeta.err === 'transaction with the same hash was already imported.') {
+ txMeta.status = 'submitted'
+ delete txMeta.err
+ }
+ return txMeta
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/017.js b/app/scripts/migrations/017.js
index 24959cd3a..5f6d906d6 100644
--- a/app/scripts/migrations/017.js
+++ b/app/scripts/migrations/017.js
@@ -27,14 +27,17 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
- newState.TransactionController.transactions = transactions.map((txMeta) => {
- if (!txMeta.status === 'failed') return txMeta
- if (txMeta.retryCount > 0 && txMeta.retryCount < 2) {
- txMeta.status = 'submitted'
- delete txMeta.err
- }
- return txMeta
- })
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ if (!txMeta.status === 'failed') return txMeta
+ if (txMeta.retryCount > 0 && txMeta.retryCount < 2) {
+ txMeta.status = 'submitted'
+ delete txMeta.err
+ }
+ return txMeta
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/018.js b/app/scripts/migrations/018.js
index d27fe3f46..bea1fe3da 100644
--- a/app/scripts/migrations/018.js
+++ b/app/scripts/migrations/018.js
@@ -29,24 +29,27 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
- newState.TransactionController.transactions = transactions.map((txMeta) => {
- // no history: initialize
- if (!txMeta.history || txMeta.history.length === 0) {
- const snapshot = txStateHistoryHelper.snapshotFromTxMeta(txMeta)
- txMeta.history = [snapshot]
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ // no history: initialize
+ if (!txMeta.history || txMeta.history.length === 0) {
+ const snapshot = txStateHistoryHelper.snapshotFromTxMeta(txMeta)
+ txMeta.history = [snapshot]
+ return txMeta
+ }
+ // has history: migrate
+ const newHistory = (
+ txStateHistoryHelper.migrateFromSnapshotsToDiffs(txMeta.history)
+ // remove empty diffs
+ .filter((entry) => {
+ return !Array.isArray(entry) || entry.length > 0
+ })
+ )
+ txMeta.history = newHistory
return txMeta
- }
- // has history: migrate
- const newHistory = (
- txStateHistoryHelper.migrateFromSnapshotsToDiffs(txMeta.history)
- // remove empty diffs
- .filter((entry) => {
- return !Array.isArray(entry) || entry.length > 0
- })
- )
- txMeta.history = newHistory
- return txMeta
- })
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/019.js b/app/scripts/migrations/019.js
index 072c96370..ce5da6859 100644
--- a/app/scripts/migrations/019.js
+++ b/app/scripts/migrations/019.js
@@ -29,32 +29,36 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
- newState.TransactionController.transactions = transactions.map((txMeta, _, txList) => {
- if (txMeta.status !== 'submitted') return txMeta
+ const transactions = newState.TransactionController.transactions
- const confirmedTxs = txList.filter((tx) => tx.status === 'confirmed')
- .filter((tx) => tx.txParams.from === txMeta.txParams.from)
- .filter((tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from)
- const highestConfirmedNonce = getHighestNonce(confirmedTxs)
+ newState.TransactionController.transactions = transactions.map((txMeta, _, txList) => {
+ if (txMeta.status !== 'submitted') return txMeta
- const pendingTxs = txList.filter((tx) => tx.status === 'submitted')
- .filter((tx) => tx.txParams.from === txMeta.txParams.from)
- .filter((tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from)
- const highestContinuousNonce = getHighestContinuousFrom(pendingTxs, highestConfirmedNonce)
+ const confirmedTxs = txList.filter((tx) => tx.status === 'confirmed')
+ .filter((tx) => tx.txParams.from === txMeta.txParams.from)
+ .filter((tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from)
+ const highestConfirmedNonce = getHighestNonce(confirmedTxs)
- const maxNonce = Math.max(highestContinuousNonce, highestConfirmedNonce)
+ const pendingTxs = txList.filter((tx) => tx.status === 'submitted')
+ .filter((tx) => tx.txParams.from === txMeta.txParams.from)
+ .filter((tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from)
+ const highestContinuousNonce = getHighestContinuousFrom(pendingTxs, highestConfirmedNonce)
- if (parseInt(txMeta.txParams.nonce, 16) > maxNonce + 1) {
- txMeta.status = 'failed'
- txMeta.err = {
- message: 'nonce too high',
- note: 'migration 019 custom error',
+ const maxNonce = Math.max(highestContinuousNonce, highestConfirmedNonce)
+
+ if (parseInt(txMeta.txParams.nonce, 16) > maxNonce + 1) {
+ txMeta.status = 'failed'
+ txMeta.err = {
+ message: 'nonce too high',
+ note: 'migration 019 custom error',
+ }
}
- }
- return txMeta
- })
+ return txMeta
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/022.js b/app/scripts/migrations/022.js
index c3c0d53ef..1fbe241e6 100644
--- a/app/scripts/migrations/022.js
+++ b/app/scripts/migrations/022.js
@@ -28,12 +28,15 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
-
- newState.TransactionController.transactions = transactions.map((txMeta) => {
- if (txMeta.status !== 'submitted' || txMeta.submittedTime) return txMeta
- txMeta.submittedTime = (new Date()).getTime()
- return txMeta
- })
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ if (txMeta.status !== 'submitted' || txMeta.submittedTime) return txMeta
+ txMeta.submittedTime = (new Date()).getTime()
+ return txMeta
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/023.js b/app/scripts/migrations/023.js
index bce0a5bea..151496b06 100644
--- a/app/scripts/migrations/023.js
+++ b/app/scripts/migrations/023.js
@@ -28,23 +28,27 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
-
- if (transactions.length <= 40) return newState
-
- let reverseTxList = transactions.reverse()
- let stripping = true
- while (reverseTxList.length > 40 && stripping) {
- let txIndex = reverseTxList.findIndex((txMeta) => {
- return (txMeta.status === 'failed' ||
- txMeta.status === 'rejected' ||
- txMeta.status === 'confirmed' ||
- txMeta.status === 'dropped')
- })
- if (txIndex < 0) stripping = false
- else reverseTxList.splice(txIndex, 1)
- }
- newState.TransactionController.transactions = reverseTxList.reverse()
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+
+ if (transactions.length <= 40) return newState
+
+ let reverseTxList = transactions.reverse()
+ let stripping = true
+ while (reverseTxList.length > 40 && stripping) {
+ let txIndex = reverseTxList.findIndex((txMeta) => {
+ return (txMeta.status === 'failed' ||
+ txMeta.status === 'rejected' ||
+ txMeta.status === 'confirmed' ||
+ txMeta.status === 'dropped')
+ })
+ if (txIndex < 0) stripping = false
+ else reverseTxList.splice(txIndex, 1)
+ }
+
+ newState.TransactionController.transactions = reverseTxList.reverse()
+ }
return newState
}
diff --git a/app/scripts/migrations/024.js b/app/scripts/migrations/024.js
new file mode 100644
index 000000000..d0b276a79
--- /dev/null
+++ b/app/scripts/migrations/024.js
@@ -0,0 +1,41 @@
+
+const version = 24
+
+/*
+
+This migration ensures that the from address in txParams is to lower case for
+all unapproved transactions
+
+*/
+
+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
+ if (!newState.TransactionController) return newState
+ const transactions = newState.TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta, _, txList) => {
+ if (
+ txMeta.status === 'unapproved' &&
+ txMeta.txParams &&
+ txMeta.txParams.from
+ ) {
+ txMeta.txParams.from = txMeta.txParams.from.toLowerCase()
+ }
+ return txMeta
+ })
+ return newState
+}
diff --git a/app/scripts/migrations/025.js b/app/scripts/migrations/025.js
new file mode 100644
index 000000000..fc3b20a44
--- /dev/null
+++ b/app/scripts/migrations/025.js
@@ -0,0 +1,61 @@
+// next version number
+const version = 25
+
+/*
+
+normalizes txParams on unconfirmed txs
+
+*/
+const ethUtil = require('ethereumjs-util')
+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
+
+ if (newState.TransactionController) {
+ if (newState.TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ if (txMeta.status !== 'unapproved') return txMeta
+ txMeta.txParams = normalizeTxParams(txMeta.txParams)
+ return txMeta
+ })
+ }
+ }
+
+ return newState
+}
+
+function normalizeTxParams (txParams) {
+ // functions that handle normalizing of that key in txParams
+ const whiteList = {
+ from: from => ethUtil.addHexPrefix(from).toLowerCase(),
+ to: to => ethUtil.addHexPrefix(txParams.to).toLowerCase(),
+ nonce: nonce => ethUtil.addHexPrefix(nonce),
+ value: value => ethUtil.addHexPrefix(value),
+ data: data => ethUtil.addHexPrefix(data),
+ gas: gas => ethUtil.addHexPrefix(gas),
+ gasPrice: gasPrice => ethUtil.addHexPrefix(gasPrice),
+ }
+
+ // apply only keys in the whiteList
+ const normalizedTxParams = {}
+ Object.keys(whiteList).forEach((key) => {
+ if (txParams[key]) normalizedTxParams[key] = whiteList[key](txParams[key])
+ })
+
+ return normalizedTxParams
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index 811e06b6b..6c4a51b32 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -34,4 +34,6 @@ module.exports = [
require('./021'),
require('./022'),
require('./023'),
+ require('./024'),
+ require('./025'),
]
diff --git a/app/scripts/migrations/template.js b/app/scripts/migrations/template.js
new file mode 100644
index 000000000..0915c6bdf
--- /dev/null
+++ b/app/scripts/migrations/template.js
@@ -0,0 +1,29 @@
+// next version number
+const version = 0
+
+/*
+
+description of migration and what it does
+
+*/
+
+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
+ return newState
+}
diff --git a/development/mock-dev.js b/development/mock-dev.js
index a1fb3a86d..f332633d5 100644
--- a/development/mock-dev.js
+++ b/development/mock-dev.js
@@ -36,15 +36,28 @@ log.setLevel('debug')
//
const qs = require('qs')
-let queryString = qs.parse(window.location.href.split('#')[1])
-let selectedView = queryString.view || 'first time'
+const routerPath = window.location.href.split('#')[1]
+let queryString = {}
+let selectedView
+
+if (routerPath) {
+ queryString = qs.parse(routerPath.split('?')[1])
+}
+
+selectedView = queryString.view || 'first time'
const firstState = states[selectedView]
updateQueryParams(selectedView)
-function updateQueryParams(newView) {
+function updateQueryParams (newView) {
queryString.view = newView
const params = qs.stringify(queryString)
- window.location.href = window.location.href.split('#')[0] + `#${params}`
+ const locationPaths = window.location.href.split('#')
+ const routerPath = locationPaths[1] || ''
+ const newPath = locationPaths[0] + '#' + routerPath.split('?')[0] + `?${params}`
+
+ if (window.location.href !== newPath) {
+ window.location.href = newPath
+ }
}
//
diff --git a/development/states/tx-list-items.js b/development/states/tx-list-items.json
index d567e3fed..d567e3fed 100644
--- a/development/states/tx-list-items.js
+++ b/development/states/tx-list-items.json
diff --git a/docs/QA_Guide.md b/docs/QA_Guide.md
new file mode 100644
index 000000000..0b7c0e023
--- /dev/null
+++ b/docs/QA_Guide.md
@@ -0,0 +1,48 @@
+# QA Guide
+
+Steps to mark a full pass of QA complete.
+* Browsers: Opera, Chrome, Firefox, Edge.
+* OS: Ubuntu, Mac OSX, Windows
+* Load older version of MetaMask and attempt to simulate updating the extension.
+* Open Developer Console in background and popup, inspect errors.
+* Watch the state logs
+ * Transactions (unapproved txs -> rejected/submitted -> confirmed)
+ * Nonces/LocalNonces
+* Vault integrity
+ * create vault
+ * Log out
+ * Log in again
+ * Log out
+ * Restore from seed
+ * Create a second account
+ * Import a loose account (not related to HD Wallet)
+ * Import old existing vault seed phrase (pref with test Ether)
+ * Download State Logs, Priv key file, seed phrase file.
+* Send Ether
+ * by address
+ * by ens name
+* Web3 API Stability
+ * Create a contract from a Ðapp (remix)
+ * Load a Ðapp that reads using events/logs (ENS)
+ * Connect to MEW/MyCypto
+ * Send a transaction from any Ðapp
+ - MEW
+ - EtherDelta
+ - Leeroy
+ - Aragon
+ - (https://tmashuang.github.io/demo-dapp)
+ * Check account balances
+* Token Management
+ * create a token with tokenfactory (http://tokenfactory.surge.sh/#/factory)
+ * Add that token to the token view
+ * Send that token to another metamask address.
+ * confirm the token arrived.
+* Send a transaction and sign a message (https://danfinlay.github.io/js-eth-personal-sign-examples/) for each keyring type
+ * hd keyring
+ * imported keyring
+* Change network from mainnet → ropsten → rinkeby → localhost (ganache)
+* Ganache set blocktime to simulate retryTx in MetaMask
+* Copy public key to clipboard
+* Export private key
+
+* Explore changes in master, target features that have been changed and break.
diff --git a/mascara/src/app/first-time/confirm-seed-screen.js b/mascara/src/app/first-time/confirm-seed-screen.js
new file mode 100644
index 000000000..438f383b1
--- /dev/null
+++ b/mascara/src/app/first-time/confirm-seed-screen.js
@@ -0,0 +1,151 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import { connect } from 'react-redux'
+import { withRouter } from 'react-router-dom'
+import classnames from 'classnames'
+import shuffle from 'lodash.shuffle'
+import { compose } from 'recompose'
+import Identicon from '../../../../ui/app/components/identicon'
+import { confirmSeedWords, showModal } from '../../../../ui/app/actions'
+import Breadcrumbs from './breadcrumbs'
+import LoadingScreen from './loading-screen'
+import { DEFAULT_ROUTE } from '../../../../ui/app/routes'
+
+class ConfirmSeedScreen extends Component {
+ static propTypes = {
+ isLoading: PropTypes.bool,
+ address: PropTypes.string,
+ seedWords: PropTypes.string,
+ confirmSeedWords: PropTypes.func,
+ history: PropTypes.object,
+ openBuyEtherModal: PropTypes.func,
+ };
+
+ static defaultProps = {
+ seedWords: '',
+ }
+
+ constructor (props) {
+ super(props)
+ const { seedWords } = props
+ this.state = {
+ selectedSeeds: [],
+ shuffledSeeds: seedWords && shuffle(seedWords.split(' ')) || [],
+ }
+ }
+
+ componentWillMount () {
+ const { seedWords, history } = this.props
+
+ if (!seedWords) {
+ history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ handleClick () {
+ const { confirmSeedWords, history, openBuyEtherModal } = this.props
+
+ confirmSeedWords()
+ .then(() => {
+ history.push(DEFAULT_ROUTE)
+ openBuyEtherModal()
+ })
+ }
+
+ render () {
+ const { seedWords } = this.props
+ const { selectedSeeds, shuffledSeeds } = this.state
+ const isValid = seedWords === selectedSeeds.map(([_, seed]) => seed).join(' ')
+
+ return (
+ <div className="first-time-flow">
+ {
+ this.props.isLoading
+ ? <LoadingScreen loadingMessage="Creating your new account" />
+ : (
+ <div className="first-view-main-wrapper">
+ <div className="first-view-main">
+ <div className="backup-phrase">
+ <Identicon address={this.props.address} diameter={70} />
+ <div className="backup-phrase__content-wrapper">
+ <div>
+ <div className="backup-phrase__title">
+ Confirm your Secret Backup Phrase
+ </div>
+ <div className="backup-phrase__body-text">
+ Please select each phrase in order to make sure it is correct.
+ </div>
+ <div className="backup-phrase__confirm-secret">
+ {selectedSeeds.map(([_, word], i) => (
+ <button
+ key={i}
+ className="backup-phrase__confirm-seed-option"
+ >
+ {word}
+ </button>
+ ))}
+ </div>
+ <div className="backup-phrase__confirm-seed-options">
+ {shuffledSeeds.map((word, i) => {
+ const isSelected = selectedSeeds
+ .filter(([index, seed]) => seed === word && index === i)
+ .length
+
+ return (
+ <button
+ key={i}
+ className={classnames('backup-phrase__confirm-seed-option', {
+ 'backup-phrase__confirm-seed-option--selected': isSelected,
+ })}
+ onClick={() => {
+ if (!isSelected) {
+ this.setState({
+ selectedSeeds: [...selectedSeeds, [i, word]],
+ })
+ } else {
+ this.setState({
+ selectedSeeds: selectedSeeds
+ .filter(([index, seed]) => !(seed === word && index === i)),
+ })
+ }
+ }}
+ >
+ {word}
+ </button>
+ )
+ })}
+ </div>
+ <button
+ className="first-time-flow__button"
+ onClick={() => isValid && this.handleClick()}
+ disabled={!isValid}
+ >
+ Confirm
+ </button>
+ </div>
+ </div>
+ <Breadcrumbs total={3} currentIndex={1} />
+ </div>
+ </div>
+ </div>
+ )
+ }
+ </div>
+ )
+ }
+}
+
+export default compose(
+ withRouter,
+ connect(
+ ({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({
+ seedWords,
+ isLoading,
+ address: selectedAddress,
+ }),
+ dispatch => ({
+ confirmSeedWords: () => dispatch(confirmSeedWords()),
+ openBuyEtherModal: () => dispatch(showModal({ name: 'DEPOSIT_ETHER'})),
+ })
+ )
+)(ConfirmSeedScreen)
diff --git a/mascara/src/app/first-time/create-password-screen.js b/mascara/src/app/first-time/create-password-screen.js
index 192da3399..6ec05e11d 100644
--- a/mascara/src/app/first-time/create-password-screen.js
+++ b/mascara/src/app/first-time/create-password-screen.js
@@ -1,20 +1,26 @@
-import EventEmitter from 'events'
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
-import classnames from 'classnames'
-import {createNewVaultAndKeychain} from '../../../../ui/app/actions'
-import LoadingScreen from './loading-screen'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'recompose'
+import { createNewVaultAndKeychain } from '../../../../ui/app/actions'
import Breadcrumbs from './breadcrumbs'
+import EventEmitter from 'events'
import Mascot from '../../../../ui/app/components/mascot'
+import classnames from 'classnames'
+import {
+ INITIALIZE_UNIQUE_IMAGE_ROUTE,
+ INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
+ INITIALIZE_NOTICE_ROUTE,
+} from '../../../../ui/app/routes'
class CreatePasswordScreen extends Component {
static propTypes = {
isLoading: PropTypes.bool.isRequired,
createAccount: PropTypes.func.isRequired,
- goToImportWithSeedPhrase: PropTypes.func.isRequired,
- goToImportAccount: PropTypes.func.isRequired,
- next: PropTypes.func.isRequired,
+ history: PropTypes.object.isRequired,
+ isInitialized: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
isMascara: PropTypes.bool.isRequired,
}
@@ -23,13 +29,21 @@ class CreatePasswordScreen extends Component {
confirmPassword: '',
}
- constructor () {
- super()
+ constructor (props) {
+ super(props)
this.animationEventEmitter = new EventEmitter()
}
+ componentWillMount () {
+ const { isInitialized, history } = this.props
+
+ if (isInitialized) {
+ history.push(INITIALIZE_NOTICE_ROUTE)
+ }
+ }
+
isValid () {
- const {password, confirmPassword} = this.state
+ const { password, confirmPassword } = this.state
if (!password || !confirmPassword) {
return false
@@ -47,93 +61,182 @@ class CreatePasswordScreen extends Component {
return
}
- const {password} = this.state
- const {createAccount, next} = this.props
+ const { password } = this.state
+ const { createAccount, history } = this.props
+ this.setState({ isLoading: true })
createAccount(password)
- .then(next)
+ .then(() => history.push(INITIALIZE_UNIQUE_IMAGE_ROUTE))
+ }
+
+ renderFields () {
+ const { isMascara, history } = this.props
+
+ return (
+ <div className={classnames({ 'first-view-main-wrapper': !isMascara })}>
+ <div className={classnames({
+ 'first-view-main': !isMascara,
+ 'first-view-main__mascara': isMascara,
+ })}>
+ {isMascara && <div className="mascara-info first-view-phone-invisible">
+ <Mascot
+ animationEventEmitter={this.animationEventEmitter}
+ width="225"
+ height="225"
+ />
+ <div className="info">
+ MetaMask is a secure identity vault for Ethereum.
+ </div>
+ <div className="info">
+ It allows you to hold ether & tokens, and interact with decentralized applications.
+ </div>
+ </div>}
+ <div className="create-password">
+ <div className="create-password__title">
+ Create Password
+ </div>
+ <input
+ className="first-time-flow__input"
+ type="password"
+ placeholder="New Password (min 8 characters)"
+ onChange={e => this.setState({password: e.target.value})}
+ />
+ <input
+ className="first-time-flow__input create-password__confirm-input"
+ type="password"
+ placeholder="Confirm Password"
+ onChange={e => this.setState({confirmPassword: e.target.value})}
+ />
+ <button
+ className="first-time-flow__button"
+ disabled={!this.isValid()}
+ onClick={this.createAccount}
+ >
+ Create
+ </button>
+ <a
+ href=""
+ className="first-time-flow__link create-password__import-link"
+ onClick={e => {
+ e.preventDefault()
+ history.push(INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE)
+ }}
+ >
+ Import with seed phrase
+ </a>
+ { /* }
+ <a
+ href=""
+ className="first-time-flow__link create-password__import-link"
+ onClick={e => {
+ e.preventDefault()
+ history.push(INITIALIZE_IMPORT_ACCOUNT_ROUTE)
+ }}
+ >
+ Import an account
+ </a>
+ { */ }
+ <Breadcrumbs total={3} currentIndex={0} />
+ </div>
+ </div>
+ </div>
+ )
}
render () {
- const { isLoading, goToImportWithSeedPhrase, isMascara } = this.props
-
- return isLoading
- ? <LoadingScreen loadingMessage="Creating your new account" />
- : (
- <div className={classnames({ 'first-view-main-wrapper': !isMascara })}>
- <div className={classnames({
- 'first-view-main': !isMascara,
- 'first-view-main__mascara': isMascara,
- })}>
- {isMascara && <div className="mascara-info first-view-phone-invisible">
- <Mascot
- animationEventEmitter={this.animationEventEmitter}
- width="225"
- height="225"
- />
- <div className="info">
- MetaMask is a secure identity vault for Ethereum.
- </div>
- <div className="info">
- It allows you to hold ether & tokens, and interact with decentralized applications.
- </div>
- </div>}
- <div className="create-password">
- <div className="create-password__title">
- Create Password
- </div>
- <input
- className="first-time-flow__input"
- type="password"
- placeholder="New Password (min 8 characters)"
- onChange={e => this.setState({password: e.target.value})}
- />
- <input
- className="first-time-flow__input create-password__confirm-input"
- type="password"
- placeholder="Confirm Password"
- onChange={e => this.setState({confirmPassword: e.target.value})}
- />
- <button
- className="first-time-flow__button"
- disabled={!this.isValid()}
- onClick={this.createAccount}
- >
- Create
- </button>
- <a
- href=""
- className="first-time-flow__link create-password__import-link"
- onClick={e => {
- e.preventDefault()
- goToImportWithSeedPhrase()
- }}
- >
- Import with seed phrase
- </a>
- { /* }
- <a
- href=""
- className="first-time-flow__link create-password__import-link"
- onClick={e => {
- e.preventDefault()
- goToImportAccount()
- }}
- >
- Import an account
- </a>
- { */ }
- <Breadcrumbs total={3} currentIndex={0} />
+ const { history, isMascara } = this.props
+
+ return (
+ <div className={classnames({ 'first-view-main-wrapper': !isMascara })}>
+ <div className={classnames({
+ 'first-view-main': !isMascara,
+ 'first-view-main__mascara': isMascara,
+ })}>
+ {isMascara && <div className="mascara-info first-view-phone-invisible">
+ <Mascot
+ animationEventEmitter={this.animationEventEmitter}
+ width="225"
+ height="225"
+ />
+ <div className="info">
+ MetaMask is a secure identity vault for Ethereum.
+ </div>
+ <div className="info">
+ It allows you to hold ether & tokens, and interact with decentralized applications.
</div>
+ </div>}
+ <div className="create-password">
+ <div className="create-password__title">
+ Create Password
+ </div>
+ <input
+ className="first-time-flow__input"
+ type="password"
+ placeholder="New Password (min 8 characters)"
+ onChange={e => this.setState({password: e.target.value})}
+ />
+ <input
+ className="first-time-flow__input create-password__confirm-input"
+ type="password"
+ placeholder="Confirm Password"
+ onChange={e => this.setState({confirmPassword: e.target.value})}
+ />
+ <button
+ className="first-time-flow__button"
+ disabled={!this.isValid()}
+ onClick={this.createAccount}
+ >
+ Create
+ </button>
+ <a
+ href=""
+ className="first-time-flow__link create-password__import-link"
+ onClick={e => {
+ e.preventDefault()
+ history.push(INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE)
+ }}
+ >
+ Import with seed phrase
+ </a>
+ { /* }
+ <a
+ href=""
+ className="first-time-flow__link create-password__import-link"
+ onClick={e => {
+ e.preventDefault()
+ history.push(INITIALIZE_IMPORT_ACCOUNT_ROUTE)
+ }}
+ >
+ Import an account
+ </a>
+ { */ }
+ <Breadcrumbs total={3} currentIndex={0} />
</div>
</div>
- )
+ </div>
+ )
+ }
+}
+
+const mapStateToProps = ({ metamask, appState }) => {
+ const { isInitialized, isUnlocked, isMascara, noActiveNotices } = metamask
+ const { isLoading } = appState
+
+ return {
+ isLoading,
+ isInitialized,
+ isUnlocked,
+ isMascara,
+ noActiveNotices,
}
}
-export default connect(
- ({ appState: { isLoading }, metamask: { isMascara } }) => ({ isLoading, isMascara }),
- dispatch => ({
- createAccount: password => dispatch(createNewVaultAndKeychain(password)),
- })
+export default compose(
+ withRouter,
+ connect(
+ mapStateToProps,
+ dispatch => ({
+ createAccount: password => dispatch(createNewVaultAndKeychain(password)),
+ })
+ )
)(CreatePasswordScreen)
diff --git a/mascara/src/app/first-time/import-seed-phrase-screen.js b/mascara/src/app/first-time/import-seed-phrase-screen.js
index 86f02ceac..5c2b21b0a 100644
--- a/mascara/src/app/first-time/import-seed-phrase-screen.js
+++ b/mascara/src/app/first-time/import-seed-phrase-screen.js
@@ -8,16 +8,16 @@ import {
displayWarning,
unMarkPasswordForgotten,
} from '../../../../ui/app/actions'
+import { DEFAULT_ROUTE, INITIALIZE_NOTICE_ROUTE } from '../../../../ui/app/routes'
class ImportSeedPhraseScreen extends Component {
static propTypes = {
warning: PropTypes.string,
- back: PropTypes.func.isRequired,
- next: PropTypes.func.isRequired,
createNewVaultAndRestore: PropTypes.func.isRequired,
hideWarning: PropTypes.func.isRequired,
displayWarning: PropTypes.func,
leaveImportSeedScreenState: PropTypes.func,
+ history: PropTypes.object,
};
state = {
@@ -64,14 +64,14 @@ class ImportSeedPhraseScreen extends Component {
const { password, seedPhrase } = this.state
const {
createNewVaultAndRestore,
- next,
displayWarning,
leaveImportSeedScreenState,
+ history,
} = this.props
leaveImportSeedScreenState()
createNewVaultAndRestore(password, this.parseSeedPhrase(seedPhrase))
- .then(next)
+ .then(() => history.push(INITIALIZE_NOTICE_ROUTE))
}
render () {
@@ -86,7 +86,7 @@ class ImportSeedPhraseScreen extends Component {
className="import-account__back-button"
onClick={e => {
e.preventDefault()
- this.props.back()
+ this.props.history.goBack()
}}
href="#"
>
diff --git a/mascara/src/app/first-time/index.js b/mascara/src/app/first-time/index.js
index 0cc3b4b0e..01e5d67a6 100644
--- a/mascara/src/app/first-time/index.js
+++ b/mascara/src/app/first-time/index.js
@@ -1,17 +1,26 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
+import { withRouter, Switch, Route } from 'react-router-dom'
+import { compose } from 'recompose'
import CreatePasswordScreen from './create-password-screen'
import UniqueImageScreen from './unique-image-screen'
import NoticeScreen from './notice-screen'
-import BackupPhraseScreen from './backup-phrase-screen'
+import BackupPhraseScreen from './seed-screen'
import ImportAccountScreen from './import-account-screen'
import ImportSeedPhraseScreen from './import-seed-phrase-screen'
+import ConfirmSeed from './confirm-seed-screen'
import {
- onboardingBuyEthView,
- unMarkPasswordForgotten,
- showModal,
-} from '../../../../ui/app/actions'
+ INITIALIZE_ROUTE,
+ INITIALIZE_IMPORT_ACCOUNT_ROUTE,
+ INITIALIZE_UNIQUE_IMAGE_ROUTE,
+ INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
+ INITIALIZE_NOTICE_ROUTE,
+ INITIALIZE_BACKUP_PHRASE_ROUTE,
+ INITIALIZE_CONFIRM_SEED_ROUTE,
+ INITIALIZE_CREATE_PASSWORD_ROUTE,
+} from '../../../../ui/app/routes'
+import WelcomeScreen from '../../../../ui/app/welcome-screen'
class FirstTimeFlow extends Component {
@@ -20,6 +29,10 @@ class FirstTimeFlow extends Component {
seedWords: PropTypes.string,
address: PropTypes.string,
noActiveNotices: PropTypes.bool,
+ goToBuyEtherView: PropTypes.func,
+ isUnlocked: PropTypes.bool,
+ history: PropTypes.object,
+ welcomeScreenSeen: PropTypes.bool,
};
static defaultProps = {
@@ -28,145 +41,53 @@ class FirstTimeFlow extends Component {
noActiveNotices: false,
};
- static SCREEN_TYPE = {
- CREATE_PASSWORD: 'create_password',
- IMPORT_ACCOUNT: 'import_account',
- IMPORT_SEED_PHRASE: 'import_seed_phrase',
- UNIQUE_IMAGE: 'unique_image',
- NOTICE: 'notice',
- BACK_UP_PHRASE: 'back_up_phrase',
- CONFIRM_BACK_UP_PHRASE: 'confirm_back_up_phrase',
- LOADING: 'loading',
- };
-
- constructor (props) {
- super(props)
- this.state = {
- screenType: this.getScreenType(),
- }
- }
-
- setScreenType (screenType) {
- this.setState({ screenType })
- }
-
- getScreenType () {
- const {
- isInitialized,
- seedWords,
- noActiveNotices,
- forgottenPassword,
- } = this.props
- const {SCREEN_TYPE} = FirstTimeFlow
-
- // return SCREEN_TYPE.NOTICE
-
- if (forgottenPassword) {
- return SCREEN_TYPE.IMPORT_SEED_PHRASE
- }
- if (!isInitialized) {
- return SCREEN_TYPE.CREATE_PASSWORD
- }
-
- if (!noActiveNotices) {
- return SCREEN_TYPE.NOTICE
- }
-
- if (seedWords) {
- return SCREEN_TYPE.BACK_UP_PHRASE
- }
- };
-
- renderScreen () {
- const {SCREEN_TYPE} = FirstTimeFlow
- const {
- openBuyEtherModal,
- address,
- restoreCreatePasswordScreen,
- forgottenPassword,
- leaveImportSeedScreenState,
- } = this.props
-
- switch (this.state.screenType) {
- case SCREEN_TYPE.CREATE_PASSWORD:
- return (
- <CreatePasswordScreen
- next={() => this.setScreenType(SCREEN_TYPE.UNIQUE_IMAGE)}
- goToImportAccount={() => this.setScreenType(SCREEN_TYPE.IMPORT_ACCOUNT)}
- goToImportWithSeedPhrase={() => this.setScreenType(SCREEN_TYPE.IMPORT_SEED_PHRASE)}
- />
- )
- case SCREEN_TYPE.IMPORT_ACCOUNT:
- return (
- <ImportAccountScreen
- back={() => this.setScreenType(SCREEN_TYPE.CREATE_PASSWORD)}
- next={() => this.setScreenType(SCREEN_TYPE.NOTICE)}
- />
- )
- case SCREEN_TYPE.IMPORT_SEED_PHRASE:
- return (
- <ImportSeedPhraseScreen
- back={() => {
- leaveImportSeedScreenState()
- this.setScreenType(SCREEN_TYPE.CREATE_PASSWORD)
- }}
- next={() => {
- const newScreenType = forgottenPassword ? null : SCREEN_TYPE.NOTICE
- this.setScreenType(newScreenType)
- }}
- />
- )
- case SCREEN_TYPE.UNIQUE_IMAGE:
- return (
- <UniqueImageScreen
- next={() => this.setScreenType(SCREEN_TYPE.NOTICE)}
- />
- )
- case SCREEN_TYPE.NOTICE:
- return (
- <NoticeScreen
- next={() => this.setScreenType(SCREEN_TYPE.BACK_UP_PHRASE)}
- />
- )
- case SCREEN_TYPE.BACK_UP_PHRASE:
- return (
- <BackupPhraseScreen
- next={() => openBuyEtherModal()}
- />
- )
- default:
- return <noscript />
- }
- }
-
render () {
return (
<div className="first-time-flow">
- {this.renderScreen()}
+ <Switch>
+ <Route exact path={INITIALIZE_IMPORT_ACCOUNT_ROUTE} component={ImportAccountScreen} />
+ <Route
+ exact
+ path={INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE}
+ component={ImportSeedPhraseScreen}
+ />
+ <Route exact path={INITIALIZE_UNIQUE_IMAGE_ROUTE} component={UniqueImageScreen} />
+ <Route exact path={INITIALIZE_NOTICE_ROUTE} component={NoticeScreen} />
+ <Route exact path={INITIALIZE_BACKUP_PHRASE_ROUTE} component={BackupPhraseScreen} />
+ <Route exact path={INITIALIZE_CONFIRM_SEED_ROUTE} component={ConfirmSeed} />
+ <Route exact path={INITIALIZE_CREATE_PASSWORD_ROUTE} component={CreatePasswordScreen} />
+ <Route exact path={INITIALIZE_ROUTE} component={WelcomeScreen} />
+ </Switch>
</div>
)
}
-
}
-export default connect(
- ({
- metamask: {
- isInitialized,
- seedWords,
- noActiveNotices,
- selectedAddress,
- forgottenPassword,
- }
- }) => ({
+const mapStateToProps = ({ metamask }) => {
+ const {
+ isInitialized,
+ seedWords,
+ noActiveNotices,
+ selectedAddress,
+ forgottenPassword,
+ isMascara,
+ isUnlocked,
+ welcomeScreenSeen,
+ } = metamask
+
+ return {
+ isMascara,
isInitialized,
seedWords,
noActiveNotices,
address: selectedAddress,
forgottenPassword,
- }),
- dispatch => ({
- leaveImportSeedScreenState: () => dispatch(unMarkPasswordForgotten()),
- openBuyEtherModal: () => dispatch(showModal({ name: 'DEPOSIT_ETHER'})),
- })
+ isUnlocked,
+ welcomeScreenSeen,
+ }
+}
+
+export default compose(
+ withRouter,
+ connect(mapStateToProps)
)(FirstTimeFlow)
diff --git a/mascara/src/app/first-time/notice-screen.js b/mascara/src/app/first-time/notice-screen.js
index cbd8f9f5b..a449ccfa9 100644
--- a/mascara/src/app/first-time/notice-screen.js
+++ b/mascara/src/app/first-time/notice-screen.js
@@ -1,11 +1,14 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Markdown from 'react-markdown'
-import {connect} from 'react-redux'
+import { connect } from 'react-redux'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'recompose'
import debounce from 'lodash.debounce'
-import {markNoticeRead} from '../../../../ui/app/actions'
+import { markNoticeRead } from '../../../../ui/app/actions'
import Identicon from '../../../../ui/app/components/identicon'
import Breadcrumbs from './breadcrumbs'
+import { INITIALIZE_BACKUP_PHRASE_ROUTE } from '../../../../ui/app/routes'
import LoadingScreen from './loading-screen'
class NoticeScreen extends Component {
@@ -16,8 +19,15 @@ class NoticeScreen extends Component {
date: PropTypes.string,
body: PropTypes.string,
}),
- next: PropTypes.func.isRequired,
+ location: PropTypes.shape({
+ state: PropTypes.shape({
+ next: PropTypes.func.isRequired,
+ }),
+ }),
markNoticeRead: PropTypes.func,
+ history: PropTypes.object,
+ isLoading: PropTypes.bool,
+ noActiveNotices: PropTypes.bool,
};
static defaultProps = {
@@ -29,17 +39,24 @@ class NoticeScreen extends Component {
}
componentDidMount () {
+ if (this.props.noActiveNotices) {
+ this.props.history.push(INITIALIZE_BACKUP_PHRASE_ROUTE)
+ }
+
this.onScroll()
}
acceptTerms = () => {
- const { markNoticeRead, lastUnreadNotice, next } = this.props
- const defer = markNoticeRead(lastUnreadNotice)
- .then(() => this.setState({ atBottom: false }))
-
- if ((/terms/gi).test(lastUnreadNotice.title)) {
- defer.then(next)
- }
+ const { markNoticeRead, lastUnreadNotice, history } = this.props
+ markNoticeRead(lastUnreadNotice)
+ .then(hasActiveNotices => {
+ if (!hasActiveNotices) {
+ history.push(INITIALIZE_BACKUP_PHRASE_ROUTE)
+ } else {
+ this.setState({ atBottom: false })
+ this.onScroll()
+ }
+ })
}
onScroll = debounce(() => {
@@ -64,27 +81,29 @@ class NoticeScreen extends Component {
isLoading
? <LoadingScreen />
: (
- <div className="first-view-main-wrapper">
- <div className="first-view-main">
- <div
- className="tou"
- onScroll={this.onScroll}
- >
- <Identicon address={address} diameter={70} />
- <div className="tou__title">{title}</div>
- <Markdown
- className="tou__body markdown"
- source={body}
- skipHtml
- />
- <button
- className="first-time-flow__button"
- onClick={atBottom && this.acceptTerms}
- disabled={!atBottom}
+ <div className="first-time-flow">
+ <div className="first-view-main-wrapper">
+ <div className="first-view-main">
+ <div
+ className="tou"
+ onScroll={this.onScroll}
>
- Accept
- </button>
- <Breadcrumbs total={3} currentIndex={2} />
+ <Identicon address={address} diameter={70} />
+ <div className="tou__title">{title}</div>
+ <Markdown
+ className="tou__body markdown"
+ source={body}
+ skipHtml
+ />
+ <button
+ className="first-time-flow__button"
+ onClick={atBottom && this.acceptTerms}
+ disabled={!atBottom}
+ >
+ Accept
+ </button>
+ <Breadcrumbs total={3} currentIndex={2} />
+ </div>
</div>
</div>
</div>
@@ -93,12 +112,24 @@ class NoticeScreen extends Component {
}
}
-export default connect(
- ({ metamask: { selectedAddress, lastUnreadNotice }, appState: { isLoading } }) => ({
- lastUnreadNotice,
+const mapStateToProps = ({ metamask, appState }) => {
+ const { selectedAddress, lastUnreadNotice, noActiveNotices } = metamask
+ const { isLoading } = appState
+
+ return {
address: selectedAddress,
- }),
- dispatch => ({
- markNoticeRead: notice => dispatch(markNoticeRead(notice)),
- })
+ lastUnreadNotice,
+ noActiveNotices,
+ isLoading,
+ }
+}
+
+export default compose(
+ withRouter,
+ connect(
+ mapStateToProps,
+ dispatch => ({
+ markNoticeRead: notice => dispatch(markNoticeRead(notice)),
+ })
+ )
)(NoticeScreen)
diff --git a/mascara/src/app/first-time/backup-phrase-screen.js b/mascara/src/app/first-time/seed-screen.js
index 6819abcf3..d004be77b 100644
--- a/mascara/src/app/first-time/backup-phrase-screen.js
+++ b/mascara/src/app/first-time/seed-screen.js
@@ -1,13 +1,13 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
-import {connect} from 'react-redux'
+import { connect } from 'react-redux'
import classnames from 'classnames'
-import shuffle from 'lodash.shuffle'
-import {compose, onlyUpdateForPropTypes} from 'recompose'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'recompose'
import Identicon from '../../../../ui/app/components/identicon'
-import {confirmSeedWords} from '../../../../ui/app/actions'
import Breadcrumbs from './breadcrumbs'
import LoadingScreen from './loading-screen'
+import { DEFAULT_ROUTE, INITIALIZE_CONFIRM_SEED_ROUTE } from '../../../../ui/app/routes'
const LockIcon = props => (
<svg
@@ -36,34 +36,32 @@ const LockIcon = props => (
/>
</g>
</svg>
-);
+)
class BackupPhraseScreen extends Component {
static propTypes = {
isLoading: PropTypes.bool.isRequired,
address: PropTypes.string.isRequired,
- seedWords: PropTypes.string.isRequired,
- next: PropTypes.func.isRequired,
- confirmSeedWords: PropTypes.func.isRequired,
+ seedWords: PropTypes.string,
+ history: PropTypes.object,
};
static defaultProps = {
- seedWords: ''
- };
-
- static PAGE = {
- SECRET: 'secret',
- CONFIRM: 'confirm'
- };
+ seedWords: '',
+ }
- constructor(props) {
- const {seedWords} = props
+ constructor (props) {
super(props)
this.state = {
isShowingSecret: false,
- page: BackupPhraseScreen.PAGE.SECRET,
- selectedSeeds: [],
- shuffledSeeds: seedWords && shuffle(seedWords.split(' ')),
+ }
+ }
+
+ componentWillMount () {
+ const { seedWords, history } = this.props
+
+ if (!seedWords) {
+ history.push(DEFAULT_ROUTE)
}
}
@@ -73,7 +71,7 @@ class BackupPhraseScreen extends Component {
return (
<div className="backup-phrase__secret">
<div className={classnames('backup-phrase__secret-words', {
- 'backup-phrase__secret-words--hidden': !isShowingSecret
+ 'backup-phrase__secret-words--hidden': !isShowingSecret,
})}>
{this.props.seedWords}
</div>
@@ -96,6 +94,7 @@ class BackupPhraseScreen extends Component {
renderSecretScreen () {
const { isShowingSecret } = this.state
+ const { history } = this.props
return (
<div className="backup-phrase__content-wrapper">
@@ -124,10 +123,7 @@ class BackupPhraseScreen extends Component {
<div className="backup-phrase__next-button">
<button
className="first-time-flow__button"
- onClick={() => isShowingSecret && this.setState({
- isShowingSecret: false,
- page: BackupPhraseScreen.PAGE.CONFIRM,
- })}
+ onClick={() => isShowingSecret && history.push(INITIALIZE_CONFIRM_SEED_ROUTE)}
disabled={!isShowingSecret}
>
Next
@@ -138,99 +134,6 @@ class BackupPhraseScreen extends Component {
)
}
- renderConfirmationScreen() {
- const { seedWords, confirmSeedWords, next } = this.props;
- const { selectedSeeds, shuffledSeeds } = this.state;
- const isValid = seedWords === selectedSeeds.map(([_, seed]) => seed).join(' ')
-
- return (
- <div className="backup-phrase__content-wrapper">
- <div>
- <div className="backup-phrase__title">Confirm your Secret Backup Phrase</div>
- <div className="backup-phrase__body-text">
- Please select each phrase in order to make sure it is correct.
- </div>
- <div className="backup-phrase__confirm-secret">
- {selectedSeeds.map(([_, word], i) => (
- <button
- key={i}
- className="backup-phrase__confirm-seed-option"
- >
- {word}
- </button>
- ))}
- </div>
- <div className="backup-phrase__confirm-seed-options">
- {shuffledSeeds.map((word, i) => {
- const isSelected = selectedSeeds
- .filter(([index, seed]) => seed === word && index === i)
- .length
-
- return (
- <button
- key={i}
- className={classnames('backup-phrase__confirm-seed-option', {
- 'backup-phrase__confirm-seed-option--selected': isSelected
- })}
- onClick={() => {
- if (!isSelected) {
- this.setState({
- selectedSeeds: [...selectedSeeds, [i, word]]
- })
- } else {
- this.setState({
- selectedSeeds: selectedSeeds
- .filter(([index, seed]) => !(seed === word && index === i))
- })
- }
- }}
- >
- {word}
- </button>
- )
- })}
- </div>
- <button
- className="first-time-flow__button"
- onClick={() => isValid && confirmSeedWords().then(next)}
- disabled={!isValid}
- >
- Confirm
- </button>
- </div>
- </div>
- )
- }
-
- renderBack () {
- return this.state.page === BackupPhraseScreen.PAGE.CONFIRM
- ? (
- <a
- className="backup-phrase__back-button"
- onClick={e => {
- e.preventDefault()
- this.setState({
- page: BackupPhraseScreen.PAGE.SECRET
- })
- }}
- href="#"
- >
- {`< Back`}
- </a>
- )
- : null
- }
-
- renderContent () {
- switch (this.state.page) {
- case BackupPhraseScreen.PAGE.CONFIRM:
- return this.renderConfirmationScreen()
- case BackupPhraseScreen.PAGE.SECRET:
- default:
- return this.renderSecretScreen()
- }
- }
-
render () {
return this.props.isLoading
? <LoadingScreen loadingMessage="Creating your new account" />
@@ -238,9 +141,8 @@ class BackupPhraseScreen extends Component {
<div className="first-view-main-wrapper">
<div className="first-view-main">
<div className="backup-phrase">
- {this.renderBack()}
<Identicon address={this.props.address} diameter={70} />
- {this.renderContent()}
+ {this.renderSecretScreen()}
</div>
</div>
</div>
@@ -249,15 +151,12 @@ class BackupPhraseScreen extends Component {
}
export default compose(
- onlyUpdateForPropTypes,
+ withRouter,
connect(
({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({
seedWords,
isLoading,
address: selectedAddress,
- }),
- dispatch => ({
- confirmSeedWords: () => dispatch(confirmSeedWords()),
})
)
)(BackupPhraseScreen)
diff --git a/mascara/src/app/first-time/unique-image-screen.js b/mascara/src/app/first-time/unique-image-screen.js
index ede17ee3d..9555e5318 100644
--- a/mascara/src/app/first-time/unique-image-screen.js
+++ b/mascara/src/app/first-time/unique-image-screen.js
@@ -1,13 +1,16 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'recompose'
import {connect} from 'react-redux'
import Identicon from '../../../../ui/app/components/identicon'
import Breadcrumbs from './breadcrumbs'
+import { INITIALIZE_NOTICE_ROUTE } from '../../../../ui/app/routes'
class UniqueImageScreen extends Component {
static propTypes = {
address: PropTypes.string,
- next: PropTypes.func.isRequired,
+ history: PropTypes.object,
}
render () {
@@ -25,7 +28,7 @@ class UniqueImageScreen extends Component {
</div>
<button
className="first-time-flow__button"
- onClick={this.props.next}
+ onClick={() => this.props.history.push(INITIALIZE_NOTICE_ROUTE)}
>
Next
</button>
@@ -37,8 +40,11 @@ class UniqueImageScreen extends Component {
}
}
-export default connect(
- ({ metamask: { selectedAddress } }) => ({
- address: selectedAddress,
- })
+export default compose(
+ withRouter,
+ connect(
+ ({ metamask: { selectedAddress } }) => ({
+ address: selectedAddress,
+ })
+ )
)(UniqueImageScreen)
diff --git a/old-ui/app/util.js b/old-ui/app/util.js
index 3f8b4dcc3..962832ce7 100644
--- a/old-ui/app/util.js
+++ b/old-ui/app/util.js
@@ -231,6 +231,7 @@ function exportAsFile (filename, data) {
window.navigator.msSaveBlob(blob, filename)
} else {
const elem = window.document.createElement('a')
+ elem.target = '_blank'
elem.href = window.URL.createObjectURL(blob)
elem.download = filename
document.body.appendChild(elem)
diff --git a/package-lock.json b/package-lock.json
index 2c1589bec..e29355da5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5112,7 +5112,7 @@
"lodash": "4.17.4",
"object.assign": "4.1.0",
"object.values": "1.0.4",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"enzyme-adapter-utils": {
@@ -5123,7 +5123,7 @@
"requires": {
"lodash": "4.17.4",
"object.assign": "4.1.0",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"errno": {
@@ -5454,7 +5454,7 @@
"doctrine": "2.0.2",
"has": "1.0.1",
"jsx-ast-utils": "2.0.1",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"eslint-scope": {
@@ -10394,6 +10394,18 @@
"request": "2.83.0"
}
},
+ "history": {
+ "version": "4.7.2",
+ "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz",
+ "integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==",
+ "requires": {
+ "invariant": "2.2.2",
+ "loose-envify": "1.3.1",
+ "resolve-pathname": "2.2.0",
+ "value-equal": "0.4.0",
+ "warning": "3.0.0"
+ }
+ },
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -18886,9 +18898,9 @@
}
},
"prop-types": {
- "version": "15.6.0",
- "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
- "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
+ "version": "15.6.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
+ "integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==",
"requires": {
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
@@ -19316,7 +19328,7 @@
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"react-addons-css-transition-group": {
@@ -19335,7 +19347,7 @@
"chain-function": "1.0.0",
"dom-helpers": "3.3.1",
"loose-envify": "1.3.1",
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"warning": "3.0.0"
}
}
@@ -19355,7 +19367,7 @@
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"react-hyperscript": {
@@ -19368,7 +19380,7 @@
"resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.1.2.tgz",
"integrity": "sha512-uAfIE4XEfBNXqjqQvd31Eoo20UkVk0xHJpfgP8HRT8gLczaN4LEmB1e2d8CJ5ziEt4clWnsk/1+QhTN27iO/EA==",
"requires": {
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"react-markdown": {
@@ -19376,7 +19388,7 @@
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-3.1.4.tgz",
"integrity": "sha512-i8WueytRXbYzyJ2GemIOTMRx/NigPo8r4m3R/KvWD7r+PxPyc9ke66cI3DR7MBRSS+nVG82VWEgRDE1VaZUCqA==",
"requires": {
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"remark-parse": "4.0.0",
"unified": "6.1.6",
"unist-util-visit": "1.3.0",
@@ -19389,7 +19401,7 @@
"integrity": "sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ==",
"requires": {
"performance-now": "0.2.0",
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"raf": "3.4.0"
},
"dependencies": {
@@ -19410,7 +19422,49 @@
"lodash": "4.17.4",
"lodash-es": "4.17.4",
"loose-envify": "1.3.1",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
+ }
+ },
+ "react-router": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.2.0.tgz",
+ "integrity": "sha512-DY6pjwRhdARE4TDw7XjxjZsbx9lKmIcyZoZ+SDO7SBJ1KUeWNxT22Kara2AC7u6/c2SYEHlEDLnzBCcNhLE8Vg==",
+ "requires": {
+ "history": "4.7.2",
+ "hoist-non-react-statics": "2.3.1",
+ "invariant": "2.2.2",
+ "loose-envify": "1.3.1",
+ "path-to-regexp": "1.7.0",
+ "prop-types": "15.6.1",
+ "warning": "3.0.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "path-to-regexp": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
+ "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
+ "requires": {
+ "isarray": "0.0.1"
+ }
+ }
+ }
+ },
+ "react-router-dom": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.2.2.tgz",
+ "integrity": "sha512-cHMFC1ZoLDfEaMFoKTjN7fry/oczMgRt5BKfMAkTu5zEuJvUiPp1J8d0eXSVTnBh6pxlbdqDhozunOOLtmKfPA==",
+ "requires": {
+ "history": "4.7.2",
+ "invariant": "2.2.2",
+ "loose-envify": "1.3.1",
+ "prop-types": "15.6.1",
+ "react-router": "4.2.0",
+ "warning": "3.0.0"
}
},
"react-select": {
@@ -19419,7 +19473,7 @@
"integrity": "sha512-c4CdxweEHN9ra85HGWjSjIMBlJ5c0fsIXOymLFZS5UbZEQCiJGHnZTVLTt6/wDh8RKQnxl85gHUwzhG5XZLcyw==",
"requires": {
"classnames": "2.2.5",
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"react-input-autosize": "2.1.2"
}
},
@@ -19428,7 +19482,7 @@
"resolved": "https://registry.npmjs.org/react-simple-file-input/-/react-simple-file-input-2.0.1.tgz",
"integrity": "sha1-Fa1P/Hj+sbiCZJrWsBwDPvJ1ceY=",
"requires": {
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"react-test-renderer": {
@@ -19472,7 +19526,7 @@
"resolved": "https://registry.npmjs.org/react-toggle-button/-/react-toggle-button-2.2.0.tgz",
"integrity": "sha1-obkhQ6oN9BRkL8sUHwh59UW8Wok=",
"requires": {
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"react-motion": "0.5.2"
}
},
@@ -19499,7 +19553,7 @@
"classnames": "2.2.5",
"dom-helpers": "3.3.1",
"loose-envify": "1.3.1",
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"warning": "3.0.0"
}
},
@@ -20058,6 +20112,11 @@
"value-or-function": "3.0.0"
}
},
+ "resolve-pathname": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz",
+ "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg=="
+ },
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -23736,6 +23795,11 @@
"spdx-expression-parse": "1.0.4"
}
},
+ "value-equal": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz",
+ "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw=="
+ },
"value-or-function": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
diff --git a/package.json b/package.json
index 11d2bb441..d3cae3e15 100644
--- a/package.json
+++ b/package.json
@@ -100,7 +100,7 @@
"ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
"ethereumjs-wallet": "^0.6.0",
"etherscan-link": "^1.0.2",
- "ethjs": "^0.2.8",
+ "ethjs": "^0.3.4",
"ethjs-contract": "^0.1.9",
"ethjs-ens": "^2.0.0",
"ethjs-query": "^0.3.4",
@@ -114,7 +114,7 @@
"gulp-autoprefixer": "^5.0.0",
"gulp-debug": "^3.2.0",
"gulp-eslint": "^4.0.0",
- "gulp-sass": "^3.1.0",
+ "gulp-sass": "^4.0.0",
"hat": "0.0.3",
"human-standard-token-abi": "^1.0.2",
"idb-global": "^2.1.0",
@@ -145,6 +145,7 @@
"post-message-stream": "^3.0.0",
"promise-filter": "^1.1.0",
"promise-to-callback": "^1.0.0",
+ "prop-types": "^15.6.1",
"pump": "^3.0.0",
"pumpify": "^1.3.4",
"qrcode-npm": "0.0.3",
@@ -156,6 +157,7 @@
"react-hyperscript": "^3.0.0",
"react-markdown": "^3.0.0",
"react-redux": "^5.0.5",
+ "react-router-dom": "^4.2.2",
"react-select": "^1.0.0",
"react-simple-file-input": "^2.0.0",
"react-tippy": "^1.2.2",
diff --git a/test/integration/lib/add-token.js b/test/integration/lib/add-token.js
index cc04beb21..1840bdd39 100644
--- a/test/integration/lib/add-token.js
+++ b/test/integration/lib/add-token.js
@@ -75,7 +75,7 @@ async function runAddTokenFlowTest (assert, done) {
// Confirm Add token
assert.equal(
$('.add-token__description')[0].textContent,
- 'Would you like to add these tokens?',
+ 'Token balance(s)',
'confirm add token rendered'
)
assert.ok($('button.btn-primary--lg')[0], 'confirm add token button found')
diff --git a/test/integration/lib/confirm-sig-requests.js b/test/integration/lib/confirm-sig-requests.js
index f1116d1a6..3936ac5fa 100644
--- a/test/integration/lib/confirm-sig-requests.js
+++ b/test/integration/lib/confirm-sig-requests.js
@@ -21,11 +21,22 @@ async function runConfirmSigRequestsTest(assert, done) {
selectState.val('confirm sig requests')
reactTriggerChange(selectState[0])
+ // await timeout(1000000)
+
+ const pendingRequestItem = $.find('.tx-list-item.tx-list-pending-item-container.tx-list-clickable')
+
+ if (pendingRequestItem[0]) {
+ pendingRequestItem[0].click()
+ }
+
let confirmSigHeadline = await queryAsync($, '.request-signature__headline')
assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
+ let confirmSigMessage = await queryAsync($, '.request-signature__notice')
+ assert.ok(confirmSigMessage[0].textContent.match(/^Signing\sthis\smessage/))
+
let confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
- assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
+ assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
let confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
@@ -33,11 +44,8 @@ async function runConfirmSigRequestsTest(assert, done) {
confirmSigHeadline = await queryAsync($, '.request-signature__headline')
assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
- let confirmSigMessage = await queryAsync($, '.request-signature__notice')
- assert.ok(confirmSigMessage[0].textContent.match(/^Signing\sthis\smessage/))
-
confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
- assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
+ assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
diff --git a/test/integration/lib/mascara-first-time.js b/test/integration/lib/mascara-first-time.js
index 564852585..5e07ab0b4 100644
--- a/test/integration/lib/mascara-first-time.js
+++ b/test/integration/lib/mascara-first-time.js
@@ -13,6 +13,9 @@ async function runFirstTimeUsageTest (assert, done) {
await skipNotices(app)
+ const welcomeButton = (await findAsync(app, '.welcome-screen__button'))[0]
+ welcomeButton.click()
+
// Scroll through terms
const title = (await findAsync(app, '.create-password__title')).text()
assert.equal(title, 'Create Password', 'create password screen')
diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js
index 163f3658c..4731117d7 100644
--- a/test/integration/lib/send-new-ui.js
+++ b/test/integration/lib/send-new-ui.js
@@ -53,7 +53,7 @@ async function runSendFlowTest(assert, done) {
assert.equal(sendFromDropdownList.children().length, 4, 'send from dropdown shows all accounts')
sendFromDropdownList.children()[1].click()
- sendFromFieldItemAddress = await queryAsync($, '.account-list-item__account-name')
+ sendFromFieldItemAddress = await queryAsync($, '.account-list-item__account-name')
assert.equal(sendFromFieldItemAddress[0].textContent, 'Send Account 2', 'send from field dropdown changes account name')
let sendToFieldInput = await queryAsync($, '.send-v2__to-autocomplete__input')
@@ -164,17 +164,27 @@ async function runSendFlowTest(assert, done) {
const sendButtonInEdit = await queryAsync($, '.btn-primary--lg.page-container__footer-button')
assert.equal(sendButtonInEdit[0].textContent, 'Next', 'next button in edit rendered')
- sendButtonInEdit[0].click()
- // TODO: Need a way to mock background so that we can test correct transition from editing to confirm
- selectState.val('confirm new ui')
+ selectState.val('send new ui')
reactTriggerChange(selectState[0])
- const confirmScreenConfirmButton = await queryAsync($, '.btn-confirm.page-container__footer-button')
- console.log(`+++++++++++++++++++++++++++++++= confirmScreenConfirmButton[0]`, confirmScreenConfirmButton[0]);
- confirmScreenConfirmButton[0].click()
- const txView = await queryAsync($, '.tx-view')
- console.log(`++++++++++++++++++++++++++++++++ txView[0]`, txView[0]);
+ const cancelButtonInEdit = await queryAsync($, '.btn-secondary--lg.page-container__footer-button')
+ cancelButtonInEdit[0].click()
+ // sendButtonInEdit[0].click()
+
+ // // TODO: Need a way to mock background so that we can test correct transition from editing to confirm
+ // selectState.val('confirm new ui')
+ // reactTriggerChange(selectState[0])
+
+
+ // const confirmScreenConfirmButton = await queryAsync($, '.btn-confirm.page-container__footer-button')
+ // console.log(`+++++++++++++++++++++++++++++++= confirmScreenConfirmButton[0]`, confirmScreenConfirmButton[0]);
+ // confirmScreenConfirmButton[0].click()
+
+ // await timeout(10000000)
+
+ // const txView = await queryAsync($, '.tx-view')
+ // console.log(`++++++++++++++++++++++++++++++++ txView[0]`, txView[0]);
- assert.ok(txView[0], 'Should return to the account details screen after confirming')
+ // assert.ok(txView[0], 'Should return to the account details screen after confirming')
}
diff --git a/test/unit/migrations/024-test.js b/test/unit/migrations/024-test.js
new file mode 100644
index 000000000..c3c03d06b
--- /dev/null
+++ b/test/unit/migrations/024-test.js
@@ -0,0 +1,49 @@
+const assert = require('assert')
+const migration24 = require('../../../app/scripts/migrations/024')
+const firstTimeState = {
+ meta: {},
+ data: require('../../../app/scripts/first-time-state'),
+}
+const properTime = (new Date()).getTime()
+const storage = {
+ "meta": {},
+ "data": {
+ "TransactionController": {
+ "transactions": [
+ ]
+ },
+ },
+}
+
+const transactions = []
+
+
+while (transactions.length <= 10) {
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: 'unapproved' })
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: 'confirmed' })
+}
+
+
+storage.data.TransactionController.transactions = transactions
+
+describe('storage is migrated successfully and the txParams.from are lowercase', () => {
+ it('should lowercase the from for unapproved txs', (done) => {
+ migration24.migrate(storage)
+ .then((migratedData) => {
+ const migratedTransactions = migratedData.data.TransactionController.transactions
+ migratedTransactions.forEach((tx) => {
+ if (tx.status === 'unapproved') assert.equal(tx.txParams.from, '0x8acce2391c0d510a6c5e5d8f819a678f79b7e675')
+ else assert.equal(tx.txParams.from, '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675')
+ })
+ done()
+ }).catch(done)
+ })
+
+ it('should migrate first time state', (done) => {
+ migration24.migrate(firstTimeState)
+ .then((migratedData) => {
+ assert.equal(migratedData.meta.version, 24)
+ done()
+ }).catch(done)
+ })
+})
diff --git a/test/unit/migrations/025-test.js b/test/unit/migrations/025-test.js
new file mode 100644
index 000000000..76c25dbb6
--- /dev/null
+++ b/test/unit/migrations/025-test.js
@@ -0,0 +1,49 @@
+const assert = require('assert')
+const migration25 = require('../../../app/scripts/migrations/025')
+const firstTimeState = {
+ meta: {},
+ data: require('../../../app/scripts/first-time-state'),
+}
+
+const storage = {
+ "meta": {},
+ "data": {
+ "TransactionController": {
+ "transactions": [
+ ]
+ },
+ },
+}
+
+const transactions = []
+
+
+while (transactions.length <= 10) {
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675', random: 'stuff', chainId: 2 }, status: 'unapproved' })
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: 'confirmed' })
+}
+
+
+storage.data.TransactionController.transactions = transactions
+
+describe('storage is migrated successfully and the txParams.from are lowercase', () => {
+ it('should lowercase the from for unapproved txs', (done) => {
+ migration25.migrate(storage)
+ .then((migratedData) => {
+ const migratedTransactions = migratedData.data.TransactionController.transactions
+ migratedTransactions.forEach((tx) => {
+ if (tx.status === 'unapproved') assert(!tx.txParams.random)
+ if (tx.status === 'unapproved') assert(!tx.txParams.chainId)
+ })
+ done()
+ }).catch(done)
+ })
+
+ it('should migrate first time state', (done) => {
+ migration25.migrate(firstTimeState)
+ .then((migratedData) => {
+ assert.equal(migratedData.meta.version, 25)
+ done()
+ }).catch(done)
+ })
+})
diff --git a/test/unit/migrations/template-test.js b/test/unit/migrations/template-test.js
new file mode 100644
index 000000000..35060e2fe
--- /dev/null
+++ b/test/unit/migrations/template-test.js
@@ -0,0 +1,17 @@
+const assert = require('assert')
+const migrationTemplate = require('../../../app/scripts/migrations/template')
+const properTime = (new Date()).getTime()
+const storage = {
+ meta: {},
+ data: {},
+}
+
+describe('storage is migrated successfully', () => {
+ it('should work', (done) => {
+ migrationTemplate.migrate(storage)
+ .then((migratedData) => {
+ assert.equal(migratedData.meta.version, 0)
+ done()
+ }).catch(done)
+ })
+})
diff --git a/test/unit/migrator-test.js b/test/unit/migrator-test.js
index 16066fefe..4404e1dc4 100644
--- a/test/unit/migrator-test.js
+++ b/test/unit/migrator-test.js
@@ -1,7 +1,8 @@
const assert = require('assert')
const clone = require('clone')
const Migrator = require('../../app/scripts/lib/migrator/')
-const migrations = [
+const liveMigrations = require('../../app/scripts/migrations/')
+const stubMigrations = [
{
version: 1,
migrate: (data) => {
@@ -29,13 +30,39 @@ const migrations = [
},
]
const versionedData = {meta: {version: 0}, data: {hello: 'world'}}
+
+const firstTimeState = {
+ meta: { version: 0 },
+ data: require('../../app/scripts/first-time-state'),
+}
+
describe('Migrator', () => {
- const migrator = new Migrator({ migrations })
+ const migrator = new Migrator({ migrations: stubMigrations })
it('migratedData version should be version 3', (done) => {
migrator.migrateData(versionedData)
.then((migratedData) => {
- assert.equal(migratedData.meta.version, migrations[2].version)
+ assert.equal(migratedData.meta.version, stubMigrations[2].version)
done()
}).catch(done)
})
+
+ it('should match the last version in live migrations', (done) => {
+ const migrator = new Migrator({ migrations: liveMigrations })
+ migrator.migrateData(firstTimeState)
+ .then((migratedData) => {
+ const last = liveMigrations.length - 1
+ assert.equal(migratedData.meta.version, liveMigrations[last].version)
+ done()
+ }).catch(done)
+ })
+
+ it('should emit an error', function (done) {
+ this.timeout(15000)
+ const migrator = new Migrator({ migrations: [{ version: 1, migrate: async () => { throw new Error('test') } } ] })
+ migrator.on('error', () => done())
+ migrator.migrateData({ meta: {version: 0} })
+ .then((migratedData) => {
+ }).catch(done)
+ })
+
})
diff --git a/test/unit/tx-controller-test.js b/test/unit/tx-controller-test.js
index 6bd010e7a..824574ff2 100644
--- a/test/unit/tx-controller-test.js
+++ b/test/unit/tx-controller-test.js
@@ -210,31 +210,99 @@ describe('Transaction Controller', function () {
})
})
- describe('#validateTxParams', function () {
- it('does not throw for positive values', function (done) {
+ describe('#_validateTxParams', function () {
+ it('does not throw for positive values', function () {
var sample = {
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
value: '0x01',
}
- txController.txGasUtil.validateTxParams(sample).then(() => {
- done()
- }).catch(done)
+ txController._validateTxParams(sample)
})
- it('returns error for negative values', function (done) {
+ it('returns error for negative values', function () {
var sample = {
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
value: '-0x01',
}
- txController.txGasUtil.validateTxParams(sample)
- .then(() => done('expected to thrown on negativity values but didn\'t'))
- .catch((err) => {
+ try {
+ txController._validateTxParams(sample)
+ } catch (err) {
assert.ok(err, 'error')
- done()
- })
+ }
})
})
+ describe('#_normalizeTxParams', () => {
+ it('should normalize txParams', () => {
+ let txParams = {
+ chainId: '0x1',
+ from: 'a7df1beDBF813f57096dF77FCd515f0B3900e402',
+ to: null,
+ data: '68656c6c6f20776f726c64',
+ random: 'hello world',
+ }
+
+ let normalizedTxParams = txController._normalizeTxParams(txParams)
+
+ assert(!normalizedTxParams.chainId, 'their should be no chainId')
+ assert(!normalizedTxParams.to, 'their should be no to address if null')
+ assert.equal(normalizedTxParams.from.slice(0, 2), '0x', 'from should be hexPrefixd')
+ assert.equal(normalizedTxParams.data.slice(0, 2), '0x', 'data should be hexPrefixd')
+ assert(!('random' in normalizedTxParams), 'their should be no random key in normalizedTxParams')
+
+ txParams.to = 'a7df1beDBF813f57096dF77FCd515f0B3900e402'
+ normalizedTxParams = txController._normalizeTxParams(txParams)
+ assert.equal(normalizedTxParams.to.slice(0, 2), '0x', 'to should be hexPrefixd')
+
+ })
+ })
+
+ describe('#_validateRecipient', () => {
+ it('removes recipient for txParams with 0x when contract data is provided', function () {
+ const zeroRecipientandDataTxParams = {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ to: '0x',
+ data: 'bytecode',
+ }
+ const sanitizedTxParams = txController._validateRecipient(zeroRecipientandDataTxParams)
+ assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x')
+ })
+
+ it('should error when recipient is 0x', function () {
+ const zeroRecipientTxParams = {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ to: '0x',
+ }
+ assert.throws(() => { txController._validateRecipient(zeroRecipientTxParams) }, Error, 'Invalid recipient address')
+ })
+ })
+
+
+ describe('#_validateFrom', () => {
+ it('should error when from is not a hex string', function () {
+
+ // where from is undefined
+ const txParams = {}
+ assert.throws(() => { txController._validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+
+ // where from is array
+ txParams.from = []
+ assert.throws(() => { txController._validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+
+ // where from is a object
+ txParams.from = {}
+ assert.throws(() => { txController._validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+
+ // where from is a invalid address
+ txParams.from = 'im going to fail'
+ assert.throws(() => { txController._validateFrom(txParams) }, Error, `Invalid from address`)
+
+ // should run
+ txParams.from ='0x1678a085c290ebd122dc42cba69373b5953b831d'
+ txController._validateFrom(txParams)
+ })
+ })
+
describe('#addTx', function () {
it('should emit updates', function (done) {
const txMeta = {
diff --git a/test/unit/tx-gas-util-test.js b/test/unit/tx-gas-util-test.js
index 15d412c72..40ea8a7d6 100644
--- a/test/unit/tx-gas-util-test.js
+++ b/test/unit/tx-gas-util-test.js
@@ -11,46 +11,4 @@ describe('Tx Gas Util', function () {
provider,
})
})
-
- it('removes recipient for txParams with 0x when contract data is provided', function () {
- const zeroRecipientandDataTxParams = {
- from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
- to: '0x',
- data: 'bytecode',
- }
- const sanitizedTxParams = txGasUtil.validateRecipient(zeroRecipientandDataTxParams)
- assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x')
- })
-
- it('should error when recipient is 0x', function () {
- const zeroRecipientTxParams = {
- from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
- to: '0x',
- }
- assert.throws(() => { txGasUtil.validateRecipient(zeroRecipientTxParams) }, Error, 'Invalid recipient address')
- })
-
- it('should error when from is not a hex string', function () {
-
- // where from is undefined
- const txParams = {}
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
-
- // where from is array
- txParams.from = []
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
-
- // where from is a object
- txParams.from = {}
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
-
- // where from is a invalid address
- txParams.from = 'im going to fail'
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address`)
-
- // should run
- txParams.from ='0x1678a085c290ebd122dc42cba69373b5953b831d'
- txGasUtil.validateFrom(txParams)
- })
-
})
diff --git a/ui/app/actions.js b/ui/app/actions.js
index ad4270cef..0748a5bea 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -347,7 +347,7 @@ function transitionBackward () {
}
function confirmSeedWords () {
- return (dispatch) => {
+ return dispatch => {
dispatch(actions.showLoadingIndication())
log.debug(`background.clearSeedWordCache`)
return new Promise((resolve, reject) => {
@@ -355,7 +355,7 @@ function confirmSeedWords () {
dispatch(actions.hideLoadingIndication())
if (err) {
dispatch(actions.displayWarning(err.message))
- reject(err)
+ return reject(err)
}
log.info('Seed word cache cleared. ' + account)
@@ -571,35 +571,47 @@ function signMsg (msgData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- log.debug(`actions calling background.signMessage`)
- background.signMessage(msgData, (err, newState) => {
- log.debug('signMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
+ return new Promise((resolve, reject) => {
+ log.debug(`actions calling background.signMessage`)
+ background.signMessage(msgData, (err, newState) => {
+ log.debug('signMessage called back')
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
+ if (err) {
+ log.error(err)
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
- dispatch(actions.completedTx(msgData.metamaskId))
+ dispatch(actions.completedTx(msgData.metamaskId))
+ return resolve(msgData)
+ })
})
}
}
function signPersonalMsg (msgData) {
log.debug('action - signPersonalMsg')
- return (dispatch) => {
+ return dispatch => {
dispatch(actions.showLoadingIndication())
- log.debug(`actions calling background.signPersonalMessage`)
- background.signPersonalMessage(msgData, (err, newState) => {
- log.debug('signPersonalMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
+ return new Promise((resolve, reject) => {
+ log.debug(`actions calling background.signPersonalMessage`)
+ background.signPersonalMessage(msgData, (err, newState) => {
+ log.debug('signPersonalMessage called back')
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
+ if (err) {
+ log.error(err)
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
- dispatch(actions.completedTx(msgData.metamaskId))
+ dispatch(actions.completedTx(msgData.metamaskId))
+ return resolve(msgData)
+ })
})
}
}
@@ -609,16 +621,22 @@ function signTypedMsg (msgData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- log.debug(`actions calling background.signTypedMessage`)
- background.signTypedMessage(msgData, (err, newState) => {
- log.debug('signTypedMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
+ return new Promise((resolve, reject) => {
+ log.debug(`actions calling background.signTypedMessage`)
+ background.signTypedMessage(msgData, (err, newState) => {
+ log.debug('signTypedMessage called back')
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
+ if (err) {
+ log.error(err)
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
- dispatch(actions.completedTx(msgData.metamaskId))
+ dispatch(actions.completedTx(msgData.metamaskId))
+ return resolve(msgData)
+ })
})
}
}
@@ -798,17 +816,24 @@ function updateTransaction (txData) {
function updateAndApproveTx (txData) {
log.info('actions: updateAndApproveTx: ' + JSON.stringify(txData))
return (dispatch) => {
- log.debug(`actions calling background.updateAndApproveTx.`)
- background.updateAndApproveTransaction(txData, (err) => {
- dispatch(actions.hideLoadingIndication())
- dispatch(actions.updateTransactionParams(txData.id, txData.txParams))
- dispatch(actions.clearSend())
- if (err) {
- dispatch(actions.txError(err))
- dispatch(actions.goHome())
- return log.error(err.message)
- }
- dispatch(actions.completedTx(txData.id))
+ log.debug(`actions calling background.updateAndApproveTx`)
+
+ return new Promise((resolve, reject) => {
+ background.updateAndApproveTransaction(txData, err => {
+ dispatch(actions.hideLoadingIndication())
+ dispatch(actions.updateTransactionParams(txData.id, txData.txParams))
+ dispatch(actions.clearSend())
+
+ if (err) {
+ dispatch(actions.txError(err))
+ dispatch(actions.goHome())
+ log.error(err.message)
+ reject(err)
+ }
+
+ dispatch(actions.completedTx(txData.id))
+ resolve(txData)
+ })
})
}
}
@@ -836,29 +861,77 @@ function txError (err) {
}
function cancelMsg (msgData) {
- log.debug(`background.cancelMessage`)
- background.cancelMessage(msgData.id)
- return actions.completedTx(msgData.id)
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+
+ return new Promise((resolve, reject) => {
+ log.debug(`background.cancelMessage`)
+ background.cancelMessage(msgData.id, (err, newState) => {
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ return reject(err)
+ }
+
+ dispatch(actions.completedTx(msgData.id))
+ return resolve(msgData)
+ })
+ })
+ }
}
function cancelPersonalMsg (msgData) {
- const id = msgData.id
- background.cancelPersonalMessage(id)
- return actions.completedTx(id)
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+
+ return new Promise((resolve, reject) => {
+ const id = msgData.id
+ background.cancelPersonalMessage(id, (err, newState) => {
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ return reject(err)
+ }
+
+ dispatch(actions.completedTx(id))
+ return resolve(msgData)
+ })
+ })
+ }
}
function cancelTypedMsg (msgData) {
- const id = msgData.id
- background.cancelTypedMessage(id)
- return actions.completedTx(id)
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+
+ return new Promise((resolve, reject) => {
+ const id = msgData.id
+ background.cancelTypedMessage(id, (err, newState) => {
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ return reject(err)
+ }
+
+ dispatch(actions.completedTx(id))
+ return resolve(msgData)
+ })
+ })
+ }
}
function cancelTx (txData) {
- return (dispatch) => {
+ return dispatch => {
log.debug(`background.cancelTransaction`)
- background.cancelTransaction(txData.id, () => {
- dispatch(actions.clearSend())
- dispatch(actions.completedTx(txData.id))
+ return new Promise((resolve, reject) => {
+ background.cancelTransaction(txData.id, () => {
+ dispatch(actions.clearSend())
+ dispatch(actions.completedTx(txData.id))
+ resolve(txData)
+ })
})
}
}
@@ -1249,12 +1322,13 @@ function markNoticeRead (notice) {
dispatch(actions.displayWarning(err))
return reject(err)
}
+
if (notice) {
dispatch(actions.showNotice(notice))
- resolve()
+ resolve(true)
} else {
dispatch(actions.clearNotices())
- resolve()
+ resolve(false)
}
})
})
@@ -1773,7 +1847,7 @@ function forceUpdateMetamaskState (dispatch) {
}
dispatch(actions.updateMetamaskState(newState))
- resolve()
+ resolve(newState)
})
})
}
diff --git a/ui/app/app.js b/ui/app/app.js
index 0b7a7a1e0..75c3febb0 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -1,62 +1,421 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
+const { Component } = require('react')
+const PropTypes = require('prop-types')
const connect = require('react-redux').connect
+const { Route, Switch, withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const h = require('react-hyperscript')
-const PropTypes = require('prop-types')
const actions = require('./actions')
const classnames = require('classnames')
-// mascara
-const MascaraFirstTime = require('../../mascara/src/app/first-time').default
-const MascaraBuyEtherScreen = require('../../mascara/src/app/first-time/buy-ether-screen').default
// init
-const OldUIInitializeMenuScreen = require('./first-time/init-menu')
-const InitializeMenuScreen = MascaraFirstTime
-const NewKeyChainScreen = require('./new-keychain')
-const WelcomeScreen = require('./welcome-screen').default
-
+const InitializeScreen = require('../../mascara/src/app/first-time').default
// accounts
-const MainContainer = require('./main-container')
const SendTransactionScreen2 = require('./components/send/send-v2-container')
const ConfirmTxScreen = require('./conf-tx')
-// notice
-const NoticeScreen = require('./components/notice')
-const generateLostAccountsNotice = require('../lib/lost-accounts-notice')
// slideout menu
const WalletView = require('./components/wallet-view')
// other views
-const Settings = require('./settings')
-const AddTokenScreen = require('./add-token')
-const Import = require('./accounts/import')
-const NewAccount = require('./accounts/new-account')
+const Home = require('./components/pages/home')
+const Authenticated = require('./components/pages/authenticated')
+const Initialized = require('./components/pages/initialized')
+const Settings = require('./components/pages/settings')
+const UnlockPage = require('./components/pages/unlock')
+const RestoreVaultPage = require('./components/pages/keychains/restore-vault')
+const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
+const AddTokenPage = require('./components/pages/add-token')
+const CreateAccountPage = require('./components/pages/create-account')
+const NoticeScreen = require('./components/pages/notice')
+
const Loading = require('./components/loading')
const NetworkIndicator = require('./components/network')
const Identicon = require('./components/identicon')
-const BuyView = require('./components/buy-button-subview')
-const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete')
-const HDRestoreVaultScreen = require('./keychains/hd/restore-vault')
-const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
const NetworkDropdown = require('./components/dropdowns/network-dropdown')
const AccountMenu = require('./components/account-menu')
-const QrView = require('./components/qr-code')
// Global Modals
const Modal = require('./components/modals/index').Modal
-App.contextTypes = {
- t: PropTypes.func,
-}
+// Routes
+const {
+ DEFAULT_ROUTE,
+ UNLOCK_ROUTE,
+ SETTINGS_ROUTE,
+ REVEAL_SEED_ROUTE,
+ RESTORE_VAULT_ROUTE,
+ ADD_TOKEN_ROUTE,
+ NEW_ACCOUNT_ROUTE,
+ SEND_ROUTE,
+ CONFIRM_TRANSACTION_ROUTE,
+ INITIALIZE_ROUTE,
+ NOTICE_ROUTE,
+} = require('./routes')
+
+class App extends Component {
+ componentWillMount () {
+ const { currentCurrency, setCurrentCurrencyToUSD } = this.props
+
+ if (!currentCurrency) {
+ setCurrentCurrencyToUSD()
+ }
+ }
+
+ renderRoutes () {
+ const exact = true
+
+ return (
+ h(Switch, [
+ h(Route, { path: INITIALIZE_ROUTE, component: InitializeScreen }),
+ h(Initialized, { path: REVEAL_SEED_ROUTE, exact, component: RevealSeedConfirmation }),
+ h(Initialized, { path: UNLOCK_ROUTE, exact, component: UnlockPage }),
+ h(Initialized, { path: SETTINGS_ROUTE, component: Settings }),
+ h(Initialized, { path: RESTORE_VAULT_ROUTE, exact, component: RestoreVaultPage }),
+ h(Initialized, { path: NOTICE_ROUTE, exact, component: NoticeScreen }),
+ h(Authenticated, { path: CONFIRM_TRANSACTION_ROUTE, component: ConfirmTxScreen }),
+ h(Authenticated, { path: SEND_ROUTE, exact, component: SendTransactionScreen2 }),
+ h(Authenticated, { path: ADD_TOKEN_ROUTE, exact, component: AddTokenPage }),
+ h(Authenticated, { path: NEW_ACCOUNT_ROUTE, component: CreateAccountPage }),
+ h(Authenticated, { path: DEFAULT_ROUTE, exact, component: Home }),
+ ])
+ )
+ }
+
+ render () {
+ const {
+ isLoading,
+ loadingMessage,
+ network,
+ isMouseUser,
+ provider,
+ frequentRpcList,
+ currentView,
+ setMouseUserState,
+ } = this.props
+ const isLoadingNetwork = network === 'loading' && currentView.name !== 'config'
+ const loadMessage = loadingMessage || isLoadingNetwork ?
+ this.getConnectingLabel() : null
+ log.debug('Main ui render function')
+
+ return (
+ h('.flex-column.full-height', {
+ className: classnames({ 'mouse-user-styles': isMouseUser }),
+ style: {
+ overflowX: 'hidden',
+ position: 'relative',
+ alignItems: 'center',
+ },
+ tabIndex: '0',
+ onClick: () => setMouseUserState(true),
+ onKeyDown: (e) => {
+ if (e.keyCode === 9) {
+ setMouseUserState(false)
+ }
+ },
+ }, [
+
+ // global modal
+ h(Modal, {}, []),
+
+ // app bar
+ this.renderAppBar(),
+
+ // sidebar
+ this.renderSidebar(),
-module.exports = connect(mapStateToProps, mapDispatchToProps)(App)
+ // network dropdown
+ h(NetworkDropdown, {
+ provider,
+ frequentRpcList,
+ }, []),
+ h(AccountMenu),
-inherits(App, Component)
-function App () { Component.call(this) }
+ (isLoading || isLoadingNetwork) && h(Loading, {
+ loadingMessage: loadMessage,
+ }),
+
+ // this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }),
+
+ // content
+ this.renderRoutes(),
+ ])
+ )
+ }
+
+ renderGlobalModal () {
+ return h(Modal, {
+ ref: 'modalRef',
+ }, [
+ // h(BuyOptions, {}, []),
+ ])
+ }
+
+ renderSidebar () {
+ return h('div', [
+ h('style', `
+ .sidebar-enter {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(-100%);
+ }
+ .sidebar-enter.sidebar-enter-active {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(0%);
+ }
+ .sidebar-leave {
+ transition: transform 200ms ease-out;
+ transform: translateX(0%);
+ }
+ .sidebar-leave.sidebar-leave-active {
+ transition: transform 200ms ease-out;
+ transform: translateX(-100%);
+ }
+ `),
+
+ h(ReactCSSTransitionGroup, {
+ transitionName: 'sidebar',
+ transitionEnterTimeout: 300,
+ transitionLeaveTimeout: 200,
+ }, [
+ // A second instance of Walletview is used for non-mobile viewports
+ this.props.sidebarOpen ? h(WalletView, {
+ responsiveDisplayClassname: '.sidebar',
+ style: {},
+ }) : undefined,
+
+ ]),
+
+ // overlay
+ // TODO: add onClick for overlay to close sidebar
+ this.props.sidebarOpen ? h('div.sidebar-overlay', {
+ style: {},
+ onClick: () => {
+ this.props.hideSidebar()
+ },
+ }, []) : undefined,
+ ])
+ }
+
+ renderAppBar () {
+ const {
+ isUnlocked,
+ network,
+ provider,
+ networkDropdownOpen,
+ showNetworkDropdown,
+ hideNetworkDropdown,
+ isInitialized,
+ welcomeScreenSeen,
+ isPopup,
+ betaUI,
+ } = this.props
+
+ if (window.METAMASK_UI_TYPE === 'notification') {
+ return null
+ }
+
+ const props = this.props
+ const {isMascara, isOnboarding} = props
+
+ // Do not render header if user is in mascara onboarding
+ if (isMascara && isOnboarding) {
+ return null
+ }
+
+ // Do not render header if user is in mascara buy ether
+ if (isMascara && props.currentView.name === 'buyEth') {
+ return null
+ }
+
+ return (
+
+ h('.full-width', {
+ style: {},
+ }, [
+
+ (isInitialized || welcomeScreenSeen || isPopup || !betaUI) && h('.app-header.flex-row.flex-space-between', {
+ className: classnames({
+ 'app-header--initialized': !isOnboarding,
+ }),
+ }, [
+ h('div.app-header-contents', {}, [
+ h('div.left-menu-wrapper', {
+ onClick: () => props.history.push(DEFAULT_ROUTE),
+ }, [
+ // mini logo
+ h('img.metafox-icon', {
+ height: 42,
+ width: 42,
+ src: '/images/metamask-fox.svg',
+ }),
+
+ // metamask name
+ h('.flex-row', [
+ h('h1', this.context.t('appName')),
+ h('div.beta-label', this.context.t('beta')),
+ ]),
+
+ ]),
+
+ betaUI && isInitialized && h('div.header__right-actions', [
+ h('div.network-component-wrapper', {
+ style: {},
+ }, [
+ // Network Indicator
+ h(NetworkIndicator, {
+ network,
+ provider,
+ disabled: this.props.location.pathname === CONFIRM_TRANSACTION_ROUTE,
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ return networkDropdownOpen === false
+ ? showNetworkDropdown()
+ : hideNetworkDropdown()
+ },
+ }),
+
+ ]),
+
+ isUnlocked && h('div.account-menu__icon', { onClick: this.props.toggleAccountMenu }, [
+ h(Identicon, {
+ address: this.props.selectedAddress,
+ diameter: 32,
+ }),
+ ]),
+ ]),
+ ]),
+ ]),
+
+ !isInitialized && !isPopup && betaUI && h('.alpha-warning__container', {}, [
+ h('h2', {
+ className: classnames({
+ 'alpha-warning': welcomeScreenSeen,
+ 'alpha-warning-welcome-screen': !welcomeScreenSeen,
+ }),
+ }, 'Please be aware that this version is still under development'),
+ ]),
+
+ ])
+ )
+ }
+
+ renderLoadingIndicator ({ isLoading, isLoadingNetwork, loadMessage }) {
+ const { isMascara } = this.props
+
+ return isMascara
+ ? null
+ : h(Loading, {
+ isLoading: isLoading || isLoadingNetwork,
+ loadingMessage: loadMessage,
+ })
+ }
+
+ toggleMetamaskActive () {
+ if (!this.props.isUnlocked) {
+ // currently inactive: redirect to password box
+ var passwordBox = document.querySelector('input[type=password]')
+ if (!passwordBox) return
+ passwordBox.focus()
+ } else {
+ // currently active: deactivate
+ this.props.dispatch(actions.lockMetamask(false))
+ }
+ }
+
+ getConnectingLabel = function () {
+ const { provider } = this.props
+ const providerName = provider.type
+
+ let name
+
+ if (providerName === 'mainnet') {
+ name = this.context.t('connectingToMainnet')
+ } else if (providerName === 'ropsten') {
+ name = this.context.t('connectingToRopsten')
+ } else if (providerName === 'kovan') {
+ name = this.context.t('connectingToRopsten')
+ } else if (providerName === 'rinkeby') {
+ name = this.context.t('connectingToRinkeby')
+ } else {
+ name = this.context.t('connectingToUnknown')
+ }
+
+ return name
+ }
+
+ getNetworkName () {
+ const { provider } = this.props
+ const providerName = provider.type
+
+ let name
+
+ if (providerName === 'mainnet') {
+ name = this.context.t('mainnet')
+ } else if (providerName === 'ropsten') {
+ name = this.context.t('ropsten')
+ } else if (providerName === 'kovan') {
+ name = this.context.t('kovan')
+ } else if (providerName === 'rinkeby') {
+ name = this.context.t('rinkeby')
+ } else {
+ name = this.context.t('unknownNetwork')
+ }
+
+ return name
+ }
+}
+
+App.propTypes = {
+ currentCurrency: PropTypes.string,
+ setCurrentCurrencyToUSD: PropTypes.func,
+ isLoading: PropTypes.bool,
+ loadingMessage: PropTypes.string,
+ network: PropTypes.string,
+ provider: PropTypes.object,
+ frequentRpcList: PropTypes.array,
+ currentView: PropTypes.object,
+ sidebarOpen: PropTypes.bool,
+ hideSidebar: PropTypes.func,
+ isMascara: PropTypes.bool,
+ isOnboarding: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
+ networkDropdownOpen: PropTypes.bool,
+ showNetworkDropdown: PropTypes.func,
+ hideNetworkDropdown: PropTypes.func,
+ history: PropTypes.object,
+ location: PropTypes.object,
+ dispatch: PropTypes.func,
+ toggleAccountMenu: PropTypes.func,
+ selectedAddress: PropTypes.string,
+ noActiveNotices: PropTypes.bool,
+ lostAccounts: PropTypes.array,
+ isInitialized: PropTypes.bool,
+ forgottenPassword: PropTypes.bool,
+ activeAddress: PropTypes.string,
+ unapprovedTxs: PropTypes.object,
+ seedWords: PropTypes.string,
+ unapprovedMsgCount: PropTypes.number,
+ unapprovedPersonalMsgCount: PropTypes.number,
+ unapprovedTypedMessagesCount: PropTypes.number,
+ welcomeScreenSeen: PropTypes.bool,
+ isPopup: PropTypes.bool,
+ betaUI: PropTypes.bool,
+ isMouseUser: PropTypes.bool,
+ setMouseUserState: PropTypes.func,
+ t: PropTypes.func,
+}
function mapStateToProps (state) {
+ const { appState, metamask } = state
+ const {
+ networkDropdownOpen,
+ sidebarOpen,
+ isLoading,
+ loadingMessage,
+ } = appState
+
const {
identities,
accounts,
@@ -65,17 +424,23 @@ function mapStateToProps (state) {
isInitialized,
noActiveNotices,
seedWords,
- } = state.metamask
+ unapprovedTxs,
+ lastUnreadNotice,
+ lostAccounts,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ } = metamask
const selected = address || Object.keys(accounts)[0]
return {
// state from plugin
- networkDropdownOpen: state.appState.networkDropdownOpen,
- sidebarOpen: state.appState.sidebarOpen,
- isLoading: state.appState.isLoading,
- loadingMessage: state.appState.loadingMessage,
- noActiveNotices: state.metamask.noActiveNotices,
- isInitialized: state.metamask.isInitialized,
+ networkDropdownOpen,
+ sidebarOpen,
+ isLoading,
+ loadingMessage,
+ noActiveNotices,
+ isInitialized,
isUnlocked: state.metamask.isUnlocked,
selectedAddress: state.metamask.selectedAddress,
currentView: state.appState.currentView,
@@ -85,14 +450,17 @@ function mapStateToProps (state) {
isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
isPopup: state.metamask.isPopup,
seedWords: state.metamask.seedWords,
- unapprovedTxs: state.metamask.unapprovedTxs,
+ unapprovedTxs,
unapprovedMsgs: state.metamask.unapprovedMsgs,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
menuOpen: state.appState.menuOpen,
network: state.metamask.network,
provider: state.metamask.provider,
- forgottenPassword: state.metamask.forgottenPassword,
- lastUnreadNotice: state.metamask.lastUnreadNotice,
- lostAccounts: state.metamask.lostAccounts,
+ forgottenPassword: state.appState.forgottenPassword,
+ lastUnreadNotice,
+ lostAccounts,
frequentRpcList: state.metamask.frequentRpcList || [],
currentCurrency: state.metamask.currentCurrency,
isMouseUser: state.appState.isMouseUser,
@@ -120,479 +488,11 @@ function mapDispatchToProps (dispatch, ownProps) {
}
}
-App.prototype.componentWillMount = function () {
- if (!this.props.currentCurrency) {
- this.props.setCurrentCurrencyToUSD()
- }
-}
-
-App.prototype.render = function () {
- var props = this.props
- const {
- isLoading,
- loadingMessage,
- network,
- isMouseUser,
- setMouseUserState,
- } = props
- const isLoadingNetwork = network === 'loading' && props.currentView.name !== 'config'
- const loadMessage = loadingMessage || isLoadingNetwork ?
- this.getConnectingLabel() : null
- log.debug('Main ui render function')
-
- return (
- h('.flex-column.full-height', {
- className: classnames({ 'mouse-user-styles': isMouseUser }),
- style: {
- overflowX: 'hidden',
- position: 'relative',
- alignItems: 'center',
- },
- tabIndex: '0',
- onClick: () => setMouseUserState(true),
- onKeyDown: (e) => {
- if (e.keyCode === 9) {
- setMouseUserState(false)
- }
- },
- }, [
-
- // global modal
- h(Modal, {}, []),
-
- // app bar
- this.renderAppBar(),
-
- // sidebar
- this.renderSidebar(),
-
- // network dropdown
- h(NetworkDropdown, {
- provider: this.props.provider,
- frequentRpcList: this.props.frequentRpcList,
- }, []),
-
- h(AccountMenu),
-
- (isLoading || isLoadingNetwork) && h(Loading, {
- loadingMessage: loadMessage,
- }),
-
- // this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }),
-
- // content
- this.renderPrimary(),
- ])
- )
-}
-
-App.prototype.renderGlobalModal = function () {
- return h(Modal, {
- ref: 'modalRef',
- }, [
- // h(BuyOptions, {}, []),
- ])
-}
-
-App.prototype.renderSidebar = function () {
-
- return h('div', {
- }, [
- h('style', `
- .sidebar-enter {
- transition: transform 300ms ease-in-out;
- transform: translateX(-100%);
- }
- .sidebar-enter.sidebar-enter-active {
- transition: transform 300ms ease-in-out;
- transform: translateX(0%);
- }
- .sidebar-leave {
- transition: transform 200ms ease-out;
- transform: translateX(0%);
- }
- .sidebar-leave.sidebar-leave-active {
- transition: transform 200ms ease-out;
- transform: translateX(-100%);
- }
- `),
-
- h(ReactCSSTransitionGroup, {
- transitionName: 'sidebar',
- transitionEnterTimeout: 300,
- transitionLeaveTimeout: 200,
- }, [
- // A second instance of Walletview is used for non-mobile viewports
- this.props.sidebarOpen ? h(WalletView, {
- responsiveDisplayClassname: '.sidebar',
- style: {},
- }) : undefined,
-
- ]),
-
- // overlay
- // TODO: add onClick for overlay to close sidebar
- this.props.sidebarOpen ? h('div.sidebar-overlay', {
- style: {},
- onClick: () => {
- this.props.hideSidebar()
- },
- }, []) : undefined,
- ])
-}
-
-App.prototype.renderAppBar = function () {
- const {
- isUnlocked,
- network,
- provider,
- networkDropdownOpen,
- showNetworkDropdown,
- hideNetworkDropdown,
- currentView,
- isInitialized,
- betaUI,
- isPopup,
- welcomeScreenSeen,
- } = this.props
-
- if (window.METAMASK_UI_TYPE === 'notification') {
- return null
- }
-
- const props = this.props
- const {isMascara, isOnboarding} = props
-
- // Do not render header if user is in mascara onboarding
- if (isMascara && isOnboarding) {
- return null
- }
-
- // Do not render header if user is in mascara buy ether
- if (isMascara && props.currentView.name === 'buyEth') {
- return null
- }
-
- return (
-
- h('.full-width', {
- style: {},
- }, [
-
- (isInitialized || welcomeScreenSeen || isPopup || !betaUI) && h('.app-header.flex-row.flex-space-between', {
- className: classnames({
- 'app-header--initialized': !isOnboarding,
- }),
- }, [
- h('div.app-header-contents', {}, [
- h('div.left-menu-wrapper', {
- onClick: () => {
- props.dispatch(actions.backToAccountDetail(props.activeAddress))
- },
- }, [
- // mini logo
- h('img.metafox-icon', {
- height: 42,
- width: 42,
- src: './images/metamask-fox.svg',
- }),
-
- // metamask name
- h('.flex-row', [
- h('h1', this.context.t('appName')),
- h('div.beta-label', this.context.t('beta')),
- ]),
- ]),
-
- betaUI && isInitialized && h('div.header__right-actions', [
- h('div.network-component-wrapper', {
- style: {},
- }, [
- // Network Indicator
- h(NetworkIndicator, {
- network,
- provider,
- disabled: currentView.name === 'confTx',
- onClick: (event) => {
- event.preventDefault()
- event.stopPropagation()
- return networkDropdownOpen === false
- ? showNetworkDropdown()
- : hideNetworkDropdown()
- },
- }),
-
- ]),
-
- isUnlocked && h('div.account-menu__icon', { onClick: this.props.toggleAccountMenu }, [
- h(Identicon, {
- address: this.props.selectedAddress,
- diameter: 32,
- }),
- ]),
- ]),
- ]),
- ]),
-
- !isInitialized && !isPopup && betaUI && h('.alpha-warning__container', {}, [
- h('h2', {
- className: classnames({
- 'alpha-warning': welcomeScreenSeen,
- 'alpha-warning-welcome-screen': !welcomeScreenSeen,
- }),
- }, 'Please be aware that this version is still under development'),
- ]),
-
- ])
- )
-}
-
-App.prototype.renderLoadingIndicator = function ({ isLoading, isLoadingNetwork, loadMessage }) {
- const { isMascara } = this.props
-
- return isMascara
- ? null
- : h(Loading, {
- isLoading: isLoading || isLoadingNetwork,
- loadingMessage: loadMessage,
- })
-}
-
-App.prototype.renderBackButton = function (style, justArrow = false) {
- var props = this.props
- return (
- h('.flex-row', {
- key: 'leftArrow',
- style: style,
- onClick: () => props.dispatch(actions.goBackToInitView()),
- }, [
- h('i.fa.fa-arrow-left.cursor-pointer'),
- justArrow ? null : h('div.cursor-pointer', {
- style: {
- marginLeft: '3px',
- },
- onClick: () => props.dispatch(actions.goBackToInitView()),
- }, 'BACK'),
- ])
- )
-}
-
-App.prototype.renderPrimary = function () {
- log.debug('rendering primary')
- var props = this.props
- const {
- isMascara,
- isOnboarding,
- betaUI,
- isRevealingSeedWords,
- welcomeScreenSeen,
- Qr,
- isInitialized,
- isUnlocked,
- } = props
- const isMascaraOnboarding = isMascara && isOnboarding
- const isBetaUIOnboarding = betaUI && isOnboarding
-
- if (!welcomeScreenSeen && betaUI && !isInitialized && !isUnlocked) {
- return h(WelcomeScreen)
- }
-
- if (isMascaraOnboarding || isBetaUIOnboarding) {
- return h(MascaraFirstTime)
- }
-
- // notices
- if (!props.noActiveNotices && !betaUI) {
- log.debug('rendering notice screen for unread notices.')
- return h(NoticeScreen, {
- notice: props.lastUnreadNotice,
- key: 'NoticeScreen',
- onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
- })
- } else if (props.lostAccounts && props.lostAccounts.length > 0) {
- log.debug('rendering notice screen for lost accounts view.')
- return h(NoticeScreen, {
- notice: generateLostAccountsNotice(props.lostAccounts),
- key: 'LostAccountsNotice',
- onConfirm: () => props.dispatch(actions.markAccountsFound()),
- })
- }
-
- if (props.isInitialized && props.forgottenPassword) {
- log.debug('rendering restore vault screen')
- return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
- } else if (!props.isInitialized && !props.isUnlocked && !isRevealingSeedWords) {
- log.debug('rendering menu screen')
- return !betaUI
- ? h(OldUIInitializeMenuScreen, {key: 'menuScreenInit'})
- : h(InitializeMenuScreen, {key: 'menuScreenInit'})
- }
-
- // show unlock screen
- if (!props.isUnlocked) {
- return h(MainContainer, {
- currentViewName: props.currentView.name,
- isUnlocked: props.isUnlocked,
- })
- }
-
- // show seed words screen
- if (props.seedWords) {
- log.debug('rendering seed words')
- return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'})
- }
-
- // show current view
- switch (props.currentView.name) {
-
- case 'accountDetail':
- log.debug('rendering main container')
- return h(MainContainer, {key: 'account-detail'})
-
- case 'sendTransaction':
- log.debug('rendering send tx screen')
-
- // Going to leave this here until we are ready to delete SendTransactionScreen v1
- // const SendComponentToRender = checkFeatureToggle('send-v2')
- // ? SendTransactionScreen2
- // : SendTransactionScreen
-
- return h(SendTransactionScreen2, {key: 'send-transaction'})
-
- case 'sendToken':
- log.debug('rendering send token screen')
-
- // Going to leave this here until we are ready to delete SendTransactionScreen v1
- // const SendTokenComponentToRender = checkFeatureToggle('send-v2')
- // ? SendTransactionScreen2
- // : SendTokenScreen
-
- return h(SendTransactionScreen2, {key: 'sendToken'})
-
- case 'newKeychain':
- log.debug('rendering new keychain screen')
- return h(NewKeyChainScreen, {key: 'new-keychain'})
-
- case 'confTx':
- log.debug('rendering confirm tx screen')
- return h(ConfirmTxScreen, {key: 'confirm-tx'})
-
- case 'add-token':
- log.debug('rendering add-token screen from unlock screen.')
- return h(AddTokenScreen, {key: 'add-token'})
-
- case 'config':
- log.debug('rendering config screen')
- return h(Settings, {key: 'config'})
-
- case 'import-menu':
- log.debug('rendering import screen')
- return h(Import, {key: 'import-menu'})
-
- case 'new-account-page':
- log.debug('rendering new account screen')
- return h(NewAccount, {key: 'new-account'})
-
- case 'reveal-seed-conf':
- log.debug('rendering reveal seed confirmation screen')
- return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'})
-
- case 'info':
- log.debug('rendering info screen')
- return h(Settings, {key: 'info', tab: 'info'})
-
- case 'buyEth':
- log.debug('rendering buy ether screen')
- return h(BuyView, {key: 'buyEthView'})
-
- case 'onboardingBuyEth':
- log.debug('rendering onboarding buy ether screen')
- return h(MascaraBuyEtherScreen, {key: 'buyEthView'})
-
- case 'qr':
- log.debug('rendering show qr screen')
- return h('div', {
- style: {
- position: 'absolute',
- height: '100%',
- top: '0px',
- left: '0px',
- },
- }, [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
- onClick: () => props.dispatch(actions.backToAccountDetail(props.activeAddress)),
- style: {
- marginLeft: '10px',
- marginTop: '50px',
- },
- }),
- h('div', {
- style: {
- position: 'absolute',
- left: '44px',
- width: '285px',
- },
- }, [
- h(QrView, {key: 'qr', Qr}),
- ]),
- ])
-
- default:
- log.debug('rendering default, account detail screen')
- return h(MainContainer, {key: 'account-detail'})
- }
-}
-
-App.prototype.toggleMetamaskActive = function () {
- if (!this.props.isUnlocked) {
- // currently inactive: redirect to password box
- var passwordBox = document.querySelector('input[type=password]')
- if (!passwordBox) return
- passwordBox.focus()
- } else {
- // currently active: deactivate
- this.props.dispatch(actions.lockMetamask(false))
- }
-}
-
-App.prototype.getConnectingLabel = function () {
- const { provider } = this.props
- const providerName = provider.type
-
- let name
-
- if (providerName === 'mainnet') {
- name = this.context.t('connectingToMainnet')
- } else if (providerName === 'ropsten') {
- name = this.context.t('connectingToRopsten')
- } else if (providerName === 'kovan') {
- name = this.context.t('connectingToRopsten')
- } else if (providerName === 'rinkeby') {
- name = this.context.t('connectingToRinkeby')
- } else {
- name = this.context.t('connectingToUnknown')
- }
-
- return name
+App.contextTypes = {
+ t: PropTypes.func,
}
-App.prototype.getNetworkName = function () {
- const { provider } = this.props
- const providerName = provider.type
-
- let name
-
- if (providerName === 'mainnet') {
- name = this.context.t('mainnet')
- } else if (providerName === 'ropsten') {
- name = this.context.t('ropsten')
- } else if (providerName === 'kovan') {
- name = this.context.t('kovan')
- } else if (providerName === 'rinkeby') {
- name = this.context.t('rinkeby')
- } else {
- name = this.context.t('unknownNetwork')
- }
-
- return name
-}
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(App)
diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js
index 21de358d6..7638995ea 100644
--- a/ui/app/components/account-menu/index.js
+++ b/ui/app/components/account-menu/index.js
@@ -1,20 +1,31 @@
const inherits = require('util').inherits
const Component = require('react').Component
-const PropTypes = require('prop-types')
const connect = require('react-redux').connect
+const { compose } = require('recompose')
+const { withRouter } = require('react-router-dom')
+const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const actions = require('../../actions')
const { Menu, Item, Divider, CloseArea } = require('../dropdowns/components/menu')
const Identicon = require('../identicon')
const { formatBalance } = require('../../util')
+const {
+ SETTINGS_ROUTE,
+ INFO_ROUTE,
+ NEW_ACCOUNT_ROUTE,
+ IMPORT_ACCOUNT_ROUTE,
+ DEFAULT_ROUTE,
+} = require('../../routes')
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(AccountMenu)
AccountMenu.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountMenu)
-
-
inherits(AccountMenu, Component)
function AccountMenu () { Component.call(this) }
@@ -25,7 +36,6 @@ function mapStateToProps (state) {
keyrings: state.metamask.keyrings,
identities: state.metamask.identities,
accounts: state.metamask.accounts,
-
}
}
@@ -48,11 +58,6 @@ function mapDispatchToProps (dispatch) {
dispatch(actions.hideSidebar())
dispatch(actions.toggleAccountMenu())
},
- showNewAccountPage: (formToSelect) => {
- dispatch(actions.showNewAccountPage(formToSelect))
- dispatch(actions.hideSidebar())
- dispatch(actions.toggleAccountMenu())
- },
showInfoPage: () => {
dispatch(actions.showInfoPage())
dispatch(actions.hideSidebar())
@@ -65,10 +70,8 @@ AccountMenu.prototype.render = function () {
const {
isAccountMenuOpen,
toggleAccountMenu,
- showNewAccountPage,
lockMetamask,
- showConfigPage,
- showInfoPage,
+ history,
} = this.props
return h(Menu, { className: 'account-menu', isShowing: isAccountMenuOpen }, [
@@ -78,30 +81,45 @@ AccountMenu.prototype.render = function () {
}, [
this.context.t('myAccounts'),
h('button.account-menu__logout-button', {
- onClick: lockMetamask,
+ onClick: () => {
+ lockMetamask()
+ history.push(DEFAULT_ROUTE)
+ },
}, this.context.t('logout')),
]),
h(Divider),
h('div.account-menu__accounts', this.renderAccounts()),
h(Divider),
h(Item, {
- onClick: () => showNewAccountPage('CREATE'),
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(NEW_ACCOUNT_ROUTE)
+ },
icon: h('img.account-menu__item-icon', { src: 'images/plus-btn-white.svg' }),
text: this.context.t('createAccount'),
}),
h(Item, {
- onClick: () => showNewAccountPage('IMPORT'),
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(IMPORT_ACCOUNT_ROUTE)
+ },
icon: h('img.account-menu__item-icon', { src: 'images/import-account.svg' }),
text: this.context.t('importAccount'),
}),
h(Divider),
h(Item, {
- onClick: showInfoPage,
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(INFO_ROUTE)
+ },
icon: h('img', { src: 'images/mm-info-icon.svg' }),
text: this.context.t('infoHelp'),
}),
h(Item, {
- onClick: showConfigPage,
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(SETTINGS_ROUTE)
+ },
icon: h('img.account-menu__item-icon', { src: 'images/settings.svg' }),
text: this.context.t('settings'),
}),
diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js
index 1f3946817..feb0a7037 100644
--- a/ui/app/components/ens-input.js
+++ b/ui/app/components/ens-input.js
@@ -32,10 +32,10 @@ EnsInput.prototype.render = function () {
const network = this.props.network
const networkHasEnsSupport = getNetworkEnsSupport(network)
- if (!networkHasEnsSupport) return
-
props.onChange(recipient)
+ if (!networkHasEnsSupport) return
+
if (recipient.match(ensRE) === null) {
return this.setState({
loadingEns: false,
diff --git a/ui/app/add-token.js b/ui/app/components/pages/add-token.js
index ebdd220aa..566e42450 100644
--- a/ui/app/add-token.js
+++ b/ui/app/components/pages/add-token.js
@@ -7,8 +7,8 @@ const connect = require('react-redux').connect
const R = require('ramda')
const Fuse = require('fuse.js')
const contractMap = require('eth-contract-metadata')
-const TokenBalance = require('./components/token-balance')
-const Identicon = require('./components/identicon')
+const TokenBalance = require('../../components/token-balance')
+const Identicon = require('../../components/identicon')
const contractList = Object.entries(contractMap)
.map(([ _, tokenData]) => tokenData)
.filter(tokenData => Boolean(tokenData.erc20))
@@ -24,9 +24,10 @@ const fuse = new Fuse(contractList, {
{ name: 'symbol', weight: 0.5 },
],
})
-const actions = require('./actions')
+const actions = require('../../actions')
const ethUtil = require('ethereumjs-util')
-const { tokenInfoGetter } = require('./token-util')
+const { tokenInfoGetter } = require('../../token-util')
+const { DEFAULT_ROUTE } = require('../../routes')
const emptyAddr = '0x0000000000000000000000000000000000000000'
@@ -47,7 +48,6 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
- goHome: () => dispatch(actions.goHome()),
addTokens: tokens => dispatch(actions.addTokens(tokens)),
}
}
@@ -56,6 +56,7 @@ inherits(AddTokenScreen, Component)
function AddTokenScreen () {
this.state = {
isShowingConfirmation: false,
+ isShowingInfoBox: true,
customAddress: '',
customSymbol: '',
customDecimals: '',
@@ -295,7 +296,7 @@ AddTokenScreen.prototype.renderConfirmation = function () {
selectedTokens,
} = this.state
- const { addTokens, goHome } = this.props
+ const { addTokens, history } = this.props
const customToken = {
address,
@@ -310,9 +311,6 @@ AddTokenScreen.prototype.renderConfirmation = function () {
return (
h('div.add-token', [
h('div.add-token__wrapper', [
- h('div.add-token__title-container.add-token__confirmation-title', [
- h('div.add-token__description', this.context.t('likeToAddTokens')),
- ]),
h('div.add-token__content-container.add-token__confirmation-content', [
h('div.add-token__description.add-token__confirmation-description', this.context.t('balances')),
h('div.add-token__confirmation-token-list',
@@ -335,7 +333,7 @@ AddTokenScreen.prototype.renderConfirmation = function () {
onClick: () => this.setState({ isShowingConfirmation: false }),
}, this.context.t('back')),
h('button.btn-primary--lg', {
- onClick: () => addTokens(tokens).then(goHome),
+ onClick: () => addTokens(tokens).then(() => history.push(DEFAULT_ROUTE)),
}, this.context.t('addTokens')),
]),
])
@@ -347,18 +345,23 @@ AddTokenScreen.prototype.displayTab = function (selectedTab) {
}
AddTokenScreen.prototype.renderTabs = function () {
- const { displayedTab, errors } = this.state
+ const { isShowingInfoBox, displayedTab, errors } = this.state
return displayedTab === 'CUSTOM_TOKEN'
? this.renderCustomForm()
: h('div', [
h('div.add-token__wrapper', [
h('div.add-token__content-container', [
- h('div.add-token__info-box', [
- h('div.add-token__info-box__close'),
+ isShowingInfoBox && h('div.add-token__info-box', [
+ h('div.add-token__info-box__close', {
+ onClick: () => this.setState({ isShowingInfoBox: false }),
+ }),
h('div.add-token__info-box__title', this.context.t('whatsThis')),
h('div.add-token__info-box__copy', this.context.t('keepTrackTokens')),
- h('div.add-token__info-box__copy--blue', this.context.t('learnMore')),
+ h('a.add-token__info-box__copy--blue', {
+ href: 'http://metamask.helpscoutdocs.com/article/16-managing-erc20-tokens',
+ target: '_blank',
+ }, this.context.t('learnMore')),
]),
h('div.add-token__input-container', [
h('input.add-token__input', {
@@ -379,23 +382,24 @@ AddTokenScreen.prototype.render = function () {
isShowingConfirmation,
displayedTab,
} = this.state
- const { goHome } = this.props
+ const { history } = this.props
return h('div.add-token', [
h('div.add-token__header', [
h('div.add-token__header__cancel', {
- onClick: () => goHome(),
+ onClick: () => history.push(DEFAULT_ROUTE),
}, [
h('i.fa.fa-angle-left.fa-lg'),
h('span', this.context.t('cancel')),
]),
h('div.add-token__header__title', this.context.t('addTokens')),
+ isShowingConfirmation && h('div.add-token__header__subtitle', this.context.t('likeToAddTokens')),
!isShowingConfirmation && h('div.add-token__header__tabs', [
h('div.add-token__header__tabs__tab', {
className: classnames('add-token__header__tabs__tab', {
'add-token__header__tabs__selected': displayedTab === 'SEARCH',
- 'add-token__header__tabs__unselected cursor-pointer': displayedTab !== 'SEARCH',
+ 'add-token__header__tabs__unselected': displayedTab !== 'SEARCH',
}),
onClick: () => this.displayTab('SEARCH'),
}, this.context.t('search')),
@@ -403,21 +407,21 @@ AddTokenScreen.prototype.render = function () {
h('div.add-token__header__tabs__tab', {
className: classnames('add-token__header__tabs__tab', {
'add-token__header__tabs__selected': displayedTab === 'CUSTOM_TOKEN',
- 'add-token__header__tabs__unselected cursor-pointer': displayedTab !== 'CUSTOM_TOKEN',
+ 'add-token__header__tabs__unselected': displayedTab !== 'CUSTOM_TOKEN',
}),
onClick: () => this.displayTab('CUSTOM_TOKEN'),
}, this.context.t('customToken')),
]),
]),
-//
+
isShowingConfirmation
? this.renderConfirmation()
: this.renderTabs(),
!isShowingConfirmation && h('div.add-token__buttons', [
h('button.btn-secondary--lg.add-token__cancel-button', {
- onClick: goHome,
+ onClick: () => history.push(DEFAULT_ROUTE),
}, this.context.t('cancel')),
h('button.btn-primary--lg.add-token__confirm-button', {
onClick: this.onNext,
diff --git a/ui/app/components/pages/authenticated.js b/ui/app/components/pages/authenticated.js
new file mode 100644
index 000000000..1f6b0be49
--- /dev/null
+++ b/ui/app/components/pages/authenticated.js
@@ -0,0 +1,34 @@
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const { Redirect } = require('react-router-dom')
+const h = require('react-hyperscript')
+const MetamaskRoute = require('./metamask-route')
+const { UNLOCK_ROUTE, INITIALIZE_ROUTE } = require('../../routes')
+
+const Authenticated = props => {
+ const { isUnlocked, isInitialized } = props
+
+ switch (true) {
+ case isUnlocked && isInitialized:
+ return h(MetamaskRoute, { ...props })
+ case !isInitialized:
+ return h(Redirect, { to: { pathname: INITIALIZE_ROUTE } })
+ default:
+ return h(Redirect, { to: { pathname: UNLOCK_ROUTE } })
+ }
+}
+
+Authenticated.propTypes = {
+ isUnlocked: PropTypes.bool,
+ isInitialized: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isUnlocked, isInitialized } } = state
+ return {
+ isUnlocked,
+ isInitialized,
+ }
+}
+
+module.exports = connect(mapStateToProps)(Authenticated)
diff --git a/ui/app/accounts/import/index.js b/ui/app/components/pages/create-account/import-account/index.js
index 52d3dcde9..52d3dcde9 100644
--- a/ui/app/accounts/import/index.js
+++ b/ui/app/components/pages/create-account/import-account/index.js
diff --git a/ui/app/accounts/import/json.js b/ui/app/components/pages/create-account/import-account/json.js
index e53c1c9ca..946907a47 100644
--- a/ui/app/accounts/import/json.js
+++ b/ui/app/components/pages/create-account/import-account/json.js
@@ -1,11 +1,12 @@
const Component = require('react').Component
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const connect = require('react-redux').connect
-const actions = require('../../actions')
+const actions = require('../../../../actions')
const FileInput = require('react-simple-file-input').default
-
-
+const { DEFAULT_ROUTE } = require('../../../../routes')
const HELP_LINK = 'https://support.metamask.io/kb/article/7-importing-accounts'
class JsonImportSubview extends Component {
@@ -51,7 +52,7 @@ class JsonImportSubview extends Component {
h('div.new-account-create-form__buttons', {}, [
h('button.btn-secondary.new-account-create-form__button', {
- onClick: () => this.props.goHome(),
+ onClick: () => this.props.history.push(DEFAULT_ROUTE),
}, [
this.context.t('cancel'),
]),
@@ -112,6 +113,7 @@ JsonImportSubview.propTypes = {
goHome: PropTypes.func,
displayWarning: PropTypes.func,
importNewJsonAccount: PropTypes.func,
+ history: PropTypes.object,
t: PropTypes.func,
}
@@ -133,5 +135,7 @@ JsonImportSubview.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(JsonImportSubview)
-
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(JsonImportSubview)
diff --git a/ui/app/accounts/import/private-key.js b/ui/app/components/pages/create-account/import-account/private-key.js
index 006131bdc..c77612ea4 100644
--- a/ui/app/accounts/import/private-key.js
+++ b/ui/app/components/pages/create-account/import-account/private-key.js
@@ -1,15 +1,21 @@
const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
-const actions = require('../../actions')
+const actions = require('../../../../actions')
+const { DEFAULT_ROUTE } = require('../../../../routes')
PrivateKeyImportView.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(PrivateKeyImportView)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(PrivateKeyImportView)
function mapStateToProps (state) {
@@ -20,9 +26,8 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
- goHome: () => dispatch(actions.goHome()),
importNewAccount: (strategy, [ privateKey ]) => {
- dispatch(actions.importNewAccount(strategy, [ privateKey ]))
+ return dispatch(actions.importNewAccount(strategy, [ privateKey ]))
},
displayWarning: () => dispatch(actions.displayWarning(null)),
}
@@ -30,11 +35,12 @@ function mapDispatchToProps (dispatch) {
inherits(PrivateKeyImportView, Component)
function PrivateKeyImportView () {
+ this.createKeyringOnEnter = this.createKeyringOnEnter.bind(this)
Component.call(this)
}
PrivateKeyImportView.prototype.render = function () {
- const { error, goHome } = this.props
+ const { error } = this.props
return (
h('div.new-account-import-form__private-key', [
@@ -46,7 +52,7 @@ PrivateKeyImportView.prototype.render = function () {
h('input.new-account-import-form__input-password', {
type: 'password',
id: 'private-key-box',
- onKeyPress: () => this.createKeyringOnEnter(),
+ onKeyPress: e => this.createKeyringOnEnter(e),
}),
]),
@@ -54,7 +60,7 @@ PrivateKeyImportView.prototype.render = function () {
h('div.new-account-import-form__buttons', {}, [
h('button.btn-secondary--lg.new-account-create-form__button', {
- onClick: () => goHome(),
+ onClick: () => this.props.history.push(DEFAULT_ROUTE),
}, [
this.context.t('cancel'),
]),
@@ -82,6 +88,8 @@ PrivateKeyImportView.prototype.createKeyringOnEnter = function (event) {
PrivateKeyImportView.prototype.createNewKeychain = function () {
const input = document.getElementById('private-key-box')
const privateKey = input.value
+ const { importNewAccount, history } = this.props
- this.props.importNewAccount('Private Key', [ privateKey ])
+ importNewAccount('Private Key', [ privateKey ])
+ .then(() => history.push(DEFAULT_ROUTE))
}
diff --git a/ui/app/accounts/import/seed.js b/ui/app/components/pages/create-account/import-account/seed.js
index d98909baa..d98909baa 100644
--- a/ui/app/accounts/import/seed.js
+++ b/ui/app/components/pages/create-account/import-account/seed.js
diff --git a/ui/app/components/pages/create-account/index.js b/ui/app/components/pages/create-account/index.js
new file mode 100644
index 000000000..0962477d8
--- /dev/null
+++ b/ui/app/components/pages/create-account/index.js
@@ -0,0 +1,81 @@
+const Component = require('react').Component
+const { Switch, Route, matchPath } = require('react-router-dom')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../../actions')
+const { getCurrentViewContext } = require('../../../selectors')
+const classnames = require('classnames')
+const NewAccountCreateForm = require('./new-account')
+const NewAccountImportForm = require('./import-account')
+const { NEW_ACCOUNT_ROUTE, IMPORT_ACCOUNT_ROUTE } = require('../../../routes')
+
+class CreateAccountPage extends Component {
+ renderTabs () {
+ const { history, location } = this.props
+
+ return h('div.new-account__tabs', [
+ h('div.new-account__tabs__tab', {
+ className: classnames('new-account__tabs__tab', {
+ 'new-account__tabs__selected': matchPath(location.pathname, {
+ path: NEW_ACCOUNT_ROUTE, exact: true,
+ }),
+ }),
+ onClick: () => history.push(NEW_ACCOUNT_ROUTE),
+ }, 'Create'),
+
+ h('div.new-account__tabs__tab', {
+ className: classnames('new-account__tabs__tab', {
+ 'new-account__tabs__selected': matchPath(location.pathname, {
+ path: IMPORT_ACCOUNT_ROUTE, exact: true,
+ }),
+ }),
+ onClick: () => history.push(IMPORT_ACCOUNT_ROUTE),
+ }, 'Import'),
+ ])
+ }
+
+ render () {
+ return h('div.new-account', {}, [
+ h('div.new-account__header', [
+ h('div.new-account__title', 'New Account'),
+ this.renderTabs(),
+ ]),
+ h('div.new-account__form', [
+ h(Switch, [
+ h(Route, {
+ exact: true,
+ path: NEW_ACCOUNT_ROUTE,
+ component: NewAccountCreateForm,
+ }),
+ h(Route, {
+ exact: true,
+ path: IMPORT_ACCOUNT_ROUTE,
+ component: NewAccountImportForm,
+ }),
+ ]),
+ ]),
+ ])
+ }
+}
+
+CreateAccountPage.propTypes = {
+ location: PropTypes.object,
+ history: PropTypes.object,
+}
+
+const mapStateToProps = state => ({
+ displayedForm: getCurrentViewContext(state),
+})
+
+const mapDispatchToProps = dispatch => ({
+ displayForm: form => dispatch(actions.setNewAccountForm(form)),
+ showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
+ showExportPrivateKeyModal: () => {
+ dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
+ },
+ hideModal: () => dispatch(actions.hideModal()),
+ saveAccountLabel: (address, label) => dispatch(actions.saveAccountLabel(address, label)),
+})
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(CreateAccountPage)
diff --git a/ui/app/accounts/new-account/create-form.js b/ui/app/components/pages/create-account/new-account.js
index 48c74192a..40fa584be 100644
--- a/ui/app/accounts/new-account/create-form.js
+++ b/ui/app/components/pages/create-account/new-account.js
@@ -2,7 +2,8 @@ const { Component } = require('react')
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const connect = require('react-redux').connect
-const actions = require('../../actions')
+const actions = require('../../../actions')
+const { DEFAULT_ROUTE } = require('../../../routes')
class NewAccountCreateForm extends Component {
constructor (props, context) {
@@ -19,7 +20,7 @@ class NewAccountCreateForm extends Component {
render () {
const { newAccountName, defaultAccountName } = this.state
-
+ const { history, createAccount } = this.props
return h('div.new-account-create-form', [
@@ -38,13 +39,16 @@ class NewAccountCreateForm extends Component {
h('div.new-account-create-form__buttons', {}, [
h('button.btn-secondary--lg.new-account-create-form__button', {
- onClick: () => this.props.goHome(),
+ onClick: () => history.push(DEFAULT_ROUTE),
}, [
this.context.t('cancel'),
]),
h('button.btn-primary--lg.new-account-create-form__button', {
- onClick: () => this.props.createAccount(newAccountName || defaultAccountName),
+ onClick: () => {
+ createAccount(newAccountName || defaultAccountName)
+ .then(() => history.push(DEFAULT_ROUTE))
+ },
}, [
this.context.t('create'),
]),
@@ -59,8 +63,8 @@ NewAccountCreateForm.propTypes = {
hideModal: PropTypes.func,
showImportPage: PropTypes.func,
createAccount: PropTypes.func,
- goHome: PropTypes.func,
numberOfExistingAccounts: PropTypes.number,
+ history: PropTypes.object,
t: PropTypes.func,
}
@@ -77,23 +81,17 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => {
return {
- toCoinbase: (address) => {
- dispatch(actions.buyEth({ network: '1', address, amount: 0 }))
- },
- hideModal: () => {
- dispatch(actions.hideModal())
- },
- createAccount: (newAccountName) => {
- dispatch(actions.addNewAccount())
- .then((newAccountAddress) => {
+ toCoinbase: address => dispatch(actions.buyEth({ network: '1', address, amount: 0 })),
+ hideModal: () => dispatch(actions.hideModal()),
+ createAccount: newAccountName => {
+ return dispatch(actions.addNewAccount())
+ .then(newAccountAddress => {
if (newAccountName) {
dispatch(actions.saveAccountLabel(newAccountAddress, newAccountName))
}
- dispatch(actions.goHome())
})
},
showImportPage: () => dispatch(actions.showImportPage()),
- goHome: () => dispatch(actions.goHome()),
}
}
diff --git a/ui/app/components/pages/home.js b/ui/app/components/pages/home.js
new file mode 100644
index 000000000..7857a2a99
--- /dev/null
+++ b/ui/app/components/pages/home.js
@@ -0,0 +1,332 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const connect = require('../../metamask-connect')
+const { Redirect, withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const h = require('react-hyperscript')
+const actions = require('../../actions')
+
+// init
+const NewKeyChainScreen = require('../../new-keychain')
+// mascara
+const MascaraBuyEtherScreen = require('../../../../mascara/src/app/first-time/buy-ether-screen').default
+
+// accounts
+const MainContainer = require('../../main-container')
+
+// other views
+const BuyView = require('../../components/buy-button-subview')
+const QrView = require('../../components/qr-code')
+
+// Routes
+const {
+ REVEAL_SEED_ROUTE,
+ RESTORE_VAULT_ROUTE,
+ CONFIRM_TRANSACTION_ROUTE,
+ NOTICE_ROUTE,
+} = require('../../routes')
+
+class Home extends Component {
+ componentDidMount () {
+ const {
+ history,
+ unapprovedTxs = {},
+ unapprovedMsgCount = 0,
+ unapprovedPersonalMsgCount = 0,
+ unapprovedTypedMessagesCount = 0,
+ } = this.props
+
+ // unapprovedTxs and unapproved messages
+ if (Object.keys(unapprovedTxs).length ||
+ unapprovedTypedMessagesCount + unapprovedMsgCount + unapprovedPersonalMsgCount > 0) {
+ history.push(CONFIRM_TRANSACTION_ROUTE)
+ }
+ }
+
+ render () {
+ log.debug('rendering primary')
+ const {
+ noActiveNotices,
+ lostAccounts,
+ forgottenPassword,
+ currentView,
+ activeAddress,
+ seedWords,
+ } = this.props
+
+ // notices
+ if (!noActiveNotices || (lostAccounts && lostAccounts.length > 0)) {
+ return h(Redirect, {
+ to: {
+ pathname: NOTICE_ROUTE,
+ },
+ })
+ }
+
+ // seed words
+ if (seedWords) {
+ log.debug('rendering seed words')
+ return h(Redirect, {
+ to: {
+ pathname: REVEAL_SEED_ROUTE,
+ },
+ })
+ }
+
+ if (forgottenPassword) {
+ log.debug('rendering restore vault screen')
+ return h(Redirect, {
+ to: {
+ pathname: RESTORE_VAULT_ROUTE,
+ },
+ })
+ }
+
+ // if (!props.noActiveNotices) {
+ // log.debug('rendering notice screen for unread notices.')
+ // return h(NoticeScreen, {
+ // notice: props.lastUnreadNotice,
+ // key: 'NoticeScreen',
+ // onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
+ // })
+ // } else if (props.lostAccounts && props.lostAccounts.length > 0) {
+ // log.debug('rendering notice screen for lost accounts view.')
+ // return h(NoticeScreen, {
+ // notice: generateLostAccountsNotice(props.lostAccounts),
+ // key: 'LostAccountsNotice',
+ // onConfirm: () => props.dispatch(actions.markAccountsFound()),
+ // })
+ // }
+
+ // if (props.seedWords) {
+ // log.debug('rendering seed words')
+ // return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'})
+ // }
+
+ // show initialize screen
+ // if (!isInitialized || forgottenPassword) {
+ // // show current view
+ // log.debug('rendering an initialize screen')
+ // // switch (props.currentView.name) {
+
+ // // case 'restoreVault':
+ // // log.debug('rendering restore vault screen')
+ // // return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
+
+ // // default:
+ // // log.debug('rendering menu screen')
+ // // return h(InitializeScreen, {key: 'menuScreenInit'})
+ // // }
+ // }
+
+ // // show unlock screen
+ // if (!props.isUnlocked) {
+ // return h(MainContainer, {
+ // currentViewName: props.currentView.name,
+ // isUnlocked: props.isUnlocked,
+ // })
+ // }
+
+ // show current view
+ switch (currentView.name) {
+
+ case 'accountDetail':
+ log.debug('rendering main container')
+ return h(MainContainer, {key: 'account-detail'})
+
+ // case 'sendTransaction':
+ // log.debug('rendering send tx screen')
+
+ // // Going to leave this here until we are ready to delete SendTransactionScreen v1
+ // // const SendComponentToRender = checkFeatureToggle('send-v2')
+ // // ? SendTransactionScreen2
+ // // : SendTransactionScreen
+
+ // return h(SendTransactionScreen2, {key: 'send-transaction'})
+
+ // case 'sendToken':
+ // log.debug('rendering send token screen')
+
+ // // Going to leave this here until we are ready to delete SendTransactionScreen v1
+ // // const SendTokenComponentToRender = checkFeatureToggle('send-v2')
+ // // ? SendTransactionScreen2
+ // // : SendTokenScreen
+
+ // return h(SendTransactionScreen2, {key: 'sendToken'})
+
+ case 'newKeychain':
+ log.debug('rendering new keychain screen')
+ return h(NewKeyChainScreen, {key: 'new-keychain'})
+
+ // case 'confTx':
+ // log.debug('rendering confirm tx screen')
+ // return h(Redirect, {
+ // to: {
+ // pathname: CONFIRM_TRANSACTION_ROUTE,
+ // },
+ // })
+ // return h(ConfirmTxScreen, {key: 'confirm-tx'})
+
+ // case 'add-token':
+ // log.debug('rendering add-token screen from unlock screen.')
+ // return h(AddTokenScreen, {key: 'add-token'})
+
+ // case 'config':
+ // log.debug('rendering config screen')
+ // return h(Settings, {key: 'config'})
+
+ // case 'import-menu':
+ // log.debug('rendering import screen')
+ // return h(Import, {key: 'import-menu'})
+
+ // case 'reveal-seed-conf':
+ // log.debug('rendering reveal seed confirmation screen')
+ // return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'})
+
+ // case 'info':
+ // log.debug('rendering info screen')
+ // return h(Settings, {key: 'info', tab: 'info'})
+
+ case 'buyEth':
+ log.debug('rendering buy ether screen')
+ return h(BuyView, {key: 'buyEthView'})
+
+ case 'onboardingBuyEth':
+ log.debug('rendering onboarding buy ether screen')
+ return h(MascaraBuyEtherScreen, {key: 'buyEthView'})
+
+ case 'qr':
+ log.debug('rendering show qr screen')
+ return h('div', {
+ style: {
+ position: 'absolute',
+ height: '100%',
+ top: '0px',
+ left: '0px',
+ },
+ }, [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
+ onClick: () => this.props.dispatch(actions.backToAccountDetail(activeAddress)),
+ style: {
+ marginLeft: '10px',
+ marginTop: '50px',
+ },
+ }),
+ h('div', {
+ style: {
+ position: 'absolute',
+ left: '44px',
+ width: '285px',
+ },
+ }, [
+ h(QrView, {key: 'qr'}),
+ ]),
+ ])
+
+ default:
+ log.debug('rendering default, account detail screen')
+ return h(MainContainer, {key: 'account-detail'})
+ }
+ }
+}
+
+Home.propTypes = {
+ currentCurrency: PropTypes.string,
+ isLoading: PropTypes.bool,
+ loadingMessage: PropTypes.string,
+ network: PropTypes.string,
+ provider: PropTypes.object,
+ frequentRpcList: PropTypes.array,
+ currentView: PropTypes.object,
+ sidebarOpen: PropTypes.bool,
+ isMascara: PropTypes.bool,
+ isOnboarding: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
+ networkDropdownOpen: PropTypes.bool,
+ history: PropTypes.object,
+ dispatch: PropTypes.func,
+ selectedAddress: PropTypes.string,
+ noActiveNotices: PropTypes.bool,
+ lostAccounts: PropTypes.array,
+ isInitialized: PropTypes.bool,
+ forgottenPassword: PropTypes.bool,
+ activeAddress: PropTypes.string,
+ unapprovedTxs: PropTypes.object,
+ seedWords: PropTypes.string,
+ unapprovedMsgCount: PropTypes.number,
+ unapprovedPersonalMsgCount: PropTypes.number,
+ unapprovedTypedMessagesCount: PropTypes.number,
+ welcomeScreenSeen: PropTypes.bool,
+ isPopup: PropTypes.bool,
+ isMouseUser: PropTypes.bool,
+ t: PropTypes.func,
+}
+
+function mapStateToProps (state) {
+ const { appState, metamask } = state
+ const {
+ networkDropdownOpen,
+ sidebarOpen,
+ isLoading,
+ loadingMessage,
+ } = appState
+
+ const {
+ accounts,
+ address,
+ isInitialized,
+ noActiveNotices,
+ seedWords,
+ unapprovedTxs,
+ lastUnreadNotice,
+ lostAccounts,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ } = metamask
+ const selected = address || Object.keys(accounts)[0]
+
+ return {
+ // state from plugin
+ networkDropdownOpen,
+ sidebarOpen,
+ isLoading,
+ loadingMessage,
+ noActiveNotices,
+ isInitialized,
+ isUnlocked: state.metamask.isUnlocked,
+ selectedAddress: state.metamask.selectedAddress,
+ currentView: state.appState.currentView,
+ activeAddress: state.appState.activeAddress,
+ transForward: state.appState.transForward,
+ isMascara: state.metamask.isMascara,
+ isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
+ isPopup: state.metamask.isPopup,
+ seedWords: state.metamask.seedWords,
+ unapprovedTxs,
+ unapprovedMsgs: state.metamask.unapprovedMsgs,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ menuOpen: state.appState.menuOpen,
+ network: state.metamask.network,
+ provider: state.metamask.provider,
+ forgottenPassword: state.appState.forgottenPassword,
+ lastUnreadNotice,
+ lostAccounts,
+ frequentRpcList: state.metamask.frequentRpcList || [],
+ currentCurrency: state.metamask.currentCurrency,
+ isMouseUser: state.appState.isMouseUser,
+ isRevealingSeedWords: state.metamask.isRevealingSeedWords,
+ Qr: state.appState.Qr,
+ welcomeScreenSeen: state.metamask.welcomeScreenSeen,
+
+ // state needed to get account dropdown temporarily rendering from app bar
+ selected,
+ }
+}
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps)
+)(Home)
diff --git a/ui/app/components/pages/initialized.js b/ui/app/components/pages/initialized.js
new file mode 100644
index 000000000..3adf67b28
--- /dev/null
+++ b/ui/app/components/pages/initialized.js
@@ -0,0 +1,25 @@
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const { Redirect } = require('react-router-dom')
+const h = require('react-hyperscript')
+const { INITIALIZE_ROUTE } = require('../../routes')
+const MetamaskRoute = require('./metamask-route')
+
+const Initialized = props => {
+ return props.isInitialized
+ ? h(MetamaskRoute, { ...props })
+ : h(Redirect, { to: { pathname: INITIALIZE_ROUTE } })
+}
+
+Initialized.propTypes = {
+ isInitialized: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isInitialized } } = state
+ return {
+ isInitialized,
+ }
+}
+
+module.exports = connect(mapStateToProps)(Initialized)
diff --git a/ui/app/components/pages/keychains/restore-vault.js b/ui/app/components/pages/keychains/restore-vault.js
new file mode 100644
index 000000000..d57894e00
--- /dev/null
+++ b/ui/app/components/pages/keychains/restore-vault.js
@@ -0,0 +1,177 @@
+const { withRouter } = require('react-router-dom')
+const PropTypes = require('prop-types')
+const { compose } = require('recompose')
+const PersistentForm = require('../../../../lib/persistent-form')
+const connect = require('../../../metamask-connect')
+const h = require('react-hyperscript')
+const { createNewVaultAndRestore, unMarkPasswordForgotten } = require('../../../actions')
+const { DEFAULT_ROUTE } = require('../../../routes')
+
+class RestoreVaultPage extends PersistentForm {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ error: null,
+ }
+ }
+
+ createOnEnter (event) {
+ if (event.key === 'Enter') {
+ this.createNewVaultAndRestore()
+ }
+ }
+
+ cancel () {
+ this.props.unMarkPasswordForgotten()
+ .then(this.props.history.push(DEFAULT_ROUTE))
+ }
+
+ createNewVaultAndRestore () {
+ this.setState({ error: null })
+
+ // check password
+ var passwordBox = document.getElementById('password-box')
+ var password = passwordBox.value
+ var passwordConfirmBox = document.getElementById('password-box-confirm')
+ var passwordConfirm = passwordConfirmBox.value
+
+ if (password.length < 8) {
+ this.setState({ error: 'Password not long enough' })
+ return
+ }
+
+ if (password !== passwordConfirm) {
+ this.setState({ error: 'Passwords don\'t match' })
+ return
+ }
+
+ // check seed
+ var seedBox = document.querySelector('textarea.twelve-word-phrase')
+ var seed = seedBox.value.trim()
+ if (seed.split(' ').length !== 12) {
+ this.setState({ error: 'Seed phrases are 12 words long' })
+ return
+ }
+
+ // submit
+ this.props.createNewVaultAndRestore(password, seed)
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
+ .catch(({ message }) => {
+ this.setState({ error: message })
+ log.error(message)
+ })
+ }
+
+ render () {
+ const { error } = this.state
+ this.persistentFormParentId = 'restore-vault-form'
+
+ return (
+ h('.initialize-screen.flex-column.flex-center.flex-grow', [
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ padding: 6,
+ },
+ }, [
+ this.props.t('restoreVault'),
+ ]),
+
+ // wallet seed entry
+ h('h3', 'Wallet Seed'),
+ h('textarea.twelve-word-phrase.letter-spacey', {
+ dataset: {
+ persistentFormId: 'wallet-seed',
+ },
+ placeholder: this.props.t('secretPhrase'),
+ }),
+
+ // password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: this.props.t('newPassword8Chars'),
+ dataset: {
+ persistentFormId: 'password',
+ },
+ style: {
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ // confirm password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box-confirm',
+ placeholder: this.props.t('confirmPassword'),
+ onKeyPress: this.createOnEnter.bind(this),
+ dataset: {
+ persistentFormId: 'password-confirmation',
+ },
+ style: {
+ width: 260,
+ marginTop: 16,
+ },
+ }),
+
+ error && (
+ h('span.error.in-progress-notification', error)
+ ),
+
+ // submit
+ h('.flex-row.flex-space-between', {
+ style: {
+ marginTop: 30,
+ width: '50%',
+ },
+ }, [
+
+ // cancel
+ h('button.primary', {
+ onClick: () => this.cancel(),
+ }, this.props.t('cancel')),
+
+ // submit
+ h('button.primary', {
+ onClick: this.createNewVaultAndRestore.bind(this),
+ }, this.props.t('ok')),
+
+ ]),
+ ])
+ )
+ }
+}
+
+RestoreVaultPage.propTypes = {
+ history: PropTypes.object,
+}
+
+const mapStateToProps = state => {
+ const { appState: { warning, forgottenPassword } } = state
+
+ return {
+ warning,
+ forgottenPassword,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ createNewVaultAndRestore: (password, seed) => {
+ return dispatch(createNewVaultAndRestore(password, seed))
+ },
+ unMarkPasswordForgotten: () => dispatch(unMarkPasswordForgotten()),
+ }
+}
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(RestoreVaultPage)
diff --git a/ui/app/components/pages/keychains/reveal-seed.js b/ui/app/components/pages/keychains/reveal-seed.js
new file mode 100644
index 000000000..247f3c8e2
--- /dev/null
+++ b/ui/app/components/pages/keychains/reveal-seed.js
@@ -0,0 +1,195 @@
+const { Component } = require('react')
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const { exportAsFile } = require('../../../util')
+const { requestRevealSeed, confirmSeedWords } = require('../../../actions')
+const { DEFAULT_ROUTE } = require('../../../routes')
+
+class RevealSeedPage extends Component {
+ componentDidMount () {
+ const passwordBox = document.getElementById('password-box')
+ if (passwordBox) {
+ passwordBox.focus()
+ }
+ }
+
+ checkConfirmation (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.revealSeedWords()
+ }
+ }
+
+ revealSeedWords () {
+ const password = document.getElementById('password-box').value
+ this.props.requestRevealSeed(password)
+ }
+
+ renderSeed () {
+ const { seedWords, confirmSeedWords, history } = this.props
+
+ return (
+ h('.initialize-screen.flex-column.flex-center.flex-grow', [
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginTop: 36,
+ marginBottom: 8,
+ width: '100%',
+ fontSize: '20px',
+ padding: 6,
+ },
+ }, [
+ 'Vault Created',
+ ]),
+
+ h('div', {
+ style: {
+ fontSize: '1em',
+ marginTop: '10px',
+ textAlign: 'center',
+ },
+ }, [
+ h('span.error', 'These 12 words are the only way to restore your MetaMask accounts.\nSave them somewhere safe and secret.'),
+ ]),
+
+ h('textarea.twelve-word-phrase', {
+ readOnly: true,
+ value: seedWords,
+ }),
+
+ h('button.primary', {
+ onClick: () => confirmSeedWords().then(() => history.push(DEFAULT_ROUTE)),
+ style: {
+ margin: '24px',
+ fontSize: '0.9em',
+ marginBottom: '10px',
+ },
+ }, 'I\'ve copied it somewhere safe'),
+
+ h('button.primary', {
+ onClick: () => exportAsFile(`MetaMask Seed Words`, seedWords),
+ style: {
+ margin: '10px',
+ fontSize: '0.9em',
+ },
+ }, 'Save Seed Words As File'),
+ ])
+ )
+ }
+
+ renderConfirmation () {
+ const { history, warning, inProgress } = this.props
+
+ return (
+ h('.initialize-screen.flex-column.flex-center.flex-grow', {
+ style: { maxWidth: '420px' },
+ }, [
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ padding: 6,
+ },
+ }, [
+ 'Reveal Seed Words',
+ ]),
+
+ h('.div', {
+ style: {
+ display: 'flex',
+ flexDirection: 'column',
+ padding: '20px',
+ justifyContent: 'center',
+ },
+ }, [
+
+ h('h4', 'Do not recover your seed words in a public place! These words can be used to steal all your accounts.'),
+
+ // confirmation
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'Enter your password to confirm',
+ onKeyPress: this.checkConfirmation.bind(this),
+ style: {
+ width: 260,
+ marginTop: '12px',
+ },
+ }),
+
+ h('.flex-row.flex-start', {
+ style: {
+ marginTop: 30,
+ width: '50%',
+ },
+ }, [
+ // cancel
+ h('button.primary', {
+ onClick: () => history.push(DEFAULT_ROUTE),
+ }, 'CANCEL'),
+
+ // submit
+ h('button.primary', {
+ style: { marginLeft: '10px' },
+ onClick: this.revealSeedWords.bind(this),
+ }, 'OK'),
+
+ ]),
+
+ warning && (
+ h('span.error', {
+ style: {
+ margin: '20px',
+ },
+ }, warning.split('-'))
+ ),
+
+ inProgress && (
+ h('span.in-progress-notification', 'Generating Seed...')
+ ),
+ ]),
+ ])
+ )
+ }
+
+ render () {
+ return this.props.seedWords
+ ? this.renderSeed()
+ : this.renderConfirmation()
+ }
+}
+
+RevealSeedPage.propTypes = {
+ requestRevealSeed: PropTypes.func,
+ confirmSeedWords: PropTypes.func,
+ seedWords: PropTypes.string,
+ inProgress: PropTypes.bool,
+ history: PropTypes.object,
+ warning: PropTypes.string,
+}
+
+const mapStateToProps = state => {
+ const { appState: { warning }, metamask: { seedWords } } = state
+
+ return {
+ warning,
+ seedWords,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ requestRevealSeed: password => dispatch(requestRevealSeed(password)),
+ confirmSeedWords: () => dispatch(confirmSeedWords()),
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(RevealSeedPage)
diff --git a/ui/app/components/pages/metamask-route.js b/ui/app/components/pages/metamask-route.js
new file mode 100644
index 000000000..23c5b5199
--- /dev/null
+++ b/ui/app/components/pages/metamask-route.js
@@ -0,0 +1,28 @@
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const { Route } = require('react-router-dom')
+const h = require('react-hyperscript')
+
+const MetamaskRoute = ({ component, mascaraComponent, isMascara, ...props }) => {
+ return (
+ h(Route, {
+ ...props,
+ component: isMascara && mascaraComponent ? mascaraComponent : component,
+ })
+ )
+}
+
+MetamaskRoute.propTypes = {
+ component: PropTypes.func,
+ mascaraComponent: PropTypes.func,
+ isMascara: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isMascara } } = state
+ return {
+ isMascara,
+ }
+}
+
+module.exports = connect(mapStateToProps)(MetamaskRoute)
diff --git a/ui/app/components/pages/notice.js b/ui/app/components/pages/notice.js
new file mode 100644
index 000000000..2329a9147
--- /dev/null
+++ b/ui/app/components/pages/notice.js
@@ -0,0 +1,203 @@
+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('../../actions')
+const { DEFAULT_ROUTE } = require('../../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, lastUnreadNotice, lostAccounts } = metamask
+
+ return {
+ noActiveNotices,
+ lastUnreadNotice,
+ lostAccounts,
+ }
+}
+
+Notice.propTypes = {
+ notice: PropTypes.object,
+ onConfirm: PropTypes.func,
+ history: PropTypes.object,
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ markNoticeRead: lastUnreadNotice => dispatch(actions.markNoticeRead(lastUnreadNotice)),
+ markAccountsFound: () => dispatch(actions.markAccountsFound()),
+ }
+}
+
+const mergeProps = (stateProps, dispatchProps, ownProps) => {
+ const { noActiveNotices, lastUnreadNotice, lostAccounts } = stateProps
+ const { markNoticeRead, markAccountsFound } = dispatchProps
+
+ let notice
+ let onConfirm
+
+ if (!noActiveNotices) {
+ notice = lastUnreadNotice
+ onConfirm = () => markNoticeRead(lastUnreadNotice)
+ } 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/components/pages/settings/index.js b/ui/app/components/pages/settings/index.js
new file mode 100644
index 000000000..384ae4b41
--- /dev/null
+++ b/ui/app/components/pages/settings/index.js
@@ -0,0 +1,59 @@
+const { Component } = require('react')
+const { Switch, Route, matchPath } = require('react-router-dom')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const TabBar = require('../../tab-bar')
+const Settings = require('./settings')
+const Info = require('./info')
+const { DEFAULT_ROUTE, SETTINGS_ROUTE, INFO_ROUTE } = require('../../../routes')
+
+class Config extends Component {
+ renderTabs () {
+ const { history, location } = this.props
+
+ return h('div.settings__tabs', [
+ h(TabBar, {
+ tabs: [
+ { content: 'Settings', key: SETTINGS_ROUTE },
+ { content: 'Info', key: INFO_ROUTE },
+ ],
+ isActive: key => matchPath(location.pathname, { path: key, exact: true }),
+ onSelect: key => history.push(key),
+ }),
+ ])
+ }
+
+ render () {
+ const { history } = this.props
+
+ return (
+ h('.main-container.settings', {}, [
+ h('.settings__header', [
+ h('div.settings__close-button', {
+ onClick: () => history.push(DEFAULT_ROUTE),
+ }),
+ this.renderTabs(),
+ ]),
+ h(Switch, [
+ h(Route, {
+ exact: true,
+ path: INFO_ROUTE,
+ component: Info,
+ }),
+ h(Route, {
+ exact: true,
+ path: SETTINGS_ROUTE,
+ component: Settings,
+ }),
+ ]),
+ ])
+ )
+ }
+}
+
+Config.propTypes = {
+ location: PropTypes.object,
+ history: PropTypes.object,
+}
+
+module.exports = Config
diff --git a/ui/app/components/pages/settings/info.js b/ui/app/components/pages/settings/info.js
new file mode 100644
index 000000000..eb9be66e6
--- /dev/null
+++ b/ui/app/components/pages/settings/info.js
@@ -0,0 +1,112 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+
+class Info extends Component {
+ renderLogo () {
+ return (
+ h('div.settings__info-logo-wrapper', [
+ h('img.settings__info-logo', { src: 'images/info-logo.png' }),
+ ])
+ )
+ }
+
+ renderInfoLinks () {
+ return (
+ h('div.settings__content-item.settings__content-item--without-height', [
+ h('div.settings__info-link-header', this.context.t('links')),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/privacy.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', this.context.t('privacyMsg')),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/terms.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', this.context.t('terms')),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/attributions.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', this.context.t('attributions')),
+ ]),
+ ]),
+ h('hr.settings__info-separator'),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://support.metamask.io',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', this.context.t('supportCenter')),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', this.context.t('visitWebSite')),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ target: '_blank',
+ href: 'mailto:help@metamask.io?subject=Feedback',
+ }, [
+ h('span.settings__info-link', this.context.t('emailUs')),
+ ]),
+ ]),
+ ])
+ )
+ }
+
+ render () {
+ return (
+ h('div.settings__content', [
+ h('div.settings__content-row', [
+ h('div.settings__content-item.settings__content-item--without-height', [
+ this.renderLogo(),
+ h('div.settings__info-item', [
+ h('div.settings__info-version-header', 'MetaMask Version'),
+ h('div.settings__info-version-number', '4.0.0'),
+ ]),
+ h('div.settings__info-item', [
+ h(
+ 'div.settings__info-about',
+ this.context.t('builtInCalifornia')
+ ),
+ ]),
+ ]),
+ this.renderInfoLinks(),
+ ]),
+ ])
+ )
+ }
+}
+
+Info.propTypes = {
+ tab: PropTypes.string,
+ metamask: PropTypes.object,
+ setCurrentCurrency: PropTypes.func,
+ setRpcTarget: PropTypes.func,
+ displayWarning: PropTypes.func,
+ revealSeedConfirmation: PropTypes.func,
+ warning: PropTypes.string,
+ location: PropTypes.object,
+ history: PropTypes.object,
+ t: PropTypes.func,
+}
+
+Info.contextTypes = {
+ t: PropTypes.func,
+}
+
+module.exports = Info
diff --git a/ui/app/settings.js b/ui/app/components/pages/settings/settings.js
index 3aa7b9c6b..05a7379fb 100644
--- a/ui/app/settings.js
+++ b/ui/app/components/pages/settings/settings.js
@@ -1,16 +1,18 @@
const { Component } = require('react')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const connect = require('react-redux').connect
-const actions = require('./actions')
-const infuraCurrencies = require('./infura-conversion.json')
+const actions = require('../../../actions')
+const infuraCurrencies = require('../../../infura-conversion.json')
const validUrl = require('valid-url')
-const { exportAsFile } = require('./util')
-const TabBar = require('./components/tab-bar')
-const SimpleDropdown = require('./components/dropdowns/simple-dropdown')
+const { exportAsFile } = require('../../../util')
+const SimpleDropdown = require('../../dropdowns/simple-dropdown')
const ToggleButton = require('react-toggle-button')
-const locales = require('../../app/_locales/index.json')
-const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
+const { REVEAL_SEED_ROUTE } = require('../../../routes')
+const locales = require('../../../../../app/_locales/index.json')
+const { OLD_UI_NETWORK_TYPE } = require('../../../../../app/scripts/config').enums
const getInfuraCurrencyOptions = () => {
const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => {
@@ -40,30 +42,11 @@ class Settings extends Component {
constructor (props) {
super(props)
- const { tab } = props
- const activeTab = tab === 'info' ? 'info' : 'settings'
-
this.state = {
- activeTab,
newRpc: '',
}
}
- renderTabs () {
- const { activeTab } = this.state
-
- return h('div.settings__tabs', [
- h(TabBar, {
- tabs: [
- { content: this.context.t('settings'), key: 'settings' },
- { content: this.context.t('info'), key: 'info' },
- ],
- defaultTab: activeTab,
- tabSelected: key => this.setState({ activeTab: key }),
- }),
- ])
- }
-
renderBlockieOptIn () {
const { metamask: { useBlockie }, setUseBlockie } = this.props
@@ -253,7 +236,7 @@ class Settings extends Component {
}
renderSeedWords () {
- const { revealSeedConfirmation } = this.props
+ const { history } = this.props
return (
h('div.settings__content-row', [
@@ -261,9 +244,9 @@ class Settings extends Component {
h('div.settings__content-item', [
h('div.settings__content-item-col', [
h('button.btn-primary--lg.settings__button--red', {
- onClick (event) {
+ onClick: event => {
event.preventDefault()
- revealSeedConfirmation()
+ history.push(REVEAL_SEED_ROUTE)
},
}, this.context.t('revealSeedWords')),
]),
@@ -310,7 +293,7 @@ class Settings extends Component {
])
}
- renderSettingsContent () {
+ render () {
const { warning, isMascara } = this.props
return (
@@ -328,120 +311,9 @@ class Settings extends Component {
])
)
}
-
- renderLogo () {
- return (
- h('div.settings__info-logo-wrapper', [
- h('img.settings__info-logo', { src: 'images/info-logo.png' }),
- ])
- )
- }
-
- renderInfoLinks () {
- return (
- h('div.settings__content-item.settings__content-item--without-height', [
- h('div.settings__info-link-header', this.context.t('links')),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/privacy.html',
- target: '_blank',
- }, [
- h('span.settings__info-link', this.context.t('privacyMsg')),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/terms.html',
- target: '_blank',
- }, [
- h('span.settings__info-link', this.context.t('terms')),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/attributions.html',
- target: '_blank',
- }, [
- h('span.settings__info-link', this.context.t('attributions')),
- ]),
- ]),
- h('hr.settings__info-separator'),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://support.metamask.io',
- target: '_blank',
- }, [
- h('span.settings__info-link', this.context.t('supportCenter')),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/',
- target: '_blank',
- }, [
- h('span.settings__info-link', this.context.t('visitWebSite')),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- target: '_blank',
- href: 'mailto:help@metamask.io?subject=Feedback',
- }, [
- h('span.settings__info-link', this.context.t('emailUs')),
- ]),
- ]),
- ])
- )
- }
-
- renderInfoContent () {
- const version = global.platform.getVersion()
-
- return (
- h('div.settings__content', [
- h('div.settings__content-row', [
- h('div.settings__content-item.settings__content-item--without-height', [
- this.renderLogo(),
- h('div.settings__info-item', [
- h('div.settings__info-version-header', 'MetaMask Version'),
- h('div.settings__info-version-number', `${version}`),
- ]),
- h('div.settings__info-item', [
- h(
- 'div.settings__info-about',
- this.context.t('builtInCalifornia')
- ),
- ]),
- ]),
- this.renderInfoLinks(),
- ]),
- ])
- )
- }
-
- render () {
- const { goHome } = this.props
- const { activeTab } = this.state
-
- return (
- h('.main-container.settings', {}, [
- h('.settings__header', [
- h('div.settings__close-button', {
- onClick: goHome,
- }),
- this.renderTabs(),
- ]),
-
- activeTab === 'settings'
- ? this.renderSettingsContent()
- : this.renderInfoContent(),
- ])
- )
- }
}
Settings.propTypes = {
- tab: PropTypes.string,
metamask: PropTypes.object,
setUseBlockie: PropTypes.func,
setCurrentCurrency: PropTypes.func,
@@ -451,7 +323,7 @@ Settings.propTypes = {
setFeatureFlagToBeta: PropTypes.func,
showResetAccountConfirmationModal: PropTypes.func,
warning: PropTypes.string,
- goHome: PropTypes.func,
+ history: PropTypes.object,
isMascara: PropTypes.bool,
updateCurrentLocale: PropTypes.func,
currentLocale: PropTypes.string,
@@ -469,7 +341,6 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => {
return {
- goHome: () => dispatch(actions.goHome()),
setCurrentCurrency: currency => dispatch(actions.setCurrentCurrency(currency)),
setRpcTarget: newRpc => dispatch(actions.setRpcTarget(newRpc)),
displayWarning: warning => dispatch(actions.displayWarning(warning)),
@@ -490,5 +361,7 @@ Settings.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(Settings)
-
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(Settings)
diff --git a/ui/app/components/pages/unlock.js b/ui/app/components/pages/unlock.js
new file mode 100644
index 000000000..b3320da21
--- /dev/null
+++ b/ui/app/components/pages/unlock.js
@@ -0,0 +1,193 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const connect = require('../../metamask-connect')
+const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const {
+ tryUnlockMetamask,
+ forgotPassword,
+ markPasswordForgotten,
+ setNetworkEndpoints,
+ setFeatureFlag,
+} = require('../../actions')
+const environmentType = require('../../../../app/scripts/lib/environment-type')
+const getCaretCoordinates = require('textarea-caret')
+const EventEmitter = require('events').EventEmitter
+const Mascot = require('../mascot')
+const { OLD_UI_NETWORK_TYPE } = require('../../../../app/scripts/config').enums
+const { DEFAULT_ROUTE, RESTORE_VAULT_ROUTE } = require('../../routes')
+
+class UnlockScreen extends Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ error: null,
+ }
+
+ this.animationEventEmitter = new EventEmitter()
+ }
+
+ componentWillMount () {
+ const { isUnlocked, history } = this.props
+
+ if (isUnlocked) {
+ history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ componentDidMount () {
+ const passwordBox = document.getElementById('password-box')
+
+ if (passwordBox) {
+ passwordBox.focus()
+ }
+ }
+
+ tryUnlockMetamask (password) {
+ const { tryUnlockMetamask, history } = this.props
+ tryUnlockMetamask(password)
+ .then(() => history.push(DEFAULT_ROUTE))
+ .catch(({ message }) => this.setState({ error: message }))
+ }
+
+ onSubmit (event) {
+ const input = document.getElementById('password-box')
+ const password = input.value
+ this.tryUnlockMetamask(password)
+ }
+
+ onKeyPress (event) {
+ if (event.key === 'Enter') {
+ this.submitPassword(event)
+ }
+ }
+
+ submitPassword (event) {
+ var element = event.target
+ var password = element.value
+ // reset input
+ element.value = ''
+ this.tryUnlockMetamask(password)
+ }
+
+ inputChanged (event) {
+ // tell mascot to look at page action
+ var element = event.target
+ var boundingRect = element.getBoundingClientRect()
+ var coordinates = getCaretCoordinates(element, element.selectionEnd)
+ this.animationEventEmitter.emit('point', {
+ x: boundingRect.left + coordinates.left - element.scrollLeft,
+ y: boundingRect.top + coordinates.top - element.scrollTop,
+ })
+ }
+
+ render () {
+ const { error } = this.state
+ return (
+ h('.unlock-screen', [
+
+ h(Mascot, {
+ animationEventEmitter: this.animationEventEmitter,
+ }),
+
+ h('h1', {
+ style: {
+ fontSize: '1.4em',
+ textTransform: 'uppercase',
+ color: '#7F8082',
+ },
+ }, this.props.t('appName')),
+
+ h('input.large-input', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'enter password',
+ style: {
+ background: 'white',
+ },
+ onKeyPress: this.onKeyPress.bind(this),
+ onInput: this.inputChanged.bind(this),
+ }),
+
+ h('.error', {
+ style: {
+ display: error ? 'block' : 'none',
+ padding: '0 20px',
+ textAlign: 'center',
+ },
+ }, error),
+
+ h('button.primary.cursor-pointer', {
+ onClick: this.onSubmit.bind(this),
+ style: {
+ margin: 10,
+ },
+ }, this.props.t('login')),
+
+ h('p.pointer', {
+ onClick: () => {
+ this.props.markPasswordForgotten()
+ this.props.history.push(RESTORE_VAULT_ROUTE)
+
+ if (environmentType() === 'popup') {
+ global.platform.openExtensionInBrowser()
+ }
+ },
+ style: {
+ fontSize: '0.8em',
+ color: 'rgb(247, 134, 28)',
+ textDecoration: 'underline',
+ },
+ }, this.props.t('restoreFromSeed')),
+
+ h('p.pointer', {
+ onClick: () => {
+ this.props.useOldInterface()
+ .then(() => this.props.setNetworkEndpoints(OLD_UI_NETWORK_TYPE))
+ },
+ style: {
+ fontSize: '0.8em',
+ color: '#aeaeae',
+ textDecoration: 'underline',
+ marginTop: '32px',
+ },
+ }, this.props.t('classicInterface')),
+ ])
+ )
+ }
+}
+
+UnlockScreen.propTypes = {
+ forgotPassword: PropTypes.func,
+ tryUnlockMetamask: PropTypes.func,
+ markPasswordForgotten: PropTypes.func,
+ history: PropTypes.object,
+ isUnlocked: PropTypes.bool,
+ t: PropTypes.func,
+ useOldInterface: PropTypes.func,
+ setNetworkEndpoints: PropTypes.func,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isUnlocked } } = state
+ return {
+ isUnlocked,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ forgotPassword: () => dispatch(forgotPassword()),
+ tryUnlockMetamask: password => dispatch(tryUnlockMetamask(password)),
+ markPasswordForgotten: () => dispatch(markPasswordForgotten()),
+ useOldInterface: () => dispatch(setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')),
+ setNetworkEndpoints: type => dispatch(setNetworkEndpoints(type)),
+ }
+}
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(UnlockScreen)
diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js
index d007e6661..3ee614a2a 100644
--- a/ui/app/components/pending-tx/confirm-send-ether.js
+++ b/ui/app/components/pending-tx/confirm-send-ether.js
@@ -1,4 +1,6 @@
const Component = require('react').Component
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
@@ -23,12 +25,16 @@ const SenderToRecipient = require('../sender-to-recipient')
const NetworkDisplay = require('../network-display')
const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
+const { SEND_ROUTE, DEFAULT_ROUTE } = require('../../routes')
ConfirmSendEther.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendEther)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(ConfirmSendEther)
function mapStateToProps (state) {
@@ -72,7 +78,6 @@ function mapDispatchToProps (dispatch) {
errors: { to: null, amount: null },
editingTransactionId: id,
}))
- dispatch(actions.showSendPage())
},
cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
showCustomizeGasModal: (txMeta, sendGasLimit, sendGasPrice, sendGasTotal) => {
@@ -237,6 +242,7 @@ ConfirmSendEther.prototype.getData = function () {
const { identities } = this.props
const txMeta = this.gatherTxMeta()
const txParams = txMeta.txParams || {}
+ const account = identities ? identities[txParams.from] || {} : {}
const { FIAT: gasFeeInFIAT, ETH: gasFeeInETH, gasFeeInHex } = this.getGasFee()
const { FIAT: amountInFIAT, ETH: amountInETH } = this.getAmount()
@@ -252,7 +258,7 @@ ConfirmSendEther.prototype.getData = function () {
return {
from: {
address: txParams.from,
- name: identities[txParams.from].name,
+ name: account.name,
},
to: {
address: txParams.to,
@@ -269,9 +275,14 @@ ConfirmSendEther.prototype.getData = function () {
}
}
+ConfirmSendEther.prototype.editTransaction = function (txMeta) {
+ const { editTransaction, history } = this.props
+ editTransaction(txMeta)
+ history.push(SEND_ROUTE)
+}
+
ConfirmSendEther.prototype.render = function () {
const {
- editTransaction,
currentCurrency,
clearSend,
conversionRate,
@@ -327,7 +338,7 @@ ConfirmSendEther.prototype.render = function () {
h('.page-container__header', [
h('.page-container__header-row', [
h('span.page-container__back-button', {
- onClick: () => editTransaction(txMeta),
+ onClick: () => this.editTransaction(txMeta),
style: {
visibility: !txMeta.lastGasPrice ? 'initial' : 'hidden',
},
@@ -505,7 +516,9 @@ ConfirmSendEther.prototype.render = function () {
}, this.context.t('cancel')),
// Accept Button
- h('button.btn-confirm.page-container__footer-button.allcaps', [this.context.t('confirm')]),
+ h('button.btn-confirm.page-container__footer-button.allcaps', {
+ onClick: event => this.onSubmit(event),
+ }, this.context.t('confirm')),
]),
]),
])
@@ -543,6 +556,7 @@ ConfirmSendEther.prototype.cancel = function (event, txMeta) {
const { cancelTransaction } = this.props
cancelTransaction(txMeta)
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
}
ConfirmSendEther.prototype.isBalanceSufficient = function (txMeta) {
@@ -630,4 +644,4 @@ ConfirmSendEther.prototype.bnMultiplyByFraction = function (targetBN, numerator,
const numBN = new BN(numerator)
const denomBN = new BN(denominator)
return targetBN.mul(numBN).div(denomBN)
-} \ No newline at end of file
+}
diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js
index 19e591fd6..6942f9b51 100644
--- a/ui/app/components/pending-tx/confirm-send-token.js
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -1,4 +1,6 @@
const Component = require('react').Component
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
@@ -33,12 +35,16 @@ const {
getSelectedAddress,
getSelectedTokenContract,
} = require('../../selectors')
+const { SEND_ROUTE, DEFAULT_ROUTE } = require('../../routes')
ConfirmSendToken.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendToken)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(ConfirmSendToken)
function mapStateToProps (state, ownProps) {
@@ -147,6 +153,12 @@ function ConfirmSendToken () {
this.onSubmit = this.onSubmit.bind(this)
}
+ConfirmSendToken.prototype.editTransaction = function (txMeta) {
+ const { editTransaction, history } = this.props
+ editTransaction(txMeta)
+ history.push(SEND_ROUTE)
+}
+
ConfirmSendToken.prototype.updateComponentSendErrors = function (prevProps) {
const {
balance: oldBalance,
@@ -406,7 +418,6 @@ ConfirmSendToken.prototype.renderErrorMessage = function (message) {
}
ConfirmSendToken.prototype.render = function () {
- const { editTransaction } = this.props
const txMeta = this.gatherTxMeta()
const {
from: {
@@ -433,7 +444,7 @@ ConfirmSendToken.prototype.render = function () {
h('div.page-container', [
h('div.page-container__header', [
!txMeta.lastGasPrice && h('button.confirm-screen-back-button', {
- onClick: () => editTransaction(txMeta),
+ onClick: () => this.editTransaction(txMeta),
}, this.context.t('edit')),
h('div.page-container__title', title),
h('div.page-container__subtitle', subtitle),
@@ -513,7 +524,9 @@ ConfirmSendToken.prototype.render = function () {
}, this.context.t('cancel')),
// Accept Button
- h('button.btn-confirm.page-container__footer-button.allcaps', [this.context.t('confirm')]),
+ h('button.btn-confirm.page-container__footer-button.allcaps', {
+ onClick: event => this.onSubmit(event),
+ }, [this.context.t('confirm')]),
]),
]),
]),
@@ -566,6 +579,7 @@ ConfirmSendToken.prototype.cancel = function (event, txMeta) {
const { cancelTransaction } = this.props
cancelTransaction(txMeta)
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
}
ConfirmSendToken.prototype.checkValidity = function () {
diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js
index 08c26a91f..aca1a5a0a 100644
--- a/ui/app/components/send/send-v2-container.js
+++ b/ui/app/components/send/send-v2-container.js
@@ -2,6 +2,8 @@ const connect = require('react-redux').connect
const actions = require('../../actions')
const abi = require('ethereumjs-abi')
const SendEther = require('../../send-v2')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const {
accountsWithSendEtherInfoSelector,
@@ -16,7 +18,10 @@ const {
getSelectedTokenContract,
} = require('../../selectors')
-module.exports = connect(mapStateToProps, mapDispatchToProps)(SendEther)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(SendEther)
function mapStateToProps (state) {
const fromAccounts = accountsWithSendEtherInfoSelector(state)
@@ -79,7 +84,6 @@ function mapDispatchToProps (dispatch) {
updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)),
updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)),
- goHome: () => dispatch(actions.goHome()),
clearSend: () => dispatch(actions.clearSend()),
setMaxModeTo: bool => dispatch(actions.setMaxModeTo(bool)),
}
diff --git a/ui/app/components/signature-request.js b/ui/app/components/signature-request.js
index 41415411e..b958a2d2d 100644
--- a/ui/app/components/signature-request.js
+++ b/ui/app/components/signature-request.js
@@ -6,6 +6,8 @@ const Identicon = require('./identicon')
const connect = require('react-redux').connect
const ethUtil = require('ethereumjs-util')
const classnames = require('classnames')
+const { compose } = require('recompose')
+const { withRouter } = require('react-router-dom')
const AccountDropdownMini = require('./dropdowns/account-dropdown-mini')
@@ -20,6 +22,8 @@ const {
conversionRateSelector,
} = require('../selectors.js')
+const { DEFAULT_ROUTE } = require('../routes')
+
function mapStateToProps (state) {
return {
balance: getSelectedAccount(state).balance,
@@ -42,7 +46,10 @@ SignatureRequest.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(SignatureRequest)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(SignatureRequest)
inherits(SignatureRequest, Component)
@@ -229,10 +236,14 @@ SignatureRequest.prototype.renderFooter = function () {
return h('div.request-signature__footer', [
h('button.btn-secondary--lg.request-signature__footer__cancel-button', {
- onClick: cancel,
+ onClick: event => {
+ cancel(event).then(() => this.props.history.push(DEFAULT_ROUTE))
+ },
}, this.context.t('cancel')),
h('button.btn-primary--lg', {
- onClick: sign,
+ onClick: event => {
+ sign(event).then(() => this.props.history.push(DEFAULT_ROUTE))
+ },
}, this.context.t('sign')),
])
}
diff --git a/ui/app/components/tab-bar.js b/ui/app/components/tab-bar.js
index a80640116..0016a09c1 100644
--- a/ui/app/components/tab-bar.js
+++ b/ui/app/components/tab-bar.js
@@ -4,31 +4,17 @@ const PropTypes = require('prop-types')
const classnames = require('classnames')
class TabBar extends Component {
- constructor (props) {
- super(props)
- const { defaultTab, tabs } = props
-
- this.state = {
- subview: defaultTab || tabs[0].key,
- }
- }
-
render () {
- const { tabs = [], tabSelected } = this.props
- const { subview } = this.state
+ const { tabs = [], onSelect, isActive } = this.props
return (
h('.tab-bar', {}, [
- tabs.map((tab) => {
- const { key, content } = tab
+ tabs.map(({ key, content }) => {
return h('div', {
className: classnames('tab-bar__tab pointer', {
- 'tab-bar__tab--active': subview === key,
+ 'tab-bar__tab--active': isActive(key, content),
}),
- onClick: () => {
- this.setState({ subview: key })
- tabSelected(key)
- },
+ onClick: () => onSelect(key),
key,
}, content)
}),
@@ -39,9 +25,9 @@ class TabBar extends Component {
}
TabBar.propTypes = {
- defaultTab: PropTypes.string,
+ isActive: PropTypes.func.isRequired,
tabs: PropTypes.array,
- tabSelected: PropTypes.func,
+ onSelect: PropTypes.func,
}
module.exports = TabBar
diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js
index 740c4a4ab..554febcff 100644
--- a/ui/app/components/tx-list.js
+++ b/ui/app/components/tx-list.js
@@ -11,14 +11,19 @@ const { formatDate } = require('../util')
const { showConfTxPage } = require('../actions')
const classnames = require('classnames')
const { tokenInfoGetter } = require('../token-util')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const { CONFIRM_TRANSACTION_ROUTE } = require('../routes')
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(TxList)
TxList.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(TxList)
-
-
function mapStateToProps (state) {
return {
txsToRender: selectors.transactionsSelector(state),
@@ -96,7 +101,7 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa
transactionNetworkId,
transactionSubmittedTime,
} = props
- const { showConfTxPage } = this.props
+ const { history } = this.props
const opts = {
key: transactionId || transactionHash,
@@ -116,7 +121,10 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa
const isUnapproved = transactionStatus === 'unapproved'
if (isUnapproved) {
- opts.onClick = () => showConfTxPage({ id: transactionId })
+ opts.onClick = () => {
+ this.props.showConfTxPage({ id: transactionId })
+ history.push(CONFIRM_TRANSACTION_ROUTE)
+ }
opts.transactionStatus = this.context.t('notStarted')
} else if (transactionHash) {
opts.onClick = () => this.view(transactionHash, transactionNetworkId)
diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js
index ca24e813f..80aac35c4 100644
--- a/ui/app/components/tx-view.js
+++ b/ui/app/components/tx-view.js
@@ -4,20 +4,25 @@ const connect = require('react-redux').connect
const h = require('react-hyperscript')
const ethUtil = require('ethereumjs-util')
const inherits = require('util').inherits
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const actions = require('../actions')
const selectors = require('../selectors')
+const { SEND_ROUTE } = require('../routes')
const BalanceComponent = require('./balance-component')
const TxList = require('./tx-list')
const Identicon = require('./identicon')
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(TxView)
+
TxView.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(TxView)
-
-
function mapStateToProps (state) {
const sidebarOpen = state.appState.sidebarOpen
const isMascara = state.appState.isMascara
@@ -69,7 +74,7 @@ TxView.prototype.renderHeroBalance = function () {
}
TxView.prototype.renderButtons = function () {
- const {selectedToken, showModal, showSendPage, showSendTokenPage } = this.props
+ const {selectedToken, showModal, history } = this.props
return !selectedToken
? (
@@ -84,14 +89,14 @@ TxView.prototype.renderButtons = function () {
style: {
marginLeft: '0.8em',
},
- onClick: showSendPage,
+ onClick: () => history.push(SEND_ROUTE),
}, this.context.t('send')),
])
)
: (
h('div.flex-row.flex-center.hero-balance-buttons', [
h('button.btn-primary.hero-balance-button', {
- onClick: showSendTokenPage,
+ onClick: () => history.push(SEND_ROUTE),
}, this.context.t('send')),
])
)
diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js
index e6b94ad12..e3e1b8903 100644
--- a/ui/app/components/wallet-view.js
+++ b/ui/app/components/wallet-view.js
@@ -2,6 +2,8 @@ const Component = require('react').Component
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const inherits = require('util').inherits
const classnames = require('classnames')
const Identicon = require('./identicon')
@@ -12,14 +14,17 @@ const actions = require('../actions')
const BalanceComponent = require('./balance-component')
const TokenList = require('./token-list')
const selectors = require('../selectors')
+const { ADD_TOKEN_ROUTE } = require('../routes')
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(WalletView)
WalletView.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(WalletView)
-
-
function mapStateToProps (state) {
return {
@@ -97,7 +102,7 @@ WalletView.prototype.render = function () {
keyrings,
showAccountDetailModal,
hideSidebar,
- showAddTokenPage,
+ history,
} = this.props
// temporary logs + fake extra wallets
// console.log('walletview, selectedAccount:', selectedAccount)
@@ -174,10 +179,7 @@ WalletView.prototype.render = function () {
h(TokenList),
h('button.btn-primary.wallet-view__add-token-button', {
- onClick: () => {
- showAddTokenPage()
- hideSidebar()
- },
+ onClick: () => history.push(ADD_TOKEN_ROUTE),
}, this.context.t('addToken')),
])
}
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index 1070436c3..fee7cd36f 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -2,6 +2,8 @@ const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const actions = require('./actions')
const txHelper = require('../lib/tx-helper')
@@ -11,19 +13,21 @@ const SignatureRequest = require('./components/signature-request')
// const PendingPersonalMsg = require('./components/pending-personal-msg')
// const PendingTypedMsg = require('./components/pending-typed-msg')
const Loading = require('./components/loading')
+const { DEFAULT_ROUTE } = require('./routes')
-// const contentDivider = h('div', {
-// style: {
-// marginLeft: '16px',
-// marginRight: '16px',
-// height:'1px',
-// background:'#E7E7E7',
-// },
-// })
-
-module.exports = connect(mapStateToProps)(ConfirmTxScreen)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps)
+)(ConfirmTxScreen)
function mapStateToProps (state) {
+ const { metamask } = state
+ const {
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ } = metamask
+
return {
identities: state.metamask.identities,
accounts: state.metamask.accounts,
@@ -40,6 +44,10 @@ function mapStateToProps (state) {
currentCurrency: state.metamask.currentCurrency,
blockGasLimit: state.metamask.currentBlockGasLimit,
computedBalances: state.metamask.computedBalances,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ send: state.metamask.send,
selectedAddressTxList: state.metamask.selectedAddressTxList,
}
}
@@ -49,11 +57,35 @@ function ConfirmTxScreen () {
Component.call(this)
}
+ConfirmTxScreen.prototype.getUnapprovedMessagesTotal = function () {
+ const {
+ unapprovedMsgCount = 0,
+ unapprovedPersonalMsgCount = 0,
+ unapprovedTypedMessagesCount = 0,
+ } = this.props
+
+ return unapprovedTypedMessagesCount + unapprovedMsgCount + unapprovedPersonalMsgCount
+}
+
+ConfirmTxScreen.prototype.componentDidMount = function () {
+ const {
+ unapprovedTxs = {},
+ network,
+ send,
+ } = this.props
+ const unconfTxList = txHelper(unapprovedTxs, {}, {}, {}, network)
+
+ if (unconfTxList.length === 0 && !send.to && this.getUnapprovedMessagesTotal() === 0) {
+ this.props.history.push(DEFAULT_ROUTE)
+ }
+}
+
ConfirmTxScreen.prototype.componentDidUpdate = function (prevProps) {
const {
- unapprovedTxs,
+ unapprovedTxs = {},
network,
selectedAddressTxList,
+ send,
} = this.props
const { index: prevIndex, unapprovedTxs: prevUnapprovedTxs } = prevProps
const prevUnconfTxList = txHelper(prevUnapprovedTxs, {}, {}, {}, network)
@@ -61,8 +93,9 @@ ConfirmTxScreen.prototype.componentDidUpdate = function (prevProps) {
const prevTx = selectedAddressTxList.find(({ id }) => id === prevTxData.id) || {}
const unconfTxList = txHelper(unapprovedTxs, {}, {}, {}, network)
- if (prevTx.status === 'dropped' && unconfTxList.length === 0) {
- this.goHome({})
+ if (unconfTxList.length === 0 &&
+ (prevTx.status === 'dropped' || !send.to && this.getUnapprovedMessagesTotal() === 0)) {
+ this.props.history.push(DEFAULT_ROUTE)
}
}
@@ -103,7 +136,6 @@ ConfirmTxScreen.prototype.render = function () {
*/
log.info(`rendering a combined ${unconfTxList.length} unconf msg & txs`)
- if (unconfTxList.length === 0) return h(Loading)
return currentTxView({
// Properties
@@ -152,6 +184,7 @@ function currentTxView (opts) {
// return h(PendingTypedMsg, opts)
// }
}
+
return h(Loading)
}
@@ -163,6 +196,7 @@ ConfirmTxScreen.prototype.buyEth = function (address, event) {
ConfirmTxScreen.prototype.sendTransaction = function (txData, event) {
this.stopPropagation(event)
this.props.dispatch(actions.updateAndApproveTx(txData))
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
}
ConfirmTxScreen.prototype.cancelTransaction = function (txData, event) {
@@ -182,7 +216,7 @@ ConfirmTxScreen.prototype.signMessage = function (msgData, event) {
var params = msgData.msgParams
params.metamaskId = msgData.id
this.stopPropagation(event)
- this.props.dispatch(actions.signMsg(params))
+ return this.props.dispatch(actions.signMsg(params))
}
ConfirmTxScreen.prototype.stopPropagation = function (event) {
@@ -196,7 +230,7 @@ ConfirmTxScreen.prototype.signPersonalMessage = function (msgData, event) {
var params = msgData.msgParams
params.metamaskId = msgData.id
this.stopPropagation(event)
- this.props.dispatch(actions.signPersonalMsg(params))
+ return this.props.dispatch(actions.signPersonalMsg(params))
}
ConfirmTxScreen.prototype.signTypedMessage = function (msgData, event) {
@@ -204,25 +238,25 @@ ConfirmTxScreen.prototype.signTypedMessage = function (msgData, event) {
var params = msgData.msgParams
params.metamaskId = msgData.id
this.stopPropagation(event)
- this.props.dispatch(actions.signTypedMsg(params))
+ return this.props.dispatch(actions.signTypedMsg(params))
}
ConfirmTxScreen.prototype.cancelMessage = function (msgData, event) {
log.info('canceling message')
this.stopPropagation(event)
- this.props.dispatch(actions.cancelMsg(msgData))
+ return this.props.dispatch(actions.cancelMsg(msgData))
}
ConfirmTxScreen.prototype.cancelPersonalMessage = function (msgData, event) {
log.info('canceling personal message')
this.stopPropagation(event)
- this.props.dispatch(actions.cancelPersonalMsg(msgData))
+ return this.props.dispatch(actions.cancelPersonalMsg(msgData))
}
ConfirmTxScreen.prototype.cancelTypedMessage = function (msgData, event) {
log.info('canceling typed message')
this.stopPropagation(event)
- this.props.dispatch(actions.cancelTypedMsg(msgData))
+ return this.props.dispatch(actions.cancelTypedMsg(msgData))
}
ConfirmTxScreen.prototype.goHome = function (event) {
diff --git a/ui/app/css/index.scss b/ui/app/css/index.scss
index 445c819ff..c068028f8 100644
--- a/ui/app/css/index.scss
+++ b/ui/app/css/index.scss
@@ -6,9 +6,15 @@
*/
@import './itcss/settings/index.scss';
+
@import './itcss/tools/index.scss';
+
@import './itcss/generic/index.scss';
+
@import './itcss/base/index.scss';
+
@import './itcss/objects/index.scss';
+
@import './itcss/components/index.scss';
+
@import './itcss/trumps/index.scss';
diff --git a/ui/app/css/itcss/components/add-token.scss b/ui/app/css/itcss/components/add-token.scss
index f5c1de67c..2fdda6f43 100644
--- a/ui/app/css/itcss/components/add-token.scss
+++ b/ui/app/css/itcss/components/add-token.scss
@@ -8,6 +8,7 @@
font-family: 'Roboto';
background: white;
border-radius: 8px;
+ box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08);
&__wrapper {
background-color: $white;
@@ -20,7 +21,7 @@
&__header {
display: flex;
flex-flow: column nowrap;
- padding: 16px 16px 0px;
+ padding: 20px 20px 0px;
border-bottom: 1px solid $geyser;
flex: 0 0 auto;
@@ -31,7 +32,8 @@
span {
font-family: Roboto;
- font-size: 16px;
+ font-size: 16px;
+ font-weight: 400;
line-height: 21px;
margin-left: 8px;
}
@@ -44,8 +46,13 @@
margin-top: 4px;
}
+ &__subtitle {
+ font-weight: 400;
+ margin-top: 15px;
+ margin-bottom: 21px;
+ }
+
&__tabs {
- margin-left: 22px;
display: flex;
&__tab {
@@ -54,6 +61,7 @@
color: $dusty-gray;
font-family: Roboto;
font-size: 18px;
+ font-weight: 400;
line-height: 24px;
text-align: center;
}
@@ -65,6 +73,7 @@
&__unselected:hover {
color: $black;
border-bottom: none;
+ cursor: pointer;
}
&__selected {
@@ -76,7 +85,7 @@
&__info-box {
height: 96px;
- margin: 20px 24px 0px;
+ margin: 20px 20px 0px;
border-radius: 4px;
background-color: $alabaster;
position: relative;
@@ -98,6 +107,7 @@
color: $mid-gray;
font-family: Roboto;
font-size: 14px;
+ font-weight: 400;
margin-top: 15px;
margin-bottom: 9px;
}
@@ -107,6 +117,7 @@
color: $mid-gray;
font-family: Roboto;
font-size: 12px;
+ font-weight: 400;
line-height: 18px;
}
@@ -124,7 +135,8 @@
}
&__confirmation-description {
- margin: 12px 0;
+ font-weight: 400;
+ margin: 20px 0 40px 0;
}
&__content-container {
@@ -151,7 +163,7 @@
&__input,
&__add-custom-input {
height: 54px;
- padding: 21px 6px;
+ padding: 0px 20px;
border: 1px solid $geyser;
border-radius: 4px;
margin: 22px 24px;
@@ -232,6 +244,7 @@
&__add-custom-label {
font-size: 16px;
+ font-weight: 400;
line-height: 21px;
margin-left: 22px;
color: $scorpion;
@@ -274,9 +287,11 @@
color: #5B5D67;
font-family: Roboto;
font-size: 18px;
+ font-weight: 400;
line-height: 24px;
margin-left: 24px;
margin-top: 8px;
+ margin-bottom: 20px;
}
&__token-icons-container {
@@ -317,6 +332,7 @@
}
&__token-name {
+ font-weight: 400;
font-size: 14px;
line-height: 19px;
}
@@ -368,6 +384,7 @@
&__symbol {
color: $scorpion;
font-size: 16px;
+ font-weight: 400;
line-height: 24px;
}
}
diff --git a/ui/app/css/itcss/components/index.scss b/ui/app/css/itcss/components/index.scss
index ffd43ecbf..959eb9d15 100644
--- a/ui/app/css/itcss/components/index.scss
+++ b/ui/app/css/itcss/components/index.scss
@@ -52,6 +52,8 @@
@import './editable-label.scss';
+@import './pages/index.scss';
+
@import './new-account.scss';
@import './tooltip.scss';
diff --git a/ui/app/css/itcss/components/new-account.scss b/ui/app/css/itcss/components/new-account.scss
index aa7fed956..293579058 100644
--- a/ui/app/css/itcss/components/new-account.scss
+++ b/ui/app/css/itcss/components/new-account.scss
@@ -35,13 +35,14 @@
font-size: 18px;
line-height: 24px;
text-align: center;
+ cursor: pointer;
}
&__tab:first-of-type {
margin-right: 20px;
}
- &__unselected:hover {
+ &__tab:hover {
color: $black;
border-bottom: none;
}
@@ -49,9 +50,9 @@
&__selected {
color: $curious-blue;
border-bottom: 3px solid $curious-blue;
+ cursor: initial;
}
}
-
}
.new-account-import-disclaimer {
diff --git a/ui/app/css/itcss/components/pages/index.scss b/ui/app/css/itcss/components/pages/index.scss
new file mode 100644
index 000000000..82446fd7a
--- /dev/null
+++ b/ui/app/css/itcss/components/pages/index.scss
@@ -0,0 +1 @@
+@import './unlock.scss';
diff --git a/ui/app/css/itcss/components/pages/unlock.scss b/ui/app/css/itcss/components/pages/unlock.scss
new file mode 100644
index 000000000..5d438377b
--- /dev/null
+++ b/ui/app/css/itcss/components/pages/unlock.scss
@@ -0,0 +1,9 @@
+.unlock-page {
+ box-shadow: none;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background: rgb(247, 247, 247);
+ width: 100%;
+}
diff --git a/ui/app/css/itcss/components/sections.scss b/ui/app/css/itcss/components/sections.scss
index 388aea175..ace46bd8a 100644
--- a/ui/app/css/itcss/components/sections.scss
+++ b/ui/app/css/itcss/components/sections.scss
@@ -17,6 +17,12 @@ textarea.twelve-word-phrase {
resize: none;
}
+.initialize-screen {
+ width: 100%;
+ z-index: $main-container-z-index;
+ background: #f7f7f7;
+}
+
.initialize-screen hr {
width: 60px;
margin: 12px;
diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js
index 4ab5f06c0..692b01c8c 100644
--- a/ui/app/first-time/init-menu.js
+++ b/ui/app/first-time/init-menu.js
@@ -1,6 +1,5 @@
-const inherits = require('util').inherits
-const EventEmitter = require('events').EventEmitter
-const Component = require('react').Component
+const { EventEmitter } = require('events')
+const { Component } = require('react')
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
@@ -8,205 +7,219 @@ const Mascot = require('../components/mascot')
const actions = require('../actions')
const Tooltip = require('../components/tooltip')
const getCaretCoordinates = require('textarea-caret')
+const { RESTORE_VAULT_ROUTE, DEFAULT_ROUTE } = require('../routes')
const environmentType = require('../../../app/scripts/lib/environment-type')
const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/config').enums
-let isSubmitting = false
+class InitializeMenuScreen extends Component {
+ constructor (props) {
+ super(props)
-InitializeMenuScreen.contextTypes = {
- t: PropTypes.func,
-}
-
-module.exports = connect(mapStateToProps)(InitializeMenuScreen)
-
-
-inherits(InitializeMenuScreen, Component)
-function InitializeMenuScreen () {
- Component.call(this)
- this.animationEventEmitter = new EventEmitter()
-}
-
-function mapStateToProps (state) {
- return {
- // state from plugin
- currentView: state.appState.currentView,
- warning: state.appState.warning,
+ this.animationEventEmitter = new EventEmitter()
+ this.state = {
+ warning: null,
+ }
}
-}
-
-InitializeMenuScreen.prototype.render = function () {
- var state = this.props
-
- switch (state.currentView.name) {
-
- default:
- return this.renderMenu(state)
+ componentWillMount () {
+ const { isInitialized, isUnlocked, history } = this.props
+ if (isInitialized || isUnlocked) {
+ history.push(DEFAULT_ROUTE)
+ }
}
-}
-// InitializeMenuScreen.prototype.componentDidMount = function(){
-// document.getElementById('password-box').focus()
-// }
-
-InitializeMenuScreen.prototype.renderMenu = function (state) {
- return (
-
- h('.initialize-screen.flex-column.flex-center.flex-grow', [
+ componentDidMount () {
+ document.getElementById('password-box').focus()
+ }
- h(Mascot, {
- animationEventEmitter: this.animationEventEmitter,
- }),
+ render () {
+ const { warning } = this.state
- h('h1', {
- style: {
- fontSize: '1.3em',
- textTransform: 'uppercase',
- color: '#7F8082',
- marginBottom: 10,
- },
- }, this.context.t('appName')),
+ return (
+ h('.initialize-screen.flex-column.flex-center', [
+ h(Mascot, {
+ animationEventEmitter: this.animationEventEmitter,
+ }),
- h('div', [
- h('h3', {
+ h('h1', {
style: {
- fontSize: '0.8em',
+ fontSize: '1.3em',
+ textTransform: 'uppercase',
color: '#7F8082',
- display: 'inline',
+ marginBottom: 10,
},
- }, this.context.t('encryptNewDen')),
+ }, this.context.t('appName')),
- h(Tooltip, {
- title: this.context.t('denExplainer'),
- }, [
- h('i.fa.fa-question-circle.pointer', {
+ h('div', [
+ h('h3', {
style: {
- fontSize: '18px',
- position: 'relative',
- color: 'rgb(247, 134, 28)',
- top: '2px',
- marginLeft: '4px',
+ fontSize: '0.8em',
+ color: '#7F8082',
+ display: 'inline',
},
- }),
+ }, this.context.t('encryptNewDen')),
+
+ h(Tooltip, {
+ title: this.context.t('denExplainer'),
+ }, [
+ h('i.fa.fa-question-circle.pointer', {
+ style: {
+ fontSize: '18px',
+ position: 'relative',
+ color: 'rgb(247, 134, 28)',
+ top: '2px',
+ marginLeft: '4px',
+ },
+ }),
+ ]),
]),
- ]),
-
- h('span.in-progress-notification', state.warning),
-
- // password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box',
- placeholder: this.context.t('newPassword'),
- onInput: this.inputChanged.bind(this),
- style: {
- width: 260,
- marginTop: 12,
- },
- }),
-
- // confirm password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box-confirm',
- placeholder: this.context.t('confirmPassword'),
- onKeyPress: this.createVaultOnEnter.bind(this),
- onInput: this.inputChanged.bind(this),
- style: {
- width: 260,
- marginTop: 16,
- },
- }),
-
-
- h('button.primary', {
- onClick: this.createNewVaultAndKeychain.bind(this),
- style: {
- margin: 12,
- },
- }, this.context.t('createDen')),
-
- h('.flex-row.flex-center.flex-grow', [
- h('p.pointer', {
- onClick: this.showRestoreVault.bind(this),
+
+ h('span.error.in-progress-notification', warning),
+
+ // password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: this.context.t('newPassword'),
+ onInput: this.inputChanged.bind(this),
+ style: {
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ // confirm password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box-confirm',
+ placeholder: this.context.t('confirmPassword'),
+ onKeyPress: this.createVaultOnEnter.bind(this),
+ onInput: this.inputChanged.bind(this),
style: {
- fontSize: '0.8em',
- color: 'rgb(247, 134, 28)',
- textDecoration: 'underline',
+ width: 260,
+ marginTop: 16,
},
- }, this.context.t('importDen')),
- ]),
+ }),
+
- h('.flex-row.flex-center.flex-grow', [
- h('p.pointer', {
- onClick: this.showOldUI.bind(this),
+ h('button.primary', {
+ onClick: this.createNewVaultAndKeychain.bind(this),
style: {
- fontSize: '0.8em',
- color: '#aeaeae',
- textDecoration: 'underline',
- marginTop: '32px',
+ margin: 12,
},
- }, 'Use classic interface'),
- ]),
+ }, this.context.t('createDen')),
- ])
- )
-}
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: () => this.showRestoreVault(),
+ style: {
+ fontSize: '0.8em',
+ color: 'rgb(247, 134, 28)',
+ textDecoration: 'underline',
+ },
+ }, this.context.t('importDen')),
+ ]),
-InitializeMenuScreen.prototype.createVaultOnEnter = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.createNewVaultAndKeychain()
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: this.showOldUI.bind(this),
+ style: {
+ fontSize: '0.8em',
+ color: '#aeaeae',
+ textDecoration: 'underline',
+ marginTop: '32px',
+ },
+ }, 'Use classic interface'),
+ ]),
+
+ ])
+ )
}
-}
-InitializeMenuScreen.prototype.componentDidMount = function () {
- document.getElementById('password-box').focus()
-}
+ createVaultOnEnter (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewVaultAndKeychain()
+ }
+ }
-InitializeMenuScreen.prototype.showRestoreVault = function () {
- this.props.dispatch(actions.markPasswordForgotten())
- if (environmentType() === 'popup') {
- global.platform.openExtensionInBrowser()
+ createNewVaultAndKeychain () {
+ const { history } = this.props
+ var passwordBox = document.getElementById('password-box')
+ var password = passwordBox.value
+ var passwordConfirmBox = document.getElementById('password-box-confirm')
+ var passwordConfirm = passwordConfirmBox.value
+
+ this.setState({ warning: null })
+
+ if (password.length < 8) {
+ this.setState({ warning: this.context.t('passwordShort') })
+ return
+ }
+
+ if (password !== passwordConfirm) {
+ this.setState({ warning: this.context.t('passwordMismatch') })
+ return
+ }
+
+ this.props.createNewVaultAndKeychain(password)
+ .then(() => history.push(DEFAULT_ROUTE))
}
-}
-InitializeMenuScreen.prototype.showOldUI = function () {
- this.props.dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
- .then(() => this.props.dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
-}
+ inputChanged (event) {
+ // tell mascot to look at page action
+ var element = event.target
+ var boundingRect = element.getBoundingClientRect()
+ var coordinates = getCaretCoordinates(element, element.selectionEnd)
+ this.animationEventEmitter.emit('point', {
+ x: boundingRect.left + coordinates.left - element.scrollLeft,
+ y: boundingRect.top + coordinates.top - element.scrollTop,
+ })
+ }
-InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
- var passwordBox = document.getElementById('password-box')
- var password = passwordBox.value
- var passwordConfirmBox = document.getElementById('password-box-confirm')
- var passwordConfirm = passwordConfirmBox.value
+ showRestoreVault () {
+ this.props.markPasswordForgotten()
+ if (environmentType() === 'popup') {
+ global.platform.openExtensionInBrowser()
+ }
- if (password.length < 8) {
- this.warning = this.context.t('passwordShort')
- this.props.dispatch(actions.displayWarning(this.warning))
- return
+ this.props.history.push(RESTORE_VAULT_ROUTE)
}
- if (password !== passwordConfirm) {
- this.warning = this.context.t('passwordMismatch')
- this.props.dispatch(actions.displayWarning(this.warning))
- return
+
+ showOldUI () {
+ this.props.dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
+ .then(() => this.props.dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
}
+}
+
+InitializeMenuScreen.propTypes = {
+ history: PropTypes.object,
+ isInitialized: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
+ createNewVaultAndKeychain: PropTypes.func,
+ markPasswordForgotten: PropTypes.func,
+ dispatch: PropTypes.func,
+}
- if (!isSubmitting) {
- isSubmitting = true
- this.props.dispatch(actions.createNewVaultAndKeychain(password))
+InitializeMenuScreen.contextTypes = {
+ t: PropTypes.func,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isInitialized, isUnlocked } } = state
+
+ return {
+ isInitialized,
+ isUnlocked,
}
}
-InitializeMenuScreen.prototype.inputChanged = function (event) {
- // tell mascot to look at page action
- var element = event.target
- var boundingRect = element.getBoundingClientRect()
- var coordinates = getCaretCoordinates(element, element.selectionEnd)
- this.animationEventEmitter.emit('point', {
- x: boundingRect.left + coordinates.left - element.scrollLeft,
- y: boundingRect.top + coordinates.top - element.scrollTop,
- })
+const mapDispatchToProps = dispatch => {
+ return {
+ createNewVaultAndKeychain: password => dispatch(actions.createNewVaultAndKeychain(password)),
+ markPasswordForgotten: () => dispatch(actions.markPasswordForgotten()),
+ }
}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(InitializeMenuScreen)
diff --git a/ui/app/i18n-provider.js b/ui/app/i18n-provider.js
index fe6d62c67..4ef618018 100644
--- a/ui/app/i18n-provider.js
+++ b/ui/app/i18n-provider.js
@@ -1,6 +1,8 @@
const { Component } = require('react')
const connect = require('react-redux').connect
const PropTypes = require('prop-types')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const t = require('../i18n-helper').getMessage
class I18nProvider extends Component {
@@ -32,5 +34,8 @@ const mapStateToProps = state => {
}
}
-module.exports = connect(mapStateToProps)(I18nProvider)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps)
+)(I18nProvider)
diff --git a/ui/app/keychains/hd/recover-seed/confirmation.js b/ui/app/keychains/hd/recover-seed/confirmation.js
index 02183f096..eb588415f 100644
--- a/ui/app/keychains/hd/recover-seed/confirmation.js
+++ b/ui/app/keychains/hd/recover-seed/confirmation.js
@@ -4,12 +4,21 @@ const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
const actions = require('../../../actions')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const {
+ DEFAULT_ROUTE,
+ INITIALIZE_BACKUP_PHRASE_ROUTE,
+} = require('../../../routes')
RevealSeedConfirmation.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps)(RevealSeedConfirmation)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps)
+)(RevealSeedConfirmation)
inherits(RevealSeedConfirmation, Component)
@@ -109,6 +118,8 @@ RevealSeedConfirmation.prototype.componentDidMount = function () {
RevealSeedConfirmation.prototype.goHome = function () {
this.props.dispatch(actions.showConfigPage(false))
+ this.props.dispatch(actions.confirmSeedWords())
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
}
// create vault
@@ -123,4 +134,5 @@ RevealSeedConfirmation.prototype.checkConfirmation = function (event) {
RevealSeedConfirmation.prototype.revealSeedWords = function () {
var password = document.getElementById('password-box').value
this.props.dispatch(actions.requestRevealSeed(password))
+ .then(() => this.props.history.push(INITIALIZE_BACKUP_PHRASE_ROUTE))
}
diff --git a/ui/app/main-container.js b/ui/app/main-container.js
index eed4bd164..6dd4ff151 100644
--- a/ui/app/main-container.js
+++ b/ui/app/main-container.js
@@ -2,8 +2,8 @@ const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const AccountAndTransactionDetails = require('./account-and-transaction-details')
-const Settings = require('./settings')
-const UnlockScreen = require('./unlock')
+const Settings = require('./components/pages/settings')
+const UnlockScreen = require('./components/pages/unlock')
module.exports = MainContainer
diff --git a/ui/app/root.js b/ui/app/root.js
index 21d6d1829..09deae1b1 100644
--- a/ui/app/root.js
+++ b/ui/app/root.js
@@ -1,22 +1,23 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const Provider = require('react-redux').Provider
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const { Provider } = require('react-redux')
const h = require('react-hyperscript')
const SelectedApp = require('./select-app')
-module.exports = Root
-
-inherits(Root, Component)
-function Root () { Component.call(this) }
-
-Root.prototype.render = function () {
- return (
+class Root extends Component {
+ render () {
+ const { store } = this.props
- h(Provider, {
- store: this.props.store,
- }, [
- h(SelectedApp),
- ])
+ return (
+ h(Provider, { store }, [
+ h(SelectedApp),
+ ])
+ )
+ }
+}
- )
+Root.propTypes = {
+ store: PropTypes.object,
}
+
+module.exports = Root
diff --git a/ui/app/routes.js b/ui/app/routes.js
new file mode 100644
index 000000000..4b3f8f4d8
--- /dev/null
+++ b/ui/app/routes.js
@@ -0,0 +1,49 @@
+const DEFAULT_ROUTE = '/'
+const UNLOCK_ROUTE = '/unlock'
+const SETTINGS_ROUTE = '/settings'
+const INFO_ROUTE = '/settings/info'
+const REVEAL_SEED_ROUTE = '/seed'
+const CONFIRM_SEED_ROUTE = '/confirm-seed'
+const RESTORE_VAULT_ROUTE = '/restore-vault'
+const ADD_TOKEN_ROUTE = '/add-token'
+const NEW_ACCOUNT_ROUTE = '/new-account'
+const IMPORT_ACCOUNT_ROUTE = '/new-account/import'
+const SEND_ROUTE = '/send'
+const CONFIRM_TRANSACTION_ROUTE = '/confirm-transaction'
+const SIGNATURE_REQUEST_ROUTE = '/confirm-transaction/signature-request'
+const NOTICE_ROUTE = '/notice'
+const WELCOME_ROUTE = '/welcome'
+const INITIALIZE_ROUTE = '/initialize'
+const INITIALIZE_CREATE_PASSWORD_ROUTE = '/initialize/create-password'
+const INITIALIZE_IMPORT_ACCOUNT_ROUTE = '/initialize/import-account'
+const INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE = '/initialize/import-with-seed-phrase'
+const INITIALIZE_UNIQUE_IMAGE_ROUTE = '/initialize/unique-image'
+const INITIALIZE_NOTICE_ROUTE = '/initialize/notice'
+const INITIALIZE_BACKUP_PHRASE_ROUTE = '/initialize/backup-phrase'
+const INITIALIZE_CONFIRM_SEED_ROUTE = '/initialize/confirm-phrase'
+
+module.exports = {
+ DEFAULT_ROUTE,
+ UNLOCK_ROUTE,
+ SETTINGS_ROUTE,
+ INFO_ROUTE,
+ REVEAL_SEED_ROUTE,
+ CONFIRM_SEED_ROUTE,
+ RESTORE_VAULT_ROUTE,
+ ADD_TOKEN_ROUTE,
+ NEW_ACCOUNT_ROUTE,
+ IMPORT_ACCOUNT_ROUTE,
+ SEND_ROUTE,
+ CONFIRM_TRANSACTION_ROUTE,
+ NOTICE_ROUTE,
+ SIGNATURE_REQUEST_ROUTE,
+ WELCOME_ROUTE,
+ INITIALIZE_ROUTE,
+ INITIALIZE_CREATE_PASSWORD_ROUTE,
+ INITIALIZE_IMPORT_ACCOUNT_ROUTE,
+ INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
+ INITIALIZE_UNIQUE_IMAGE_ROUTE,
+ INITIALIZE_NOTICE_ROUTE,
+ INITIALIZE_BACKUP_PHRASE_ROUTE,
+ INITIALIZE_CONFIRM_SEED_ROUTE,
+}
diff --git a/ui/app/select-app.js b/ui/app/select-app.js
index 101eb1cf6..d1565e2fb 100644
--- a/ui/app/select-app.js
+++ b/ui/app/select-app.js
@@ -2,6 +2,7 @@ const inherits = require('util').inherits
const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
+const { HashRouter } = require('react-router-dom')
const App = require('./app')
const OldApp = require('../../old-ui/app/app')
const { autoAddToBetaUI } = require('./selectors')
@@ -63,7 +64,12 @@ SelectedApp.prototype.render = function () {
// const Selected = betaUI || isMascara || firstTime ? App : OldApp
const { betaUI, isMascara } = this.props
- const Selected = betaUI || isMascara ? h(I18nProvider, [ h(App) ]) : h(OldApp)
- return Selected
+ return betaUI || isMascara
+ ? h(HashRouter, {
+ hashType: 'noslash',
+ }, [
+ h(I18nProvider, [ h(App) ]),
+ ])
+ : h(OldApp)
}
diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js
index 0f2997fb2..d0c28caa2 100644
--- a/ui/app/send-v2.js
+++ b/ui/app/send-v2.js
@@ -30,6 +30,7 @@ const {
getGasTotal,
} = require('./components/send/send-utils')
const { isValidAddress } = require('./util')
+const { CONFIRM_TRANSACTION_ROUTE, DEFAULT_ROUTE } = require('./routes')
SendTransactionScreen.contextTypes = {
t: PropTypes.func,
@@ -182,7 +183,7 @@ SendTransactionScreen.prototype.componentDidUpdate = function (prevProps) {
}
SendTransactionScreen.prototype.renderHeader = function () {
- const { selectedToken, clearSend, goHome } = this.props
+ const { selectedToken, clearSend, history } = this.props
return h('div.page-container__header', [
@@ -193,7 +194,7 @@ SendTransactionScreen.prototype.renderHeader = function () {
h('div.page-container__header-close', {
onClick: () => {
clearSend()
- goHome()
+ history.push(DEFAULT_ROUTE)
},
}),
@@ -254,7 +255,6 @@ SendTransactionScreen.prototype.handleToChange = function (to, nickname = '') {
const {
updateSendTo,
updateSendErrors,
- from: {address: from},
} = this.props
let toError = null
@@ -262,8 +262,6 @@ SendTransactionScreen.prototype.handleToChange = function (to, nickname = '') {
toError = this.context.t('required')
} else if (!isValidAddress(to)) {
toError = this.context.t('invalidAddressRecipient')
- } else if (to === from) {
- toError = this.context.t('fromToSame')
}
updateSendTo(to, nickname)
@@ -498,12 +496,12 @@ SendTransactionScreen.prototype.renderForm = function () {
SendTransactionScreen.prototype.renderFooter = function () {
const {
- goHome,
clearSend,
gasTotal,
tokenBalance,
selectedToken,
errors: { amount: amountError, to: toError },
+ history,
} = this.props
const missingTokenBalance = selectedToken && !tokenBalance
@@ -513,7 +511,7 @@ SendTransactionScreen.prototype.renderFooter = function () {
h('button.btn-secondary--lg.page-container__footer-button', {
onClick: () => {
clearSend()
- goHome()
+ history.push(DEFAULT_ROUTE)
},
}, this.context.t('cancel')),
h('button.btn-primary--lg.page-container__footer-button', {
@@ -579,12 +577,17 @@ SendTransactionScreen.prototype.getEditedTx = function () {
data,
})
} else {
- const data = unapprovedTxs[editingTransactionId].txParams.data
+ const { data } = unapprovedTxs[editingTransactionId].txParams
+
Object.assign(editingTx.txParams, {
value: ethUtil.addHexPrefix(amount),
to: ethUtil.addHexPrefix(to),
data,
})
+
+ if (typeof editingTx.txParams.data === 'undefined') {
+ delete editingTx.txParams.data
+ }
}
return editingTx
@@ -619,7 +622,6 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
if (editingTransactionId) {
const editedTx = this.getEditedTx()
-
updateTx(editedTx)
} else {
@@ -643,4 +645,6 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
? signTokenTx(selectedToken.address, to, amount, txParams)
: signTx(txParams)
}
+
+ this.props.history.push(CONFIRM_TRANSACTION_ROUTE)
}
diff --git a/ui/app/util.js b/ui/app/util.js
index 800ccb218..bbe2bb09e 100644
--- a/ui/app/util.js
+++ b/ui/app/util.js
@@ -271,6 +271,7 @@ function exportAsFile (filename, data) {
window.navigator.msSaveBlob(blob, filename)
} else {
const elem = window.document.createElement('a')
+ elem.target = '_blank'
elem.href = window.URL.createObjectURL(blob)
elem.download = filename
document.body.appendChild(elem)
diff --git a/ui/app/welcome-screen.js b/ui/app/welcome-screen.js
index cdbb6dba8..2fa244d9f 100644
--- a/ui/app/welcome-screen.js
+++ b/ui/app/welcome-screen.js
@@ -3,21 +3,35 @@ import h from 'react-hyperscript'
import { Component } from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'recompose'
import {closeWelcomeScreen} from './actions'
import Mascot from './components/mascot'
+import { INITIALIZE_CREATE_PASSWORD_ROUTE } from './routes'
class WelcomeScreen extends Component {
static propTypes = {
closeWelcomeScreen: PropTypes.func.isRequired,
+ welcomeScreenSeen: PropTypes.bool,
+ history: PropTypes.object,
}
- constructor(props) {
+ constructor (props) {
super(props)
this.animationEventEmitter = new EventEmitter()
}
+ componentWillMount () {
+ const { history, welcomeScreenSeen } = this.props
+
+ if (welcomeScreenSeen) {
+ history.push(INITIALIZE_CREATE_PASSWORD_ROUTE)
+ }
+ }
+
initiateAccountCreation = () => {
this.props.closeWelcomeScreen()
+ this.props.history.push(INITIALIZE_CREATE_PASSWORD_ROUTE)
}
render () {
@@ -48,9 +62,18 @@ class WelcomeScreen extends Component {
}
}
-export default connect(
- null,
- dispatch => ({
- closeWelcomeScreen: () => dispatch(closeWelcomeScreen()),
- })
+const mapStateToProps = ({ metamask: { welcomeScreenSeen } }) => {
+ return {
+ welcomeScreenSeen,
+ }
+}
+
+export default compose(
+ withRouter,
+ connect(
+ mapStateToProps,
+ dispatch => ({
+ closeWelcomeScreen: () => dispatch(closeWelcomeScreen()),
+ })
+ )
)(WelcomeScreen)
diff --git a/yarn.lock b/yarn.lock
index cda23f3c3..5fad03a2d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,54 +2,53 @@
# yarn lockfile v1
-"@babel/code-frame@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.31.tgz#473d021ecc573a2cce1c07d5b509d5215f46ba35"
+"@babel/code-frame@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.36.tgz#2349d7ec04b3a06945ae173280ef8579b63728e4"
dependencies:
chalk "^2.0.0"
esutils "^2.0.2"
js-tokens "^3.0.0"
-"@babel/helper-function-name@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.31.tgz#afe63ad799209989348b1109b44feb66aa245f57"
+"@babel/helper-function-name@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.36.tgz#366e3bc35147721b69009f803907c4d53212e88d"
dependencies:
- "@babel/helper-get-function-arity" "7.0.0-beta.31"
- "@babel/template" "7.0.0-beta.31"
- "@babel/traverse" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
+ "@babel/helper-get-function-arity" "7.0.0-beta.36"
+ "@babel/template" "7.0.0-beta.36"
+ "@babel/types" "7.0.0-beta.36"
-"@babel/helper-get-function-arity@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.31.tgz#1176d79252741218e0aec872ada07efb2b37a493"
+"@babel/helper-get-function-arity@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.36.tgz#f5383bac9a96b274828b10d98900e84ee43e32b8"
dependencies:
- "@babel/types" "7.0.0-beta.31"
+ "@babel/types" "7.0.0-beta.36"
-"@babel/template@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.31.tgz#577bb29389f6c497c3e7d014617e7d6713f68bda"
+"@babel/template@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.36.tgz#02e903de5d68bd7899bce3c5b5447e59529abb00"
dependencies:
- "@babel/code-frame" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
- babylon "7.0.0-beta.31"
+ "@babel/code-frame" "7.0.0-beta.36"
+ "@babel/types" "7.0.0-beta.36"
+ babylon "7.0.0-beta.36"
lodash "^4.2.0"
-"@babel/traverse@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.31.tgz#db399499ad74aefda014f0c10321ab255134b1df"
+"@babel/traverse@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.36.tgz#1dc6f8750e89b6b979de5fe44aa993b1a2192261"
dependencies:
- "@babel/code-frame" "7.0.0-beta.31"
- "@babel/helper-function-name" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
- babylon "7.0.0-beta.31"
+ "@babel/code-frame" "7.0.0-beta.36"
+ "@babel/helper-function-name" "7.0.0-beta.36"
+ "@babel/types" "7.0.0-beta.36"
+ babylon "7.0.0-beta.36"
debug "^3.0.1"
- globals "^10.0.0"
+ globals "^11.1.0"
invariant "^2.2.0"
lodash "^4.2.0"
-"@babel/types@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.31.tgz#42c9c86784f674c173fb21882ca9643334029de4"
+"@babel/types@7.0.0-beta.36":
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.36.tgz#64f2004353de42adb72f9ebb4665fc35b5499d23"
dependencies:
esutils "^2.0.2"
lodash "^4.2.0"
@@ -81,9 +80,13 @@
progress "2.0.0"
proxy-from-env "^1.0.0"
+"@sindresorhus/is@^0.7.0":
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
+
"@types/node@*":
- version "8.5.2"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.2.tgz#83b8103fa9a2c2e83d78f701a9aa7c9539739aa5"
+ version "8.0.53"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8"
JSONStream@^0.8.4:
version "0.8.4"
@@ -268,6 +271,16 @@ ansi-colors@^1.0.1:
dependencies:
ansi-wrap "^0.1.0"
+ansi-cyan@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873"
+ dependencies:
+ ansi-wrap "0.1.0"
+
+ansi-escapes@^1.0.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
+
ansi-escapes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92"
@@ -278,6 +291,12 @@ ansi-gray@^0.1.1:
dependencies:
ansi-wrap "0.1.0"
+ansi-red@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c"
+ dependencies:
+ ansi-wrap "0.1.0"
+
ansi-regex@^0.2.0, ansi-regex@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9"
@@ -310,6 +329,10 @@ ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
+ansi-styles@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
+
ansi-wrap@0.1.0, ansi-wrap@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
@@ -318,6 +341,10 @@ ansicolors@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979"
+any-observable@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242"
+
any-promise@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-0.1.0.tgz#830b680aa7e56f33451d4b049f3bd8044498ee27"
@@ -373,6 +400,13 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
+arr-diff@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a"
+ dependencies:
+ arr-flatten "^1.0.1"
+ array-slice "^0.2.3"
+
arr-diff@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
@@ -399,6 +433,10 @@ arr-map@^2.0.0, arr-map@^2.0.2:
dependencies:
make-iterator "^1.0.0"
+arr-union@^2.0.1:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d"
+
arr-union@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
@@ -536,13 +574,21 @@ assert@^1.1.1, assert@^1.4.0:
util "0.10.3"
assertion-error@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
assign-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
+ast-types@0.10.1:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.10.1.tgz#f52fca9715579a14f841d67d7f8d25432ab6a3dd"
+
+ast-types@0.11.3:
+ version "0.11.3"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.3.tgz#c20757fe72ee71278ea0ff3d87e5c2ca30d9edf8"
+
ast-types@0.9.6:
version "0.9.6"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9"
@@ -558,8 +604,8 @@ astw@^2.0.0:
acorn "^4.0.3"
async-done@^1.2.0, async-done@^1.2.2:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.2.3.tgz#6c7abc7d61ca27fe6f1f2ba3206ea9ae60a43983"
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.2.4.tgz#17b0fcefb9a33cb9de63daa8904c0a65bd535fa0"
dependencies:
end-of-stream "^1.1.0"
once "^1.3.2"
@@ -600,11 +646,52 @@ async-settle@^1.0.0:
dependencies:
async-done "^1.2.2"
-async@^1.4.0, async@^1.4.2:
+async.queue@^0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.queue/-/async.queue-0.5.2.tgz#8d5d90812e1481066bc0904e8cc1712b17c3bd7c"
+ dependencies:
+ async.util.queue "0.5.2"
+
+async.util.arrayeach@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.arrayeach/-/async.util.arrayeach-0.5.2.tgz#58c4e98028d55d69bfb05aeb3af44e0a555a829c"
+
+async.util.isarray@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.isarray/-/async.util.isarray-0.5.2.tgz#e62dac8f2636f65875dcf7521c2d24d0dfb2bbdf"
+
+async.util.map@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.map/-/async.util.map-0.5.2.tgz#e588ef86e0b3ab5f027d97af4d6835d055ca69d6"
+
+async.util.noop@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.noop/-/async.util.noop-0.5.2.tgz#bdd62b97cb0aa3f60b586ad148468698975e58b9"
+
+async.util.onlyonce@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz#b8e6fc004adc923164d79e32f2813ee465c24ff2"
+
+async.util.queue@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.queue/-/async.util.queue-0.5.2.tgz#57f65abe1a3cdf273d31abd28ab95425f8222ee5"
+ dependencies:
+ async.util.arrayeach "0.5.2"
+ async.util.isarray "0.5.2"
+ async.util.map "0.5.2"
+ async.util.noop "0.5.2"
+ async.util.onlyonce "0.5.2"
+ async.util.setimmediate "0.5.2"
+
+async.util.setimmediate@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.setimmediate/-/async.util.setimmediate-0.5.2.tgz#2812ebabf2a58027758d4bc7793d1ccfaf10255f"
+
+async@^1.4.0, async@^1.4.2, async@^1.5.0:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
-async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0:
+async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
dependencies:
@@ -717,13 +804,13 @@ babel-core@^6.0.14, babel-core@^6.23.1, babel-core@^6.24.1, babel-core@^6.26.0:
source-map "^0.5.6"
babel-eslint@^8.0.0:
- version "8.1.2"
- resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.1.2.tgz#a39230b0c20ecbaa19a35d5633bf9b9ca2c8116f"
+ version "8.2.1"
+ resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.1.tgz#136888f3c109edc65376c23ebf494f36a3e03951"
dependencies:
- "@babel/code-frame" "7.0.0-beta.31"
- "@babel/traverse" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
- babylon "7.0.0-beta.31"
+ "@babel/code-frame" "7.0.0-beta.36"
+ "@babel/traverse" "7.0.0-beta.36"
+ "@babel/types" "7.0.0-beta.36"
+ babylon "7.0.0-beta.36"
eslint-scope "~3.7.1"
eslint-visitor-keys "^1.0.0"
@@ -1180,7 +1267,7 @@ babel-plugin-transform-export-extensions@^6.22.0:
babel-plugin-syntax-export-extensions "^6.8.0"
babel-runtime "^6.22.0"
-babel-plugin-transform-flow-strip-types@^6.22.0:
+babel-plugin-transform-flow-strip-types@^6.22.0, babel-plugin-transform-flow-strip-types@^6.8.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf"
dependencies:
@@ -1291,7 +1378,7 @@ babel-preset-env@^1.3.2:
invariant "^2.2.2"
semver "^5.3.0"
-babel-preset-es2015@^6.22.0, babel-preset-es2015@^6.24.0, babel-preset-es2015@^6.6.0:
+babel-preset-es2015@^6.22.0, babel-preset-es2015@^6.6.0, babel-preset-es2015@^6.9.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939"
dependencies:
@@ -1345,7 +1432,7 @@ babel-preset-stage-0@^6.24.1:
babel-plugin-transform-function-bind "^6.22.0"
babel-preset-stage-1 "^6.24.1"
-babel-preset-stage-1@^6.24.1:
+babel-preset-stage-1@^6.24.1, babel-preset-stage-1@^6.5.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0"
dependencies:
@@ -1372,7 +1459,7 @@ babel-preset-stage-3@^6.24.1:
babel-plugin-transform-exponentiation-operator "^6.24.1"
babel-plugin-transform-object-rest-spread "^6.22.0"
-babel-register@^6.26.0, babel-register@^6.7.2:
+babel-register@^6.26.0, babel-register@^6.7.2, babel-register@^6.9.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
dependencies:
@@ -1435,14 +1522,18 @@ babelify@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/babelify/-/babelify-8.0.0.tgz#6f60f5f062bfe7695754ef2403b842014a580ed3"
-babylon@7.0.0-beta.31:
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.31.tgz#7ec10f81e0e456fd0f855ad60fa30c2ac454283f"
+babylon@7.0.0-beta.36:
+ version "7.0.0-beta.36"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.36.tgz#3a3683ba6a9a1e02b0aa507c8e63435e39305b9e"
-babylon@^6.18.0:
+babylon@^6.17.3, babylon@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
+babylon@^7.0.0-beta.30:
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d"
+
bach@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880"
@@ -1574,6 +1665,10 @@ binary-extensions@^1.0.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
+binaryextensions@2:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935"
+
binaryextensions@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-1.0.1.tgz#1e637488b35b58bda5f4774bf96a5212a8c90755"
@@ -1583,8 +1678,8 @@ bindings@^1.2.1:
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7"
bip39@^2.2.0, bip39@^2.4.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.4.0.tgz#a0b8adbf163f53495f00f05d9ede7c25369ccf13"
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235"
dependencies:
create-hash "^1.1.0"
pbkdf2 "^3.0.9"
@@ -1696,6 +1791,13 @@ boron@^0.2.3:
dependencies:
domkit "^0.0.1"
+brace-expansion@^1.0.0:
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
+ dependencies:
+ balanced-match "^1.0.0"
+ concat-map "0.0.1"
+
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
@@ -1774,12 +1876,13 @@ browser-pack@^5.0.1:
umd "^3.0.0"
browser-pack@^6.0.1:
- version "6.0.2"
- resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.0.2.tgz#f86cd6cef4f5300c8e63e07a4d512f65fbff4531"
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.0.3.tgz#91ca96518583ef580ab063a309de62e407767a39"
dependencies:
JSONStream "^1.0.3"
- combine-source-map "~0.7.1"
+ combine-source-map "~0.8.0"
defined "^1.0.0"
+ safe-buffer "^5.1.1"
through2 "^2.0.0"
umd "^3.0.0"
@@ -1881,7 +1984,7 @@ browserify-zlib@^0.2.0, browserify-zlib@~0.2.0:
dependencies:
pako "~1.0.5"
-browserify@^14.0.0, browserify@^14.5.0:
+browserify@^14.5.0:
version "14.5.0"
resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5"
dependencies:
@@ -1933,6 +2036,59 @@ browserify@^14.0.0, browserify@^14.5.0:
vm-browserify "~0.0.1"
xtend "^4.0.0"
+browserify@^15.2.0:
+ version "15.2.0"
+ resolved "https://registry.yarnpkg.com/browserify/-/browserify-15.2.0.tgz#1e121ba1fa72cf9fd2d8df002f8674b68b45df89"
+ dependencies:
+ JSONStream "^1.0.3"
+ assert "^1.4.0"
+ browser-pack "^6.0.1"
+ browser-resolve "^1.11.0"
+ browserify-zlib "~0.2.0"
+ buffer "^5.0.2"
+ cached-path-relative "^1.0.0"
+ concat-stream "~1.5.1"
+ console-browserify "^1.1.0"
+ constants-browserify "~1.0.0"
+ crypto-browserify "^3.0.0"
+ defined "^1.0.0"
+ deps-sort "^2.0.0"
+ domain-browser "~1.1.0"
+ duplexer2 "~0.1.2"
+ events "~1.1.0"
+ glob "^7.1.0"
+ has "^1.0.0"
+ htmlescape "^1.1.0"
+ https-browserify "^1.0.0"
+ inherits "~2.0.1"
+ insert-module-globals "^7.0.0"
+ labeled-stream-splicer "^2.0.0"
+ mkdirp "^0.5.0"
+ module-deps "^5.0.1"
+ os-browserify "~0.3.0"
+ parents "^1.0.1"
+ path-browserify "~0.0.0"
+ process "~0.11.0"
+ punycode "^1.3.2"
+ querystring-es3 "~0.2.0"
+ read-only-stream "^2.0.0"
+ readable-stream "^2.0.2"
+ resolve "^1.1.4"
+ shasum "^1.0.0"
+ shell-quote "^1.6.1"
+ stream-browserify "^2.0.0"
+ stream-http "^2.0.0"
+ string_decoder "~1.0.0"
+ subarg "^1.0.0"
+ syntax-error "^1.1.1"
+ through2 "^2.0.0"
+ timers-browserify "^1.0.1"
+ tty-browserify "~0.0.0"
+ url "~0.11.0"
+ util "~0.10.1"
+ vm-browserify "~0.0.1"
+ xtend "^4.0.0"
+
browserify@^16.1.1:
version "16.1.1"
resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.1.1.tgz#7905ec07e0147c4d90f92001944050a6e1c2844e"
@@ -2109,6 +2265,18 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
+cacheable-request@^2.1.1:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d"
+ dependencies:
+ clone-response "1.0.2"
+ get-stream "3.0.0"
+ http-cache-semantics "3.8.1"
+ keyv "3.0.0"
+ lowercase-keys "1.0.0"
+ normalize-url "2.0.1"
+ responselike "1.0.2"
+
cached-path-relative@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.1.tgz#d09c4b52800aa4c078e2dd81a869aac90d2e54e7"
@@ -2159,12 +2327,12 @@ camelcase@^4.1.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
caniuse-db@^1.0.30000187, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
- version "1.0.30000784"
- resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000784.tgz#1be95012d9489c7719074f81aee57dbdffe6361b"
+ version "1.0.30000798"
+ resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000798.tgz#92f26f77f89cc2a4d60487f41e0b3d2a6c3fe341"
caniuse-lite@^1.0.30000780:
- version "1.0.30000784"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz#129ced74e9a1280a441880b6cd2bce30ef59e6c0"
+ version "1.0.30000821"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000821.tgz#0f3223f1e048ed96451c56ca6cf197058c42cb93"
caniuse-lite@^1.0.30000810, caniuse-lite@^1.0.30000813:
version "1.0.30000814"
@@ -2236,7 +2404,7 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
escape-string-regexp "^1.0.5"
supports-color "^4.0.0"
-chalk@^2.3.1:
+chalk@^2.3.1, chalk@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65"
dependencies:
@@ -2244,6 +2412,14 @@ chalk@^2.3.1:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
+chalk@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
+ dependencies:
+ ansi-styles "~1.0.0"
+ has-color "~0.1.0"
+ strip-ansi "~0.1.0"
+
change-emitter@^0.1.2:
version "0.1.6"
resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515"
@@ -2365,29 +2541,58 @@ circular-json@^0.5.1:
resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.1.tgz#b8942a09e535863dc21b04417a91971e1d9cd91f"
class-utils@^0.3.5:
- version "0.3.5"
- resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.5.tgz#17e793103750f9627b2176ea34cfd1b565903c80"
+ version "0.3.6"
+ resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
dependencies:
arr-union "^3.1.0"
define-property "^0.2.5"
isobject "^3.0.0"
- lazy-cache "^2.0.2"
static-extend "^0.1.1"
classnames@^2.2.4, classnames@^2.2.5:
version "2.2.5"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
+cli-cursor@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
+ dependencies:
+ restore-cursor "^1.0.1"
+
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
dependencies:
restore-cursor "^2.0.0"
+cli-spinners@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
+
+cli-table@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23"
+ dependencies:
+ colors "1.0.3"
+
+cli-truncate@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
+ dependencies:
+ slice-ansi "0.0.4"
+ string-width "^1.0.1"
+
cli-width@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
+cli@~1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.1.tgz#22817534f24bfa4950c34d532d48ecbc621b8c14"
+ dependencies:
+ exit "0.1.2"
+ glob "^7.1.1"
+
cliui@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
@@ -2404,6 +2609,14 @@ cliui@^3.0.3, cliui@^3.2.0:
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
+cliui@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc"
+ dependencies:
+ string-width "^2.1.1"
+ strip-ansi "^4.0.0"
+ wrap-ansi "^2.0.0"
+
clone-buffer@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
@@ -2415,6 +2628,12 @@ clone-regexp@^1.0.0:
is-regexp "^1.0.0"
is-supported-regexp-flag "^1.0.0"
+clone-response@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
+ dependencies:
+ mimic-response "^1.0.0"
+
clone-stats@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1"
@@ -2528,7 +2747,7 @@ colors@0.5.x:
version "0.5.1"
resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774"
-colors@1.0.x:
+colors@1.0.3, colors@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
@@ -2560,6 +2779,15 @@ combine-source-map@~0.7.1:
lodash.memoize "~3.0.3"
source-map "~0.5.3"
+combine-source-map@~0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.8.0.tgz#a58d0df042c186fcf822a8e8015f5450d2d79a8b"
+ dependencies:
+ convert-source-map "~1.1.0"
+ inline-source-map "~0.6.0"
+ lodash.memoize "~3.0.3"
+ source-map "~0.5.3"
+
combined-stream@^1.0.5, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
@@ -2576,14 +2804,14 @@ commander@2.9.0:
dependencies:
graceful-readlink ">= 1.0.0"
-commander@^2.5.0, commander@^2.6.0, commander@^2.9.0, commander@~2.12.1:
- version "2.12.2"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
-
-commander@~2.13.0:
+commander@^2.5.0, commander@^2.6.0, commander@^2.9.0, commander@~2.13.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
+commander@~2.12.1:
+ version "2.12.2"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
+
commander@~2.14.1:
version "2.14.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
@@ -2680,7 +2908,7 @@ connect@^3.6.0:
parseurl "~1.3.2"
utils-merge "1.0.1"
-console-browserify@^1.1.0:
+console-browserify@1.1.x, console-browserify@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
dependencies:
@@ -2753,6 +2981,10 @@ core-js@^2.2.0, core-js@^2.4.0, core-js@^2.5.0:
version "2.5.3"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
+core-js@^2.4.1:
+ version "2.5.4"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.4.tgz#f2c8bf181f2a80b92f360121429ce63a2f0aeae0"
+
core-js@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65"
@@ -2847,6 +3079,16 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0:
shebang-command "^1.2.0"
which "^1.2.9"
+cross-spawn@^6.0.5:
+ version "6.0.5"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
+ dependencies:
+ nice-try "^1.0.4"
+ path-key "^2.0.1"
+ semver "^5.5.0"
+ shebang-command "^1.2.0"
+ which "^1.2.9"
+
cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
@@ -2971,6 +3213,10 @@ d@1:
dependencies:
es5-ext "^0.10.9"
+dargs@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/dargs/-/dargs-5.1.0.tgz#ec7ea50c78564cd36c9d5ec18f66329fade27829"
+
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@@ -2981,6 +3227,10 @@ data-uri-to-buffer@1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835"
+date-fns@^1.27.2:
+ version "1.29.0"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6"
+
date-format@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/date-format/-/date-format-1.2.0.tgz#615e828e233dd1ab9bb9ae0950e0ceccfa6ecad8"
@@ -2993,6 +3243,10 @@ dateformat@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062"
+dateformat@^3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
+
debounce-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/debounce-stream/-/debounce-stream-2.0.0.tgz#1e33400ccff015abd8ec330661a562b68410b08f"
@@ -3049,6 +3303,12 @@ decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
+decompress-response@^3.2.0, decompress-response@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
+ dependencies:
+ mimic-response "^1.0.0"
+
deep-diff@^0.3.5:
version "0.3.8"
resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84"
@@ -3073,14 +3333,14 @@ deep-equal@~0.2.1:
version "0.2.2"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d"
+deep-extend@^0.4.0, deep-extend@~0.4.0:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
+
deep-extend@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.0.tgz#6ef4a09b05f98b0e358d6d93d4ca3caec6672803"
-deep-extend@~0.4.0:
- version "0.4.2"
- resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
-
deep-freeze-strict@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/deep-freeze-strict/-/deep-freeze-strict-1.1.1.tgz#77d0583ca24a69be4bbd9ac2fae415d55523e5b0"
@@ -3184,10 +3444,14 @@ delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
-depd@1.1.1, depd@~1.1.0, depd@~1.1.1:
+depd@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
+depd@~1.1.0, depd@~1.1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
+
deps-sort@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/deps-sort/-/deps-sort-2.0.0.tgz#091724902e84658260eb910748cccd1af6e21fb5"
@@ -3218,6 +3482,10 @@ destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
+detect-conflict@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e"
+
detect-file@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63"
@@ -3281,6 +3549,10 @@ diff@^3.1.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c"
+diff@^3.3.1, diff@^3.5.0:
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
+
diffie-hellman@^5.0.0:
version "5.0.2"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e"
@@ -3328,9 +3600,9 @@ dnode@^1.2.2:
optionalDependencies:
weak "^1.0.0"
-doctrine@^2.0.0, doctrine@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075"
+doctrine@^2.0.2, doctrine@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
dependencies:
esutils "^2.0.2"
@@ -3375,14 +3647,14 @@ dom-walk@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
-domain-browser@^1.1.1, domain-browser@~1.1.0:
- version "1.1.7"
- resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
-
-domain-browser@^1.2.0:
+domain-browser@^1.1.1, domain-browser@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
+domain-browser@~1.1.0:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
+
domelementtype@1, domelementtype@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
@@ -3392,8 +3664,16 @@ domelementtype@~1.1.1:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
domexception@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.0.tgz#81fe5df81b3f057052cde3a9fa9bf536a85b9ab0"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
+ dependencies:
+ webidl-conversions "^4.0.2"
+
+domhandler@2.3:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738"
+ dependencies:
+ domelementtype "1"
domhandler@^2.3.0:
version "2.4.1"
@@ -3405,7 +3685,7 @@ domkit@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/domkit/-/domkit-0.0.1.tgz#88399d586794efc1154fec6c22cfe50f19bd4dbb"
-domutils@1.5.1:
+domutils@1.5, domutils@1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
dependencies:
@@ -3443,6 +3723,10 @@ duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2:
dependencies:
readable-stream "^2.0.2"
+duplexer3@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
+
duplexer@^0.1.1, duplexer@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
@@ -3469,6 +3753,10 @@ ecc-jsbn@~0.1.1:
dependencies:
jsbn "~0.1.0"
+editions@^1.3.3:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b"
+
editorconfig@^0.13.2:
version "0.13.3"
resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.13.3.tgz#e5219e587951d60958fd94ea9a9a008cdeff1b34"
@@ -3483,20 +3771,26 @@ ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
-electron-releases@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/electron-releases/-/electron-releases-2.1.0.tgz#c5614bf811f176ce3c836e368a0625782341fd4e"
+ejs@^2.3.1:
+ version "2.5.8"
+ resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.8.tgz#2ab6954619f225e6193b7ac5f7c39c48fefe4380"
-electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.28:
- version "1.3.30"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz#9666f532a64586651fc56a72513692e820d06a80"
- dependencies:
- electron-releases "^2.1.0"
+electron-to-chromium@^1.2.7:
+ version "1.3.31"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.31.tgz#00d832cba9fe2358652b0c48a8816c8e3a037e9f"
+
+electron-to-chromium@^1.3.28:
+ version "1.3.41"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.41.tgz#7e33643e00cd85edfd17e04194f6d00e73737235"
electron-to-chromium@^1.3.36:
version "1.3.37"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.37.tgz#4a92734e0044c8cf0b1553be57eae21a4c6e5fab"
+elegant-spinner@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
+
elliptic@^6.0.0, elliptic@^6.2.3:
version "6.4.0"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df"
@@ -3514,8 +3808,8 @@ emojis-list@^2.0.0:
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
encodeurl@~1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
encoding@^0.1.11:
version "0.1.12"
@@ -3524,8 +3818,8 @@ encoding@^0.1.11:
iconv-lite "~0.4.13"
end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206"
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
dependencies:
once "^1.4.0"
@@ -3616,6 +3910,14 @@ enhanced-resolve@^3.3.0:
object-assign "^4.0.1"
tapable "^0.2.7"
+enhanced-resolve@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a"
+ dependencies:
+ graceful-fs "^4.1.2"
+ memory-fs "^0.4.0"
+ tapable "^1.0.0"
+
ensnare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ensnare/-/ensnare-1.0.0.tgz#72d2bf7ef48aba21f66adf29d00a0904eddb61c7"
@@ -3630,6 +3932,10 @@ ent@~2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
+entities@1.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26"
+
entities@^1.1.1, entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
@@ -3652,12 +3958,12 @@ enzyme-adapter-react-15@^1.0.5:
prop-types "^15.5.10"
enzyme-adapter-utils@^1.1.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.3.0.tgz#d6c85756826c257a8544d362cc7a67e97ea698c7"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.2.0.tgz#7f4471ee0a70b91169ec8860d2bf0a6b551664b2"
dependencies:
lodash "^4.17.4"
object.assign "^4.0.4"
- prop-types "^15.6.0"
+ prop-types "^15.5.10"
enzyme@^3.3.0:
version "3.3.0"
@@ -3686,12 +3992,19 @@ errno@^0.1.3, errno@~0.1.1:
dependencies:
prr "~1.0.1"
-error-ex@^1.2.0:
+error-ex@^1.2.0, error-ex@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
dependencies:
is-arrayish "^0.2.1"
+error@^7.0.2:
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02"
+ dependencies:
+ string-template "~0.2.1"
+ xtend "~4.0.0"
+
es-abstract@^1.5.0, es-abstract@^1.6.1, es-abstract@^1.7.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
@@ -3711,13 +4024,13 @@ es-to-primitive@^1.1.1:
is-symbol "^1.0.1"
es5-ext@^0.10.14, es5-ext@^0.10.30, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2:
- version "0.10.37"
- resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.37.tgz#0ee741d148b80069ba27d020393756af257defc3"
+ version "0.10.38"
+ resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.38.tgz#fa7d40d65bbc9bb8a67e1d3f9cc656a00530eed3"
dependencies:
- es6-iterator "~2.0.1"
+ es6-iterator "~2.0.3"
es6-symbol "~3.1.1"
-es6-iterator@^2.0.1, es6-iterator@~2.0.1:
+es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
dependencies:
@@ -3838,6 +4151,12 @@ eslint-plugin-chai@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-chai/-/eslint-plugin-chai-0.0.1.tgz#9a1dea58b335c31242219d059b37ffb14309f6e1"
+eslint-plugin-json@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-json/-/eslint-plugin-json-1.2.0.tgz#9ba73bb0be99d50093e889f5b968463d2a30efae"
+ dependencies:
+ jshint "^2.8.0"
+
eslint-plugin-mocha@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-5.0.0.tgz#43946a7ecaf39039eb3ee20635ebd4cc19baf6dd"
@@ -3845,12 +4164,12 @@ eslint-plugin-mocha@^5.0.0:
ramda "^0.25.0"
eslint-plugin-react@^7.4.0:
- version "7.5.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz#52e56e8d80c810de158859ef07b880d2f56ee30b"
+ version "7.6.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.6.1.tgz#5d0e908be599f0c02fbf4eef0c7ed6f29dff7633"
dependencies:
- doctrine "^2.0.0"
+ doctrine "^2.0.2"
has "^1.0.1"
- jsx-ast-utils "^2.0.0"
+ jsx-ast-utils "^2.0.1"
prop-types "^15.6.0"
eslint-scope@^3.7.1, eslint-scope@~3.7.1:
@@ -3865,8 +4184,8 @@ eslint-visitor-keys@^1.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
eslint@^4.0.0, eslint@^4.2.0:
- version "4.14.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.14.0.tgz#96609768d1dd23304faba2d94b7fefe5a5447a82"
+ version "4.16.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.16.0.tgz#934ada9e98715e1d7bbfd6f6f0519ed2fab35cc1"
dependencies:
ajv "^5.3.0"
babel-code-frame "^6.22.0"
@@ -3874,7 +4193,7 @@ eslint@^4.0.0, eslint@^4.2.0:
concat-stream "^1.6.0"
cross-spawn "^5.1.0"
debug "^3.1.0"
- doctrine "^2.0.2"
+ doctrine "^2.1.0"
eslint-scope "^3.7.1"
eslint-visitor-keys "^1.0.0"
espree "^3.5.2"
@@ -3921,7 +4240,7 @@ esprima@3.x.x, esprima@^3.1.3, esprima@~3.1.0:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
-esprima@^4.0.0:
+esprima@^4.0.0, esprima@~4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
@@ -4013,8 +4332,8 @@ eth-block-tracker@^2.3.0:
tape "^4.6.3"
eth-contract-metadata@^1.1.5:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.3.0.tgz#caf3cdc3d69995b6d7532c9d96fedbad46361ca8"
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.5.0.tgz#97fbbfe588b66b55f2830dae0fa0ccdb40280128"
eth-ens-namehash@^1.0.2:
version "1.0.2"
@@ -4023,17 +4342,7 @@ eth-ens-namehash@^1.0.2:
idna-uts46 "^1.0.1"
js-sha3 "^0.5.7"
-eth-hd-keyring@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/eth-hd-keyring/-/eth-hd-keyring-1.2.1.tgz#15ab3919b4153a8497e14673e8e8039e5965131c"
- dependencies:
- bip39 "^2.2.0"
- eth-sig-util "^1.3.0"
- ethereumjs-util "^5.1.1"
- ethereumjs-wallet "^0.6.0"
- events "^1.1.1"
-
-eth-hd-keyring@^1.2.2:
+eth-hd-keyring@^1.2.1, eth-hd-keyring@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/eth-hd-keyring/-/eth-hd-keyring-1.2.2.tgz#ad5f479074436a93b439b0b95c79095c28791882"
dependencies:
@@ -4063,8 +4372,8 @@ eth-json-rpc-infura@^3.0.0:
tape "^4.8.0"
eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7, eth-json-rpc-middleware@^1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.5.0.tgz#16b1053386aa3803b125732aa6de07eadf068729"
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.5.2.tgz#14cb0af1e9910c24dd063beabbbb7142d39d9bb9"
dependencies:
async "^2.5.0"
eth-query "^2.1.2"
@@ -4074,6 +4383,7 @@ eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7, eth-json-rpc-mid
ethereumjs-util "^5.1.2"
ethereumjs-vm "^2.1.0"
fetch-ponyfill "^4.0.0"
+ json-rpc-engine "^3.6.0"
json-rpc-error "^2.0.0"
json-stable-stringify "^1.0.1"
promise-to-callback "^1.0.0"
@@ -4107,14 +4417,7 @@ eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2:
json-rpc-random-id "^1.0.0"
xtend "^4.0.1"
-eth-sig-util@^1.3.0, eth-sig-util@^1.4.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.1.tgz#dfcde3cbd03c38d429ad8695938a2678ec56f1ae"
- dependencies:
- ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git"
- ethereumjs-util "^5.1.1"
-
-eth-sig-util@^1.4.2:
+eth-sig-util@^1.3.0, eth-sig-util@^1.4.0, eth-sig-util@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210"
dependencies:
@@ -4212,20 +4515,7 @@ ethereumjs-util@4.5.0, ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumj
rlp "^2.0.0"
secp256k1 "^3.0.1"
-ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.2.tgz#25ba0215cbb4c2f0b108a6f96af2a2e62e45921f"
- dependencies:
- babel-preset-es2015 "^6.24.0"
- babelify "^7.3.0"
- bn.js "^4.8.0"
- create-hash "^1.1.2"
- ethjs-util "^0.1.3"
- keccak "^1.0.2"
- rlp "^2.0.0"
- secp256k1 "^3.0.1"
-
-ethereumjs-util@^5.1.3:
+ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.3.tgz#0c1f6efb1da9c5b6720a65697859fc0be6672df0"
dependencies:
@@ -4436,7 +4726,7 @@ event-emitter@^0.3.5, event-emitter@~0.3.5:
d "1"
es5-ext "~0.10.14"
-event-stream@^3.1.7:
+event-stream@^3.1.7, event-stream@~3.3.0:
version "3.3.4"
resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
dependencies:
@@ -4505,6 +4795,14 @@ exists-stat@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/exists-stat/-/exists-stat-1.0.0.tgz#0660e3525a2e89d9e446129440c272edfa24b529"
+exit-hook@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
+
+exit@0.1.2, exit@0.1.x:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
+
expand-braces@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea"
@@ -4591,6 +4889,12 @@ express@^4.10.7, express@^4.15.5:
utils-merge "1.0.1"
vary "~1.1.2"
+extend-shallow@^1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071"
+ dependencies:
+ kind-of "^1.1.0"
+
extend-shallow@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
@@ -4630,26 +4934,21 @@ external-editor@^2.0.4:
iconv-lite "^0.4.17"
tmp "^0.0.33"
+external-editor@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
+ dependencies:
+ chardet "^0.4.0"
+ iconv-lite "^0.4.17"
+ tmp "^0.0.33"
+
extglob@^0.3.1:
version "0.3.2"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
dependencies:
is-extglob "^1.0.0"
-extglob@^2.0.2:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.3.tgz#55e019d0c95bf873949c737b7e5172dba84ebb29"
- dependencies:
- array-unique "^0.3.2"
- define-property "^1.0.0"
- expand-brackets "^2.1.4"
- extend-shallow "^2.0.1"
- fragment-cache "^0.2.1"
- regex-not "^1.0.0"
- snapdragon "^0.8.1"
- to-regex "^3.0.1"
-
-extglob@^2.0.4:
+extglob@^2.0.2, extglob@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
dependencies:
@@ -4754,6 +5053,13 @@ fetch-ponyfill@^4.0.0:
dependencies:
node-fetch "~1.7.1"
+figures@^1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
+ dependencies:
+ escape-string-regexp "^1.0.5"
+ object-assign "^4.1.0"
+
figures@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
@@ -4840,6 +5146,10 @@ find-global-packages@0.0.1:
dependencies:
which "^1.0.5"
+find-index@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4"
+
find-up@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
@@ -4847,7 +5157,7 @@ find-up@^1.0.0:
path-exists "^2.0.0"
pinkie-promise "^2.0.0"
-find-up@^2.1.0:
+find-up@^2.0.0, find-up@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
dependencies:
@@ -4922,7 +5232,11 @@ flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
-flush-write-stream@^1.0.0, flush-write-stream@^1.0.2:
+flow-parser@^0.*:
+ version "0.69.0"
+ resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.69.0.tgz#378b5128d6d0b554a8b2f16a4ca3e1ab9649f00e"
+
+flush-write-stream@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417"
dependencies:
@@ -5016,6 +5330,13 @@ fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
+from2@^2.1.1:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
+ dependencies:
+ inherits "^2.0.1"
+ readable-stream "^2.0.0"
+
from@~0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
@@ -5103,11 +5424,11 @@ function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1, function-bind@
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
function.prototype.name@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.0.3.tgz#0099ae5572e9dd6f03c97d023fd92bcc5e639eac"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
dependencies:
define-properties "^1.1.2"
- function-bind "^1.1.0"
+ function-bind "^1.1.1"
is-callable "^1.1.3"
functional-red-black-tree@^1.0.1:
@@ -5118,6 +5439,13 @@ fuse.js@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.2.0.tgz#f0448e8069855bf2a3e683cdc1d320e7e2a07ef4"
+ganache-cli@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.1.0.tgz#486c846497204b644166b5f0f74c9b41d02bdc25"
+ dependencies:
+ source-map-support "^0.5.3"
+ webpack-cli "^2.0.9"
+
gather-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/gather-stream/-/gather-stream-1.0.0.tgz#b33994af457a8115700d410f317733cbe7a0904b"
@@ -5175,7 +5503,7 @@ get-stdin@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
-get-stream@^3.0.0:
+get-stream@3.0.0, get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
@@ -5200,6 +5528,23 @@ getpass@^0.1.1:
dependencies:
assert-plus "^1.0.0"
+gh-got@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-6.0.0.tgz#d74353004c6ec466647520a10bd46f7299d268d0"
+ dependencies:
+ got "^7.0.0"
+ is-plain-obj "^1.1.0"
+
+gifencoder@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/gifencoder/-/gifencoder-1.1.0.tgz#50e7d98c4b0cf97edd0d885d7e1b997f88802de3"
+
+github-username@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417"
+ dependencies:
+ gh-got "^6.0.0"
+
gl-mat4@1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/gl-mat4/-/gl-mat4-1.1.4.tgz#1e895b55892e56a896867abd837d38f37a178086"
@@ -5208,7 +5553,7 @@ gl-vec3@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/gl-vec3/-/gl-vec3-1.0.3.tgz#110fd897d0729f6398307381567d0944941bf22b"
-glob-all@^3.0.1:
+glob-all@^3.0.1, glob-all@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab"
dependencies:
@@ -5250,6 +5595,17 @@ glob-stream@^6.1.0:
to-absolute-glob "^2.0.0"
unique-stream "^2.0.2"
+glob-stream@~3.1.9:
+ version "3.1.18"
+ resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b"
+ dependencies:
+ glob "^4.3.1"
+ glob2base "^0.0.12"
+ minimatch "^2.0.1"
+ ordered-read-streams "^0.1.0"
+ through2 "^0.6.1"
+ unique-stream "^1.0.0"
+
glob-watcher@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-4.0.0.tgz#9e63a8ff6e61e932de6cc2caece5071a6d737329"
@@ -5259,6 +5615,12 @@ glob-watcher@^4.0.0:
just-debounce "^1.0.0"
object.defaults "^1.1.0"
+glob2base@^0.0.12:
+ version "0.0.12"
+ resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56"
+ dependencies:
+ find-index "^0.1.1"
+
glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
@@ -5270,6 +5632,15 @@ glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glo
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@^4.3.1:
+ version "4.5.3"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f"
+ dependencies:
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^2.0.1"
+ once "^1.3.0"
+
glob@^5.0.15:
version "5.0.15"
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
@@ -5331,13 +5702,9 @@ global@~4.3.0:
min-document "^2.19.0"
process "~0.5.1"
-globals@^10.0.0:
- version "10.4.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-10.4.0.tgz#5c477388b128a9e4c5c5d01c7a2aca68c68b2da7"
-
-globals@^11.0.1:
- version "11.1.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-11.1.0.tgz#632644457f5f0e3ae711807183700ebf2e4633e4"
+globals@^11.0.1, globals@^11.1.0:
+ version "11.2.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.2.0.tgz#aa2ece052a787563ba70a3dcd9dc2eb8a9a0488c"
globals@^9.18.0:
version "9.18.0"
@@ -5377,11 +5744,52 @@ globule@^1.0.0:
minimatch "~3.0.2"
glogg@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.1.tgz#dcf758e44789cc3f3d32c1f3562a3676e6a34810"
dependencies:
sparkles "^1.0.0"
+got@^7.0.0:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
+ dependencies:
+ decompress-response "^3.2.0"
+ duplexer3 "^0.1.4"
+ get-stream "^3.0.0"
+ is-plain-obj "^1.1.0"
+ is-retry-allowed "^1.0.0"
+ is-stream "^1.0.0"
+ isurl "^1.0.0-alpha5"
+ lowercase-keys "^1.0.0"
+ p-cancelable "^0.3.0"
+ p-timeout "^1.1.1"
+ safe-buffer "^5.0.1"
+ timed-out "^4.0.0"
+ url-parse-lax "^1.0.0"
+ url-to-options "^1.0.1"
+
+got@^8.2.0:
+ version "8.3.0"
+ resolved "https://registry.yarnpkg.com/got/-/got-8.3.0.tgz#6ba26e75f8a6cc4c6b3eb1fe7ce4fec7abac8533"
+ dependencies:
+ "@sindresorhus/is" "^0.7.0"
+ cacheable-request "^2.1.1"
+ decompress-response "^3.3.0"
+ duplexer3 "^0.1.4"
+ get-stream "^3.0.0"
+ into-stream "^3.1.0"
+ is-retry-allowed "^1.1.0"
+ isurl "^1.0.0-alpha5"
+ lowercase-keys "^1.0.0"
+ mimic-response "^1.0.0"
+ p-cancelable "^0.4.0"
+ p-timeout "^2.0.1"
+ pify "^3.0.0"
+ safe-buffer "^5.1.1"
+ timed-out "^4.0.1"
+ url-parse-lax "^3.0.0"
+ url-to-options "^1.0.1"
+
graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
@@ -5390,6 +5798,12 @@ graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, gr
version "1.0.1"
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
+grouped-queue@^0.3.3:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-0.3.3.tgz#c167d2a5319c5a0e0964ef6a25b7c2df8996c85c"
+ dependencies:
+ lodash "^4.17.2"
+
growl@1.10.3:
version "1.10.3"
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f"
@@ -5410,17 +5824,17 @@ gulp-autoprefixer@^5.0.0:
vinyl-sourcemaps-apply "^0.2.0"
gulp-babel@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-7.0.0.tgz#7b93c975159f7a0553e4263b4a55100ccc239b28"
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-7.0.1.tgz#b9c8e29fa376b36c57989db820fc1c1715bb47cb"
dependencies:
- gulp-util "^3.0.0"
+ plugin-error "^1.0.1"
replace-ext "0.0.1"
through2 "^2.0.0"
vinyl-sourcemaps-apply "^0.2.0"
gulp-cli@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.0.0.tgz#7f049ad298ed388cda9bd813b5d7062407d62cad"
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.0.1.tgz#7847e220cb3662f2be8a6d572bf14e17be5a994b"
dependencies:
ansi-colors "^1.0.1"
archy "^1.0.0"
@@ -5428,16 +5842,16 @@ gulp-cli@^2.0.0:
color-support "^1.1.3"
concat-stream "^1.6.0"
copy-props "^2.0.1"
- fancy-log "^1.1.0"
+ fancy-log "^1.3.2"
gulplog "^1.0.0"
- interpret "^1.0.0"
+ interpret "^1.1.0"
isobject "^3.0.1"
- liftoff "^2.3.0"
+ liftoff "^2.5.0"
matchdep "^2.0.0"
mute-stdout "^1.0.0"
pretty-hrtime "^1.0.0"
replace-homedir "^1.0.0"
- semver-greatest-satisfied-range "^1.0.0"
+ semver-greatest-satisfied-range "^1.1.0"
v8flags "^3.0.1"
yargs "^7.1.0"
@@ -5453,11 +5867,12 @@ gulp-debug@^3.2.0:
tildify "^1.1.2"
gulp-eslint@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/gulp-eslint/-/gulp-eslint-4.0.0.tgz#16d9ea4d696e7b7a9d65eeb1aa5bc4ba0a22c7f7"
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/gulp-eslint/-/gulp-eslint-4.0.2.tgz#18a2a6768e4404cbf3e203239cb57474168fa606"
dependencies:
eslint "^4.0.0"
- gulp-util "^3.0.8"
+ fancy-log "^1.3.2"
+ plugin-error "^1.0.0"
gulp-json-editor@^2.2.1:
version "2.2.1"
@@ -5480,6 +5895,12 @@ gulp-livereload@^3.8.1:
lodash.assign "^3.0.0"
mini-lr "^0.1.8"
+gulp-multi-process@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/gulp-multi-process/-/gulp-multi-process-1.3.1.tgz#e12aa818e4c234357ad99d5caff8df8a18f46e9e"
+ dependencies:
+ async.queue "^0.5.2"
+
gulp-replace@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/gulp-replace/-/gulp-replace-0.6.1.tgz#11bf8c8fce533e33e2f6a8f2f430b955ba0be066"
@@ -5499,8 +5920,8 @@ gulp-sass@^3.1.0:
vinyl-sourcemaps-apply "^0.2.0"
gulp-sourcemaps@^2.6.0:
- version "2.6.2"
- resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.2.tgz#4f41c72b35a7ea06b666d2e3f57917e2c0e71c4e"
+ version "2.6.4"
+ resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.4.tgz#cbb2008450b1bcce6cd23bf98337be751bf6e30a"
dependencies:
"@gulp-sourcemaps/identity-map" "1.X"
"@gulp-sourcemaps/map-sources" "1.X"
@@ -5510,7 +5931,7 @@ gulp-sourcemaps@^2.6.0:
debug-fabulous "1.X"
detect-newline "2.X"
graceful-fs "4.X"
- source-map "0.X"
+ source-map "~0.6.0"
strip-bom-string "1.X"
through2 "2.X"
@@ -5560,7 +5981,7 @@ gulp-uglify@^3.0.0:
uglify-js "^3.0.5"
vinyl-sourcemaps-apply "^0.2.0"
-gulp-util@^3.0, gulp-util@^3.0.0, gulp-util@^3.0.2, gulp-util@^3.0.7, gulp-util@^3.0.8, gulp-util@~3.0.0:
+gulp-util@^3.0, gulp-util@^3.0.2, gulp-util@^3.0.7, gulp-util@~3.0.0:
version "3.0.8"
resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f"
dependencies:
@@ -5599,12 +6020,13 @@ gulp-watch@^5.0.0:
vinyl-file "^2.0.0"
gulp-zip@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-4.0.0.tgz#1cefc08b4bf36df4b5b1e7c6b36ee55ebbe4a881"
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-4.1.0.tgz#dab178bd99afa190923f1eb78abaf0db47817704"
dependencies:
get-stream "^3.0.0"
- gulp-util "^3.0.0"
+ plugin-error "^0.1.2"
through2 "^2.0.1"
+ vinyl "^2.1.0"
yazl "^2.1.0"
"gulp@github:gulpjs/gulp#4.0":
@@ -5693,6 +6115,10 @@ has-binary@0.1.7:
dependencies:
isarray "0.0.1"
+has-color@~0.1.0:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f"
+
has-cors@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39"
@@ -5715,10 +6141,20 @@ has-gulplog@^0.1.0:
dependencies:
sparkles "^1.0.0"
+has-symbol-support-x@^1.4.1:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455"
+
has-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
+has-to-string-tag-x@^1.2.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
+ dependencies:
+ has-symbol-support-x "^1.4.1"
+
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -5816,6 +6252,16 @@ hipchat-notifier@^1.1.0:
lodash "^4.0.0"
request "^2.0.0"
+history@^4.7.2:
+ version "4.7.2"
+ resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b"
+ dependencies:
+ invariant "^2.2.1"
+ loose-envify "^1.2.0"
+ resolve-pathname "^2.2.0"
+ value-equal "^0.4.0"
+ warning "^3.0.0"
+
hmac-drbg@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@@ -5832,7 +6278,7 @@ hoek@4.x.x:
version "4.2.0"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
-hoist-non-react-statics@^2.2.1, hoist-non-react-statics@^2.3.1:
+hoist-non-react-statics@^2.2.1, hoist-non-react-statics@^2.3.0, hoist-non-react-statics@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
@@ -5889,6 +6335,16 @@ htmlescape@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351"
+htmlparser2@3.8.x:
+ version "3.8.3"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068"
+ dependencies:
+ domelementtype "1"
+ domhandler "2.3"
+ domutils "1.5"
+ entities "1.0"
+ readable-stream "1.1"
+
htmlparser2@^3.9.1:
version "3.9.2"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
@@ -5900,6 +6356,10 @@ htmlparser2@^3.9.1:
inherits "^2.0.1"
readable-stream "^2.0.2"
+http-cache-semantics@3.8.1:
+ version "3.8.1"
+ resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
+
http-errors@1.6.2, http-errors@~1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
@@ -6039,6 +6499,10 @@ ignorepatterns@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ignorepatterns/-/ignorepatterns-1.1.0.tgz#ac8f436f2239b5dfb66d5f0d3a904a87ac67cc5e"
+image-size@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.2.tgz#8ee316d4298b028b965091b673d5f1537adee5b4"
+
immediate@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c"
@@ -6061,6 +6525,10 @@ indent-string@^2.1.0:
dependencies:
repeating "^2.0.0"
+indent-string@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
+
indexes-of@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
@@ -6112,7 +6580,7 @@ inline-source-map@~0.6.0:
dependencies:
source-map "~0.5.3"
-inquirer@^3.0.6:
+inquirer@^3.0.6, inquirer@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
dependencies:
@@ -6131,6 +6599,24 @@ inquirer@^3.0.6:
strip-ansi "^4.0.0"
through "^2.3.6"
+inquirer@^5.1.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726"
+ dependencies:
+ ansi-escapes "^3.0.0"
+ chalk "^2.0.0"
+ cli-cursor "^2.1.0"
+ cli-width "^2.0.0"
+ external-editor "^2.1.0"
+ figures "^2.0.0"
+ lodash "^4.3.0"
+ mute-stream "0.0.7"
+ run-async "^2.2.0"
+ rxjs "^5.5.2"
+ string-width "^2.1.0"
+ strip-ansi "^4.0.0"
+ through "^2.3.6"
+
insert-module-globals@^7.0.0:
version "7.0.1"
resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.0.1.tgz#c03bf4e01cb086d5b5e5ace8ad0afe7889d638c3"
@@ -6144,11 +6630,18 @@ insert-module-globals@^7.0.0:
through2 "^2.0.0"
xtend "^4.0.0"
-interpret@^1.0.0:
+interpret@^1.0.0, interpret@^1.0.4, interpret@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
-invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.2:
+into-stream@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6"
+ dependencies:
+ from2 "^2.1.1"
+ p-is-promise "^1.1.0"
+
+invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
dependencies:
@@ -6391,6 +6884,16 @@ is-obj@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
+is-object@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
+
+is-observable@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2"
+ dependencies:
+ symbol-observable "^0.2.2"
+
is-odd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-1.0.0.tgz#3b8a932eb028b3775c39bb09e91767accdb69088"
@@ -6419,7 +6922,7 @@ is-path-inside@^1.0.0:
dependencies:
path-is-inside "^1.0.1"
-is-plain-obj@^1.1.0:
+is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
@@ -6462,10 +6965,20 @@ is-relative@^1.0.0:
is-unc-path "^1.0.0"
is-resolvable@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
-is-stream@^1.0.1, is-stream@^1.1.0:
+is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
+
+is-scoped@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-scoped/-/is-scoped-1.0.0.tgz#449ca98299e713038256289ecb2b540dc437cb30"
+ dependencies:
+ scoped-regex "^1.0.0"
+
+is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
@@ -6624,6 +7137,21 @@ istextorbinary@1.0.2:
binaryextensions "~1.0.0"
textextensions "~1.0.0"
+istextorbinary@^2.1.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.2.1.tgz#a5231a08ef6dd22b268d0895084cf8d58b5bec53"
+ dependencies:
+ binaryextensions "2"
+ editions "^1.3.3"
+ textextensions "2"
+
+isurl@^1.0.0-alpha5:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
+ dependencies:
+ has-to-string-tag-x "^1.2.0"
+ is-object "^1.0.1"
+
jazzicon@^1.2.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/jazzicon/-/jazzicon-1.5.0.tgz#d7f36b516023db39ee6eac117f4054e937b65e99"
@@ -6633,8 +7161,8 @@ jazzicon@^1.2.0:
raphael "^2.2.0"
js-base64@^2.1.8, js-base64@^2.1.9:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa"
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582"
js-beautify@~1.5.4:
version "1.5.10"
@@ -6675,6 +7203,46 @@ jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+jscodeshift@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.4.1.tgz#da91a1c2eccfa03a3387a21d39948e251ced444a"
+ dependencies:
+ async "^1.5.0"
+ babel-plugin-transform-flow-strip-types "^6.8.0"
+ babel-preset-es2015 "^6.9.0"
+ babel-preset-stage-1 "^6.5.0"
+ babel-register "^6.9.0"
+ babylon "^6.17.3"
+ colors "^1.1.2"
+ flow-parser "^0.*"
+ lodash "^4.13.1"
+ micromatch "^2.3.7"
+ node-dir "0.1.8"
+ nomnom "^1.8.1"
+ recast "^0.12.5"
+ temp "^0.8.1"
+ write-file-atomic "^1.2.0"
+
+jscodeshift@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.5.0.tgz#bdb7b6cc20dd62c16aa728c3fa2d2fe66ca7c748"
+ dependencies:
+ babel-plugin-transform-flow-strip-types "^6.8.0"
+ babel-preset-es2015 "^6.9.0"
+ babel-preset-stage-1 "^6.5.0"
+ babel-register "^6.9.0"
+ babylon "^7.0.0-beta.30"
+ colors "^1.1.2"
+ flow-parser "^0.*"
+ lodash "^4.13.1"
+ micromatch "^2.3.7"
+ neo-async "^2.5.0"
+ node-dir "0.1.8"
+ nomnom "^1.8.1"
+ recast "^0.14.1"
+ temp "^0.8.1"
+ write-file-atomic "^1.2.0"
+
jsdom-global@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/jsdom-global/-/jsdom-global-3.0.2.tgz#6bd299c13b0c4626b2da2c0393cd4385d606acb9"
@@ -6729,10 +7297,31 @@ jshint-stylish@~2.2.1:
string-length "^1.0.0"
text-table "^0.2.0"
+jshint@^2.8.0:
+ version "2.9.5"
+ resolved "https://registry.yarnpkg.com/jshint/-/jshint-2.9.5.tgz#1e7252915ce681b40827ee14248c46d34e9aa62c"
+ dependencies:
+ cli "~1.0.0"
+ console-browserify "1.1.x"
+ exit "0.1.x"
+ htmlparser2 "3.8.x"
+ lodash "3.7.x"
+ minimatch "~3.0.2"
+ shelljs "0.3.x"
+ strip-json-comments "1.0.x"
+
+json-buffer@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
+
json-loader@^0.5.4:
version "0.5.7"
resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"
+json-parse-better-errors@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
+
json-rpc-engine@^3.0.1, json-rpc-engine@^3.1.0, json-rpc-engine@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.4.0.tgz#8a1647a7f2cc7018f4802f41ec8208d281f78bfc"
@@ -6867,7 +7456,7 @@ jstransform@^10.1.0:
esprima-fb "13001.1001.0-dev-harmony-fb"
source-map "0.1.31"
-jsx-ast-utils@^2.0.0:
+jsx-ast-utils@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f"
dependencies:
@@ -6965,6 +7554,16 @@ kew@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b"
+keyv@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373"
+ dependencies:
+ json-buffer "3.0.0"
+
+kind-of@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44"
+
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.1.0, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
@@ -7136,7 +7735,7 @@ lie@~3.1.0:
dependencies:
immediate "~3.0.5"
-liftoff@^2.3.0:
+liftoff@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec"
dependencies:
@@ -7149,9 +7748,57 @@ liftoff@^2.3.0:
rechoir "^0.6.2"
resolve "^1.1.7"
+listr-silent-renderer@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
+
+listr-update-renderer@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7"
+ dependencies:
+ chalk "^1.1.3"
+ cli-truncate "^0.2.1"
+ elegant-spinner "^1.0.1"
+ figures "^1.7.0"
+ indent-string "^3.0.0"
+ log-symbols "^1.0.2"
+ log-update "^1.0.2"
+ strip-ansi "^3.0.1"
+
+listr-verbose-renderer@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35"
+ dependencies:
+ chalk "^1.1.3"
+ cli-cursor "^1.0.2"
+ date-fns "^1.27.2"
+ figures "^1.7.0"
+
+listr@^0.13.0:
+ version "0.13.0"
+ resolved "https://registry.yarnpkg.com/listr/-/listr-0.13.0.tgz#20bb0ba30bae660ee84cc0503df4be3d5623887d"
+ dependencies:
+ chalk "^1.1.3"
+ cli-truncate "^0.2.1"
+ figures "^1.7.0"
+ indent-string "^2.1.0"
+ is-observable "^0.2.0"
+ is-promise "^2.1.0"
+ is-stream "^1.1.0"
+ listr-silent-renderer "^1.1.1"
+ listr-update-renderer "^0.4.0"
+ listr-verbose-renderer "^0.4.0"
+ log-symbols "^1.0.2"
+ log-update "^1.0.2"
+ ora "^0.2.3"
+ p-map "^1.1.1"
+ rxjs "^5.4.2"
+ stream-to-observable "^0.2.0"
+ strip-ansi "^3.0.1"
+
livereload-js@^2.2.0:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2"
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.3.0.tgz#c3ab22e8aaf5bf3505d80d098cbad67726548c9a"
load-json-file@^1.0.0:
version "1.1.0"
@@ -7163,6 +7810,15 @@ load-json-file@^1.0.0:
pinkie-promise "^2.0.0"
strip-bom "^2.0.0"
+load-json-file@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
+ dependencies:
+ graceful-fs "^4.1.2"
+ parse-json "^4.0.0"
+ pify "^3.0.0"
+ strip-bom "^3.0.0"
+
loader-runner@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
@@ -7176,6 +7832,14 @@ loader-utils@^0.2.16:
json5 "^0.5.0"
object-assign "^4.0.1"
+loader-utils@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd"
+ dependencies:
+ big.js "^3.1.3"
+ emojis-list "^2.0.0"
+ json5 "^0.5.0"
+
locate-path@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
@@ -7377,10 +8041,18 @@ lodash.uniqby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302"
+lodash@3.7.x:
+ version "3.7.0"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.7.0.tgz#3678bd8ab995057c07ade836ed2ef087da811d45"
+
lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@~4.17.2, lodash@~4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+lodash@^4.17.2, lodash@^4.17.5:
+ version "4.17.5"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
+
log-driver@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056"
@@ -7391,6 +8063,19 @@ log-symbols@^1.0.0, log-symbols@^1.0.2:
dependencies:
chalk "^1.0.0"
+log-symbols@^2.1.0, log-symbols@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
+ dependencies:
+ chalk "^2.0.1"
+
+log-update@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
+ dependencies:
+ ansi-escapes "^1.0.0"
+ cli-cursor "^1.0.2"
+
log4js@^2.3.9:
version "2.5.3"
resolved "https://registry.yarnpkg.com/log4js/-/log4js-2.5.3.tgz#38bb7bde5e9c1c181bd75e8bc128c5cd0409caf1"
@@ -7419,22 +8104,22 @@ loggly@^1.1.0:
timespan "2.3.x"
loglevel@^1.4.1, loglevel@^1.5.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.0.tgz#ae0caa561111498c5ba13723d6fb631d24003934"
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
lolex@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6"
lolex@^2.2.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.1.tgz#3d2319894471ea0950ef64692ead2a5318cff362"
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.2.tgz#85f9450425103bf9e7a60668ea25dc43274ca807"
longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
-loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
+loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
dependencies:
@@ -7447,23 +8132,27 @@ loud-rejection@^1.0.0:
currently-unhandled "^0.4.1"
signal-exit "^3.0.0"
-lru-cache@2.2.x:
- version "2.2.4"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d"
+lowercase-keys@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
-lru-cache@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee"
- dependencies:
- pseudomap "^1.0.1"
+lowercase-keys@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
-lru-cache@^4.0.1:
+lru-cache@4.1.x, lru-cache@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
dependencies:
pseudomap "^1.0.2"
yallist "^2.1.2"
+lru-cache@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee"
+ dependencies:
+ pseudomap "^1.0.1"
+
lru-cache@~2.6.5:
version "2.6.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.6.5.tgz#e56d6354148ede8d7707b58d143220fd08df0fd5"
@@ -7499,6 +8188,12 @@ mailgun-js@^0.7.0:
q "~1.4.0"
tsscmp "~1.0.0"
+make-dir@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.2.0.tgz#6d6a49eead4aae296c53bbf3a1a008bd6c89469b"
+ dependencies:
+ pify "^3.0.0"
+
make-error-cause@^1.1.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/make-error-cause/-/make-error-cause-1.2.2.tgz#df0388fcd0b37816dff0a5fb8108939777dcbc9d"
@@ -7581,6 +8276,29 @@ media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
+mem-fs-editor@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-3.0.2.tgz#dd0a6eaf2bb8a6b37740067aa549eb530105af9f"
+ dependencies:
+ commondir "^1.0.1"
+ deep-extend "^0.4.0"
+ ejs "^2.3.1"
+ glob "^7.0.3"
+ globby "^6.1.0"
+ mkdirp "^0.5.0"
+ multimatch "^2.0.0"
+ rimraf "^2.2.8"
+ through2 "^2.0.0"
+ vinyl "^2.0.1"
+
+mem-fs@^1.1.0:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc"
+ dependencies:
+ through2 "^2.0.0"
+ vinyl "^1.1.0"
+ vinyl-file "^2.0.0"
+
mem@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76"
@@ -7706,8 +8424,8 @@ micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7:
regex-cache "^0.4.2"
micromatch@^3.0.4:
- version "3.1.4"
- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.4.tgz#bb812e741a41f982c854e42b421a7eac458796f4"
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.5.tgz#d05e168c206472dfbca985bfef4f57797b4cd4ba"
dependencies:
arr-diff "^4.0.0"
array-unique "^0.3.2"
@@ -7788,6 +8506,10 @@ mimic-fn@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
+mimic-response@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e"
+
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
@@ -7819,6 +8541,12 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
dependencies:
brace-expansion "^1.1.7"
+minimatch@^2.0.1:
+ version "2.0.10"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7"
+ dependencies:
+ brace-expansion "^1.0.0"
+
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
@@ -7910,6 +8638,26 @@ module-deps@^4.0.8:
through2 "^2.0.0"
xtend "^4.0.0"
+module-deps@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-5.0.1.tgz#3bc47c14b0a6d925aff2ec4a177b456a96ae0396"
+ dependencies:
+ JSONStream "^1.0.3"
+ browser-resolve "^1.7.0"
+ cached-path-relative "^1.0.0"
+ concat-stream "~1.6.0"
+ defined "^1.0.0"
+ detective "^5.0.2"
+ duplexer2 "^0.1.2"
+ inherits "^2.0.1"
+ parents "^1.0.0"
+ readable-stream "^2.0.2"
+ resolve "^1.1.3"
+ stream-combiner2 "^1.1.1"
+ subarg "^1.0.0"
+ through2 "^2.0.0"
+ xtend "^4.0.0"
+
module-deps@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-6.0.0.tgz#4417b49a4f4d7af79b104186e5389ea99b1dc837"
@@ -7992,8 +8740,8 @@ nan@^2.0.5, nan@^2.0.8, nan@^2.2.1, nan@^2.3.0, nan@^2.3.2:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
nanomatch@^1.2.5:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.6.tgz#f27233e97c34a8706b7e781a4bc611c957a81625"
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.7.tgz#53cd4aa109ff68b7f869591fdc9d10daeeea3e79"
dependencies:
arr-diff "^4.0.0"
array-unique "^0.3.2"
@@ -8044,6 +8792,10 @@ negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
+neo-async@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.0.tgz#76b1c823130cca26acfbaccc8fbaf0a2fa33b18f"
+
netmask@~1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35"
@@ -8052,9 +8804,13 @@ next-tick@1:
version "1.0.0"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
+nice-try@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"
+
nise@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.0.tgz#079d6cadbbcb12ba30e38f1c999f36ad4d6baa53"
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.2.tgz#9aa5edb500da38035884106e3c571341bc68b2c1"
dependencies:
formatio "^1.2.0"
just-extend "^1.1.26"
@@ -8063,8 +8819,8 @@ nise@^1.2.0:
text-encoding "^0.6.4"
nock@^9.0.14:
- version "9.1.5"
- resolved "https://registry.yarnpkg.com/nock/-/nock-9.1.5.tgz#9e4878e0e1c050bdd93ae1e326e89461ea15618b"
+ version "9.1.6"
+ resolved "https://registry.yarnpkg.com/nock/-/nock-9.1.6.tgz#16395af4c45b0fd84d1a4a9668154e16fa6624db"
dependencies:
chai ">=1.9.2 <4.0.0"
debug "^2.2.0"
@@ -8076,6 +8832,10 @@ nock@^9.0.14:
qs "^6.5.1"
semver "^5.3.0"
+node-dir@0.1.8:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d"
+
node-fetch@^1.0.1, node-fetch@^1.7.3, node-fetch@~1.7.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
@@ -8130,13 +8890,13 @@ node-libs-browser@^2.0.0:
vm-browserify "0.0.4"
node-notifier@^5.0.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.1.2.tgz#2fa9e12605fa10009d44549d6fcd8a63dde0e4ff"
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea"
dependencies:
growly "^1.3.0"
- semver "^5.3.0"
- shellwords "^0.1.0"
- which "^1.2.12"
+ semver "^5.4.1"
+ shellwords "^0.1.1"
+ which "^1.3.0"
node-pre-gyp@^0.6.39:
version "0.6.39"
@@ -8231,6 +8991,13 @@ nodemailer@^2.5.0:
nodemailer-smtp-transport "2.7.2"
socks "1.1.9"
+nomnom@^1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7"
+ dependencies:
+ chalk "~0.4.0"
+ underscore "~1.6.0"
+
nomnom@~1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.6.2.tgz#84a66a260174408fc5b77a18f888eccc44fb6971"
@@ -8274,6 +9041,14 @@ normalize-selector@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03"
+normalize-url@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6"
+ dependencies:
+ prepend-http "^2.0.0"
+ query-string "^5.0.1"
+ sort-keys "^2.0.0"
+
now-and-later@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee"
@@ -8529,6 +9304,10 @@ onecolor@^3.0.4:
version "3.0.5"
resolved "https://registry.yarnpkg.com/onecolor/-/onecolor-3.0.5.tgz#36eff32201379efdf1180fb445e51a8e2425f9f6"
+onetime@^1.0.0:
+ version "1.1.0"
+ resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
+
onetime@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
@@ -8569,6 +9348,19 @@ options@>=0.0.5:
version "0.0.6"
resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f"
+ora@^0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4"
+ dependencies:
+ chalk "^1.1.1"
+ cli-cursor "^1.0.2"
+ cli-spinners "^0.1.2"
+ object-assign "^4.0.1"
+
+ordered-read-streams@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126"
+
ordered-read-streams@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e"
@@ -8614,13 +9406,37 @@ outpipe@^1.1.0:
dependencies:
shell-quote "^1.4.2"
+p-cancelable@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
+
+p-cancelable@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0"
+
+p-each-series@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71"
+ dependencies:
+ p-reduce "^1.0.0"
+
p-finally@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
-p-limit@^1.1.0:
+p-is-promise@^1.1.0:
version "1.1.0"
- resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
+ resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
+
+p-lazy@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-lazy/-/p-lazy-1.0.0.tgz#ec53c802f2ee3ac28f166cc82d0b2b02de27a835"
+
+p-limit@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c"
+ dependencies:
+ p-try "^1.0.0"
p-locate@^2.0.0:
version "2.0.0"
@@ -8632,6 +9448,26 @@ p-map@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
+p-reduce@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa"
+
+p-timeout@^1.1.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386"
+ dependencies:
+ p-finally "^1.0.0"
+
+p-timeout@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038"
+ dependencies:
+ p-finally "^1.0.0"
+
+p-try@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
+
pac-proxy-agent@1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz#34a385dfdf61d2f0ecace08858c745d3e791fd4d"
@@ -8717,6 +9553,13 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"
+parse-json@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
+ dependencies:
+ error-ex "^1.3.1"
+ json-parse-better-errors "^1.0.1"
+
parse-passwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
@@ -8783,7 +9626,7 @@ path-is-inside@^1.0.1, path-is-inside@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
-path-key@^2.0.0:
+path-key@^2.0.0, path-key@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
@@ -8829,6 +9672,12 @@ path-type@^1.0.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
+path-type@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
+ dependencies:
+ pify "^3.0.0"
+
pathval@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0"
@@ -8916,7 +9765,17 @@ plucker@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/plucker/-/plucker-0.0.0.tgz#2ffa24e03ab2cffa4e75adc1df70f25623c45d09"
-plugin-error@^1.0.1:
+plugin-error@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace"
+ dependencies:
+ ansi-cyan "^0.1.1"
+ ansi-red "^0.1.1"
+ arr-diff "^1.0.1"
+ arr-union "^2.0.1"
+ extend-shallow "^1.1.2"
+
+plugin-error@^1.0.0, plugin-error@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c"
dependencies:
@@ -8939,6 +9798,18 @@ pn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
+png-file-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/png-file-stream/-/png-file-stream-1.0.0.tgz#e083d0fe56e097a5cbd0d341a1387379052cad35"
+ dependencies:
+ glob-stream "~3.1.9"
+ png-js "~0.1.1"
+ through2 "~0.2.3"
+
+png-js@~0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/png-js/-/png-js-0.1.1.tgz#1cc7c212303acabe74263ec3ac78009580242d93"
+
pojo-migrator@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/pojo-migrator/-/pojo-migrator-2.1.0.tgz#3c2a3b9f80ba5a9fb7ebb921d3344db4efa5f669"
@@ -9055,10 +9926,26 @@ prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
+prepend-http@^1.0.1:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
+
+prepend-http@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
+
preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
+prettier@^1.5.3:
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75"
+
+pretty-bytes@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9"
+
pretty-bytes@~0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-0.1.2.tgz#cd90294d58a1ca4e8a5d0fb9c8225998881acf00"
@@ -9131,7 +10018,14 @@ prompt@^1.0.0:
utile "0.3.x"
winston "2.1.x"
-prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0:
+prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.8:
+ version "15.5.10"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
+ dependencies:
+ fbjs "^0.8.9"
+ loose-envify "^1.3.1"
+
+prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.6.0:
version "15.6.0"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
dependencies:
@@ -9139,6 +10033,14 @@ prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8,
loose-envify "^1.3.1"
object-assign "^4.1.1"
+prop-types@^15.6.1:
+ version "15.6.1"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.3.1"
+ object-assign "^4.1.1"
+
propagate@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/propagate/-/propagate-0.4.0.tgz#f3fcca0a6fe06736a7ba572966069617c130b481"
@@ -9175,6 +10077,12 @@ prr@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
+ps-tree@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014"
+ dependencies:
+ event-stream "~3.3.0"
+
pseudomap@^1.0.1, pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
@@ -9263,6 +10171,14 @@ qs@~6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
+query-string@^5.0.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb"
+ dependencies:
+ decode-uri-component "^0.2.0"
+ object-assign "^4.1.0"
+ strict-uri-encode "^1.0.0"
+
querystring-es3@^0.2.0, querystring-es3@~0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@@ -9331,8 +10247,8 @@ randomatic@^1.1.3:
kind-of "^4.0.0"
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79"
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80"
dependencies:
safe-buffer "^5.1.0"
@@ -9375,8 +10291,8 @@ raw-body@~2.1.5:
unpipe "1.0.0"
rc@^1.1.7:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077"
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.4.tgz#a0f606caae2a3b862bbd0ef85482c0125b315fa3"
dependencies:
deep-extend "~0.4.0"
ini "~1.3.0"
@@ -9409,18 +10325,18 @@ react-hyperscript@^2.4.0:
react ">= 0.12.0 < 16.0.0"
react-hyperscript@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/react-hyperscript/-/react-hyperscript-3.0.0.tgz#3c16010b33175de6bc01fd1ebad0a16a9a6dc9ab"
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/react-hyperscript/-/react-hyperscript-3.1.0.tgz#8f0fa74003b20ccee98fbb496dfb0791139a287d"
-react-input-autosize@^2.1.0:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.1.2.tgz#a3dc11a5517c434db25229925541309de3f7a8f5"
+react-input-autosize@^2.1.2:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8"
dependencies:
prop-types "^15.5.8"
react-markdown@^3.0.0:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.1.3.tgz#5ac1f20cb5a3e8c47b6ae3c8522e813b08f58c34"
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.1.4.tgz#4f37aa5ac4f78f64f93b41b12ad0c08e92eb1680"
dependencies:
prop-types "^15.6.0"
remark-parse "^4.0.0"
@@ -9447,13 +10363,36 @@ react-redux@^5.0.5:
loose-envify "^1.1.0"
prop-types "^15.5.10"
+react-router-dom@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.2.2.tgz#c8a81df3adc58bba8a76782e946cbd4eae649b8d"
+ dependencies:
+ history "^4.7.2"
+ invariant "^2.2.2"
+ loose-envify "^1.3.1"
+ prop-types "^15.5.4"
+ react-router "^4.2.0"
+ warning "^3.0.0"
+
+react-router@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.2.0.tgz#61f7b3e3770daeb24062dae3eedef1b054155986"
+ dependencies:
+ history "^4.7.2"
+ hoist-non-react-statics "^2.3.0"
+ invariant "^2.2.2"
+ loose-envify "^1.3.1"
+ path-to-regexp "^1.7.0"
+ prop-types "^15.5.4"
+ warning "^3.0.0"
+
react-select@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.1.0.tgz#626a2de839fdea2ade74dd1b143a9bde34be6c82"
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.2.1.tgz#a2fe58a569eb14dcaa6543816260b97e538120d1"
dependencies:
classnames "^2.2.4"
prop-types "^15.5.8"
- react-input-autosize "^2.1.0"
+ react-input-autosize "^2.1.2"
react-simple-file-input@^2.0.0:
version "2.0.1"
@@ -9541,6 +10480,13 @@ reactify@^1.1.1:
react-tools "~0.13.0"
through "~2.3.4"
+read-chunk@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655"
+ dependencies:
+ pify "^3.0.0"
+ safe-buffer "^5.1.1"
+
read-file-stdin@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/read-file-stdin/-/read-file-stdin-0.2.1.tgz#25eccff3a153b6809afacb23ee15387db9e0ee61"
@@ -9560,6 +10506,13 @@ read-pkg-up@^1.0.1:
find-up "^1.0.0"
read-pkg "^1.0.0"
+read-pkg-up@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07"
+ dependencies:
+ find-up "^2.0.0"
+ read-pkg "^3.0.0"
+
read-pkg@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
@@ -9568,12 +10521,29 @@ read-pkg@^1.0.0:
normalize-package-data "^2.3.2"
path-type "^1.0.0"
+read-pkg@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
+ dependencies:
+ load-json-file "^4.0.0"
+ normalize-package-data "^2.3.2"
+ path-type "^3.0.0"
+
read@1.0.x:
version "1.0.7"
resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
dependencies:
mute-stream "~0.0.4"
+readable-stream@1.1:
+ version "1.1.13"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e"
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "0.0.1"
+ string_decoder "~0.10.x"
+
readable-stream@1.1.x, "readable-stream@1.x >=1.1.9", "readable-stream@>=1.1.13-1 <1.2.0-0", readable-stream@^1.0.27-1, readable-stream@^1.0.33, readable-stream@^1.1.13-1, readable-stream@~1.1.9:
version "1.1.14"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
@@ -9604,7 +10574,7 @@ readable-stream@2, readable-stream@^2.3.0:
isarray "0.0.1"
string_decoder "~0.10.x"
-readable-stream@^2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9, readable-stream@^2.3.3:
+readable-stream@^2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
dependencies:
@@ -9651,6 +10621,25 @@ recast@^0.11.17:
private "~0.1.5"
source-map "~0.5.0"
+recast@^0.12.5:
+ version "0.12.9"
+ resolved "https://registry.yarnpkg.com/recast/-/recast-0.12.9.tgz#e8e52bdb9691af462ccbd7c15d5a5113647a15f1"
+ dependencies:
+ ast-types "0.10.1"
+ core-js "^2.4.1"
+ esprima "~4.0.0"
+ private "~0.1.5"
+ source-map "~0.6.1"
+
+recast@^0.14.1:
+ version "0.14.7"
+ resolved "https://registry.yarnpkg.com/recast/-/recast-0.14.7.tgz#4f1497c2b5826d42a66e8e3c9d80c512983ff61d"
+ dependencies:
+ ast-types "0.11.3"
+ esprima "~4.0.0"
+ private "~0.1.5"
+ source-map "~0.6.1"
+
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
@@ -10013,6 +11002,12 @@ requires-port@1.x.x:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
+resolve-cwd@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
+ dependencies:
+ resolve-from "^3.0.0"
+
resolve-dir@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e"
@@ -10045,6 +11040,10 @@ resolve-options@^1.1.0:
dependencies:
value-or-function "^3.0.0"
+resolve-pathname@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879"
+
resolve-url@^0.2.1, resolve-url@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
@@ -10079,6 +11078,19 @@ response-stream@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/response-stream/-/response-stream-0.0.0.tgz#da4b17cc7684c98c962beb4d95f668c8dcad09d5"
+responselike@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
+ dependencies:
+ lowercase-keys "^1.0.0"
+
+restore-cursor@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
+ dependencies:
+ exit-hook "^1.0.0"
+ onetime "^1.0.0"
+
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
@@ -10112,6 +11124,10 @@ rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.4.4, rimraf@^2.5.1, rimraf@^2.5
dependencies:
glob "^7.0.5"
+rimraf@~2.2.6:
+ version "2.2.8"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"
+
ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7"
@@ -10130,7 +11146,7 @@ rst-selector-parser@^2.2.3:
lodash.flattendeep "^4.4.0"
nearley "^2.7.10"
-run-async@^2.2.0:
+run-async@^2.0.0, run-async@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
dependencies:
@@ -10150,6 +11166,12 @@ rx-lite@*, rx-lite@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
+rxjs@^5.4.2, rxjs@^5.5.2:
+ version "5.5.8"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.8.tgz#b2b0809a57614ad6254c03d7446dea0d83ca3791"
+ dependencies:
+ symbol-observable "1.0.1"
+
safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@@ -10181,6 +11203,10 @@ sax@>=0.6.0, sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
+scoped-regex@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8"
+
script-injector@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/script-injector/-/script-injector-1.0.0.tgz#f6f4c7f6a5dcc59e08246e76bdfc83a0a1406926"
@@ -10216,8 +11242,8 @@ scss-tokenizer@^0.2.3:
source-map "^0.4.2"
secp256k1@^3.0.1:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.4.0.tgz#1c905b256fa4ae5b9cc170e672dd59b4c5de46a4"
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.5.0.tgz#677d3b8a8e04e1a5fa381a1ae437c54207b738d0"
dependencies:
bindings "^1.2.1"
bip66 "^1.1.3"
@@ -10241,15 +11267,15 @@ semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.0.5:
version "1.1.0"
resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa"
-semver-greatest-satisfied-range@^1.0.0:
+semver-greatest-satisfied-range@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b"
dependencies:
sver-compat "^1.5.0"
-"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@~5.4.1:
- version "5.4.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
+"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
semver@~5.0.1:
version "5.0.3"
@@ -10259,6 +11285,10 @@ semver@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
+semver@~5.4.1:
+ version "5.4.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
+
send@0.16.1:
version "0.16.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3"
@@ -10331,8 +11361,8 @@ setprototypeof@1.1.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4:
- version "2.4.9"
- resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d"
+ version "2.4.10"
+ resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.10.tgz#b1fde5cd7d11a5626638a07c604ab909cfa31f9b"
dependencies:
inherits "^2.0.1"
safe-buffer "^5.0.1"
@@ -10364,6 +11394,15 @@ shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
+shell-parallel@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/shell-parallel/-/shell-parallel-1.0.3.tgz#bf262bf25967ca38546d77f1e2de3be1100fcdbe"
+ dependencies:
+ once "^1.4.0"
+ pify "^3.0.0"
+ ps-tree "^1.1.0"
+ yargs "^11.0.0"
+
shell-quote@^1.4.2, shell-quote@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767"
@@ -10373,7 +11412,19 @@ shell-quote@^1.4.2, shell-quote@^1.6.1:
array-reduce "~0.0.0"
jsonify "~0.0.0"
-shellwords@^0.1.0:
+shelljs@0.3.x:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1"
+
+shelljs@^0.8.0:
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.1.tgz#729e038c413a2254c4078b95ed46e0397154a9f1"
+ dependencies:
+ glob "^7.0.0"
+ interpret "^1.0.0"
+ rechoir "^0.6.2"
+
+shellwords@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
@@ -10411,6 +11462,10 @@ slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
+slice-ansi@0.0.4:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
+
slice-ansi@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
@@ -10588,6 +11643,12 @@ solc@^0.4.2:
semver "^5.3.0"
yargs "^4.7.1"
+sort-keys@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128"
+ dependencies:
+ is-plain-obj "^1.0.0"
+
source-list-map@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
@@ -10617,6 +11678,12 @@ source-map-support@^0.4.15:
dependencies:
source-map "^0.5.6"
+source-map-support@^0.5.3:
+ version "0.5.4"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.4.tgz#54456efa89caa9270af7cd624cc2f123e51fbae8"
+ dependencies:
+ source-map "^0.6.0"
+
source-map-url@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
@@ -10631,9 +11698,9 @@ source-map@0.1.31:
dependencies:
amdefine ">=0.0.4"
-source-map@0.X, "source-map@>= 0.1.2", source-map@^0.6.1, source-map@~0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+"source-map@>= 0.1.2":
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.0.tgz#ebf0d13a48f3619f91891816fdda932f83a6021f"
source-map@^0.1.38, source-map@~0.1.33:
version "0.1.43"
@@ -10651,6 +11718,10 @@ source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, sour
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+
sparkles@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3"
@@ -10815,12 +11886,12 @@ stream-exhaust@^1.0.1:
resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d"
stream-http@^2.0.0, stream-http@^2.7.2:
- version "2.7.2"
- resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad"
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.0.tgz#fd86546dac9b1c91aff8fc5d287b98fafb41bc10"
dependencies:
builtin-status-codes "^3.0.0"
inherits "^2.0.1"
- readable-stream "^2.2.6"
+ readable-stream "^2.3.3"
to-arraybuffer "^1.0.0"
xtend "^4.0.0"
@@ -10846,6 +11917,12 @@ stream-splicer@^2.0.0:
inherits "^2.0.1"
readable-stream "^2.0.2"
+stream-to-observable@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.2.0.tgz#59d6ea393d87c2c0ddac10aa0d561bc6ba6f0e10"
+ dependencies:
+ any-observable "^0.2.0"
+
streamroller@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-0.7.0.tgz#a1d1b7cf83d39afb0d63049a5acbf93493bdf64b"
@@ -10855,12 +11932,20 @@ streamroller@^0.7.0:
mkdirp "^0.5.1"
readable-stream "^2.3.0"
+strict-uri-encode@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
+
string-length@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac"
dependencies:
strip-ansi "^3.0.0"
+string-template@~0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"
+
string-width@^1.0.1, string-width@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@@ -10924,6 +12009,10 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
+strip-ansi@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991"
+
strip-bom-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca"
@@ -10941,6 +12030,10 @@ strip-bom@^2.0.0:
dependencies:
is-utf8 "^0.2.0"
+strip-bom@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
@@ -10957,6 +12050,10 @@ strip-indent@^1.0.1:
dependencies:
get-stdin "^4.0.1"
+strip-json-comments@1.0.x:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91"
+
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@@ -11140,9 +12237,17 @@ sw-stream@^2.0.2:
readable-stream "^2.2.2"
through2 "^2.0.3"
+symbol-observable@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"
+
+symbol-observable@^0.2.2:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40"
+
symbol-observable@^1.0.3, symbol-observable@^1.0.4:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
symbol-tree@^3.2.2:
version "3.2.2"
@@ -11184,6 +12289,10 @@ tapable@^0.2.7, tapable@~0.2.5:
version "0.2.8"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22"
+tapable@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2"
+
tape@^4.4.0, tape@^4.5.1, tape@^4.6.0, tape@^4.6.2, tape@^4.6.3, tape@^4.8.0:
version "4.8.0"
resolved "https://registry.yarnpkg.com/tape/-/tape-4.8.0.tgz#f6a9fec41cc50a1de50fa33603ab580991f6068e"
@@ -11223,6 +12332,13 @@ tar@^2.0.0, tar@^2.2.1:
fstream "^1.0.2"
inherits "2"
+temp@^0.8.1:
+ version "0.8.3"
+ resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59"
+ dependencies:
+ os-tmpdir "^1.0.0"
+ rimraf "~2.2.6"
+
test-exclude@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26"
@@ -11277,6 +12393,10 @@ textarea-caret@^3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/textarea-caret/-/textarea-caret-3.0.2.tgz#f360c48699aa1abf718680a43a31a850665c2caf"
+textextensions@2:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.2.0.tgz#38ac676151285b658654581987a0ce1a4490d286"
+
textextensions@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-1.0.2.tgz#65486393ee1f2bb039a60cbba05b0b68bd9501d2"
@@ -11321,6 +12441,13 @@ through2@^1.0.0, through2@^1.1.1:
readable-stream ">=1.1.13-1 <1.2.0-0"
xtend ">=4.0.0 <4.1.0-0"
+through2@~0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/through2/-/through2-0.2.3.tgz#eb3284da4ea311b6cc8ace3653748a52abf25a3f"
+ dependencies:
+ readable-stream "~1.1.9"
+ xtend "~2.1.1"
+
through2@~0.4.1:
version "0.4.2"
resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b"
@@ -11357,6 +12484,10 @@ time-stamp@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3"
+timed-out@^4.0.0, timed-out@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
+
timers-browserify@^1.0.1:
version "1.4.2"
resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d"
@@ -11364,8 +12495,8 @@ timers-browserify@^1.0.1:
process "~0.11.0"
timers-browserify@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.4.tgz#96ca53f4b794a5e7c0e1bd7cc88a372298fa01e6"
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.6.tgz#241e76927d9ca05f4d959819022f5b3664b64bae"
dependencies:
setimmediate "^1.0.4"
@@ -11544,8 +12675,8 @@ type-detect@^1.0.0:
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2"
type-detect@^4.0.0, type-detect@^4.0.5:
- version "4.0.5"
- resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.5.tgz#d70e5bc81db6de2a381bcaca0c6e0cbdc7635de2"
+ version "4.0.7"
+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.7.tgz#862bd2cf6058ad92799ff5a5b8cf7b6cec726198"
type-is@~1.6.10, type-is@~1.6.15:
version "1.6.15"
@@ -11586,8 +12717,8 @@ uglify-js@^2.6, uglify-js@^2.8.27:
uglify-to-browserify "~1.0.0"
uglify-js@^3.0.5:
- version "3.3.7"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.7.tgz#28463e7c7451f89061d2b235e30925bf5625e14d"
+ version "3.3.9"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.9.tgz#33869666c8ab7f7658ce3d22f0f1ced40097d33a"
dependencies:
commander "~2.13.0"
source-map "~0.6.1"
@@ -11596,7 +12727,7 @@ uglify-to-browserify@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
-uglifyify@^4.0.2:
+uglifyify@^4.0.5:
version "4.0.5"
resolved "https://registry.yarnpkg.com/uglifyify/-/uglifyify-4.0.5.tgz#49c1fca9828c10a5a8e8d70f191a95f7ab475911"
dependencies:
@@ -11634,6 +12765,10 @@ underscore@~1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604"
+underscore@~1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8"
+
underscore@~1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
@@ -11688,6 +12823,10 @@ uniq@^1.0.0, uniq@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
+unique-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b"
+
unique-stream@^2.0.2:
version "2.2.1"
resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369"
@@ -11730,6 +12869,10 @@ unset-value@^1.0.0:
has-value "^0.3.1"
isobject "^3.0.0"
+untildify@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.2.tgz#7f1f302055b3fea0f3e81dc78eb36766cb65e3f1"
+
upath@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.4.tgz#ee2321ba0a786c50973db043a50b7bcba822361d"
@@ -11738,6 +12881,22 @@ urix@^0.1.0, urix@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
+url-parse-lax@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
+ dependencies:
+ prepend-http "^1.0.1"
+
+url-parse-lax@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
+ dependencies:
+ prepend-http "^2.0.0"
+
+url-to-options@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
+
url@^0.11.0, url@~0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@@ -11754,10 +12913,10 @@ use@^2.0.0:
lazy-cache "^2.0.2"
useragent@^2.1.12:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.1.tgz#cf593ef4f2d175875e8bb658ea92e18a4fd06d8e"
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972"
dependencies:
- lru-cache "2.2.x"
+ lru-cache "4.1.x"
tmp "0.0.x"
utf8@^2.1.1:
@@ -11794,13 +12953,17 @@ uuid@^2.0.1:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
uuid@^3.0.0, uuid@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
uws@~9.14.0:
version "9.14.0"
resolved "https://registry.yarnpkg.com/uws/-/uws-9.14.0.tgz#fac8386befc33a7a3705cbd58dc47b430ca4dd95"
+v8-compile-cache@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz#8d32e4f16974654657e676e0e467a348e89b0dc4"
+
v8flags@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.0.1.tgz#dce8fc379c17d9f2c9e9ed78d89ce00052b1b76b"
@@ -11818,6 +12981,10 @@ validate-npm-package-license@^3.0.1:
spdx-correct "~1.0.0"
spdx-expression-parse "~1.0.0"
+value-equal@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7"
+
value-or-function@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813"
@@ -11876,10 +13043,9 @@ vinyl-file@^2.0.0:
vinyl "^1.1.0"
vinyl-fs@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.1.tgz#74af5f6836a1cf414d35eeb3c10f2e65fc2a2c10"
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.2.tgz#1b86258844383f57581fcaac081fe09ef6d6d752"
dependencies:
- flush-write-stream "^1.0.0"
fs-mkdirp-stream "^1.0.0"
glob-stream "^6.1.0"
graceful-fs "^4.0.0"
@@ -11888,6 +13054,7 @@ vinyl-fs@^3.0.0:
lead "^1.0.0"
object.assign "^4.0.4"
pumpify "^1.3.5"
+ readable-stream "^2.3.3"
remove-bom-buffer "^3.0.0"
remove-bom-stream "^1.2.0"
resolve-options "^1.1.0"
@@ -11938,7 +13105,7 @@ vinyl@^1.1.0:
clone-stats "^0.0.1"
replace-ext "0.0.1"
-vinyl@^2.0.0, vinyl@^2.1.0:
+vinyl@^2.0.0, vinyl@^2.0.1, vinyl@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c"
dependencies:
@@ -11983,11 +13150,11 @@ warning@^3.0.0:
loose-envify "^1.0.0"
watchify@^3.9.0:
- version "3.9.0"
- resolved "https://registry.yarnpkg.com/watchify/-/watchify-3.9.0.tgz#f075fd2e8a86acde84cedba6e5c2a0bedd523d9e"
+ version "3.10.0"
+ resolved "https://registry.yarnpkg.com/watchify/-/watchify-3.10.0.tgz#f436605553c432d87f62f718cc78077418ffbccb"
dependencies:
anymatch "^1.3.0"
- browserify "^14.0.0"
+ browserify "^15.2.0"
chokidar "^1.0.0"
defined "^1.0.0"
outpipe "^1.1.0"
@@ -12074,8 +13241,8 @@ web3@^0.18.4:
xmlhttprequest "*"
web3@^0.20.1:
- version "0.20.3"
- resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.3.tgz#caa44373dc8815ac8767bddb6ba73073964caa8b"
+ version "0.20.4"
+ resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.4.tgz#400e6579a65bb4a3dde71a6ebf6509afadc33a04"
dependencies:
bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git"
crypto-js "^3.1.4"
@@ -12087,6 +13254,42 @@ webidl-conversions@^4.0.1, webidl-conversions@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
+webpack-addons@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/webpack-addons/-/webpack-addons-1.1.5.tgz#2b178dfe873fb6e75e40a819fa5c26e4a9bc837a"
+ dependencies:
+ jscodeshift "^0.4.0"
+
+webpack-cli@^2.0.9:
+ version "2.0.13"
+ resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-2.0.13.tgz#6e2bd9ef91345344737217e22e29001ad8537518"
+ dependencies:
+ chalk "^2.3.2"
+ cross-spawn "^6.0.5"
+ diff "^3.5.0"
+ enhanced-resolve "^4.0.0"
+ glob-all "^3.1.0"
+ global-modules "^1.0.0"
+ got "^8.2.0"
+ inquirer "^5.1.0"
+ interpret "^1.0.4"
+ jscodeshift "^0.5.0"
+ listr "^0.13.0"
+ loader-utils "^1.1.0"
+ lodash "^4.17.5"
+ log-symbols "^2.2.0"
+ mkdirp "^0.5.1"
+ p-each-series "^1.0.0"
+ p-lazy "^1.0.0"
+ prettier "^1.5.3"
+ resolve-cwd "^2.0.0"
+ supports-color "^5.3.0"
+ v8-compile-cache "^1.1.2"
+ webpack-addons "^1.1.5"
+ yargs "^11.0.0"
+ yeoman-environment "^2.0.0"
+ yeoman-generator "^2.0.3"
+
webpack-sources@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54"
@@ -12224,7 +13427,7 @@ wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
-write-file-atomic@^1.1.4:
+write-file-atomic@^1.1.4, write-file-atomic@^1.2.0:
version "1.3.4"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f"
dependencies:
@@ -12369,21 +13572,27 @@ yargs-parser@^5.0.0:
dependencies:
camelcase "^3.0.0"
-yargs-parser@^8.0.0:
+yargs-parser@^8.0.0, yargs-parser@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950"
dependencies:
camelcase "^4.1.0"
+yargs-parser@^9.0.2:
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
+ dependencies:
+ camelcase "^4.1.0"
+
yargs@^1.2.6:
version "1.3.3"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.3.3.tgz#054de8b61f22eefdb7207059eaef9d6b83fb931a"
yargs@^10.0.3:
- version "10.0.3"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae"
+ version "10.1.2"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5"
dependencies:
- cliui "^3.2.0"
+ cliui "^4.0.0"
decamelize "^1.1.1"
find-up "^2.1.0"
get-caller-file "^1.0.1"
@@ -12394,7 +13603,24 @@ yargs@^10.0.3:
string-width "^2.0.0"
which-module "^2.0.0"
y18n "^3.2.1"
- yargs-parser "^8.0.0"
+ yargs-parser "^8.1.0"
+
+yargs@^11.0.0:
+ version "11.1.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77"
+ dependencies:
+ cliui "^4.0.0"
+ decamelize "^1.1.1"
+ find-up "^2.1.0"
+ get-caller-file "^1.0.1"
+ os-locale "^2.0.0"
+ require-directory "^2.1.1"
+ require-main-filename "^1.0.1"
+ set-blocking "^2.0.0"
+ string-width "^2.0.0"
+ which-module "^2.0.0"
+ y18n "^3.2.1"
+ yargs-parser "^9.0.2"
yargs@^3.5.4:
version "3.32.0"
@@ -12493,3 +13719,51 @@ yazl@^2.1.0:
yeast@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
+
+yeoman-environment@^2.0.0, yeoman-environment@^2.0.5:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-2.0.6.tgz#ae1b21d826b363f3d637f88a7fc9ea7414cb5377"
+ dependencies:
+ chalk "^2.1.0"
+ debug "^3.1.0"
+ diff "^3.3.1"
+ escape-string-regexp "^1.0.2"
+ globby "^6.1.0"
+ grouped-queue "^0.3.3"
+ inquirer "^3.3.0"
+ is-scoped "^1.0.0"
+ lodash "^4.17.4"
+ log-symbols "^2.1.0"
+ mem-fs "^1.1.0"
+ text-table "^0.2.0"
+ untildify "^3.0.2"
+
+yeoman-generator@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-2.0.3.tgz#19426ed22687ffe05d31526c3f1c2cf67ba768f3"
+ dependencies:
+ async "^2.6.0"
+ chalk "^2.3.0"
+ cli-table "^0.3.1"
+ cross-spawn "^5.1.0"
+ dargs "^5.1.0"
+ dateformat "^3.0.2"
+ debug "^3.1.0"
+ detect-conflict "^1.0.0"
+ error "^7.0.2"
+ find-up "^2.1.0"
+ github-username "^4.0.0"
+ istextorbinary "^2.1.0"
+ lodash "^4.17.4"
+ make-dir "^1.1.0"
+ mem-fs-editor "^3.0.2"
+ minimist "^1.2.0"
+ pretty-bytes "^4.0.2"
+ read-chunk "^2.1.0"
+ read-pkg-up "^3.0.0"
+ rimraf "^2.6.2"
+ run-async "^2.0.0"
+ shelljs "^0.8.0"
+ text-table "^0.2.0"
+ through2 "^2.0.0"
+ yeoman-environment "^2.0.5"