diff --git a/CHANGELOG.md b/CHANGELOG.md index fc20d601f..b585b20d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ ## Current Develop Branch +## 9.2.0 Tue Mar 09 2021 +- [#10546](https://github.com/MetaMask/metamask-extension/pull/10546): Add a warning when sending a token to its own contract address +- [#10563](https://github.com/MetaMask/metamask-extension/pull/10563): Update references to MetaMask support +- [#10126](https://github.com/MetaMask/metamask-extension/pull/10126): Update Italian translation +- [#10591](https://github.com/MetaMask/metamask-extension/pull/10591): Fix mobile sync of ERC20 tokens +- [#10582](https://github.com/MetaMask/metamask-extension/pull/10582): Adding warnings for excessive custom gas input +- [#10601](https://github.com/MetaMask/metamask-extension/pull/10601): Fix activity title text truncation +- [#10598](https://github.com/MetaMask/metamask-extension/pull/10598): Remove 'Ethereum' from custom RPC endpoint warning +- [#10606](https://github.com/MetaMask/metamask-extension/pull/10606): Show loading screen while fetching token data for approve screen +- [#10486](https://github.com/MetaMask/metamask-extension/pull/10486): Add setting to hide zero balance tokens +- [#10505](https://github.com/MetaMask/metamask-extension/pull/10505): Add support for multiple Ledger & Trezor hardware accounts +- [#10587](https://github.com/MetaMask/metamask-extension/pull/10587): Show correct block explorer for custom RPC endpoints for built-in networks + ## 9.1.1 Wed Mar 03 2021 - [#10560](https://github.com/MetaMask/metamask-extension/pull/10560): Fix ENS resolution related crashes when switching networks on send screen - [#10561](https://github.com/MetaMask/metamask-extension/pull/10561): Fix crash when speeding up an attempt to cancel a transaction on custom networks diff --git a/app/_locales/am/messages.json b/app/_locales/am/messages.json index 9b9444dbd..a52aee23f 100644 --- a/app/_locales/am/messages.json +++ b/app/_locales/am/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "የዘር ሐረግዎን በድጋሚ መጠባበቂያ ለመያዝ ከፈለጉ፣ በቅንብሮች -> ግላዊነት ውስጥ ሊያገኙት ይችላሉ።" }, - "endOfFlowMessage7": { - "message": "ጥያቄዎች ካሉዎት ወይም የሆነ አጠራጣሪ ነገር ካዩ፣ እባክዎ ለ support@metamask.io ኢሜይል ይላኩ።" - }, "endOfFlowMessage8": { "message": "MetaMask የዘር ሐረግዎን መልሶ ማግኘት አልቻለም። ተጨማሪ መረጃ ያግኙ።" }, @@ -772,15 +769,6 @@ "privateNetwork": { "message": "የግል አውታረ መረብ" }, - "protectYourKeys": { - "message": "ቁልፎችዎን ይጠብቁ!" - }, - "protectYourKeysMessage1": { - "message": "ስለ ዘር ሐረግዎ ይጠንቀቁ - ራሳቸውን ከ MetaMask ጋር ለማመሳሰል የሚሞከሩ ድረ ገጾች እናሉ ሰምተናል። MetaMask በጭራሽ የዘር ሐረግዎን አይጠይቅዎትም!" - }, - "protectYourKeysMessage2": { - "message": "የሐረግዎን ደህንነት ይጠብቁ። ይም የሆነ አጠራጣሪ ነገር ካዩ ወይም ስለ አንድ ድረ ገጽ እርግጠኛ ካልሆኑ፣ እባክዎ ለ support@metamask.io ኢሜይል ይላኩ" - }, "queue": { "message": "ወረፋ" }, diff --git a/app/_locales/ar/messages.json b/app/_locales/ar/messages.json index cdc187925..9a04e15d8 100644 --- a/app/_locales/ar/messages.json +++ b/app/_locales/ar/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "إذا كنت بحاجة إلى عمل نسخة احتياطية من عبارة الأمان الخاصة بك مرة أخرى، يمكنك العثور عليها في الإعدادات -> الأمان." }, - "endOfFlowMessage7": { - "message": "إذا كانت لديك أسئلة أو ترى شيئاً ما مريباً، فأرسل بريداً إلكترونياً إلى support@metamask.io." - }, "endOfFlowMessage8": { "message": "لا يمكن لـ MetaMask استعادة جملتك البذرية. تعلم المزيد." }, @@ -768,15 +765,6 @@ "privateNetwork": { "message": "شبكة خاصة" }, - "protectYourKeys": { - "message": "احمِ مفاتيحك!" - }, - "protectYourKeysMessage1": { - "message": "كن حذراً بشأن عبارة الأمان الخاصة بك - فهناك بلاغات عن مواقع ويب تحاول تقليد MetaMask. لن تسأل MetaMask عن عبارة الأمان الخاصة بك أبداً!" - }, - "protectYourKeysMessage2": { - "message": "أبقِ عبارة الأمان الخاصة بك بأمان. إذا رأيت شيئاً مريباً، أو كنت غير متأكد من موقع ويب ما، أرسل بريداً إلكترونياً إلى support@metamask.io" - }, "queue": { "message": "اللائحة" }, diff --git a/app/_locales/bg/messages.json b/app/_locales/bg/messages.json index 0d5f8dfc5..26abfe956 100644 --- a/app/_locales/bg/messages.json +++ b/app/_locales/bg/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Ако отново трябва да архивирате основната си фраза, можете да я намерите в Настройки -> Защита." }, - "endOfFlowMessage7": { - "message": "Ако имате въпроси или забележите нещо съмнително, изпратете имейл на support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask не може да възстанови ключовата Ви фраза. Научете повече." }, @@ -771,15 +768,6 @@ "privateNetwork": { "message": "Частна мрежа" }, - "protectYourKeys": { - "message": "Защитете ключовете си!" - }, - "protectYourKeysMessage1": { - "message": "Внимавайте с вашата фраза - има съобщения за уебсайтове, които се опитват да имитират MetaMask. MetaMask никога няма да поиска вашата фраза-зародиш!" - }, - "protectYourKeysMessage2": { - "message": "Пазете фразата си. Ако забележите нещо съмнително или не сте сигурни за даден уебсайт, изпратете имейл на support@metamask.io" - }, "queue": { "message": "Опашка" }, diff --git a/app/_locales/bn/messages.json b/app/_locales/bn/messages.json index c01b44a0e..2ef360f19 100644 --- a/app/_locales/bn/messages.json +++ b/app/_locales/bn/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "আপনাকে আপনার সীড আবার ব্যাকআপ করতে হলে, আপনি সেটি সেটিংস -> নিরাপত্তায় পাবেন।" }, - "endOfFlowMessage7": { - "message": "আপনার কখনও কোনো প্রশ্ন থাকলে বা সন্দেহজনক কিছু দেখলে, support@metamask.io ঠিকানায় ইমেল করুন।" - }, "endOfFlowMessage8": { "message": "MetaMask আপনার সীডফ্রেজ পুনরুদ্ধার করতে পারবে না। আরও জানুন।" }, @@ -775,15 +772,6 @@ "privateNetwork": { "message": "ব্যক্তিগত নেটওয়ার্ক" }, - "protectYourKeys": { - "message": "আপনার কীগুলি সুরক্ষিত করুন!" - }, - "protectYourKeysMessage1": { - "message": "আপনার সীড ফ্রেজ বিষয়ে সাবধান থাকুন — এমন ওয়েবসাইটগুলির রিপোর্ট পাওয়া গেছে যেগুলি MetaMask কে অনুকরণ করার চেষ্টা করে। MetaMask কখনও আপনার সীড ফ্রেজ জিজ্ঞাসা করবে না।" - }, - "protectYourKeysMessage2": { - "message": "আপনার ফ্রেজটিকে নিরাপদে রাখুন।সন্দেহজনক কিছু দেখলে, বা একটি ওয়েবসাইট সম্পর্কে নিশ্চিত না হলে, support@metamask.io এ ইমেল করুন" - }, "queue": { "message": "অপেক্ষমাণ" }, diff --git a/app/_locales/ca/messages.json b/app/_locales/ca/messages.json index 3d9c73237..fda999248 100644 --- a/app/_locales/ca/messages.json +++ b/app/_locales/ca/messages.json @@ -347,9 +347,6 @@ "endOfFlowMessage6": { "message": "Si necessites fer una còpia de seguretat de la teva frase de recuperació una altra vegada, la pots trobar a Configuració-> Seguretat." }, - "endOfFlowMessage7": { - "message": "Si mai tens preguntes o veus alguna cosa sospitosa, envia un correu a support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask no pot recuperar la teva seedphrase. Descobreix per què." }, @@ -756,15 +753,6 @@ "privateNetwork": { "message": "Xarxa privada" }, - "protectYourKeys": { - "message": "Protegeix les Teves Claus!" - }, - "protectYourKeysMessage1": { - "message": "Vigila amb la teva frase de recuperació —s'han documentat casos de llocs web que intenten imitar MetaMask. MetaMask mai no et demanarà la frase de recuperació!" - }, - "protectYourKeysMessage2": { - "message": "Mantingues segura la teva frase. Si veus alguna cosa sospitosa, o no estàs segur d'un lloc web, envia un correu a support@metamask.io" - }, "queue": { "message": "Cua" }, diff --git a/app/_locales/da/messages.json b/app/_locales/da/messages.json index db9091c0a..9378cbbbd 100644 --- a/app/_locales/da/messages.json +++ b/app/_locales/da/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Hvis du får brug for at lave en backup af din seedfrase igen, kan du finde det under Indstillinger -> Sikkerhed." }, - "endOfFlowMessage7": { - "message": "Hvis du har spørgsmål eller bemærker noget mistænkeligt, send en mail til support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask kan ikke gendanne din seed-sætning. Få mere at vide." }, @@ -756,15 +753,6 @@ "privateNetwork": { "message": "Privat netværk" }, - "protectYourKeys": { - "message": "Beskyt dine nøgler!" - }, - "protectYourKeysMessage1": { - "message": "Vær forsigtig med din backupsætning - der har været rapporter om websteder, der forsøger at efterligne MetaMask. MetaMask vil aldrig bede om din backupsætning!" - }, - "protectYourKeysMessage2": { - "message": "Opbevar din frase et sikkert sted. Hvis du ser noget mistænkeligt, eller du er usikker på hjemmesiden, skriv en email til support@metamask.io" - }, "queue": { "message": "Kø" }, diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index 0ff63d570..f90cd388e 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -338,9 +338,6 @@ "endOfFlowMessage6": { "message": "Wenn Sie Ihre mnemonische Phrase erneut sicherstellen müssen, finden Sie sie unter Einstellungen -> Sicherheit." }, - "endOfFlowMessage7": { - "message": "Wenn Sie Fragen haben sollten oder etwas Suspektes bemerken, schreiben Sie eine E-Mail an support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask kann Ihren Seedschlüssel nicht wiederherstellen. Erfahren Sie mehr." }, @@ -744,15 +741,6 @@ "privateNetwork": { "message": "Privates Netzwerk" }, - "protectYourKeys": { - "message": "Schützen Sie Ihre Schlüssel!" - }, - "protectYourKeysMessage1": { - "message": "Seien Sie mit Ihrer mnemonischen Phrase vorsichtig - es gab Berichte über Websites, die MetaMask zu imitieren versuchen. MetaMask fragt nie nach Ihrer mnemonischen Phrase!" - }, - "protectYourKeysMessage2": { - "message": "Bewahren Sie Ihren Schlüssel sicher auf. Wenn etwas faul zu sein scheint oder Sie Zweifel wegen einer Website haben, schicken Sie eine E-Mail an support@metamask.io" - }, "queue": { "message": "Warteschlange" }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index ae30afdce..95df989d9 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -347,9 +347,6 @@ "endOfFlowMessage6": { "message": "Αν χρειάζεται να δημιουργήσετε ξανά αντίγραφο της φράσης επαναφοράς σας, μπορείτε να την βρείτε στη Ρυθμίσεις -> Ασφάλεια." }, - "endOfFlowMessage7": { - "message": "Εάν έχετε οποιαδήποτε ερώτηση ή αντιληφθείτε κάτι ύποπτο στείλτε μας email στο support@metamask.io." - }, "endOfFlowMessage8": { "message": "Το MetaMask δεν μπορεί να ανακτήσει τη φράση φύτρου σας. Μάθετε περισσότερα." }, @@ -772,15 +769,6 @@ "privateNetwork": { "message": "Ιδιωτικό Δίκτυο" }, - "protectYourKeys": { - "message": "Προστατεύστε τα Κλειδιά Σας!" - }, - "protectYourKeysMessage1": { - "message": "Να προσέχετε με τη φάση σπόρου. Υπάρχουν αναφορές για ιστότοπους που προσπαθούν να προσποιηθούν ότι είναι το MetaTask. Το MetaTask δεν θα σας ρωτήσει ποτέ για τη φάση σπόρου!" - }, - "protectYourKeysMessage2": { - "message": "Κρατήστε τη φράση σας ασφαλή. Αν δείτε κάτι ύποπτο ή δεν είστε βέβαιοι για έναν ιστότοπο, στείλτε ένα email στο support@metamask.io" - }, "queue": { "message": "Ουρά" }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 99789f491..b79c5b9b0 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -405,6 +405,9 @@ "continueToWyre": { "message": "Continue to Wyre" }, + "contractAddressError": { + "message": "You are sending tokens to the token's contract address. This may result in the loss of these tokens." + }, "contractDeployment": { "message": "Contract Deployment" }, @@ -607,7 +610,8 @@ "message": "If you need to back up your seed phrase again, you can find it in Settings -> Security." }, "endOfFlowMessage7": { - "message": "If you ever have questions or see something fishy, email support@metamask.io." + "message": "If you ever have questions or see something fishy, contact our support $1.", + "description": "$1 is a clickable link with text defined by the 'here' key. The link will open to a form where users can file support tickets." }, "endOfFlowMessage8": { "message": "MetaMask cannot recover your seedphrase." @@ -654,12 +658,12 @@ "description": "Displayed error name for debugging purposes. $1 is the error name" }, "errorPageMessage": { - "message": "Try again by reloading the page, or contact support at support@metamask.io", - "description": "Message displayed on generic error page in the fullscreen or notification UI" + "message": "Try again by reloading the page, or contact support $1.", + "description": "Message displayed on generic error page in the fullscreen or notification UI, $1 is a clickable link with text defined by the 'here' key. The link will open to a form where users can file support tickets." }, "errorPagePopupMessage": { - "message": "Try again by closing and reopening the popup, or contact support at support@metamask.io", - "description": "Message displayed on generic error page in the popup UI" + "message": "Try again by closing and reopening the popup, or contact support $1.", + "description": "Message displayed on generic error page in the popup UI, $1 is a clickable link with text defined by the 'here' key. The link will open to a form where users can file support tickets." }, "errorPageTitle": { "message": "MetaMask encountered an error", @@ -759,6 +763,12 @@ "gasPrice": { "message": "Gas Price (GWEI)" }, + "gasPriceExcessive": { + "message": "Your gas fee is set unnecessarily high. Consider lowering the amount." + }, + "gasPriceExcessiveInput": { + "message": "Gas Price Is Excessive" + }, "gasPriceExtremelyLow": { "message": "Gas Price Extremely Low" }, @@ -807,6 +817,10 @@ "hardwareWalletConnected": { "message": "Hardware wallet connected" }, + "hardwareWalletLegacyDescription": { + "message": "(legacy)", + "description": "Text representing the MEW path" + }, "hardwareWallets": { "message": "Connect a hardware wallet" }, @@ -833,6 +847,9 @@ "message": "Hide $1", "description": "$1 is the symbol for a token (e.g. 'DAI')" }, + "hideZeroBalanceTokens": { + "message": "Hide Tokens Without Balance" + }, "history": { "message": "History" }, @@ -1203,7 +1220,7 @@ "description": "Return the user to the site that initiated onboarding" }, "onlyAddTrustedNetworks": { - "message": "A malicious Ethereum network provider can lie about the state of the blockchain and record your network activity. Only add custom networks you trust." + "message": "A malicious network provider can lie about the state of the blockchain and record your network activity. Only add custom networks you trust." }, "onlyAvailableOnMainnet": { "message": "Only available on mainnet" @@ -1289,15 +1306,6 @@ "proposedApprovalLimit": { "message": "Proposed Approval Limit" }, - "protectYourKeys": { - "message": "Protect Your Keys!" - }, - "protectYourKeysMessage1": { - "message": "Be careful with your seed phrase — there have been reports of websites that attempt to imitate MetaMask. MetaMask will never ask for your seed phrase!" - }, - "protectYourKeysMessage2": { - "message": "Keep your phrase safe. If you see something fishy, or you’re uncertain about a website, email support@metamask.io" - }, "provide": { "message": "Provide" }, @@ -1476,6 +1484,9 @@ "selectAnAccount": { "message": "Select an Account" }, + "selectAnAccountAlreadyConnected": { + "message": "This account has already been connected to MetaMask" + }, "selectAnAccountHelp": { "message": "Select the account to view in MetaMask" }, diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 3188d5ef8..f7cb42082 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -562,9 +562,6 @@ "endOfFlowMessage6": { "message": "Si necesita hacer una copia de seguridad de su frase semilla nuevamente, puede encontrarla en Configuración -> Seguridad." }, - "endOfFlowMessage7": { - "message": "Si alguna vez tiene preguntas o ve algo sospechoso, envíe un correo electrónico a support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask no puede recuperar tu frase semilla. Saber más." }, @@ -609,14 +606,6 @@ "message": "Código: $1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "Vuelva a intentarlo recargando la página o póngase en contacto con el soporte en support@metamask.io", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "Vuelva a intentarlo cerrando y volviendo a abrir la ventana emergente, o comuníquese con el soporte en support@metamask.io", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "MetaMask encontró un error", "description": "Title of generic error page" @@ -1136,7 +1125,7 @@ "description": "Return the user to the site that initiated onboarding" }, "onlyAddTrustedNetworks": { - "message": "Un proveedor de red de Ethereum malintencionado puede mentir sobre el estado de la cadena de bloques y registrar la actividad de su red. Solo agregue redes personalizadas en las que confíe." + "message": "Un proveedor de red de malintencionado puede mentir sobre el estado de la cadena de bloques y registrar la actividad de su red. Solo agregue redes personalizadas en las que confíe." }, "onlyAvailableOnMainnet": { "message": "Solo disponible en la red principal de Ethereum (Main Net)" @@ -1222,15 +1211,6 @@ "proposedApprovalLimit": { "message": "Límite de aprobación propuesto" }, - "protectYourKeys": { - "message": "¡Proteja sus llaves!" - }, - "protectYourKeysMessage1": { - "message": "Tenga cuidado con su frase semilla — ha habido informes de sitios web que intentan imitar MetaMask. ¡MetaMask nunca le pedirá su frase semilla!" - }, - "protectYourKeysMessage2": { - "message": "Mantenga su frase a salvo. Si ve algo sospechoso o no está seguro acerca de un sitio web, envíe un correo electrónico a support@metamask.io" - }, "provide": { "message": "Proveer" }, diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index 1dccd990a..9428674bd 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -562,9 +562,6 @@ "endOfFlowMessage6": { "message": "Si necesitas otro respaldo de tu frase semilla, puedes encontrarla en Configuración -> Seguridad." }, - "endOfFlowMessage7": { - "message": "Si tienes preguntas o ves algo sospechoso, envía un correo electrónico a support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask no puede recuperar tu frase semilla. Obtén más información." }, @@ -609,14 +606,6 @@ "message": "Código: $1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "Vuelva a intentarlo recargando la página o póngase en contacto con el soporte en support@metamask.io", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "Vuelva a intentarlo cerrando y volviendo a abrir la ventana emergente, o comuníquese con el soporte en support@metamask.io", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "MetaMask encontró un error", "description": "Title of generic error page" @@ -1136,7 +1125,7 @@ "description": "Return the user to the site that initiated onboarding" }, "onlyAddTrustedNetworks": { - "message": "Un proveedor de red de Ethereum malintencionado puede mentir sobre el estado de la cadena de bloques y registrar la actividad de su red. Solo agregue redes personalizadas en las que confíe." + "message": "Un proveedor de red de malintencionado puede mentir sobre el estado de la cadena de bloques y registrar la actividad de su red. Solo agregue redes personalizadas en las que confíe." }, "onlyAvailableOnMainnet": { "message": "Solo disponible en la red principal de Ethereum (Main Net)" @@ -1222,15 +1211,6 @@ "proposedApprovalLimit": { "message": "Límite de aprobación propuesto" }, - "protectYourKeys": { - "message": "¡Protege tus claves!" - }, - "protectYourKeysMessage1": { - "message": "Ten cuidado con tu frase semilla — hay informes sobre sitios web que intentan hacerse pasar por MetaMask. ¡MetaMask no te pedirá nunca tu frase semilla!" - }, - "protectYourKeysMessage2": { - "message": "Mantén tu frase segura. Si notas algo raro o si no está seguro sobre si usar algún sitio web en específico, envíanos un correo electrónico a support@metamask.io" - }, "provide": { "message": "Proveer" }, diff --git a/app/_locales/et/messages.json b/app/_locales/et/messages.json index 8064a0e0c..e2cfe7aa3 100644 --- a/app/_locales/et/messages.json +++ b/app/_locales/et/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Kui peate oma seemnefraasi uuesti varundama, leiate selle valikust Settings (Seaded) -> Security (Turvalisus)." }, - "endOfFlowMessage7": { - "message": "Kui teil on küsimusi või näete midagi kahtlast, kirjutage meile support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask ei saa teie seemnefraasi taastada. Lisateave." }, @@ -765,15 +762,6 @@ "privateNetwork": { "message": "Privaatvõrk" }, - "protectYourKeys": { - "message": "Kaitske oma võtmeid!" - }, - "protectYourKeysMessage1": { - "message": "Kaitske oma seemnefraasi. Meid on teavitatud veebilehtedest, mis püüavad MetaMaski jäljendada. MetaMask ei küsi teilt kunagi teie seemnefraasi!" - }, - "protectYourKeysMessage2": { - "message": "Kaitske oma seemnefraasi. Kui näete midagi kahtlast või pole veebilehe ehtsuses kindel, saatke e-kiri aadressile support@metamask.io" - }, "queue": { "message": "Järjekord" }, diff --git a/app/_locales/fa/messages.json b/app/_locales/fa/messages.json index da5872eee..b8bffe956 100644 --- a/app/_locales/fa/messages.json +++ b/app/_locales/fa/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "در صورتیکه شما نیاز به گرفتن دوباره پشتیبان عبارت بازیاب داشته باشید، میتوانید آنرا در Settings -> Security دریافت نمایید." }, - "endOfFlowMessage7": { - "message": "در صورتیکه پرسشی داشته یا چیزی مشکوک را میبینید، به support@metamask.io ایمیل کنید." - }, "endOfFlowMessage8": { "message": "MetaMask نمیتواند عبارت بازیاب تان را دوباره دریافت نماید.\nبیشتر بدانید." }, @@ -775,15 +772,6 @@ "privateNetwork": { "message": "شبکه شخصی" }, - "protectYourKeys": { - "message": "کلید های خود را حفظ کنید!" - }, - "protectYourKeysMessage1": { - "message": "مراقب عبارت بازیاب تان باشید - گفته هایی وجود دارد که وبسایت ها تلاش میکنند تا از MetaMask نسخه برداری کنند. MetaMask هرگز از شما عبارت بازیاب را نمیپرسد!" - }, - "protectYourKeysMessage2": { - "message": "عبارت تان را مصؤن نگهدارید. در صورت مشاهده چیز مشکوک، یا در صورتیکه در مورد یک وبسایت مطمئن نیستید، به support@metamask.io ایمیل کنید" - }, "queue": { "message": "صف" }, diff --git a/app/_locales/fi/messages.json b/app/_locales/fi/messages.json index 97ec89982..fa5bd1125 100644 --- a/app/_locales/fi/messages.json +++ b/app/_locales/fi/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Jos tarvitse uuden varmuuskopion juurilauseestasi, niin se löytyy osiosta Asetukset -> Turvallisuus." }, - "endOfFlowMessage7": { - "message": "Jos sinulla on joskus jotakin kysyttävää tai jos näet jotakin epäilyttävää, lähetä sähköpostia osoitteeseen support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask ei pysty palauttamaan salaustekstiäsi. Lue lisää." }, @@ -772,15 +769,6 @@ "privateNetwork": { "message": "Yksityinen verkko" }, - "protectYourKeys": { - "message": "Suojele avaimiasi!" - }, - "protectYourKeysMessage1": { - "message": "Ole varovainen salausavaimesi kanssa – joidenkin verkkosivustojen kerrotaan yrittäneen matkia MetaMaskia. MetaMask ei koskaan kysy salausavaintasi!" - }, - "protectYourKeysMessage2": { - "message": "Pidä lauseesi tallessa. Jos näet jotain epäilyttävää tai et ole varma jostain sivustosta, lähetä sähköpostia osoitteeseen support@metamask.io" - }, "queue": { "message": "Jono" }, diff --git a/app/_locales/fil/messages.json b/app/_locales/fil/messages.json index 09f8c2bc4..473331a30 100644 --- a/app/_locales/fil/messages.json +++ b/app/_locales/fil/messages.json @@ -326,9 +326,6 @@ "endOfFlowMessage6": { "message": "Kung kailangan mong i-back up ulit ang iyong seed phrase, makikita mo ito sa Mga Setting -> Seguridad." }, - "endOfFlowMessage7": { - "message": "Kung may mga tanong ka o nakakita ka ng kahina-hinalang bagay, i-email ang support@metamask.io." - }, "endOfFlowMessage8": { "message": "Hindi ma-recover ng MetaMask ang iyong seedphrase. Alamin pa." }, @@ -699,15 +696,6 @@ "privateNetwork": { "message": "Pribadong Network" }, - "protectYourKeys": { - "message": "Protektahan Ang Iyong Mga Key!" - }, - "protectYourKeysMessage1": { - "message": "Mag-ingat sa iyong seed phrase — may mga ulat na may mga website na nagpapanggap bilang MetaMask. Hindi kailanman hihilingin ng MetaMask ang iyong seed phrase!" - }, - "protectYourKeysMessage2": { - "message": "Panatilihing ligtas ang iyong parirala. Kung may makikita kang kahina-hinala, o hindi ka sigurado tungkol sa isang website, mag-email sa support@metamask.io" - }, "queue": { "message": "I-queue" }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index 22a15af1c..39d44fb72 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -341,9 +341,6 @@ "endOfFlowMessage6": { "message": "Si vous avez besoin de sauvegarder à nouveau votre phrase de départ, vous pouvez la trouver dans Paramètres -> Sécurité." }, - "endOfFlowMessage7": { - "message": "Si vous avez des questions ou remarquez quelque chose de suspect, envoyez un e-mail à : support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask ne peut pas récupérer votre phrase de départ. Renseignez-vous davantage." }, @@ -757,15 +754,6 @@ "privateNetwork": { "message": "Réseau privé" }, - "protectYourKeys": { - "message": "Protégez vos clés !" - }, - "protectYourKeysMessage1": { - "message": "Soyez prudent avec votre phrase mnémotechnique — on nous a signalé des sites web qui tentaient d'imiter MetaMask. MetaMask ne vous demandera jamais votre phrase mnémotechnique !" - }, - "protectYourKeysMessage2": { - "message": "Ne dévoilez pas votre phrase. Si vous remarquez quelque chose de suspect ou que vous avez un doute à propos d'un site web, envoyez un e-mail à : support@metamask.io" - }, "queue": { "message": "File d'attente" }, diff --git a/app/_locales/he/messages.json b/app/_locales/he/messages.json index d5e148bf8..9b426ea16 100644 --- a/app/_locales/he/messages.json +++ b/app/_locales/he/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "אם עליך לגבות את צירוף הגרעין שלך שוב, תוכל/י למצוא זאת בהגדרות -> אבטחה." }, - "endOfFlowMessage7": { - "message": "אם יש לך שאלות או שנתקלת במשהו חשוד, שלח/י מייל ל- support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask לא הצליח לשחזר את ה-seedphrase שלך. למד/י עוד." }, @@ -772,15 +769,6 @@ "privateNetwork": { "message": "רשת פרטית" }, - "protectYourKeys": { - "message": "הגנ/י על המפתחות שלך!" - }, - "protectYourKeysMessage1": { - "message": "יש לנקוט זהירות בנוגע לצירוף הגרעין שלך - היו דיווחים על אתרים שמנסים להתחזות ל-MetaMask .MetaMask לעולם לא תבקש את צירוף הגרעין שלך!" - }, - "protectYourKeysMessage2": { - "message": "יש לשמור את ה-seedphrase שלך במקום בטוח. אם את/ה רואה משהו חשוד, או שאינך בטוח/ה בנוע לאתר, שלח/י אימייל לכתובת support@metamask.io" - }, "queue": { "message": "תור" }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index 5eb356e15..8feb56e55 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -553,9 +553,6 @@ "endOfFlowMessage6": { "message": "यदि आपको अपने सीड फ्रेज़ को फिर से बैकअप लेने की आवश्यकता है, तो आप इसे सेटिंग्स -> सुरक्षा में पा सकते हैं।" }, - "endOfFlowMessage7": { - "message": "यदि आपको कभी कुछ पूछना हो या कुछ गड़बड़ लगे, तो support@metamask.io पर ईमेल करें।" - }, "endOfFlowMessage8": { "message": "MetaMask आपके सीडफ्रेज़ को पुनर्प्राप्त नहीं कर सकता है।" }, @@ -600,14 +597,6 @@ "message": "कोड: $1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "पृष्ठ को पुनः लोड करके पुनः प्रयास करें या support@metamask.io पर सहायता से संपर्क करें", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "पॉपअप को बंद करके और फिर से खोलने की कोशिश करें या support@metamask.io पर सहायता से संपर्क करें", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "MetaMask में कोई त्रुटि हुई", "description": "Title of generic error page" @@ -1213,15 +1202,6 @@ "proposedApprovalLimit": { "message": "प्रस्तावित अनुमोदन सीमा" }, - "protectYourKeys": { - "message": "अपनी कुंजियों को सुरक्षित रखें!" - }, - "protectYourKeysMessage1": { - "message": "अपने सीडफ्रेज़ को लेकर सावधान रहें — ऐसी वेबसाइटों की रिपोर्टें आई हैं, जो MetaMask की नकल करने का प्रयास करती हैं। MetaMask कभी भी आपके सीड फ्रेज़ के बारे में नहीं पूछेगा!" - }, - "protectYourKeysMessage2": { - "message": "अपने वाक्यांश को सुरक्षित रखें। यदि आपको कुछ गड़बड़ लगे या आप किसी वेबसाइट के बारे में अनिश्चित हैं, तो support@metamask.io पर ईमेल करें" - }, "provide": { "message": "प्रदान करें" }, diff --git a/app/_locales/hr/messages.json b/app/_locales/hr/messages.json index 9ffa140c1..17c35b6b7 100644 --- a/app/_locales/hr/messages.json +++ b/app/_locales/hr/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Ako trebate ponovno sigurnosno kopirati svoju početnu rečenicu, možete je pronaći unutar stavke Postavke --> Sigurnost." }, - "endOfFlowMessage7": { - "message": "Ako imate bilo kakvo pitanje ili vidite nešto što vam se čini sumnjivim, pošaljite nam elektroničku poruku na support@metamask.io." - }, "endOfFlowMessage8": { "message": "Osoblje MetaMask ne može obnoviti vašu početnu rečenicu. Saznajte više." }, @@ -768,15 +765,6 @@ "privateNetwork": { "message": "Privatna mreža" }, - "protectYourKeys": { - "message": "Zaštitite svoje ključeve!" - }, - "protectYourKeysMessage1": { - "message": "Pazite na svoju početnu rečenicu jer smo zaprimili prijave o postojanju mrežnih mjesta koja oponašaju mrežno mjesto usluge MetaMask. Na mrežnom se mjestu MetaMask nikada ne traži vaša početna rečenica!" - }, - "protectYourKeysMessage2": { - "message": "Zaštite svoju rečenicu. Ako vam se nešto čini sumnjivim ili nemate povjerenja u mrežno mjesto, pošaljite nam elektroničku poruku na support@metamask.io" - }, "queue": { "message": "Red čekanja" }, diff --git a/app/_locales/hu/messages.json b/app/_locales/hu/messages.json index 3d41627db..ce8df8e5d 100644 --- a/app/_locales/hu/messages.json +++ b/app/_locales/hu/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Ha ismét biztonsági másolatot kell készítenie a seed mondatról, megtalálja azt a Beállítások -> Biztonság menüben." }, - "endOfFlowMessage7": { - "message": "Ha bármilyen kérdése van, vagy valami gyanús dolgot tapasztal, írjon a support@metamask.io címre." - }, "endOfFlowMessage8": { "message": "A MetaMask nem tudta helyreállítani a seed mondatot. Tudjon meg többet." }, @@ -768,15 +765,6 @@ "privateNetwork": { "message": "Magánhálózat" }, - "protectYourKeys": { - "message": "Védje kulcsait!" - }, - "protectYourKeysMessage1": { - "message": "Vigyázzod a gyarapítási fázissal - olyan oldalakat jelentettek, amelyek a MetaMask-ot utánozzák. A MetaMask soha nem kéri el a gyarapítási fázisát." - }, - "protectYourKeysMessage2": { - "message": "Őrizze biztonságos helyen a mondatot. Ha bármilyen gyanús dolgot tapasztal, vagy bizonytalan egy weboldalt illetően, írjon a support@metamask.io címre." - }, "queue": { "message": "Nyomtatólista" }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 480e63e20..67f7d4470 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -553,9 +553,6 @@ "endOfFlowMessage6": { "message": "Jika Anda perlu mencadangkan frasa pemulihan lagi, Anda dapat menemukannya di Pengaturan -> Keamanan." }, - "endOfFlowMessage7": { - "message": "Jika Anda memiliki pertanyaan atau melihat sesuatu yang mencurigakan hubungi lewat email ke support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask tidak dapat memulihkan frasa pemulihan Anda." }, @@ -600,14 +597,6 @@ "message": "Kode: $1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "Coba lagi dengan memuat kembali halaman, atau hubungi dukungan di support@metamask.io", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "Coba lagi dengan menutup dan membuka kembali popup, atau hubungi dukungan di support@metamask.io", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "MetaMask menemukan kesalahan", "description": "Title of generic error page" @@ -1127,7 +1116,7 @@ "description": "Return the user to the site that initiated onboarding" }, "onlyAddTrustedNetworks": { - "message": "Penyedia jaringan Ethereum jahat dapat berbohong tentang status blockchain dan merekam aktivitas jaringan Anda. Hanya tambahkan jaringan kustom yang Anda percayai." + "message": "Penyedia jaringan jahat dapat berbohong tentang status blockchain dan merekam aktivitas jaringan Anda. Hanya tambahkan jaringan kustom yang Anda percayai." }, "onlyAvailableOnMainnet": { "message": "Hanya tersedia di mainnet" @@ -1213,15 +1202,6 @@ "proposedApprovalLimit": { "message": "Batas Persetujuan yang Diajukan" }, - "protectYourKeys": { - "message": "Lindungi Kunci Anda!" - }, - "protectYourKeysMessage1": { - "message": "Berhati-hatilah dengan frasa pemulihan Anda — ada laporan dari beberapa situs web yang mencoba membuat MetaMask imitasi. MetaMask tidak pernah meminta frasa pemulihan Anda!" - }, - "protectYourKeysMessage2": { - "message": "Jaga frasa Anda tetap aman. Jika Anda melihat sesuatu yang mencurigakan, atau tidak yakin dengan satu situs web, hubungi lewat email di support@metamask.io" - }, "provide": { "message": "Berikan" }, diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index f1d13d7c8..c497ee342 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -43,6 +43,9 @@ "activityLog": { "message": "log attività" }, + "addAccount": { + "message": "Aggiungi un account" + }, "addAcquiredTokens": { "message": "Aggiungi i token che hai acquistato usando MetaMask" }, @@ -82,6 +85,9 @@ "affirmAgree": { "message": "Acconsento" }, + "aggregatorFeeCost": { + "message": "Tassa per la rete aggregatore" + }, "alertDisableTooltip": { "message": "Può essere cambiato in \"Impostazioni > Avvisi\"" }, @@ -91,6 +97,12 @@ "alertSettingsUnconnectedAccountDescription": { "message": "Questo avviso è mostrato nel popup quando stai visitando un sito Web3, ma l'account selezionato non è connesso al sito." }, + "alertSettingsWeb3ShimUsage": { + "message": "Quando un sito prova a usare la API window.web3 rimossa" + }, + "alertSettingsWeb3ShimUsageDescription": { + "message": "L'avviso che viene mostrato nel popup quando stai visitando un sito che prova a usare la API window.web3 rimossa e che potrebbe non funzionare." + }, "alerts": { "message": "Avvisi" }, @@ -114,6 +126,10 @@ "amount": { "message": "Importo" }, + "amountInEth": { + "message": "$1 ETH", + "description": "Displays an eth amount to the user. $1 is a decimal number" + }, "amountWithColon": { "message": "Importo:" }, @@ -125,6 +141,12 @@ "message": "MetaMask", "description": "The name of the application" }, + "approvalAndAggregatorTxFeeCost": { + "message": "Tassa di approvazione per la rete aggregatore" + }, + "approvalTxGasCost": { + "message": "Costo Gas Approvazione Tx" + }, "approve": { "message": "Approva" }, @@ -217,6 +239,9 @@ "bytes": { "message": "Bytes" }, + "canToggleInSettings": { + "message": "Puoi riabilitare questa notifica in Impostazioni -> Avvisi." + }, "cancel": { "message": "Annulla" }, @@ -227,7 +252,7 @@ "message": "Annullata" }, "chainId": { - "message": "Blockchain ID" + "message": "Chain ID" }, "chromeRequiredForHardwareWallets": { "message": "Devi usare MetaMask con Google Chrome per connettere il tuo Portafoglio Hardware" @@ -339,6 +364,9 @@ "contactsSettingsDescription": { "message": "Aggiungi, modifica, rimuovi e gestisci i tuoi contatti" }, + "continue": { + "message": "Continua" + }, "continueToWyre": { "message": "Continua su Wyre" }, @@ -537,15 +565,16 @@ "endOfFlowMessage6": { "message": "Se vorrai fare nuovamente un backup della frase, la puoi trovare in Impostazioni -> Sicurezza & Privacy." }, - "endOfFlowMessage7": { - "message": "Se hai delle domande o vedi delle attività sospette, manda una mail a support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask non può recuperare la tua frase seed. Impara di più." }, "endOfFlowMessage9": { "message": "Scopri di più." }, + "endpointReturnedDifferentChainId": { + "message": "L'endpoint ha restituito un chain ID diverso: $1", + "description": "$1 is the return value of eth_chainId from an RPC endpoint" + }, "ensNotFoundOnCurrentNetwork": { "message": "Nome ENS non trovato sulla rete attuale. Prova a passare alla rete principale di Ethereum." }, @@ -580,14 +609,6 @@ "message": "Codice: $1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "Prova di nuovo ricaricando la pagina, o contatta il supporto a support@metamask.io (inglese)", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "Prova a chiudere e riaprire il popup, o contatta il supporto a support@metamask.io (inglese)", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "MetaMask ha riscontrato un errore", "description": "Title of generic error page" @@ -606,6 +627,9 @@ "ethereumPublicAddress": { "message": "Indirizzo pubblico Ethereum " }, + "etherscan": { + "message": "Etherscan" + }, "etherscanView": { "message": "Vedi account su Etherscan" }, @@ -618,15 +642,25 @@ "externalExtension": { "message": "Estensione Esterna" }, + "extraApprovalGas": { + "message": "+$1 gas approvazione", + "description": "Expresses an additional gas amount the user will have to pay, on top of some other displayed amount. $1 is a decimal amount of gas" + }, "failed": { "message": "Fallita" }, + "failedToFetchChainId": { + "message": "Non è stato possibile ottenere il chain ID. L'URL RPC è corretto?" + }, "failureMessage": { "message": "Qualcosa è andato storto e non è possibile completare l'azione" }, "fast": { "message": "Veloce" }, + "fastest": { + "message": "Più veloce" + }, "feeAssociatedRequest": { "message": "Una tassa è associata a questa richiesta." }, @@ -666,6 +700,10 @@ "gasLimitTooLow": { "message": "Il Gas Limite deve essere almeno 21000" }, + "gasLimitTooLowWithDynamicFee": { + "message": "Il gas limite deve essere almeno $1", + "description": "$1 is the custom gas limit, in decimal." + }, "gasPrice": { "message": "Prezzo del Gas (GWEI)" }, @@ -799,9 +837,38 @@ "invalidBlockExplorerURL": { "message": "URI Block Explorer invalido" }, + "invalidChainIdTooBig": { + "message": "Chain ID non valido. Il chain ID è troppo grande." + }, + "invalidCustomNetworkAlertContent1": { + "message": "Il chain ID per la rete personalizzata '$1' deve essere reinserito.", + "description": "$1 is the name/identifier of the network." + }, + "invalidCustomNetworkAlertContent2": { + "message": "Per proteggerti da fornitori di rete maligni o non funzionanti, i chain ID sono ora richiesti per tutte le reti personalizzate." + }, + "invalidCustomNetworkAlertContent3": { + "message": "Vai in Impostazioni > Reti e inserisci il chain ID. Puoi trovare i chain ID più popolari su $1.", + "description": "$1 is a link to https://chainid.network" + }, + "invalidCustomNetworkAlertTitle": { + "message": "Rete Personalizzata non Valida" + }, + "invalidHexNumber": { + "message": "Numero esadecimale non valido." + }, + "invalidHexNumberLeadingZeros": { + "message": "Numero esadecimale non valido. Rimuovi gli zero iniziali." + }, "invalidIpfsGateway": { "message": "Portale IPFS non valido: il valore deve essere un URL valido" }, + "invalidNumber": { + "message": "Numero non valido. Inserisci un numero intero o un numero esadecimale con prefisso '0x'." + }, + "invalidNumberLeadingZeros": { + "message": "Numero non valido. Rimuovi gli zero iniziali." + }, "invalidRPC": { "message": "URI RPC invalido" }, @@ -890,9 +957,43 @@ "metamaskDescription": { "message": "MetaMask è una cassaforte sicura per identità su Ethereum." }, + "metamaskSwapsOfflineDescription": { + "message": "MetaMask Swaps è in manutenzione. Prova più tardi." + }, "metamaskVersion": { "message": "versione di MetaMask" }, + "metametricsCommitmentsAllowOptOut": { + "message": "Ti consentirà sempre di rimuovere il consenso tramite Impostazioni" + }, + "metametricsCommitmentsBoldNever": { + "message": "Non", + "description": "This string is localized separately from some of the commitments so that we can bold it" + }, + "metametricsCommitmentsIntro": { + "message": "MetaMask.." + }, + "metametricsCommitmentsNeverCollectIP": { + "message": "$1 raccoglierà il tuo indirizzo IP completo", + "description": "The $1 is the bolded word 'Never', from 'metametricsCommitmentsBoldNever'" + }, + "metametricsCommitmentsNeverCollectKeysEtc": { + "message": "$1 raccoglierà chiavi, indirizzi, transazioni, bilanci, hash, o qualsiasi altra informazione personale", + "description": "The $1 is the bolded word 'Never', from 'metametricsCommitmentsBoldNever'" + }, + "metametricsCommitmentsNeverSellDataForProfit": { + "message": "$1 venderà i tuoi dati per profitto. Mai!", + "description": "The $1 is the bolded word 'Never', from 'metametricsCommitmentsBoldNever'" + }, + "metametricsCommitmentsSendAnonymizedEvents": { + "message": "Invierà click e visualizzazioni di pagina in modo anonimo" + }, + "metametricsHelpImproveMetaMask": { + "message": "Aiutaci a Migliorare MetaMask" + }, + "metametricsOptInDescription": { + "message": "MetaMask vorrebbe raccogliere dati di utilizzo per capire meglio come gli utenti interagiscono con l'estensione. Questi dati verranno usati continuamente per migliorare l'usabilità e l'esperienza utente dei nostri prodotti e dell'ecosistema Ethereum." + }, "mobileSyncText": { "message": "Per favore inserisci la password per confermare che sei te!" }, @@ -921,6 +1022,9 @@ "networkName": { "message": "Nome Rete" }, + "networkSettingsChainIdDescription": { + "message": "Il chain ID è usato per firmare le transazioni. Deve essere uguale al chain ID restituito dalla rete. Puoi inserire un numero intero o un numero esadecimale con prefisso '0x', ma mostreremo sempre un numero intero." + }, "networkSettingsDescription": { "message": "Aggiungi e modifica reti RPC personalizzate" }, @@ -1013,6 +1117,9 @@ "off": { "message": "Off" }, + "offlineForMaintenance": { + "message": "Offline per manutenzione" + }, "ok": { "message": "Ok" }, @@ -1024,7 +1131,10 @@ "description": "Return the user to the site that initiated onboarding" }, "onlyAddTrustedNetworks": { - "message": "Una rete Ethereum malevola può mentire sullo stato della blockchain e registrare le tue azioni. Aggiungi solo reti fidate." + "message": "Una rete malevola può mentire sullo stato della blockchain e registrare le tue azioni. Aggiungi solo reti fidate." + }, + "onlyAvailableOnMainnet": { + "message": "Disponibile solo nella rete principale" }, "onlyConnectTrust": { "message": "Connettiti solo con siti di cui ti fidi." @@ -1107,15 +1217,6 @@ "proposedApprovalLimit": { "message": "Limite di Approvazione Proposto" }, - "protectYourKeys": { - "message": "Proteggi le tue chiavi!" - }, - "protectYourKeysMessage1": { - "message": "Stai attento con la tua frase seed - ci sono stati report di siti web che hanno tentato di imitare MetaMask. MetaMask non ti chiederà mai la tua frase seed!" - }, - "protectYourKeysMessage2": { - "message": "Tieni la tua frase al sicuro. Se vedi qualcosa di sospetto, o non sei sicuro di un sito web, manda una mail a support@metamask.io" - }, "provide": { "message": "Fornisci" }, @@ -1240,6 +1341,9 @@ "scanQrCode": { "message": "Scansiona Codice QR" }, + "scrollDown": { + "message": "Scorri verso il basso" + }, "search": { "message": "Cerca" }, @@ -1400,6 +1504,12 @@ "speedUpTransaction": { "message": "Accelera questa transazione" }, + "spendLimitAmount": { + "message": "Limite di spesa" + }, + "spendLimitInsufficient": { + "message": "Limite di spesa insufficiente" + }, "spendLimitInvalid": { "message": "Limite di spesa non valido; deve essere un numero positivo" }, @@ -1461,6 +1571,300 @@ "supportCenter": { "message": "Visita il nostro Centro di Supporto" }, + "swap": { + "message": "Scambia" + }, + "swapAdvancedSlippageInfo": { + "message": "Si chiama “slippage” la differenza tra il prezzo quando il tuo ordine viene inserito e quando viene confermato. Lo scambio sarà annullato automaticamente se lo slippage supera il “massimo slippage” impostato." + }, + "swapAggregator": { + "message": "Aggregatore" + }, + "swapAmountReceived": { + "message": "Importo garantito" + }, + "swapAmountReceivedInfo": { + "message": "Questo è l'importo minimo che riceverai. Potresti ricevere di più a seconda dello slippage." + }, + "swapApproval": { + "message": "Approva $1 per gli scambi", + "description": "Used in the transaction display list to describe a transaction that is an approve call on a token that is to be swapped.. $1 is the symbol of a token that has been approved." + }, + "swapApproveNeedMoreTokens": { + "message": "Devi avere $1 $2 in più per completare lo scambio", + "description": "Tells the user how many more of a given token they need for a specific swap. $1 is an amount of tokens and $2 is the token symbol." + }, + "swapBetterQuoteAvailable": { + "message": "È disponibile una quotazione migliore" + }, + "swapBuildQuotePlaceHolderText": { + "message": "Non ci sono token disponibile con questo nome $1", + "description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text" + }, + "swapCheckingQuote": { + "message": "Verificando $1", + "description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap." + }, + "swapCustom": { + "message": "personalizza" + }, + "swapDecentralizedExchange": { + "message": "Sito di scambio decentralizzato" + }, + "swapEditLimit": { + "message": "Modifica limite" + }, + "swapEnableDescription": { + "message": "Questo è richiesto e darà a MetaMask il permesso di scambiare $1.", + "description": "Gives the user info about the required approval transaction for swaps. $1 will be the symbol of a token being approved for swaps." + }, + "swapEstimatedNetworkFee": { + "message": "Tassa di rete stimata" + }, + "swapEstimatedNetworkFeeSummary": { + "message": "La “$1” è ciò che ci aspettiamo possa essere la tassa reale. L'importo esatto dipende dalle condizioni della rete.", + "description": "$1 will be the translation of swapEstimatedNetworkFee, with the font bolded" + }, + "swapEstimatedNetworkFees": { + "message": "Tasse di rete stimate" + }, + "swapEstimatedNetworkFeesInfo": { + "message": "Questa è una stima della tassa di rete che verrà pagata per completare lo scambio. L'importo reale può cambiare a seconda della condizione della rete." + }, + "swapFailedErrorTitle": { + "message": "Scambio fallito" + }, + "swapFetchingQuotesErrorDescription": { + "message": "Hmmm... qualcosa è andato storto. Prova di nuovo, o se l'errore persiste, contatta il supporto." + }, + "swapFetchingQuotesErrorTitle": { + "message": "Errore recuperando le quotazioni" + }, + "swapFetchingTokens": { + "message": "Recuperando i token..." + }, + "swapFinalizing": { + "message": "Finalizzando..." + }, + "swapHighSlippageWarning": { + "message": "L'importo di slippage è molto alto. Assicurati di sapere cosa stai facendo!" + }, + "swapIntroLearnMoreHeader": { + "message": "Vuoi sapere di più?" + }, + "swapIntroLearnMoreLink": { + "message": "Scopri di più su MetaMask Swaps" + }, + "swapIntroLiquiditySourcesLabel": { + "message": "Sorgenti di liquidità incluse:" + }, + "swapIntroPopupSubTitle": { + "message": "Adesso puoi scambiare token direttamente dal tuo portafgolio MetaMask. MetaMask Swaps combina vari siti di scambio decentralizzati, aggregatori e market maker professionisti per assicurare che gli utenti di MetaMask ottengano sempre il miglior prezzo con le tasse di rete minori." + }, + "swapIntroPopupTitle": { + "message": "Lo scambio di token è qui!" + }, + "swapLearnMoreContractsAuditReview": { + "message": "Esamina l'audit ufficiale dei nostri smart contracts" + }, + "swapLowSlippageError": { + "message": "La transazione può fallire, il massimo slippage è troppo basso." + }, + "swapMaxNetworkFeeInfo": { + "message": "“$1” è il massimo che spenderai. Quando la rete è volatile può essere un importo alto.", + "description": "$1 will be the translation of swapMaxNetworkFees, with the font bolded" + }, + "swapMaxNetworkFees": { + "message": "Tassa di rete massima" + }, + "swapMaxSlippage": { + "message": "Slippage massimo" + }, + "swapMetaMaskFee": { + "message": "Tassa MetaMask" + }, + "swapMetaMaskFeeDescription": { + "message": "Troviamo i migliori prezzi dalle sorgenti di liquidità migliori, sempre. Una tassa del $1% è automaticamente aggiunta ad ogni quotazione, ciò serve a supportare lo sviluppo in modo da rendere MetaMask sempre migliore.", + "description": "Provides information about the fee that metamask takes for swaps. $1 is a decimal number." + }, + "swapNQuotes": { + "message": "$1 quotazioni", + "description": "$1 is the number of quotes that the user can select from when opening the list of quotes on the 'view quote' screen" + }, + "swapNetworkFeeSummary": { + "message": "La tassa di rete copre il costo di processamento dello scambio e della memorizzazione nella rete Ethereum. MetaMask non trae profitto da questa tassa." + }, + "swapNewQuoteIn": { + "message": "Nuove quotazioni in $1", + "description": "Tells the user the amount of time until the currently displayed quotes are update. $1 is a time that is counting down from 1:00 to 0:00" + }, + "swapOnceTransactionHasProcess": { + "message": "I tuoi $1 saranno aggiunti al tuo account quando la transazione sarà processata.", + "description": "This message communicates the token that is being transferred. It is shown on the awaiting swap screen. The $1 will be a token symbol." + }, + "swapPriceDifference": { + "message": "Stai per scambiare $1 $2 (~$3) per $4 $5 (~$6).", + "description": "This message represents the price slippage for the swap. $1 and $4 are a number (ex: 2.89), $2 and $5 are symbols (ex: ETH), and $3 and $6 are fiat currency amounts." + }, + "swapPriceDifferenceAcknowledgement": { + "message": "Sono consapevole" + }, + "swapPriceDifferenceTitle": { + "message": "Differenza di prezzo di circa ~$1%", + "description": "$1 is a number (ex: 1.23) that represents the price difference." + }, + "swapPriceDifferenceTooltip": { + "message": "La differenza tra i prezzi del mercato può essere influenzata da commissioni prelevate da intermediari, dimensione del mercato, dimensione dello scambio, o inefficienze del mercato." + }, + "swapPriceDifferenceUnavailable": { + "message": "Il prezzo di mercato non è disponibile. Assicurati di sentirti a tuo agio con l'importo restituito prima di procedere." + }, + "swapProcessing": { + "message": "In elaborazione" + }, + "swapQuoteDetails": { + "message": "Dettagli quotazione" + }, + "swapQuoteDetailsSlippageInfo": { + "message": "Si chiama \"slippage\" la differenza tra il prezzo quando il tuo ordine viene inserito e quando viene confermato. Lo scambio sarà annullato automaticamente se lo slippage supera il \"massimo slippage\" impostato." + }, + "swapQuoteIncludesRate": { + "message": "La quotazione include la tassa del $1% di MetaMask", + "description": "Provides information about the fee that metamask takes for swaps. $1 is a decimal number." + }, + "swapQuoteNofN": { + "message": "Quotazione $1 di $2", + "description": "A count of loaded quotes shown to the user while they are waiting for quotes to be fetched. $1 is the number of quotes already loaded, and $2 is the total number of quotes to load." + }, + "swapQuoteSource": { + "message": "Sorgente della quota" + }, + "swapQuotesAreRefreshed": { + "message": "Le quotazioni sono aggiornate spesso per riflettere le condizioni di mercato correnti." + }, + "swapQuotesExpiredErrorDescription": { + "message": "Richiedi nuove quotazioni per ottenere le ultime tariffe." + }, + "swapQuotesExpiredErrorTitle": { + "message": "Timeout quotazioni" + }, + "swapQuotesNotAvailableErrorDescription": { + "message": "Prova ad aggiustare l'importo o le impostazioni dello slippage e prova di nuovo." + }, + "swapQuotesNotAvailableErrorTitle": { + "message": "Nessuna quotazione disponibile" + }, + "swapRate": { + "message": "Tariffa" + }, + "swapReceiving": { + "message": "Ricevendo" + }, + "swapReceivingInfoTooltip": { + "message": "Questa è una stima. L'importo esatto dipende dallo slippage." + }, + "swapRequestForQuotation": { + "message": "Richiedi quotazione" + }, + "swapReviewSwap": { + "message": "Verifica Scambio" + }, + "swapSearchForAToken": { + "message": "Cerca un token" + }, + "swapSelect": { + "message": "Selezione" + }, + "swapSelectAQuote": { + "message": "Seleziona una quotazione" + }, + "swapSelectAToken": { + "message": "Seleziona un token" + }, + "swapSelectQuotePopoverDescription": { + "message": "Sotto trovi tutte le quotazioni raccolte da multiple sorgenti di liquidità." + }, + "swapSlippageTooLow": { + "message": "Lo slippage deve essere maggiore di zero" + }, + "swapSource": { + "message": "Sorgente di liquidità" + }, + "swapSourceInfo": { + "message": "Cerchiamo sorgenti di liquidità multiple (siti di scambio, aggregatori, market maker professionisti) per trovare le tariffe migliori e le tasse di rete minori." + }, + "swapStartSwapping": { + "message": "Inizia a scambiare" + }, + "swapSwapFrom": { + "message": "Scambia da" + }, + "swapSwapSwitch": { + "message": "Inverti token" + }, + "swapSwapTo": { + "message": "Scambia a" + }, + "swapThisWillAllowApprove": { + "message": "Questo permetterà di scambiare $1." + }, + "swapTokenAvailable": { + "message": "I $1 sono stati aggiunti al tuo account.", + "description": "This message is shown after a swap is successful and communicates the exact amount of tokens the user has received for a swap. The $1 is a decimal number of tokens followed by the token symbol." + }, + "swapTokenToToken": { + "message": "Scambia da $1 a $2", + "description": "Used in the transaction display list to describe a swap. $1 and $2 are the symbols of tokens in involved in a swap." + }, + "swapTokenVerificationMessage": { + "message": "Verifica sempre l'indirizzo del token su $1.", + "description": "Points the user to Etherscan as a place they can verify information about a token. $1 is replaced with the translation for \"Etherscan\" followed by an info icon that shows more info on hover." + }, + "swapTokenVerificationOnlyOneSource": { + "message": "Verificato solo su una fonte." + }, + "swapTokenVerificationSources": { + "message": "Verificato su $1 fonti.", + "description": "Indicates the number of token information sources that recognize the symbol + address. $1 is a decimal number." + }, + "swapTransactionComplete": { + "message": "Transazione completata" + }, + "swapUnknown": { + "message": "Sconosciuto" + }, + "swapUsingBestQuote": { + "message": "Quotazione migliore" + }, + "swapVerifyTokenExplanation": { + "message": "Più token possono usare lo stesso nome e simbolo. Verifica su Etherscan che questo sia il token che stai cercando." + }, + "swapViewToken": { + "message": "Vedi $1" + }, + "swapYourTokenBalance": { + "message": "$1 $2 disponibili allo scambio", + "description": "Tells the user how much of a token they have in their balance. $1 is a decimal number amount of tokens, and $2 is a token symbol" + }, + "swapZeroSlippage": { + "message": "0% Slippage" + }, + "swapsAdvancedOptions": { + "message": "Impostazioni Avanzate" + }, + "swapsExcessiveSlippageWarning": { + "message": "L'importo di slippage è troppo alto e risulterà in una tariffa sconveniente. Riduci la tolleranza allo slippage ad un valore minore di 15%." + }, + "swapsMaxSlippage": { + "message": "Tolleranza Slippage" + }, + "swapsNotEnoughForTx": { + "message": "Non hai abbastanza $1 per completare la transazione", + "description": "Tells the user that they don't have enough of a token for a proposed swap. $1 is a token symbol" + }, + "swapsViewInActivity": { + "message": "Vedi in attività" + }, "switchNetworks": { "message": "Cambia Reti" }, @@ -1506,6 +1910,9 @@ "terms": { "message": "Termini di Uso" }, + "termsOfService": { + "message": "Termini di Servizio" + }, "testFaucet": { "message": "Prova Faucet" }, @@ -1660,9 +2067,16 @@ "userName": { "message": "Nome utente" }, + "verifyThisTokenOn": { + "message": "Verifica questo token su $1", + "description": "Points the user to etherscan as a place they can verify information about a token. $1 is replaced with the translation for \"etherscan\"" + }, "viewAccount": { "message": "Vedi Account" }, + "viewAllDetails": { + "message": "Vedi tutti i dettagli" + }, "viewContact": { "message": "Visualizza contatto" }, @@ -1684,6 +2098,10 @@ "walletSeed": { "message": "Seed del Portafoglio" }, + "web3ShimUsageNotification": { + "message": "Abbiamo notato che il sito corrente ha provato ad usare la API window.web3 rimossa. Se il sito ti sembra non funzionare, clicca $1 per più informazioni.", + "description": "$1 is a clickable link." + }, "welcome": { "message": "Benvenuto nella Beta di MetaMask" }, diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 556ba6fff..69b2f208e 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -562,9 +562,6 @@ "endOfFlowMessage6": { "message": "シードフレーズを再度バックアップする場合は、[設定] -> [セキュリティとプライバシー] で見つけることができます。" }, - "endOfFlowMessage7": { - "message": "問題や不審な点がある場合は、support@metamask.io 宛に電子メールをお送りください。" - }, "endOfFlowMessage8": { "message": "MetaMaskはシードフレーズを復元できません。" }, @@ -609,14 +606,6 @@ "message": "エラー名:$1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "ページをリロードして再試行するか、サポート(support@metamask.io)までお問い合わせください", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "ポップアップを閉じてから再び開いてもう一度実行するか、サポート(support@metamask.io)までお問い合わせください", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "MetaMaskにエラーが発生しました", "description": "Title of generic error page" @@ -1138,9 +1127,6 @@ "message": "\"$1\" はこのタブを閉じます。 $2 に戻ってください。", "description": "Return the user to the site that initiated onboarding" }, - "onlyAddTrustedNetworks": { - "message": "悪意のあるEthereumネットワークプロバイダは、不正なブロックチェーンによりネットワーク行動を記録することがあります。信頼できるカスタムネットワークのみを追加してください。" - }, "onlyAvailableOnMainnet": { "message": "メインネットのみ使用可能です" }, @@ -1225,15 +1211,6 @@ "proposedApprovalLimit": { "message": "承認限度額の提案" }, - "protectYourKeys": { - "message": "キーを保護してください!" - }, - "protectYourKeysMessage1": { - "message": "シードフレーズは厳重に取り扱ってください。MetaMaskの偽物がWebサイトで報告されています。MetaMaskがシードフレーズを要求することは絶対にありえません!" - }, - "protectYourKeysMessage2": { - "message": "シードフレーズを厳重に保管してください。不審な点がやWebサイトについて不明確な場合は、support@metamask.io まで電子メールでお問い合わせください" - }, "provide": { "message": "提供する" }, diff --git a/app/_locales/kn/messages.json b/app/_locales/kn/messages.json index 66c6b4358..e07994172 100644 --- a/app/_locales/kn/messages.json +++ b/app/_locales/kn/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "ನಿಮ್ಮ ಸೀಡ್ ಫ್ರೇಸ್‌ನಿಂದ ಮತ್ತೊಮ್ಮೆ ನೀವು ಮತ್ತೆ ಬ್ಯಾಕಪ್ ಮಾಡಬೇಕಾದರೆ, ನೀವು ಅದನ್ನು ಸೆಟ್ಟಿಂಗ್‌ಗಳು -> ಭದ್ರತೆಯಲ್ಲಿ ಕಾಣಬಹುದು." }, - "endOfFlowMessage7": { - "message": "ನೀವು ಎಂದಾದರೂ ಪ್ರಶ್ನೆಗಳನ್ನು ಹೊಂದಿದ್ದರೆ ಅಥವಾ ನೀವು ಯಾವಗಲಾದರೂ ಗೊಂದಲಮಯವಾಗಿದ್ದರೆ support@metamask.io ಗೆ ಇಮೇಲ್ ಮಾಡಿ." - }, "endOfFlowMessage8": { "message": "MetaMask ಗೆ ನಿಮ್ಮ ಸೀಡ್‌ಫ್ರೇಸ್ ಮರಳಿಪಡೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ. ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ." }, @@ -775,15 +772,6 @@ "privateNetwork": { "message": "ಖಾಸಗಿ ನೆಟ್‌ವರ್ಕ್" }, - "protectYourKeys": { - "message": "ನಿಮ್ಮ ಕೀಗಳನ್ನು ರಕ್ಷಿಸಿ!" - }, - "protectYourKeysMessage1": { - "message": "ನಿಮ್ಮ ಸೀಡ್ ಫ್ರೇಸ್‌ನೊಂದಿಗೆ ಜಾಗರೂಕರಾಗಿರಿ — MetaMask ಅನ್ನು ಅನುಕರಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರುವ ವೆಬ್‌ಸೈಟ್‌ಗಳ ವರದಿಗಳಿವೆ. MetaMask ನಿಮ್ಮ ಸೀಡ್ ಫ್ರೇಸ್ ಅನ್ನು ಎಂದಿಗೂ ಕೇಳುವುದಿಲ್ಲ!" - }, - "protectYourKeysMessage2": { - "message": "ನಿಮ್ಮ ಫ್ರೇಸ್ ಅನ್ನು ಸುರಕ್ಷಿತವಾಗಿರಿಸಿ. ಏನಾದರೂ ಅನುಮಾನಾಸ್ಪದವಾಗಿರುವುದನ್ನು ಅಥವಾ ವೆಬ್‌ಸೈಟ್ ಕುರಿತು ನಿಮಗೆ ಅನಿಶ್ಚಿತತೆಯಿದ್ದರೆ, support@metamask.io ಗೆ ಇಮೇಲ್ ಮಾಡಿ" - }, "queue": { "message": "ಸರತಿ" }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index e389148ed..3f1df0f86 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -553,9 +553,6 @@ "endOfFlowMessage6": { "message": "시드 구문을 다시 백업해야 한다면 설정 -> 보안에서 시드 구문을 찾을 수 있습니다." }, - "endOfFlowMessage7": { - "message": "질문이 있거나 피싱으로 의심되는 행위를 목격했다면 support@metamask.io로 이메일을 보내세요." - }, "endOfFlowMessage8": { "message": "MetaMask에서는 시드 구문을 복구할 수 없습니다." }, @@ -600,14 +597,6 @@ "message": "코드: $1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "페이지를 새로고침하여 다시 시도하거나 support@metamask.io에 요청하여 도움을 받으세요.", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "팝업을 닫은 후 다시 열어 다시 시도하거나 support@metamask.io에 요청하여 도움을 받으세요.", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "MetaMask에서 오류 발생", "description": "Title of generic error page" @@ -1126,9 +1115,6 @@ "message": "\"$1\"에서 이 탭을 닫고 $2(으)로 돌아갑니다.", "description": "Return the user to the site that initiated onboarding" }, - "onlyAddTrustedNetworks": { - "message": "악성 이더리움 네트워크 공급업체는 블록체인 상태를 거짓으로 보고하고 네트워크 활동을 기록할 수 있습니다. 신뢰하는 맞춤형 네트워크만 추가하세요." - }, "onlyAvailableOnMainnet": { "message": "메인넷에서만 사용 가능" }, @@ -1213,15 +1199,6 @@ "proposedApprovalLimit": { "message": "제안된 승인 한도" }, - "protectYourKeys": { - "message": "키를 보호하세요!" - }, - "protectYourKeysMessage1": { - "message": "시드 구문을 조심하세요. MetaMask를 흉내 내는 웹사이트가 보고되고 있습니다. MetaMask에서는 시드 구문을 절대로 물어보지 않습니다!" - }, - "protectYourKeysMessage2": { - "message": "시드 구문을 안전하게 보관하세요. 피싱으로 의심되는 행위를 목격했거나 웹사이트가 수상하다면 support@metamask.io로 이메일을 보내세요." - }, "provide": { "message": "제공" }, diff --git a/app/_locales/lt/messages.json b/app/_locales/lt/messages.json index f6bf6ef41..ec9137030 100644 --- a/app/_locales/lt/messages.json +++ b/app/_locales/lt/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Jeigu reikia dar kartą padaryti jūsų atkūrimo frazės kopiją, ją galite rasti pasirinkę Nuostatos -> Sauga." }, - "endOfFlowMessage7": { - "message": "Jeigu turite klausimų arba pastebite ką nors įtartino, rašykite el. paštu support@metamask.io." - }, "endOfFlowMessage8": { "message": "„MetaMask“ negali atkurti jūsų atkūrimo frazės. Sužinokite daugiau." }, @@ -775,15 +772,6 @@ "privateNetwork": { "message": "Privatus tinklas" }, - "protectYourKeys": { - "message": "Apsaugokite savo raktus!" - }, - "protectYourKeysMessage1": { - "message": "Saugokite savo atkūrimo frazę – gavome pranešimų apie interneto svetaines, kuriomis bandoma imituoti „MetaMask“. „MetaMask“ niekada neprašys jūsų pateikti savo atkūrimo frazę!" - }, - "protectYourKeysMessage2": { - "message": "Saugokite savo frazę. Jei pastebėjote kažką įtartino arba nesate tikri dėl svetainės, rašykite mums adresu support@metamask.io" - }, "queue": { "message": "Eilė" }, diff --git a/app/_locales/lv/messages.json b/app/_locales/lv/messages.json index 73497939b..fd1b79205 100644 --- a/app/_locales/lv/messages.json +++ b/app/_locales/lv/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Ja nepieciešams atkārtoti dublēt atkopšanas frāzi, varat to atrast, dodoties uz Iestatījumi -> Drošība." }, - "endOfFlowMessage7": { - "message": "Ja jums rodas kādi jautājumi vai pamanāt ko aizdomīgu, rakstiet uz support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask nevar atjaunot jūsu atkopšanas frāzi. Uzzināt vairāk." }, @@ -771,15 +768,6 @@ "privateNetwork": { "message": "Privātais tīkls" }, - "protectYourKeys": { - "message": "Sargājiet savas atslēgas!" - }, - "protectYourKeysMessage1": { - "message": "Rīkojieties uzmanīgi ar sēklas frāzi — saņemti ziņojumi par tīmekļa vietnēm, kas mēģina imitēt MetaMask. MetaMask nekad nelūgs norādīt sēklas frāzi." - }, - "protectYourKeysMessage2": { - "message": "Glabājiet frāzi drošībā. Ja kaut kas šķiet aizdomīgs vai neesat pārliecināti par tīmekļa vietni, rakstiet e-pastu uz support@metamask.io" - }, "queue": { "message": "Rinda" }, diff --git a/app/_locales/ms/messages.json b/app/_locales/ms/messages.json index a3e9b340c..355a2ca28 100644 --- a/app/_locales/ms/messages.json +++ b/app/_locales/ms/messages.json @@ -344,9 +344,6 @@ "endOfFlowMessage6": { "message": "Jika anda perlu membuat sandaran ungkapan benih anda sekali lagi, anda boleh lakukannya melalui Tetapan -> Keselamatan." }, - "endOfFlowMessage7": { - "message": "JIka anda mempunyai soalan atau melihat sesuatu yang mencurigakan, hantarkan e-mel ke support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask tidak dapat memulihkan ungkapan benih anda. Ketahui lebih lanjut." }, @@ -752,15 +749,6 @@ "privateNetwork": { "message": "Rangkaian Persendirian" }, - "protectYourKeys": { - "message": "Lindungi Kunci Anda!" - }, - "protectYourKeysMessage1": { - "message": "Berhati-hati dengan ungkapan benih anda — terdapat laporan ada tapak web yang cuba meniru MetaMask. MetaMask tidak sekali-kali akan meminta ungkapan benih anda!" - }, - "protectYourKeysMessage2": { - "message": "Pastikan ungkapan anda selamat. Jika anda melihterlihat at sesuatu yang mencurigakan, atau anda tidak pasti mengenai tapak web tertentu, e-mel kepada support@metamask.io" - }, "queue": { "message": "Baris Gilir" }, diff --git a/app/_locales/no/messages.json b/app/_locales/no/messages.json index 936ffbb5a..8489dff4f 100644 --- a/app/_locales/no/messages.json +++ b/app/_locales/no/messages.json @@ -347,9 +347,6 @@ "endOfFlowMessage6": { "message": "Hvis du trenger å sikkerhetskopiere seed-frasen din igjen kan du finne den i Innstillinger -> Sikkerhet." }, - "endOfFlowMessage7": { - "message": "Hvis du noen gang har spørsmål eller ser noe mistenksomt, send e-post til support@metamask.io" - }, "endOfFlowMessage8": { "message": "MetaMask klarer ikke å gjenopprette den mnemoniske gjenopprettingsfrasen din. Finn ut mer. " }, @@ -762,15 +759,6 @@ "privateNetwork": { "message": "Privat nettverk " }, - "protectYourKeys": { - "message": "Beskytt nøklene dine! " - }, - "protectYourKeysMessage1": { - "message": "Vær forsiktig med den mnemoniske gjenopprettingsfrasen din - det rapporteres om nettsteder som prøver å etterligne MetaMask. MetaMask vil aldri be om den mnemoniske gjenopprettingsfrasen din!" - }, - "protectYourKeysMessage2": { - "message": "Oppbevar setningen din trygt. Hvis du ser noe mistenksomt, eller du er usikker på et nettsted, kan du sende en e-post til support@metamask.io" - }, "queue": { "message": "Kø" }, diff --git a/app/_locales/pl/messages.json b/app/_locales/pl/messages.json index f45639fc4..4a4c717a8 100644 --- a/app/_locales/pl/messages.json +++ b/app/_locales/pl/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Jeśli zajdzie konieczność ponownego wykonania kopii zapasowej frazy seed, znajdziesz ją w Ustawieniach -> Zabezpieczenia." }, - "endOfFlowMessage7": { - "message": "Jeśli masz jakieś pytania lub zauważysz coś podejrzanego, wyślij e-mail na adres support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask nie może odzyskać Twojej frazy seed. Dowiedz się więcej." }, @@ -769,15 +766,6 @@ "privateNetwork": { "message": "Sieć prywatna" }, - "protectYourKeys": { - "message": "Chroń swoje klucze!" - }, - "protectYourKeysMessage1": { - "message": "Traktuj swoją frazę seed z ostrożnością – zgłaszano nam przypadki stron internetowych, które podają się za MetaMask. MetaMask nigdy nie poprosi Cię o podanie frazy seed!" - }, - "protectYourKeysMessage2": { - "message": "Przechowuj frazę z zachowaniem zasad bezpieczeństwa. Jeśli zauważysz coś podejrzanego lub nie masz pewności co do strony internetowej, wyślij e-mail na adres support@metamask.io" - }, "queue": { "message": "Kolejka" }, diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index e09fd0861..5aac3e78b 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -344,9 +344,6 @@ "endOfFlowMessage6": { "message": "Se precisar fazer backup de sua frase-semente de novo, acesse Configurações -> Segurança." }, - "endOfFlowMessage7": { - "message": "Caso você tenha alguma dúvida ou veja algo suspeito, envie um e-mail para support@metamask.io." - }, "endOfFlowMessage8": { "message": "O MetaMask não pode recuperar sua frase semente. Saiba mais." }, @@ -763,15 +760,6 @@ "privateNetwork": { "message": "Rede Particular" }, - "protectYourKeys": { - "message": "Proteja as suas chaves!" - }, - "protectYourKeysMessage1": { - "message": "Tome cuidado com sua frase semente — houve relatos de sites que tentam imitar o MetaMask. O MetaMask nunca pedirá sua frase semente!" - }, - "protectYourKeysMessage2": { - "message": "Mantenha a sua frase segura. Se você vir algo esquisito ou está inseguro quanto a um site, envie um e-mail para support@metamask.io" - }, "queue": { "message": "Fila" }, diff --git a/app/_locales/ro/messages.json b/app/_locales/ro/messages.json index 7a8ce67d5..d29f98239 100644 --- a/app/_locales/ro/messages.json +++ b/app/_locales/ro/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Dacă trebuie să vă salvați din nou fraza seed, puteți să o găsiți în Setări -> Securitate." }, - "endOfFlowMessage7": { - "message": "Dacă aveți întrebări sau vedeți ceva suspect, trimiteți un e-mail la support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask nu vă poate recupera expresia sursă. Aflați mai multe." }, @@ -762,15 +759,6 @@ "privateNetwork": { "message": "Rețea privată" }, - "protectYourKeys": { - "message": "Protejați-vă cheile!" - }, - "protectYourKeysMessage1": { - "message": "Aveți grijă cu expresia dvs. sursă – au existat raportări despre site-uri web care încearcă să imite MetaMask. MetaMask nu vă va cere niciodată expresia sursă!" - }, - "protectYourKeysMessage2": { - "message": "Aveți grijă de fraza dvs. Dacă vedeți ceva care este în neregulă sau aveți dubii cu privire la un site, trimiteți un mesaj la support@metamask.io" - }, "queue": { "message": "Coadă" }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 37a32d357..697abea15 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -553,9 +553,6 @@ "endOfFlowMessage6": { "message": "Если вам нужно снова создать резервную копию исходной фразы, вы можете найти ее в Настройки -> Безопасность." }, - "endOfFlowMessage7": { - "message": "Если у вас возникнут вопросы или вы увидите что-то подозрительное, напишите на support@metamask.io." - }, "endOfFlowMessage8": { "message": "Просто помните, что MetaMask не может восстановить исходную фразу." }, @@ -600,14 +597,6 @@ "message": "Код: $1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "Повторите попытку, перезагрузив страницу, или обратитесь в службу поддержки по адресу support@metamask.io", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "Повторите попытку, закрыв и вновь открыв всплывающее окно, или обратитесь в службу поддержки по адресу support@metamask.io", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "MetaMask обнаружил ошибку", "description": "Title of generic error page" @@ -1213,15 +1202,6 @@ "proposedApprovalLimit": { "message": "Предлагаемый предел утверждения" }, - "protectYourKeys": { - "message": "Защитите свои ключи!" - }, - "protectYourKeysMessage1": { - "message": "Будьте осторожны с исходной фразой — были сообщения о веб-сайтах, которые пытались имитировать MetaMask. MetaMask никогда не запросит вашу исходную фразу!" - }, - "protectYourKeysMessage2": { - "message": "Храните свою исходную фразу в безопасности. Если вы увидите что-то подозрительное или вы не уверены в сайте, напишите на support@metamask.io" - }, "provide": { "message": "Предоставить" }, diff --git a/app/_locales/sk/messages.json b/app/_locales/sk/messages.json index 29254b61a..3124751fb 100644 --- a/app/_locales/sk/messages.json +++ b/app/_locales/sk/messages.json @@ -344,9 +344,6 @@ "endOfFlowMessage6": { "message": "Ak potrebujete backup frázu znova zálohovať, nájdete ju v časti Nastavenia -> Zabezpečenie." }, - "endOfFlowMessage7": { - "message": "Ak budete mať nejaké otázky alebo niečo zaujímavé, pošlite email na support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask nemôže obnoviť vašu seed frázu. Zistiť viac." }, @@ -744,15 +741,6 @@ "privateNetwork": { "message": "Soukromá síť" }, - "protectYourKeys": { - "message": "Chráňte si svoje kľúče!" - }, - "protectYourKeysMessage1": { - "message": "Pri seed fráze buďte opatrní – vyskytli sa správy o webových stránkach, ktoré sa snažia napodobniť MetaMask. MetaMask nikdy nebude žiadať vašu seed frázu!" - }, - "protectYourKeysMessage2": { - "message": "Držte svoju frázu v bezpečí. Ak zbadáte niečo podozrivé alebo si nie ste istí webom, pošlite email na adresu support@metamask.io" - }, "queue": { "message": "Poradie" }, diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json index 81ada8e54..f2fc5b566 100644 --- a/app/_locales/sl/messages.json +++ b/app/_locales/sl/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Če morate ponovno varnostno kopirati vaše geslo seed phrase, ga najdete v Nastavitve -> Varnost." }, - "endOfFlowMessage7": { - "message": "Če imate kakršna koli vprašanja ali opazite kaj sumljivega, nam pišite na support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask ne more obnoviti vašega gesla seed phrase. Več informacij." }, @@ -760,15 +757,6 @@ "privateNetwork": { "message": "Zasebno omrežje" }, - "protectYourKeys": { - "message": "Varujte svoje ključe!" - }, - "protectYourKeysMessage1": { - "message": "Bodite previdni in svoj seed phrase skrbno varujte - obstajajo poročila o spletnih mestih, ki poskušajo posnemati MetaMask. MetaMask nikoli ne bo zahteval vašega gesla seed phrase!" - }, - "protectYourKeysMessage2": { - "message": "Hranite svoj seed phrase. Če opazite sumljivo delovanje ali niste prepričani ali je določeno spletno mesto varno, nam pišite na support@metamask.io" - }, "queue": { "message": "Čakalna vrsta" }, diff --git a/app/_locales/sr/messages.json b/app/_locales/sr/messages.json index 64a26aa38..fcf6cf06e 100644 --- a/app/_locales/sr/messages.json +++ b/app/_locales/sr/messages.json @@ -347,9 +347,6 @@ "endOfFlowMessage6": { "message": "Ako treba ponovo da izradite rezervnu kopiju svoje početne fraze, možete je pronaći u Postavke -> Bezbednost." }, - "endOfFlowMessage7": { - "message": "Ako imate bilo kakvih pitanja ili primetite nešto sumnjivo, pošaljite e-poruku na support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask ne može da oporavi vašu početnu frazu. Saznajte više." }, @@ -766,15 +763,6 @@ "privateNetwork": { "message": "Privatna mreža" }, - "protectYourKeys": { - "message": "Zaštitite svoje ključeve!" - }, - "protectYourKeysMessage1": { - "message": "Budite pažljivi sa vašom seed frazom - bilo je izveštaja o veb lokacijama koje pokušavaju da imitiraju MetaMask. MetaMask nikada neće tražiti vašu seed frazu!" - }, - "protectYourKeysMessage2": { - "message": "Čuvajte svoju frazu. Ako primetite nešto sumnjivo, ili niste sigurni u vezi veb lokacije, pošaljite e-poruku na upport@metamask.io" - }, "queue": { "message": "Ред" }, diff --git a/app/_locales/sv/messages.json b/app/_locales/sv/messages.json index bf41b49e9..f961555dc 100644 --- a/app/_locales/sv/messages.json +++ b/app/_locales/sv/messages.json @@ -344,9 +344,6 @@ "endOfFlowMessage6": { "message": "Om du behöver säkerhetskopiera din nyckelfras igen, kan du hitta den i Inställningar -> Säkerhet" }, - "endOfFlowMessage7": { - "message": "Om du har frågor eller ser något misstänksamt, skicka ett e-postmeddelande till support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask kan inte återställa din seedphrase. Läs mer." }, @@ -759,15 +756,6 @@ "privateNetwork": { "message": "Privat nätverk" }, - "protectYourKeys": { - "message": "Skydda dina nycklar!" - }, - "protectYourKeysMessage1": { - "message": "Var försiktig med din seedfras — det har rapporterats om hemsidor som försöker imitera MetaMask. MetaMask kommer aldrig fråga efter din seedfras!" - }, - "protectYourKeysMessage2": { - "message": "Håll din fras i säkert förvar. Om du ser något misstänksamt eller om du är osäker på en hemsida, skicka ett e-postmeddelande till support@metamask.io." - }, "queue": { "message": "Utskriftskö" }, diff --git a/app/_locales/sw/messages.json b/app/_locales/sw/messages.json index 0124d0782..3176cc28d 100644 --- a/app/_locales/sw/messages.json +++ b/app/_locales/sw/messages.json @@ -344,9 +344,6 @@ "endOfFlowMessage6": { "message": "Ikiwa unataka kuhifadhi tena kwa njia mbadla kirai chako kianzio, unaweza kukipata kwenye Mipangilio -> Usalama." }, - "endOfFlowMessage7": { - "message": "Ikiwa una maswali au umeona kitu ambacho ni cha ulaghai, tuma barua pepe support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask haiwezi kurejesha kirai chako kianzio. Pata maelezo ziadi." }, @@ -753,15 +750,6 @@ "privateNetwork": { "message": "Mtandao Binafsi" }, - "protectYourKeys": { - "message": "Linda Funguo Zako!" - }, - "protectYourKeysMessage1": { - "message": "Kuwa mwangalifu na kirai kianzio chako - kumekuwa na taarifa za tovuti ambazo zinajaribu kuiga MetaMask. MetaMask kamwe haitakuomba kirai kianzio chako!" - }, - "protectYourKeysMessage2": { - "message": "Weka salama kirai kianzio chako. Ikiwa unaona kitu cha kilaghai, au huna uhakika na tovuti fulani, tuma barua pepe kwenda support@metamask.io" - }, "queue": { "message": "Foleni" }, diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index 239c54195..f35d6ae6a 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -553,9 +553,6 @@ "endOfFlowMessage6": { "message": "Kung kailangan mong i-back up ulit ang iyong seed phrase, makikita mo ito sa Mga Setting -> Seguridad." }, - "endOfFlowMessage7": { - "message": "Sakaling mayroon kang mga tanong o may nakita kang kahina-hinalang bagay, mag-email sa support@metamask.io." - }, "endOfFlowMessage8": { "message": "Hindi mababawi ng MetaMask ang iyong seedphrase." }, @@ -600,14 +597,6 @@ "message": "Code: $1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "Subukan ulit sa pamamagitan ng pag-reload ng page, o makipag-ugnayan sa suporta sa support@metamask.io", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "Subukan ulit sa pamamagitan ng pagsara at muling pagbukas ng popup, o makipag-ugnayan sa suporta sa support@metamask.io", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "Nagkaroon ng error sa MetaMask", "description": "Title of generic error page" @@ -1126,9 +1115,6 @@ "message": "Isasara ng \"$1\" ang tab na ito at ididirekta ka pabalik sa $2", "description": "Return the user to the site that initiated onboarding" }, - "onlyAddTrustedNetworks": { - "message": "Maaaring magsinungaling ang nakakahamak na Ethereum network providertungkol sa estado ng blockchain at i-record ang aktibidad ng iyong network. Magdagdag lang ng mga custom na network na pinagkakatiwalaan mo." - }, "onlyAvailableOnMainnet": { "message": "Available lang sa mainnet" }, @@ -1213,15 +1199,6 @@ "proposedApprovalLimit": { "message": "Iminumungkahing Limitasyon sa Pag-apruba" }, - "protectYourKeys": { - "message": "Protektahan ang Iyong Mga Key!" - }, - "protectYourKeysMessage1": { - "message": "Ingatan ang iyong seed phrase — may mga naiulat na website na sinusubukang gayahin ang MetaMask. Hindi kailanman hihingin ng MetaMask ang iyong seed phrase!" - }, - "protectYourKeysMessage2": { - "message": "Ingatan ang iyong phrase. Kung may makikita kang kahina-hinalang bagay, o hindi ka sigurado sa isang website, mag-email sa support@metamask.io" - }, "provide": { "message": "Ibigay" }, diff --git a/app/_locales/uk/messages.json b/app/_locales/uk/messages.json index 11029c216..8f499bc2f 100644 --- a/app/_locales/uk/messages.json +++ b/app/_locales/uk/messages.json @@ -350,9 +350,6 @@ "endOfFlowMessage6": { "message": "Якщо вам потрібно знову зробити резервну копію вашої початкової фрази, ви можете знайти її у Налаштування -> Безпека." }, - "endOfFlowMessage7": { - "message": "Якщо у вас коли-небудь виникатимуть питання або ви побачите щось фішингове, пишіть на support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask не вдалося відновити вашу мнемонічну фразу. Докладніше." }, @@ -775,15 +772,6 @@ "privateNetwork": { "message": "Приватна мережа" }, - "protectYourKeys": { - "message": "Захистіть свої ключі!" - }, - "protectYourKeysMessage1": { - "message": "Будьте обережними з вашою початковою фразою - надходила інформація про сайти, які намагались імітувати MetaMask. MetaMask ніколи не запитує вашої початкової фрази!" - }, - "protectYourKeysMessage2": { - "message": "Тримайте свою фразу у безпеці. Якщо ви бачите щось фішингове або ви не впевнені щодо сайту, напишіть нам на support@metamask.io" - }, "queue": { "message": "Черга" }, diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index d24e310d4..da2e8d5b5 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -553,9 +553,6 @@ "endOfFlowMessage6": { "message": "Nếu cần sao lưu lại cụm mật khẩu gốc của mình, bạn có thể tìm thấy cụm mật khẩu này trong phần Cài đặt -> Bảo mật." }, - "endOfFlowMessage7": { - "message": "Nếu bạn có câu hỏi hoặc nhận thấy điều gì đó đáng ngờ, hãy gửi email đến support@metamask.io." - }, "endOfFlowMessage8": { "message": "MetaMask không thể khôi phục cụm mật khẩu gốc của bạn." }, @@ -600,14 +597,6 @@ "message": "Mã: $1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "Hãy thử lại bằng cách tải lại trang hoặc liên hệ với bộ phận hỗ trợ theo địa chỉ support@metamask.io", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "Hãy thử lại bằng cách đóng và mở lại cửa sổ bật lên hoặc liên hệ với bộ phận hỗ trợ theo địa chỉ support@metamask.io", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "MetaMask đã gặp lỗi", "description": "Title of generic error page" @@ -1127,7 +1116,7 @@ "description": "Return the user to the site that initiated onboarding" }, "onlyAddTrustedNetworks": { - "message": "Một nhà cung cấp mạng Ethereum độc hại có thể nói dối về trạng thái của chuỗi khối và ghi lại hoạt động của bạn trên mạng. Chỉ thêm các mạng tùy chỉnh mà bạn tin tưởng." + "message": "Một nhà cung cấp mạng độc hại có thể nói dối về trạng thái của chuỗi khối và ghi lại hoạt động của bạn trên mạng. Chỉ thêm các mạng tùy chỉnh mà bạn tin tưởng." }, "onlyAvailableOnMainnet": { "message": "Chỉ có trên mạng chính thức" @@ -1213,15 +1202,6 @@ "proposedApprovalLimit": { "message": "Giới hạn phê duyệt đề xuất" }, - "protectYourKeys": { - "message": "Bảo vệ khóa của bạn!" - }, - "protectYourKeysMessage1": { - "message": "Hãy cẩn với cụm mật khẩu gốc của bạn, đã có báo cáo về các trang web cố tình giả mạo MetaMask. MetaMask sẽ không bao giờ hỏi cụm mật khẩu gốc của bạn!" - }, - "protectYourKeysMessage2": { - "message": "Hãy lưu giữ cụm mật khẩu của bạn an toàn. Nếu bạn nhận thấy điều gì đó đáng ngờ hoặc không chắc chắn về một trang web, hãy gửi email đến support@metamask.io" - }, "provide": { "message": "Cung cấp" }, diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index cef95ab7e..09c370050 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -562,9 +562,6 @@ "endOfFlowMessage6": { "message": "如果您需要再次备份账户助记词,请通过设置 -> 安全选项完成该操作。" }, - "endOfFlowMessage7": { - "message": "如果您仍存有疑问或发现任何可疑的地方,请发送电子邮件至 support@metamask.io 进行咨询。" - }, "endOfFlowMessage8": { "message": "MetaMask 无法恢复您的账户助记词。" }, @@ -609,14 +606,6 @@ "message": "代码:$1", "description": "Displayed error name for debugging purposes. $1 is the error name" }, - "errorPageMessage": { - "message": "请重新加载页面重试,或通过 support@metamask.io 联系支持。", - "description": "Message displayed on generic error page in the fullscreen or notification UI" - }, - "errorPagePopupMessage": { - "message": "请关闭并重新打开弹窗再试一次,或通过 support@metamask.io 联系支持。", - "description": "Message displayed on generic error page in the popup UI" - }, "errorPageTitle": { "message": "MetaMask 遇到了一个错误", "description": "Title of generic error page" @@ -1138,9 +1127,6 @@ "message": "“$1”会关闭此标签,直接回到 $2", "description": "Return the user to the site that initiated onboarding" }, - "onlyAddTrustedNetworks": { - "message": "恶意的 Ethereum 以太坊网络提供商可以伪造区块链状态,并记录您的网络活动。只添加您信任的自定义网络。" - }, "onlyAvailableOnMainnet": { "message": "仅在主网(mainnet)上提供" }, @@ -1225,15 +1211,6 @@ "proposedApprovalLimit": { "message": "拟议的审批上限" }, - "protectYourKeys": { - "message": "妥善保管您的密钥!" - }, - "protectYourKeysMessage1": { - "message": "请注意个人账户助记词的安全。报告显示有多个网站企图伪造 MetaMask。MetaMask 绝不会要求您提供个人账户助记词!" - }, - "protectYourKeysMessage2": { - "message": "请妥善保管您的账户助记词。如果您发现任何可疑的地方,或无法确认网络安全性,请发送电子邮件至 support@metamask.io 进行咨询" - }, "provide": { "message": "提供" }, diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index c62c3677f..d724a8647 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -359,9 +359,6 @@ "endOfFlowMessage6": { "message": "如你需要再次備份助記詞,可至設定 -> 安全。" }, - "endOfFlowMessage7": { - "message": "如你有任何問題或察覺有異,請寄信給 support@metamask.io" - }, "endOfFlowMessage8": { "message": "MetaMask 無法還原你的助記詞。暸解更多" }, @@ -772,15 +769,6 @@ "privateNetwork": { "message": "私有網路" }, - "protectYourKeys": { - "message": "保護你的鑰匙!" - }, - "protectYourKeysMessage1": { - "message": "小心保管你的註記詞—我們接到報告有網站嘗試模仿 MetaMask。MetaMask 永遠不會詢問你的助記詞!" - }, - "protectYourKeysMessage2": { - "message": "安全存放你的助記詞。如你察覺有異,或你對某網站起疑,請寄信給 support@metamask.io" - }, "queue": { "message": "佇列" }, diff --git a/app/manifest/_base.json b/app/manifest/_base.json index 8c04191bb..d32f75c3f 100644 --- a/app/manifest/_base.json +++ b/app/manifest/_base.json @@ -78,6 +78,6 @@ "notifications" ], "short_name": "__MSG_appName__", - "version": "9.1.1", + "version": "9.2.0", "web_accessible_resources": ["inpage.js", "phishing.html"] } diff --git a/app/scripts/controllers/cached-balances.js b/app/scripts/controllers/cached-balances.js index d4762f84f..a32c1f0ac 100644 --- a/app/scripts/controllers/cached-balances.js +++ b/app/scripts/controllers/cached-balances.js @@ -3,7 +3,7 @@ import { ObservableStore } from '@metamask/obs-store'; /** * @typedef {Object} CachedBalancesOptions * @property {Object} accountTracker An {@code AccountTracker} reference - * @property {Function} getNetwork A function to get the current network + * @property {Function} getCurrentChainId A function to get the current chain id * @property {Object} initState The initial controller state */ @@ -18,10 +18,10 @@ export default class CachedBalancesController { * @param {CachedBalancesOptions} [opts] - Controller configuration parameters */ constructor(opts = {}) { - const { accountTracker, getNetwork } = opts; + const { accountTracker, getCurrentChainId } = opts; this.accountTracker = accountTracker; - this.getNetwork = getNetwork; + this.getCurrentChainId = getCurrentChainId; const initState = { cachedBalances: {}, ...opts.initState }; this.store = new ObservableStore(initState); @@ -30,37 +30,37 @@ export default class CachedBalancesController { } /** - * Updates the cachedBalances property for the current network. Cached balances will be updated to those in the passed accounts + * Updates the cachedBalances property for the current chain. Cached balances will be updated to those in the passed accounts * if balances in the passed accounts are truthy. * - * @param {Object} obj - The the recently updated accounts object for the current network + * @param {Object} obj - The the recently updated accounts object for the current chain * @returns {Promise} */ async updateCachedBalances({ accounts }) { - const network = await this.getNetwork(); + const chainId = this.getCurrentChainId(); const balancesToCache = await this._generateBalancesToCache( accounts, - network, + chainId, ); this.store.updateState({ cachedBalances: balancesToCache, }); } - _generateBalancesToCache(newAccounts, currentNetwork) { + _generateBalancesToCache(newAccounts, chainId) { const { cachedBalances } = this.store.getState(); - const currentNetworkBalancesToCache = { ...cachedBalances[currentNetwork] }; + const currentChainBalancesToCache = { ...cachedBalances[chainId] }; Object.keys(newAccounts).forEach((accountID) => { const account = newAccounts[accountID]; if (account.balance) { - currentNetworkBalancesToCache[accountID] = account.balance; + currentChainBalancesToCache[accountID] = account.balance; } }); const balancesToCache = { ...cachedBalances, - [currentNetwork]: currentNetworkBalancesToCache, + [chainId]: currentChainBalancesToCache, }; return balancesToCache; diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 539978bca..240aaaa18 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -61,6 +61,7 @@ export default class PreferencesController { autoLockTimeLimit: undefined, showFiatInTestnets: false, useNativeCurrencyAsPrimaryCurrency: true, + hideZeroBalanceTokens: false, }, completedOnboarding: false, // ENS decentralized website resolution diff --git a/app/scripts/controllers/swaps.js b/app/scripts/controllers/swaps.js index d82ac305f..3aef182fb 100644 --- a/app/scripts/controllers/swaps.js +++ b/app/scripts/controllers/swaps.js @@ -8,7 +8,7 @@ import { calcTokenAmount } from '../../../ui/app/helpers/utils/token-util'; import { calcGasTotal } from '../../../ui/app/pages/send/send.utils'; import { conversionUtil } from '../../../ui/app/helpers/utils/conversion-util'; import { - ETH_SWAPS_TOKEN_ADDRESS, + ETH_SWAPS_TOKEN_OBJECT, DEFAULT_ERC20_APPROVE_GAS, QUOTES_EXPIRED_ERROR, QUOTES_NOT_AVAILABLE_ERROR, @@ -191,7 +191,7 @@ export default class SwapsController { let approvalRequired = false; if ( - fetchParams.sourceToken !== ETH_SWAPS_TOKEN_ADDRESS && + fetchParams.sourceToken !== ETH_SWAPS_TOKEN_OBJECT.address && Object.values(newQuotes).length ) { const allowance = await this._getERC20Allowance( @@ -552,7 +552,7 @@ export default class SwapsController { // If the swap is from ETH, subtract the sourceAmount from the total cost. // Otherwise, the total fee is simply trade.value plus gas fees. const ethFee = - sourceToken === ETH_SWAPS_TOKEN_ADDRESS + sourceToken === ETH_SWAPS_TOKEN_OBJECT.address ? conversionUtil( totalWeiCost.minus(sourceAmount, 10), // sourceAmount is in wei { @@ -589,7 +589,9 @@ export default class SwapsController { ); const conversionRateForCalculations = - destinationToken === ETH_SWAPS_TOKEN_ADDRESS ? 1 : tokenConversionRate; + destinationToken === ETH_SWAPS_TOKEN_OBJECT.address + ? 1 + : tokenConversionRate; const overallValueOfQuoteForSorting = conversionRateForCalculations === undefined @@ -616,7 +618,7 @@ export default class SwapsController { }); const isBest = - newQuotes[topAggId].destinationToken === ETH_SWAPS_TOKEN_ADDRESS || + newQuotes[topAggId].destinationToken === ETH_SWAPS_TOKEN_OBJECT.address || Boolean(tokenConversionRates[newQuotes[topAggId]?.destinationToken]); let savings = null; diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index a71ad26d2..d0cf9c1a0 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -26,6 +26,7 @@ import { } from '@metamask/controllers'; import { getBackgroundMetaMetricState } from '../../ui/app/selectors'; import { TRANSACTION_STATUSES } from '../../shared/constants/transaction'; +import { MAINNET_CHAIN_ID } from '../../shared/constants/network'; import ComposableObservableStore from './lib/ComposableObservableStore'; import AccountTracker from './lib/account-tracker'; import createLoggerMiddleware from './lib/createLoggerMiddleware'; @@ -218,7 +219,7 @@ export default class MetamaskController extends EventEmitter { this.cachedBalancesController = new CachedBalancesController({ accountTracker: this.accountTracker, - getNetwork: this.networkController.getNetworkState.bind( + getCurrentChainId: this.networkController.getCurrentChainId.bind( this.networkController, ), initState: initState.CachedBalancesController, @@ -318,7 +319,15 @@ export default class MetamaskController extends EventEmitter { status === TRANSACTION_STATUSES.FAILED ) { const txMeta = this.txController.txStateManager.getTx(txId); - this.platform.showTransactionNotification(txMeta); + const frequentRpcListDetail = this.preferencesController.getFrequentRpcListDetail(); + let rpcPrefs = {}; + if (txMeta.chainId) { + const rpcSettings = frequentRpcListDetail.find( + (rpc) => txMeta.chainId === rpc.chainId, + ); + rpcPrefs = rpcSettings?.rpcPrefs ?? {}; + } + this.platform.showTransactionNotification(txMeta, rpcPrefs); const { txReceipt } = txMeta; if (txReceipt && txReceipt.status === '0x0') { @@ -1074,10 +1083,10 @@ export default class MetamaskController extends EventEmitter { Object.keys(accountTokens).forEach((address) => { const checksummedAddress = ethUtil.toChecksumAddress(address); filteredAccountTokens[checksummedAddress] = {}; - Object.keys(accountTokens[address]).forEach((networkType) => { - filteredAccountTokens[checksummedAddress][networkType] = - networkType === 'mainnet' - ? accountTokens[address][networkType].filter( + Object.keys(accountTokens[address]).forEach((chainId) => { + filteredAccountTokens[checksummedAddress][chainId] = + chainId === MAINNET_CHAIN_ID + ? accountTokens[address][chainId].filter( ({ address: tokenAddress }) => { const checksumAddress = ethUtil.toChecksumAddress( tokenAddress, @@ -1087,7 +1096,7 @@ export default class MetamaskController extends EventEmitter { : true; }, ) - : accountTokens[address][networkType]; + : accountTokens[address][chainId]; }); }); @@ -1288,11 +1297,16 @@ export default class MetamaskController extends EventEmitter { } /** - * Imports an account from a trezor device. + * Imports an account from a Trezor or Ledger device. * * @returns {} keyState */ - async unlockHardwareWalletAccount(index, deviceName, hdPath) { + async unlockHardwareWalletAccount( + index, + deviceName, + hdPath, + hdPathDescription, + ) { const keyring = await this.getKeyringForDevice(deviceName, hdPath); keyring.setAccountToUnlock(index); @@ -1302,13 +1316,11 @@ export default class MetamaskController extends EventEmitter { this.preferencesController.setAddresses(newAccounts); newAccounts.forEach((address) => { if (!oldAccounts.includes(address)) { + const label = `${deviceName[0].toUpperCase()}${deviceName.slice(1)} ${ + parseInt(index, 10) + 1 + } ${hdPathDescription || ''}`.trim(); // Set the account label to Trezor 1 / Ledger 1, etc - this.preferencesController.setAccountLabel( - address, - `${deviceName[0].toUpperCase()}${deviceName.slice(1)} ${ - parseInt(index, 10) + 1 - }`, - ); + this.preferencesController.setAccountLabel(address, label); // Select the account this.preferencesController.setSelectedAddress(address); } diff --git a/app/scripts/platforms/extension.js b/app/scripts/platforms/extension.js index 98196c946..0eaeefaa8 100644 --- a/app/scripts/platforms/extension.js +++ b/app/scripts/platforms/extension.js @@ -1,8 +1,8 @@ import extension from 'extensionizer'; -import { createExplorerLink as explorerLink } from '@metamask/etherscan-link'; import { getEnvironmentType, checkForError } from '../lib/util'; import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import { getBlockExplorerUrlForTx } from '../../../shared/modules/transaction.utils'; export default class ExtensionPlatform { // @@ -110,7 +110,7 @@ export default class ExtensionPlatform { } } - showTransactionNotification(txMeta) { + showTransactionNotification(txMeta, rpcPrefs) { const { status, txReceipt: { status: receiptStatus } = {} } = txMeta; if (status === TRANSACTION_STATUSES.CONFIRMED) { @@ -120,7 +120,7 @@ export default class ExtensionPlatform { txMeta, 'Transaction encountered an error.', ) - : this._showConfirmedTransaction(txMeta); + : this._showConfirmedTransaction(txMeta, rpcPrefs); } else if (status === TRANSACTION_STATUSES.FAILED) { this._showFailedTransaction(txMeta); } @@ -189,10 +189,10 @@ export default class ExtensionPlatform { }); } - _showConfirmedTransaction(txMeta) { + _showConfirmedTransaction(txMeta, rpcPrefs) { this._subscribeToNotificationClicked(); - const url = explorerLink(txMeta.hash, txMeta.metamaskNetworkId); + const url = getBlockExplorerUrlForTx(txMeta, rpcPrefs); const nonce = parseInt(txMeta.txParams.nonce, 16); const title = 'Confirmed transaction'; diff --git a/package.json b/package.json index dfc829560..a3cb1f318 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "scripts": { "setup": "yarn install && yarn patch-package && yarn allow-scripts", "setup-ci": "yarn install --frozen-lockfile --har && yarn patch-package && yarn allow-scripts", - "start": "yarn build dev", + "start": "node development/build/index.js dev", + "start:lavamoat": "yarn build dev", "dist": "yarn build prod", "build": "lavamoat development/build/index.js", "start:test": "yarn build testDev", @@ -19,10 +20,10 @@ "forwarder": "node ./development/static-server.js ./node_modules/@metamask/forwarder/dist/ --port 9010", "dapp-forwarder": "concurrently -k -n forwarder,dapp -p '[{time}][{name}]' 'yarn forwarder' 'yarn dapp'", "sendwithprivatedapp": "node development/static-server.js test/e2e/send-eth-with-private-key-test --port 8080", - "test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\"", - "test:unit:global": "mocha --exit --require test/env.js --require test/setup.js --recursive test/unit-global/*", - "test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/{,**/!(permissions)}/*.js\" \"ui/app/**/*.test.js\"", - "test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/permissions/*.js\"", + "test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/*.test.js\" \"ui/app/**/*.test.js\" \"shared/**/*.test.js\"", + "test:unit:global": "mocha --exit --require test/env.js --require test/setup.js --recursive test/unit-global/*.test.js", + "test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/{,**/!(permissions)}/*.test.js\" \"ui/app/**/*.test.js\" \"shared/**/*.test.js\"", + "test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/permissions/*.test.js\"", "test:unit:path": "mocha --exit --require test/env.js --require test/setup.js --recursive", "test:e2e:chrome": "SELENIUM_BROWSER=chrome test/e2e/run-all.sh", "test:e2e:chrome:metrics": "SELENIUM_BROWSER=chrome mocha test/e2e/metrics.spec.js", @@ -44,7 +45,7 @@ "verify-locales": "node ./development/verify-locale-strings.js", "verify-locales:fix": "node ./development/verify-locale-strings.js --fix", "mozilla-lint": "addons-linter dist/firefox", - "watch": "mocha --watch --require test/env.js --require test/setup.js --reporter min --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\"", + "watch": "mocha --watch --require test/env.js --require test/setup.js --reporter min --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\" \"shared/**/*.test.js\"", "devtools:react": "react-devtools", "devtools:redux": "remotedev --hostname=localhost --port=8000", "start:dev": "concurrently -k -n build,react,redux yarn:start yarn:devtools:react yarn:devtools:redux", @@ -59,7 +60,7 @@ }, "resolutions": { "**/configstore/dot-prop": "^5.1.1", - "**/ethers/elliptic": "^6.5.3", + "**/ethers/elliptic": "^6.5.4", "**/knex/minimist": "^1.2.5", "**/optimist/minimist": "^1.2.5", "**/socketcluster/minimist": "^1.2.5", @@ -67,10 +68,11 @@ "**/redux-devtools-instrument/symbol-observable": "^2.0.3", "**/rxjs/symbol-observable": "^2.0.3", "3box/ipfs/ipld-zcash/zcash-bitcore-lib/lodash": "^4.17.19", - "3box/ipfs/ipld-zcash/zcash-bitcore-lib/elliptic": "^6.5.3", + "3box/ipfs/ipld-zcash/zcash-bitcore-lib/elliptic": "^6.5.4", "3box/**/libp2p-crypto/node-forge": "^0.10.0", "3box/**/libp2p-keychain/node-forge": "^0.10.0", - "analytics-node/axios": "^0.21.1" + "analytics-node/axios": "^0.21.1", + "pull-ws": "^3.3.2" }, "dependencies": { "3box": "^1.10.2", @@ -82,9 +84,9 @@ "@material-ui/core": "^4.11.0", "@metamask/contract-metadata": "^1.22.0", "@metamask/controllers": "^5.1.0", - "@metamask/eth-ledger-bridge-keyring": "^0.2.6", + "@metamask/eth-ledger-bridge-keyring": "^0.3.0", "@metamask/eth-token-tracker": "^3.0.1", - "@metamask/etherscan-link": "^1.4.1", + "@metamask/etherscan-link": "^1.5.0", "@metamask/inpage-provider": "^8.0.4", "@metamask/jazzicon": "^2.0.0", "@metamask/logo": "^2.5.0", @@ -118,7 +120,7 @@ "eth-query": "^2.1.2", "eth-rpc-errors": "^4.0.2", "eth-sig-util": "^3.0.0", - "eth-trezor-keyring": "^0.5.2", + "eth-trezor-keyring": "^0.6.0", "ethereum-ens-network-map": "^1.0.2", "ethereumjs-abi": "^0.6.4", "ethereumjs-tx": "1.3.7", @@ -194,7 +196,7 @@ "@babel/preset-env": "^7.5.5", "@babel/preset-react": "^7.0.0", "@babel/register": "^7.5.5", - "@lavamoat/allow-scripts": "^1.0.3", + "@lavamoat/allow-scripts": "^1.0.4", "@metamask/eslint-config": "^5.0.0", "@metamask/forwarder": "^1.1.0", "@metamask/test-dapp": "^4.0.1", diff --git a/shared/modules/tests/transaction.utils.test.js b/shared/modules/tests/transaction.utils.test.js new file mode 100644 index 000000000..2aac76828 --- /dev/null +++ b/shared/modules/tests/transaction.utils.test.js @@ -0,0 +1,96 @@ +import assert from 'assert'; +import { + MAINNET_CHAIN_ID, + MAINNET_NETWORK_ID, + ROPSTEN_CHAIN_ID, + ROPSTEN_NETWORK_ID, +} from '../../constants/network'; +import { getBlockExplorerUrlForTx } from '../transaction.utils'; + +const tests = [ + { + expected: 'https://etherscan.io/tx/0xabcd', + transaction: { + metamaskNetworkId: MAINNET_NETWORK_ID, + hash: '0xabcd', + }, + }, + { + expected: 'https://ropsten.etherscan.io/tx/0xdef0', + transaction: { + metamaskNetworkId: ROPSTEN_NETWORK_ID, + hash: '0xdef0', + }, + rpcPrefs: {}, + }, + { + // test handling of `blockExplorerUrl` for a custom RPC + expected: 'https://block.explorer/tx/0xabcd', + transaction: { + metamaskNetworkId: '31', + hash: '0xabcd', + }, + rpcPrefs: { + blockExplorerUrl: 'https://block.explorer', + }, + }, + { + // test handling of trailing `/` in `blockExplorerUrl` for a custom RPC + expected: 'https://another.block.explorer/tx/0xdef0', + transaction: { + networkId: '33', + hash: '0xdef0', + }, + rpcPrefs: { + blockExplorerUrl: 'https://another.block.explorer/', + }, + }, + { + expected: 'https://etherscan.io/tx/0xabcd', + transaction: { + chainId: MAINNET_CHAIN_ID, + hash: '0xabcd', + }, + }, + { + expected: 'https://ropsten.etherscan.io/tx/0xdef0', + transaction: { + chainId: ROPSTEN_CHAIN_ID, + hash: '0xdef0', + }, + rpcPrefs: {}, + }, + { + // test handling of `blockExplorerUrl` for a custom RPC + expected: 'https://block.explorer/tx/0xabcd', + transaction: { + chainId: '0x1f', + hash: '0xabcd', + }, + rpcPrefs: { + blockExplorerUrl: 'https://block.explorer', + }, + }, + { + // test handling of trailing `/` in `blockExplorerUrl` for a custom RPC + expected: 'https://another.block.explorer/tx/0xdef0', + transaction: { + chainId: '0x21', + hash: '0xdef0', + }, + rpcPrefs: { + blockExplorerUrl: 'https://another.block.explorer/', + }, + }, +]; + +describe('getBlockExplorerUrlForTx', function () { + tests.forEach((test) => { + it(`should return '${test.expected}' for transaction with hash: '${test.transaction.hash}'`, function () { + assert.strictEqual( + getBlockExplorerUrlForTx(test.transaction, test.rpcPrefs), + test.expected, + ); + }); + }); +}); diff --git a/shared/modules/transaction.utils.js b/shared/modules/transaction.utils.js index 9e89679f8..47a0a4334 100644 --- a/shared/modules/transaction.utils.js +++ b/shared/modules/transaction.utils.js @@ -1,6 +1,37 @@ +import { + createExplorerLink, + createExplorerLinkForChain, +} from '@metamask/etherscan-link'; + export function transactionMatchesNetwork(transaction, chainId, networkId) { if (typeof transaction.chainId !== 'undefined') { return transaction.chainId === chainId; } return transaction.metamaskNetworkId === networkId; } + +/** + * build the etherscan link for a transaction by either chainId, if available + * or metamaskNetworkId as a fallback. If rpcPrefs is provided will build the + * url for the provided blockExplorerUrl. + * + * @param {Object} transaction - a transaction object from state + * @param {string} [transaction.metamaskNetworkId] - network id tx occurred on + * @param {string} [transaction.chainId] - chain id tx occurred on + * @param {string} [transaction.hash] - hash of the transaction + * @param {Object} [rpcPrefs] - the rpc preferences for the current RPC network + * @param {string} [rpcPrefs.blockExplorerUrl] - the block explorer url for RPC + * networks + * @returns {string} + */ +export function getBlockExplorerUrlForTx(transaction, rpcPrefs = {}) { + if (rpcPrefs.blockExplorerUrl) { + return `${rpcPrefs.blockExplorerUrl.replace(/\/+$/u, '')}/tx/${ + transaction.hash + }`; + } + if (transaction.chainId) { + return createExplorerLinkForChain(transaction.hash, transaction.chainId); + } + return createExplorerLink(transaction.hash, transaction.metamaskNetworkId); +} diff --git a/test/unit-global/frozenPromise.js b/test/unit-global/frozenPromise.test.js similarity index 100% rename from test/unit-global/frozenPromise.js rename to test/unit-global/frozenPromise.test.js diff --git a/test/unit/actions/config_test.js b/test/unit/actions/config.test.js similarity index 100% rename from test/unit/actions/config_test.js rename to test/unit/actions/config.test.js diff --git a/test/unit/actions/set_account_label_test.js b/test/unit/actions/set_account_label.test.js similarity index 100% rename from test/unit/actions/set_account_label_test.js rename to test/unit/actions/set_account_label.test.js diff --git a/test/unit/actions/set_selected_account_test.js b/test/unit/actions/set_selected_account.test.js similarity index 100% rename from test/unit/actions/set_selected_account_test.js rename to test/unit/actions/set_selected_account.test.js diff --git a/test/unit/actions/tx_test.js b/test/unit/actions/tx.test.js similarity index 100% rename from test/unit/actions/tx_test.js rename to test/unit/actions/tx.test.js diff --git a/test/unit/actions/warning_test.js b/test/unit/actions/warning.test.js similarity index 100% rename from test/unit/actions/warning_test.js rename to test/unit/actions/warning.test.js diff --git a/test/unit/app/ComposableObservableStore.js b/test/unit/app/ComposableObservableStore.test.js similarity index 100% rename from test/unit/app/ComposableObservableStore.js rename to test/unit/app/ComposableObservableStore.test.js diff --git a/test/unit/app/account-import-strategies.spec.js b/test/unit/app/account-import-strategies.test.js similarity index 100% rename from test/unit/app/account-import-strategies.spec.js rename to test/unit/app/account-import-strategies.test.js diff --git a/test/unit/app/buy-eth-url.spec.js b/test/unit/app/buy-eth-url.test.js similarity index 100% rename from test/unit/app/buy-eth-url.spec.js rename to test/unit/app/buy-eth-url.test.js diff --git a/test/unit/app/cleanErrorStack.spec.js b/test/unit/app/cleanErrorStack.test.js similarity index 100% rename from test/unit/app/cleanErrorStack.spec.js rename to test/unit/app/cleanErrorStack.test.js diff --git a/test/unit/app/controllers/cached-balances-test.js b/test/unit/app/controllers/cached-balances.test.js similarity index 91% rename from test/unit/app/controllers/cached-balances-test.js rename to test/unit/app/controllers/cached-balances.test.js index 1267e083b..cf2826024 100644 --- a/test/unit/app/controllers/cached-balances-test.js +++ b/test/unit/app/controllers/cached-balances.test.js @@ -1,12 +1,13 @@ import assert from 'assert'; import sinon from 'sinon'; import CachedBalancesController from '../../../../app/scripts/controllers/cached-balances'; +import { KOVAN_CHAIN_ID } from '../../../../shared/constants/network'; describe('CachedBalancesController', function () { describe('updateCachedBalances', function () { it('should update the cached balances', async function () { const controller = new CachedBalancesController({ - getNetwork: () => Promise.resolve(17), + getCurrentChainId: () => KOVAN_CHAIN_ID, accountTracker: { store: { subscribe: () => undefined, @@ -26,7 +27,7 @@ describe('CachedBalancesController', function () { assert.equal(controller._generateBalancesToCache.callCount, 1); assert.deepEqual(controller._generateBalancesToCache.args[0], [ 'mockAccounts', - 17, + KOVAN_CHAIN_ID, ]); assert.equal( controller.store.getState().cachedBalances, @@ -45,7 +46,7 @@ describe('CachedBalancesController', function () { }, initState: { cachedBalances: { - 17: { + [KOVAN_CHAIN_ID]: { a: '0x1', b: '0x2', c: '0x3', @@ -65,11 +66,11 @@ describe('CachedBalancesController', function () { b: { balance: null }, c: { balance: '0x5' }, }, - 17, + KOVAN_CHAIN_ID, ); assert.deepEqual(result, { - 17: { + [KOVAN_CHAIN_ID]: { a: '0x4', b: '0x2', c: '0x5', @@ -91,7 +92,7 @@ describe('CachedBalancesController', function () { }, initState: { cachedBalances: { - 17: { + [KOVAN_CHAIN_ID]: { a: '0x1', b: '0x2', c: '0x3', @@ -110,7 +111,7 @@ describe('CachedBalancesController', function () { ); assert.deepEqual(result, { - 17: { + [KOVAN_CHAIN_ID]: { a: '0x1', b: '0x2', c: '0x3', @@ -127,7 +128,7 @@ describe('CachedBalancesController', function () { it('should subscribe to the account tracker with the updateCachedBalances method', async function () { const subscribeSpy = sinon.spy(); const controller = new CachedBalancesController({ - getNetwork: () => Promise.resolve(17), + getCurrentChainId: () => KOVAN_CHAIN_ID, accountTracker: { store: { subscribe: subscribeSpy, diff --git a/test/unit/app/controllers/detect-tokens-test.js b/test/unit/app/controllers/detect-tokens.test.js similarity index 100% rename from test/unit/app/controllers/detect-tokens-test.js rename to test/unit/app/controllers/detect-tokens.test.js diff --git a/test/unit/app/controllers/ens-controller-test.js b/test/unit/app/controllers/ens-controller.test.js similarity index 100% rename from test/unit/app/controllers/ens-controller-test.js rename to test/unit/app/controllers/ens-controller.test.js diff --git a/test/unit/app/controllers/incoming-transactions-test.js b/test/unit/app/controllers/incoming-transactions.test.js similarity index 100% rename from test/unit/app/controllers/incoming-transactions-test.js rename to test/unit/app/controllers/incoming-transactions.test.js diff --git a/test/unit/app/controllers/metamask-controller-test.js b/test/unit/app/controllers/metamask-controller.test.js similarity index 100% rename from test/unit/app/controllers/metamask-controller-test.js rename to test/unit/app/controllers/metamask-controller.test.js diff --git a/test/unit/app/controllers/metametrics-test.js b/test/unit/app/controllers/metametrics.test.js similarity index 100% rename from test/unit/app/controllers/metametrics-test.js rename to test/unit/app/controllers/metametrics.test.js diff --git a/test/unit/app/controllers/network/network-controller-test.js b/test/unit/app/controllers/network/network-controller.test.js similarity index 100% rename from test/unit/app/controllers/network/network-controller-test.js rename to test/unit/app/controllers/network/network-controller.test.js diff --git a/test/unit/app/controllers/network/pending-middleware-test.js b/test/unit/app/controllers/network/pending-middleware.test.js similarity index 100% rename from test/unit/app/controllers/network/pending-middleware-test.js rename to test/unit/app/controllers/network/pending-middleware.test.js diff --git a/test/unit/app/controllers/permissions/permissions-controller-test.js b/test/unit/app/controllers/permissions/permissions-controller.test.js similarity index 100% rename from test/unit/app/controllers/permissions/permissions-controller-test.js rename to test/unit/app/controllers/permissions/permissions-controller.test.js diff --git a/test/unit/app/controllers/permissions/permissions-log-controller-test.js b/test/unit/app/controllers/permissions/permissions-log-controller.test.js similarity index 100% rename from test/unit/app/controllers/permissions/permissions-log-controller-test.js rename to test/unit/app/controllers/permissions/permissions-log-controller.test.js diff --git a/test/unit/app/controllers/permissions/permissions-middleware-test.js b/test/unit/app/controllers/permissions/permissions-middleware.test.js similarity index 100% rename from test/unit/app/controllers/permissions/permissions-middleware-test.js rename to test/unit/app/controllers/permissions/permissions-middleware.test.js diff --git a/test/unit/app/controllers/permissions/restricted-methods-test.js b/test/unit/app/controllers/permissions/restricted-methods.test.js similarity index 100% rename from test/unit/app/controllers/permissions/restricted-methods-test.js rename to test/unit/app/controllers/permissions/restricted-methods.test.js diff --git a/test/unit/app/controllers/preferences-controller-test.js b/test/unit/app/controllers/preferences-controller.test.js similarity index 100% rename from test/unit/app/controllers/preferences-controller-test.js rename to test/unit/app/controllers/preferences-controller.test.js diff --git a/test/unit/app/controllers/swaps-test.js b/test/unit/app/controllers/swaps.test.js similarity index 98% rename from test/unit/app/controllers/swaps-test.js rename to test/unit/app/controllers/swaps.test.js index 299f99229..8b9a2b0f6 100644 --- a/test/unit/app/controllers/swaps-test.js +++ b/test/unit/app/controllers/swaps.test.js @@ -9,7 +9,7 @@ import { ROPSTEN_NETWORK_ID, MAINNET_NETWORK_ID, } from '../../../../shared/constants/network'; -import { ETH_SWAPS_TOKEN_ADDRESS } from '../../../../ui/app/helpers/constants/swaps'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../../../../ui/app/helpers/constants/swaps'; import { createTestProviderTools } from '../../../stub/provider'; import SwapsController, { utils, @@ -471,7 +471,7 @@ describe('SwapsController', function () { getTopQuoteAndSavingsMockQuotes(), (quote) => ({ ...quote, - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, }), @@ -480,42 +480,42 @@ describe('SwapsController', function () { const expectedResultQuotes = { [TEST_AGG_ID_1]: { ...baseExpectedResultQuotes[TEST_AGG_ID_1], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '2.0195', }, [TEST_AGG_ID_2]: { ...baseExpectedResultQuotes[TEST_AGG_ID_2], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.9996', }, [TEST_AGG_ID_3]: { ...baseExpectedResultQuotes[TEST_AGG_ID_3], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.9698', }, [TEST_AGG_ID_4]: { ...baseExpectedResultQuotes[TEST_AGG_ID_4], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.94', }, [TEST_AGG_ID_5]: { ...baseExpectedResultQuotes[TEST_AGG_ID_5], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.9102', }, [TEST_AGG_ID_6]: { ...baseExpectedResultQuotes[TEST_AGG_ID_6], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.8705', @@ -535,7 +535,7 @@ describe('SwapsController', function () { getTopQuoteAndSavingsMockQuotes(), (quote) => ({ ...quote, - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, }), @@ -546,7 +546,7 @@ describe('SwapsController', function () { const expectedResultQuotes = { [TEST_AGG_ID_1]: { ...baseExpectedResultQuotes[TEST_AGG_ID_1], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8b553ece48ec0000' }, overallValueOfQuote: '1.9795', @@ -554,7 +554,7 @@ describe('SwapsController', function () { }, [TEST_AGG_ID_2]: { ...baseExpectedResultQuotes[TEST_AGG_ID_2], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.9996', @@ -569,28 +569,28 @@ describe('SwapsController', function () { }, [TEST_AGG_ID_3]: { ...baseExpectedResultQuotes[TEST_AGG_ID_3], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.9698', }, [TEST_AGG_ID_4]: { ...baseExpectedResultQuotes[TEST_AGG_ID_4], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.94', }, [TEST_AGG_ID_5]: { ...baseExpectedResultQuotes[TEST_AGG_ID_5], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.9102', }, [TEST_AGG_ID_6]: { ...baseExpectedResultQuotes[TEST_AGG_ID_6], - sourceToken: ETH_SWAPS_TOKEN_ADDRESS, + sourceToken: ETH_SWAPS_TOKEN_OBJECT.address, destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.8705', diff --git a/test/unit/app/controllers/token-rates-controller.js b/test/unit/app/controllers/token-rates-controller.test.js similarity index 100% rename from test/unit/app/controllers/token-rates-controller.js rename to test/unit/app/controllers/token-rates-controller.test.js diff --git a/test/unit/app/controllers/transactions/pending-tx-tracker-test.js b/test/unit/app/controllers/transactions/pending-tx-tracker.test.js similarity index 100% rename from test/unit/app/controllers/transactions/pending-tx-tracker-test.js rename to test/unit/app/controllers/transactions/pending-tx-tracker.test.js diff --git a/test/unit/app/controllers/transactions/tx-controller-test.js b/test/unit/app/controllers/transactions/tx-controller.test.js similarity index 99% rename from test/unit/app/controllers/transactions/tx-controller-test.js rename to test/unit/app/controllers/transactions/tx-controller.test.js index d8b362555..2dacf3c6a 100644 --- a/test/unit/app/controllers/transactions/tx-controller-test.js +++ b/test/unit/app/controllers/transactions/tx-controller.test.js @@ -437,6 +437,7 @@ describe('Transaction Controller', function () { gasPrice: originalValue, }, }; + // eslint-disable-next-line @babel/no-invalid-this this.timeout(15000); const wrongValue = '0x05'; diff --git a/test/unit/app/controllers/transactions/tx-gas-util-test.js b/test/unit/app/controllers/transactions/tx-gas-util.test.js similarity index 100% rename from test/unit/app/controllers/transactions/tx-gas-util-test.js rename to test/unit/app/controllers/transactions/tx-gas-util.test.js diff --git a/test/unit/app/controllers/transactions/tx-helper-test.js b/test/unit/app/controllers/transactions/tx-helper.test.js similarity index 100% rename from test/unit/app/controllers/transactions/tx-helper-test.js rename to test/unit/app/controllers/transactions/tx-helper.test.js diff --git a/test/unit/app/controllers/transactions/tx-state-history-helpers-test.js b/test/unit/app/controllers/transactions/tx-state-history-helpers.test.js similarity index 100% rename from test/unit/app/controllers/transactions/tx-state-history-helpers-test.js rename to test/unit/app/controllers/transactions/tx-state-history-helpers.test.js diff --git a/test/unit/app/controllers/transactions/tx-state-manager-test.js b/test/unit/app/controllers/transactions/tx-state-manager.test.js similarity index 100% rename from test/unit/app/controllers/transactions/tx-state-manager-test.js rename to test/unit/app/controllers/transactions/tx-state-manager.test.js diff --git a/test/unit/app/controllers/transactions/tx-utils-test.js b/test/unit/app/controllers/transactions/tx-utils.test.js similarity index 100% rename from test/unit/app/controllers/transactions/tx-utils-test.js rename to test/unit/app/controllers/transactions/tx-utils.test.js diff --git a/test/unit/app/message-manager-test.js b/test/unit/app/message-manager.test.js similarity index 100% rename from test/unit/app/message-manager-test.js rename to test/unit/app/message-manager.test.js diff --git a/test/unit/app/nodeify-test.js b/test/unit/app/nodeify.test.js similarity index 100% rename from test/unit/app/nodeify-test.js rename to test/unit/app/nodeify.test.js diff --git a/test/unit/app/personal-message-manager-test.js b/test/unit/app/personal-message-manager.test.js similarity index 100% rename from test/unit/app/personal-message-manager-test.js rename to test/unit/app/personal-message-manager.test.js diff --git a/test/unit/app/seed-phrase-verifier-test.js b/test/unit/app/seed-phrase-verifier.test.js similarity index 100% rename from test/unit/app/seed-phrase-verifier-test.js rename to test/unit/app/seed-phrase-verifier.test.js diff --git a/test/unit/app/typed-message-manager.spec.js b/test/unit/app/typed-message-manager.test.js similarity index 100% rename from test/unit/app/typed-message-manager.spec.js rename to test/unit/app/typed-message-manager.test.js diff --git a/test/unit/app/util-test.js b/test/unit/app/util.test.js similarity index 100% rename from test/unit/app/util-test.js rename to test/unit/app/util.test.js diff --git a/test/unit/balance-formatter-test.js b/test/unit/balance-formatter.test.js similarity index 100% rename from test/unit/balance-formatter-test.js rename to test/unit/balance-formatter.test.js diff --git a/test/unit/lib/account-link.test.js b/test/unit/lib/account-link.test.js index a8a25ee31..784133f75 100644 --- a/test/unit/lib/account-link.test.js +++ b/test/unit/lib/account-link.test.js @@ -1,4 +1,8 @@ import assert from 'assert'; +import { + MAINNET_CHAIN_ID, + ROPSTEN_CHAIN_ID, +} from '../../../shared/constants/network'; import getAccountLink from '../../../ui/lib/account-link'; describe('Account link', function () { @@ -7,19 +11,19 @@ describe('Account link', function () { const tests = [ { expected: 'https://etherscan.io/address/0xabcd', - network: 1, + chainId: MAINNET_CHAIN_ID, address: '0xabcd', }, { expected: 'https://ropsten.etherscan.io/address/0xdef0', - network: 3, + chainId: ROPSTEN_CHAIN_ID, address: '0xdef0', rpcPrefs: {}, }, { // test handling of `blockExplorerUrl` for a custom RPC expected: 'https://block.explorer/address/0xabcd', - network: 31, + chainId: '0x21', address: '0xabcd', rpcPrefs: { blockExplorerUrl: 'https://block.explorer', @@ -28,7 +32,7 @@ describe('Account link', function () { { // test handling of trailing `/` in `blockExplorerUrl` for a custom RPC expected: 'https://another.block.explorer/address/0xdef0', - network: 33, + chainId: '0x1f', address: '0xdef0', rpcPrefs: { blockExplorerUrl: 'https://another.block.explorer/', @@ -36,8 +40,8 @@ describe('Account link', function () { }, ]; - tests.forEach(({ expected, address, network, rpcPrefs }) => { - assert.equal(getAccountLink(address, network, rpcPrefs), expected); + tests.forEach(({ expected, address, chainId, rpcPrefs }) => { + assert.equal(getAccountLink(address, chainId, rpcPrefs), expected); }); }); }); diff --git a/test/unit/migrations/021-test.js b/test/unit/migrations/021.test.js similarity index 100% rename from test/unit/migrations/021-test.js rename to test/unit/migrations/021.test.js diff --git a/test/unit/migrations/022-test.js b/test/unit/migrations/022.test.js similarity index 100% rename from test/unit/migrations/022-test.js rename to test/unit/migrations/022.test.js diff --git a/test/unit/migrations/023-test.js b/test/unit/migrations/023.test.js similarity index 100% rename from test/unit/migrations/023-test.js rename to test/unit/migrations/023.test.js diff --git a/test/unit/migrations/024-test.js b/test/unit/migrations/024.test.js similarity index 100% rename from test/unit/migrations/024-test.js rename to test/unit/migrations/024.test.js diff --git a/test/unit/migrations/025-test.js b/test/unit/migrations/025.test.js similarity index 100% rename from test/unit/migrations/025-test.js rename to test/unit/migrations/025.test.js diff --git a/test/unit/migrations/026-test.js b/test/unit/migrations/026.test.js similarity index 100% rename from test/unit/migrations/026-test.js rename to test/unit/migrations/026.test.js diff --git a/test/unit/migrations/027-test.js b/test/unit/migrations/027.test.js similarity index 100% rename from test/unit/migrations/027-test.js rename to test/unit/migrations/027.test.js diff --git a/test/unit/migrations/028-test.js b/test/unit/migrations/028.test.js similarity index 100% rename from test/unit/migrations/028-test.js rename to test/unit/migrations/028.test.js diff --git a/test/unit/migrations/029-test.js b/test/unit/migrations/029.test.js similarity index 100% rename from test/unit/migrations/029-test.js rename to test/unit/migrations/029.test.js diff --git a/test/unit/migrations/030-test.js b/test/unit/migrations/030.test.js similarity index 100% rename from test/unit/migrations/030-test.js rename to test/unit/migrations/030.test.js diff --git a/test/unit/migrations/031-test.js b/test/unit/migrations/031.test.js similarity index 100% rename from test/unit/migrations/031-test.js rename to test/unit/migrations/031.test.js diff --git a/test/unit/migrations/033-test.js b/test/unit/migrations/033.test.js similarity index 100% rename from test/unit/migrations/033-test.js rename to test/unit/migrations/033.test.js diff --git a/test/unit/migrations/034-test.js b/test/unit/migrations/034.test.js similarity index 100% rename from test/unit/migrations/034-test.js rename to test/unit/migrations/034.test.js diff --git a/test/unit/migrations/035-test.js b/test/unit/migrations/035.test.js similarity index 100% rename from test/unit/migrations/035-test.js rename to test/unit/migrations/035.test.js diff --git a/test/unit/migrations/036-test.js b/test/unit/migrations/036.test.js similarity index 100% rename from test/unit/migrations/036-test.js rename to test/unit/migrations/036.test.js diff --git a/test/unit/migrations/037-test.js b/test/unit/migrations/037.test.js similarity index 100% rename from test/unit/migrations/037-test.js rename to test/unit/migrations/037.test.js diff --git a/test/unit/migrations/038-test.js b/test/unit/migrations/038.test.js similarity index 100% rename from test/unit/migrations/038-test.js rename to test/unit/migrations/038.test.js diff --git a/test/unit/migrations/039-test.js b/test/unit/migrations/039.test.js similarity index 100% rename from test/unit/migrations/039-test.js rename to test/unit/migrations/039.test.js diff --git a/test/unit/migrations/040-test.js b/test/unit/migrations/040.test.js similarity index 100% rename from test/unit/migrations/040-test.js rename to test/unit/migrations/040.test.js diff --git a/test/unit/migrations/041-test.js b/test/unit/migrations/041.test.js similarity index 100% rename from test/unit/migrations/041-test.js rename to test/unit/migrations/041.test.js diff --git a/test/unit/migrations/042-test.js b/test/unit/migrations/042.test.js similarity index 100% rename from test/unit/migrations/042-test.js rename to test/unit/migrations/042.test.js diff --git a/test/unit/migrations/043-test.js b/test/unit/migrations/043.test.js similarity index 100% rename from test/unit/migrations/043-test.js rename to test/unit/migrations/043.test.js diff --git a/test/unit/migrations/044-test.js b/test/unit/migrations/044.test.js similarity index 100% rename from test/unit/migrations/044-test.js rename to test/unit/migrations/044.test.js diff --git a/test/unit/migrations/045-test.js b/test/unit/migrations/045.test.js similarity index 100% rename from test/unit/migrations/045-test.js rename to test/unit/migrations/045.test.js diff --git a/test/unit/migrations/046-test.js b/test/unit/migrations/046.test.js similarity index 100% rename from test/unit/migrations/046-test.js rename to test/unit/migrations/046.test.js diff --git a/test/unit/migrations/047-test.js b/test/unit/migrations/047.test.js similarity index 100% rename from test/unit/migrations/047-test.js rename to test/unit/migrations/047.test.js diff --git a/test/unit/migrations/048-test.js b/test/unit/migrations/048.test.js similarity index 100% rename from test/unit/migrations/048-test.js rename to test/unit/migrations/048.test.js diff --git a/test/unit/migrations/049-test.js b/test/unit/migrations/049.test.js similarity index 100% rename from test/unit/migrations/049-test.js rename to test/unit/migrations/049.test.js diff --git a/test/unit/migrations/050-test.js b/test/unit/migrations/050.test.js similarity index 100% rename from test/unit/migrations/050-test.js rename to test/unit/migrations/050.test.js diff --git a/test/unit/migrations/051-test.js b/test/unit/migrations/051.test.js similarity index 100% rename from test/unit/migrations/051-test.js rename to test/unit/migrations/051.test.js diff --git a/test/unit/migrations/052-test.js b/test/unit/migrations/052.test.js similarity index 100% rename from test/unit/migrations/052-test.js rename to test/unit/migrations/052.test.js diff --git a/test/unit/migrations/migrations-test.js b/test/unit/migrations/migrations.test.js similarity index 100% rename from test/unit/migrations/migrations-test.js rename to test/unit/migrations/migrations.test.js diff --git a/test/unit/migrations/migrator-test.js b/test/unit/migrations/migrator.test.js similarity index 98% rename from test/unit/migrations/migrator-test.js rename to test/unit/migrations/migrator.test.js index ee20cc7a6..bb0771cd9 100644 --- a/test/unit/migrations/migrator-test.js +++ b/test/unit/migrations/migrator.test.js @@ -70,7 +70,7 @@ describe('migrations', function () { const fileNames = fs.readdirSync('./test/unit/migrations/'); const testNumbers = fileNames .reduce((acc, filename) => { - const name = filename.split('-test.')[0]; + const name = filename.split('.test.')[0]; if (/^\d+$/u.test(name)) { acc.push(name); } diff --git a/test/unit/migrations/template-test.js b/test/unit/migrations/template.test.js similarity index 100% rename from test/unit/migrations/template-test.js rename to test/unit/migrations/template.test.js diff --git a/test/unit/responsive/components/dropdown-test.js b/test/unit/responsive/components/dropdown.test.js similarity index 100% rename from test/unit/responsive/components/dropdown-test.js rename to test/unit/responsive/components/dropdown.test.js diff --git a/test/unit/ui/app/actions.spec.js b/test/unit/ui/app/actions.test.js similarity index 99% rename from test/unit/ui/app/actions.spec.js rename to test/unit/ui/app/actions.test.js index 5cb248434..705783dbd 100644 --- a/test/unit/ui/app/actions.spec.js +++ b/test/unit/ui/app/actions.test.js @@ -588,13 +588,18 @@ describe('Actions', function () { it('calls unlockHardwareWalletAccount in background', async function () { const store = mockStore(); const unlockHardwareWalletAccount = background.unlockHardwareWalletAccount.callsFake( - (_, __, ___, cb) => cb(), + (_, __, ___, ____, cb) => cb(), ); actions._setBackgroundConnection(background); await store.dispatch( - actions.unlockHardwareWalletAccount('ledger', 0, `m/44'/60'/0'/0`), + actions.unlockHardwareWalletAccounts( + [0], + 'ledger', + `m/44'/60'/0'/0`, + '', + ), ); assert(unlockHardwareWalletAccount.calledOnce); }); @@ -602,7 +607,7 @@ describe('Actions', function () { it('shows loading indicator and displays error', async function () { const store = mockStore(); - background.unlockHardwareWalletAccount.callsFake((_, __, ___, cb) => + background.unlockHardwareWalletAccount.callsFake((_, __, ___, ____, cb) => cb(new Error('error')), ); @@ -610,12 +615,12 @@ describe('Actions', function () { const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, - { type: 'HIDE_LOADING_INDICATION' }, { type: 'DISPLAY_WARNING', value: 'error' }, + { type: 'HIDE_LOADING_INDICATION' }, ]; try { - await store.dispatch(actions.unlockHardwareWalletAccount()); + await store.dispatch(actions.unlockHardwareWalletAccounts([null])); assert.fail('Should have thrown error'); } catch (error) { assert.deepStrictEqual(store.getActions(), expectedActions); diff --git a/test/unit/ui/app/reducers/app.spec.js b/test/unit/ui/app/reducers/app.test.js similarity index 100% rename from test/unit/ui/app/reducers/app.spec.js rename to test/unit/ui/app/reducers/app.test.js diff --git a/test/unit/ui/app/reducers/metamask.spec.js b/test/unit/ui/app/reducers/metamask.test.js similarity index 100% rename from test/unit/ui/app/reducers/metamask.spec.js rename to test/unit/ui/app/reducers/metamask.test.js diff --git a/test/unit/ui/etherscan-prefix-for-network.spec.js b/test/unit/ui/etherscan-prefix-for-network.spec.js deleted file mode 100644 index e53c32e5e..000000000 --- a/test/unit/ui/etherscan-prefix-for-network.spec.js +++ /dev/null @@ -1,28 +0,0 @@ -import assert from 'assert'; -import { getEtherscanNetworkPrefix } from '../../../ui/lib/etherscan-prefix-for-network'; - -describe('Etherscan Network Prefix', function () { - it('returns empty string as default value', function () { - assert.equal(getEtherscanNetworkPrefix(), ''); - }); - - it('returns empty string as a prefix for networkId of 1', function () { - assert.equal(getEtherscanNetworkPrefix('1'), ''); - }); - - it('returns ropsten as prefix for networkId of 3', function () { - assert.equal(getEtherscanNetworkPrefix('3'), 'ropsten.'); - }); - - it('returns rinkeby as prefix for networkId of 4', function () { - assert.equal(getEtherscanNetworkPrefix('4'), 'rinkeby.'); - }); - - it('returs kovan as prefix for networkId of 42', function () { - assert.equal(getEtherscanNetworkPrefix('42'), 'kovan.'); - }); - - it('returs goerli as prefix for networkId of 5', function () { - assert.equal(getEtherscanNetworkPrefix('5'), 'goerli.'); - }); -}); diff --git a/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js b/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js index 701ffa163..57cae337e 100644 --- a/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js +++ b/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js @@ -11,10 +11,9 @@ import { renderWithProvider } from '../../../../../../../test/lib/render-helpers import * as actions from '../../../../../store/actions'; import UnconnectedAccountAlert from '..'; +import { KOVAN_CHAIN_ID } from '../../../../../../../shared/constants/network'; describe('Unconnected Account Alert', function () { - const network = '123'; - const selectedAddress = '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b'; const identities = { @@ -40,7 +39,7 @@ describe('Unconnected Account Alert', function () { }; const cachedBalances = { - 123: { + [KOVAN_CHAIN_ID]: { '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': '0x0', '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b': '0x0', }, @@ -58,12 +57,14 @@ describe('Unconnected Account Alert', function () { const mockState = { metamask: { - network, selectedAddress, identities, accounts, cachedBalances, keyrings, + provider: { + chainId: KOVAN_CHAIN_ID, + }, permissionsHistory: { 'https://test.dapp': { eth_accounts: { diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js index e394b453a..a775cec65 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js @@ -20,10 +20,12 @@ export default class AdvancedGasInputs extends Component { isSpeedUp: PropTypes.bool, customGasLimitMessage: PropTypes.string, minimumGasLimit: PropTypes.number, + customPriceIsExcessive: PropTypes.bool, }; static defaultProps = { minimumGasLimit: Number(MIN_GAS_LIMIT_DEC), + customPriceIsExcessive: false, }; constructor(props) { @@ -75,6 +77,7 @@ export default class AdvancedGasInputs extends Component { customPriceIsSafe, isSpeedUp, gasPrice, + customPriceIsExcessive, }) { const { t } = this.context; @@ -93,6 +96,11 @@ export default class AdvancedGasInputs extends Component { errorText: t('gasPriceExtremelyLow'), errorType: 'warning', }; + } else if (customPriceIsExcessive) { + return { + errorText: t('gasPriceExcessiveInput'), + errorType: 'error', + }; } return {}; @@ -185,6 +193,7 @@ export default class AdvancedGasInputs extends Component { isSpeedUp, customGasLimitMessage, minimumGasLimit, + customPriceIsExcessive, } = this.props; const { gasPrice, gasLimit } = this.state; @@ -196,6 +205,7 @@ export default class AdvancedGasInputs extends Component { customPriceIsSafe, isSpeedUp, gasPrice, + customPriceIsExcessive, }); const gasPriceErrorComponent = gasPriceErrorType ? (
diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 4c27f9900..f57cce92d 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -35,6 +35,7 @@ export default class GasModalPageContainer extends Component { isSpeedUp: PropTypes.bool, isRetry: PropTypes.bool, disableSave: PropTypes.bool, + customPriceIsExcessive: PropTypes.bool.isRequired, }; componentDidMount() { @@ -57,6 +58,7 @@ export default class GasModalPageContainer extends Component { customPriceIsSafe, isSpeedUp, isRetry, + customPriceIsExcessive, infoRowProps: { transactionFee }, } = this.props; @@ -71,6 +73,7 @@ export default class GasModalPageContainer extends Component { customPriceIsSafe={customPriceIsSafe} isSpeedUp={isSpeedUp} isRetry={isRetry} + customPriceIsExcessive={customPriceIsExcessive} /> ); } diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index fc1b111b9..136fdccc8 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -37,6 +37,7 @@ import { getTokenBalance, getSendMaxModeState, getAveragePriceEstimateInHexWEI, + isCustomPriceExcessive, } from '../../../../selectors'; import { @@ -141,6 +142,7 @@ const mapStateToProps = (state, ownProps) => { customGasTotal, newTotalFiat, customPriceIsSafe: isCustomPriceSafe(state), + customPriceIsExcessive: isCustomPriceExcessive(state), maxModeOn, gasPriceButtonGroupProps: { buttonDataLoading, diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 100e30780..0ba5aabbc 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -126,6 +126,7 @@ describe('gas-modal-page-container container', function () { conversionRate: 50, customModalGasLimitInHex: 'aaaaaaaa', customModalGasPriceInHex: 'ffffffff', + customPriceIsExcessive: false, customGasTotal: 'aaaaaaa955555556', customPriceIsSafe: true, gasPriceButtonGroupProps: { diff --git a/ui/app/components/app/menu-bar/account-options-menu.js b/ui/app/components/app/menu-bar/account-options-menu.js index 8d11bb057..b8ea6d1d4 100644 --- a/ui/app/components/app/menu-bar/account-options-menu.js +++ b/ui/app/components/app/menu-bar/account-options-menu.js @@ -8,8 +8,8 @@ import { CONNECTED_ROUTE } from '../../../helpers/constants/routes'; import { Menu, MenuItem } from '../../ui/menu'; import getAccountLink from '../../../../lib/account-link'; import { + getCurrentChainId, getCurrentKeyring, - getCurrentNetwork, getRpcPrefsForCurrentProvider, getSelectedIdentity, } from '../../../selectors'; @@ -52,7 +52,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { }); const keyring = useSelector(getCurrentKeyring); - const network = useSelector(getCurrentNetwork); + const chainId = useSelector(getCurrentChainId); const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider); const selectedIdentity = useSelector(getSelectedIdentity); @@ -92,7 +92,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { onClick={() => { viewOnEtherscanEvent(); global.platform.openTab({ - url: getAccountLink(address, network, rpcPrefs), + url: getAccountLink(address, chainId, rpcPrefs), }); onClose(); }} diff --git a/ui/app/components/app/menu-bar/tests/menu-bar.test.js b/ui/app/components/app/menu-bar/tests/menu-bar.test.js index 4960ef627..fbac945f2 100644 --- a/ui/app/components/app/menu-bar/tests/menu-bar.test.js +++ b/ui/app/components/app/menu-bar/tests/menu-bar.test.js @@ -4,11 +4,14 @@ import { Provider } from 'react-redux'; import configureStore from 'redux-mock-store'; import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; import MenuBar from '..'; +import { ROPSTEN_CHAIN_ID } from '../../../../../../shared/constants/network'; const initState = { activeTab: {}, metamask: { - network: '1', + provider: { + chainId: ROPSTEN_CHAIN_ID, + }, selectedAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', identities: { '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': { diff --git a/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js index fb01b6e41..7e36e0a6c 100644 --- a/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js +++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js @@ -9,7 +9,7 @@ import Button from '../../../ui/button'; export default class AccountDetailsModal extends Component { static propTypes = { selectedIdentity: PropTypes.object, - network: PropTypes.string, + chainId: PropTypes.string, showExportPrivateKeyModal: PropTypes.func, setAccountLabel: PropTypes.func, keyrings: PropTypes.array, @@ -23,7 +23,7 @@ export default class AccountDetailsModal extends Component { render() { const { selectedIdentity, - network, + chainId, showExportPrivateKeyModal, setAccountLabel, keyrings, @@ -62,7 +62,7 @@ export default class AccountDetailsModal extends Component { className="account-details-modal__button" onClick={() => { global.platform.openTab({ - url: getAccountLink(address, network, rpcPrefs), + url: getAccountLink(address, chainId, rpcPrefs), }); }} > diff --git a/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js index 8267e1a4b..04f28d976 100644 --- a/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js +++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js @@ -3,12 +3,13 @@ import { showModal, setAccountLabel } from '../../../../store/actions'; import { getSelectedIdentity, getRpcPrefsForCurrentProvider, + getCurrentChainId, } from '../../../../selectors'; import AccountDetailsModal from './account-details-modal.component'; const mapStateToProps = (state) => { return { - network: state.metamask.network, + chainId: getCurrentChainId(state), selectedIdentity: getSelectedIdentity(state), keyrings: state.metamask.keyrings, rpcPrefs: getRpcPrefsForCurrentProvider(state), diff --git a/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.component.js b/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.component.js index 7c7213aa0..8c2831c2c 100644 --- a/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.component.js +++ b/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.component.js @@ -10,7 +10,8 @@ export default class ConfirmRemoveAccount extends Component { hideModal: PropTypes.func.isRequired, removeAccount: PropTypes.func.isRequired, identity: PropTypes.object.isRequired, - network: PropTypes.string.isRequired, + chainId: PropTypes.string.isRequired, + rpcPrefs: PropTypes.object.isRequired, }; static contextTypes = { @@ -49,7 +50,11 @@ export default class ConfirmRemoveAccount extends Component {
{ return { - network: state.metamask.network, + chainId: getCurrentChainId(state), + rpcPrefs: getRpcPrefsForCurrentProvider(state), }; }; diff --git a/ui/app/components/app/token-list/token-list.js b/ui/app/components/app/token-list/token-list.js index 298dda081..9d0fdc77e 100644 --- a/ui/app/components/app/token-list/token-list.js +++ b/ui/app/components/app/token-list/token-list.js @@ -6,18 +6,27 @@ import { useSelector } from 'react-redux'; import TokenCell from '../token-cell'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { useTokenTracker } from '../../../hooks/useTokenTracker'; -import { getAssetImages } from '../../../selectors'; +import { + getAssetImages, + getShouldHideZeroBalanceTokens, +} from '../../../selectors'; import { getTokens } from '../../../ducks/metamask/metamask'; export default function TokenList({ onTokenClick }) { const t = useI18nContext(); const assetImages = useSelector(getAssetImages); + const shouldHideZeroBalanceTokens = useSelector( + getShouldHideZeroBalanceTokens, + ); // use `isEqual` comparison function because the token array is serialized // from the background so it has a new reference with each background update, // even if the tokens haven't changed const tokens = useSelector(getTokens, isEqual); - const { loading, tokensWithBalances } = useTokenTracker(tokens, true); - + const { loading, tokensWithBalances } = useTokenTracker( + tokens, + true, + shouldHideZeroBalanceTokens, + ); if (loading) { return (
{ - const { primaryTransaction } = this.props; - const { metamaskNetworkId } = primaryTransaction; - - const prefix = getEtherscanNetworkPrefix(metamaskNetworkId); - const etherscanUrl = `https://${prefix}etherscan.io/tx/${hash}`; - + handleActivityClick = (activity) => { + const etherscanUrl = getBlockExplorerUrlForTx( + activity, + this.props.rpcPrefs, + ); global.platform.openTab({ url: etherscanUrl }); }; @@ -79,7 +79,7 @@ export default class TransactionActivityLog extends PureComponent { renderActivity(activity, index) { const { conversionRate, nativeCurrency } = this.props; - const { eventKey, value, timestamp, hash } = activity; + const { eventKey, value, timestamp } = activity; const ethValue = index === 0 ? `${getValueFromWeiHex({ @@ -111,7 +111,7 @@ export default class TransactionActivityLog extends PureComponent {
this.handleActivityClick(hash)} + onClick={() => this.handleActivityClick(activity)} > {activityText}
diff --git a/ui/app/components/app/transaction-activity-log/transaction-activity-log.container.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log.container.js index bea5e6f7a..99f96baca 100644 --- a/ui/app/components/app/transaction-activity-log/transaction-activity-log.container.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log.container.js @@ -1,6 +1,10 @@ import { connect } from 'react-redux'; import { findLastIndex } from 'lodash'; -import { conversionRateSelector, getNativeCurrency } from '../../../selectors'; +import { + conversionRateSelector, + getNativeCurrency, + getRpcPrefsForCurrentProvider, +} from '../../../selectors'; import TransactionActivityLog from './transaction-activity-log.component'; import { combineTransactionHistories } from './transaction-activity-log.util'; import { @@ -15,6 +19,7 @@ const mapStateToProps = (state) => { return { conversionRate: conversionRateSelector(state), nativeCurrency: getNativeCurrency(state), + rpcPrefs: getRpcPrefsForCurrentProvider(state), }; }; diff --git a/ui/app/components/app/transaction-activity-log/transaction-activity-log.util.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log.util.js index 0846b85bc..624e1027d 100644 --- a/ui/app/components/app/transaction-activity-log/transaction-activity-log.util.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log.util.js @@ -49,6 +49,8 @@ const statusHash = { export function getActivities(transaction, isFirstTransaction = false) { const { id, + chainId, + metamaskNetworkId, hash, history = [], txParams: { gas: paramsGasLimit, gasPrice: paramsGasPrice }, @@ -76,6 +78,8 @@ export function getActivities(transaction, isFirstTransaction = false) { return acc.concat({ id, hash, + chainId, + metamaskNetworkId, eventKey: TRANSACTION_CREATED_EVENT, timestamp, value, @@ -127,6 +131,8 @@ export function getActivities(transaction, isFirstTransaction = false) { hash, eventKey, timestamp, + chainId, + metamaskNetworkId, value: gasFee, }); } @@ -165,6 +171,8 @@ export function getActivities(transaction, isFirstTransaction = false) { events.push({ id, hash, + chainId, + metamaskNetworkId, eventKey: TRANSACTION_UPDATED_EVENT, timestamp, }); @@ -185,6 +193,8 @@ export function getActivities(transaction, isFirstTransaction = false) { ? historyActivities.concat({ id, hash, + chainId, + metamaskNetworkId, eventKey: TRANSACTION_ERRORED_EVENT, }) : historyActivities; diff --git a/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js b/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js index faa80846c..3c93ff921 100644 --- a/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js +++ b/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js @@ -1,7 +1,6 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import copyToClipboard from 'copy-to-clipboard'; -import { getBlockExplorerUrlForTx } from '../../../helpers/utils/transactions.util'; import SenderToRecipient from '../../ui/sender-to-recipient'; import { FLAT_VARIANT } from '../../ui/sender-to-recipient/sender-to-recipient.constants'; import TransactionActivityLog from '../transaction-activity-log'; @@ -10,6 +9,7 @@ import Button from '../../ui/button'; import Tooltip from '../../ui/tooltip'; import Copy from '../../ui/icon/copy-icon.component'; import Popover from '../../ui/popover'; +import { getBlockExplorerUrlForTx } from '../../../../../shared/modules/transaction.utils'; export default class TransactionListItemDetails extends PureComponent { static contextTypes = { @@ -51,7 +51,6 @@ export default class TransactionListItemDetails extends PureComponent { transactionGroup: { primaryTransaction }, rpcPrefs, } = this.props; - const { hash, metamaskNetworkId } = primaryTransaction; this.context.metricsEvent({ eventOpts: { @@ -62,7 +61,7 @@ export default class TransactionListItemDetails extends PureComponent { }); global.platform.openTab({ - url: getBlockExplorerUrlForTx(metamaskNetworkId, hash, rpcPrefs), + url: getBlockExplorerUrlForTx(primaryTransaction, rpcPrefs), }); }; diff --git a/ui/app/components/app/wallet-overview/eth-overview.js b/ui/app/components/app/wallet-overview/eth-overview.js index d1de6730b..38ada5c24 100644 --- a/ui/app/components/app/wallet-overview/eth-overview.js +++ b/ui/app/components/app/wallet-overview/eth-overview.js @@ -14,7 +14,6 @@ import { useMetricEvent, useNewMetricEvent, } from '../../../hooks/useMetricEvent'; -import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken'; import Tooltip from '../../ui/tooltip'; import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'; import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'; @@ -26,6 +25,7 @@ import { getIsMainnet, getIsTestnet, getCurrentKeyring, + getSwapsEthToken, } from '../../../selectors/selectors'; import SwapIcon from '../../ui/icon/swap-icon.component'; import BuyIcon from '../../ui/icon/overview-buy-icon.component'; @@ -69,7 +69,7 @@ const EthOverview = ({ className }) => { category: 'swaps', }); const swapsEnabled = useSelector(getSwapsFeatureLiveness); - const swapsEthToken = useSwapsEthToken(); + const swapsEthToken = useSelector(getSwapsEthToken); return ( { + if (event.key === 'Enter') { + onClick(); + } + }} > {icon &&
{icon}
}
{React.isValidElement(title) ? ( title ) : ( - +

{title}

)} {titleIcon && (
{titleIcon}
diff --git a/ui/app/ducks/gas/gas-duck.test.js b/ui/app/ducks/gas/gas-duck.test.js index b1c8447d9..b66b1dadd 100644 --- a/ui/app/ducks/gas/gas-duck.test.js +++ b/ui/app/ducks/gas/gas-duck.test.js @@ -1,48 +1,26 @@ import assert from 'assert'; import nock from 'nock'; import sinon from 'sinon'; -import proxyquire from 'proxyquire'; import BN from 'bn.js'; -const fakeStorage = {}; - -const GasDuck = proxyquire('./gas.duck.js', { - '../../../lib/storage-helpers': fakeStorage, -}); - -const { +import GasDuck, { basicGasEstimatesLoadingStarted, basicGasEstimatesLoadingFinished, setBasicGasEstimateData, setCustomGasPrice, setCustomGasLimit, - resetCustomGasState, fetchBasicGasEstimates, -} = GasDuck; -const GasReducer = GasDuck.default; +} from './gas.duck'; + +const mockGasPriceApiResponse = { + SafeGasPrice: 10, + ProposeGasPrice: 20, + FastGasPrice: 30, +}; + +const GasReducer = GasDuck; describe('Gas Duck', function () { - let tempDateNow; - const mockGasPriceApiResponse = { - SafeGasPrice: 10, - ProposeGasPrice: 20, - FastGasPrice: 30, - }; - - beforeEach(function () { - tempDateNow = global.Date.now; - - fakeStorage.getStorageItem = sinon.stub(); - fakeStorage.setStorageItem = sinon.spy(); - global.Date.now = () => 2000000; - }); - - afterEach(function () { - sinon.restore(); - - global.Date.now = tempDateNow; - }); - const mockState = { mockProp: 123, }; @@ -57,7 +35,6 @@ describe('Gas Duck', function () { safeLow: null, }, basicEstimateIsLoading: true, - basicPriceEstimatesLastRetrieved: 0, }; const providerState = { @@ -73,13 +50,10 @@ describe('Gas Duck', function () { 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED'; const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED'; - const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE'; const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA'; const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT'; const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE'; - const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED'; describe('GasReducer()', function () { it('should initialize state', function () { @@ -139,13 +113,6 @@ describe('Gas Duck', function () { { customData: { limit: 9876 }, ...mockState }, ); }); - - it('should return the initial state in response to a RESET_CUSTOM_GAS_STATE action', function () { - assert.deepStrictEqual( - GasReducer(mockState, { type: RESET_CUSTOM_GAS_STATE }), - initState, - ); - }); }); describe('basicGasEstimatesLoadingStarted', function () { @@ -167,7 +134,6 @@ describe('Gas Duck', function () { describe('fetchBasicGasEstimates', function () { it('should call fetch with the expected params', async function () { const mockDistpatch = sinon.spy(); - const windowFetchSpy = sinon.spy(window, 'fetch'); nock('https://api.metaswap.codefi.network') @@ -175,32 +141,21 @@ describe('Gas Duck', function () { .reply(200, mockGasPriceApiResponse); await fetchBasicGasEstimates()(mockDistpatch, () => ({ - gas: { ...initState, basicPriceAEstimatesLastRetrieved: 1000000 }, + gas: { ...initState }, metamask: { provider: { ...providerState } }, })); assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, ]); + assert.ok( windowFetchSpy .getCall(0) .args[0].startsWith('https://api.metaswap.codefi.network/gasPrices'), 'should fetch metaswap /gasPrices', ); - assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ - { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, - ]); + assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ - { - type: SET_BASIC_GAS_ESTIMATE_DATA, - value: { - average: 20, - fast: 30, - safeLow: 10, - }, - }, - ]); - assert.deepStrictEqual(mockDistpatch.getCall(3).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, ]); }); @@ -209,7 +164,7 @@ describe('Gas Duck', function () { global.eth = { gasPrice: sinon.fake.returns(new BN(48199313, 10)) }; const mockDistpatch = sinon.spy(); - const providerStateForTestNetwrok = { + const providerStateForTestNetwork = { chainId: '0x5', nickname: '', rpcPrefs: {}, @@ -219,8 +174,8 @@ describe('Gas Duck', function () { }; await fetchBasicGasEstimates()(mockDistpatch, () => ({ - gas: { ...initState, basicPriceAEstimatesLastRetrieved: 1000000 }, - metamask: { provider: { ...providerStateForTestNetwrok } }, + gas: { ...initState }, + metamask: { provider: { ...providerStateForTestNetwork } }, })); assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, @@ -237,88 +192,6 @@ describe('Gas Duck', function () { { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, ]); }); - - it('should fetch recently retrieved estimates from storage', async function () { - const mockDistpatch = sinon.spy(); - - const windowFetchSpy = sinon.spy(window, 'fetch'); - - fakeStorage.getStorageItem - .withArgs('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') - .returns(2000000 - 1); // one second ago from "now" - fakeStorage.getStorageItem.withArgs('BASIC_PRICE_ESTIMATES').returns({ - average: 25, - fast: 35, - safeLow: 15, - }); - - await fetchBasicGasEstimates()(mockDistpatch, () => ({ - gas: { ...initState }, - metamask: { provider: { ...providerState } }, - })); - assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]); - assert.ok(windowFetchSpy.notCalled); - assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ - { - type: SET_BASIC_GAS_ESTIMATE_DATA, - value: { - average: 25, - fast: 35, - safeLow: 15, - }, - }, - ]); - assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]); - }); - - it('should fallback to network if retrieving estimates from storage fails', async function () { - const mockDistpatch = sinon.spy(); - - const windowFetchSpy = sinon.spy(window, 'fetch'); - - nock('https://api.metaswap.codefi.network') - .get('/gasPrices') - .reply(200, mockGasPriceApiResponse); - - fakeStorage.getStorageItem - .withArgs('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') - .returns(2000000 - 1); // one second ago from "now" - - await fetchBasicGasEstimates()(mockDistpatch, () => ({ - gas: { ...initState }, - metamask: { provider: { ...providerState } }, - })); - assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]); - assert.ok( - windowFetchSpy - .getCall(0) - .args[0].startsWith('https://api.metaswap.codefi.network/gasPrices'), - 'should fetch metaswap /gasPrices', - ); - - assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ - { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, - ]); - assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ - { - type: SET_BASIC_GAS_ESTIMATE_DATA, - value: { - safeLow: 10, - average: 20, - fast: 30, - }, - }, - ]); - assert.deepStrictEqual(mockDistpatch.getCall(3).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]); - }); }); describe('setBasicGasEstimateData', function () { @@ -347,12 +220,4 @@ describe('Gas Duck', function () { }); }); }); - - describe('resetCustomGasState', function () { - it('should create the correct action', function () { - assert.deepStrictEqual(resetCustomGasState(), { - type: RESET_CUSTOM_GAS_STATE, - }); - }); - }); }); diff --git a/ui/app/ducks/gas/gas.duck.js b/ui/app/ducks/gas/gas.duck.js index d97dd70c4..5785b2cf3 100644 --- a/ui/app/ducks/gas/gas.duck.js +++ b/ui/app/ducks/gas/gas.duck.js @@ -5,23 +5,18 @@ import { decGWEIToHexWEI, getValueFromWeiHex, } from '../../helpers/utils/conversions.util'; -import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'; import { getIsMainnet, getCurrentChainId } from '../../selectors'; - -const fetchWithTimeout = getFetchWithTimeout(30000); +import fetchWithCache from '../../helpers/utils/fetch-with-cache'; // Actions const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED'; const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED'; -const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE'; const RESET_CUSTOM_DATA = 'metamask/gas/RESET_CUSTOM_DATA'; const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA'; const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT'; const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE'; -const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED'; const initState = { customData: { @@ -34,7 +29,6 @@ const initState = { fast: null, }, basicEstimateIsLoading: true, - basicPriceEstimatesLastRetrieved: 0, }; // Reducer @@ -71,18 +65,11 @@ export default function reducer(state = initState, action) { limit: action.value, }, }; - case SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED: - return { - ...state, - basicPriceEstimatesLastRetrieved: action.value, - }; case RESET_CUSTOM_DATA: return { ...state, customData: cloneDeep(initState.customData), }; - case RESET_CUSTOM_GAS_STATE: - return cloneDeep(initState); default: return state; } @@ -103,40 +90,27 @@ export function basicGasEstimatesLoadingFinished() { async function basicGasPriceQuery() { const url = `https://api.metaswap.codefi.network/gasPrices`; - return await fetchWithTimeout(url, { - headers: {}, - referrer: 'https://api.metaswap.codefi.network/gasPrices', - referrerPolicy: 'no-referrer-when-downgrade', - body: null, - method: 'GET', - mode: 'cors', - }); + return await fetchWithCache( + url, + { + referrer: url, + referrerPolicy: 'no-referrer-when-downgrade', + method: 'GET', + mode: 'cors', + }, + { cacheRefreshTime: 75000 }, + ); } export function fetchBasicGasEstimates() { return async (dispatch, getState) => { const isMainnet = getIsMainnet(getState()); - const { basicPriceEstimatesLastRetrieved } = getState().gas; - - const timeLastRetrieved = - basicPriceEstimatesLastRetrieved || - (await getStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED')) || - 0; dispatch(basicGasEstimatesLoadingStarted()); let basicEstimates; if (isMainnet || process.env.IN_TEST) { - if (Date.now() - timeLastRetrieved > 75000) { - basicEstimates = await fetchExternalBasicGasEstimates(dispatch); - } else { - const cachedBasicEstimates = await getStorageItem( - 'BASIC_PRICE_ESTIMATES', - ); - basicEstimates = - cachedBasicEstimates || - (await fetchExternalBasicGasEstimates(dispatch)); - } + basicEstimates = await fetchExternalBasicGasEstimates(); } else { basicEstimates = await fetchEthGasPriceEstimates(getState()); } @@ -148,10 +122,12 @@ export function fetchBasicGasEstimates() { }; } -async function fetchExternalBasicGasEstimates(dispatch) { - const response = await basicGasPriceQuery(); - - const { SafeGasPrice, ProposeGasPrice, FastGasPrice } = await response.json(); +async function fetchExternalBasicGasEstimates() { + const { + SafeGasPrice, + ProposeGasPrice, + FastGasPrice, + } = await basicGasPriceQuery(); const [safeLow, average, fast] = [ SafeGasPrice, @@ -165,12 +141,6 @@ async function fetchExternalBasicGasEstimates(dispatch) { fast, }; - const timeRetrieved = Date.now(); - await Promise.all([ - setStorageItem('BASIC_PRICE_ESTIMATES', basicEstimates), - setStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED', timeRetrieved), - ]); - dispatch(setBasicPriceEstimatesLastRetrieved(timeRetrieved)); return basicEstimates; } @@ -209,7 +179,7 @@ async function fetchEthGasPriceEstimates(state) { export function setCustomGasPriceForRetry(newPrice) { return async (dispatch) => { if (newPrice === '0x0') { - const { fast } = await getStorageItem('BASIC_PRICE_ESTIMATES'); + const { fast } = await fetchExternalBasicGasEstimates(); dispatch(setCustomGasPrice(decGWEIToHexWEI(fast))); } else { dispatch(setCustomGasPrice(newPrice)); @@ -238,17 +208,6 @@ export function setCustomGasLimit(newLimit) { }; } -export function setBasicPriceEstimatesLastRetrieved(retrievalTime) { - return { - type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, - value: retrievalTime, - }; -} - -export function resetCustomGasState() { - return { type: RESET_CUSTOM_GAS_STATE }; -} - export function resetCustomData() { return { type: RESET_CUSTOM_DATA }; } diff --git a/ui/app/helpers/constants/swaps.js b/ui/app/helpers/constants/swaps.js index 1011306a8..7ae20c5ae 100644 --- a/ui/app/helpers/constants/swaps.js +++ b/ui/app/helpers/constants/swaps.js @@ -1,6 +1,5 @@ // An address that the metaswap-api recognizes as ETH, in place of the token address that ERC-20 tokens have -export const ETH_SWAPS_TOKEN_ADDRESS = - '0x0000000000000000000000000000000000000000'; +const ETH_SWAPS_TOKEN_ADDRESS = '0x0000000000000000000000000000000000000000'; export const ETH_SWAPS_TOKEN_OBJECT = { symbol: 'ETH', @@ -22,3 +21,5 @@ export const DEFAULT_ERC20_APPROVE_GAS = '0x1d4c0'; export const SWAPS_CONTRACT_ADDRESS = '0x881d40237659c251811cec9c364ef91dc08d300c'; + +export const METASWAP_API_HOST = 'https://api.metaswap.codefi.network'; diff --git a/ui/app/helpers/utils/transactions.util.js b/ui/app/helpers/utils/transactions.util.js index 463ddab5e..ad2af9162 100644 --- a/ui/app/helpers/utils/transactions.util.js +++ b/ui/app/helpers/utils/transactions.util.js @@ -2,8 +2,8 @@ import { MethodRegistry } from 'eth-method-registry'; import abi from 'human-standard-token-abi'; import { ethers } from 'ethers'; import log from 'loglevel'; + import { addHexPrefix } from '../../../../app/scripts/lib/util'; -import { getEtherscanNetworkPrefix } from '../../../lib/etherscan-prefix-for-network'; import { TRANSACTION_CATEGORIES, TRANSACTION_GROUP_STATUSES, @@ -192,20 +192,6 @@ export function getStatusKey(transaction) { return transaction.status; } -/** - * Returns an external block explorer URL at which a transaction can be viewed. - * @param {number} networkId - * @param {string} hash - * @param {Object} rpcPrefs - */ -export function getBlockExplorerUrlForTx(networkId, hash, rpcPrefs = {}) { - if (rpcPrefs.blockExplorerUrl) { - return `${rpcPrefs.blockExplorerUrl.replace(/\/+$/u, '')}/tx/${hash}`; - } - const prefix = getEtherscanNetworkPrefix(networkId); - return `https://${prefix}etherscan.io/tx/${hash}`; -} - /** * Returns a title for the given transaction category. * diff --git a/ui/app/helpers/utils/transactions.util.test.js b/ui/app/helpers/utils/transactions.util.test.js index a725156bd..386edd6f8 100644 --- a/ui/app/helpers/utils/transactions.util.test.js +++ b/ui/app/helpers/utils/transactions.util.test.js @@ -60,47 +60,4 @@ describe('Transactions utils', function () { }); }); }); - - describe('getBlockExplorerUrlForTx', function () { - it('should return the correct block explorer url for a transaction', function () { - const tests = [ - { - expected: 'https://etherscan.io/tx/0xabcd', - networkId: '1', - hash: '0xabcd', - }, - { - expected: 'https://ropsten.etherscan.io/tx/0xdef0', - networkId: '3', - hash: '0xdef0', - rpcPrefs: {}, - }, - { - // test handling of `blockExplorerUrl` for a custom RPC - expected: 'https://block.explorer/tx/0xabcd', - networkId: '31', - hash: '0xabcd', - rpcPrefs: { - blockExplorerUrl: 'https://block.explorer', - }, - }, - { - // test handling of trailing `/` in `blockExplorerUrl` for a custom RPC - expected: 'https://another.block.explorer/tx/0xdef0', - networkId: '33', - hash: '0xdef0', - rpcPrefs: { - blockExplorerUrl: 'https://another.block.explorer/', - }, - }, - ]; - - tests.forEach(({ expected, networkId, hash, rpcPrefs }) => { - assert.strictEqual( - utils.getBlockExplorerUrlForTx(networkId, hash, rpcPrefs), - expected, - ); - }); - }); - }); }); diff --git a/ui/app/helpers/utils/util.js b/ui/app/helpers/utils/util.js index a7c06c052..1480781c0 100644 --- a/ui/app/helpers/utils/util.js +++ b/ui/app/helpers/utils/util.js @@ -108,6 +108,13 @@ export function isValidDomainName(address) { return match !== null; } +export function isOriginContractAddress(to, sendTokenAddress) { + if (!to || !sendTokenAddress) { + return false; + } + return to.toLowerCase() === sendTokenAddress.toLowerCase(); +} + export function isAllOneCase(address) { if (!address) { return true; diff --git a/ui/app/helpers/utils/util.test.js b/ui/app/helpers/utils/util.test.js index 9f9c7ba54..fc79ef3b0 100644 --- a/ui/app/helpers/utils/util.test.js +++ b/ui/app/helpers/utils/util.test.js @@ -152,6 +152,38 @@ describe('util', function () { }); }); + describe('isOriginContractAddress', function () { + it('should return true when the send address is the same as the selected tokens contract address', function () { + assert.equal( + util.isOriginContractAddress( + '0x8d6b81208414189a58339873ab429b6c47ab92d3', + '0x8d6b81208414189a58339873ab429b6c47ab92d3', + ), + true, + ); + }); + + it('should return true when the send address is the same as the selected tokens contract address, capitalized input', function () { + assert.equal( + util.isOriginContractAddress( + '0x8d6b81208414189a58339873ab429b6c47ab92d3', + '0X8D6B81208414189A58339873AB429B6C47AB92D3', + ), + true, + ); + }); + + it('should return false when the recipient address differs', function () { + assert.equal( + util.isOriginContractAddress( + '0x8d6b81208414189a58339873ab429b6c47ab92d3', + '0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B', + ), + false, + ); + }); + }); + describe('#numericBalance', function () { it('should return a BN 0 if given nothing', function () { const result = util.numericBalance(); diff --git a/ui/app/hooks/useSwappedTokenValue.js b/ui/app/hooks/useSwappedTokenValue.js index 0a5e5bc27..f48e3de69 100644 --- a/ui/app/hooks/useSwappedTokenValue.js +++ b/ui/app/hooks/useSwappedTokenValue.js @@ -1,5 +1,5 @@ import { TRANSACTION_CATEGORIES } from '../../../shared/constants/transaction'; -import { ETH_SWAPS_TOKEN_ADDRESS } from '../helpers/constants/swaps'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; import { getSwapsTokensReceivedFromTxMeta } from '../pages/swaps/swaps.util'; import { useTokenFiatAmount } from './useTokenFiatAmount'; @@ -30,7 +30,7 @@ export function useSwappedTokenValue(transactionGroup, currentAsset) { const isViewingReceivedTokenFromSwap = currentAsset?.symbol === primaryTransaction.destinationTokenSymbol || - (currentAsset.address === ETH_SWAPS_TOKEN_ADDRESS && + (currentAsset.address === ETH_SWAPS_TOKEN_OBJECT.address && primaryTransaction.destinationTokenSymbol === 'ETH'); const swapTokenValue = diff --git a/ui/app/hooks/useSwapsEthToken.js b/ui/app/hooks/useSwapsEthToken.js deleted file mode 100644 index d1707ed88..000000000 --- a/ui/app/hooks/useSwapsEthToken.js +++ /dev/null @@ -1,53 +0,0 @@ -import { useSelector } from 'react-redux'; -import { getSelectedAccount } from '../selectors'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; -import { - getValueFromWeiHex, - hexToDecimal, -} from '../helpers/utils/conversions.util'; - -/** - * @typedef {Object} SwapsEthToken - * @property {string} symbol - The symbol for ETH, namely "ETH" - * @property {string} name - The name of the ETH currency, "Ether" - * @property {string} address - A substitute address for the metaswap-api to - * recognize the ETH token - * @property {string} decimals - The number of ETH decimals, i.e. 18 - * @property {string} balance - The user's ETH balance in decimal wei, with a - * precision of 4 decimal places - * @property {string} string - The user's ETH balance in decimal ETH - */ - -/** - * Swaps related code uses token objects for various purposes. These objects - * always have the following properties: `symbol`, `name`, `address`, and - * `decimals`. - * - * When available for the current account, the objects can have `balance` and - * `string` properties. - * `balance` is the users token balance in decimal values, denominated in the - * minimal token units (according to its decimals). - * `string` is the token balance in a readable format, ready for rendering. - * - * Swaps treats ETH as a token, and we use the ETH_SWAPS_TOKEN_OBJECT constant - * to set the standard properties for the token. The useSwapsEthToken hook - * extends that object with `balance` and `balance` values of the same type as - * in regular ERC-20 token objects, per the above description. - * - * @returns {SwapsEthToken} The token object representation of the currently - * selected account's ETH balance, as expected by the Swaps API. - */ -export function useSwapsEthToken() { - const selectedAccount = useSelector(getSelectedAccount); - const { balance } = selectedAccount; - - return { - ...ETH_SWAPS_TOKEN_OBJECT, - balance: hexToDecimal(balance), - string: getValueFromWeiHex({ - value: balance, - numberOfDecimals: 4, - toDenomination: 'ETH', - }), - }; -} diff --git a/ui/app/hooks/useTokenTracker.js b/ui/app/hooks/useTokenTracker.js index ea7892b08..2b2411d1e 100644 --- a/ui/app/hooks/useTokenTracker.js +++ b/ui/app/hooks/useTokenTracker.js @@ -4,21 +4,30 @@ import { useSelector } from 'react-redux'; import { getCurrentNetwork, getSelectedAddress } from '../selectors'; import { useEqualityCheck } from './useEqualityCheck'; -export function useTokenTracker(tokens, includeFailedTokens = false) { +export function useTokenTracker( + tokens, + includeFailedTokens = false, + hideZeroBalanceTokens = false, +) { const network = useSelector(getCurrentNetwork); const userAddress = useSelector(getSelectedAddress); - const [loading, setLoading] = useState(() => tokens?.length >= 0); const [tokensWithBalances, setTokensWithBalances] = useState([]); const [error, setError] = useState(null); const tokenTracker = useRef(null); const memoizedTokens = useEqualityCheck(tokens); - const updateBalances = useCallback((tokenWithBalances) => { - setTokensWithBalances(tokenWithBalances); - setLoading(false); - setError(null); - }, []); + const updateBalances = useCallback( + (tokenWithBalances) => { + const matchingTokens = hideZeroBalanceTokens + ? tokenWithBalances.filter((token) => Number(token.balance) > 0) + : tokenWithBalances; + setTokensWithBalances(matchingTokens); + setLoading(false); + setError(null); + }, + [hideZeroBalanceTokens], + ); const showError = useCallback((err) => { setError(err); diff --git a/ui/app/hooks/useTokensToSearch.js b/ui/app/hooks/useTokensToSearch.js index cbaf4df66..3336ceae0 100644 --- a/ui/app/hooks/useTokensToSearch.js +++ b/ui/app/hooks/useTokensToSearch.js @@ -9,9 +9,9 @@ import { getTokenExchangeRates, getConversionRate, getCurrentCurrency, + getSwapsEthToken, } from '../selectors'; import { getSwapsTokens } from '../ducks/swaps/swaps'; -import { useSwapsEthToken } from './useSwapsEthToken'; import { useEqualityCheck } from './useEqualityCheck'; const tokenList = shuffle( @@ -79,11 +79,11 @@ export function useTokensToSearch({ const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual); const conversionRate = useSelector(getConversionRate); const currentCurrency = useSelector(getCurrentCurrency); + const swapsEthToken = useSelector(getSwapsEthToken); const memoizedTopTokens = useEqualityCheck(topTokens); const memoizedUsersToken = useEqualityCheck(usersTokens); - const swapsEthToken = useSwapsEthToken(); const ethToken = getRenderableTokenData( swapsEthToken, tokenConversionRates, diff --git a/ui/app/pages/asset/components/token-asset.js b/ui/app/pages/asset/components/token-asset.js index 4c6647ec4..19059343b 100644 --- a/ui/app/pages/asset/components/token-asset.js +++ b/ui/app/pages/asset/components/token-asset.js @@ -2,12 +2,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; -import { createTokenTrackerLink } from '@metamask/etherscan-link'; +import { createTokenTrackerLinkForChain } from '@metamask/etherscan-link'; import TransactionList from '../../../components/app/transaction-list'; import { TokenOverview } from '../../../components/app/wallet-overview'; import { - getCurrentNetworkId, + getCurrentChainId, getSelectedIdentity, } from '../../../selectors/selectors'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; @@ -18,7 +18,7 @@ import TokenOptions from './token-options'; export default function TokenAsset({ token }) { const dispatch = useDispatch(); - const network = useSelector(getCurrentNetworkId); + const chainId = useSelector(getCurrentChainId); const selectedIdentity = useSelector(getSelectedIdentity); const selectedAccountName = selectedIdentity.name; const selectedAddress = selectedIdentity.address; @@ -36,9 +36,9 @@ export default function TokenAsset({ token }) { dispatch(showModal({ name: 'HIDE_TOKEN_CONFIRMATION', token })) } onViewEtherscan={() => { - const url = createTokenTrackerLink( + const url = createTokenTrackerLinkForChain( token.address, - network, + chainId, selectedAddress, ); global.platform.openTab({ url }); diff --git a/ui/app/pages/confirm-approve/confirm-approve.js b/ui/app/pages/confirm-approve/confirm-approve.js index bb9cb6ccc..cedd987af 100644 --- a/ui/app/pages/confirm-approve/confirm-approve.js +++ b/ui/app/pages/confirm-approve/confirm-approve.js @@ -19,6 +19,7 @@ import { getNativeCurrency, } from '../../selectors'; import { currentNetworkTxListSelector } from '../../selectors/transactions'; +import Loading from '../../components/ui/loading-screen'; import { getCustomTxParamsData } from './confirm-approve.util'; import ConfirmApproveContent from './confirm-approve-content'; @@ -87,7 +88,7 @@ export default function ConfirmApprove() { ? getCustomTxParamsData(data, { customPermissionAmount, decimals }) : null; - return ( + return tokenSymbol ? ( + ) : ( + ); } diff --git a/ui/app/pages/create-account/connect-hardware/account-list.js b/ui/app/pages/create-account/connect-hardware/account-list.js index 53b9d8f7b..5ce75ae81 100644 --- a/ui/app/pages/create-account/connect-hardware/account-list.js +++ b/ui/app/pages/create-account/connect-hardware/account-list.js @@ -2,25 +2,10 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import getAccountLink from '../../../../lib/account-link'; import Button from '../../../components/ui/button'; +import Checkbox from '../../../components/ui/check-box'; import Dropdown from '../../../components/ui/dropdown'; class AccountList extends Component { - getHdPaths() { - const ledgerLiveKey = `m/44'/60'/0'/0/0`; - const mewKey = `m/44'/60'/0'`; - - return [ - { - name: `Ledger Live`, - value: ledgerLiveKey, - }, - { - name: `Legacy (MEW / MyCrypto)`, - value: mewKey, - }, - ]; - } - goToNextPage = () => { // If we have < 5 accounts, it's restricted by BIP-44 if (this.props.accounts.length === 5) { @@ -35,8 +20,7 @@ class AccountList extends Component { }; renderHdPathSelector() { - const { onPathChange, selectedPath } = this.props; - const options = this.getHdPaths(); + const { onPathChange, selectedPath, hdPaths } = this.props; return (
@@ -47,7 +31,7 @@ class AccountList extends Component {
{ onPathChange(value); @@ -81,45 +65,67 @@ class AccountList extends Component { } renderAccounts() { + const { accounts, connectedAccounts } = this.props; + return ( ); } @@ -144,7 +150,7 @@ class AccountList extends Component { } renderButtons() { - const disabled = this.props.selectedAccount === null; + const disabled = this.props.selectedAccounts.length === 0; const buttonProps = {}; if (disabled) { buttonProps.disabled = true; @@ -165,7 +171,11 @@ class AccountList extends Component { large className="new-external-account-form__button unlock" disabled={disabled} - onClick={this.props.onUnlockAccount.bind(this, this.props.device)} + onClick={this.props.onUnlockAccounts.bind( + this, + this.props.device, + this.props.selectedPath, + )} > {this.context.t('unlock')} @@ -201,14 +211,17 @@ AccountList.propTypes = { selectedPath: PropTypes.string.isRequired, device: PropTypes.string.isRequired, accounts: PropTypes.array.isRequired, + connectedAccounts: PropTypes.array.isRequired, onAccountChange: PropTypes.func.isRequired, onForgetDevice: PropTypes.func.isRequired, getPage: PropTypes.func.isRequired, - network: PropTypes.string, - selectedAccount: PropTypes.string, - onUnlockAccount: PropTypes.func, + chainId: PropTypes.string, + rpcPrefs: PropTypes.object, + selectedAccounts: PropTypes.array.isRequired, + onUnlockAccounts: PropTypes.func, onCancel: PropTypes.func, onAccountRestriction: PropTypes.func, + hdPaths: PropTypes.array.isRequired, }; AccountList.contextTypes = { diff --git a/ui/app/pages/create-account/connect-hardware/index.js b/ui/app/pages/create-account/connect-hardware/index.js index 153195088..4af6e501d 100644 --- a/ui/app/pages/create-account/connect-hardware/index.js +++ b/ui/app/pages/create-account/connect-hardware/index.js @@ -2,7 +2,12 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import * as actions from '../../../store/actions'; -import { getMetaMaskAccounts } from '../../../selectors'; +import { + getCurrentChainId, + getMetaMaskAccounts, + getRpcPrefsForCurrentProvider, + getMetaMaskAccountsConnected, +} from '../../../selectors'; import { formatBalance } from '../../../helpers/utils/util'; import { getMostRecentOverviewPage } from '../../../ducks/history/history'; import SelectHardware from './select-hardware'; @@ -10,10 +15,17 @@ import AccountList from './account-list'; const U2F_ERROR = 'U2F'; +const LEDGER_LIVE_PATH = `m/44'/60'/0'/0/0`; +const MEW_PATH = `m/44'/60'/0'`; +const HD_PATHS = [ + { name: 'Ledger Live', value: LEDGER_LIVE_PATH }, + { name: 'Legacy (MEW / MyCrypto)', value: MEW_PATH }, +]; + class ConnectHardwareForm extends Component { state = { error: null, - selectedAccount: null, + selectedAccounts: [], accounts: [], browserSupported: true, unlocked: false, @@ -24,9 +36,7 @@ class ConnectHardwareForm extends Component { const { accounts } = nextProps; const newAccounts = this.state.accounts.map((a) => { const normalizedAddress = a.address.toLowerCase(); - const balanceValue = - (accounts[normalizedAddress] && accounts[normalizedAddress].balance) || - null; + const balanceValue = accounts[normalizedAddress]?.balance || null; a.balance = balanceValue ? formatBalance(balanceValue, 6) : '...'; return a; }); @@ -39,13 +49,11 @@ class ConnectHardwareForm extends Component { async checkIfUnlocked() { for (const device of ['trezor', 'ledger']) { - const unlocked = await this.props.checkHardwareStatus( - device, - this.props.defaultHdPaths[device], - ); + const path = this.props.defaultHdPaths[device]; + const unlocked = await this.props.checkHardwareStatus(device, path); if (unlocked) { this.setState({ unlocked: true }); - this.getPage(device, 0, this.props.defaultHdPaths[device]); + this.getPage(device, 0, path); } } } @@ -65,11 +73,20 @@ class ConnectHardwareForm extends Component { device: this.state.device, path, }); + this.setState({ + selectedAccounts: [], + }); this.getPage(this.state.device, 0, path); }; onAccountChange = (account) => { - this.setState({ selectedAccount: account.toString(), error: null }); + let { selectedAccounts } = this.state; + if (selectedAccounts.includes(account)) { + selectedAccounts = selectedAccounts.filter((acc) => account !== acc); + } else { + selectedAccounts.push(account); + } + this.setState({ selectedAccounts, error: null }); }; onAccountRestriction = () => { @@ -95,37 +112,23 @@ class ConnectHardwareForm extends Component { this.showTemporaryAlert(); } - const newState = { unlocked: true, device, error: null }; - // Default to the first account - if (this.state.selectedAccount === null) { - accounts.forEach((a) => { - if (a.address.toLowerCase() === this.props.address) { - newState.selectedAccount = a.index.toString(); - } - }); - // If the page doesn't contain the selected account, let's deselect it - } else if ( - !accounts.filter( - (a) => a.index.toString() === this.state.selectedAccount, - ).length - ) { - newState.selectedAccount = null; - } - // Map accounts with balances - newState.accounts = accounts.map((account) => { + const newAccounts = accounts.map((account) => { const normalizedAddress = account.address.toLowerCase(); const balanceValue = - (this.props.accounts[normalizedAddress] && - this.props.accounts[normalizedAddress].balance) || - null; + this.props.accounts[normalizedAddress]?.balance || null; account.balance = balanceValue ? formatBalance(balanceValue, 6) : '...'; return account; }); - this.setState(newState); + this.setState({ + accounts: newAccounts, + unlocked: true, + device, + error: null, + }); } }) .catch((e) => { @@ -149,7 +152,7 @@ class ConnectHardwareForm extends Component { .then((_) => { this.setState({ error: null, - selectedAccount: null, + selectedAccounts: [], accounts: [], unlocked: false, }); @@ -159,18 +162,28 @@ class ConnectHardwareForm extends Component { }); }; - onUnlockAccount = (device) => { + onUnlockAccounts = (device, path) => { const { history, mostRecentOverviewPage, - unlockHardwareWalletAccount, + unlockHardwareWalletAccounts, } = this.props; + const { selectedAccounts } = this.state; - if (this.state.selectedAccount === null) { + if (selectedAccounts.length === 0) { this.setState({ error: this.context.t('accountSelectionRequired') }); } - unlockHardwareWalletAccount(this.state.selectedAccount, device) + const description = + MEW_PATH === path + ? this.context.t('hardwareWalletLegacyDescription') + : ''; + return unlockHardwareWalletAccounts( + selectedAccounts, + device, + path || null, + description, + ) .then((_) => { this.context.metricsEvent({ eventOpts: { @@ -243,14 +256,17 @@ class ConnectHardwareForm extends Component { selectedPath={this.props.defaultHdPaths[this.state.device]} device={this.state.device} accounts={this.state.accounts} - selectedAccount={this.state.selectedAccount} + connectedAccounts={this.props.connectedAccounts} + selectedAccounts={this.state.selectedAccounts} onAccountChange={this.onAccountChange} - network={this.props.network} + chainId={this.props.chainId} + rpcPrefs={this.props.rpcPrefs} getPage={this.getPage} - onUnlockAccount={this.onUnlockAccount} + onUnlockAccounts={this.onUnlockAccounts} onForgetDevice={this.onForgetDevice} onCancel={this.onCancel} onAccountRestriction={this.onAccountRestriction} + hdPaths={HD_PATHS} /> ); } @@ -271,33 +287,25 @@ ConnectHardwareForm.propTypes = { forgetDevice: PropTypes.func, showAlert: PropTypes.func, hideAlert: PropTypes.func, - unlockHardwareWalletAccount: PropTypes.func, + unlockHardwareWalletAccounts: PropTypes.func, setHardwareWalletDefaultHdPath: PropTypes.func, history: PropTypes.object, - network: PropTypes.string, + chainId: PropTypes.string, + rpcPrefs: PropTypes.object, accounts: PropTypes.object, - address: PropTypes.string, + connectedAccounts: PropTypes.array.isRequired, defaultHdPaths: PropTypes.object, mostRecentOverviewPage: PropTypes.string.isRequired, }; -const mapStateToProps = (state) => { - const { - metamask: { network, selectedAddress }, - } = state; - const accounts = getMetaMaskAccounts(state); - const { - appState: { defaultHdPaths }, - } = state; - - return { - network, - accounts, - address: selectedAddress, - defaultHdPaths, - mostRecentOverviewPage: getMostRecentOverviewPage(state), - }; -}; +const mapStateToProps = (state) => ({ + chainId: getCurrentChainId(state), + rpcPrefs: getRpcPrefsForCurrentProvider(state), + accounts: getMetaMaskAccounts(state), + connectedAccounts: getMetaMaskAccountsConnected(state), + defaultHdPaths: state.appState.defaultHdPaths, + mostRecentOverviewPage: getMostRecentOverviewPage(state), +}); const mapDispatchToProps = (dispatch) => { return { @@ -313,9 +321,19 @@ const mapDispatchToProps = (dispatch) => { forgetDevice: (deviceName) => { return dispatch(actions.forgetDevice(deviceName)); }, - unlockHardwareWalletAccount: (index, deviceName, hdPath) => { + unlockHardwareWalletAccounts: ( + indexes, + deviceName, + hdPath, + hdPathDescription, + ) => { return dispatch( - actions.unlockHardwareWalletAccount(index, deviceName, hdPath), + actions.unlockHardwareWalletAccounts( + indexes, + deviceName, + hdPath, + hdPathDescription, + ), ); }, showAlert: (msg) => dispatch(actions.showAlert(msg)), diff --git a/ui/app/pages/create-account/connect-hardware/index.scss b/ui/app/pages/create-account/connect-hardware/index.scss index b9eb4c8f8..03d4de75b 100644 --- a/ui/app/pages/create-account/connect-hardware/index.scss +++ b/ui/app/pages/create-account/connect-hardware/index.scss @@ -256,12 +256,11 @@ width: 24px; } - &__item__radio { + &__item__checkbox { display: flex; flex: 1; input { - padding: 10px; margin-top: 13px; } } diff --git a/ui/app/pages/error/error.component.js b/ui/app/pages/error/error.component.js index 22d7f5229..92fad5fa6 100644 --- a/ui/app/pages/error/error.component.js +++ b/ui/app/pages/error/error.component.js @@ -34,13 +34,24 @@ class ErrorPage extends PureComponent { const { t } = this.context; const isPopup = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP; + const supportLink = ( + + {this.context.t('here')} + + ); + const message = isPopup + ? t('errorPagePopupMessage', [supportLink]) + : t('errorPageMessage', [supportLink]); return (

{t('errorPageTitle')}

-

- {isPopup ? t('errorPagePopupMessage') : t('errorPageMessage')} -

+

{message}

{t('errorDetails')} diff --git a/ui/app/pages/error/index.scss b/ui/app/pages/error/index.scss index 0edb6a630..517c43e1e 100644 --- a/ui/app/pages/error/index.scss +++ b/ui/app/pages/error/index.scss @@ -38,4 +38,8 @@ overflow-x: auto; background-color: #eee; } + + &__link-text { + color: #037dd6; + } } diff --git a/ui/app/pages/first-time-flow/create-password/unique-image/index.js b/ui/app/pages/first-time-flow/create-password/unique-image/index.js deleted file mode 100644 index 8a16dbcce..000000000 --- a/ui/app/pages/first-time-flow/create-password/unique-image/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './unique-image.container'; diff --git a/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.component.js b/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.component.js deleted file mode 100644 index 3533b8b2d..000000000 --- a/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.component.js +++ /dev/null @@ -1,49 +0,0 @@ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; -import Button from '../../../../components/ui/button'; -import { INITIALIZE_END_OF_FLOW_ROUTE } from '../../../../helpers/constants/routes'; - -export default class UniqueImageScreen extends PureComponent { - static contextTypes = { - t: PropTypes.func, - metricsEvent: PropTypes.func, - }; - - static propTypes = { - history: PropTypes.object, - }; - - render() { - const { t } = this.context; - const { history } = this.props; - - return ( -
- -
{t('protectYourKeys')}
-
- {t('protectYourKeysMessage1')} -
-
- {t('protectYourKeysMessage2')} -
- -
- ); - } -} diff --git a/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.container.js b/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.container.js deleted file mode 100644 index fd3e5953f..000000000 --- a/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.container.js +++ /dev/null @@ -1,12 +0,0 @@ -import { connect } from 'react-redux'; -import UniqueImage from './unique-image.component'; - -const mapStateToProps = ({ metamask }) => { - const { selectedAddress } = metamask; - - return { - address: selectedAddress, - }; -}; - -export default connect(mapStateToProps)(UniqueImage); diff --git a/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.component.js b/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.component.js index c461fa637..f9ab3bb33 100644 --- a/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.component.js +++ b/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.component.js @@ -89,7 +89,19 @@ export default class EndOfFlowScreen extends PureComponent { {`• ${t('endOfFlowMessage6')}`}
- {`• ${t('endOfFlowMessage7')}`} + •{' '} + {t('endOfFlowMessage7', [ + + + {this.context.t('here')} + + , + ])}
{`*${t('endOfFlowMessage8')}`}  diff --git a/ui/app/pages/first-time-flow/index.scss b/ui/app/pages/first-time-flow/index.scss index 90861c18d..994d218d3 100644 --- a/ui/app/pages/first-time-flow/index.scss +++ b/ui/app/pages/first-time-flow/index.scss @@ -90,10 +90,6 @@ margin: 36px 0; } - &__unique-image { - margin-bottom: 20px; - } - &__text-block { margin-bottom: 24px; color: black; diff --git a/ui/app/pages/send/send-content/add-recipient/add-recipient.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.js index 195da89cb..c735957cf 100644 --- a/ui/app/pages/send/send-content/add-recipient/add-recipient.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.js @@ -7,6 +7,7 @@ import { KNOWN_RECIPIENT_ADDRESS_ERROR, INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR, CONFUSING_ENS_ERROR, + CONTRACT_ADDRESS_ERROR, } from '../../send.constants'; import { @@ -14,18 +15,19 @@ import { isEthNetwork, checkExistingAddresses, isValidDomainName, + isOriginContractAddress, } from '../../../../helpers/utils/util'; -export function getToErrorObject(to, hasHexData = false, network) { +export function getToErrorObject(to, sendTokenAddress, network) { let toError = null; if (!to) { - if (!hasHexData) { - toError = REQUIRED_ERROR; - } - } else if (!isValidAddress(to) && !toError) { + toError = REQUIRED_ERROR; + } else if (!isValidAddress(to)) { toError = isEthNetwork(network) ? INVALID_RECIPIENT_ADDRESS_ERROR : INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR; + } else if (isOriginContractAddress(to, sendTokenAddress)) { + toError = CONTRACT_ADDRESS_ERROR; } return { to: toError }; diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js index cdf1a0c36..3ffdc96af 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js @@ -7,6 +7,7 @@ import { INVALID_RECIPIENT_ADDRESS_ERROR, KNOWN_RECIPIENT_ADDRESS_ERROR, CONFUSING_ENS_ERROR, + CONTRACT_ADDRESS_ERROR, } from '../../../send.constants'; const stubs = { @@ -30,12 +31,6 @@ describe('add-recipient utils', function () { }); }); - it('should return null if "to" is falsy and hexData is truthy', function () { - assert.deepStrictEqual(getToErrorObject(null, true), { - to: null, - }); - }); - it('should return an invalid recipient error if "to" is truthy but invalid', function () { assert.deepStrictEqual(getToErrorObject('mockInvalidTo'), { to: INVALID_RECIPIENT_ADDRESS_ERROR, @@ -47,6 +42,18 @@ describe('add-recipient utils', function () { to: null, }); }); + + it('should return a contract address error if the recipient is the same as the tokens contract address', function () { + assert.deepStrictEqual(getToErrorObject('0xabc123', '0xabc123'), { + to: CONTRACT_ADDRESS_ERROR, + }); + }); + + it('should return null if the recipient address is not the token contract address', function () { + assert.deepStrictEqual(getToErrorObject('0xabc123', '0xabc456'), { + to: null, + }); + }); }); describe('getToWarningObject()', function () { diff --git a/ui/app/pages/send/send-content/send-content.component.js b/ui/app/pages/send/send-content/send-content.component.js index 2dee77e65..6f4fd7924 100644 --- a/ui/app/pages/send/send-content/send-content.component.js +++ b/ui/app/pages/send/send-content/send-content.component.js @@ -19,15 +19,19 @@ export default class SendContent extends Component { contact: PropTypes.object, isOwnedAccount: PropTypes.bool, warning: PropTypes.string, + error: PropTypes.string, + gasIsExcessive: PropTypes.bool.isRequired, }; updateGas = (updateData) => this.props.updateGas(updateData); render() { - const { warning } = this.props; + const { warning, error, gasIsExcessive } = this.props; return (
+ {gasIsExcessive && this.renderError(true)} + {error && this.renderError()} {warning && this.renderWarning()} {this.maybeRenderAddContact()} @@ -74,4 +78,15 @@ export default class SendContent extends Component { ); } + + renderError(gasError = false) { + const { t } = this.context; + const { error } = this.props; + + return ( + + {gasError ? t('gasPriceExcessive') : t(error)} + + ); + } } diff --git a/ui/app/pages/send/send.component.js b/ui/app/pages/send/send.component.js index 98c3b6600..23696807a 100644 --- a/ui/app/pages/send/send.component.js +++ b/ui/app/pages/send/send.component.js @@ -17,7 +17,11 @@ import AddRecipient from './send-content/add-recipient'; import SendContent from './send-content'; import SendFooter from './send-footer'; import EnsInput from './send-content/add-recipient/ens-input'; -import { INVALID_RECIPIENT_ADDRESS_ERROR } from './send.constants'; +import { + INVALID_RECIPIENT_ADDRESS_ERROR, + KNOWN_RECIPIENT_ADDRESS_ERROR, + CONTRACT_ADDRESS_ERROR, +} from './send.constants'; export default class SendTransactionScreen extends Component { static propTypes = { @@ -31,7 +35,6 @@ export default class SendTransactionScreen extends Component { gasLimit: PropTypes.string, gasPrice: PropTypes.string, gasTotal: PropTypes.string, - hasHexData: PropTypes.bool, history: PropTypes.object, network: PropTypes.string, primaryCurrency: PropTypes.string, @@ -54,6 +57,8 @@ export default class SendTransactionScreen extends Component { scanQrCode: PropTypes.func.isRequired, qrCodeDetected: PropTypes.func.isRequired, qrCodeData: PropTypes.object, + sendTokenAddress: PropTypes.string, + gasIsExcessive: PropTypes.bool.isRequired, }; static contextTypes = { @@ -94,6 +99,7 @@ export default class SendTransactionScreen extends Component { qrCodeData, qrCodeDetected, } = this.props; + const { toError, toWarning } = this.state; let updateGas = false; const { @@ -188,6 +194,25 @@ export default class SendTransactionScreen extends Component { this.updateGas(); } } + + // If selecting ETH after selecting a token, clear token related messages. + if (prevSendToken && !sendToken) { + let error = toError; + let warning = toWarning; + + if (toError === CONTRACT_ADDRESS_ERROR) { + error = null; + } + + if (toWarning === KNOWN_RECIPIENT_ADDRESS_ERROR) { + warning = null; + } + + this.setState({ + toError: error, + toWarning: warning, + }); + } } componentDidMount() { @@ -234,7 +259,7 @@ export default class SendTransactionScreen extends Component { } validate(query) { - const { hasHexData, tokens, sendToken, network } = this.props; + const { tokens, sendToken, network, sendTokenAddress } = this.props; const { internalSearch } = this.state; @@ -243,7 +268,7 @@ export default class SendTransactionScreen extends Component { return; } - const toErrorObject = getToErrorObject(query, hasHexData, network); + const toErrorObject = getToErrorObject(query, sendTokenAddress, network); const toWarningObject = getToWarningObject(query, tokens, sendToken); this.setState({ @@ -358,8 +383,8 @@ export default class SendTransactionScreen extends Component { } renderSendContent() { - const { history, showHexData } = this.props; - const { toWarning } = this.state; + const { history, showHexData, gasIsExcessive } = this.props; + const { toWarning, toError } = this.state; return [ , , ]; diff --git a/ui/app/pages/send/send.constants.js b/ui/app/pages/send/send.constants.js index 5584a6c99..93b620d14 100644 --- a/ui/app/pages/send/send.constants.js +++ b/ui/app/pages/send/send.constants.js @@ -35,6 +35,7 @@ const INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR = 'invalidAddressRecipientNotEthNetwork'; const REQUIRED_ERROR = 'required'; const KNOWN_RECIPIENT_ADDRESS_ERROR = 'knownAddressRecipient'; +const CONTRACT_ADDRESS_ERROR = 'contractAddressError'; const CONFUSING_ENS_ERROR = 'confusingEnsDomain'; const SIMPLE_GAS_COST = '0x5208'; // Hex for 21000, cost of a simple send. @@ -45,6 +46,7 @@ export { INSUFFICIENT_TOKENS_ERROR, INVALID_RECIPIENT_ADDRESS_ERROR, KNOWN_RECIPIENT_ADDRESS_ERROR, + CONTRACT_ADDRESS_ERROR, INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR, MIN_GAS_LIMIT_DEC, MIN_GAS_LIMIT_HEX, diff --git a/ui/app/pages/send/send.container.js b/ui/app/pages/send/send.container.js index c460b4526..898546a81 100644 --- a/ui/app/pages/send/send.container.js +++ b/ui/app/pages/send/send.container.js @@ -22,6 +22,8 @@ import { getQrCodeData, getSelectedAddress, getAddressBook, + getSendTokenAddress, + isCustomPriceExcessive, } from '../../selectors'; import { @@ -65,6 +67,8 @@ function mapStateToProps(state) { tokens: getTokens(state), tokenBalance: getTokenBalance(state), tokenContract: getSendTokenContract(state), + sendTokenAddress: getSendTokenAddress(state), + gasIsExcessive: isCustomPriceExcessive(state, true), }; } diff --git a/ui/app/pages/settings/settings-tab/settings-tab.component.js b/ui/app/pages/settings/settings-tab/settings-tab.component.js index 74e9c8563..71aae33a6 100644 --- a/ui/app/pages/settings/settings-tab/settings-tab.component.js +++ b/ui/app/pages/settings/settings-tab/settings-tab.component.js @@ -41,6 +41,8 @@ export default class SettingsTab extends PureComponent { nativeCurrency: PropTypes.string, useNativeCurrencyAsPrimaryCurrency: PropTypes.bool, setUseNativeCurrencyAsPrimaryCurrencyPreference: PropTypes.func, + hideZeroBalanceTokens: PropTypes.bool, + setHideZeroBalanceTokens: PropTypes.func, }; renderCurrentConversion() { @@ -101,12 +103,35 @@ export default class SettingsTab extends PureComponent { ); } + renderHideZeroBalanceTokensOptIn() { + const { t } = this.context; + const { hideZeroBalanceTokens, setHideZeroBalanceTokens } = this.props; + + return ( +
+
+ {t('hideZeroBalanceTokens')} +
+
+
+ setHideZeroBalanceTokens(!value)} + offLabel={t('off')} + onLabel={t('on')} + /> +
+
+
+ ); + } + renderBlockieOptIn() { const { t } = this.context; const { useBlockie, setUseBlockie } = this.props; return ( -
+
{this.context.t('blockiesIdenticon')}
@@ -192,6 +217,7 @@ export default class SettingsTab extends PureComponent { {this.renderUsePrimaryCurrencyOptions()} {this.renderCurrentLocale()} {this.renderBlockieOptIn()} + {this.renderHideZeroBalanceTokensOptIn()}
); } diff --git a/ui/app/pages/settings/settings-tab/settings-tab.container.js b/ui/app/pages/settings/settings-tab/settings-tab.container.js index ce8de1363..2e964e551 100644 --- a/ui/app/pages/settings/settings-tab/settings-tab.container.js +++ b/ui/app/pages/settings/settings-tab/settings-tab.container.js @@ -4,6 +4,7 @@ import { setUseBlockie, updateCurrentLocale, setUseNativeCurrencyAsPrimaryCurrencyPreference, + setHideZeroBalanceTokens, setParticipateInMetaMetrics, } from '../../../store/actions'; import { getPreferences } from '../../../selectors'; @@ -21,7 +22,10 @@ const mapStateToProps = (state) => { useBlockie, currentLocale, } = metamask; - const { useNativeCurrencyAsPrimaryCurrency } = getPreferences(state); + const { + useNativeCurrencyAsPrimaryCurrency, + hideZeroBalanceTokens, + } = getPreferences(state); return { warning, @@ -31,6 +35,7 @@ const mapStateToProps = (state) => { nativeCurrency, useBlockie, useNativeCurrencyAsPrimaryCurrency, + hideZeroBalanceTokens, }; }; @@ -44,6 +49,8 @@ const mapDispatchToProps = (dispatch) => { }, setParticipateInMetaMetrics: (val) => dispatch(setParticipateInMetaMetrics(val)), + setHideZeroBalanceTokens: (value) => + dispatch(setHideZeroBalanceTokens(value)), }; }; diff --git a/ui/app/pages/settings/settings-tab/tests/settings-tab.test.js b/ui/app/pages/settings/settings-tab/tests/settings-tab.test.js index da3630a24..969044da7 100644 --- a/ui/app/pages/settings/settings-tab/tests/settings-tab.test.js +++ b/ui/app/pages/settings/settings-tab/tests/settings-tab.test.js @@ -13,6 +13,7 @@ describe('Settings Tab', function () { setUseBlockie: sinon.spy(), updateCurrentLocale: sinon.spy(), setUseNativeCurrencyAsPrimaryCurrencyPreference: sinon.spy(), + setHideZeroBalanceTokens: sinon.spy(), warning: '', currentLocale: 'en', useBlockie: false, @@ -51,9 +52,16 @@ describe('Settings Tab', function () { }); it('toggles blockies', function () { - const toggleBlockies = wrapper.find({ type: 'checkbox' }); + const toggleBlockies = wrapper.find('#blockie-optin input'); toggleBlockies.simulate('click'); assert(props.setUseBlockie.calledOnce); }); + + it('toggles hiding zero balance', function () { + const toggleBlockies = wrapper.find('#toggle-zero-balance input'); + + toggleBlockies.simulate('click'); + assert(props.setHideZeroBalanceTokens.calledOnce); + }); }); diff --git a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js index 3828dab6f..b02639b26 100644 --- a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js +++ b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js @@ -6,7 +6,12 @@ import { useHistory } from 'react-router-dom'; import { I18nContext } from '../../../contexts/i18n'; import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; import { MetaMetricsContext } from '../../../contexts/metametrics.new'; -import { getCurrentCurrency, getUSDConversionRate } from '../../../selectors'; +import { + getCurrentChainId, + getCurrentCurrency, + getRpcPrefsForCurrentProvider, + getUSDConversionRate, +} from '../../../selectors'; import { getUsedQuote, getFetchParams, @@ -19,7 +24,6 @@ import { } from '../../../ducks/swaps/swaps'; import Mascot from '../../../components/ui/mascot'; import PulseLoader from '../../../components/ui/pulse-loader'; -import { getBlockExplorerUrlForTx } from '../../../helpers/utils/transactions.util'; import { QUOTES_EXPIRED_ERROR, SWAP_FAILED_ERROR, @@ -31,6 +35,7 @@ import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import { getRenderableNetworkFeesForQuote } from '../swaps.util'; import SwapsFooter from '../swaps-footer'; +import { getBlockExplorerUrlForTx } from '../../../../../shared/modules/transaction.utils'; import SwapFailureIcon from './swap-failure-icon'; import SwapSuccessIcon from './swap-success-icon'; import QuotesTimeoutIcon from './quotes-timeout-icon'; @@ -40,9 +45,7 @@ export default function AwaitingSwap({ swapComplete, errorKey, txHash, - networkId, tokensReceived, - rpcPrefs, submittingSwap, inputValue, maxSlippage, @@ -60,6 +63,8 @@ export default function AwaitingSwap({ const swapsGasPrice = useSelector(getUsedSwapsGasPrice); const currentCurrency = useSelector(getCurrentCurrency); const usdConversionRate = useSelector(getUSDConversionRate); + const chainId = useSelector(getCurrentChainId); + const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider); const [trackedQuotesExpiredEvent, setTrackedQuotesExpiredEvent] = useState( false, @@ -96,7 +101,7 @@ export default function AwaitingSwap({ }); const blockExplorerUrl = - txHash && getBlockExplorerUrlForTx(networkId, txHash, rpcPrefs); + txHash && getBlockExplorerUrlForTx({ chainId, hash: txHash }, rpcPrefs); let headerText; let statusImage; @@ -240,10 +245,8 @@ export default function AwaitingSwap({ AwaitingSwap.propTypes = { swapComplete: PropTypes.bool, - networkId: PropTypes.string.isRequired, txHash: PropTypes.string, tokensReceived: PropTypes.string, - rpcPrefs: PropTypes.object.isRequired, errorKey: PropTypes.oneOf([ QUOTES_EXPIRED_ERROR, SWAP_FAILED_ERROR, diff --git a/ui/app/pages/swaps/build-quote/build-quote.js b/ui/app/pages/swaps/build-quote/build-quote.js index d71f78ad7..9237016ea 100644 --- a/ui/app/pages/swaps/build-quote/build-quote.js +++ b/ui/app/pages/swaps/build-quote/build-quote.js @@ -7,7 +7,6 @@ import { useHistory } from 'react-router-dom'; import { MetaMetricsContext } from '../../../contexts/metametrics.new'; import { useTokensToSearch } from '../../../hooks/useTokensToSearch'; import { useEqualityCheck } from '../../../hooks/useEqualityCheck'; -import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken'; import { I18nContext } from '../../../contexts/i18n'; import DropdownInputPair from '../dropdown-input-pair'; import DropdownSearchList from '../dropdown-search-list'; @@ -26,6 +25,7 @@ import { getTopAssets, getFetchParams, } from '../../../ducks/swaps/swaps'; +import { getSwapsEthToken } from '../../../selectors'; import { getValueFromWeiHex, hexToDecimal, @@ -76,7 +76,7 @@ export default function BuildQuote({ const topAssets = useSelector(getTopAssets); const fromToken = useSelector(getFromToken); const toToken = useSelector(getToToken) || destinationTokenInfo; - const swapsEthToken = useSwapsEthToken(); + const swapsEthToken = useSelector(getSwapsEthToken); const fetchParamsFromToken = sourceTokenInfo?.symbol === 'ETH' ? swapsEthToken : sourceTokenInfo; diff --git a/ui/app/pages/swaps/index.js b/ui/app/pages/swaps/index.js index 517e2b0a3..42f7e7e9f 100644 --- a/ui/app/pages/swaps/index.js +++ b/ui/app/pages/swaps/index.js @@ -11,11 +11,9 @@ import BigNumber from 'bignumber.js'; import { I18nContext } from '../../contexts/i18n'; import { getSelectedAccount, - getCurrentNetworkId, getCurrentChainId, } from '../../selectors/selectors'; import { - getFromToken, getQuotes, clearSwapsState, getTradeTxId, @@ -44,7 +42,6 @@ import { import { ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, - ETH_SWAPS_TOKEN_OBJECT, SWAP_FAILED_ERROR, OFFLINE_FOR_MAINTENANCE, } from '../../helpers/constants/swaps'; @@ -57,12 +54,8 @@ import { setBackgroundSwapRouteState, setSwapsErrorKey, } from '../../store/actions'; -import { - currentNetworkTxListSelector, - getRpcPrefsForCurrentProvider, -} from '../../selectors'; +import { currentNetworkTxListSelector } from '../../selectors'; import { useNewMetricEvent } from '../../hooks/useMetricEvent'; -import { getValueFromWeiHex } from '../../helpers/utils/conversions.util'; import FeatureToggledRoute from '../../helpers/higher-order-components/feature-toggled-route'; import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; @@ -88,8 +81,7 @@ export default function Swap() { const isLoadingQuotesRoute = pathname === LOADING_QUOTES_ROUTE; const fetchParams = useSelector(getFetchParams); - const { sourceTokenInfo = {}, destinationTokenInfo = {} } = - fetchParams?.metaData || {}; + const { destinationTokenInfo = {} } = fetchParams?.metaData || {}; const [inputValue, setInputValue] = useState(fetchParams?.value || ''); const [maxSlippage, setMaxSlippage] = useState(fetchParams?.slippage || 2); @@ -101,8 +93,6 @@ export default function Swap() { const tradeTxId = useSelector(getTradeTxId); const approveTxId = useSelector(getApproveTxId); const aggregatorMetadata = useSelector(getAggregatorMetadata); - const networkId = useSelector(getCurrentNetworkId); - const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider); const fetchingQuotes = useSelector(getFetchingQuotes); let swapsErrorKey = useSelector(getSwapsErrorKey); const swapsEnabled = useSelector(getSwapsFeatureLiveness); @@ -111,20 +101,7 @@ export default function Swap() { balance: ethBalance, address: selectedAccountAddress, } = selectedAccount; - const fetchParamsFromToken = - sourceTokenInfo?.symbol === 'ETH' - ? { - ...ETH_SWAPS_TOKEN_OBJECT, - string: getValueFromWeiHex({ - value: ethBalance, - numberOfDecimals: 4, - toDenomination: 'ETH', - }), - balance: ethBalance, - } - : sourceTokenInfo; - const selectedFromToken = - useSelector(getFromToken) || fetchParamsFromToken || {}; + const { destinationTokenAddedForSwap } = fetchParams || {}; const approveTxData = @@ -299,7 +276,6 @@ export default function Swap() { return ( { return swapsEnabled === false ? ( - + ) : ( ); @@ -399,13 +369,11 @@ export default function Swap() { return routeState === 'awaiting' || tradeTxData ? ( diff --git a/ui/app/pages/swaps/intro-popup/intro-popup.js b/ui/app/pages/swaps/intro-popup/intro-popup.js index 30d934841..359cd0d34 100644 --- a/ui/app/pages/swaps/intro-popup/intro-popup.js +++ b/ui/app/pages/swaps/intro-popup/intro-popup.js @@ -1,12 +1,12 @@ import React, { useContext } from 'react'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import PropTypes from 'prop-types'; import { setSwapsFromToken } from '../../../ducks/swaps/swaps'; import { I18nContext } from '../../../contexts/i18n'; import { BUILD_QUOTE_ROUTE } from '../../../helpers/constants/routes'; import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; -import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken'; +import { getSwapsEthToken } from '../../../selectors'; import Button from '../../../components/ui/button'; import Popover from '../../../components/ui/popover'; @@ -31,7 +31,7 @@ export default function IntroPopup({ onClose }) { event: 'Product Overview Dismissed', category: 'swaps', }); - const swapsEthToken = useSwapsEthToken(); + const swapsEthToken = useSelector(getSwapsEthToken); return (
diff --git a/ui/app/pages/swaps/swaps.util.js b/ui/app/pages/swaps/swaps.util.js index 934caf509..aed3ce2f0 100644 --- a/ui/app/pages/swaps/swaps.util.js +++ b/ui/app/pages/swaps/swaps.util.js @@ -2,7 +2,10 @@ import log from 'loglevel'; import BigNumber from 'bignumber.js'; import abi from 'human-standard-token-abi'; import { isValidAddress } from 'ethereumjs-util'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../../helpers/constants/swaps'; +import { + ETH_SWAPS_TOKEN_OBJECT, + METASWAP_API_HOST, +} from '../../helpers/constants/swaps'; import { calcTokenValue, calcTokenAmount, @@ -27,8 +30,6 @@ const TOKEN_TRANSFER_LOG_TOPIC_HASH = const CACHE_REFRESH_ONE_HOUR = 3600000; -const METASWAP_API_HOST = 'https://api.metaswap.codefi.network'; - const getBaseApi = function (type) { switch (type) { case 'trade': diff --git a/ui/app/pages/swaps/view-quote/view-quote.js b/ui/app/pages/swaps/view-quote/view-quote.js index c553be9d9..1efa81751 100644 --- a/ui/app/pages/swaps/view-quote/view-quote.js +++ b/ui/app/pages/swaps/view-quote/view-quote.js @@ -10,7 +10,6 @@ import { useEthFiatAmount } from '../../../hooks/useEthFiatAmount'; import { useEqualityCheck } from '../../../hooks/useEqualityCheck'; import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; import { usePrevious } from '../../../hooks/usePrevious'; -import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken'; import { MetaMetricsContext } from '../../../contexts/metametrics.new'; import FeeCard from '../fee-card'; import { @@ -37,6 +36,7 @@ import { getSelectedAccount, getCurrentCurrency, getTokenExchangeRates, + getSwapsEthToken, } from '../../../selectors'; import { toPrecisionWithoutTrailingZeros } from '../../../helpers/utils/util'; import { getTokens } from '../../../ducks/metamask/metamask'; @@ -125,6 +125,7 @@ export default function ViewQuote() { const usedQuote = selectedQuote || topQuote; const tradeValue = usedQuote?.trade?.value ?? '0x0'; const swapsQuoteRefreshTime = useSelector(getSwapsQuoteRefreshTime); + const swapsEthToken = useSelector(getSwapsEthToken); const { isBestQuote } = usedQuote; @@ -149,7 +150,6 @@ export default function ViewQuote() { const gasTotalInWeiHex = calcGasTotal(maxGasLimit, gasPrice); const { tokensWithBalances } = useTokenTracker(swapsTokens, true); - const swapsEthToken = useSwapsEthToken(); const balanceToken = fetchParamsSourceToken === swapsEthToken.address ? swapsEthToken diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index 2cb40f5a6..2ac6b4767 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -9,7 +9,12 @@ import { formatETHFee } from '../helpers/utils/formatters'; import { calcGasTotal } from '../pages/send/send.utils'; import { GAS_ESTIMATE_TYPES } from '../helpers/constants/common'; -import { getCurrentCurrency, getIsMainnet, getPreferences } from '.'; +import { + getCurrentCurrency, + getIsMainnet, + getPreferences, + getGasPrice, +} from '.'; const NUMBER_OF_DECIMALS_SM_BTNS = 5; @@ -31,7 +36,7 @@ export function getAveragePriceEstimateInHexWEI(state) { } export function getFastPriceEstimateInHexWEI(state) { - const fastPriceEstimate = state.gas.basicEstimates.fast; + const fastPriceEstimate = getFastPriceEstimate(state); return getGasPriceInHexWei(fastPriceEstimate || '0x0'); } @@ -55,6 +60,16 @@ export function getSafeLowEstimate(state) { return safeLow; } +export function getFastPriceEstimate(state) { + const { + gas: { + basicEstimates: { fast }, + }, + } = state; + + return fast; +} + export function isCustomPriceSafe(state) { const safeLow = getSafeLowEstimate(state); @@ -81,6 +96,31 @@ export function isCustomPriceSafe(state) { return customPriceSafe; } +export function isCustomPriceExcessive(state, checkSend = false) { + const customPrice = checkSend ? getGasPrice(state) : getCustomGasPrice(state); + const fastPrice = getFastPriceEstimate(state); + + if (!customPrice || !fastPrice) { + return false; + } + + // Custom gas should be considered excessive when it is 1.5 times greater than the fastest estimate. + const customPriceExcessive = conversionGreaterThan( + { + value: customPrice, + fromNumericBase: 'hex', + fromDenomination: 'WEI', + toDenomination: 'GWEI', + }, + { + fromNumericBase: 'dec', + value: Math.floor(fastPrice * 1.5), + }, + ); + + return customPriceExcessive; +} + export function basicPriceEstimateToETHTotal( estimate, gasLimit, diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index 46ac30393..5b6f90c68 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -11,6 +11,11 @@ import { checksumAddress, getAccountByAddress, } from '../helpers/utils/util'; +import { + getValueFromWeiHex, + hexToDecimal, +} from '../helpers/utils/conversions.util'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; export function getNetworkIdentifier(state) { const { @@ -127,9 +132,16 @@ export function getMetaMaskAccountsRaw(state) { } export function getMetaMaskCachedBalances(state) { + const chainId = getCurrentChainId(state); + + // Fallback to fetching cached balances from network id + // this can eventually be removed const network = getCurrentNetworkId(state); - return state.metamask.cachedBalances[network]; + return ( + state.metamask.cachedBalances[chainId] ?? + state.metamask.cachedBalances[network] + ); } /** @@ -146,6 +158,12 @@ export const getMetaMaskAccountsOrdered = createSelector( .map((address) => ({ ...identities[address], ...accounts[address] })), ); +export const getMetaMaskAccountsConnected = createSelector( + getMetaMaskAccountsOrdered, + (connectedAccounts) => + connectedAccounts.map(({ address }) => address.toLowerCase()), +); + export function isBalanceCached(state) { const selectedAccountBalance = state.metamask.accounts[getSelectedAddress(state)].balance; @@ -155,7 +173,7 @@ export function isBalanceCached(state) { } export function getSelectedAccountCachedBalance(state) { - const cachedBalances = state.metamask.cachedBalances[state.metamask.network]; + const cachedBalances = getMetaMaskCachedBalances(state); const selectedAddress = getSelectedAddress(state); return cachedBalances && cachedBalances[selectedAddress]; @@ -308,6 +326,11 @@ export function getShouldShowFiat(state) { return Boolean(isMainNet || showFiatInTestnets); } +export function getShouldHideZeroBalanceTokens(state) { + const { hideZeroBalanceTokens } = getPreferences(state); + return hideZeroBalanceTokens; +} + export function getAdvancedInlineGasShown(state) { return Boolean(state.metamask.featureFlags.advancedInlineGas); } @@ -374,3 +397,51 @@ export function getUSDConversionRate(state) { export function getWeb3ShimUsageStateForOrigin(state, origin) { return state.metamask.web3ShimUsageOrigins[origin]; } + +/** + * @typedef {Object} SwapsEthToken + * @property {string} symbol - The symbol for ETH, namely "ETH" + * @property {string} name - The name of the ETH currency, "Ether" + * @property {string} address - A substitute address for the metaswap-api to + * recognize the ETH token + * @property {string} decimals - The number of ETH decimals, i.e. 18 + * @property {string} balance - The user's ETH balance in decimal wei, with a + * precision of 4 decimal places + * @property {string} string - The user's ETH balance in decimal ETH + */ + +/** + * Swaps related code uses token objects for various purposes. These objects + * always have the following properties: `symbol`, `name`, `address`, and + * `decimals`. + * + * When available for the current account, the objects can have `balance` and + * `string` properties. + * `balance` is the users token balance in decimal values, denominated in the + * minimal token units (according to its decimals). + * `string` is the token balance in a readable format, ready for rendering. + * + * Swaps treats ETH as a token, and we use the ETH_SWAPS_TOKEN_OBJECT constant + * to set the standard properties for the token. The getSwapsEthToken selector + * extends that object with `balance` and `balance` values of the same type as + * in regular ERC-20 token objects, per the above description. + * + * @param {object} state - the redux state object + * @returns {SwapsEthToken} The token object representation of the currently + * selected account's ETH balance, as expected by the Swaps API. + */ + +export function getSwapsEthToken(state) { + const selectedAccount = getSelectedAccount(state); + const { balance } = selectedAccount; + + return { + ...ETH_SWAPS_TOKEN_OBJECT, + balance: hexToDecimal(balance), + string: getValueFromWeiHex({ + value: balance, + numberOfDecimals: 4, + toDenomination: 'ETH', + }), + }; +} diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js index 3afb1afdd..ddfd6b136 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -7,6 +7,7 @@ const { getRenderableBasicEstimateData, getRenderableEstimateDataForSmallButtonsFromGWEI, isCustomPriceSafe, + isCustomPriceExcessive, } = proxyquire('../custom-gas', {}); describe('custom-gas selectors', function () { @@ -55,6 +56,91 @@ describe('custom-gas selectors', function () { }); }); + describe('isCustomPriceExcessive()', function () { + it('should return false for gas.customData.price null', function () { + const mockState = { + gas: { + customData: { price: null }, + basicEstimates: { fast: 150 }, + }, + }; + assert.strictEqual(isCustomPriceExcessive(mockState), false); + }); + it('should return false gas.basicEstimates.fast undefined', function () { + const mockState = { + gas: { + customData: { price: '0x77359400' }, + basicEstimates: { fast: undefined }, + }, + }; + assert.strictEqual(isCustomPriceExcessive(mockState), false); + }); + it('should return false gas.basicEstimates.price 0x205d0bae00 (139)', function () { + const mockState = { + gas: { + customData: { price: '0x205d0bae00' }, + basicEstimates: { fast: 139 }, + }, + }; + assert.strictEqual(isCustomPriceExcessive(mockState), false); + }); + it('should return false gas.basicEstimates.price 0x1bf08eb000 (120)', function () { + const mockState = { + gas: { + customData: { price: '0x1bf08eb000' }, + basicEstimates: { fast: 139 }, + }, + }; + assert.strictEqual(isCustomPriceExcessive(mockState), false); + }); + it('should return false gas.basicEstimates.price 0x28bed01600 (175)', function () { + const mockState = { + gas: { + customData: { price: '0x28bed01600' }, + basicEstimates: { fast: 139 }, + }, + }; + assert.strictEqual(isCustomPriceExcessive(mockState), false); + }); + it('should return true gas.basicEstimates.price 0x30e4f9b400 (210)', function () { + const mockState = { + gas: { + customData: { price: '0x30e4f9b400' }, + basicEstimates: { fast: 139 }, + }, + }; + assert.strictEqual(isCustomPriceExcessive(mockState), true); + }); + it('should return false gas.basicEstimates.price 0x28bed01600 (175) (checkSend=true)', function () { + const mockState = { + metamask: { + send: { + gasPrice: '0x28bed0160', + }, + }, + gas: { + customData: { price: null }, + basicEstimates: { fast: 139 }, + }, + }; + assert.strictEqual(isCustomPriceExcessive(mockState, true), false); + }); + it('should return true gas.basicEstimates.price 0x30e4f9b400 (210) (checkSend=true)', function () { + const mockState = { + metamask: { + send: { + gasPrice: '0x30e4f9b400', + }, + }, + gas: { + customData: { price: null }, + basicEstimates: { fast: 139 }, + }, + }; + assert.strictEqual(isCustomPriceExcessive(mockState, true), true); + }); + }); + describe('getCustomGasLimit()', function () { it('should return gas.customData.limit', function () { const mockState = { gas: { customData: { limit: 'mockLimit' } } }; diff --git a/ui/app/selectors/tests/permissions.test.js b/ui/app/selectors/tests/permissions.test.js index c9d303603..d2f82893d 100644 --- a/ui/app/selectors/tests/permissions.test.js +++ b/ui/app/selectors/tests/permissions.test.js @@ -1,4 +1,5 @@ import assert from 'assert'; +import { KOVAN_CHAIN_ID } from '../../../../shared/constants/network'; import { getConnectedDomainsForSelectedAddress, getOrderedConnectedAccountsForActiveTab, @@ -163,6 +164,9 @@ describe('selectors', function () { url: 'https://remix.ethereum.org/', }, metamask: { + provider: { + chainId: KOVAN_CHAIN_ID, + }, accounts: { 0x7250739de134d33ec7ab1ee592711e15098c9d2d: { address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d', diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js index d0dae9c76..06e4d84b7 100644 --- a/ui/app/store/actions.js +++ b/ui/app/store/actions.js @@ -422,33 +422,40 @@ export function connectHardware(deviceName, page, hdPath) { }; } -export function unlockHardwareWalletAccount(index, deviceName, hdPath) { +export function unlockHardwareWalletAccounts( + indexes, + deviceName, + hdPath, + hdPathDescription, +) { log.debug( `background.unlockHardwareWalletAccount`, - index, + indexes, deviceName, hdPath, + hdPathDescription, ); - return (dispatch) => { + return async (dispatch) => { dispatch(showLoadingIndication()); - return new Promise((resolve, reject) => { - background.unlockHardwareWalletAccount( - index, - deviceName, - hdPath, - (err) => { - dispatch(hideLoadingIndication()); - if (err) { - log.error(err); - dispatch(displayWarning(err.message)); - reject(err); - return; - } - resolve(); - }, - ); - }); + for (const index of indexes) { + try { + await promisifiedBackground.unlockHardwareWalletAccount( + index, + deviceName, + hdPath, + hdPathDescription, + ); + } catch (e) { + log.error(e); + dispatch(displayWarning(e.message)); + dispatch(hideLoadingIndication()); + throw e; + } + } + + dispatch(hideLoadingIndication()); + return undefined; }; } @@ -2046,6 +2053,10 @@ export function setUseNativeCurrencyAsPrimaryCurrencyPreference(value) { return setPreference('useNativeCurrencyAsPrimaryCurrency', value); } +export function setHideZeroBalanceTokens(value) { + return setPreference('hideZeroBalanceTokens', value); +} + export function setShowFiatConversionOnTestnetsPreference(value) { return setPreference('showFiatInTestnets', value); } diff --git a/ui/lib/account-link.js b/ui/lib/account-link.js index 9d7014487..47d36908a 100644 --- a/ui/lib/account-link.js +++ b/ui/lib/account-link.js @@ -1,4 +1,6 @@ -export default function getAccountLink(address, network, rpcPrefs) { +import { createAccountLinkForChain } from '@metamask/etherscan-link'; + +export default function getAccountLink(address, chainId, rpcPrefs) { if (rpcPrefs && rpcPrefs.blockExplorerUrl) { return `${rpcPrefs.blockExplorerUrl.replace( /\/+$/u, @@ -6,22 +8,5 @@ export default function getAccountLink(address, network, rpcPrefs) { )}/address/${address}`; } - // eslint-disable-next-line radix - const net = parseInt(network); - switch (net) { - case 1: // main net - return `https://etherscan.io/address/${address}`; - case 2: // morden test net - return `https://morden.etherscan.io/address/${address}`; - case 3: // ropsten test net - return `https://ropsten.etherscan.io/address/${address}`; - case 4: // rinkeby test net - return `https://rinkeby.etherscan.io/address/${address}`; - case 42: // kovan test net - return `https://kovan.etherscan.io/address/${address}`; - case 5: // goerli test net - return `https://goerli.etherscan.io/address/${address}`; - default: - return ''; - } + return createAccountLinkForChain(address, chainId); } diff --git a/ui/lib/etherscan-prefix-for-network.js b/ui/lib/etherscan-prefix-for-network.js deleted file mode 100644 index 9fb740090..000000000 --- a/ui/lib/etherscan-prefix-for-network.js +++ /dev/null @@ -1,23 +0,0 @@ -import * as networkEnums from '../../shared/constants/network'; - -/** - * Gets the etherscan.io URL prefix for a given network ID. - * - * @param {string} networkId - The network ID to get the prefix for. - * @returns {string} The etherscan.io URL prefix for the given network ID. - */ -export function getEtherscanNetworkPrefix(networkId) { - switch (networkId) { - case networkEnums.ROPSTEN_NETWORK_ID: - return 'ropsten.'; - case networkEnums.RINKEBY_NETWORK_ID: - return 'rinkeby.'; - case networkEnums.KOVAN_NETWORK_ID: - return 'kovan.'; - case networkEnums.GOERLI_NETWORK_ID: - return 'goerli.'; - default: - // also covers mainnet - return ''; - } -} diff --git a/yarn.lock b/yarn.lock index 1f7a9175e..28eb70bbc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1292,22 +1292,35 @@ "@ethersproject/properties" ">=5.0.0-beta.131" "@ethersproject/strings" ">=5.0.0-beta.130" -"@ethersproject/abi@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.2.tgz#7fe8f080aa1483fe32cd27bb5b8f2019266af1e2" - integrity sha512-Z+5f7xOgtRLu/W2l9Ry5xF7ehh9QVQ0m1vhynmTcS7DMfHgqTd1/PDFC62aw91ZPRCRZsYdZJu8ymokC5e1JSw== +"@ethersproject/abi@5.0.13", "@ethersproject/abi@^5.0.10": + version "5.0.13" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.13.tgz#600a559c3730467716595658beaa2894b4352bcc" + integrity sha512-2coOH3D7ra1lwamKEH0HVc+Jbcsw5yfeCgmY8ekhCDualEiyyovD2qDcMBBcY3+kjoLHVTmo7ost6MNClxdOrg== dependencies: - "@ethersproject/address" "^5.0.0" - "@ethersproject/bignumber" "^5.0.0" - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/constants" "^5.0.0" - "@ethersproject/hash" "^5.0.0" - "@ethersproject/keccak256" "^5.0.0" - "@ethersproject/logger" "^5.0.0" - "@ethersproject/properties" "^5.0.0" - "@ethersproject/strings" "^5.0.0" + "@ethersproject/address" "^5.0.9" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/constants" "^5.0.8" + "@ethersproject/hash" "^5.0.10" + "@ethersproject/keccak256" "^5.0.7" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/strings" "^5.0.8" -"@ethersproject/abstract-provider@^5.0.0", "@ethersproject/abstract-provider@^5.0.4": +"@ethersproject/abstract-provider@5.0.10", "@ethersproject/abstract-provider@^5.0.8": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.10.tgz#a533aed39a5f27312745c8c4c40fa25fc884831c" + integrity sha512-OSReY5iz94iIaPlRvLiJP8YVIvQLx4aUvMMnHWSaA/vTU8QHZmgNlt4OBdYV1+aFY8Xl+VRYiWBHq72ZDKXXCQ== + dependencies: + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/networks" "^5.0.7" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/transactions" "^5.0.9" + "@ethersproject/web" "^5.0.12" + +"@ethersproject/abstract-provider@^5.0.4": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.5.tgz#797a32a8707830af1ad8f833e9c228994d5572b9" integrity sha512-i/CjElAkzV7vQBAeoz+IpjGfcFYEP9eD7j3fzZ0fzTq03DO7PPnR+xkEZ1IoDXGwDS+55aLM1xvLDwB/Lx6IOQ== @@ -1320,7 +1333,18 @@ "@ethersproject/transactions" "^5.0.5" "@ethersproject/web" "^5.0.6" -"@ethersproject/abstract-signer@^5.0.0", "@ethersproject/abstract-signer@^5.0.6": +"@ethersproject/abstract-signer@5.0.14", "@ethersproject/abstract-signer@^5.0.10": + version "5.0.14" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.14.tgz#30ef912b0f86599d90fdffc65c110452e7b55cf1" + integrity sha512-JztBwVO7o5OHLh2vyjordlS4/1EjRyaECtc8vPdXTF1i4dXN+J0coeRoPN6ZFbBvi/YbaB6br2fvqhst1VQD/g== + dependencies: + "@ethersproject/abstract-provider" "^5.0.8" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + +"@ethersproject/abstract-signer@^5.0.6": version "5.0.7" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.7.tgz#cdbd3bd479edf77c71b7f6a6156b0275b1176ded" integrity sha512-8W8gy/QutEL60EoMEpvxZ8MFAEWs/JvH5nmZ6xeLXoZvmBCasGmxqHdYjo2cxg0nevkPkq9SeenSsBBZSCx+SQ== @@ -1331,7 +1355,18 @@ "@ethersproject/logger" "^5.0.5" "@ethersproject/properties" "^5.0.3" -"@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.0", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.0.5": +"@ethersproject/address@5.0.11", "@ethersproject/address@^5.0.9": + version "5.0.11" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.11.tgz#12022e8c590c33939beb5ab18b401ecf585eac59" + integrity sha512-Et4GBdD8/tsBGjCEOKee9upN29qjL5kbRcmJifb4Penmiuh9GARXL2/xpXvEp5EW+EIW/rfCHFJrkYBgoQFQBw== + dependencies: + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/keccak256" "^5.0.7" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/rlp" "^5.0.7" + +"@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.0.5": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.5.tgz#2caa65f6b7125015395b1b54c985ee0b27059cc7" integrity sha512-DpkQ6rwk9jTefrRsJzEm6nhRiJd9pvhn1xN0rw5N/jswXG5r7BLk/GVA0mMAVWAsYfvi2xSc5L41FMox43RYEA== @@ -1343,22 +1378,38 @@ "@ethersproject/rlp" "^5.0.3" bn.js "^4.4.0" -"@ethersproject/base64@^5.0.0", "@ethersproject/base64@^5.0.3": +"@ethersproject/base64@5.0.9", "@ethersproject/base64@^5.0.7": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.9.tgz#bb1f35d3dba92082a574d5e2418f9202a0a1a7e6" + integrity sha512-37RBz5LEZ9SlTNGiWCYFttnIN9J7qVs9Xo2EbqGqDH5LfW9EIji66S+YDMpXVo1zWDax1FkEldAoatxHK2gfgA== + dependencies: + "@ethersproject/bytes" "^5.0.9" + +"@ethersproject/base64@^5.0.3": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.4.tgz#b0d8fdbf3dda977cf546dcd35725a7b1d5256caa" integrity sha512-4KRykQ7BQMeOXfvio1YITwHjxwBzh92UoXIdzxDE1p53CK28bbHPdsPNYo0wl0El7lJAMpT2SOdL0hhbWRnyIA== dependencies: "@ethersproject/bytes" "^5.0.4" -"@ethersproject/basex@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.0.2.tgz#13029ce0ad63674f4d4dbebf6763181fb22f0e6d" - integrity sha512-p4m2CeQqI9vma3XipRbP2iDf6zTsbroE0MEXBAYXidsoJQSvePKrC6MVRKfTzfcHej1b9wfmjVBzqhqn3FRhIA== +"@ethersproject/basex@5.0.9", "@ethersproject/basex@^5.0.7": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.0.9.tgz#00d727a031bac563cb8bb900955206f1bf3cf1fc" + integrity sha512-FANswl1IN3PS0eltQxH2aM2+utPrkLUVG4XVFi6SafRG9EpAqXCgycxC8PU90mPGhigYTpg9cnTB5mCZ6ejQjw== dependencies: - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/properties" "^5.0.0" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/properties" "^5.0.7" -"@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.0", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.0.8": +"@ethersproject/bignumber@5.0.15", "@ethersproject/bignumber@^5.0.13": + version "5.0.15" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.15.tgz#b089b3f1e0381338d764ac1c10512f0c93b184ed" + integrity sha512-MTADqnyacvdRwtKh7o9ujwNDSM1SDJjYDMYAzjIgjoi9rh6TY4suMbhCa3i2vh3SUXiXSICyTI8ui+NPdrZ9Lw== + dependencies: + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + bn.js "^4.4.0" + +"@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.0.8": version "5.0.8" resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.8.tgz#cee33bd8eb0266176def0d371b45274b1d2c4ec0" integrity sha512-KXFVAFKS1jdTXYN8BE5Oj+ZfPMh28iRdFeNGBVT6cUFdtiPVqeXqc0ggvBqA3A1VoFFGgM7oAeaagA393aORHA== @@ -1367,36 +1418,64 @@ "@ethersproject/logger" "^5.0.5" bn.js "^4.4.0" -"@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0", "@ethersproject/bytes@^5.0.4": +"@ethersproject/bytes@5.0.11", "@ethersproject/bytes@^5.0.9": + version "5.0.11" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.11.tgz#21118e75b1d00db068984c15530e316021101276" + integrity sha512-D51plLYY5qF05AsoVQwIZVLqlBkaTPVHVP/1WmmBIWyHB0cRW0C9kh0kx5Exo51rB63Hk8PfHxc7SmpoaQFEyg== + dependencies: + "@ethersproject/logger" "^5.0.8" + +"@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.4": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.5.tgz#688b70000e550de0c97a151a21f15b87d7f97d7c" integrity sha512-IEj9HpZB+ACS6cZ+QQMTqmu/cnUK2fYNE6ms/PVxjoBjoxc6HCraLpam1KuRvreMy0i523PLmjN8OYeikRdcUQ== dependencies: "@ethersproject/logger" "^5.0.5" -"@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.0", "@ethersproject/constants@^5.0.4": +"@ethersproject/constants@5.0.10", "@ethersproject/constants@^5.0.8": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.10.tgz#eb0c604fbc44c53ba9641eed31a1d0c9e1ebcadc" + integrity sha512-OSo8jxkHLDXieCy8bgOFR7lMfgPxEzKvSDdP+WAWHCDM8+orwch0B6wzkTmiQFgryAtIctrBt5glAdJikZ3hGw== + dependencies: + "@ethersproject/bignumber" "^5.0.13" + +"@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.4": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.5.tgz#0ed19b002e8404bdf6d135234dc86a7d9bcf9b71" integrity sha512-foaQVmxp2+ik9FrLUCtVrLZCj4M3Ibgkqvh+Xw/vFRSerkjVSYePApaVE5essxhoSlF1U9oXfWY09QI2AXtgKA== dependencies: "@ethersproject/bignumber" "^5.0.7" -"@ethersproject/contracts@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.0.2.tgz#f19ed8335ceeb6abb60f5d45641f0a2a62b6fbc5" - integrity sha512-Ud3oW8mBNIWE+WHRjvwVEwfvshn7lfYWSSKG0fPSb6baRN9mLOoNguX+VIv3W5Sne9w2utnBmxLF2ESXitw64A== +"@ethersproject/contracts@5.0.12": + version "5.0.12" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.0.12.tgz#6d488db46221258399dfe80b89bf849b3afd7897" + integrity sha512-srijy31idjz8bE+gL1I6IRj2H4I9dUwfQ+QroLrIgNdGArqY8y2iFUKa3QTy+JBX26fJsdYiCQi1kKkaNpnMpQ== dependencies: - "@ethersproject/abi" "^5.0.0" - "@ethersproject/abstract-provider" "^5.0.0" - "@ethersproject/abstract-signer" "^5.0.0" - "@ethersproject/address" "^5.0.0" - "@ethersproject/bignumber" "^5.0.0" - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/constants" "^5.0.0" - "@ethersproject/logger" "^5.0.0" - "@ethersproject/properties" "^5.0.0" + "@ethersproject/abi" "^5.0.10" + "@ethersproject/abstract-provider" "^5.0.8" + "@ethersproject/abstract-signer" "^5.0.10" + "@ethersproject/address" "^5.0.9" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/constants" "^5.0.8" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" -"@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.0.0": +"@ethersproject/hash@5.0.12", "@ethersproject/hash@^5.0.10": + version "5.0.12" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.12.tgz#1074599f7509e2ca2bb7a3d4f4e39ab3a796da42" + integrity sha512-kn4QN+fhNFbUgX3XZTZUaQixi0oyfIEY+hfW+KtkHu+rq7dV76oAIvaLEEynu1/4npOL38E4X4YI42gGZk+C0Q== + dependencies: + "@ethersproject/abstract-signer" "^5.0.10" + "@ethersproject/address" "^5.0.9" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/keccak256" "^5.0.7" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/strings" "^5.0.8" + +"@ethersproject/hash@>=5.0.0-beta.128": version "5.0.6" resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.6.tgz#2a2e8a1470685421217e9e86e9971ca636e609ce" integrity sha512-Gvh57v6BWhwnud6l7tMfQm32PRQ2DYx2WaAAQmAxAfYvmzUkpQCBstnGeNMXIL8/2wdkvcB2u+WZRWaZtsFuUQ== @@ -1410,44 +1489,52 @@ "@ethersproject/properties" "^5.0.4" "@ethersproject/strings" "^5.0.4" -"@ethersproject/hdnode@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.0.2.tgz#c4f2152590a64822d0c0feb90f09cc247af657e0" - integrity sha512-QAUI5tfseTFqv00Vnbwzofqse81wN9TaL+x5GufTHIHJXgVdguxU+l39E3VYDCmO+eVAA6RCn5dJgeyra+PU2g== +"@ethersproject/hdnode@5.0.10", "@ethersproject/hdnode@^5.0.8": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.0.10.tgz#f7cdf154bf5d104c76dce2940745fc71d9e7eb1b" + integrity sha512-ZLwMtIcXK7xz2lSITDCl40W04CtRq4K9NwBxhCzdzPdaz6XnoJMwGz2YMVLg+8ksseq+RYtTwIIXtlK6vyvQyg== dependencies: - "@ethersproject/abstract-signer" "^5.0.0" - "@ethersproject/basex" "^5.0.0" - "@ethersproject/bignumber" "^5.0.0" - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/logger" "^5.0.0" - "@ethersproject/pbkdf2" "^5.0.0" - "@ethersproject/properties" "^5.0.0" - "@ethersproject/sha2" "^5.0.0" - "@ethersproject/signing-key" "^5.0.0" - "@ethersproject/strings" "^5.0.0" - "@ethersproject/transactions" "^5.0.0" - "@ethersproject/wordlists" "^5.0.0" + "@ethersproject/abstract-signer" "^5.0.10" + "@ethersproject/basex" "^5.0.7" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/pbkdf2" "^5.0.7" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/sha2" "^5.0.7" + "@ethersproject/signing-key" "^5.0.8" + "@ethersproject/strings" "^5.0.8" + "@ethersproject/transactions" "^5.0.9" + "@ethersproject/wordlists" "^5.0.8" -"@ethersproject/json-wallets@^5.0.0": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.0.4.tgz#e09bf2d34279c6dd2b4a4d4c44db65471bacc68b" - integrity sha512-jqtb+X3rJXWG/w+Qyr7vq1V+fdc5jiLlyc6akwI3SQIHTfcuuyF+eZRd9u2/455urNwV3nuCsnrgxs2NrtHHIw== +"@ethersproject/json-wallets@5.0.12", "@ethersproject/json-wallets@^5.0.10": + version "5.0.12" + resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.0.12.tgz#8946a0fcce1634b636313a50330b7d30a24996e8" + integrity sha512-nac553zGZnOewpjlqbfy7WBl8m3y7qudzRsI2dCxrediYtPIVIs9f6Pbnou8vDmmp8X4/U4W788d+Ma88o+Gbg== dependencies: - "@ethersproject/abstract-signer" "^5.0.0" - "@ethersproject/address" "^5.0.0" - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/hdnode" "^5.0.0" - "@ethersproject/keccak256" "^5.0.0" - "@ethersproject/logger" "^5.0.0" - "@ethersproject/pbkdf2" "^5.0.0" - "@ethersproject/properties" "^5.0.0" - "@ethersproject/random" "^5.0.0" - "@ethersproject/strings" "^5.0.0" - "@ethersproject/transactions" "^5.0.0" + "@ethersproject/abstract-signer" "^5.0.10" + "@ethersproject/address" "^5.0.9" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/hdnode" "^5.0.8" + "@ethersproject/keccak256" "^5.0.7" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/pbkdf2" "^5.0.7" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/random" "^5.0.7" + "@ethersproject/strings" "^5.0.8" + "@ethersproject/transactions" "^5.0.9" aes-js "3.0.0" scrypt-js "3.0.1" -"@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.0", "@ethersproject/keccak256@^5.0.3": +"@ethersproject/keccak256@5.0.9", "@ethersproject/keccak256@^5.0.7": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.9.tgz#ca0d86e4af56c13b1ef25e533bde3e96d28f647d" + integrity sha512-zhdUTj6RGtCJSgU+bDrWF6cGbvW453LoIC1DSNWrTlXzC7WuH4a+EiPrgc7/kNoRxerKuA/cxYlI8GwNtVtDlw== + dependencies: + "@ethersproject/bytes" "^5.0.9" + js-sha3 "0.5.7" + +"@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.3": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.4.tgz#36ca0a7d1ae2a272da5654cb886776d0c680ef3a" integrity sha512-GNpiOUm9PGUxFNqOxYKDQBM0u68bG9XC9iOulEQ8I0tOx/4qUpgVzvgXL6ugxr0RY554Gz/NQsVqknqPzUcxpQ== @@ -1455,64 +1542,94 @@ "@ethersproject/bytes" "^5.0.4" js-sha3 "0.5.7" -"@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.0", "@ethersproject/logger@^5.0.5": +"@ethersproject/logger@5.0.10", "@ethersproject/logger@^5.0.8": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.10.tgz#fd884688b3143253e0356ef92d5f22d109d2e026" + integrity sha512-0y2T2NqykDrbPM3Zw9RSbPkDOxwChAL8detXaom76CfYoGxsOnRP/zTX8OUAV+x9LdwzgbWvWmeXrc0M7SuDZw== + +"@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.5": version "5.0.6" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.6.tgz#faa484203e86e08be9e07fef826afeef7183fe88" integrity sha512-FrX0Vnb3JZ1md/7GIZfmJ06XOAA8r3q9Uqt9O5orr4ZiksnbpXKlyDzQtlZ5Yv18RS8CAUbiKH9vwidJg1BPmQ== -"@ethersproject/networks@^5.0.0", "@ethersproject/networks@^5.0.3": +"@ethersproject/networks@5.0.9", "@ethersproject/networks@^5.0.7": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.9.tgz#ec5da11e4d4bfd69bec4eaebc9ace33eb9569279" + integrity sha512-L8+VCQwArBLGkxZb/5Ns/OH/OxP38AcaveXIxhUTq+VWpXYjrObG3E7RDQIKkUx1S1IcQl/UWTz5w4DK0UitJg== + dependencies: + "@ethersproject/logger" "^5.0.8" + +"@ethersproject/networks@^5.0.3": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.4.tgz#6d320a5e15a0cda804f5da88be0ba846156f6eec" integrity sha512-/wHDTRms5mpJ09BoDrbNdFWINzONe05wZRgohCXvEv39rrH/Gd/yAnct8wC0RsW3tmFOgjgQxuBvypIxuUynTw== dependencies: "@ethersproject/logger" "^5.0.5" -"@ethersproject/pbkdf2@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.0.2.tgz#d12c5f434bbdf6f52401eddb7d753a713dd9e4ea" - integrity sha512-OJFxdX/VtGI5M04lAzXKEOb76XBzjCOzGyko3/bMWat3ePAw7RveBOLyhm79SBs2fh21MSYgdG6JScEMHoSImw== +"@ethersproject/pbkdf2@5.0.9", "@ethersproject/pbkdf2@^5.0.7": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.0.9.tgz#be39c7f0a66c0d3cb1ad1dbb12a78e9bcdf9b5ae" + integrity sha512-ItE/wQ/WVw/ajEHPUVgfu0aEvksPgOQc+278bke8sGKnGO3ppjmqp0MHh17tHc1EBTzJbSms5aLIqc56qZ/oiA== dependencies: - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/sha2" "^5.0.0" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/sha2" "^5.0.7" -"@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.0", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.0.4": +"@ethersproject/properties@5.0.9", "@ethersproject/properties@^5.0.7": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.9.tgz#d7aae634680760136ea522e25c3ef043ec15b5c2" + integrity sha512-ZCjzbHYTw+rF1Pn8FDCEmx3gQttwIHcm/6Xee8g/M3Ga3SfW4tccNMbs5zqnBH0E4RoOPaeNgyg1O68TaF0tlg== + dependencies: + "@ethersproject/logger" "^5.0.8" + +"@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.0.4": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.4.tgz#a67a1f5a52c30850b5062c861631e73d131f666e" integrity sha512-UdyX3GqBxFt15B0uSESdDNmhvEbK3ACdDXl2soshoPcneXuTswHDeA0LoPlnaZzhbgk4p6jqb4GMms5C26Qu6A== dependencies: "@ethersproject/logger" "^5.0.5" -"@ethersproject/providers@^5.0.0": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.0.5.tgz#fa28498ce9683d1d99f6cb11e1a7fe8d4886e0ce" - integrity sha512-ZR3yFg/m8qDl7317yXOHE7tKeGfoyZIZ/imhVC4JqAH+SX1rb6bdZcSjhJfet7rLmnJSsnYLTgIiVIT85aVLgg== +"@ethersproject/providers@5.0.24": + version "5.0.24" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.0.24.tgz#4c638a029482d052faa18364b5e0e2d3ddd9c0cb" + integrity sha512-M4Iw1r4gGJkt7ZUa++iREuviKL/DIpmIMsaUlVlXtV+ZrUXeN8xQ3zOTrbz7R4h9W9oljBZM7i4D3Kn1krJ30A== dependencies: - "@ethersproject/abstract-provider" "^5.0.0" - "@ethersproject/abstract-signer" "^5.0.0" - "@ethersproject/address" "^5.0.0" - "@ethersproject/bignumber" "^5.0.0" - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/constants" "^5.0.0" - "@ethersproject/hash" "^5.0.0" - "@ethersproject/logger" "^5.0.0" - "@ethersproject/networks" "^5.0.0" - "@ethersproject/properties" "^5.0.0" - "@ethersproject/random" "^5.0.0" - "@ethersproject/rlp" "^5.0.0" - "@ethersproject/strings" "^5.0.0" - "@ethersproject/transactions" "^5.0.0" - "@ethersproject/web" "^5.0.0" + "@ethersproject/abstract-provider" "^5.0.8" + "@ethersproject/abstract-signer" "^5.0.10" + "@ethersproject/address" "^5.0.9" + "@ethersproject/basex" "^5.0.7" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/constants" "^5.0.8" + "@ethersproject/hash" "^5.0.10" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/networks" "^5.0.7" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/random" "^5.0.7" + "@ethersproject/rlp" "^5.0.7" + "@ethersproject/sha2" "^5.0.7" + "@ethersproject/strings" "^5.0.8" + "@ethersproject/transactions" "^5.0.9" + "@ethersproject/web" "^5.0.12" + bech32 "1.1.4" ws "7.2.3" -"@ethersproject/random@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.0.2.tgz#bb58aca69a85e8de506686117f050d03dac69023" - integrity sha512-kLeS+6bwz37WR2zbe69gudyoGVoUzljQO0LhifnATsZ7rW0JZ9Zgt0h5aXY7tqFDo9TvdqeCwUFdp1t3T5Fkhg== +"@ethersproject/random@5.0.9", "@ethersproject/random@^5.0.7": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.0.9.tgz#1903d4436ba66e4c8ac77968b16f756abea3a0d0" + integrity sha512-DANG8THsKqFbJOantrxumtG6gyETNE54VfbsWa+SQAT8WKpDo9W/X5Zhh73KuhClaey1UI32uVmISZeq/Zxn1A== dependencies: - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/logger" "^5.0.0" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" -"@ethersproject/rlp@^5.0.0", "@ethersproject/rlp@^5.0.3": +"@ethersproject/rlp@5.0.9", "@ethersproject/rlp@^5.0.7": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.9.tgz#da205bf8a34d3c3409eb73ddd237130a4b376aff" + integrity sha512-ns1U7ZMVeruUW6JXc4om+1w3w4ynHN/0fpwmeNTsAjwGKoF8SAUgue6ylKpHKWSti2idx7jDxbn8hNNFHk67CA== + dependencies: + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + +"@ethersproject/rlp@^5.0.3": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.4.tgz#0090a0271e84ea803016a112a79f5cfd80271a77" integrity sha512-5qrrZad7VTjofxSsm7Zg/7Dr4ZOln4S2CqiDdOuTv6MBKnXj0CiBojXyuDy52M8O3wxH0CyE924hXWTDV1PQWQ== @@ -1520,37 +1637,46 @@ "@ethersproject/bytes" "^5.0.4" "@ethersproject/logger" "^5.0.5" -"@ethersproject/sha2@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.0.2.tgz#baefc78c071be8729b180759eb29267129314252" - integrity sha512-VFl4qSStjQZaygpqoAHswaCY59qBm1Sm0rf8iv0tmgVsRf0pBg2nJaNf9NXXvcuJ9AYPyXl57dN8kozdC4z5Cg== +"@ethersproject/sha2@5.0.9", "@ethersproject/sha2@^5.0.7": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.0.9.tgz#41275ee03e6e1660b3c997754005e089e936adc6" + integrity sha512-5FH4s47gM7N1fFAYQ1+m7aX0SbLg0Xr+6tvqndmNqc382/qBIbzXiGlUookrsjlPb6gLNurnTssCXjNM72J6lQ== dependencies: - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/logger" "^5.0.0" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" hash.js "1.1.3" -"@ethersproject/signing-key@^5.0.0", "@ethersproject/signing-key@^5.0.4": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.5.tgz#acfd06fc05a14180df7e027688bbd23fc4baf782" - integrity sha512-Z1wY7JC1HVO4CvQWY2TyTTuAr8xK3bJijZw1a9G92JEmKdv1j255R/0YLBBcFTl2J65LUjtXynNJ2GbArPGi5g== +"@ethersproject/signing-key@5.0.11", "@ethersproject/signing-key@^5.0.4", "@ethersproject/signing-key@^5.0.8": + version "5.0.11" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.11.tgz#19fc5c4597e18ad0a5efc6417ba5b74069fdd2af" + integrity sha512-Jfcru/BGwdkXhLxT+8WCZtFy7LL0TPFZw05FAb5asxB/MyVsEfNdNxGDtjVE9zXfmRSPe/EusXYY4K7wcygOyQ== dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - elliptic "6.5.3" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + elliptic "6.5.4" -"@ethersproject/solidity@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.0.2.tgz#431cee341ec51e022bd897b93fef04521f414756" - integrity sha512-RygurUe1hPW1LDYAPXy4471AklGWNnxgFWc3YUE6H11gzkit26jr6AyZH4Yyjw38eBBL6j0AOfQzMWm+NhxZ9g== +"@ethersproject/solidity@5.0.10": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.0.10.tgz#128c9289761cf83d81ff62a1195d6079a924a86c" + integrity sha512-8OG3HLqynWXDA6mVIHuHfF/ojTTwBahON7hc9GAKCqglzXCkVA3OpyxOJXPzjHClRIAUUiU7r9oy9Z/nsjtT/g== dependencies: - "@ethersproject/bignumber" "^5.0.0" - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/keccak256" "^5.0.0" - "@ethersproject/sha2" "^5.0.0" - "@ethersproject/strings" "^5.0.0" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/keccak256" "^5.0.7" + "@ethersproject/sha2" "^5.0.7" + "@ethersproject/strings" "^5.0.8" -"@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.0", "@ethersproject/strings@^5.0.4": +"@ethersproject/strings@5.0.10", "@ethersproject/strings@^5.0.8": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.10.tgz#ddce1e9724f4ac4f3f67e0cac0b48748e964bfdb" + integrity sha512-KAeoS1tZ9/5ECXiIZA6S6hywbD0so2VmuW+Wfyo5EDXeyZ6Na1nxTPhTnW7voQmjbeYJffCrOc0qLFJeylyg7w== + dependencies: + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/constants" "^5.0.8" + "@ethersproject/logger" "^5.0.8" + +"@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.4": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.5.tgz#ed7e99a282a02f40757691b04a24cd83f3752195" integrity sha512-JED6WaIV00xM/gvj8vSnd+0VWtDYdidTmavFRCTQakqfz+4tDo6Jz5LHgG+dd45h7ah7ykCHW0C7ZXWEDROCXQ== @@ -1559,7 +1685,22 @@ "@ethersproject/constants" "^5.0.4" "@ethersproject/logger" "^5.0.5" -"@ethersproject/transactions@^5.0.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.0.5": +"@ethersproject/transactions@5.0.11", "@ethersproject/transactions@^5.0.9": + version "5.0.11" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.11.tgz#b31df5292f47937136a45885d6ee6112477c13df" + integrity sha512-ftsRvR9+gQp7L63F6+XmstvsZ4w8GtWvQB08e/zB+oB86Fnhq8+i/tkgpJplSHC8I/qgiCisva+M3u2GVhDFPA== + dependencies: + "@ethersproject/address" "^5.0.9" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/constants" "^5.0.8" + "@ethersproject/keccak256" "^5.0.7" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/rlp" "^5.0.7" + "@ethersproject/signing-key" "^5.0.8" + +"@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.0.5": version "5.0.6" resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.6.tgz#b8b27938be6e9ed671dbdd35fe98af8b14d0df7c" integrity sha512-htsFhOD+NMBxx676A8ehSuwVV49iqpSB+CkjPZ02tpNew0K6p8g0CZ46Z1ZP946gIHAU80xQ0NACHYrjIUaCFA== @@ -1574,37 +1715,48 @@ "@ethersproject/rlp" "^5.0.3" "@ethersproject/signing-key" "^5.0.4" -"@ethersproject/units@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.0.2.tgz#de1461ff3ad2587e57bf367d056b6b72cfceda78" - integrity sha512-PSuzycBA1zmRysTtKtp+XYZ3HIJfbmfRdZchOUxdyeGo5siUi9H6mYQcxdJHv82oKp/FniMj8qS8qtLQThhOEg== +"@ethersproject/units@5.0.11": + version "5.0.11" + resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.0.11.tgz#f82f6e353ac0d6fa43b17337790f1f9aa72cb4c8" + integrity sha512-nOSPmcCWyB/dwoBRhhTtPGCsTbiXqmc7Q0Adwvafc432AC7hy3Fj3IFZtnSXsbtJ/GdHCIUIoA8gtvxSsFuBJg== dependencies: - "@ethersproject/bignumber" "^5.0.0" - "@ethersproject/constants" "^5.0.0" - "@ethersproject/logger" "^5.0.0" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/constants" "^5.0.8" + "@ethersproject/logger" "^5.0.8" -"@ethersproject/wallet@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.0.2.tgz#714ca8324c1b3b66e51b9b4e0358c882e88caf1d" - integrity sha512-gg86ynLV5k5caNnYpJoYc6WyIUHKMTjOITCk5zXGyVbbkXE07y/fGql4A51W0C6mWkeb5Mzz8AKqzHZECdH30w== +"@ethersproject/wallet@5.0.12": + version "5.0.12" + resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.0.12.tgz#bfb96f95e066b4b1b4591c4615207b87afedda8b" + integrity sha512-rboJebGf47/KPZrKZQdYg9BAYuXbc/OwcUyML1K1f2jnJeo1ObWV11U1PAWTjTbhhSy6/Fg+34GO2yMb5Dt1Rw== dependencies: - "@ethersproject/abstract-provider" "^5.0.0" - "@ethersproject/abstract-signer" "^5.0.0" - "@ethersproject/address" "^5.0.0" - "@ethersproject/bignumber" "^5.0.0" - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/hash" "^5.0.0" - "@ethersproject/hdnode" "^5.0.0" - "@ethersproject/json-wallets" "^5.0.0" - "@ethersproject/keccak256" "^5.0.0" - "@ethersproject/logger" "^5.0.0" - "@ethersproject/properties" "^5.0.0" - "@ethersproject/random" "^5.0.0" - "@ethersproject/signing-key" "^5.0.0" - "@ethersproject/transactions" "^5.0.0" - "@ethersproject/wordlists" "^5.0.0" + "@ethersproject/abstract-provider" "^5.0.8" + "@ethersproject/abstract-signer" "^5.0.10" + "@ethersproject/address" "^5.0.9" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/hash" "^5.0.10" + "@ethersproject/hdnode" "^5.0.8" + "@ethersproject/json-wallets" "^5.0.10" + "@ethersproject/keccak256" "^5.0.7" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/random" "^5.0.7" + "@ethersproject/signing-key" "^5.0.8" + "@ethersproject/transactions" "^5.0.9" + "@ethersproject/wordlists" "^5.0.8" -"@ethersproject/web@^5.0.0", "@ethersproject/web@^5.0.6": +"@ethersproject/web@5.0.14", "@ethersproject/web@^5.0.12": + version "5.0.14" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.14.tgz#6e7bebdd9fb967cb25ee60f44d9218dc0803bac4" + integrity sha512-QpTgplslwZ0Sp9oKNLoRuS6TKxnkwfaEk3gr7zd7XLF8XBsYejsrQO/03fNfnMx/TAT/RR6WEw/mbOwpRSeVRA== + dependencies: + "@ethersproject/base64" "^5.0.7" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/strings" "^5.0.8" + +"@ethersproject/web@^5.0.6": version "5.0.9" resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.9.tgz#b08f8295f4bfd4777c8723fe9572f5453b9f03cb" integrity sha512-//QNlv1MSkOII1hv3+HQwWoiVFS+BMVGI0KYeUww4cyrEktnx1QIez5bTSab9s9fWTFaWKNmQNBwMbxAqPuYDw== @@ -1615,16 +1767,16 @@ "@ethersproject/properties" "^5.0.3" "@ethersproject/strings" "^5.0.4" -"@ethersproject/wordlists@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.0.2.tgz#eded47314509c8608373fc2b22879ee2b71b7c7c" - integrity sha512-6vKDQcjjpnfdSCr0+jNxpFH3ieKxUPkm29tQX2US7a3zT/sJU/BGlKBR7D8oOpwdE0hpkHhJyMlypRBK+A2avA== +"@ethersproject/wordlists@5.0.10", "@ethersproject/wordlists@^5.0.8": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.0.10.tgz#177b9a0b4d72b9c4f304d08b36612d6c60e9b896" + integrity sha512-jWsEm1iJzpg9SCXnNfFz+tcp4Ofzv0TJb6mj+soCNcar9GcT0yGz62ZsHC3pLQWaF4LkCzGwRJHJTXKjHQfG1A== dependencies: - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/hash" "^5.0.0" - "@ethersproject/logger" "^5.0.0" - "@ethersproject/properties" "^5.0.0" - "@ethersproject/strings" "^5.0.0" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/hash" "^5.0.10" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/strings" "^5.0.8" "@formatjs/intl-relativetimeformat@^5.2.6": version "5.2.6" @@ -1971,16 +2123,17 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" -"@lavamoat/allow-scripts@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@lavamoat/allow-scripts/-/allow-scripts-1.0.3.tgz#8fa54a3f250977fdc85484d0870ae65c4e50a0c8" - integrity sha512-bzRYwOqjx5UU2vQYIV/QZYQGDA1Nm4lXipTUCK4UNBwGSwYlK8A1SUrQdX+Rp0ASbr/mb8IH6rPIjz1LgsDbDA== +"@lavamoat/allow-scripts@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@lavamoat/allow-scripts/-/allow-scripts-1.0.4.tgz#1804c552c40e522ad5210879181869030737321a" + integrity sha512-720ZQn/PGI1kOvO51I4bTknX3jhztbuytHSHh4i9D4fAqz4NHW14vLR6xbvyk8gh+QtbmsLloeulrA81+if1bw== dependencies: "@npmcli/run-script" "^1.8.1" "@yarnpkg/lockfile" "^1.1.0" + npm-logical-tree "^1.2.1" + resolve "^1.20.0" semver "^7.3.4" yargs "^16.2.0" - yarn-logical-tree "^1.0.2" "@lavamoat/preinstall-always-fail@^1.0.0": version "1.0.0" @@ -2094,10 +2247,10 @@ resolved "https://registry.yarnpkg.com/@metamask/eslint-config/-/eslint-config-5.0.0.tgz#70c1ca854ce9b3b1cabd89cb736e8bb36127d164" integrity sha512-eZt17NofPMmtoNjmBGOhUdAmyL0C+2/smtqAkVhpzZsU2ZGv+4Kekn8p8gcNONOYN8EotpWUxGkN1CTdVLdWZw== -"@metamask/eth-ledger-bridge-keyring@^0.2.6": - version "0.2.6" - resolved "https://registry.yarnpkg.com/@metamask/eth-ledger-bridge-keyring/-/eth-ledger-bridge-keyring-0.2.6.tgz#2721c118a5eeb3685d372d0258f2a3b03dd01315" - integrity sha512-7OtX24lHSCioFZM+x4ZCsndT1wkI7cf8+ua3UntYqHFSRu/SDf6xVNBuD8isvWidNbVdcJKhfJuO3vFCDNsPBw== +"@metamask/eth-ledger-bridge-keyring@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@metamask/eth-ledger-bridge-keyring/-/eth-ledger-bridge-keyring-0.3.0.tgz#4fc2a6345199e18f94c098d8c632d3d55add5c36" + integrity sha512-Iv9fmxPClBohIK6ciy0ZVYNTUodlmrdQt19cZDAicSfFdR2Gcgbq2FDA75o63+fW8TwPEohhDRV/vWQ0MU5esw== dependencies: eth-sig-util "^1.4.2" ethereumjs-tx "^1.3.4" @@ -2118,10 +2271,10 @@ human-standard-token-abi "^1.0.2" safe-event-emitter "^1.0.1" -"@metamask/etherscan-link@^1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-1.4.1.tgz#44377c5c9be2c02ef26aff5da74bd839e50c09f9" - integrity sha512-hs8Qi62+6BZN9J7dknnoJR4DStEP6PzWEwRt+ScEVM4CuBVo08mqY0HXRny52A6FjBQrSnBgA5gvMbBOMqDavg== +"@metamask/etherscan-link@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-1.5.0.tgz#c6940ea934b3a7dcf04e459d9ea3c630b69f6b5f" + integrity sha512-vPCkZJwZ5p933n20Zh+cC3umJv05un2CRZ8y+14KgMq3I4eOwllqmqxoYf9tn3BLGM8QXm/Nie+aBjmoe/T9ag== "@metamask/forwarder@^1.1.0": version "1.1.0" @@ -2916,10 +3069,10 @@ "@babel/runtime" "^7.10.3" "@testing-library/dom" "^7.17.1" -"@trezor/blockchain-link@^1.0.15": - version "1.0.15" - resolved "https://registry.yarnpkg.com/@trezor/blockchain-link/-/blockchain-link-1.0.15.tgz#a3f7c1122d568a1a945f7f0c43de217cdc2d3c7a" - integrity sha512-qcGHa1OXHdQb6SoPW6yfXyomkKwtd/JpFXL4eSGvAl08roxtgmtXNHmQaJ8F0oRSClbPEprqf/qR3BPdK33HoQ== +"@trezor/blockchain-link@^1.0.17": + version "1.0.17" + resolved "https://registry.yarnpkg.com/@trezor/blockchain-link/-/blockchain-link-1.0.17.tgz#3155b44ee9beb71326986d404385ede673519b3c" + integrity sha512-o1ZmZVdhXM8K4OY61A6l/pvmasC6OTGDeDliVlVnNdy3eVDVlnEivQVnMD7CvQr0Crxl1Flox0mp90Ljp/DIkA== dependencies: bignumber.js "^9.0.1" es6-promise "^4.2.8" @@ -2928,7 +3081,7 @@ tiny-worker "^2.3.0" ws "^7.4.0" -"@trezor/rollout@^1.0.4": +"@trezor/rollout@1.0.7": version "1.0.7" resolved "https://registry.yarnpkg.com/@trezor/rollout/-/rollout-1.0.7.tgz#e4ee8281866ab6712ccc8873f3a383621b1a18ca" integrity sha512-yFN2J/g3Epv1dM0dCsRnOagK7lrsfs7vDy1uc4T7DF9qtN0ZGO/tdCjSdgRGUZECRdXRcPrzRUsZDXGOkPcLoA== @@ -2936,10 +3089,10 @@ cross-fetch "^3.0.6" runtypes "^5.0.1" -"@trezor/utxo-lib@0.1.1", "@trezor/utxo-lib@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@trezor/utxo-lib/-/utxo-lib-0.1.1.tgz#63cb4b3accc90352a42a1c866fce8bfbb1c94b26" - integrity sha512-Wonj9ldKCeoajCV6lSE6+hJ2hdPxmVaysWRO9GxhnKyiOdRhiOIQcdKOiXYqpcxwkIbbL9eLGDg73tfn3MUa6w== +"@trezor/utxo-lib@0.1.2", "@trezor/utxo-lib@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@trezor/utxo-lib/-/utxo-lib-0.1.2.tgz#19319a424b0d0c648b0df456f1849eb08697fb44" + integrity sha512-ONAsg8LAyZY9g6X/qgqloUHwWsqtRmrx2Wt3wkz+7LO2VdE69HktAHWUjJLK9drskNwly3Fp0GKK6ZbbtX+Ghw== dependencies: bech32 "0.0.3" bigi "^1.4.0" @@ -2951,6 +3104,7 @@ create-hmac "^1.1.3" debug "~3.1.0" ecurve "^1.0.0" + int64-buffer "0.99.1007" merkle-lib "^2.0.10" pushdata-bitcoin "^1.0.1" randombytes "^2.0.1" @@ -3100,11 +3254,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== -"@types/node@^10.3.2": - version "10.14.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" - integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== - "@types/node@^8.10.11": version "8.10.48" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.48.tgz#e385073561643a9ba6199a1985ffc03530f90781" @@ -5521,21 +5670,15 @@ batch-processor@1.0.0: resolved "https://registry.yarnpkg.com/batch-processor/-/batch-processor-1.0.0.tgz#75c95c32b748e0850d10c2b168f6bdbe9891ace8" integrity sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg= -bchaddrjs@0.4.9: - version "0.4.9" - resolved "https://registry.yarnpkg.com/bchaddrjs/-/bchaddrjs-0.4.9.tgz#c17036bf5bab31bfbb9f3cec432c7c578f0faf46" - integrity sha512-Mf5Uf+P452ltYg1b/NncX/eAEKW+iAfUs8rO1mcgro8S+/WG6gRh8OqgBtyCK1jBHViajovWoAG+ZCkKbhZbNg== +bchaddrjs@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/bchaddrjs/-/bchaddrjs-0.5.2.tgz#1f52b5077329774e7c82d4882964628106bb11a0" + integrity sha512-OO7gIn3m7ea4FVx4cT8gdlWQR2+++EquhdpWQJH9BQjK63tJJ6ngB3QMZDO6DiBoXiIGUsTPHjlrHVxPGcGxLQ== dependencies: - bs58check "^2.1.2" - cashaddrjs "^0.3.12" - -bchaddrjs@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/bchaddrjs/-/bchaddrjs-0.3.2.tgz#62d4915f8f69012b7a16ae9fd0c99eca3a8ccf91" - integrity sha512-jpoq2GX6PphcCpuvvrQG4oQmEzn4nGQSm5dT208W72r9GDdbmNPi0hG9TY/dFF3r9sNtdl0qKwNsh8dNL3Q62g== - dependencies: - bs58check "^2.1.2" - cashaddrjs "^0.3.3" + bs58check "2.1.2" + buffer "^6.0.3" + cashaddrjs "0.4.4" + stream-browserify "^3.0.0" bcrypt-pbkdf@^1.0.0: version "1.0.2" @@ -5549,6 +5692,11 @@ bech32@0.0.3: resolved "https://registry.yarnpkg.com/bech32/-/bech32-0.0.3.tgz#736747c4a6531c5d8937d0400498de30e93b2f9c" integrity sha512-O+K1w8P/aAOLcYwwQ4sbiPYZ51ZIW95lnS4/6nE8Aib/z+OOddQIIPdu2qi94qGDp4HhYy/wJotttXKkak1lXg== +bech32@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + bech32@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.3.tgz#bd47a8986bbb3eec34a56a097a84b8d3e9a2dfcd" @@ -5915,7 +6063,7 @@ brfs@^2.0.2: static-module "^3.0.2" through2 "^2.0.0" -brorand@^1.0.1, brorand@^1.0.5: +brorand@^1.0.1, brorand@^1.0.5, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= @@ -6127,7 +6275,7 @@ bs58@^2.0.1: resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d" integrity sha1-VZCNWPGYKrogCPob7Y+RmYopv40= -bs58check@<3.0.0, bs58check@^2.0.0, bs58check@^2.1.1, bs58check@^2.1.2: +bs58check@2.1.2, bs58check@<3.0.0, bs58check@^2.0.0, bs58check@^2.1.1, bs58check@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== @@ -6232,6 +6380,14 @@ buffer@^5.0.5, buffer@^5.2.1: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + buffer@~5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" @@ -6403,6 +6559,14 @@ caching-transform@^4.0.0: package-hash "^4.0.0" write-file-atomic "^3.0.0" +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + call-me-maybe@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" @@ -6505,10 +6669,10 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -cashaddrjs@^0.3.12, cashaddrjs@^0.3.3: - version "0.3.12" - resolved "https://registry.yarnpkg.com/cashaddrjs/-/cashaddrjs-0.3.12.tgz#73089588113459741e854aa842db1f7816d8428d" - integrity sha512-GdjCYMVwd86HXcFcxyEZQLPLFv8a/u0ccYPsO0PpnUW26LhZzHX9l9QA+DjaeUah7tnebwPs33NWDbbUy8iVYQ== +cashaddrjs@0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cashaddrjs/-/cashaddrjs-0.4.4.tgz#169f1ae620d325db77700273d972282adeeee331" + integrity sha512-xZkuWdNOh0uq/mxJIng6vYWfTowZLd9F4GMAlp2DwFHlcCqCm91NtuAc47RuV4L7r4PYcY5p6Cr2OKNb4hnkWA== dependencies: big-integer "1.6.36" @@ -8686,18 +8850,18 @@ element-resize-detector@^1.2.1: dependencies: batch-processor "1.0.0" -elliptic@6.3.3, elliptic@6.5.3, elliptic@=3.0.3, elliptic@^6.0.0, elliptic@^6.4.0, elliptic@^6.4.1, elliptic@^6.5.2, elliptic@^6.5.3: - version "6.5.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" - integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== +elliptic@6.5.3, elliptic@6.5.4, elliptic@=3.0.3, elliptic@^6.0.0, elliptic@^6.4.0, elliptic@^6.4.1, elliptic@^6.5.2, elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" + bn.js "^4.11.9" + brorand "^1.1.0" hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" emoji-regex@^7.0.1: version "7.0.3" @@ -8986,6 +9150,28 @@ es-abstract@^1.18.0-next.0: string.prototype.trimend "^1.0.1" string.prototype.trimstart "^1.0.1" +es-abstract@^1.18.0-next.2: + version "1.18.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" + integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.2" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.2" + is-string "^1.0.5" + object-inspect "^1.9.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.0" + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -9749,16 +9935,16 @@ eth-simple-keyring@^3.5.0: events "^1.1.1" xtend "^4.0.1" -eth-trezor-keyring@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/eth-trezor-keyring/-/eth-trezor-keyring-0.5.2.tgz#b2bbb52701e382e831d9889bc4dd71faaf8000c3" - integrity sha512-ciTDHBdKJQciNdGnoEdiORRcbHLUX1NvGmesup6EsW5eD023kvw2xVQlfDj8YxuUsA+sX47IDbS/SwWxvN/PiQ== +eth-trezor-keyring@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/eth-trezor-keyring/-/eth-trezor-keyring-0.6.0.tgz#85192ab5d98be28512a58b0bc731e4e6a124ba27" + integrity sha512-10r2uYbrNdYlzgHy2VFEyoGmGw3YIBa21WDT365cTzIQ7C6ozAvfZ9t5YZkTVY2AQP5TVS41UZJdbj0R2DG2Lg== dependencies: eth-sig-util "^1.4.2" ethereumjs-tx "^1.3.4" ethereumjs-util "^5.1.5" hdkey "0.8.0" - trezor-connect "8.1.19-extended" + trezor-connect "8.1.23-extended" eth-tx-summary@^3.1.2: version "3.2.4" @@ -10042,14 +10228,13 @@ ethereumjs-wallet@0.6.5, ethereumjs-wallet@^0.6.0, ethereumjs-wallet@^0.6.4: uuid "^3.3.2" ethers@^4.0.20, ethers@^4.0.28: - version "4.0.33" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.33.tgz#f7b88d2419d731a39aefc37843a3f293e396f918" - integrity sha512-lAHkSPzBe0Vj+JrhmkEHLtUEKEheVktIjGDyE9gbzF4zf1vibjYgB57LraDHu4/ItqWVkztgsm8GWqcDMN+6vQ== + version "4.0.48" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.48.tgz#330c65b8133e112b0613156e57e92d9009d8fbbe" + integrity sha512-sZD5K8H28dOrcidzx9f8KYh8083n5BexIO3+SbE4jK83L85FxtpXZBCQdXb8gkg+7sBqomcLhhkU7UHL+F7I2g== dependencies: - "@types/node" "^10.3.2" aes-js "3.0.0" bn.js "^4.4.0" - elliptic "6.3.3" + elliptic "6.5.3" hash.js "1.1.3" js-sha3 "0.5.7" scrypt-js "2.0.4" @@ -10058,40 +10243,40 @@ ethers@^4.0.20, ethers@^4.0.28: xmlhttprequest "1.8.0" ethers@^5.0.8: - version "5.0.8" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.0.8.tgz#c13d0fdf5e66db8085e2036d3309ed2f8a17ed89" - integrity sha512-of/rPgJ7E3yyBADUv5A7Gtkd7EB8ta/T9NS5CCG9tj9cifnXcI3KIdYQ7d8AS+9vm38pR1g6S5I+Q/mRnlQZlg== + version "5.0.32" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.0.32.tgz#f009970be31d96a589bf0ce597a39c10c7e297a6" + integrity sha512-rORfGWR0HsA4pjKMMcWZorw12DHsXqfIAuPVHJsXt+vI24jvXcVqx+rLsSvgOoLdaCMdxiN5qlIq2+4axKG31g== dependencies: - "@ethersproject/abi" "^5.0.0" - "@ethersproject/abstract-provider" "^5.0.0" - "@ethersproject/abstract-signer" "^5.0.0" - "@ethersproject/address" "^5.0.0" - "@ethersproject/base64" "^5.0.0" - "@ethersproject/basex" "^5.0.0" - "@ethersproject/bignumber" "^5.0.0" - "@ethersproject/bytes" "^5.0.0" - "@ethersproject/constants" "^5.0.0" - "@ethersproject/contracts" "^5.0.0" - "@ethersproject/hash" "^5.0.0" - "@ethersproject/hdnode" "^5.0.0" - "@ethersproject/json-wallets" "^5.0.0" - "@ethersproject/keccak256" "^5.0.0" - "@ethersproject/logger" "^5.0.0" - "@ethersproject/networks" "^5.0.0" - "@ethersproject/pbkdf2" "^5.0.0" - "@ethersproject/properties" "^5.0.0" - "@ethersproject/providers" "^5.0.0" - "@ethersproject/random" "^5.0.0" - "@ethersproject/rlp" "^5.0.0" - "@ethersproject/sha2" "^5.0.0" - "@ethersproject/signing-key" "^5.0.0" - "@ethersproject/solidity" "^5.0.0" - "@ethersproject/strings" "^5.0.0" - "@ethersproject/transactions" "^5.0.0" - "@ethersproject/units" "^5.0.0" - "@ethersproject/wallet" "^5.0.0" - "@ethersproject/web" "^5.0.0" - "@ethersproject/wordlists" "^5.0.0" + "@ethersproject/abi" "5.0.13" + "@ethersproject/abstract-provider" "5.0.10" + "@ethersproject/abstract-signer" "5.0.14" + "@ethersproject/address" "5.0.11" + "@ethersproject/base64" "5.0.9" + "@ethersproject/basex" "5.0.9" + "@ethersproject/bignumber" "5.0.15" + "@ethersproject/bytes" "5.0.11" + "@ethersproject/constants" "5.0.10" + "@ethersproject/contracts" "5.0.12" + "@ethersproject/hash" "5.0.12" + "@ethersproject/hdnode" "5.0.10" + "@ethersproject/json-wallets" "5.0.12" + "@ethersproject/keccak256" "5.0.9" + "@ethersproject/logger" "5.0.10" + "@ethersproject/networks" "5.0.9" + "@ethersproject/pbkdf2" "5.0.9" + "@ethersproject/properties" "5.0.9" + "@ethersproject/providers" "5.0.24" + "@ethersproject/random" "5.0.9" + "@ethersproject/rlp" "5.0.9" + "@ethersproject/sha2" "5.0.9" + "@ethersproject/signing-key" "5.0.11" + "@ethersproject/solidity" "5.0.10" + "@ethersproject/strings" "5.0.10" + "@ethersproject/transactions" "5.0.11" + "@ethersproject/units" "5.0.11" + "@ethersproject/wallet" "5.0.12" + "@ethersproject/web" "5.0.14" + "@ethersproject/wordlists" "5.0.10" ethjs-abi@0.2.0: version "0.2.0" @@ -11518,6 +11703,15 @@ get-folder-size@^2.0.0: gar "^1.0.4" tiny-each-async "2.0.3" +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + get-iterator@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/get-iterator/-/get-iterator-1.0.2.tgz#cd747c02b4c084461fac14f48f6b45a80ed25c82" @@ -12288,6 +12482,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-bigints@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + has-binary2@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" @@ -12337,6 +12536,11 @@ has-symbols@^1.0.0, has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + 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" @@ -12445,13 +12649,13 @@ hastscript@^6.0.0: property-information "^5.0.0" space-separated-tokens "^1.0.0" -hd-wallet@9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/hd-wallet/-/hd-wallet-9.1.0.tgz#0cfdae4e0d7147438c7802fedce29b7d049c0f5f" - integrity sha512-Oto94Q1e9C9wPsrxErky8TFoOqERiL6EZEo3jZ3BSPu36hpz1KfsB3MqPorvoOWQt6AjC5FoIy/lIPLx3aDMew== +hd-wallet@9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/hd-wallet/-/hd-wallet-9.1.1.tgz#4a6e49ff09e8cb4bbe0127133cfaf80e24142096" + integrity sha512-Z1UhEcFv6aGrPL2fDDkEzO3MwPuiAKbLAs8MSNQ1BxeW9c2HxXjTWMEfx8xhQ0gv10Blf1bmXLm+itOe1+nh6Q== dependencies: - "@trezor/utxo-lib" "0.1.1" - bchaddrjs "^0.3.2" + "@trezor/utxo-lib" "0.1.2" + bchaddrjs "^0.5.2" bignumber.js "^9.0.1" queue "^6.0.1" socket.io-client "^2.2.0" @@ -12497,7 +12701,7 @@ history@^4.9.0: tiny-warning "^1.0.0" value-equal "^1.0.1" -hmac-drbg@^1.0.0: +hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= @@ -12795,7 +12999,7 @@ idna-uts46@^1.0.1: dependencies: punycode "^2.1.0" -ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.1.8: +ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.1.8, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -13043,6 +13247,11 @@ insert-module-globals@^7.0.0: undeclared-identifiers "^1.1.2" xtend "^4.0.0" +int64-buffer@0.99.1007: + version "0.99.1007" + resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-0.99.1007.tgz#211ea089a2fdb960070a2e77cd6d17dc456a5220" + integrity sha512-XDBEu44oSTqlvCSiOZ/0FoUkpWu/vwjJLGSKDabNISPQNZ5wub1FodGHBljRsrR0IXRPq7SslshZYMuA55CgTQ== + interface-connection@~0.3.2, interface-connection@~0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/interface-connection/-/interface-connection-0.3.3.tgz#d82dd81efee5f2d40d7cb0fd75e6e858f92fa199" @@ -13709,6 +13918,11 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= +is-bigint@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" + integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -13728,6 +13942,13 @@ is-boolean-object@^1.0.0: resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93" integrity sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M= +is-boolean-object@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" + integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== + dependencies: + call-bind "^1.0.0" + is-buffer@^1.0.2, is-buffer@^1.1.0, is-buffer@^1.1.5, is-buffer@~1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -13743,6 +13964,11 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.2: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== +is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== + is-ci@^1.0.10: version "1.2.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" @@ -13776,6 +14002,13 @@ is-core-module@^2.1.0: dependencies: has "^1.0.3" +is-core-module@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -14018,6 +14251,11 @@ is-negative-zero@^2.0.0: resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" @@ -14033,6 +14271,11 @@ is-number-object@^1.0.3: resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799" integrity sha1-8mWrian0RQNO9q/xWo8AsA9VF5k= +is-number-object@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" + integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== + is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -14171,6 +14414,14 @@ is-regex@^1.0.4, is-regex@^1.1.1: dependencies: has-symbols "^1.0.1" +is-regex@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" + integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== + dependencies: + call-bind "^1.0.2" + has-symbols "^1.0.1" + is-regexp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-2.1.0.tgz#cd734a56864e23b956bf4e7c66c396a4c0b22c2d" @@ -14344,7 +14595,7 @@ iso-stream-http@~0.1.2: inherits "^2.0.1" readable-stream "^3.1.1" -iso-url@^0.4.4, iso-url@~0.4.4, iso-url@~0.4.6: +iso-url@~0.4.4, iso-url@~0.4.6: version "0.4.6" resolved "https://registry.yarnpkg.com/iso-url/-/iso-url-0.4.6.tgz#45005c4af4984cad4f8753da411b41b74cf0a8a6" integrity sha512-YQO7+aIe6l1aSJUKOx+Vrv08DlhZeLFIVfehG2L29KLSEb9RszqPXilxJRVpp57px36BddKR5ZsebacO5qG0tg== @@ -16912,7 +17163,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: +minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= @@ -18006,6 +18257,11 @@ object-inspect@^1.6.0, object-inspect@^1.7.0, object-inspect@^1.8.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== +object-inspect@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" + integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== + object-inspect@~1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" @@ -18053,6 +18309,16 @@ object.assign@^4.0.4, object.assign@^4.1.0, object.assign@^4.1.1: has-symbols "^1.0.1" object-keys "^1.1.1" +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + object.defaults@^1.0.0, object.defaults@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" @@ -18131,6 +18397,16 @@ object.values@^1.0.4, object.values@^1.1.0, object.values@^1.1.1: function-bind "^1.1.1" has "^1.0.3" +object.values@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" + integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + has "^1.0.3" + objectorarray@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.4.tgz#d69b2f0ff7dc2701903d308bb85882f4ddb49483" @@ -20087,11 +20363,11 @@ pull-window@^2.1.4: dependencies: looper "^2.0.0" -pull-ws@hugomrdias/pull-ws#fix/bundle-size: - version "3.3.1" - resolved "https://codeload.github.com/hugomrdias/pull-ws/tar.gz/8e2ce0bb3b1cd6804828316e937fff8e0bef6225" +pull-ws@^3.3.2, pull-ws@hugomrdias/pull-ws#fix/bundle-size: + version "3.3.2" + resolved "https://registry.yarnpkg.com/pull-ws/-/pull-ws-3.3.2.tgz#abac497a4800e74ab9a6d749c81a44d12d4e77b3" + integrity sha512-Bn4bcJsSzJGOQl4RBulDhG1FkcbDHSCXteI8Jg5k4X6X5TxVzZzKilWJ1WV2v4OnRXl2eYbtHFGsPl8Cr1xJzw== dependencies: - iso-url "^0.4.4" relative-url "^1.0.2" safe-buffer "^5.1.1" ws "^1.1.0" @@ -20865,7 +21141,7 @@ readable-stream@1.1.x, readable-stream@^1.0.33: isarray "0.0.1" string_decoder "~0.10.x" -"readable-stream@2 || 3", readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.0.2, readable-stream@^3.0.5, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: +"readable-stream@2 || 3", readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.0.2, readable-stream@^3.0.5, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -21531,6 +21807,14 @@ resolve@^1.15.1: is-core-module "^2.1.0" path-parse "^1.0.6" +resolve@^1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + resolve@~1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" @@ -22991,6 +23275,14 @@ stream-browserify@^2.0.0, stream-browserify@^2.0.1: inherits "~2.0.1" readable-stream "^2.0.2" +stream-browserify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + stream-combiner2@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" @@ -23186,6 +23478,14 @@ string.prototype.trimend@^1.0.1: define-properties "^1.1.3" es-abstract "^1.17.5" +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + string.prototype.trimstart@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" @@ -23194,6 +23494,14 @@ string.prototype.trimstart@^1.0.1: define-properties "^1.1.3" es-abstract "^1.17.5" +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + string_decoder@0.10, string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" @@ -24069,37 +24377,37 @@ tree-kill@^1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -trezor-connect@8.1.19-extended: - version "8.1.19-extended" - resolved "https://registry.yarnpkg.com/trezor-connect/-/trezor-connect-8.1.19-extended.tgz#2b5f7f232f2064121f9b3adc05cbf2bc2f7c08cc" - integrity sha512-elm4fgPB79q5e+q8/i7pW2ms3mwkSQjYrgUD2nV40yP4cP8Cp7DYtu0bh4ZYhMNN0+BFwIYw86fvPSCo6D7OQA== +trezor-connect@8.1.23-extended: + version "8.1.23-extended" + resolved "https://registry.yarnpkg.com/trezor-connect/-/trezor-connect-8.1.23-extended.tgz#353369a9f136216630b9673a239dcdb140abe49e" + integrity sha512-Otlim+/tPiywWcuK7uIVP9UDUPvIhkvdBOPHzV6UKVylbqecTKb1LcUNq3tSfHq78CIsWvTa6g5AQrHq1wSPAw== dependencies: "@babel/runtime" "^7.12.5" - "@trezor/blockchain-link" "^1.0.15" - "@trezor/rollout" "^1.0.4" - "@trezor/utxo-lib" "^0.1.1" - bchaddrjs "0.4.9" + "@trezor/blockchain-link" "^1.0.17" + "@trezor/rollout" "1.0.7" + "@trezor/utxo-lib" "^0.1.2" + bchaddrjs "^0.5.2" bignumber.js "^9.0.1" bowser "^2.11.0" events "^3.2.0" - hd-wallet "9.1.0" + hd-wallet "9.1.1" keccak "^3.0.1" node-fetch "^2.6.1" parse-uri "^1.0.3" tiny-worker "^2.3.0" - trezor-link "1.7.1" + trezor-link "1.7.3" whatwg-fetch "^3.5.0" -trezor-link@1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/trezor-link/-/trezor-link-1.7.1.tgz#8ad08f59ae4c9d49c44d1ed8be0bdb6a3e4bbe5b" - integrity sha512-2oEEUJgs4RmwifFaE+B14z4zUBVoekkXyT7S6U6667Fnqg40tpGC+gqbqwaeU/2ARsAXvbD5YBhPdTLsL9Up9w== +trezor-link@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/trezor-link/-/trezor-link-1.7.3.tgz#33c4b558913a3da395243018c04ee1804affcdc3" + integrity sha512-KaVYcK96BLD+cBuYmJmsxr6G9Z0ZeO6VYPhcYQyFxJ7jvc6/UvTmdACZdHjlUD7U5VuJEGMI4G8L3IGxFTFv4Q== dependencies: bigi "^1.4.1" ecurve "^1.0.3" json-stable-stringify "^1.0.1" node-fetch "^2.6.1" - object.values "^1.1.1" + object.values "^1.1.2" protobufjs-old-fixed-webpack "3.8.5" semver-compare "^1.0.0" whatwg-fetch "^3.5.0" @@ -24368,6 +24676,16 @@ umd@^3.0.0: resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.3.tgz#aa9fe653c42b9097678489c01000acb69f0b26cf" integrity sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow== +unbox-primitive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.0.tgz#eeacbc4affa28e9b3d36b5eaeccc50b3251b1d3f" + integrity sha512-P/51NX+JXyxK/aigg1/ZgyccdAxm5K1+n8+tvqSntjOivPt19gvm1VC49RWYetsiub8WViUchdxl/KWHHB0kzA== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.0" + has-symbols "^1.0.0" + which-boxed-primitive "^1.0.1" + unc-path-regex@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" @@ -25584,6 +25902,17 @@ whatwg-url@^6.3.0: tr46 "^1.0.0" webidl-conversions "^4.0.1" +which-boxed-primitive@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" @@ -26059,14 +26388,6 @@ yargs@^7.1.0: y18n "^3.2.1" yargs-parser "5.0.0-security.0" -yarn-logical-tree@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/yarn-logical-tree/-/yarn-logical-tree-1.0.2.tgz#11130e00333b02174efcfd5599a5e68ca356fa14" - integrity sha512-ra0Bl8oB7sN4fkWSSC2+P3luaFiwFFJ/KcCLSjY6HHRvKcBMjOcIIF1z6IHU+plmEYyZOc546cWwi0f0QiOQtw== - dependencies: - npm-logical-tree "^1.2.1" - semver "^5.5.0" - yauzl@2.10.0, yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"