Merge pull request #13498 from MetaMask/Version-v10.10.0

Version v10.10.0 RC
feature/default_network_editable
ryanml 3 years ago committed by GitHub
commit 09c880d165
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      .github/ISSUE_TEMPLATE/bug-report.md
  2. 97
      .github/ISSUE_TEMPLATE/bug-report.yml
  3. 2
      .github/workflows/crowdin_action.yml
  4. 1
      .metamaskrc.dist
  5. 2
      .storybook/test-data.js
  6. 38
      CHANGELOG.md
  7. 2
      LICENSE
  8. 12
      app/_locales/am/messages.json
  9. 32
      app/_locales/ar/messages.json
  10. 24
      app/_locales/bg/messages.json
  11. 24
      app/_locales/bn/messages.json
  12. 24
      app/_locales/ca/messages.json
  13. 18
      app/_locales/cs/messages.json
  14. 24
      app/_locales/da/messages.json
  15. 65
      app/_locales/de/messages.json
  16. 2324
      app/_locales/el/messages.json
  17. 111
      app/_locales/en/messages.json
  18. 43
      app/_locales/es/messages.json
  19. 57
      app/_locales/es_419/messages.json
  20. 24
      app/_locales/et/messages.json
  21. 24
      app/_locales/fa/messages.json
  22. 24
      app/_locales/fi/messages.json
  23. 21
      app/_locales/fil/messages.json
  24. 2344
      app/_locales/fr/messages.json
  25. 6
      app/_locales/gu/messages.json
  26. 24
      app/_locales/he/messages.json
  27. 1115
      app/_locales/hi/messages.json
  28. 12
      app/_locales/hn/messages.json
  29. 24
      app/_locales/hr/messages.json
  30. 21
      app/_locales/ht/messages.json
  31. 24
      app/_locales/hu/messages.json
  32. 1121
      app/_locales/id/messages.json
  33. 74
      app/_locales/it/messages.json
  34. 1115
      app/_locales/ja/messages.json
  35. 24
      app/_locales/kn/messages.json
  36. 1115
      app/_locales/ko/messages.json
  37. 26
      app/_locales/lt/messages.json
  38. 24
      app/_locales/lv/messages.json
  39. 6
      app/_locales/ml/messages.json
  40. 6
      app/_locales/mr/messages.json
  41. 21
      app/_locales/ms/messages.json
  42. 15
      app/_locales/nl/messages.json
  43. 24
      app/_locales/no/messages.json
  44. 12
      app/_locales/ph/messages.json
  45. 24
      app/_locales/pl/messages.json
  46. 12
      app/_locales/pt/messages.json
  47. 64
      app/_locales/pt_BR/messages.json
  48. 24
      app/_locales/ro/messages.json
  49. 1115
      app/_locales/ru/messages.json
  50. 24
      app/_locales/sk/messages.json
  51. 24
      app/_locales/sl/messages.json
  52. 24
      app/_locales/sr/messages.json
  53. 24
      app/_locales/sv/messages.json
  54. 24
      app/_locales/sw/messages.json
  55. 21
      app/_locales/ta/messages.json
  56. 6
      app/_locales/te/messages.json
  57. 18
      app/_locales/th/messages.json
  58. 1593
      app/_locales/tl/messages.json
  59. 3353
      app/_locales/tr/messages.json
  60. 24
      app/_locales/uk/messages.json
  61. 1115
      app/_locales/vi/messages.json
  62. 1522
      app/_locales/zh_CN/messages.json
  63. 12
      app/_locales/zh_TW/messages.json
  64. 2
      app/images/curve-high.svg
  65. 2
      app/images/curve-low.svg
  66. 2
      app/images/curve-medium.svg
  67. 116
      app/images/videos/recovery-onboarding/subtitles/de.vtt
  68. 4
      app/phishing.html
  69. 5
      app/scripts/background.js
  70. 24
      app/scripts/controllers/app-state.js
  71. 179
      app/scripts/controllers/metametrics.js
  72. 43
      app/scripts/controllers/metametrics.test.js
  73. 21
      app/scripts/controllers/preferences.js
  74. 360
      app/scripts/controllers/transactions/index.js
  75. 466
      app/scripts/controllers/transactions/index.test.js
  76. 2
      app/scripts/controllers/transactions/tx-state-manager.js
  77. 75
      app/scripts/lib/buy-eth-url.test.js
  78. 19
      app/scripts/lib/buy-url.js
  79. 117
      app/scripts/lib/buy-url.test.js
  80. 148
      app/scripts/metamask-controller.js
  81. 18
      app/scripts/metamask-controller.test.js
  82. 2
      development/build/scripts.js
  83. 12
      development/build/transforms/remove-fenced-code.js
  84. 11
      development/build/transforms/remove-fenced-code.test.js
  85. 4
      development/run-ganache.sh
  86. 8
      lavamoat/browserify/beta/policy.json
  87. 8
      lavamoat/browserify/flask/policy.json
  88. 8
      lavamoat/browserify/main/policy.json
  89. 80
      package.json
  90. 7
      shared/constants/hardware-wallets.js
  91. 40
      shared/constants/metametrics.js
  92. 58
      shared/constants/network.js
  93. 50
      shared/constants/transaction.js
  94. 145
      test/e2e/fixtures/eip-1559-v2-dapp/state.json
  95. 214
      test/e2e/fixtures/eip-1559-v2/state.json
  96. 40
      test/e2e/fixtures/navigate-transactions/state.json
  97. 214
      test/e2e/fixtures/send-edit-v2/state.json
  98. 13
      test/e2e/fixtures/send-edit/state.json
  99. 16
      test/e2e/ganache.js
  100. 52
      test/e2e/helpers.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,37 +0,0 @@
---
name: Bug Report
about: Using MetaMask, but it's not working as you expect?
---
<!--
BEFORE SUBMITTING:
1) Please search to make sure this issue has not been opened already
2) If this is an implementation question or trouble with your personal project, please post on StackExchange. This will get your question answered more quickly and make it easier for other devs to find the answer in the future.
-->
**Describe the bug**
A clear and concise description of what the bug is.
**Steps to reproduce (REQUIRED)**
Steps to reproduce the behavior, libraries used with version number, and/or any setup information to easily reproduce:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Browser details (please complete the following information):**
- OS: [e.g. OS X, Windows]
- Hardware Wallet: [e.g. Trezor Firmware version 1.8.3, Ledger Nano S Firmware version 1.6.0]
- Browser: [e.g. Chrome Version 79.0.3945.79 (Official Build) (64-bit), Firefox Browser 71.0 (64-bit)]
- MetaMask Version: [e.g. 5.0.2 - find it in Settings > About]
**Additional context (Error Messages, etc.)**
Add any other context about the problem here.

@ -0,0 +1,97 @@
name: Bug Report
description: Using MetaMask, but it's not working as you expect?
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
## **Before Submitting:**
* Please search to make sure this issue has not been opened already.
* If this is a question about how to integrate MetaMask with your project, please ask in our [Community forum](https://community.metamask.io/c/developer-questions/) instead. This will get your question answered more quickly and make it easier for other devs to find the answer in the future.
- type: textarea
id: what-happened
attributes:
label: Describe the bug
description: What happened? What did you expect to happen? Please include screenshots if applicable!
placeholder: Tell us what you see!
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: List all steps needed to reproduce the problem
value: |
1.
validations:
required: true
- type: textarea
id: error
attributes:
label: Error messages or log output
description: Please copy and paste any relevant error messages or log output. This will be automatically formatted, so there is no need for backticks.
render: shell
- type: input
id: version
attributes:
label: Version
description: What version of MetaMask are you running? You can find the version in "Settings" > "About"
validations:
required: true
- type: dropdown
id: build
attributes:
label: Build type
description: Are you using a testing or development build of MetaMask? If so, please select the type of build you are using.
options:
- Beta
- Flask
- Other (please specify exactly where you obtained this build in "Additional Context" section)
- type: dropdown
id: browsers
attributes:
label: Browser
description: Which browsers have you seen the problem on?
multiple: true
options:
- Chrome
- Firefox
- Microsoft Edge
- Brave
- Other (please elaborate in the "Additional Context" section)
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating system
description: Which operating systems have you seen the problem on?
multiple: true
options:
- Windows
- MacOS
- Linux
- Other (please elaborate in the "Additional Context" section)
validations:
required: true
- type: dropdown
id: hardware-wallet
attributes:
label: Hardware wallet
description: Are you using any of these hardware wallets? Please include the firmware version in the "Additional context" section below for any that you select here.
multiple: true
options:
- Ledger
- Trezor
- Keystone
- GridPlus Lattice1
- Other (please elaborate in the "Additional Context" section)
- type: textarea
id: additional
attributes:
label: Additional context
description: Add any other context about the problem here, e.g. related issues, additional error messages or logs, or any potentially relevant details about the environment or situation the bug occurred in.

@ -26,6 +26,6 @@ jobs:
upload_translations: true upload_translations: true
download_translations: true download_translations: true
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.METAMASKBOT_CROWDIN_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}

@ -3,6 +3,5 @@ PASSWORD=METAMASK PASSWORD
INFURA_PROJECT_ID=00000000000 INFURA_PROJECT_ID=00000000000
SEGMENT_WRITE_KEY= SEGMENT_WRITE_KEY=
ONBOARDING_V2= ONBOARDING_V2=
EIP_1559_V2=
SWAPS_USE_DEV_APIS= SWAPS_USE_DEV_APIS=
COLLECTIBLES_V1= COLLECTIBLES_V1=

@ -907,7 +907,7 @@ const state = {
'0xaD6D458402F60fD3Bd25163575031ACDce07538D': './sai.svg', '0xaD6D458402F60fD3Bd25163575031ACDce07538D': './sai.svg',
}, },
hiddenTokens: [], hiddenTokens: [],
suggestedAssets: {}, suggestedAssets: [],
useNonceField: false, useNonceField: false,
usePhishDetect: true, usePhishDetect: true,
lostIdentities: {}, lostIdentities: {},

@ -6,6 +6,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [10.10.0]
### Added
- Enable toggle to turn on the new gas fee customization UI ([#13481](https://github.com/MetaMask/metamask-extension/pull/13481))
- Select between new 'Low', 'Market', and 'Aggressive' gas options
- Improved advanced gas fee editing
- Adds the ability to save custom gas values as defaults
- More informative tooltips about suggested gas options
- More information about the status of the network
- Enable buying MATIC on Polygon, BNB on BSC, AVAX on Avalanche, FTM on Fantom, CELO on Celo, and respective stablecoins on Transak ([#13398](https://github.com/MetaMask/metamask-extension/pull/13398))
- Add German subtitles for SRP Video ([#13368](https://github.com/MetaMask/metamask-extension/pull/13368))
- Adding Brazilian Portuguese translation for some copy in Settings ([#13470](https://github.com/MetaMask/metamask-extension/pull/13470))
### Changed
- Hide 0 balance tokens in send screen dropdown if the "Hide Tokens Without Balance" toggle is on ([#13306](https://github.com/MetaMask/metamask-extension/pull/13306))
- Change the 'Connected Sites' removal icon to a button ([#13476](https://github.com/MetaMask/metamask-extension/pull/13476))
- Add specific hardware wallet names next to HW accounts in the account dropdown ([#13339](https://github.com/MetaMask/metamask-extension/pull/13339))
- Update title of phishing.html ([#13323](https://github.com/MetaMask/metamask-extension/pull/13323))
- Update language while importing an SRP to limit encouragement of copy-pasting seed phrases ([#12012](https://github.com/MetaMask/metamask-extension/pull/12012))
- Maintain leading whitespace in for data to be signed in the signature request popup ([#13340](https://github.com/MetaMask/metamask-extension/pull/13340))
- Update global link hover color from orange to blue ([#13344](https://github.com/MetaMask/metamask-extension/pull/13344))
- Adjust ordering of tokens in the Swaps token dropdown ([#13270](https://github.com/MetaMask/metamask-extension/pull/13270))
### Fixed
- Ensure a correct update of the gas limit upon editing of a transaction recipient ([#12784](https://github.com/MetaMask/metamask-extension/pull/12784))
- Ensure that the toggled display of currency in the send flow persists when editing a transaction ([#12813](https://github.com/MetaMask/metamask-extension/pull/12813))
- Ensure settings can be opened if browser zoom level > 100% ([#13460](https://github.com/MetaMask/metamask-extension/pull/13460))
- Ensure displayed balances of tokens are not incorrectly rounded down ([#13337](https://github.com/MetaMask/metamask-extension/pull/13337))
- Improve visual spacing on the wallet selection flow of onboarding ([#12799](https://github.com/MetaMask/metamask-extension/pull/12799))
## [10.9.3] ## [10.9.3]
### Fixed ### Fixed
- Allow for scrolling when sign type data message is too long ([#13642](https://github.com/MetaMask/metamask-extension/pull/13642)) - Allow for scrolling when sign type data message is too long ([#13642](https://github.com/MetaMask/metamask-extension/pull/13642))
@ -429,7 +458,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#11093](https://github.com/MetaMask/metamask-extension/pull/11093): Update all uses of "Seed Phrase" to "Secret Recovery Phrase" - [#11093](https://github.com/MetaMask/metamask-extension/pull/11093): Update all uses of "Seed Phrase" to "Secret Recovery Phrase"
### Fixed ### Fixed
- [#11025](https://github.com/MetaMask/metamask-extension/pull/11025): Fixed redirection to the build quotes page from the swaps page when failure has occured - [#11025](https://github.com/MetaMask/metamask-extension/pull/11025): Fixed redirection to the build quotes page from the swaps page when failure has occurred
- [#11015](https://github.com/MetaMask/metamask-extension/pull/11015): Prevent an undefined gas price from breaking the transaction list - [#11015](https://github.com/MetaMask/metamask-extension/pull/11015): Prevent an undefined gas price from breaking the transaction list
- [#11013](https://github.com/MetaMask/metamask-extension/pull/11013): Prevent signature request component from canceling hardware wallet signing - [#11013](https://github.com/MetaMask/metamask-extension/pull/11013): Prevent signature request component from canceling hardware wallet signing
- [#10982](https://github.com/MetaMask/metamask-extension/pull/10982): Re-validating chain id when rpc url changes [custom network form] - [#10982](https://github.com/MetaMask/metamask-extension/pull/10982): Re-validating chain id when rpc url changes [custom network form]
@ -483,7 +512,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [9.5.1] ## [9.5.1]
### Fixed ### Fixed
- Fixed icon on approval screen ([#11048](https://github.com/MetaMask/metamask-extension/pull/11048)) - Fixed icon on approval screen ([#11048](https://github.com/MetaMask/metamask-extension/pull/11048))
- Fixed broken app state for some users with Chinese, Portugese or Spanish browser language settings. ([#11036](https://github.com/MetaMask/metamask-extension/pull/11036)) - Fixed broken app state for some users with Chinese, Portuguese or Spanish browser language settings. ([#11036](https://github.com/MetaMask/metamask-extension/pull/11036))
## [9.5.0] - 2021-04-28 ## [9.5.0] - 2021-04-28
### Added ### Added
@ -572,7 +601,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Update Japanese translations. ([#10265](https://github.com/MetaMask/metamask-extension/pull/10265)) - Update Japanese translations. ([#10265](https://github.com/MetaMask/metamask-extension/pull/10265))
- Update Chinese(Simplified) translations. ([#9388](https://github.com/MetaMask/metamask-extension/pull/9388)) - Update Chinese(Simplified) translations. ([#9388](https://github.com/MetaMask/metamask-extension/pull/9388))
- Update Vietnamese translations. ([#10270](https://github.com/MetaMask/metamask-extension/pull/10270)) - Update Vietnamese translations. ([#10270](https://github.com/MetaMask/metamask-extension/pull/10270))
- Update Spanish and Spanish(Latin American and Carribean) translations. ([#10258](https://github.com/MetaMask/metamask-extension/pull/10258)) - Update Spanish and Spanish(Latin American and Caribbean) translations. ([#10258](https://github.com/MetaMask/metamask-extension/pull/10258))
- Update Russian translations. ([#10268](https://github.com/MetaMask/metamask-extension/pull/10268)) - Update Russian translations. ([#10268](https://github.com/MetaMask/metamask-extension/pull/10268))
- Update Tagalog localized messages. ([#10269](https://github.com/MetaMask/metamask-extension/pull/10269)) - Update Tagalog localized messages. ([#10269](https://github.com/MetaMask/metamask-extension/pull/10269))
- Fix 'imported' translation use case for Dutch. ([#10448](https://github.com/MetaMask/metamask-extension/pull/10448)) - Fix 'imported' translation use case for Dutch. ([#10448](https://github.com/MetaMask/metamask-extension/pull/10448))
@ -2702,7 +2731,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Uncategorized ### Uncategorized
- Added the ability to restore accounts from seed words. - Added the ability to restore accounts from seed words.
[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.9.3...HEAD [Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.10.0...HEAD
[10.10.0]: https://github.com/MetaMask/metamask-extension/compare/v10.9.3...v10.10.0
[10.9.3]: https://github.com/MetaMask/metamask-extension/compare/v10.9.2...v10.9.3 [10.9.3]: https://github.com/MetaMask/metamask-extension/compare/v10.9.2...v10.9.3
[10.9.2]: https://github.com/MetaMask/metamask-extension/compare/v10.9.1...v10.9.2 [10.9.2]: https://github.com/MetaMask/metamask-extension/compare/v10.9.1...v10.9.2
[10.9.1]: https://github.com/MetaMask/metamask-extension/compare/v10.9.0...v10.9.1 [10.9.1]: https://github.com/MetaMask/metamask-extension/compare/v10.9.0...v10.9.1

@ -1,4 +1,4 @@
Copyright ConsenSys Software Inc. 2020. All rights reserved. Copyright ConsenSys Software Inc. 2022. All rights reserved.
You acknowledge and agree that ConsenSys Software Inc. (“ConsenSys”) (or ConsenSys’s licensors) own all legal right, title and interest in and to the work, software, application, source code, documentation and any other documents in this repository (collectively, the “Program”), including any intellectual property rights which subsist in the Program (whether those rights happen to be registered or not, and wherever in the world those rights may exist), whether in source code or any other form. You acknowledge and agree that ConsenSys Software Inc. (“ConsenSys”) (or ConsenSys’s licensors) own all legal right, title and interest in and to the work, software, application, source code, documentation and any other documents in this repository (collectively, the “Program”), including any intellectual property rights which subsist in the Program (whether those rights happen to be registered or not, and wherever in the world those rights may exist), whether in source code or any other form.

@ -283,18 +283,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "ይህን አውታረ መረብ ለመሰረዝ እንደሚፈልጉ እርግጠኛ ነዎት?" "message": "ይህን አውታረ መረብ ለመሰረዝ እንደሚፈልጉ እርግጠኛ ነዎት?"
}, },
"depositEther": {
"message": "Ether አስቀምጥ"
},
"details": { "details": {
"message": "ዝርዝሮች" "message": "ዝርዝሮች"
}, },
"directDepositEther": {
"message": "Ether በቀጥታ ያስቀምጡ"
},
"directDepositEtherExplainer": {
"message": "ቀደም ሲል የተወሰነ Ether ካለዎት፣ በአዲሱ ቋትዎ Ether ለማግኘት ፈጣኑ መንገድ ቀጥተኛ ተቀማጭ ነው።"
},
"done": { "done": {
"message": "ተጠናቅቋል" "message": "ተጠናቅቋል"
}, },
@ -581,9 +572,6 @@
"myAccounts": { "myAccounts": {
"message": "የእኔ መለያዎች" "message": "የእኔ መለያዎች"
}, },
"needEtherInWallet": {
"message": "MetaMask በመጠቀም ያልተማከሉ መተግበሪያዎች ጋር ግንኙነት ለማድረግ፣ በቋትዎ ውስጥ Ether ያስፈልግዎታል።"
},
"needImportFile": { "needImportFile": {
"message": "የሚያስመጡትን ፋይል መምረጥ አለብዎት።", "message": "የሚያስመጡትን ፋይል መምረጥ አለብዎት።",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "رفض"
},
"QRHardwareWalletImporterTitle": {
"message": "مسح كود الاستجابة السريعة QR"
},
"about": { "about": {
"message": "حول" "message": "حول"
}, },
@ -8,6 +14,14 @@
"acceleratingATransaction": { "acceleratingATransaction": {
"message": "* تسريع المعاملات باستخدام سعر عملة جاس أعلى يزيد من فرص معالجتها بواسطة الشبكة بشكلٍ أسرع، لكن ذلك غير مضمون دائماً." "message": "* تسريع المعاملات باستخدام سعر عملة جاس أعلى يزيد من فرص معالجتها بواسطة الشبكة بشكلٍ أسرع، لكن ذلك غير مضمون دائماً."
}, },
"acceptTermsOfUse": {
"message": "لقد قرأت دولار واحد وأوافق عليه",
"description": "$1 is the `terms` message"
},
"accessAndSpendNotice": {
"message": "$1 يمكن الوصول إلى هذا المبلغ الأقصى وإنفاقه حتى",
"description": "$1 is the url of the site requesting ability to spend"
},
"accessingYourCamera": { "accessingYourCamera": {
"message": "جاري استخدام كاميرتك..." "message": "جاري استخدام كاميرتك..."
}, },
@ -256,6 +270,9 @@
"currentLanguage": { "currentLanguage": {
"message": "اللغة الحالية" "message": "اللغة الحالية"
}, },
"custom": {
"message": "إعدادات متقدمة"
},
"customGas": { "customGas": {
"message": "تخصيص الغاز" "message": "تخصيص الغاز"
}, },
@ -283,18 +300,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "هل أنت متأكد أنك تريد حذف هذه الشبكة؟" "message": "هل أنت متأكد أنك تريد حذف هذه الشبكة؟"
}, },
"depositEther": {
"message": "إيداع عملة إيثير"
},
"details": { "details": {
"message": "التفاصيل" "message": "التفاصيل"
}, },
"directDepositEther": {
"message": "إيداع مباشرة لعملة الأثير"
},
"directDepositEtherExplainer": {
"message": "إذا كان لديك بالفعل بعض الأثير، فإن أسرع طريقة للحصول على الأثير في محفظتك الجديدة عن طريق الإيداع المباشر."
},
"done": { "done": {
"message": "تم" "message": "تم"
}, },
@ -526,6 +534,9 @@
"learnMore": { "learnMore": {
"message": "اكتشف المزيد" "message": "اكتشف المزيد"
}, },
"learnMoreUpperCase": {
"message": "اكتشف المزيد"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "أنت بحاجة إلى استخدام حسابك الأخير قبل أن تتمكن من إضافة حساب جديد." "message": "أنت بحاجة إلى استخدام حسابك الأخير قبل أن تتمكن من إضافة حساب جديد."
}, },
@ -577,9 +588,6 @@
"myAccounts": { "myAccounts": {
"message": "حساباتي" "message": "حساباتي"
}, },
"needEtherInWallet": {
"message": "للتفاعل مع التطبيقات اللامركزية باستخدام MetaMask، ستحتاج إلى الإيثير في محفظتك."
},
"needImportFile": { "needImportFile": {
"message": "يلزم تحديد ملف للاستيراد.", "message": "يلزم تحديد ملف للاستيراد.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Отхвърляне"
},
"QRHardwareWalletImporterTitle": {
"message": "Сканиране на QR код"
},
"about": { "about": {
"message": "Информация" "message": "Информация"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Настоящ език" "message": "Настоящ език"
}, },
"custom": {
"message": "Разширени"
},
"customGas": { "customGas": {
"message": "Персонализирайте газ" "message": "Персонализирайте газ"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Наистина ли искате да изтриете тази мрежа?" "message": "Наистина ли искате да изтриете тази мрежа?"
}, },
"depositEther": {
"message": "Депозирайте етер"
},
"details": { "details": {
"message": "Подробности" "message": "Подробности"
}, },
"directDepositEther": {
"message": "Директно депозиране на етер"
},
"directDepositEtherExplainer": {
"message": "Ако вече имате някакъв етер, най-бързият начин да получите етер в новия си портфейл е чрез директен депозит."
},
"done": { "done": {
"message": "Готово" "message": "Готово"
}, },
@ -526,6 +526,9 @@
"learnMore": { "learnMore": {
"message": "Научете повече" "message": "Научете повече"
}, },
"learnMoreUpperCase": {
"message": "Научете повече"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Трябва да използвате последния си акаунт, преди да можете да добавите нов." "message": "Трябва да използвате последния си акаунт, преди да можете да добавите нов."
}, },
@ -580,9 +583,6 @@
"myAccounts": { "myAccounts": {
"message": "Моите акаунти" "message": "Моите акаунти"
}, },
"needEtherInWallet": {
"message": "За да взаимодействате с децентрализираните приложения, използвайки MetaMask, ще ви е необходим етер в портфейла ви."
},
"needImportFile": { "needImportFile": {
"message": "Трябва да изберете файл за импортиране.", "message": "Трябва да изберете файл за импортиране.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "পরতন"
},
"QRHardwareWalletImporterTitle": {
"message": "QR কড সন করন"
},
"about": { "about": {
"message": "সমপর" "message": "সমপর"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "বরতমন ভ" "message": "বরতমন ভ"
}, },
"custom": {
"message": "উননত"
},
"customGas": { "customGas": {
"message": "গস কইজ করন" "message": "গস কইজ করন"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "আপনিি এই নটওয়কটির বিষয়িিত?" "message": "আপনিি এই নটওয়কটির বিষয়িিত?"
}, },
"depositEther": {
"message": "ইথর জম করন"
},
"details": { "details": {
"message": "বিশদ বিবরণ" "message": "বিশদ বিবরণ"
}, },
"directDepositEther": {
"message": "সরসরি ইথর জম করন"
},
"directDepositEtherExplainer": {
"message": "আপনর ইতিমধি ইথর থকল আপনর নতন ওয় ইথর পওয়র দততম উপয় হল সরসরি জম কর।"
},
"done": { "done": {
"message": "সমপনন " "message": "সমপনন "
}, },
@ -530,6 +530,9 @@
"learnMore": { "learnMore": {
"message": "আরও জন" "message": "আরও জন"
}, },
"learnMoreUpperCase": {
"message": "আরও জন"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "একটি নতন অউনট যগ করর আগ আপন আপনর শষ অউনট বযবহর করলত হব।" "message": "একটি নতন অউনট যগ করর আগ আপন আপনর শষ অউনট বযবহর করলত হব।"
}, },
@ -584,9 +587,6 @@
"myAccounts": { "myAccounts": {
"message": "আমর অউনটগি" "message": "আমর অউনটগি"
}, },
"needEtherInWallet": {
"message": "MetaMask বযবহর কর ছড়িিিিশনগির সগ করত, আপনর ওয় ইথর লগব।"
},
"needImportFile": { "needImportFile": {
"message": "আমদি করর জনয আপন অবশযই একটিইল নিচন করত হব।", "message": "আমদি করর জনয আপন অবশযই একটিইল নিচন করত হব।",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Rebutja"
},
"QRHardwareWalletImporterTitle": {
"message": "Escanejar Codi QR"
},
"about": { "about": {
"message": "Informació" "message": "Informació"
}, },
@ -253,6 +259,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Llengua Actual" "message": "Llengua Actual"
}, },
"custom": {
"message": "Configuració avançada"
},
"customGas": { "customGas": {
"message": "Customitza el gas" "message": "Customitza el gas"
}, },
@ -280,18 +289,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Estàs segur que vols eliminar aquesta xarxa?" "message": "Estàs segur que vols eliminar aquesta xarxa?"
}, },
"depositEther": {
"message": "Diposita Ether"
},
"details": { "details": {
"message": "Detalls" "message": "Detalls"
}, },
"directDepositEther": {
"message": "Diposita Ether directament"
},
"directDepositEtherExplainer": {
"message": "Si ja tens una mica d'Ether, la manera més ràpida de posar Ether al teu nou moneder és per dipòsit directe."
},
"done": { "done": {
"message": "Fet" "message": "Fet"
}, },
@ -517,6 +517,9 @@
"learnMore": { "learnMore": {
"message": "Saber més" "message": "Saber més"
}, },
"learnMoreUpperCase": {
"message": "Saber més"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Has de fer servir el teu últim compte abans de poder afegir-ne un altre." "message": "Has de fer servir el teu últim compte abans de poder afegir-ne un altre."
}, },
@ -568,9 +571,6 @@
"myAccounts": { "myAccounts": {
"message": "Els meus Comptes" "message": "Els meus Comptes"
}, },
"needEtherInWallet": {
"message": "Per a interactuar amb aplicacions descentralitzades fent servir MetaMask, necessitaràs Ether al teu moneder."
},
"needImportFile": { "needImportFile": {
"message": "Has de seleccionar un arxiu per a importar.", "message": "Has de seleccionar un arxiu per a importar.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,7 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Odmítnout"
},
"account": { "account": {
"message": "Účet" "message": "Účet"
}, },
@ -105,18 +108,9 @@
"decimalsMustZerotoTen": { "decimalsMustZerotoTen": {
"message": "Desetinných míst musí být od 0 do 36." "message": "Desetinných míst musí být od 0 do 36."
}, },
"depositEther": {
"message": "Vložit Ether"
},
"details": { "details": {
"message": "Podrobnosti" "message": "Podrobnosti"
}, },
"directDepositEther": {
"message": "Vložit Ether přímo"
},
"directDepositEtherExplainer": {
"message": "Pokud už vlastníte nějaký Ether, nejrychleji ho dostanete do peněženky přímým vkladem."
},
"done": { "done": {
"message": "Hotovo" "message": "Hotovo"
}, },
@ -213,6 +207,9 @@
"learnMore": { "learnMore": {
"message": "Zjistěte více." "message": "Zjistěte více."
}, },
"learnMoreUpperCase": {
"message": "Zjistěte více."
},
"likeToImportTokens": { "likeToImportTokens": {
"message": "Chcete přidat tyto tokeny?" "message": "Chcete přidat tyto tokeny?"
}, },
@ -240,9 +237,6 @@
"myAccounts": { "myAccounts": {
"message": "Moje účty" "message": "Moje účty"
}, },
"needEtherInWallet": {
"message": "Potřebujete Ether v peněžence, abyste mohli pomocí MetaMasku interagovat s decentralizovanými aplikacemi."
},
"needImportFile": { "needImportFile": {
"message": "Musíte zvolit soubor k importu.", "message": "Musíte zvolit soubor k importu.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Afvis"
},
"QRHardwareWalletImporterTitle": {
"message": "Scan QR-kode"
},
"about": { "about": {
"message": "Om" "message": "Om"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Nuværende sprog" "message": "Nuværende sprog"
}, },
"custom": {
"message": "Avanceret"
},
"customGas": { "customGas": {
"message": "Tilpas brændstof" "message": "Tilpas brændstof"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Er du sikker på, at du vil slette dette netværk?" "message": "Er du sikker på, at du vil slette dette netværk?"
}, },
"depositEther": {
"message": "Indbetal Ether"
},
"details": { "details": {
"message": "Detaljer" "message": "Detaljer"
}, },
"directDepositEther": {
"message": "Indskyd Ether direkte"
},
"directDepositEtherExplainer": {
"message": "Hvis du allerede har Ether, er den hurtigste måde at få Ether i din nye tegnebog ved direkte indbetaling."
},
"done": { "done": {
"message": "Færdig" "message": "Færdig"
}, },
@ -523,6 +523,9 @@
"learnMore": { "learnMore": {
"message": "Lær mere" "message": "Lær mere"
}, },
"learnMoreUpperCase": {
"message": "Lær mere"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Du skal benytte din tidligere konto, før du kan tilføje en ny." "message": "Du skal benytte din tidligere konto, før du kan tilføje en ny."
}, },
@ -568,9 +571,6 @@
"myAccounts": { "myAccounts": {
"message": "Mine Konti" "message": "Mine Konti"
}, },
"needEtherInWallet": {
"message": "Du skal have Ether i din tegnebog for at interagere med decentraliserede applikationer, der bruger MetaMask."
},
"needImportFile": { "needImportFile": {
"message": "Du skal vælge en fil, der skal importeres.", "message": "Du skal vælge en fil, der skal importeres.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Ablehnen"
},
"QRHardwareWalletImporterTitle": {
"message": "QR-Code scannen"
},
"about": { "about": {
"message": "Über" "message": "Über"
}, },
@ -247,6 +253,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Aktuelle Sprache" "message": "Aktuelle Sprache"
}, },
"custom": {
"message": "Erweitert"
},
"customGas": { "customGas": {
"message": "Gas anpassen" "message": "Gas anpassen"
}, },
@ -274,14 +283,42 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Sind Sie sicher, dass Sie dieses Netzwerk löschen möchten?" "message": "Sind Sie sicher, dass Sie dieses Netzwerk löschen möchten?"
}, },
"depositEther": { "description": {
"message": "Ether einzahlen" "message": "Beschreibung"
},
"details": {
"message": "Details"
},
"disabledGasOptionToolTipMessage": {
"message": "“$1” ist deaktiviert, weil es nicht das Minimum einer zehnprozentigen Erhöhung gegenüber der ursprünglichen Gasgebühr erfüllt.",
"description": "$1 is gas estimate type which can be market or aggressive"
},
"disconnect": {
"message": "Verbindung trennen"
},
"disconnectAllAccounts": {
"message": "Alle Konten trennen"
},
"disconnectAllAccountsConfirmationDescription": {
"message": "Sind Sie sicher, dass Sie die Verbindung trennen möchten? Sie könnten die Site-Funktionalität verlieren."
}, },
"directDepositEther": { "disconnectPrompt": {
"message": "Sofort Ether einzahlen" "message": "$1 trennen"
}, },
"directDepositEtherExplainer": { "disconnectThisAccount": {
"message": "Wenn du bereits Ether besitzt, ist die sofortige Einzahlung die schnellste Methode Ether in deine neue Wallet zu bekommen." "message": "Dieses Konto trennen"
},
"dismiss": {
"message": "Verwerfen"
},
"dismissReminderDescriptionField": {
"message": "Aktivieren Sie diese Option, um die Erinnerungsmeldung zur Sicherung des Geheime Wiederherstellungsphrase zu deaktivieren. Wir empfehlen Ihnen dringend, eine Sicherungskopie Ihrer Geheime Wiederherstellungsphrase zu erstellen, um den Verlust von Geldern zu vermeiden"
},
"dismissReminderField": {
"message": "Erinnerung Geheime Wiederherstellungsphrase abweisen"
},
"domain": {
"message": "Domäne"
}, },
"done": { "done": {
"message": "Fertig" "message": "Fertig"
@ -427,9 +464,6 @@
"happyToSeeYou": { "happyToSeeYou": {
"message": "Wir freuen uns, Sie zu sehen." "message": "Wir freuen uns, Sie zu sehen."
}, },
"hardware": {
"message": "Hardware"
},
"hardwareWalletConnected": { "hardwareWalletConnected": {
"message": "Hardware-Wallet verknüpft" "message": "Hardware-Wallet verknüpft"
}, },
@ -518,6 +552,9 @@
"learnMore": { "learnMore": {
"message": "Mehr erfahren" "message": "Mehr erfahren"
}, },
"learnMoreUpperCase": {
"message": "Mehr erfahren"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Sie müssen Ihr letztes Konto verwenden, ehe Sie ein neues hinzufügen können." "message": "Sie müssen Ihr letztes Konto verwenden, ehe Sie ein neues hinzufügen können."
}, },
@ -539,9 +576,6 @@
"lock": { "lock": {
"message": "Ausloggen" "message": "Ausloggen"
}, },
"mainnet": {
"message": "Ethereum Mainnet"
},
"memo": { "memo": {
"message": " Memo" "message": " Memo"
}, },
@ -563,9 +597,6 @@
"myAccounts": { "myAccounts": {
"message": "Meine Accounts" "message": "Meine Accounts"
}, },
"needEtherInWallet": {
"message": "Um dezentralisierte Applikationen mit MetaMask verwenden zu können, benötigst du Ether in deiner Wallet."
},
"needImportFile": { "needImportFile": {
"message": "Für den Import musst du eine Datei auswählen.", "message": "Für den Import musst du eine Datei auswählen.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"
@ -591,10 +622,6 @@
"newAccountDetectedDialogMessage": { "newAccountDetectedDialogMessage": {
"message": "Neue Adresse erkannt! Klicken Sie hier, um sie zu Ihrem Adressbuch hinzuzufügen." "message": "Neue Adresse erkannt! Klicken Sie hier, um sie zu Ihrem Adressbuch hinzuzufügen."
}, },
"newAccountNumberName": {
"message": "Account $1",
"description": "Default name of next account to be created on create account screen"
},
"newContact": { "newContact": {
"message": "Neuer Kontakt" "message": "Neuer Kontakt"
}, },

File diff suppressed because it is too large Load Diff

@ -140,9 +140,6 @@
"addMemo": { "addMemo": {
"message": "Add memo" "message": "Add memo"
}, },
"addNFT": {
"message": "Add NFT"
},
"addNetwork": { "addNetwork": {
"message": "Add Network" "message": "Add Network"
}, },
@ -392,11 +389,13 @@
"buy": { "buy": {
"message": "Buy" "message": "Buy"
}, },
"buyWithTransak": { "buyCryptoWithTransak": {
"message": "Buy ETH with Transak" "message": "Buy $1 with Transak",
"description": "$1 represents the cypto symbol to be purchased"
}, },
"buyWithTransakDescription": { "buyCryptoWithTransakDescription": {
"message": "Transak supports debit card and bank transfers (depending on location) in 59+ countries. ETH deposits into your MetaMask account." "message": "Transak supports debit card and bank transfers (depending on location) in 59+ countries. $1 deposits into your MetaMask account.",
"description": "$1 represents the cypto symbol to be purchased"
}, },
"buyWithWyre": { "buyWithWyre": {
"message": "Buy ETH with Wyre" "message": "Buy ETH with Wyre"
@ -458,6 +457,10 @@
"close": { "close": {
"message": "Close" "message": "Close"
}, },
"collectibleAddressError": {
"message": "This token is an NFT. Add on the $1",
"description": "$1 is a clickable link with text defined by the 'importNFTPage' key"
},
"confirm": { "confirm": {
"message": "Confirm" "message": "Confirm"
}, },
@ -595,6 +598,9 @@
"contractInteraction": { "contractInteraction": {
"message": "Contract Interaction" "message": "Contract Interaction"
}, },
"convertTokenToNFTDescription": {
"message": "We've detected that this asset is an NFT. Metamask now has full native support for NFTs. Would you like to remove it from your token list and add it as an NFT?"
},
"copiedExclamation": { "copiedExclamation": {
"message": "Copied!" "message": "Copied!"
}, },
@ -652,6 +658,15 @@
"currentlyUnavailable": { "currentlyUnavailable": {
"message": "Unavailable on this network" "message": "Unavailable on this network"
}, },
"curveHighGasEstimate": {
"message": "Aggressive gas estimate graph"
},
"curveLowGasEstimate": {
"message": "Low gas estimate graph"
},
"curveMediumGasEstimate": {
"message": "Market gas estimate graph"
},
"custom": { "custom": {
"message": "Advanced" "message": "Advanced"
}, },
@ -659,7 +674,7 @@
"message": "Customize Gas" "message": "Customize Gas"
}, },
"customGasSettingToolTipMessage": { "customGasSettingToolTipMessage": {
"message": "Use $1 to customise the gas price. This can be confusing if you aren’t familiar. Interact at your own risk.", "message": "Use $1 to customize the gas price. This can be confusing if you aren’t familiar. Interact at your own risk.",
"description": "$1 is key 'advanced' (text: 'Advanced') separated here so that it can be passed in with bold fontweight" "description": "$1 is key 'advanced' (text: 'Advanced') separated here so that it can be passed in with bold fontweight"
}, },
"customGasSubTitle": { "customGasSubTitle": {
@ -732,8 +747,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Are you sure you want to delete this network?" "message": "Are you sure you want to delete this network?"
}, },
"depositEther": { "depositCrypto": {
"message": "Deposit Ether" "message": "Deposit $1",
"description": "$1 represents the cypto symbol to be purchased"
}, },
"description": { "description": {
"message": "Description" "message": "Description"
@ -741,11 +757,11 @@
"details": { "details": {
"message": "Details" "message": "Details"
}, },
"directDepositEther": { "directDepositCrypto": {
"message": "Directly Deposit Ether" "message": "Directly Deposit $1"
}, },
"directDepositEtherExplainer": { "directDepositCryptoExplainer": {
"message": "If you already have some Ether, the quickest way to get Ether in your new wallet by direct deposit." "message": "If you already have some $1, the quickest way to get $1 in your new wallet by direct deposit."
}, },
"disabledGasOptionToolTipMessage": { "disabledGasOptionToolTipMessage": {
"message": "“$1” is disabled because it does not meet the minimum of a 10% increase from the original gas fee.", "message": "“$1” is disabled because it does not meet the minimum of a 10% increase from the original gas fee.",
@ -933,6 +949,22 @@
"enableAutoDetect": { "enableAutoDetect": {
"message": " Enable Autodetect" "message": " Enable Autodetect"
}, },
"enableEIP1559V2": {
"message": "Enable Enhanced Gas Fee UI"
},
"enableEIP1559V2AlertMessage": {
"message": "We've updated how gas fee estimation and customization works."
},
"enableEIP1559V2ButtonText": {
"message": "Turn on Enhanced Gas Fee UI in Settings"
},
"enableEIP1559V2Description": {
"message": "We've updated how gas estimation and customization works. Turn on if you'd like to use the new gas experience. $1",
"description": "$1 here is Learn More link"
},
"enableEIP1559V2Header": {
"message": "New gas experience"
},
"enableFromSettings": { "enableFromSettings": {
"message": " Enable it from Settings." "message": " Enable it from Settings."
}, },
@ -1054,7 +1086,7 @@
"message": "Backup gas price is provided as the main gas estimation service is unavailable right now." "message": "Backup gas price is provided as the main gas estimation service is unavailable right now."
}, },
"eth_accounts": { "eth_accounts": {
"message": "See address, account balance, activity and initiate transactions", "message": "See address, account balance, activity and suggest transactions to approve",
"description": "The description for the `eth_accounts` permission" "description": "The description for the `eth_accounts` permission"
}, },
"ethereumPublicAddress": { "ethereumPublicAddress": {
@ -1190,6 +1222,9 @@
"gasLimitInfoTooltipContent": { "gasLimitInfoTooltipContent": {
"message": "Gas limit is the maximum amount of units of gas you are willing to spend." "message": "Gas limit is the maximum amount of units of gas you are willing to spend."
}, },
"gasLimitRecommended": {
"message": "Recommended gas limit is $1. If the gas limit is less than that, it may fail."
},
"gasLimitTooLow": { "gasLimitTooLow": {
"message": "Gas limit must be at least 21000" "message": "Gas limit must be at least 21000"
}, },
@ -1337,11 +1372,8 @@
"high": { "high": {
"message": "Aggressive" "message": "Aggressive"
}, },
"highGasSettingToolTipDialog": {
"message": "High probability, even in volatile markets"
},
"highGasSettingToolTipMessage": { "highGasSettingToolTipMessage": {
"message": "Use $1 to cover surges in network traffic due to things like popular NFT drops.", "message": "High probability, even in volatile markets. Use $1 to cover surges in network traffic due to things like popular NFT drops.",
"description": "$1 is key 'high' (text: 'Aggressive') separated here so that it can be passed in with bold fontweight" "description": "$1 is key 'high' (text: 'Aggressive') separated here so that it can be passed in with bold fontweight"
}, },
"highLowercase": { "highLowercase": {
@ -1350,9 +1382,6 @@
"history": { "history": {
"message": "History" "message": "History"
}, },
"id": {
"message": "ID"
},
"import": { "import": {
"message": "Import", "message": "Import",
"description": "Button to import an account from a selected file" "description": "Button to import an account from a selected file"
@ -1386,6 +1415,18 @@
"importMyWallet": { "importMyWallet": {
"message": "Import My Wallet" "message": "Import My Wallet"
}, },
"importNFT": {
"message": "Import NFT"
},
"importNFTAddressToolTip": {
"message": "On OpenSea, for example, on the NFT's page under Details, there is a blue hyperlinked value labeled 'Contract Address'. If you click on this, it will take you to the contract's address on Etherscan; at the top-left of that page, there should be an icon labeled 'Contract', and to the right, a long string of letters and numbers. This is the address of the contract that created your NFT. Click on the 'copy' icon to the right of the address, and you'll have it on your clipboard."
},
"importNFTPage": {
"message": "Import NFT page"
},
"importNFTTokenIdToolTip": {
"message": "A collectible's ID is a unique identifier since no two NFTs are alike. Again, on OpenSea this number is under 'Details'. Make a note of it, or copy it onto your clipboard."
},
"importNFTs": { "importNFTs": {
"message": "Import NFTs" "message": "Import NFTs"
}, },
@ -1439,6 +1480,9 @@
"invalidAddressRecipientNotEthNetwork": { "invalidAddressRecipientNotEthNetwork": {
"message": "Not ETH network, set to lowercase" "message": "Not ETH network, set to lowercase"
}, },
"invalidAssetType": {
"message": "This asset is an NFT and needs to be re-added on the Import NFTs page found under the NFTs tab"
},
"invalidBlockExplorerURL": { "invalidBlockExplorerURL": {
"message": "Invalid Block Explorer URL" "message": "Invalid Block Explorer URL"
}, },
@ -1503,7 +1547,7 @@
"message": "Known contract address." "message": "Known contract address."
}, },
"knownTokenWarning": { "knownTokenWarning": {
"message": "This action will edit tokens that are already listed in your wallet, which can be used to phish you. Only approve if you are certain that you mean to change what these tokens represent." "message": "This action will edit tokens that are already listed in your wallet, which can be used to phish you. Only approve if you are certain that you mean to change what these tokens represent. Learn more about $1"
}, },
"kovan": { "kovan": {
"message": "Kovan Test Network" "message": "Kovan Test Network"
@ -1596,6 +1640,9 @@
"loading": { "loading": {
"message": "Loading..." "message": "Loading..."
}, },
"loadingNFTs": {
"message": "Loading NFTs..."
},
"loadingTokens": { "loadingTokens": {
"message": "Loading Tokens..." "message": "Loading Tokens..."
}, },
@ -1612,14 +1659,14 @@
"message": "Low" "message": "Low"
}, },
"lowGasSettingToolTipMessage": { "lowGasSettingToolTipMessage": {
"message": "Use $1 to wait for a cheaper price. Time estimates are much less accurate as prices are somewhat unpredicible.", "message": "Use $1 to wait for a cheaper price. Time estimates are much less accurate as prices are somewhat unpredictable.",
"description": "$1 is key 'low' separated here so that it can be passed in with bold fontweight" "description": "$1 is key 'low' separated here so that it can be passed in with bold fontweight"
}, },
"lowLowercase": { "lowLowercase": {
"message": "low" "message": "low"
}, },
"lowPriorityMessage": { "lowPriorityMessage": {
"message": "Future transactions will queue after this one. This price was last seen was some time ago." "message": "Future transactions will queue after this one."
}, },
"mainnet": { "mainnet": {
"message": "Ethereum Mainnet" "message": "Ethereum Mainnet"
@ -1755,8 +1802,9 @@
"name": { "name": {
"message": "Name" "message": "Name"
}, },
"needEtherInWallet": { "needCryptoInWallet": {
"message": "To interact with decentralized applications using MetaMask, you’ll need Ether in your wallet." "message": "To interact with decentralized applications using MetaMask, you’ll need $1 in your wallet.",
"description": "$1 represents the cypto symbol to be purchased"
}, },
"needHelp": { "needHelp": {
"message": "Need help? Contact $1", "message": "Need help? Contact $1",
@ -1891,7 +1939,7 @@
"description": "The next nonce according to MetaMask's internal logic" "description": "The next nonce according to MetaMask's internal logic"
}, },
"nftTokenIdPlaceholder": { "nftTokenIdPlaceholder": {
"message": "Enter the collectible ID" "message": "Enter the Token ID"
}, },
"nfts": { "nfts": {
"message": "NFTs" "message": "NFTs"
@ -2155,7 +2203,7 @@
"message": "Passwords Don't Match" "message": "Passwords Don't Match"
}, },
"pastePrivateKey": { "pastePrivateKey": {
"message": "Paste your private key string here:", "message": "Enter your private key string here:",
"description": "For importing an account from a private key" "description": "For importing an account from a private key"
}, },
"pending": { "pending": {
@ -2467,7 +2515,7 @@
"message": "Separate each word with a single space" "message": "Separate each word with a single space"
}, },
"seedPhrasePlaceholderPaste": { "seedPhrasePlaceholderPaste": {
"message": "Paste Secret Recovery Phrase from clipboard" "message": "Enter your Secret Recovery Phrase"
}, },
"seedPhraseReq": { "seedPhraseReq": {
"message": "Secret Recovery Phrases contain 12, 15, 18, 21, or 24 words" "message": "Secret Recovery Phrases contain 12, 15, 18, 21, or 24 words"
@ -3508,6 +3556,9 @@
"message": "$1 of $2 pending", "message": "$1 of $2 pending",
"description": "$1 and $2 are intended to be two numbers, where $2 is a total number of pending confirmations, and $1 is a count towards that total" "description": "$1 and $2 are intended to be two numbers, where $2 is a total number of pending confirmations, and $1 is a count towards that total"
}, },
"yes": {
"message": "Yes"
},
"yesLetsTry": { "yesLetsTry": {
"message": "Yes, let's try" "message": "Yes, let's try"
}, },

@ -260,9 +260,6 @@
"buyWithWyreDescription": { "buyWithWyreDescription": {
"message": "Wyre le permite usar una tarjeta de débito para depositar ETH directamente en su cuenta de MetaMask." "message": "Wyre le permite usar una tarjeta de débito para depositar ETH directamente en su cuenta de MetaMask."
}, },
"bytes": {
"message": "Bytes"
},
"canToggleInSettings": { "canToggleInSettings": {
"message": "Puede volver a activar esta notificación desde Configuración -> Alertas." "message": "Puede volver a activar esta notificación desde Configuración -> Alertas."
}, },
@ -519,18 +516,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "¿Está seguro de que quiere eliminar esta red?" "message": "¿Está seguro de que quiere eliminar esta red?"
}, },
"depositEther": {
"message": "Depositar ether"
},
"details": { "details": {
"message": "Detalles" "message": "Detalles"
}, },
"directDepositEther": {
"message": "Depositar ether directamente"
},
"directDepositEtherExplainer": {
"message": "Si ya tiene algunos ethers, la forma más rápida de tenerlos en la cartera nueva es mediante depósito directo."
},
"disconnect": { "disconnect": {
"message": "Desconectar" "message": "Desconectar"
}, },
@ -696,9 +684,6 @@
"ethereumPublicAddress": { "ethereumPublicAddress": {
"message": "Dirección pública de Ethereum" "message": "Dirección pública de Ethereum"
}, },
"etherscan": {
"message": "Etherscan"
},
"etherscanView": { "etherscanView": {
"message": "Ver cuenta en Etherscan" "message": "Ver cuenta en Etherscan"
}, },
@ -802,9 +787,6 @@
"message": "Política de privacidad aquí", "message": "Política de privacidad aquí",
"description": "this translation is intended to be exclusively used as the replacement for the $1 in the gdprMessage translation" "description": "this translation is intended to be exclusively used as the replacement for the $1 in the gdprMessage translation"
}, },
"general": {
"message": "General"
},
"generalSettingsDescription": { "generalSettingsDescription": {
"message": "Conversión de moneda, moneda principal, idioma, Blockies Identicon" "message": "Conversión de moneda, moneda principal, idioma, Blockies Identicon"
}, },
@ -824,16 +806,9 @@
"happyToSeeYou": { "happyToSeeYou": {
"message": "Nos alegra verlo." "message": "Nos alegra verlo."
}, },
"hardware": {
"message": "Hardware"
},
"hardwareWalletConnected": { "hardwareWalletConnected": {
"message": "Cartera de hardware conectada" "message": "Cartera de hardware conectada"
}, },
"hardwareWalletLegacyDescription": {
"message": "(legacy)",
"description": "Text representing the MEW path"
},
"hardwareWalletSupportLinkConversion": { "hardwareWalletSupportLinkConversion": {
"message": "Haga clic aquí" "message": "Haga clic aquí"
}, },
@ -1116,9 +1091,6 @@
"name": { "name": {
"message": "Nombre" "message": "Nombre"
}, },
"needEtherInWallet": {
"message": "Para interactuar con aplicaciones descentralizadas mediante MetaMask, necesitará ethers en su cartera."
},
"needHelp": { "needHelp": {
"message": "¿Necesita ayuda? Comuníquese con $1", "message": "¿Necesita ayuda? Comuníquese con $1",
"description": "$1 represents `needHelpLinkText`, the text which goes in the help link" "description": "$1 represents `needHelpLinkText`, the text which goes in the help link"
@ -1139,15 +1111,9 @@
"networkName": { "networkName": {
"message": "Nombre de la red" "message": "Nombre de la red"
}, },
"networkNameBSC": {
"message": "BSC"
},
"networkNameDefinition": { "networkNameDefinition": {
"message": "El nombre asociado a esta red." "message": "El nombre asociado a esta red."
}, },
"networkNameEthereum": {
"message": "Ethereum"
},
"networkNameTestnet": { "networkNameTestnet": {
"message": "Red de prueba" "message": "Red de prueba"
}, },
@ -1228,9 +1194,6 @@
"noWebcamFoundTitle": { "noWebcamFoundTitle": {
"message": "No se encontró cámara web" "message": "No se encontró cámara web"
}, },
"nonce": {
"message": "Nonce"
},
"nonceField": { "nonceField": {
"message": "Personalizar nonce de transacción" "message": "Personalizar nonce de transacción"
}, },
@ -2128,9 +2091,6 @@
"message": "Para: $1", "message": "Para: $1",
"description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress"
}, },
"token": {
"message": "Token"
},
"tokenAlreadyAdded": { "tokenAlreadyAdded": {
"message": "Ya se agregó el token." "message": "Ya se agregó el token."
}, },
@ -2146,9 +2106,6 @@
"tooltipApproveButton": { "tooltipApproveButton": {
"message": "Comprendo" "message": "Comprendo"
}, },
"total": {
"message": "Total"
},
"transaction": { "transaction": {
"message": "transacción" "message": "transacción"
}, },

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Rechazar"
},
"QRHardwareWalletImporterTitle": {
"message": "Escanear código QR"
},
"about": { "about": {
"message": "Acerca de" "message": "Acerca de"
}, },
@ -260,9 +266,6 @@
"buyWithWyreDescription": { "buyWithWyreDescription": {
"message": "Wyre le permite usar una tarjeta de débito para depositar ETH directamente en su cuenta de MetaMask." "message": "Wyre le permite usar una tarjeta de débito para depositar ETH directamente en su cuenta de MetaMask."
}, },
"bytes": {
"message": "Bytes"
},
"canToggleInSettings": { "canToggleInSettings": {
"message": "Puede volver a activar esta notificación desde Configuración -> Alertas." "message": "Puede volver a activar esta notificación desde Configuración -> Alertas."
}, },
@ -466,6 +469,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Idioma actual" "message": "Idioma actual"
}, },
"custom": {
"message": "Avanzado"
},
"customGas": { "customGas": {
"message": "Personalizar gas" "message": "Personalizar gas"
}, },
@ -519,17 +525,12 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "¿Está seguro de que quiere eliminar esta red?" "message": "¿Está seguro de que quiere eliminar esta red?"
}, },
"depositEther": {
"message": "Depositar ether"
},
"details": { "details": {
"message": "Detalles" "message": "Detalles"
}, },
"directDepositEther": { "disabledGasOptionToolTipMessage": {
"message": "Depositar ether directamente" "message": "\"1$\" está desactivado porque no cumple el mínimo de un aumento del 10% respecto a la tarifa de gas original.",
}, "description": "$1 is gas estimate type which can be market or aggressive"
"directDepositEtherExplainer": {
"message": "Si ya tiene algunos ethers, la forma más rápida de tenerlos en la cartera nueva es mediante depósito directo."
}, },
"disconnect": { "disconnect": {
"message": "Desconectar" "message": "Desconectar"
@ -696,9 +697,6 @@
"ethereumPublicAddress": { "ethereumPublicAddress": {
"message": "Dirección pública de Ethereum" "message": "Dirección pública de Ethereum"
}, },
"etherscan": {
"message": "Etherscan"
},
"etherscanView": { "etherscanView": {
"message": "Ver cuenta en Etherscan" "message": "Ver cuenta en Etherscan"
}, },
@ -802,9 +800,6 @@
"message": "Política de privacidad aquí", "message": "Política de privacidad aquí",
"description": "this translation is intended to be exclusively used as the replacement for the $1 in the gdprMessage translation" "description": "this translation is intended to be exclusively used as the replacement for the $1 in the gdprMessage translation"
}, },
"general": {
"message": "General"
},
"generalSettingsDescription": { "generalSettingsDescription": {
"message": "Conversión de moneda, moneda principal, idioma, Blockies Identicon" "message": "Conversión de moneda, moneda principal, idioma, Blockies Identicon"
}, },
@ -824,16 +819,9 @@
"happyToSeeYou": { "happyToSeeYou": {
"message": "Nos alegra verlo." "message": "Nos alegra verlo."
}, },
"hardware": {
"message": "Hardware"
},
"hardwareWalletConnected": { "hardwareWalletConnected": {
"message": "Cartera de hardware conectada" "message": "Cartera de hardware conectada"
}, },
"hardwareWalletLegacyDescription": {
"message": "(legacy)",
"description": "Text representing the MEW path"
},
"hardwareWalletSupportLinkConversion": { "hardwareWalletSupportLinkConversion": {
"message": "Haga clic aquí" "message": "Haga clic aquí"
}, },
@ -993,6 +981,9 @@
"learnMore": { "learnMore": {
"message": "Más información" "message": "Más información"
}, },
"learnMoreUpperCase": {
"message": "Más información"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Debe usar su última cuenta antes de poder agregar una nueva." "message": "Debe usar su última cuenta antes de poder agregar una nueva."
}, },
@ -1116,9 +1107,6 @@
"name": { "name": {
"message": "Nombre" "message": "Nombre"
}, },
"needEtherInWallet": {
"message": "Para interactuar con aplicaciones descentralizadas mediante MetaMask, necesitará ethers en su cartera."
},
"needHelp": { "needHelp": {
"message": "¿Necesita ayuda? Comuníquese con $1", "message": "¿Necesita ayuda? Comuníquese con $1",
"description": "$1 represents `needHelpLinkText`, the text which goes in the help link" "description": "$1 represents `needHelpLinkText`, the text which goes in the help link"
@ -1139,15 +1127,9 @@
"networkName": { "networkName": {
"message": "Nombre de la red" "message": "Nombre de la red"
}, },
"networkNameBSC": {
"message": "BSC"
},
"networkNameDefinition": { "networkNameDefinition": {
"message": "El nombre asociado a esta red." "message": "El nombre asociado a esta red."
}, },
"networkNameEthereum": {
"message": "Ethereum"
},
"networkNameTestnet": { "networkNameTestnet": {
"message": "Red de prueba" "message": "Red de prueba"
}, },
@ -1228,9 +1210,6 @@
"noWebcamFoundTitle": { "noWebcamFoundTitle": {
"message": "No se encontró cámara web" "message": "No se encontró cámara web"
}, },
"nonce": {
"message": "Nonce"
},
"nonceField": { "nonceField": {
"message": "Personalizar nonce de transacción" "message": "Personalizar nonce de transacción"
}, },
@ -2128,9 +2107,6 @@
"message": "Para: $1", "message": "Para: $1",
"description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress"
}, },
"token": {
"message": "Token"
},
"tokenAlreadyAdded": { "tokenAlreadyAdded": {
"message": "Ya se agregó el token." "message": "Ya se agregó el token."
}, },
@ -2146,9 +2122,6 @@
"tooltipApproveButton": { "tooltipApproveButton": {
"message": "Comprendo" "message": "Comprendo"
}, },
"total": {
"message": "Total"
},
"transaction": { "transaction": {
"message": "transacción" "message": "transacción"
}, },

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Lükka tagasi"
},
"QRHardwareWalletImporterTitle": {
"message": "Skannige QR-koos"
},
"about": { "about": {
"message": "Teave" "message": "Teave"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Praegune keel" "message": "Praegune keel"
}, },
"custom": {
"message": "Täpsemad"
},
"customGas": { "customGas": {
"message": "Gaasi kohandamine" "message": "Gaasi kohandamine"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Olete kindel, et soovite selle võrgu kustutada?" "message": "Olete kindel, et soovite selle võrgu kustutada?"
}, },
"depositEther": {
"message": "Eetri sissemakse"
},
"details": { "details": {
"message": "Üksikasjad" "message": "Üksikasjad"
}, },
"directDepositEther": {
"message": "Eetri otsene sissemakse"
},
"directDepositEtherExplainer": {
"message": "Kui teil on juba veidi eetrit, on kiirem viis eetri rahakotti saamiseks otsene sissemakse."
},
"done": { "done": {
"message": "Valmis" "message": "Valmis"
}, },
@ -526,6 +526,9 @@
"learnMore": { "learnMore": {
"message": "Lisateave" "message": "Lisateave"
}, },
"learnMoreUpperCase": {
"message": "Lisateave"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Enne uue konto loomist peate kasutama eelmist kontot." "message": "Enne uue konto loomist peate kasutama eelmist kontot."
}, },
@ -574,9 +577,6 @@
"myAccounts": { "myAccounts": {
"message": "Minu kontod" "message": "Minu kontod"
}, },
"needEtherInWallet": {
"message": "Selleks, et suhelda MetaMaski abil detsentraliseeritud rakendustega, peab teil rahakotis eetrit olema."
},
"needImportFile": { "needImportFile": {
"message": "Peate importimiseks faili valima.", "message": "Peate importimiseks faili valima.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "عدم پذیرش"
},
"QRHardwareWalletImporterTitle": {
"message": "سکن کود QR"
},
"about": { "about": {
"message": "درباره" "message": "درباره"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "زبان فعلی" "message": "زبان فعلی"
}, },
"custom": {
"message": "پیشرفته"
},
"customGas": { "customGas": {
"message": "گاز دلخواه" "message": "گاز دلخواه"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "آیا مطمئن هستید که این شبکه حذف شود؟" "message": "آیا مطمئن هستید که این شبکه حذف شود؟"
}, },
"depositEther": {
"message": "پرداخت ایتر"
},
"details": { "details": {
"message": "جزئیات" "message": "جزئیات"
}, },
"directDepositEther": {
"message": "پرداخت مستقیم ایتر"
},
"directDepositEtherExplainer": {
"message": "در صورتیکه شما کدام ایتر داشته باشید، سریعترین روش برای گرفتن ایتر در کیف جدید تان توسط پرداخت مستقیم."
},
"done": { "done": {
"message": "تمام" "message": "تمام"
}, },
@ -530,6 +530,9 @@
"learnMore": { "learnMore": {
"message": "بیشتر بدانید" "message": "بیشتر بدانید"
}, },
"learnMoreUpperCase": {
"message": "بیشتر بدانید"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "لازم است تا حساب قبلی تان را قبل از اینکه جدید اضافه کنید، مورد استفاده قرار دهید." "message": "لازم است تا حساب قبلی تان را قبل از اینکه جدید اضافه کنید، مورد استفاده قرار دهید."
}, },
@ -584,9 +587,6 @@
"myAccounts": { "myAccounts": {
"message": "حساب های من" "message": "حساب های من"
}, },
"needEtherInWallet": {
"message": "برای تعامل با اپلیکیشن های غیر متمرکز شده با استفاده از MetaMask، شما نیاز به ایتر در کیف تان خواهید داشت."
},
"needImportFile": { "needImportFile": {
"message": "شما باید یک فایل برای وارد کردن را انتخاب کنید.", "message": "شما باید یک فایل برای وارد کردن را انتخاب کنید.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Hylkää"
},
"QRHardwareWalletImporterTitle": {
"message": "Lue QR-koodi"
},
"about": { "about": {
"message": "Tietoja asetuksista" "message": "Tietoja asetuksista"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Nykyinen kieli" "message": "Nykyinen kieli"
}, },
"custom": {
"message": "Lisäasetukset"
},
"customGas": { "customGas": {
"message": "Mukauta bensa" "message": "Mukauta bensa"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Haluatko varmasti poistaa tämän verkon?" "message": "Haluatko varmasti poistaa tämän verkon?"
}, },
"depositEther": {
"message": "Talleta Etheriä"
},
"details": { "details": {
"message": "Tiedot" "message": "Tiedot"
}, },
"directDepositEther": {
"message": "Talleta etheriä suoraan"
},
"directDepositEtherExplainer": {
"message": "Jos sinulla on jo etheriä, nopein tapa hankkia etheriä uuteen lompakkoosi on suoratalletus."
},
"done": { "done": {
"message": "Valmis" "message": "Valmis"
}, },
@ -530,6 +530,9 @@
"learnMore": { "learnMore": {
"message": "Lisätietoa" "message": "Lisätietoa"
}, },
"learnMoreUpperCase": {
"message": "Lisätietoa"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Sinun tarvitsee käyttää edellistä tiliäsi ennen kuin voit lisätä uuden." "message": "Sinun tarvitsee käyttää edellistä tiliäsi ennen kuin voit lisätä uuden."
}, },
@ -584,9 +587,6 @@
"myAccounts": { "myAccounts": {
"message": "Omat tilit" "message": "Omat tilit"
}, },
"needEtherInWallet": {
"message": "Ollaksesi vuorovaikutuksessa hajautettujen sovellusten kanssa sinulla on oltava lompakossasi Ether."
},
"needImportFile": { "needImportFile": {
"message": "Sinun tarvitsee valita tuotava tiedosto.", "message": "Sinun tarvitsee valita tuotava tiedosto.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Tanggihan"
},
"QRHardwareWalletImporterTitle": {
"message": "I-scan ang QR Code"
},
"about": { "about": {
"message": "Tungkol sa" "message": "Tungkol sa"
}, },
@ -262,18 +268,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Sigurado ka bang gusto mong i-delete ang network na ito?" "message": "Sigurado ka bang gusto mong i-delete ang network na ito?"
}, },
"depositEther": {
"message": "Magdeposito ng Ether"
},
"details": { "details": {
"message": "Mga Detalye" "message": "Mga Detalye"
}, },
"directDepositEther": {
"message": "Direktang Magdeposito ng Ether"
},
"directDepositEtherExplainer": {
"message": "Kung mayroon ka nang Ether, ang pinakamabilis na paraan para magkaroon ng Ether sa iyong bagong wallet ay sa pamamagitan ng direkang deposito."
},
"done": { "done": {
"message": "Tapos na" "message": "Tapos na"
}, },
@ -483,6 +480,9 @@
"learnMore": { "learnMore": {
"message": "Matuto pa" "message": "Matuto pa"
}, },
"learnMoreUpperCase": {
"message": "Matuto pa"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Kailangan mong gamitin ang iyong dating account bago ka makapagdagdag ng bago." "message": "Kailangan mong gamitin ang iyong dating account bago ka makapagdagdag ng bago."
}, },
@ -525,9 +525,6 @@
"myAccounts": { "myAccounts": {
"message": "Mga Account Ko" "message": "Mga Account Ko"
}, },
"needEtherInWallet": {
"message": "Para gumamit ng mga decentralized na application gamit ang MetaMask, mangangailangan ka ng Ether sa iyong wallet."
},
"needImportFile": { "needImportFile": {
"message": "Dapat kang pumili ng file na ii-import.", "message": "Dapat kang pumili ng file na ii-import.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

File diff suppressed because it is too large Load Diff

@ -1,4 +1,7 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "નક"
},
"about": { "about": {
"message": "વિ" "message": "વિ"
}, },
@ -44,6 +47,9 @@
"create": { "create": {
"message": "બન" "message": "બન"
}, },
"custom": {
"message": "વિગતવર"
},
"delete": { "delete": {
"message": "ક" "message": "ક"
}, },

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "דחה"
},
"QRHardwareWalletImporterTitle": {
"message": "סריקת קוד QR"
},
"about": { "about": {
"message": "מידע כללי" "message": "מידע כללי"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "שפה נוכחית" "message": "שפה נוכחית"
}, },
"custom": {
"message": "מתקדם"
},
"customGas": { "customGas": {
"message": "התאמה אישית של דלק" "message": "התאמה אישית של דלק"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "הנך בטוח/ה שברצונך למחוק רשת זו?" "message": "הנך בטוח/ה שברצונך למחוק רשת זו?"
}, },
"depositEther": {
"message": "הפקדת את'ר"
},
"details": { "details": {
"message": "פרטים" "message": "פרטים"
}, },
"directDepositEther": {
"message": "הפקד את'ר ישירות"
},
"directDepositEtherExplainer": {
"message": "אם כבר יש ברשותך את'ר (Ether) , הדרך המהירה ביותר להכניס את'ר לארנק החדש שלך היא באמצעות הפקדה ישירה."
},
"done": { "done": {
"message": "סיום" "message": "סיום"
}, },
@ -530,6 +530,9 @@
"learnMore": { "learnMore": {
"message": "למדו עוד" "message": "למדו עוד"
}, },
"learnMoreUpperCase": {
"message": "למדו עוד"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "עליך להשתמש בחשבון האחרון שלך לפני שתוכל/י להוסיף חשבון חדש." "message": "עליך להשתמש בחשבון האחרון שלך לפני שתוכל/י להוסיף חשבון חדש."
}, },
@ -581,9 +584,6 @@
"myAccounts": { "myAccounts": {
"message": "החשבונות שלי" "message": "החשבונות שלי"
}, },
"needEtherInWallet": {
"message": "כדי לתקשר עם אפליקציות מבוזרות באמצעות MetaMask, צריך להיות לך את'ר בארנק."
},
"needImportFile": { "needImportFile": {
"message": "יש לבחור קובץ לייצוא.", "message": "יש לבחור קובץ לייצוא.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

File diff suppressed because it is too large Load Diff

@ -84,18 +84,9 @@
"decimalsMustZerotoTen": { "decimalsMustZerotoTen": {
"message": "दशमलव कम स कम 0 हिए, और 36 स अधिक नहिए।" "message": "दशमलव कम स कम 0 हिए, और 36 स अधिक नहिए।"
}, },
"depositEther": {
"message": "जम - Ether"
},
"details": { "details": {
"message": "सश विवरण" "message": "सश विवरण"
}, },
"directDepositEther": {
"message": "स ईथर जम कर"
},
"directDepositEtherExplainer": {
"message": "यदि आपकस पहलछ ईथर ह, त जम अपन नए बटए म ईथर पत करन तर।"
},
"done": { "done": {
"message": "सपनन" "message": "सपनन"
}, },
@ -223,9 +214,6 @@
"myAccounts": { "myAccounts": {
"message": "म" "message": "म"
}, },
"needEtherInWallet": {
"message": "मक क उपयग करनित अनरयथ बतचत करनिए, आपक अपनट म ईथर क आवशयकत।"
},
"needImportFile": { "needImportFile": {
"message": "आयत करनिए आपक एक फइल क चयन करन।", "message": "आयत करनिए आपक एक फइल क चयन करन।",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Odbaci"
},
"QRHardwareWalletImporterTitle": {
"message": "Skeniraj kôd QR"
},
"about": { "about": {
"message": "O opcijama" "message": "O opcijama"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Trenutačni jezik" "message": "Trenutačni jezik"
}, },
"custom": {
"message": "Napredno"
},
"customGas": { "customGas": {
"message": "Prilagodi gorivo" "message": "Prilagodi gorivo"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Sigurno želite izbrisati ovu mrežu?" "message": "Sigurno želite izbrisati ovu mrežu?"
}, },
"depositEther": {
"message": "Položi Ether"
},
"details": { "details": {
"message": "Detalji" "message": "Detalji"
}, },
"directDepositEther": {
"message": "Izravan polog Ether"
},
"directDepositEtherExplainer": {
"message": "Ako imate nešto Ethera, najbrži je način prebacivanja Ethera u vaš novi novčanik izravan polog."
},
"done": { "done": {
"message": "Gotovo" "message": "Gotovo"
}, },
@ -526,6 +526,9 @@
"learnMore": { "learnMore": {
"message": "Saznajte više" "message": "Saznajte više"
}, },
"learnMoreUpperCase": {
"message": "Saznajte više"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Treba se koristiti zadnjim računom kako biste dodali novi račun." "message": "Treba se koristiti zadnjim računom kako biste dodali novi račun."
}, },
@ -577,9 +580,6 @@
"myAccounts": { "myAccounts": {
"message": "Moji računi" "message": "Moji računi"
}, },
"needEtherInWallet": {
"message": "Trebate Ether u svojem novčaniku kako biste ostvarili interakciju s decentraliziranim aplikacijama uporabom usluge MetaMask. "
},
"needImportFile": { "needImportFile": {
"message": "Morate odabrati datoteku za uvoz.", "message": "Morate odabrati datoteku za uvoz.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Rejte"
},
"QRHardwareWalletImporterTitle": {
"message": "Enspeksyon QR Kòd"
},
"accessingYourCamera": { "accessingYourCamera": {
"message": "Aksè a Kamera" "message": "Aksè a Kamera"
}, },
@ -153,18 +159,9 @@
"decimalsMustZerotoTen": { "decimalsMustZerotoTen": {
"message": "Desimal yo dwe omwen 0, epi pa dwe plis pase 36." "message": "Desimal yo dwe omwen 0, epi pa dwe plis pase 36."
}, },
"depositEther": {
"message": "Depo Ether"
},
"details": { "details": {
"message": "Detay yo" "message": "Detay yo"
}, },
"directDepositEther": {
"message": "Dirèkteman Depo Ether"
},
"directDepositEtherExplainer": {
"message": "Si ou deja gen kèk Ether, fason ki pi rapid yo ka resevwa Ether nan nouvo Wallet ou pa depo dirèk."
},
"done": { "done": {
"message": "Fini" "message": "Fini"
}, },
@ -307,6 +304,9 @@
"learnMore": { "learnMore": {
"message": "Aprann plis" "message": "Aprann plis"
}, },
"learnMoreUpperCase": {
"message": "Aprann plis"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Ou bezwen sèvi ak dènye kont ou anvan ou ka ajoute yon nouvo." "message": "Ou bezwen sèvi ak dènye kont ou anvan ou ka ajoute yon nouvo."
}, },
@ -346,9 +346,6 @@
"myAccounts": { "myAccounts": {
"message": "Kont mwen" "message": "Kont mwen"
}, },
"needEtherInWallet": {
"message": "Pou kominike avèk aplikasyon desantralize ou dwe itilize MetaMask, ou pral bezwen Ether nan Wallet ou."
},
"needImportFile": { "needImportFile": {
"message": "Ou dwe chwazi yon dosye pou enpòte.", "message": "Ou dwe chwazi yon dosye pou enpòte.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Elutasítás"
},
"QRHardwareWalletImporterTitle": {
"message": "QR-kód beolvasása"
},
"about": { "about": {
"message": "Névjegy" "message": "Névjegy"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Aktuális nyelv" "message": "Aktuális nyelv"
}, },
"custom": {
"message": "Speciális"
},
"customGas": { "customGas": {
"message": "Gáz testreszabása" "message": "Gáz testreszabása"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Biztosan törli ezt a hálózatot?" "message": "Biztosan törli ezt a hálózatot?"
}, },
"depositEther": {
"message": "Ether befizetése"
},
"details": { "details": {
"message": "Részletek" "message": "Részletek"
}, },
"directDepositEther": {
"message": "Fizess be ethert közvetlenül"
},
"directDepositEtherExplainer": {
"message": "Amennyiben már rendelkezik némi Ether-rel, a közvetlen letéttel gyorsan elhelyezheti azt új pénztárcájában."
},
"done": { "done": {
"message": "Kész" "message": "Kész"
}, },
@ -526,6 +526,9 @@
"learnMore": { "learnMore": {
"message": "Tudjon meg többet" "message": "Tudjon meg többet"
}, },
"learnMoreUpperCase": {
"message": "Tudjon meg többet"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Használnia kell a korábbi fiókját, mielőtt újat adhat hozzá. " "message": "Használnia kell a korábbi fiókját, mielőtt újat adhat hozzá. "
}, },
@ -577,9 +580,6 @@
"myAccounts": { "myAccounts": {
"message": "Fiókjaim" "message": "Fiókjaim"
}, },
"needEtherInWallet": {
"message": "Ha a MetaMaskon keresztül szeretne interakcióba lépni decentralizált alkalmazással, ahhoz a tárcájában Ethernek kell lennie."
},
"needImportFile": { "needImportFile": {
"message": "Ki kell választania az importálni kívánt fájlt.", "message": "Ki kell választania az importálni kívánt fájlt.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

File diff suppressed because it is too large Load Diff

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Annulla"
},
"QRHardwareWalletImporterTitle": {
"message": "Scansiona Codice QR"
},
"about": { "about": {
"message": "Informazioni" "message": "Informazioni"
}, },
@ -19,9 +25,6 @@
"accessingYourCamera": { "accessingYourCamera": {
"message": "Accesso alla fotocamera..." "message": "Accesso alla fotocamera..."
}, },
"account": {
"message": "Account"
},
"accountDetails": { "accountDetails": {
"message": "Dettagli Account" "message": "Dettagli Account"
}, },
@ -145,9 +148,6 @@
"approved": { "approved": {
"message": "Approvato" "message": "Approvato"
}, },
"asset": {
"message": "Asset"
},
"assets": { "assets": {
"message": "Patrimonio" "message": "Patrimonio"
}, },
@ -221,9 +221,6 @@
"buyWithWyreDescription": { "buyWithWyreDescription": {
"message": "Wyre ti consente di usare la carta di credito per depositare ETH direttamente nel tuo account MetaMask." "message": "Wyre ti consente di usare la carta di credito per depositare ETH direttamente nel tuo account MetaMask."
}, },
"bytes": {
"message": "Bytes"
},
"canToggleInSettings": { "canToggleInSettings": {
"message": "Puoi riabilitare questa notifica in Impostazioni -> Avvisi." "message": "Puoi riabilitare questa notifica in Impostazioni -> Avvisi."
}, },
@ -236,9 +233,6 @@
"cancelled": { "cancelled": {
"message": "Annullata" "message": "Annullata"
}, },
"chainId": {
"message": "Chain ID"
},
"chromeRequiredForHardwareWallets": { "chromeRequiredForHardwareWallets": {
"message": "Devi usare MetaMask con Google Chrome per connettere il tuo Portafoglio Hardware" "message": "Devi usare MetaMask con Google Chrome per connettere il tuo Portafoglio Hardware"
}, },
@ -400,6 +394,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Lingua Corrente" "message": "Lingua Corrente"
}, },
"custom": {
"message": "Avanzate"
},
"customGas": { "customGas": {
"message": "Personalizza Gas" "message": "Personalizza Gas"
}, },
@ -453,18 +450,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Sei sicuro di voler eliminare questa rete?" "message": "Sei sicuro di voler eliminare questa rete?"
}, },
"depositEther": {
"message": "Deposita Ether"
},
"details": { "details": {
"message": "Dettagli" "message": "Dettagli"
}, },
"directDepositEther": {
"message": "Deposita Direttamente Ether"
},
"directDepositEtherExplainer": {
"message": "Se possiedi già degli Ether, questa è la via più veloce per aggiungere Ether al tuo portafoglio con un deposito diretto."
},
"disconnect": { "disconnect": {
"message": "Disconnetti" "message": "Disconnetti"
}, },
@ -586,10 +574,6 @@
"message": "MetaMask ha riscontrato un errore", "message": "MetaMask ha riscontrato un errore",
"description": "Title of generic error page" "description": "Title of generic error page"
}, },
"errorStack": {
"message": "Stack:",
"description": "Title for error stack, which is displayed for debugging purposes"
},
"estimatedProcessingTimes": { "estimatedProcessingTimes": {
"message": "Tempi di Elaborazione Stimati" "message": "Tempi di Elaborazione Stimati"
}, },
@ -600,9 +584,6 @@
"ethereumPublicAddress": { "ethereumPublicAddress": {
"message": "Indirizzo pubblico Ethereum " "message": "Indirizzo pubblico Ethereum "
}, },
"etherscan": {
"message": "Etherscan"
},
"etherscanView": { "etherscanView": {
"message": "Vedi account su Etherscan" "message": "Vedi account su Etherscan"
}, },
@ -858,6 +839,9 @@
"learnMore": { "learnMore": {
"message": "Scopri di più" "message": "Scopri di più"
}, },
"learnMoreUpperCase": {
"message": "Scopri di più"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "E' necessario utilizzare l'ultimo account prima di poterne aggiungere uno nuovo." "message": "E' necessario utilizzare l'ultimo account prima di poterne aggiungere uno nuovo."
}, },
@ -879,9 +863,6 @@
"loadingTokens": { "loadingTokens": {
"message": "Caricamento Tokens..." "message": "Caricamento Tokens..."
}, },
"localhost": {
"message": "Localhost 8545"
},
"lock": { "lock": {
"message": "Disconnetti" "message": "Disconnetti"
}, },
@ -958,9 +939,6 @@
"myAccounts": { "myAccounts": {
"message": "Miei Account" "message": "Miei Account"
}, },
"needEtherInWallet": {
"message": "Per interagire con applicazioni decentralizzate con MetaMask, devi possedere Ether nel tuo portafoglio."
},
"needImportFile": { "needImportFile": {
"message": "Devi selezionare un file da importare.", "message": "Devi selezionare un file da importare.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"
@ -989,10 +967,6 @@
"newAccountDetectedDialogMessage": { "newAccountDetectedDialogMessage": {
"message": "Rilevato un nuovo indirizzo! Clicca qui per aggiungerlo alla tua rubrica." "message": "Rilevato un nuovo indirizzo! Clicca qui per aggiungerlo alla tua rubrica."
}, },
"newAccountNumberName": {
"message": "Account $1",
"description": "Default name of next account to be created on create account screen"
},
"newContact": { "newContact": {
"message": "Nuovo contatto" "message": "Nuovo contatto"
}, },
@ -1060,18 +1034,9 @@
"ofTextNofM": { "ofTextNofM": {
"message": "di" "message": "di"
}, },
"off": {
"message": "Off"
},
"offlineForMaintenance": { "offlineForMaintenance": {
"message": "Offline per manutenzione" "message": "Offline per manutenzione"
}, },
"ok": {
"message": "Ok"
},
"on": {
"message": "On"
},
"onboardingReturnNotice": { "onboardingReturnNotice": {
"message": "\"$1\" chiuderà questa tab e ritornerà a $2", "message": "\"$1\" chiuderà questa tab e ritornerà a $2",
"description": "Return the user to the site that initiated onboarding" "description": "Return the user to the site that initiated onboarding"
@ -1094,9 +1059,6 @@
"participateInMetaMetricsDescription": { "participateInMetaMetricsDescription": {
"message": "Participa in MetaMetrics per aiutarci a rendere MetaMask migliore" "message": "Participa in MetaMetrics per aiutarci a rendere MetaMask migliore"
}, },
"password": {
"message": "Password"
},
"passwordNotLongEnough": { "passwordNotLongEnough": {
"message": "Password non abbastanza lunga" "message": "Password non abbastanza lunga"
}, },
@ -1218,9 +1180,6 @@
"message": "È stato trovato un backup dei tuoi dati da $1. Vuoi ripristinare le preferenze del portafoglio?", "message": "È stato trovato un backup dei tuoi dati da $1. Vuoi ripristinare le preferenze del portafoglio?",
"description": "$1 is the date at which the data was backed up" "description": "$1 is the date at which the data was backed up"
}, },
"retryTransaction": {
"message": "Retry Transaction"
},
"reusedTokenNameWarning": { "reusedTokenNameWarning": {
"message": "Un token usa un simbolo già usato da un altro token, ciò può confondere o ingannare." "message": "Un token usa un simbolo già usato da un altro token, ciò può confondere o ingannare."
}, },
@ -1384,9 +1343,6 @@
"signatureRequest": { "signatureRequest": {
"message": "Firma Richiesta" "message": "Firma Richiesta"
}, },
"signatureRequest1": {
"message": "Message"
},
"signed": { "signed": {
"message": "Firmata" "message": "Firmata"
}, },
@ -1647,9 +1603,6 @@
"message": "$1 $2 disponibili allo scambio", "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" "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": { "swapsAdvancedOptions": {
"message": "Impostazioni Avanzate" "message": "Impostazioni Avanzate"
}, },
@ -1730,9 +1683,6 @@
"message": "A: $1", "message": "A: $1",
"description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress"
}, },
"token": {
"message": "Token"
},
"tokenAlreadyAdded": { "tokenAlreadyAdded": {
"message": "Il token è già stato aggiunto." "message": "Il token è già stato aggiunto."
}, },

File diff suppressed because it is too large Load Diff

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "ತಿರಸಕರಿಿ"
},
"QRHardwareWalletImporterTitle": {
"message": "QR ಕಿ"
},
"about": { "about": {
"message": "ಕಿ" "message": "ಕಿ"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "ಪರಸತ ಭ" "message": "ಪರಸತ ಭ"
}, },
"custom": {
"message": "ಸಿತ"
},
"customGas": { "customGas": {
"message": "ಗ ಕಸಟಮಿ" "message": "ಗ ಕಸಟಮಿ"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "ನ ಈ ನವರ ಅನ ಖಚಿತವಿ ಅಳಿಸಲ ಬಯಸ?" "message": "ನ ಈ ನವರ ಅನ ಖಚಿತವಿ ಅಳಿಸಲ ಬಯಸ?"
}, },
"depositEther": {
"message": "ಎಥರವಣಿಿ"
},
"details": { "details": {
"message": "ವಿವರಗಳ" "message": "ವಿವರಗಳ"
}, },
"directDepositEther": {
"message": "ಎಥರರವಿವಣಿಿ"
},
"directDepositEtherExplainer": {
"message": "ನ ಈಗಗಲಲವ ಎಥರಿದರ, ನರ ಠವಣಿಲಕ ನಿಮ ಹಸ ವನಲಿ ಎಥರ ಅನ ಪಡವ ತವರಿತ ಮಗ."
},
"done": { "done": {
"message": "ಮಿಿ" "message": "ಮಿಿ"
}, },
@ -530,6 +530,9 @@
"learnMore": { "learnMore": {
"message": "ಇನನಷಿಿಿಿ" "message": "ಇನನಷಿಿಿಿ"
}, },
"learnMoreUpperCase": {
"message": "ಇನನಷಿಿಿಿ"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "ನಸದನಿದರ ಮದಲಿಮ ಹಿಿನ ಖಯನ ಬಳಸಬ." "message": "ನಸದನಿದರ ಮದಲಿಮ ಹಿಿನ ಖಯನ ಬಳಸಬ."
}, },
@ -584,9 +587,6 @@
"myAccounts": { "myAccounts": {
"message": "ನನನ ಖಗಳ" "message": "ನನನ ಖಗಳ"
}, },
"needEtherInWallet": {
"message": "MetaMask ಬಳಸಿಿತ ಖಗಳಿವಹನ ನಡಸಲ, ನಿಮ ವನಲಿಿಮಗ ಎಥರ ಅಗತಯವಿ."
},
"needImportFile": { "needImportFile": {
"message": "ಆಮದಡಲ ಅನ ಆಯಡಬ.", "message": "ಆಮದಡಲ ಅನ ಆಯಡಬ.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

File diff suppressed because it is too large Load Diff

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Atmesti"
},
"QRHardwareWalletImporterTitle": {
"message": "Nuskaityti QR kodą"
},
"about": { "about": {
"message": "Apie" "message": "Apie"
}, },
@ -67,7 +73,7 @@
"description": "The description of the application" "description": "The description of the application"
}, },
"appName": { "appName": {
"message": "MetaMask", "message": "MetaMask",
"description": "The name of the application" "description": "The name of the application"
}, },
"appNameBeta": { "appNameBeta": {
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Dabartinė kalba" "message": "Dabartinė kalba"
}, },
"custom": {
"message": "Išplėstiniai"
},
"customGas": { "customGas": {
"message": "Pritaikyti dujas" "message": "Pritaikyti dujas"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Ar tikrai norite panaikinti šį tinklą?" "message": "Ar tikrai norite panaikinti šį tinklą?"
}, },
"depositEther": {
"message": "Įnešti eterių"
},
"details": { "details": {
"message": "Išsami informacija" "message": "Išsami informacija"
}, },
"directDepositEther": {
"message": "Tiesiogiai įnešti eteriai"
},
"directDepositEtherExplainer": {
"message": "Jeigu jau turite šiek tiek eterių, sparčiausias būdas gauti eterių į naują piniginę yra tiesioginis įnašas."
},
"done": { "done": {
"message": "Atlikta" "message": "Atlikta"
}, },
@ -530,6 +530,9 @@
"learnMore": { "learnMore": {
"message": "Sužinokite daugiau" "message": "Sužinokite daugiau"
}, },
"learnMoreUpperCase": {
"message": "Sužinokite daugiau"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Prieš įtraukdami naują, turite pasinaudoti paskutine paskyra." "message": "Prieš įtraukdami naują, turite pasinaudoti paskutine paskyra."
}, },
@ -584,9 +587,6 @@
"myAccounts": { "myAccounts": {
"message": "Mano paskyros" "message": "Mano paskyros"
}, },
"needEtherInWallet": {
"message": "Norėdami dirbti su decentralizuotomis programomis „MetaMask“, savo piniginėje turite turėti eterių."
},
"needImportFile": { "needImportFile": {
"message": "Turite pasirinkti failą, kurį pageidaujate importuoti.", "message": "Turite pasirinkti failą, kurį pageidaujate importuoti.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Noraidīt"
},
"QRHardwareWalletImporterTitle": {
"message": "Ieskenēt QR kodu"
},
"about": { "about": {
"message": "Par" "message": "Par"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Pašreizējā valodā" "message": "Pašreizējā valodā"
}, },
"custom": {
"message": "Papildu"
},
"customGas": { "customGas": {
"message": "Pielāgot Gas" "message": "Pielāgot Gas"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Vai tiešām vēlaties dzēst šo tīklu?" "message": "Vai tiešām vēlaties dzēst šo tīklu?"
}, },
"depositEther": {
"message": "Noguldīt Ether"
},
"details": { "details": {
"message": "Informācija" "message": "Informācija"
}, },
"directDepositEther": {
"message": "Tiešā Ether iemaksa"
},
"directDepositEtherExplainer": {
"message": "Ja jums jau ir Ether, tad visātrāk Ether savā makā varat saņemt ar tiešo iemaksu."
},
"done": { "done": {
"message": "Pabeigts" "message": "Pabeigts"
}, },
@ -526,6 +526,9 @@
"learnMore": { "learnMore": {
"message": "Uzzināt vairāk" "message": "Uzzināt vairāk"
}, },
"learnMoreUpperCase": {
"message": "Uzzināt vairāk"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Jums jāizmanto pēdējais konts pirms varat pievienot jaunu." "message": "Jums jāizmanto pēdējais konts pirms varat pievienot jaunu."
}, },
@ -580,9 +583,6 @@
"myAccounts": { "myAccounts": {
"message": "Mani konti" "message": "Mani konti"
}, },
"needEtherInWallet": {
"message": "Lai izmantotu decentralizētas lietotnes ar MetaMask, jūsu makā jābūt Ether."
},
"needImportFile": { "needImportFile": {
"message": "Jums jāatlasa fails, ko importēt", "message": "Jums jāatlasa fails, ko importēt",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,7 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "നിരസിക"
},
"about": { "about": {
"message": "വിവര" "message": "വിവര"
}, },
@ -44,6 +47,9 @@
"create": { "create": {
"message": "സിക" "message": "സിക"
}, },
"custom": {
"message": "നതന"
},
"delete": { "delete": {
"message": "ഇലക" "message": "ഇലക"
}, },

@ -1,4 +1,7 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "न"
},
"about": { "about": {
"message": "बददल" "message": "बददल"
}, },
@ -44,6 +47,9 @@
"create": { "create": {
"message": "तयर कर" "message": "तयर कर"
}, },
"custom": {
"message": "परगत"
},
"delete": { "delete": {
"message": "हटव" "message": "हटव"
}, },

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Tolak"
},
"QRHardwareWalletImporterTitle": {
"message": "Imbas Kod QR"
},
"about": { "about": {
"message": "Mengenai" "message": "Mengenai"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Bahasa Semasa" "message": "Bahasa Semasa"
}, },
"custom": {
"message": "Lanjutan"
},
"customGas": { "customGas": {
"message": "Suaikan Gas" "message": "Suaikan Gas"
}, },
@ -286,12 +295,6 @@
"details": { "details": {
"message": "Butiran" "message": "Butiran"
}, },
"directDepositEther": {
"message": "Deposit Ether Secara Terus"
},
"directDepositEtherExplainer": {
"message": "Jika anda sudah mempunyai Ether, cara paling cepat untuk mendapatkan Ether di dompet baru anda ialah dengan deposit langsung."
},
"done": { "done": {
"message": "Selesai" "message": "Selesai"
}, },
@ -516,6 +519,9 @@
"learnMore": { "learnMore": {
"message": "Maklumat lanjut" "message": "Maklumat lanjut"
}, },
"learnMoreUpperCase": {
"message": "Maklumat lanjut"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Anda perlu menggunakan akaun terakhir anda sebelum anda boleh menambah yang baru." "message": "Anda perlu menggunakan akaun terakhir anda sebelum anda boleh menambah yang baru."
}, },
@ -564,9 +570,6 @@
"myAccounts": { "myAccounts": {
"message": "Akaun Saya" "message": "Akaun Saya"
}, },
"needEtherInWallet": {
"message": "Untuk berinteraksi dengan aplikasi ternyahpusat menggunakan MetaMask, anda memerlukan Ether di dalam dompet anda."
},
"needImportFile": { "needImportFile": {
"message": "Anda mesti pilih fail untuk diimport.", "message": "Anda mesti pilih fail untuk diimport.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,7 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Afwijzen"
},
"accountDetails": { "accountDetails": {
"message": "Accountgegevens" "message": "Accountgegevens"
}, },
@ -81,15 +84,6 @@
"decimalsMustZerotoTen": { "decimalsMustZerotoTen": {
"message": "Decimalen moeten minimaal 0 en niet meer dan 36 zijn." "message": "Decimalen moeten minimaal 0 en niet meer dan 36 zijn."
}, },
"depositEther": {
"message": "Stort Ether"
},
"directDepositEther": {
"message": "Directe Ether storten"
},
"directDepositEtherExplainer": {
"message": "Als je al wat Ether hebt, de snelste manier om Ether in je nieuwe portemonnee te krijgen door een directe storting."
},
"done": { "done": {
"message": "Gedaan" "message": "Gedaan"
}, },
@ -214,9 +208,6 @@
"myAccounts": { "myAccounts": {
"message": "Mijn accounts" "message": "Mijn accounts"
}, },
"needEtherInWallet": {
"message": "Om te communiceren met gedecentraliseerde applicaties met MetaMask, heb je Ether nodig in je portemonnee."
},
"needImportFile": { "needImportFile": {
"message": "U moet een bestand selecteren om te importeren.", "message": "U moet een bestand selecteren om te importeren.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Avslå"
},
"QRHardwareWalletImporterTitle": {
"message": "Skann QR-kode"
},
"about": { "about": {
"message": "Info" "message": "Info"
}, },
@ -253,6 +259,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Nåværende språk " "message": "Nåværende språk "
}, },
"custom": {
"message": "Avansert"
},
"customGas": { "customGas": {
"message": "Tilpass Gass" "message": "Tilpass Gass"
}, },
@ -280,18 +289,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Er du sikker på at du vil slette dette nettverket?" "message": "Er du sikker på at du vil slette dette nettverket?"
}, },
"depositEther": {
"message": "Sett inn Ether "
},
"details": { "details": {
"message": "Detaljer" "message": "Detaljer"
}, },
"directDepositEther": {
"message": "Sett Ether direkte inn"
},
"directDepositEtherExplainer": {
"message": "Hvis du allerede har noe Ether, er den raskeste måten å få Ether i den nye lommeboken din på ved hjelp av direkte innskudd."
},
"done": { "done": {
"message": "Ferdig" "message": "Ferdig"
}, },
@ -517,6 +517,9 @@
"learnMore": { "learnMore": {
"message": "Lær mer" "message": "Lær mer"
}, },
"learnMoreUpperCase": {
"message": "Lær mer"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Du må bruke den siste kontoen din før du kan legge til en ny." "message": "Du må bruke den siste kontoen din før du kan legge til en ny."
}, },
@ -571,9 +574,6 @@
"myAccounts": { "myAccounts": {
"message": "Mine kontoer " "message": "Mine kontoer "
}, },
"needEtherInWallet": {
"message": "Du må ha Ether i lommeboken din for å samhandle med desentraliserte applikasjoner gjennom MateMask."
},
"needImportFile": { "needImportFile": {
"message": "Du må velge en fil å importere.", "message": "Du må velge en fil å importere.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -519,18 +519,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Sigurado ka bang gusto mong i-delete ang network na ito?" "message": "Sigurado ka bang gusto mong i-delete ang network na ito?"
}, },
"depositEther": {
"message": "Mag-deposit ng Ether"
},
"details": { "details": {
"message": "Mga Detalye" "message": "Mga Detalye"
}, },
"directDepositEther": {
"message": "Direktang Mag-deposit ng Ether"
},
"directDepositEtherExplainer": {
"message": "Kung mayroon ka nang ilang Ether, ang pinakamabilis na paraan para makakuha ng Ether sa bago mong wallet ay sa pamamagitan ng direktang pag-deposit."
},
"disconnect": { "disconnect": {
"message": "Idiskonekta" "message": "Idiskonekta"
}, },
@ -1116,9 +1107,6 @@
"name": { "name": {
"message": "Pangalan" "message": "Pangalan"
}, },
"needEtherInWallet": {
"message": "Para makaugnayan ang mga decentralized na application gamit ang MetaMask, kakailanganin mo ang Ether sa iyong wallet."
},
"needHelp": { "needHelp": {
"message": "Kailangan ng tulong? Makipag-ugnayan sa $1", "message": "Kailangan ng tulong? Makipag-ugnayan sa $1",
"description": "$1 represents `needHelpLinkText`, the text which goes in the help link" "description": "$1 represents `needHelpLinkText`, the text which goes in the help link"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Odrzuć"
},
"QRHardwareWalletImporterTitle": {
"message": "Skanuj kod QR"
},
"about": { "about": {
"message": "Informacje" "message": "Informacje"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Obecny język" "message": "Obecny język"
}, },
"custom": {
"message": "Zaawansowane"
},
"customGas": { "customGas": {
"message": "Ustaw gaz" "message": "Ustaw gaz"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Czy na pewno chcesz usunąć tę sieć?" "message": "Czy na pewno chcesz usunąć tę sieć?"
}, },
"depositEther": {
"message": "Zdeponuj Eter"
},
"details": { "details": {
"message": "Szczegóły" "message": "Szczegóły"
}, },
"directDepositEther": {
"message": "Zdeponuj Eter bezpośrednio"
},
"directDepositEtherExplainer": {
"message": "Jeśli już masz Eter, najszybciej umieścisz go w swoim nowym portfelu przy pomocy bezpośredniego depozytu."
},
"done": { "done": {
"message": "Gotowe" "message": "Gotowe"
}, },
@ -530,6 +530,9 @@
"learnMore": { "learnMore": {
"message": "Dowiedz się więcej" "message": "Dowiedz się więcej"
}, },
"learnMoreUpperCase": {
"message": "Dowiedz się więcej"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Musisz użyć swojego poprzedniego konta zanim dodasz kolejne." "message": "Musisz użyć swojego poprzedniego konta zanim dodasz kolejne."
}, },
@ -581,9 +584,6 @@
"myAccounts": { "myAccounts": {
"message": "Moje konta" "message": "Moje konta"
}, },
"needEtherInWallet": {
"message": "Żeby skorzystać ze zdecentraliowanych aplikacji (dApps) przy pomocy MetaMask, potrzebujesz Eteru w swoim portfelu."
},
"needImportFile": { "needImportFile": {
"message": "Musisz wybrać plik do zaimportowania.", "message": "Musisz wybrać plik do zaimportowania.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -84,18 +84,9 @@
"decimalsMustZerotoTen": { "decimalsMustZerotoTen": {
"message": "Decimais devem ser no mínimo 0 e não passar de 36." "message": "Decimais devem ser no mínimo 0 e não passar de 36."
}, },
"depositEther": {
"message": "Depositar Ether"
},
"details": { "details": {
"message": "Detalhes" "message": "Detalhes"
}, },
"directDepositEther": {
"message": "Depositar Diretamente Ether"
},
"directDepositEtherExplainer": {
"message": "Se já tem Ether, a forma mais rápida de ficar com Ether na sua carteira é através de depósito direto."
},
"done": { "done": {
"message": "Finalizado" "message": "Finalizado"
}, },
@ -220,9 +211,6 @@
"myAccounts": { "myAccounts": {
"message": "As minhas contas" "message": "As minhas contas"
}, },
"needEtherInWallet": {
"message": "Para interagir com applicações descentralizadas usando MetaMask tem de ter Ether na sua carteira."
},
"needImportFile": { "needImportFile": {
"message": "Deve selecionar um ficheiro para importar.", "message": "Deve selecionar um ficheiro para importar.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,7 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Rejeitar"
},
"about": { "about": {
"message": "Sobre" "message": "Sobre"
}, },
@ -251,6 +254,9 @@
"buildContactList": { "buildContactList": {
"message": "Crie sua lista de contatos" "message": "Crie sua lista de contatos"
}, },
"builtAroundTheWorld": {
"message": "MetaMask é projetado e construído em todo o mundo.."
},
"buy": { "buy": {
"message": "Comprar" "message": "Comprar"
}, },
@ -260,9 +266,6 @@
"buyWithWyreDescription": { "buyWithWyreDescription": {
"message": "Com o Wyre, você pode usar um cartão de débito para depositar ETH diretamente na sua conta do MetaMask." "message": "Com o Wyre, você pode usar um cartão de débito para depositar ETH diretamente na sua conta do MetaMask."
}, },
"bytes": {
"message": "Bytes"
},
"canToggleInSettings": { "canToggleInSettings": {
"message": "Você pode reabilitar essa notificação em Configurações -> Alertas." "message": "Você pode reabilitar essa notificação em Configurações -> Alertas."
}, },
@ -519,17 +522,12 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Tem certeza de que deseja excluir esta rede?" "message": "Tem certeza de que deseja excluir esta rede?"
}, },
"depositEther": {
"message": "Depositar ether"
},
"details": { "details": {
"message": "Detalhes" "message": "Detalhes"
}, },
"directDepositEther": { "disabledGasOptionToolTipMessage": {
"message": "Depositar ether diretamente" "message": "“$1” está desativado porque não satisfaz o aumento mínimo de 10% em relação à taxa de gás original.",
}, "description": "$1 is gas estimate type which can be market or aggressive"
"directDepositEtherExplainer": {
"message": "Se você já tiver alguns ethers, a forma mais rápida de colocar ethers na sua nova carteira é por depósito direto."
}, },
"disconnect": { "disconnect": {
"message": "Desconectar" "message": "Desconectar"
@ -679,10 +677,6 @@
"message": "O MetaMask encontrou um erro", "message": "O MetaMask encontrou um erro",
"description": "Title of generic error page" "description": "Title of generic error page"
}, },
"errorStack": {
"message": "Stack:",
"description": "Title for error stack, which is displayed for debugging purposes"
},
"estimatedProcessingTimes": { "estimatedProcessingTimes": {
"message": "Tempo estimado de processamento" "message": "Tempo estimado de processamento"
}, },
@ -696,9 +690,6 @@
"ethereumPublicAddress": { "ethereumPublicAddress": {
"message": "Endereço público do Ethereum" "message": "Endereço público do Ethereum"
}, },
"etherscan": {
"message": "Etherscan"
},
"etherscanView": { "etherscanView": {
"message": "Exibir conta no Etherscan" "message": "Exibir conta no Etherscan"
}, },
@ -761,7 +752,7 @@
"message": "Tipo de função" "message": "Tipo de função"
}, },
"gasLimit": { "gasLimit": {
"message": "Gas Limit" "message": "Limite de Gas"
}, },
"gasLimitInfoTooltipContent": { "gasLimitInfoTooltipContent": {
"message": "O Gas Limit é o valor máximo das unidades de gas que você está disposto a gastar." "message": "O Gas Limit é o valor máximo das unidades de gas que você está disposto a gastar."
@ -774,7 +765,7 @@
"description": "$1 is the custom gas limit, in decimal." "description": "$1 is the custom gas limit, in decimal."
}, },
"gasPrice": { "gasPrice": {
"message": "Gas Price (GWEI)" "message": "Preço Gas (GWEI)"
}, },
"gasPriceExcessive": { "gasPriceExcessive": {
"message": "Sua taxa de gas é desnecessariamente alta. Considere reduzir o valor." "message": "Sua taxa de gas é desnecessariamente alta. Considere reduzir o valor."
@ -824,9 +815,6 @@
"happyToSeeYou": { "happyToSeeYou": {
"message": "Ficamos felizes em ver você." "message": "Ficamos felizes em ver você."
}, },
"hardware": {
"message": "Hardware"
},
"hardwareWalletConnected": { "hardwareWalletConnected": {
"message": "Carteira de hardware conectada" "message": "Carteira de hardware conectada"
}, },
@ -1011,9 +999,6 @@
"likeToImportTokens": { "likeToImportTokens": {
"message": "Você gostaria de adicionar esses tokens?" "message": "Você gostaria de adicionar esses tokens?"
}, },
"links": {
"message": "Links"
},
"loadMore": { "loadMore": {
"message": "Carregar mais" "message": "Carregar mais"
}, },
@ -1023,9 +1008,6 @@
"loadingTokens": { "loadingTokens": {
"message": "Carregando tokens..." "message": "Carregando tokens..."
}, },
"localhost": {
"message": "Localhost 8545"
},
"lock": { "lock": {
"message": "Bloquear" "message": "Bloquear"
}, },
@ -1116,9 +1098,6 @@
"name": { "name": {
"message": "Nome" "message": "Nome"
}, },
"needEtherInWallet": {
"message": "Para interagir com aplicativos descentralizados usando o MetaMask, você precisará de ethers na sua carteira."
},
"needHelp": { "needHelp": {
"message": "Precisa de ajuda? Contato $1", "message": "Precisa de ajuda? Contato $1",
"description": "$1 represents `needHelpLinkText`, the text which goes in the help link" "description": "$1 represents `needHelpLinkText`, the text which goes in the help link"
@ -1139,18 +1118,9 @@
"networkName": { "networkName": {
"message": "Nome da rede" "message": "Nome da rede"
}, },
"networkNameBSC": {
"message": "BSC"
},
"networkNameDefinition": { "networkNameDefinition": {
"message": "O nome associado com esta rede." "message": "O nome associado com esta rede."
}, },
"networkNameEthereum": {
"message": "Ethereum"
},
"networkNameTestnet": {
"message": "Testnet"
},
"networkSettingsChainIdDescription": { "networkSettingsChainIdDescription": {
"message": "O ID da chain é usado para assinar transações. É preciso ser igual ao ID da chain retornado pela rede. Você pode informar um número decimal ou um número hexadecimal com prefixo “0x”, mas exibiremos o número em casas decimais." "message": "O ID da chain é usado para assinar transações. É preciso ser igual ao ID da chain retornado pela rede. Você pode informar um número decimal ou um número hexadecimal com prefixo “0x”, mas exibiremos o número em casas decimais."
}, },
@ -1228,9 +1198,6 @@
"noWebcamFoundTitle": { "noWebcamFoundTitle": {
"message": "Câmera não encontrada" "message": "Câmera não encontrada"
}, },
"nonce": {
"message": "Nonce"
},
"nonceField": { "nonceField": {
"message": "Personalizar nonce da transação" "message": "Personalizar nonce da transação"
}, },
@ -1788,9 +1755,6 @@
"supportCenter": { "supportCenter": {
"message": "Visite nossa Central de Suporte" "message": "Visite nossa Central de Suporte"
}, },
"swap": {
"message": "Swap"
},
"swapAdvancedSlippageInfo": { "swapAdvancedSlippageInfo": {
"message": "Quando o preço varia entre o momento em que seu pedido é feito e o momento em que é confirmado, isso recebe o nome de “slippage”. Seu swap será automaticamente cancelado se o slippage for superior à configuração “slippage máximo”." "message": "Quando o preço varia entre o momento em que seu pedido é feito e o momento em que é confirmado, isso recebe o nome de “slippage”. Seu swap será automaticamente cancelado se o slippage for superior à configuração “slippage máximo”."
}, },
@ -2128,9 +2092,6 @@
"message": "Até: $1", "message": "Até: $1",
"description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress"
}, },
"token": {
"message": "Token"
},
"tokenAlreadyAdded": { "tokenAlreadyAdded": {
"message": "O token já foi adicionado." "message": "O token já foi adicionado."
}, },
@ -2146,9 +2107,6 @@
"tooltipApproveButton": { "tooltipApproveButton": {
"message": "Eu entendo" "message": "Eu entendo"
}, },
"total": {
"message": "Total"
},
"transaction": { "transaction": {
"message": "transação" "message": "transação"
}, },

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Respingeți"
},
"QRHardwareWalletImporterTitle": {
"message": "Scanați codul QR"
},
"about": { "about": {
"message": "Despre" "message": "Despre"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Limba actuală" "message": "Limba actuală"
}, },
"custom": {
"message": "Avansate"
},
"customGas": { "customGas": {
"message": "Particularizați Gas" "message": "Particularizați Gas"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Sigur vreți să ștergeți această rețea?" "message": "Sigur vreți să ștergeți această rețea?"
}, },
"depositEther": {
"message": "Depuneți Ether"
},
"details": { "details": {
"message": "Detalii" "message": "Detalii"
}, },
"directDepositEther": {
"message": "Depuneți direct Ether"
},
"directDepositEtherExplainer": {
"message": "Dacă deja aveți Ether, cel mai rapid mod de a avea Ether în portofelul nou prin depunere directă."
},
"done": { "done": {
"message": "Efectuat" "message": "Efectuat"
}, },
@ -520,6 +520,9 @@
"learnMore": { "learnMore": {
"message": "Aflați mai multe" "message": "Aflați mai multe"
}, },
"learnMoreUpperCase": {
"message": "Aflați mai multe"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Trebuie să folosiți ultimul cont înainte să adăugați altul." "message": "Trebuie să folosiți ultimul cont înainte să adăugați altul."
}, },
@ -571,9 +574,6 @@
"myAccounts": { "myAccounts": {
"message": "Conturile mele" "message": "Conturile mele"
}, },
"needEtherInWallet": {
"message": "Pentru a interacționa cu aplicațiile descentralizate prin intermediul MetaMask, trebuie să aveți Ether în portofel."
},
"needImportFile": { "needImportFile": {
"message": "Trebuie să selectați un fișier pentru importare.", "message": "Trebuie să selectați un fișier pentru importare.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

File diff suppressed because it is too large Load Diff

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Odmítnout"
},
"QRHardwareWalletImporterTitle": {
"message": "Skenovať QR kód"
},
"about": { "about": {
"message": "Informácie" "message": "Informácie"
}, },
@ -250,6 +256,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Aktuálny jazyk" "message": "Aktuálny jazyk"
}, },
"custom": {
"message": "Rozšírené"
},
"customGas": { "customGas": {
"message": "Nastavit palivo" "message": "Nastavit palivo"
}, },
@ -277,18 +286,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Naozaj chcete túto sieť odstrániť?" "message": "Naozaj chcete túto sieť odstrániť?"
}, },
"depositEther": {
"message": "Vložit Ether"
},
"details": { "details": {
"message": "Podrobnosti" "message": "Podrobnosti"
}, },
"directDepositEther": {
"message": "Vložit Ether přímo"
},
"directDepositEtherExplainer": {
"message": "Pokud už vlastníte nějaký Ether, nejrychleji ho dostanete do peněženky přímým vkladem."
},
"done": { "done": {
"message": "Hotovo" "message": "Hotovo"
}, },
@ -514,6 +514,9 @@
"learnMore": { "learnMore": {
"message": "Zjistěte více." "message": "Zjistěte více."
}, },
"learnMoreUpperCase": {
"message": "Zjistěte více."
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Skôr ako budete môcť pridať nový účet, musíte použiť svoj posledný účet." "message": "Skôr ako budete môcť pridať nový účet, musíte použiť svoj posledný účet."
}, },
@ -556,9 +559,6 @@
"myAccounts": { "myAccounts": {
"message": "Moje účty" "message": "Moje účty"
}, },
"needEtherInWallet": {
"message": "Potřebujete Ether v peněžence, abyste mohli pomocí MetaMasku interagovat s decentralizovanými aplikacemi."
},
"needImportFile": { "needImportFile": {
"message": "Musíte zvolit soubor k importu.", "message": "Musíte zvolit soubor k importu.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Zavrni"
},
"QRHardwareWalletImporterTitle": {
"message": "Skeniraj QR kodo"
},
"about": { "about": {
"message": "O možnostih" "message": "O možnostih"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Trenutni jezik" "message": "Trenutni jezik"
}, },
"custom": {
"message": "Napredno"
},
"customGas": { "customGas": {
"message": "Prilagodi gas" "message": "Prilagodi gas"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Ali ste prepričani, da želite izbrisati to omrežje?" "message": "Ali ste prepričani, da želite izbrisati to omrežje?"
}, },
"depositEther": {
"message": "Vplačilo ethra"
},
"details": { "details": {
"message": "Podrobnosti" "message": "Podrobnosti"
}, },
"directDepositEther": {
"message": "Neposredno vplačilo ehera"
},
"directDepositEtherExplainer": {
"message": "Če že imate Ether, ga lahko najhitreje dobite v MetaMask z neposrednim vplačilom."
},
"done": { "done": {
"message": "Končano" "message": "Končano"
}, },
@ -524,6 +524,9 @@
"learnMore": { "learnMore": {
"message": "Preberite več" "message": "Preberite več"
}, },
"learnMoreUpperCase": {
"message": "Preberite več"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Za dodajanje novega računa morate uporabiti zadnji račun." "message": "Za dodajanje novega računa morate uporabiti zadnji račun."
}, },
@ -572,9 +575,6 @@
"myAccounts": { "myAccounts": {
"message": "Moji računi" "message": "Moji računi"
}, },
"needEtherInWallet": {
"message": "Za interakcijo z decentraliziranimi aplikacijami boste v svoji denarnici potrebovali Eter."
},
"needImportFile": { "needImportFile": {
"message": "Za uvoz morate izbrati datoteko.", "message": "Za uvoz morate izbrati datoteko.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Одбиј"
},
"QRHardwareWalletImporterTitle": {
"message": "Skenirajte QR kod"
},
"about": { "about": {
"message": "Основни подаци" "message": "Основни подаци"
}, },
@ -253,6 +259,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Trenutni jezik" "message": "Trenutni jezik"
}, },
"custom": {
"message": "Напредне опције"
},
"customGas": { "customGas": {
"message": "Prilagodi gas" "message": "Prilagodi gas"
}, },
@ -280,18 +289,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Da li ste sigurni da želite da izbrišete ovu mrežu?" "message": "Da li ste sigurni da želite da izbrišete ovu mrežu?"
}, },
"depositEther": {
"message": "Dajte depozit Ether-u"
},
"details": { "details": {
"message": "Детаљи" "message": "Детаљи"
}, },
"directDepositEther": {
"message": "Direktno deponujte Ether"
},
"directDepositEtherExplainer": {
"message": "Ako već imate neki Ether, najbrži način da preuzmete Ether u svoj novi novčanik jeste direktnim deponovanjem."
},
"done": { "done": {
"message": "Gotovo" "message": "Gotovo"
}, },
@ -527,6 +527,9 @@
"learnMore": { "learnMore": {
"message": "Nauči više" "message": "Nauči više"
}, },
"learnMoreUpperCase": {
"message": "Nauči više"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Treba da koristite svoj poslednji nalog pre nego što budete mogli da dodate novi." "message": "Treba da koristite svoj poslednji nalog pre nego što budete mogli da dodate novi."
}, },
@ -575,9 +578,6 @@
"myAccounts": { "myAccounts": {
"message": "Moji nalozi" "message": "Moji nalozi"
}, },
"needEtherInWallet": {
"message": "Da biste stupili u interakciju sa decentralizovanim aplikacijama koristeći MetaMask, biće vam potreban Ether u vašem novčaniku."
},
"needImportFile": { "needImportFile": {
"message": "Morate izabrati fajl koji ćete uvesti.", "message": "Morate izabrati fajl koji ćete uvesti.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Avvisa"
},
"QRHardwareWalletImporterTitle": {
"message": "Skanna QR-koden"
},
"about": { "about": {
"message": "Om" "message": "Om"
}, },
@ -250,6 +256,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Aktuellt språk" "message": "Aktuellt språk"
}, },
"custom": {
"message": "Avancerat"
},
"customGas": { "customGas": {
"message": "Anpassa gas" "message": "Anpassa gas"
}, },
@ -277,18 +286,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Är du säker på att du vill ta bort detta nätverk?" "message": "Är du säker på att du vill ta bort detta nätverk?"
}, },
"depositEther": {
"message": "Sätt in Ether"
},
"details": { "details": {
"message": "Info" "message": "Info"
}, },
"directDepositEther": {
"message": "Sätt in Ether direkt"
},
"directDepositEtherExplainer": {
"message": "Om du redan har Ether är det snabbaste sättet att få Ether i din nya plånbok att göra en direktinsättning."
},
"done": { "done": {
"message": "Klart" "message": "Klart"
}, },
@ -520,6 +520,9 @@
"learnMore": { "learnMore": {
"message": "Läs mer" "message": "Läs mer"
}, },
"learnMoreUpperCase": {
"message": "Läs mer"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Du måste använda ditt senaste konto innan du kan lägga till ett nytt." "message": "Du måste använda ditt senaste konto innan du kan lägga till ett nytt."
}, },
@ -568,9 +571,6 @@
"myAccounts": { "myAccounts": {
"message": "Mina konton" "message": "Mina konton"
}, },
"needEtherInWallet": {
"message": "För att interagera med decentraliserade applikationer med MetaMask behöver du Ether i din plånbok."
},
"needImportFile": { "needImportFile": {
"message": "Du måste välja en fil att importera.", "message": "Du måste välja en fil att importera.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Kataa"
},
"QRHardwareWalletImporterTitle": {
"message": "Kagua Msimbo wa QR"
},
"about": { "about": {
"message": "Kuhusu" "message": "Kuhusu"
}, },
@ -250,6 +256,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Lugha ya Sasa" "message": "Lugha ya Sasa"
}, },
"custom": {
"message": "Mipangilio ya kina"
},
"customGas": { "customGas": {
"message": "Weka Mipangilio ya Gesi Upendavyo" "message": "Weka Mipangilio ya Gesi Upendavyo"
}, },
@ -277,18 +286,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Una uhakika unataka kufuta mtandao huu?" "message": "Una uhakika unataka kufuta mtandao huu?"
}, },
"depositEther": {
"message": "Weka Ether"
},
"details": { "details": {
"message": "Maelezo" "message": "Maelezo"
}, },
"directDepositEther": {
"message": "Weka Ether Moja kwa Moja"
},
"directDepositEtherExplainer": {
"message": "Ikiwa tayari una sarafu kadhaa za Ether, njia rahisi ya kupata Ether kwenye waleti yako mpya kupitia kuweka moja kwa moja."
},
"done": { "done": {
"message": "Imekamilika" "message": "Imekamilika"
}, },
@ -517,6 +517,9 @@
"learnMore": { "learnMore": {
"message": "Jifunze zaidi" "message": "Jifunze zaidi"
}, },
"learnMoreUpperCase": {
"message": "Jifunze zaidi"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Unapaswa kutumia akaunti yako ya mwisho kabla hujaongeza mpya." "message": "Unapaswa kutumia akaunti yako ya mwisho kabla hujaongeza mpya."
}, },
@ -562,9 +565,6 @@
"myAccounts": { "myAccounts": {
"message": "Akaunti zangu" "message": "Akaunti zangu"
}, },
"needEtherInWallet": {
"message": "Ili kuingiliana na programu zilizosambazwa kwa kutumia MetaMask, utahitaji kuwa na Ether kwenye waleti yako."
},
"needImportFile": { "needImportFile": {
"message": "Unapaswa kuchagua faili la kuhamisha.", "message": "Unapaswa kuchagua faili la kuhamisha.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,7 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "நிகரி"
},
"about": { "about": {
"message": "அறிகம" "message": "அறிகம"
}, },
@ -108,6 +111,9 @@
"createAccount": { "createAccount": {
"message": "உஙகள கணகவஙகள" "message": "உஙகள கணகவஙகள"
}, },
"custom": {
"message": "மபடடவ"
},
"customGas": { "customGas": {
"message": "எரி தனிபயனகள" "message": "எரி தனிபயனகள"
}, },
@ -123,18 +129,9 @@
"delete": { "delete": {
"message": "ந" "message": "ந"
}, },
"depositEther": {
"message": "வ எதி "
},
"details": { "details": {
"message": "விவரஙகள" "message": "விவரஙகள"
}, },
"directDepositEther": {
"message": "நரடிக வ"
},
"directDepositEtherExplainer": {
"message": "நகள ஏறகனவ ஏத இர, நரடிலம உஙகளிய பணபி ஈததரற வின வழி."
},
"done": { "done": {
"message": "மிதத" "message": "மிதத"
}, },
@ -250,6 +247,9 @@
"learnMore": { "learnMore": {
"message": "ம அறிக" "message": "ம அறிக"
}, },
"learnMoreUpperCase": {
"message": "ம அறிக"
},
"likeToImportTokens": { "likeToImportTokens": {
"message": "இநத டகனகளக விிகள?" "message": "இநத டகனகளக விிகள?"
}, },
@ -286,9 +286,6 @@
"myAccounts": { "myAccounts": {
"message": "எனத கணககள" "message": "எனத கணககள"
}, },
"needEtherInWallet": {
"message": "மடமஸ ஐ பயனபடி பரவலகபபடட பயனகளடனடரள, உஙகள பணபபரிறதி ஈதர."
},
"needImportFile": { "needImportFile": {
"message": "இறகமதிய ஒரகளக வ.", "message": "இறகமதிய ஒரகளக வ.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1,4 +1,7 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "తిరసకరి"
},
"about": { "about": {
"message": "గిి" "message": "గిి"
}, },
@ -44,6 +47,9 @@
"create": { "create": {
"message": "సి" "message": "సి"
}, },
"custom": {
"message": "ఆధిక"
},
"delete": { "delete": {
"message": "తలగి" "message": "తలగి"
}, },

@ -1,4 +1,7 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "ปฏเสธ"
},
"about": { "about": {
"message": "เกยวกบ" "message": "เกยวกบ"
}, },
@ -129,18 +132,9 @@
"deleteNetwork": { "deleteNetwork": {
"message": "ลบเครอขาย?" "message": "ลบเครอขาย?"
}, },
"depositEther": {
"message": "การฝากอเธอร"
},
"details": { "details": {
"message": "รายละเอยด" "message": "รายละเอยด"
}, },
"directDepositEther": {
"message": "ฝากอเธอรโดยตรง"
},
"directDepositEtherExplainer": {
"message": "ถาคณมเธอรอยแลววการทเรวทดในการเอาเงนเขากระเปาใหมอการโอนตรงๆ"
},
"done": { "done": {
"message": "เสรจสน" "message": "เสรจสน"
}, },
@ -268,6 +262,9 @@
"learnMore": { "learnMore": {
"message": "เรยนรเพมเตม" "message": "เรยนรเพมเตม"
}, },
"learnMoreUpperCase": {
"message": "เรยนรเพมเตม"
},
"likeToImportTokens": { "likeToImportTokens": {
"message": "คณตองการเพมโทเคนเหลานหรอไม?" "message": "คณตองการเพมโทเคนเหลานหรอไม?"
}, },
@ -295,9 +292,6 @@
"myAccounts": { "myAccounts": {
"message": "บญชของฉน" "message": "บญชของฉน"
}, },
"needEtherInWallet": {
"message": "คณจะตองมเธอรในกระเปาเงนของคณในการใชงานกบแอพพลเคชนแบบกระจายดวย MetaMask"
},
"needImportFile": { "needImportFile": {
"message": "คณตองเลอกไฟลจะนำเขา", "message": "คณตองเลอกไฟลจะนำเขา",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,4 +1,10 @@
{ {
"QRHardwareSignRequestCancel": {
"message": "Відхилити"
},
"QRHardwareWalletImporterTitle": {
"message": "Сканувати QR-код"
},
"about": { "about": {
"message": "Про Google Chrome" "message": "Про Google Chrome"
}, },
@ -256,6 +262,9 @@
"currentLanguage": { "currentLanguage": {
"message": "Поточна мова" "message": "Поточна мова"
}, },
"custom": {
"message": "Розширені"
},
"customGas": { "customGas": {
"message": "Налаштувати пальне" "message": "Налаштувати пальне"
}, },
@ -283,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "Ви впевнені, що хочете видалити цю мережу?" "message": "Ви впевнені, що хочете видалити цю мережу?"
}, },
"depositEther": {
"message": "Депонувати Ether"
},
"details": { "details": {
"message": "Деталі" "message": "Деталі"
}, },
"directDepositEther": {
"message": "Внести безпосередньо Ефір"
},
"directDepositEtherExplainer": {
"message": "Якщо ви вже маєте ефір, пряме переведення – найшвидший спосіб передати ефір у свій гаманець."
},
"done": { "done": {
"message": "Готово" "message": "Готово"
}, },
@ -530,6 +530,9 @@
"learnMore": { "learnMore": {
"message": "Дізнатись більше" "message": "Дізнатись більше"
}, },
"learnMoreUpperCase": {
"message": "Дізнатись більше"
},
"ledgerAccountRestriction": { "ledgerAccountRestriction": {
"message": "Потрібно скористатися своїм останнім обліковим записом, перш ніж додавати новий." "message": "Потрібно скористатися своїм останнім обліковим записом, перш ніж додавати новий."
}, },
@ -584,9 +587,6 @@
"myAccounts": { "myAccounts": {
"message": "Мої облікові записи" "message": "Мої облікові записи"
}, },
"needEtherInWallet": {
"message": "Щоб взаємодіяти з децентралізованими застосунками використовуючи MetaMask, вам буде потрібен Ether у вашому гаманці."
},
"needImportFile": { "needImportFile": {
"message": "Потрібно вибрати файл для імпорту.", "message": "Потрібно вибрати файл для імпорту.",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -292,18 +292,9 @@
"deleteNetworkDescription": { "deleteNetworkDescription": {
"message": "你確定要刪除網路嗎?" "message": "你確定要刪除網路嗎?"
}, },
"depositEther": {
"message": "存入以太幣"
},
"details": { "details": {
"message": "詳情" "message": "詳情"
}, },
"directDepositEther": {
"message": "直接存入以太幣"
},
"directDepositEtherExplainer": {
"message": "如果您已經擁有以太幣,直接存入功能是讓新錢包最快取得以太幣的方式。"
},
"done": { "done": {
"message": "完成" "message": "完成"
}, },
@ -590,9 +581,6 @@
"myAccounts": { "myAccounts": {
"message": "我的帳戶" "message": "我的帳戶"
}, },
"needEtherInWallet": {
"message": "要使用 MetaMask 存取去中心化應用服務時,您的錢包中需要有以太幣。"
},
"needImportFile": { "needImportFile": {
"message": "您必須選擇一個檔案來匯入", "message": "您必須選擇一個檔案來匯入",
"description": "User is important an account and needs to add a file to continue" "description": "User is important an account and needs to add a file to continue"

@ -1 +1 @@
<svg width="136" height="31" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M91.201 8.705h1.03l2.39 5.65 2.4-5.65h1.01l-3.02 7.1h-.78l-3.03-7.1Zm9.327 7.2a2.73 2.73 0 0 1-1.06-.2 2.431 2.431 0 0 1-1.35-1.37 2.91 2.91 0 0 1-.18-1.03c0-.367.063-.707.19-1.02.126-.32.303-.597.53-.83.233-.234.51-.417.83-.55.32-.134.67-.2 1.05-.2.326 0 .633.056.92.17.286.106.536.27.75.49.22.213.393.476.52.79.126.306.19.66.19 1.06v.13c0 .033-.004.076-.01.13h-4.1c.006.233.053.45.14.65.093.2.213.373.36.52.153.146.333.263.54.35.213.08.443.12.69.12.386 0 .703-.077.95-.23a1.82 1.82 0 0 0 .61-.64l.68.47a2.48 2.48 0 0 1-.91.87c-.374.213-.82.32-1.34.32Zm1.51-3.13a1.601 1.601 0 0 0-.19-.55c-.087-.16-.2-.297-.34-.41a1.431 1.431 0 0 0-.46-.26 1.645 1.645 0 0 0-.54-.09 1.73 1.73 0 0 0-1.04.35 1.5 1.5 0 0 0-.38.41c-.107.16-.18.343-.22.55h3.17Zm2.1-1.97h.86v.97c.047-.16.12-.304.22-.43a1.556 1.556 0 0 1 .74-.52c.147-.047.294-.07.44-.07.134 0 .264.013.39.04v.89a.78.78 0 0 0-.23-.06 1.342 1.342 0 0 0-.24-.02c-.16 0-.32.036-.48.11-.153.066-.293.17-.42.31-.12.14-.22.32-.3.54-.08.213-.12.466-.12.76v2.48h-.86v-5Zm4.032 7.09 1.09-2.35-2.19-4.74h.95l1.72 3.8 1.71-3.8h.96l-3.28 7.09h-.96Zm7.287-2.09v-7.5h.86v3.27c.173-.3.4-.52.68-.66s.583-.21.91-.21c.28 0 .536.046.77.14.233.093.43.23.59.41.166.173.296.386.39.64.093.246.14.523.14.83v3.08h-.85v-2.95c0-.42-.11-.75-.33-.99-.214-.247-.497-.37-.85-.37-.2 0-.39.04-.57.12-.174.08-.327.2-.46.36-.127.153-.23.343-.31.57-.074.226-.11.486-.11.78v2.48h-.86Zm6.328-6.34a.599.599 0 0 1-.62-.61c0-.167.06-.31.18-.43s.267-.18.44-.18a.602.602 0 0 1 .6.61c0 .173-.056.32-.17.44a.581.581 0 0 1-.43.17Zm-.44 1.34h.86v5h-.86v-5Zm4.671 4.19c.246 0 .473-.044.68-.13.213-.087.393-.207.54-.36.146-.16.26-.347.34-.56.086-.214.13-.447.13-.7 0-.247-.044-.477-.13-.69a1.588 1.588 0 0 0-.34-.56 1.542 1.542 0 0 0-.54-.36 1.637 1.637 0 0 0-.68-.14c-.254 0-.484.046-.69.14a1.548 1.548 0 0 0-.53.36c-.147.153-.264.34-.35.56-.08.213-.12.443-.12.69 0 .253.04.486.12.7.086.213.203.4.35.56.146.153.323.273.53.36.206.086.436.13.69.13Zm-.05 3c-.54 0-1.014-.1-1.42-.3-.407-.2-.717-.44-.93-.72l.6-.6c.2.253.443.456.73.61.293.153.633.23 1.02.23.213 0 .42-.034.62-.1.2-.067.376-.174.53-.32.16-.14.286-.32.38-.54.093-.214.14-.47.14-.77v-.57a2.032 2.032 0 0 1-.72.63c-.307.166-.647.25-1.02.25-.347 0-.67-.064-.97-.19-.3-.134-.56-.314-.78-.54a2.623 2.623 0 0 1-.52-.81 2.8 2.8 0 0 1-.18-1.01c0-.354.06-.684.18-.99.126-.314.3-.584.52-.81.22-.234.48-.414.78-.54.3-.134.623-.2.97-.2.373 0 .713.083 1.02.25.306.16.546.366.72.62v-.77h.86v4.71c0 .42-.067.783-.2 1.09-.127.313-.304.57-.53.77-.227.206-.494.36-.8.46-.307.106-.64.16-1 .16Zm4.149-2.19v-7.5h.86v3.27c.173-.3.4-.52.68-.66s.583-.21.91-.21c.28 0 .537.046.77.14.233.093.43.23.59.41.167.173.297.386.39.64.093.246.14.523.14.83v3.08h-.85v-2.95c0-.42-.11-.75-.33-.99-.213-.247-.497-.37-.85-.37-.2 0-.39.04-.57.12-.173.08-.327.2-.46.36-.127.153-.23.343-.31.57-.073.226-.11.486-.11.78v2.48h-.86Z" fill="#F66A0A"/><path opacity=".3" d="M19.506 22.805c-10.763 7.42-19.416 8-19.416 8h110.25s-8.653-.58-19.417-8c-10.763-7.42-23.363-22-35.708-22-12.345 0-24.945 14.58-35.709 22Z" fill="#037DD6"/><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="111" height="31"><path d="M19.506 22.672c-10.763 7.42-19.416 8-19.416 8h110.25s-8.653-.58-19.417-8c-10.763-7.42-23.363-22-35.708-22-12.345 0-24.945 14.58-35.709 22Z" fill="#EAF6FF"/></mask><g mask="url(#a)"><path fill="#F66A0A" stroke="#fff" stroke-width="2" d="M91.986-5.143h20.706v39.25H91.986z"/></g></svg> <svg width="162" height="32" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path fill="#fff" d="M.813.082h161v31h-161z"/><path d="M117.469 8.638h1.03l2.39 5.65 2.4-5.65h1.01l-3.02 7.1h-.78l-3.03-7.1ZM126.795 15.838c-.386 0-.74-.067-1.06-.2a2.436 2.436 0 0 1-1.35-1.37 2.91 2.91 0 0 1-.18-1.03c0-.367.064-.707.19-1.02.127-.32.304-.597.53-.83.234-.233.51-.417.83-.55.32-.133.67-.2 1.05-.2.327 0 .634.057.92.17.287.107.537.27.75.49.22.213.394.477.52.79.127.307.19.66.19 1.06v.13c0 .033-.003.077-.01.13h-4.1c.007.233.054.45.14.65.094.2.214.373.36.52.154.147.334.263.54.35.214.08.444.12.69.12.387 0 .704-.077.95-.23.254-.16.457-.373.61-.64l.68.47c-.226.367-.53.657-.91.87-.373.213-.82.32-1.34.32Zm1.51-3.13a1.56 1.56 0 0 0-.19-.55c-.086-.16-.2-.297-.34-.41a1.408 1.408 0 0 0-.46-.26 1.636 1.636 0 0 0-.54-.09 1.732 1.732 0 0 0-1.04.35 1.512 1.512 0 0 0-.38.41c-.106.16-.18.343-.22.55h3.17ZM130.406 10.738h.86v.97c.046-.16.12-.303.22-.43s.213-.233.34-.32a1.59 1.59 0 0 1 .4-.2c.146-.047.293-.07.44-.07.133 0 .263.013.39.04v.89a.782.782 0 0 0-.23-.06 1.348 1.348 0 0 0-.24-.02c-.16 0-.32.037-.48.11-.154.067-.294.17-.42.31-.12.14-.22.32-.3.54-.08.213-.12.467-.12.76v2.48h-.86v-5ZM134.438 17.828l1.09-2.35-2.19-4.74h.95l1.72 3.8 1.71-3.8h.96l-3.28 7.09h-.96ZM141.724 15.738v-7.5h.86v3.27c.173-.3.4-.52.68-.66s.583-.21.91-.21c.28 0 .537.047.77.14.233.093.43.23.59.41.167.173.297.387.39.64.093.247.14.523.14.83v3.08h-.85v-2.95c0-.42-.11-.75-.33-.99-.213-.247-.497-.37-.85-.37-.2 0-.39.04-.57.12-.173.08-.327.2-.46.36-.127.153-.23.343-.31.57-.073.227-.11.487-.11.78v2.48h-.86ZM148.053 9.398a.599.599 0 0 1-.62-.61c0-.167.06-.31.18-.43s.266-.18.44-.18c.173 0 .316.06.43.18.113.12.17.263.17.43 0 .173-.057.32-.17.44a.584.584 0 0 1-.43.17Zm-.44 1.34h.86v5h-.86v-5ZM152.283 14.928c.247 0 .473-.043.68-.13.213-.087.393-.207.54-.36a1.7 1.7 0 0 0 .34-.56c.087-.213.13-.447.13-.7a1.81 1.81 0 0 0-.13-.69 1.573 1.573 0 0 0-.34-.56 1.54 1.54 0 0 0-.54-.36 1.632 1.632 0 0 0-.68-.14c-.253 0-.483.047-.69.14a1.554 1.554 0 0 0-.53.36 1.7 1.7 0 0 0-.35.56c-.08.213-.12.443-.12.69 0 .253.04.487.12.7.087.213.203.4.35.56.147.153.323.273.53.36.207.087.437.13.69.13Zm-.05 3c-.54 0-1.013-.1-1.42-.3-.407-.2-.717-.44-.93-.72l.6-.6c.2.253.443.457.73.61.293.153.633.23 1.02.23.213 0 .42-.033.62-.1s.377-.173.53-.32c.16-.14.287-.32.38-.54.093-.213.14-.47.14-.77v-.57a2.015 2.015 0 0 1-.72.63c-.307.167-.647.25-1.02.25-.347 0-.67-.063-.97-.19-.3-.133-.56-.313-.78-.54a2.643 2.643 0 0 1-.52-.81 2.8 2.8 0 0 1-.18-1.01c0-.353.06-.683.18-.99.127-.313.3-.583.52-.81.22-.233.48-.413.78-.54.3-.133.623-.2.97-.2.373 0 .713.083 1.02.25.307.16.547.367.72.62v-.77h.86v4.71c0 .42-.067.783-.2 1.09-.127.313-.303.57-.53.77a2.17 2.17 0 0 1-.8.46c-.307.107-.64.16-1 .16ZM156.382 15.738v-7.5h.86v3.27c.174-.3.4-.52.68-.66s.584-.21.91-.21c.28 0 .537.047.77.14.234.093.43.23.59.41.167.173.297.387.39.64.094.247.14.523.14.83v3.08h-.85v-2.95c0-.42-.11-.75-.33-.99-.213-.247-.496-.37-.85-.37-.2 0-.39.04-.57.12-.173.08-.326.2-.46.36-.126.153-.23.343-.31.57-.073.227-.11.487-.11.78v2.48h-.86Z" fill="#F66A0A"/><path opacity=".3" d="M45.774 22.738c-10.764 7.42-19.417 8-19.417 8h110.251s-8.653-.58-19.417-8c-10.764-7.42-23.364-22-35.709-22-12.344 0-24.944 14.58-35.708 22Z" fill="#037DD6"/><mask id="b" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="26" y="0" width="111" height="31"><path d="M45.774 22.605c-10.764 7.42-19.417 8-19.417 8h110.251s-8.653-.58-19.417-8c-10.764-7.42-23.364-22-35.709-22-12.344 0-24.944 14.58-35.708 22Z" fill="#EAF6FF"/></mask><g mask="url(#b)"><path fill="#F66A0A" stroke="#fff" stroke-width="2" d="M118.254-5.209h20.706v39.25h-20.706z"/></g></g><defs><clipPath id="a"><path fill="#fff" transform="translate(.813 .082)" d="M0 0h161v31H0z"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

@ -1 +1 @@
<svg width="125" height="31" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M14.233 8.738h.93v6.22h3.43v.88h-4.36v-7.1Zm7.412 7.2c-.38 0-.73-.067-1.05-.2a2.679 2.679 0 0 1-.83-.56 2.569 2.569 0 0 1-.55-.82c-.126-.32-.19-.66-.19-1.02s.064-.697.19-1.01a2.54 2.54 0 0 1 .55-.83c.234-.233.51-.417.83-.55.32-.14.67-.21 1.05-.21.374 0 .72.07 1.04.21.32.133.597.317.83.55.234.233.414.51.54.83.134.313.2.65.2 1.01s-.066.7-.2 1.02a2.44 2.44 0 0 1-.54.82 2.68 2.68 0 0 1-.83.56c-.32.133-.666.2-1.04.2Zm0-.8c.26 0 .497-.047.71-.14.214-.093.394-.22.54-.38.154-.167.27-.357.35-.57.087-.22.13-.457.13-.71 0-.247-.043-.48-.13-.7-.08-.22-.196-.41-.35-.57a1.52 1.52 0 0 0-.54-.39 1.754 1.754 0 0 0-.71-.14c-.26 0-.496.047-.71.14a1.619 1.619 0 0 0-.55.39c-.153.16-.273.35-.36.57-.08.22-.12.453-.12.7 0 .253.04.49.12.71.087.213.207.403.36.57.154.16.337.287.55.38.214.093.45.14.71.14Zm6.825-2.89-1.23 3.59h-.76l-1.7-5h.9l1.21 3.65 1.25-3.65h.66l1.25 3.65 1.21-3.65h.91l-1.7 5h-.76l-1.24-3.59Z" fill="#F66A0A"/><path opacity=".3" d="M33.96 22.838c-10.764 7.42-19.417 8-19.417 8h110.25s-8.653-.58-19.416-8c-10.764-7.42-23.364-22-35.709-22-12.345 0-24.945 14.58-35.709 22Z" fill="#037DD6"/><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="14" y="0" width="111" height="31"><path d="M33.96 22.705c-10.764 7.42-19.417 8-19.417 8h110.25s-8.653-.58-19.416-8c-10.764-7.42-23.364-22-35.709-22-12.345 0-24.945 14.58-35.709 22Z" fill="#EAF6FF"/></mask><g mask="url(#a)"><path fill="#F66A0A" stroke="#fff" stroke-width="2" d="M12.793 16.838h20.706v17.303H12.793z"/></g></svg> <svg width="162" height="32" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path fill="#fff" d="M.813.082h161v31h-161z"/><path d="M26.047 8.638h.93v6.22h3.43v.88h-4.36v-7.1ZM33.46 15.838c-.38 0-.73-.067-1.05-.2a2.573 2.573 0 0 1-1.38-1.38c-.127-.32-.19-.66-.19-1.02s.063-.697.19-1.01c.133-.32.316-.597.55-.83.233-.233.51-.417.83-.55.32-.14.67-.21 1.05-.21.373 0 .72.07 1.04.21.32.133.596.317.83.55.233.233.413.51.54.83.133.313.2.65.2 1.01s-.068.7-.2 1.02a2.438 2.438 0 0 1-.54.82c-.234.233-.51.42-.83.56-.32.133-.667.2-1.04.2Zm0-.8c.26 0 .496-.047.71-.14.212-.093.392-.22.54-.38.152-.167.27-.357.35-.57.086-.22.13-.457.13-.71 0-.247-.044-.48-.13-.7-.08-.22-.198-.41-.35-.57a1.518 1.518 0 0 0-.54-.39 1.752 1.752 0 0 0-.71-.14c-.26 0-.498.047-.71.14a1.62 1.62 0 0 0-.55.39 1.73 1.73 0 0 0-.36.57c-.08.22-.12.453-.12.7 0 .253.04.49.12.71.086.213.206.403.36.57.152.16.336.287.55.38.212.093.45.14.71.14ZM40.284 12.148l-1.23 3.59h-.76l-1.7-5h.9l1.21 3.65 1.25-3.65h.66l1.25 3.65 1.21-3.65h.91l-1.7 5h-.76l-1.24-3.59Z" fill="#F66A0A"/><path opacity=".3" d="M45.774 22.738c-10.764 7.42-19.417 8-19.417 8h110.251s-8.653-.58-19.417-8c-10.764-7.42-23.364-22-35.709-22-12.344 0-24.944 14.58-35.708 22Z" fill="#037DD6"/><mask id="b" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="26" y="0" width="111" height="31"><path d="M45.774 22.605c-10.764 7.42-19.417 8-19.417 8h110.251s-8.653-.58-19.417-8c-10.764-7.42-23.364-22-35.709-22-12.344 0-24.944 14.58-35.708 22Z" fill="#EAF6FF"/></mask><g mask="url(#b)"><path fill="#F66A0A" stroke="#fff" stroke-width="2" d="M24.607 16.738h20.706v17.303H24.607z"/></g></g><defs><clipPath id="a"><path fill="#fff" transform="translate(.813 .082)" d="M0 0h161v31H0z"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -1 +1 @@
<svg width="111" height="49" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="m38 4.334 2.63 3.54 2.65-3.54h.84v7.1h-.92v-5.52l-2.56 3.44-2.56-3.44v5.52h-.93v-7.1H38Zm9.99 7.2a2.73 2.73 0 0 1-1.06-.2 2.431 2.431 0 0 1-1.35-1.37 2.91 2.91 0 0 1-.18-1.03c0-.367.063-.707.19-1.02.126-.32.303-.597.53-.83.233-.234.51-.417.83-.55.32-.134.67-.2 1.05-.2.326 0 .633.056.92.17.286.106.536.27.75.49.22.213.393.476.52.79.126.306.19.66.19 1.06v.13c0 .033-.004.076-.01.13h-4.1c.006.233.053.45.14.65.093.2.213.373.36.52.153.146.333.263.54.35.213.08.443.12.69.12.386 0 .703-.077.95-.23.253-.16.456-.374.61-.64l.68.47c-.227.366-.53.656-.91.87-.374.213-.82.32-1.34.32Zm1.51-3.13a1.579 1.579 0 0 0-.19-.55c-.087-.16-.2-.297-.34-.41a1.419 1.419 0 0 0-.46-.26 1.639 1.639 0 0 0-.54-.09 1.729 1.729 0 0 0-1.04.35 1.5 1.5 0 0 0-.38.41c-.107.16-.18.343-.22.55h3.17Zm4.16 3.13c-.353 0-.68-.067-.98-.2a2.57 2.57 0 0 1-.77-.56 2.73 2.73 0 0 1-.52-.83 2.8 2.8 0 0 1-.18-1.01c0-.36.06-.697.18-1.01.127-.314.3-.587.52-.82a2.359 2.359 0 0 1 1.75-.77c.38 0 .727.086 1.04.26.314.166.554.37.72.61v-3.27h.86v7.5h-.86v-.77a2.08 2.08 0 0 1-.72.62 2.18 2.18 0 0 1-1.04.25Zm.13-.79a1.607 1.607 0 0 0 1.22-.52c.154-.167.27-.36.35-.58.087-.22.13-.457.13-.71 0-.254-.043-.49-.13-.71-.08-.22-.196-.41-.35-.57a1.544 1.544 0 0 0-.53-.39 1.658 1.658 0 0 0-.69-.14c-.253 0-.486.046-.7.14a1.648 1.648 0 0 0-.54.39 1.82 1.82 0 0 0-.35.57c-.08.22-.12.456-.12.71 0 .253.04.49.12.71.087.22.204.413.35.58.154.16.334.286.54.38.214.093.447.14.7.14Zm4.55-5.65a.599.599 0 0 1-.62-.61c0-.167.06-.31.18-.43s.266-.18.44-.18c.172 0 .316.06.43.18.112.12.17.263.17.43 0 .173-.058.32-.17.44a.583.583 0 0 1-.43.17Zm-.44 1.34h.86v5h-.86v-5Zm4.26 5.1c-.274 0-.524-.047-.75-.14-.227-.1-.42-.237-.58-.41a1.917 1.917 0 0 1-.38-.63 2.617 2.617 0 0 1-.13-.85v-3.07h.86v2.94c0 .42.1.753.3 1 .206.246.483.37.83.37.193 0 .373-.04.54-.12.173-.087.32-.207.44-.36.126-.16.226-.354.3-.58.073-.227.11-.484.11-.77v-2.48h.86v5h-.86v-.77a1.654 1.654 0 0 1-.66.66c-.267.14-.56.21-.88.21Zm10.46-3.04c0-.407-.083-.737-.25-.99-.166-.254-.413-.38-.74-.38-.4 0-.726.156-.98.47-.246.313-.376.74-.39 1.28v2.56h-.86v-2.94c0-.407-.083-.737-.25-.99-.16-.254-.403-.38-.73-.38-.406 0-.74.163-1 .49-.253.326-.38.773-.38 1.34v2.48h-.86v-5h.86v.77a1.63 1.63 0 0 1 .61-.63c.26-.16.56-.24.9-.24.374 0 .69.096.95.29.267.186.464.446.59.78.134-.327.344-.587.63-.78.294-.194.63-.29 1.01-.29.274 0 .517.05.73.15.22.093.404.23.55.41.154.173.27.386.35.64.08.246.12.523.12.83v3.07h-.86v-2.94Z" fill="#037DD6"/><path opacity=".3" d="M19.506 40.566c-10.763 7.42-19.416 8-19.416 8h110.25s-8.653-.58-19.417-8c-10.763-7.42-23.363-22-35.708-22-12.345 0-24.945 14.58-35.709 22Z" fill="#037DD6"/><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="18" width="111" height="31"><path d="M19.506 40.434c-10.763 7.42-19.416 8-19.416 8h110.25s-8.653-.58-19.417-8c-10.763-7.42-23.363-22-35.708-22-12.345 0-24.945 14.58-35.709 22Z" fill="#EAF6FF"/></mask><g mask="url(#a)"><path fill="#037DD6" stroke="#fff" stroke-width="2" d="M36.047 12.619H73.39v39.25H36.047z"/></g></svg> <svg width="162" height="47" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M.813.082h161v46h-161z"/><path d="m64.268 1.505 2.63 3.54 2.65-3.54h.84v7.1h-.92v-5.52l-2.56 3.44-2.56-3.44v5.52h-.93v-7.1h.85ZM74.257 8.705a2.73 2.73 0 0 1-1.06-.2 2.432 2.432 0 0 1-1.35-1.37 2.91 2.91 0 0 1-.18-1.03c0-.367.064-.707.19-1.02.127-.32.304-.596.53-.83.234-.233.51-.417.83-.55.32-.133.67-.2 1.05-.2.327 0 .634.057.92.17.287.107.537.27.75.49.22.213.394.477.52.79.127.307.19.66.19 1.06v.13c0 .034-.003.077-.01.13h-4.1c.007.233.054.45.14.65.094.2.214.373.36.52.154.147.334.263.54.35.214.08.444.12.69.12.387 0 .704-.077.95-.23.254-.16.457-.373.61-.64l.68.47c-.226.367-.53.657-.91.87-.373.213-.82.32-1.34.32Zm1.51-3.13a1.58 1.58 0 0 0-.19-.55c-.086-.16-.2-.296-.34-.41a1.42 1.42 0 0 0-.46-.26 1.639 1.639 0 0 0-.54-.09 1.728 1.728 0 0 0-1.04.35 1.498 1.498 0 0 0-.38.41 1.49 1.49 0 0 0-.22.55h3.17ZM79.928 8.705c-.353 0-.68-.066-.98-.2a2.57 2.57 0 0 1-.77-.56 2.732 2.732 0 0 1-.52-.83 2.8 2.8 0 0 1-.18-1.01c0-.36.06-.697.18-1.01.127-.313.3-.587.52-.82a2.36 2.36 0 0 1 1.75-.77c.38 0 .727.087 1.04.26.313.167.553.37.72.61v-3.27h.86v7.5h-.86v-.77c-.167.24-.407.447-.72.62a2.18 2.18 0 0 1-1.04.25Zm.13-.79a1.606 1.606 0 0 0 1.22-.52c.153-.167.27-.36.35-.58.087-.22.13-.457.13-.71 0-.253-.043-.49-.13-.71-.08-.22-.197-.41-.35-.57a1.542 1.542 0 0 0-.53-.39 1.657 1.657 0 0 0-.69-.14c-.253 0-.487.047-.7.14a1.65 1.65 0 0 0-.54.39c-.147.16-.263.35-.35.57-.08.22-.12.457-.12.71 0 .253.04.49.12.71.087.22.203.413.35.58.153.16.333.287.54.38.213.093.447.14.7.14ZM84.607 2.265a.599.599 0 0 1-.62-.61c0-.167.06-.31.18-.43s.266-.18.44-.18c.173 0 .317.06.43.18.113.12.17.263.17.43 0 .173-.057.32-.17.44a.583.583 0 0 1-.43.17Zm-.44 1.34h.86v5h-.86v-5ZM88.427 8.705c-.273 0-.523-.046-.75-.14-.227-.1-.42-.236-.58-.41a1.916 1.916 0 0 1-.38-.63 2.614 2.614 0 0 1-.13-.85v-3.07h.86v2.94c0 .42.1.753.3 1 .207.247.483.37.83.37.193 0 .373-.04.54-.12.173-.087.32-.207.44-.36.127-.16.227-.353.3-.58.073-.227.11-.483.11-.77v-2.48h.86v5h-.86v-.77a1.654 1.654 0 0 1-.66.66c-.267.14-.56.21-.88.21ZM98.888 5.665c0-.407-.083-.737-.25-.99-.166-.253-.413-.38-.74-.38-.4 0-.727.157-.98.47-.247.314-.377.74-.39 1.28v2.56h-.86v-2.94c0-.407-.083-.737-.25-.99-.16-.253-.403-.38-.73-.38-.407 0-.74.163-1 .49-.253.327-.38.774-.38 1.34v2.48h-.86v-5h.86v.77a1.63 1.63 0 0 1 .61-.63c.26-.16.56-.24.9-.24.374 0 .69.097.95.29.267.187.463.447.59.78.133-.327.343-.587.63-.78.293-.193.63-.29 1.01-.29.273 0 .517.05.73.15.22.094.404.23.55.41.153.173.27.387.35.64.08.247.12.524.12.83v3.07h-.86v-2.94Z" fill="#037DD6"/><path opacity=".3" d="M45.774 37.738c-10.764 7.42-19.417 8-19.417 8h110.251s-8.653-.58-19.417-8c-10.764-7.42-23.364-22-35.709-22-12.344 0-24.944 14.58-35.708 22Z" fill="#037DD6"/><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="26" y="15" width="111" height="31"><path d="M45.774 37.605c-10.764 7.42-19.417 8-19.417 8h110.251s-8.653-.58-19.417-8c-10.764-7.42-23.364-22-35.709-22-12.344 0-24.944 14.58-35.708 22Z" fill="#EAF6FF"/></mask><g mask="url(#a)"><path fill="#037DD6" stroke="#fff" stroke-width="2" d="M62.313 9.791h37.343v39.25H62.313z"/></g></svg>

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

@ -0,0 +1,116 @@
WEBVTT
1
00:00:00.780 --> 00:00:04.580
MetaMask ist eine neue Möglichkeit, sich mit
Webseiten und Anwendungen zu verbinden.
2
00:00:04.580 --> 00:00:08.860
Auf traditionellen Webseiten ist eine
zentrale Datenbank für die Steuerung und
3
00:00:08.860 --> 00:00:10.179
Wiederherstellung der Konten zuständig.
4
00:00:10.179 --> 00:00:15.050
Bei MetaMask gehört all diese Macht dem
Besitzer eines „Hauptschlüssels“.
5
00:00:15.050 --> 00:00:18.460
Wer den Schlüssel besitzt, kontrolliert
das Wallet und damit die Konten.
6
00:00:18.460 --> 00:00:21.110
Der geheime Satz zur Wiederherstellung
Deines Wallets ist der „Hauptschlüssel“.
7
00:00:21.110 --> 00:00:26.070
Es ist eine Reihe von 12 Wörtern, welche generiert werden,
wenn MetaMask zum ersten Mal eingerichtet wird, diese erlauben dir
8
00:00:26.070 --> 00:00:30.120
Deinen „Hauptschlüssel“ zu Deinem Wallet wieder herzustellen,
solltest Du jemals den Zugriff darauf verlieren.
9
00:00:30.120 --> 00:00:33.451
Es ist wichtig, dass Du Dein Wallet sicherst,
indem Du Deinen geheimen
10
00:00:33.451 --> 00:00:37.510
Wiederherstellungssatz sicher
und geheim verwahrst.
11
00:00:37.510 --> 00:00:41.429
Wenn jemand Zugriff darauf erhält, hat er
den „Hauptschlüssel“ für Dein Wallet und kann
12
00:00:41.429 --> 00:00:45.190
frei auf Deine Konten zugreifen und alle Gelder stehlen.
13
00:00:45.190 --> 00:00:50.109
Um Dein MetaMask-Wallet zu sichern, musst Du Deinen
geheimen Wiederherstellungssatz sicher speichern.
14
00:00:50.109 --> 00:00:54.930
Du kannst ihn aufschreiben, irgendwo verstecken,
in ein Schließfach legen
15
00:00:54.930 --> 00:00:57.729
oder in einen sicheren Passwort-Manager speichern.
16
00:00:57.729 --> 00:01:01.050
Einige Benutzer gravieren ihren
Satz sogar auf eine Metallplatte.
17
00:01:01.050 --> 00:01:04.440
Niemand, nicht einmal das Team von MetaMask,
kann Dir dabei helfen
18
00:01:04.440 --> 00:01:07.820
Dein Wallet wiederherzustellen, wenn Du Deinen
geheimen Wiederherstellungssatz verlierst.
19
00:01:07.820 --> 00:01:12.072
Wenn Du Deinen geheimen Wiederherstellungssatz noch nicht
aufgeschrieben und an einem sicheren Ort aufbewahrt hast,
20
00:01:12.072 --> 00:01:15.492
mach es jetzt. Wir warten solange.
21
00:01:15.500 --> 00:01:20.780
Und denk daran, teilen Deinen geheimen Wiederherstellungssatz
niemals: nicht einmal mit uns.
22
00:01:20.780 --> 00:01:24.910
Wenn dich jemals jemand danach fragt,
versucht er dich zu betrügen.
23
00:01:24.910 --> 00:01:26.250
Das ist alles!
24
00:01:26.250 --> 00:01:31.020
Jetzt weist Du, was ein geheimer Wiederherstellungssatz ist
und wie Du dafür sorgst, das Dein Wallete sicher bleibt.

@ -1,7 +1,7 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<title>Ethereum Phishing Detection - MetaMask</title> <title>MetaMask Phishing Detection</title>
<script src="./globalthis.js" type="text/javascript" charset="utf-8"></script> <script src="./globalthis.js" type="text/javascript" charset="utf-8"></script>
<script src="./lockdown-install.js" type="text/javascript" charset="utf-8"></script> <script src="./lockdown-install.js" type="text/javascript" charset="utf-8"></script>
<script src="./lockdown-run.js" type="text/javascript" charset="utf-8"></script> <script src="./lockdown-run.js" type="text/javascript" charset="utf-8"></script>
@ -37,7 +37,7 @@
<img src="./images/info-logo.png" alt=""> <img src="./images/info-logo.png" alt="">
<h1> <h1>
<i class="fa fa-exclamation-circle" aria-hidden="true"></i> <i class="fa fa-exclamation-circle" aria-hidden="true"></i>
Ethereum Phishing Detection MetaMask Phishing Detection
</h1> </h1>
</div> </div>
<div class="content__body"> <div class="content__body">

@ -414,7 +414,10 @@ function setupController(initState, initLangCode) {
// communication with page or other extension // communication with page or other extension
function connectExternal(remotePort) { function connectExternal(remotePort) {
const portStream = new PortStream(remotePort); const portStream = new PortStream(remotePort);
controller.setupUntrustedCommunication(portStream, remotePort.sender); controller.setupUntrustedCommunication({
connectionStream: portStream,
sender: remotePort.sender,
});
} }
// //

@ -31,10 +31,12 @@ export default class AppStateController extends EventEmitter {
recoveryPhraseReminderHasBeenShown: false, recoveryPhraseReminderHasBeenShown: false,
recoveryPhraseReminderLastShown: new Date().getTime(), recoveryPhraseReminderLastShown: new Date().getTime(),
collectiblesDetectionNoticeDismissed: false, collectiblesDetectionNoticeDismissed: false,
enableEIP1559V2NoticeDismissed: false,
showTestnetMessageInDropdown: true, showTestnetMessageInDropdown: true,
trezorModel: null, trezorModel: null,
...initState, ...initState,
qrHardware: {}, qrHardware: {},
collectiblesDropdownState: {},
}); });
this.timer = null; this.timer = null;
@ -270,4 +272,26 @@ export default class AppStateController extends EventEmitter {
collectiblesDetectionNoticeDismissed, collectiblesDetectionNoticeDismissed,
}); });
} }
/**
* A setter for the `enableEIP1559V2NoticeDismissed` property
*
* @param enableEIP1559V2NoticeDismissed
*/
setEnableEIP1559V2NoticeDismissed(enableEIP1559V2NoticeDismissed) {
this.store.updateState({
enableEIP1559V2NoticeDismissed,
});
}
/**
* A setter for the `collectiblesDropdownState` property
*
* @param collectiblesDropdownState
*/
updateCollectibleDropDownState(collectiblesDropdownState) {
this.store.updateState({
collectiblesDropdownState,
});
}
} }

@ -1,15 +1,17 @@
import { merge, omit } from 'lodash'; import { merge, omit, omitBy } from 'lodash';
import { ObservableStore } from '@metamask/obs-store'; import { ObservableStore } from '@metamask/obs-store';
import { bufferToHex, keccak } from 'ethereumjs-util'; import { bufferToHex, keccak } from 'ethereumjs-util';
import { generateUUID } from 'pubnub';
import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app';
import { import {
METAMETRICS_ANONYMOUS_ID, METAMETRICS_ANONYMOUS_ID,
METAMETRICS_BACKGROUND_PAGE_OBJECT, METAMETRICS_BACKGROUND_PAGE_OBJECT,
} from '../../../shared/constants/metametrics'; } from '../../../shared/constants/metametrics';
import { SECOND } from '../../../shared/constants/time';
const defaultCaptureException = (err) => { const defaultCaptureException = (err) => {
// throw error on clean stack so its captured by platform integrations (eg sentry) // throw error on clean stack so its captured by platform integrations (eg sentry)
// but does not interupt the call stack // but does not interrupt the call stack
setTimeout(() => { setTimeout(() => {
throw err; throw err;
}); });
@ -27,15 +29,18 @@ const exceptionsToFilter = {
* @typedef {import('../../../shared/constants/metametrics').SegmentInterface} SegmentInterface * @typedef {import('../../../shared/constants/metametrics').SegmentInterface} SegmentInterface
* @typedef {import('../../../shared/constants/metametrics').MetaMetricsPagePayload} MetaMetricsPagePayload * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPagePayload} MetaMetricsPagePayload
* @typedef {import('../../../shared/constants/metametrics').MetaMetricsPageOptions} MetaMetricsPageOptions * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPageOptions} MetaMetricsPageOptions
* @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventFragment} MetaMetricsEventFragment
*/ */
/** /**
* @typedef {Object} MetaMetricsControllerState * @typedef {Object} MetaMetricsControllerState
* @property {?string} metaMetricsId - The user's metaMetricsId that will be * @property {string} [metaMetricsId] - The user's metaMetricsId that will be
* attached to all non-anonymized event payloads * attached to all non-anonymized event payloads
* @property {?boolean} participateInMetaMetrics - The user's preference for * @property {boolean} [participateInMetaMetrics] - The user's preference for
* participating in the MetaMetrics analytics program. This setting controls * participating in the MetaMetrics analytics program. This setting controls
* whether or not events are tracked * whether or not events are tracked
* @property {{[string]: MetaMetricsEventFragment}} [fragments] - Object keyed
* by UUID with stored fragments as values.
*/ */
export default class MetaMetricsController { export default class MetaMetricsController {
@ -81,10 +86,15 @@ export default class MetaMetricsController {
this.version = this.version =
environment === 'production' ? version : `${version}-${environment}`; environment === 'production' ? version : `${version}-${environment}`;
const abandonedFragments = omitBy(initState?.fragments, 'persist');
this.store = new ObservableStore({ this.store = new ObservableStore({
participateInMetaMetrics: null, participateInMetaMetrics: null,
metaMetricsId: null, metaMetricsId: null,
...initState, ...initState,
fragments: {
...initState?.fragments,
},
}); });
preferencesStore.subscribe(({ currentLocale }) => { preferencesStore.subscribe(({ currentLocale }) => {
@ -96,6 +106,32 @@ export default class MetaMetricsController {
this.network = getNetworkIdentifier(); this.network = getNetworkIdentifier();
}); });
this.segment = segment; this.segment = segment;
// Track abandoned fragments that weren't properly cleaned up.
// Abandoned fragments are those that were stored in persistent memory
// and are available at controller instance creation, but do not have the
// 'persist' flag set. This means anytime the extension is unlocked, any
// fragments that are not marked as persistent will be purged and the
// failure event will be emitted.
Object.values(abandonedFragments).forEach((fragment) => {
this.finalizeEventFragment(fragment.id, { abandoned: true });
});
// Close out event fragments that were created but not progressed. An
// interval is used to routinely check if a fragment has not been updated
// within the fragment's timeout window. When creating a new event fragment
// a timeout can be specified that will cause an abandoned event to be
// tracked if the event isn't progressed within that amount of time.
setInterval(() => {
Object.values(this.store.getState().fragments).forEach((fragment) => {
if (
fragment.timeout &&
Date.now() - fragment.lastUpdated / 1000 > fragment.timeout
) {
this.finalizeEventFragment(fragment.id, { abandoned: true });
}
});
}, SECOND * 30);
} }
generateMetaMetricsId() { generateMetaMetricsId() {
@ -109,6 +145,141 @@ export default class MetaMetricsController {
); );
} }
/**
* Create an event fragment in state and returns the event fragment object.
*
* @param {MetaMetricsEventFragment} options - Fragment settings and properties
* to initiate the fragment with.
* @returns {MetaMetricsEventFragment}
*/
createEventFragment(options) {
if (!options.successEvent || !options.category) {
throw new Error(
`Must specify success event and category. Success event was: ${
options.event
}. Category was: ${options.category}. Payload keys were: ${Object.keys(
options,
)}. ${
typeof options.properties === 'object'
? `Payload property keys were: ${Object.keys(options.properties)}`
: ''
}`,
);
}
const { fragments } = this.store.getState();
const id = options.uniqueIdentifier ?? generateUUID();
const fragment = {
id,
...options,
lastUpdated: Date.now(),
};
this.store.updateState({
fragments: {
...fragments,
[id]: fragment,
},
});
if (options.initialEvent) {
this.trackEvent({
event: fragment.initialEvent,
category: fragment.category,
properties: fragment.properties,
sensitiveProperties: fragment.sensitiveProperties,
page: fragment.page,
referrer: fragment.referrer,
revenue: fragment.revenue,
value: fragment.value,
currency: fragment.currency,
environmentType: fragment.environmentType,
});
}
return fragment;
}
/**
* Returns the fragment stored in memory with provided id or undefined if it
* does not exist.
*
* @param {string} id - id of fragment to retrieve
* @returns {[MetaMetricsEventFragment]}
*/
getEventFragmentById(id) {
const { fragments } = this.store.getState();
const fragment = fragments[id];
return fragment;
}
/**
* Updates an event fragment in state
*
* @param {string} id - The fragment id to update
* @param {MetaMetricsEventFragment} payload - Fragment settings and
* properties to initiate the fragment with.
*/
updateEventFragment(id, payload) {
const { fragments } = this.store.getState();
const fragment = fragments[id];
if (!fragment) {
throw new Error(`Event fragment with id ${id} does not exist.`);
}
this.store.updateState({
fragments: {
...fragments,
[id]: merge(fragments[id], {
...payload,
lastUpdated: Date.now(),
}),
},
});
}
/**
* Finalizes a fragment, tracking either a success event or failure Event
* and then removes the fragment from state.
*
* @param {string} id - UUID of the event fragment to be closed
* @param {object} options
* @param {boolean} [options.abandoned] - if true track the failure
* event instead of the success event
* @param {MetaMetricsContext.page} [options.page] - page the final event
* occurred on. This will override whatever is set on the fragment
* @param {MetaMetricsContext.referrer} [options.referrer] - Dapp that
* originated the fragment. This is for fallback only, the fragment referrer
* property will take precedence.
*/
finalizeEventFragment(id, { abandoned = false, page, referrer } = {}) {
const fragment = this.store.getState().fragments[id];
if (!fragment) {
throw new Error(`Funnel with id ${id} does not exist.`);
}
const eventName = abandoned ? fragment.failureEvent : fragment.successEvent;
this.trackEvent({
event: eventName,
category: fragment.category,
properties: fragment.properties,
sensitiveProperties: fragment.sensitiveProperties,
page: page ?? fragment.page,
referrer: fragment.referrer ?? referrer,
revenue: fragment.revenue,
value: fragment.value,
currency: fragment.currency,
environmentType: fragment.environmentType,
});
const { fragments } = this.store.getState();
delete fragments[id];
this.store.updateState({ fragments });
}
/** /**
* Setter for the `participateInMetaMetrics` property * Setter for the `participateInMetaMetrics` property
* *

@ -81,6 +81,28 @@ function getMockPreferencesStore({ currentLocale = LOCALE } = {}) {
}; };
} }
const SAMPLE_PERSISTED_EVENT = {
id: 'testid',
persist: true,
category: 'Unit Test',
successEvent: 'sample persisted event success',
failureEvent: 'sample persisted event failure',
properties: {
test: true,
},
};
const SAMPLE_NON_PERSISTED_EVENT = {
id: 'testid2',
persist: false,
category: 'Unit Test',
successEvent: 'sample non-persisted event success',
failureEvent: 'sample non-persisted event failure',
properties: {
test: true,
},
};
function getMetaMetricsController({ function getMetaMetricsController({
participateInMetaMetrics = true, participateInMetaMetrics = true,
metaMetricsId = TEST_META_METRICS_ID, metaMetricsId = TEST_META_METRICS_ID,
@ -105,12 +127,29 @@ function getMetaMetricsController({
initState: { initState: {
participateInMetaMetrics, participateInMetaMetrics,
metaMetricsId, metaMetricsId,
fragments: {
testid: SAMPLE_PERSISTED_EVENT,
testid2: SAMPLE_NON_PERSISTED_EVENT,
},
}, },
}); });
} }
describe('MetaMetricsController', function () { describe('MetaMetricsController', function () {
describe('constructor', function () { describe('constructor', function () {
it('should properly initialize', function () { it('should properly initialize', function () {
const mock = sinon.mock(segment);
mock
.expects('track')
.once()
.withArgs({
event: 'sample non-persisted event failure',
userId: TEST_META_METRICS_ID,
context: DEFAULT_TEST_CONTEXT,
properties: {
...DEFAULT_EVENT_PROPERTIES,
test: true,
},
});
const metaMetricsController = getMetaMetricsController(); const metaMetricsController = getMetaMetricsController();
assert.strictEqual(metaMetricsController.version, VERSION); assert.strictEqual(metaMetricsController.version, VERSION);
assert.strictEqual(metaMetricsController.network, NETWORK); assert.strictEqual(metaMetricsController.network, NETWORK);
@ -127,6 +166,10 @@ describe('MetaMetricsController', function () {
metaMetricsController.locale, metaMetricsController.locale,
LOCALE.replace('_', '-'), LOCALE.replace('_', '-'),
); );
assert.deepStrictEqual(metaMetricsController.state.fragments, {
testid: SAMPLE_PERSISTED_EVENT,
});
mock.verify();
}); });
it('should update when network changes', function () { it('should update when network changes', function () {

@ -134,16 +134,10 @@ export default class PreferencesController {
/** /**
* Setter for the `useCollectibleDetection` property * Setter for the `useCollectibleDetection` property
* *
* @param {boolean} val - Whether or not the user prefers to autodetect collectibles. * @param {boolean} useCollectibleDetection - Whether or not the user prefers to autodetect collectibles.
*/ */
setUseCollectibleDetection(val) { setUseCollectibleDetection(useCollectibleDetection) {
const { openSeaEnabled } = this.store.getState(); this.store.updateState({ useCollectibleDetection });
if (val && !openSeaEnabled) {
throw new Error(
'useCollectibleDetection cannot be enabled if openSeaEnabled is false',
);
}
this.store.updateState({ useCollectibleDetection: val });
} }
/** /**
@ -167,6 +161,15 @@ export default class PreferencesController {
this.store.updateState({ advancedGasFee: val }); this.store.updateState({ advancedGasFee: val });
} }
/**
* Setter for the `eip1559V2Enabled` property
*
* @param {object} val - holds the eip1559V2Enabled that the user set as experimental settings.
*/
setEIP1559V2Enabled(val) {
this.store.updateState({ eip1559V2Enabled: val });
}
/** /**
* Add new methodData to state, to avoid requesting this information again through Infura * Add new methodData to state, to avoid requesting this information again through Infura
* *

@ -25,6 +25,7 @@ import {
TRANSACTION_STATUSES, TRANSACTION_STATUSES,
TRANSACTION_TYPES, TRANSACTION_TYPES,
TRANSACTION_ENVELOPE_TYPES, TRANSACTION_ENVELOPE_TYPES,
TRANSACTION_EVENTS,
} from '../../../../shared/constants/transaction'; } from '../../../../shared/constants/transaction';
import { TRANSACTION_ENVELOPE_TYPE_NAMES } from '../../../../ui/helpers/constants/transactions'; import { TRANSACTION_ENVELOPE_TYPE_NAMES } from '../../../../ui/helpers/constants/transactions';
import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller'; import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller';
@ -54,13 +55,15 @@ const hstInterface = new ethers.utils.Interface(abi);
const MAX_MEMSTORE_TX_LIST_SIZE = 100; // Number of transactions (by unique nonces) to keep in memory const MAX_MEMSTORE_TX_LIST_SIZE = 100; // Number of transactions (by unique nonces) to keep in memory
export const TRANSACTION_EVENTS = { const SWAP_TRANSACTION_TYPES = [
ADDED: 'Transaction Added', TRANSACTION_TYPES.SWAP,
APPROVED: 'Transaction Approved', TRANSACTION_TYPES.SWAP_APPROVAL,
FINALIZED: 'Transaction Finalized', ];
REJECTED: 'Transaction Rejected',
SUBMITTED: 'Transaction Submitted', /**
}; * @typedef {import('../../../../shared/constants/transaction').TransactionMeta} TransactionMeta
* @typedef {import('../../../../shared/constants/transaction').TransactionMetaMetricsEventString} TransactionMetaMetricsEventString
*/
/** /**
* @typedef {Object} CustomGasSettings * @typedef {Object} CustomGasSettings
@ -118,6 +121,10 @@ export default class TransactionController extends EventEmitter {
this._trackMetaMetricsEvent = opts.trackMetaMetricsEvent; this._trackMetaMetricsEvent = opts.trackMetaMetricsEvent;
this._getParticipateInMetrics = opts.getParticipateInMetrics; this._getParticipateInMetrics = opts.getParticipateInMetrics;
this._getEIP1559GasFeeEstimates = opts.getEIP1559GasFeeEstimates; this._getEIP1559GasFeeEstimates = opts.getEIP1559GasFeeEstimates;
this.createEventFragment = opts.createEventFragment;
this.updateEventFragment = opts.updateEventFragment;
this.finalizeEventFragment = opts.finalizeEventFragment;
this.getEventFragmentById = opts.getEventFragmentById;
this.memStore = new ObservableStore({}); this.memStore = new ObservableStore({});
this.query = new EthQuery(this.provider); this.query = new EthQuery(this.provider);
@ -335,9 +342,19 @@ export default class TransactionController extends EventEmitter {
* *
* @param txParams * @param txParams
* @param origin * @param origin
* @param transactionType
* @returns {txMeta} * @returns {txMeta}
*/ */
async addUnapprovedTransaction(txParams, origin) { async addUnapprovedTransaction(txParams, origin, transactionType) {
if (
transactionType !== undefined &&
!SWAP_TRANSACTION_TYPES.includes(transactionType)
) {
throw new Error(
`TransactionController - invalid transactionType value: ${transactionType}`,
);
}
// validate // validate
const normalizedTxParams = txUtils.normalizeTxParams(txParams); const normalizedTxParams = txUtils.normalizeTxParams(txParams);
const eip1559Compatibility = await this.getEIP1559Compatibility(); const eip1559Compatibility = await this.getEIP1559Compatibility();
@ -379,7 +396,7 @@ export default class TransactionController extends EventEmitter {
const { type, getCodeResponse } = await this._determineTransactionType( const { type, getCodeResponse } = await this._determineTransactionType(
txParams, txParams,
); );
txMeta.type = type; txMeta.type = transactionType || type;
// ensure value // ensure value
txMeta.txParams.value = txMeta.txParams.value txMeta.txParams.value = txMeta.txParams.value
@ -432,7 +449,6 @@ export default class TransactionController extends EventEmitter {
gasLimit: defaultGasLimit, gasLimit: defaultGasLimit,
simulationFails, simulationFails,
} = await this._getDefaultGasLimit(txMeta, getCodeResponse); } = await this._getDefaultGasLimit(txMeta, getCodeResponse);
const advancedGasFeeDefaultValues = this.getAdvancedGasFee();
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
txMeta = this.txStateManager.getTransaction(txMeta.id); txMeta = this.txStateManager.getTransaction(txMeta.id);
@ -441,7 +457,13 @@ export default class TransactionController extends EventEmitter {
} }
if (eip1559Compatibility) { if (eip1559Compatibility) {
if (process.env.EIP_1559_V2 && Boolean(advancedGasFeeDefaultValues)) { const { eip1559V2Enabled } = this.preferencesStore.getState();
const advancedGasFeeDefaultValues = this.getAdvancedGasFee();
if (
eip1559V2Enabled &&
Boolean(advancedGasFeeDefaultValues) &&
!SWAP_TRANSACTION_TYPES.includes(txMeta.type)
) {
txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE; txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE;
txMeta.txParams.maxFeePerGas = decGWEIToHexWEI( txMeta.txParams.maxFeePerGas = decGWEIToHexWEI(
advancedGasFeeDefaultValues.maxBaseFee, advancedGasFeeDefaultValues.maxBaseFee,
@ -458,7 +480,7 @@ export default class TransactionController extends EventEmitter {
// then we set maxFeePerGas and maxPriorityFeePerGas to the suggested gasPrice. // then we set maxFeePerGas and maxPriorityFeePerGas to the suggested gasPrice.
txMeta.txParams.maxFeePerGas = txMeta.txParams.gasPrice; txMeta.txParams.maxFeePerGas = txMeta.txParams.gasPrice;
txMeta.txParams.maxPriorityFeePerGas = txMeta.txParams.gasPrice; txMeta.txParams.maxPriorityFeePerGas = txMeta.txParams.gasPrice;
if (process.env.EIP_1559_V2) { if (eip1559V2Enabled && txMeta.origin !== 'metamask') {
txMeta.userFeeLevel = PRIORITY_LEVELS.DAPP_SUGGESTED; txMeta.userFeeLevel = PRIORITY_LEVELS.DAPP_SUGGESTED;
} else { } else {
txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE; txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE;
@ -472,7 +494,7 @@ export default class TransactionController extends EventEmitter {
txMeta.origin === 'metamask' txMeta.origin === 'metamask'
) { ) {
txMeta.userFeeLevel = GAS_RECOMMENDATIONS.MEDIUM; txMeta.userFeeLevel = GAS_RECOMMENDATIONS.MEDIUM;
} else if (process.env.EIP_1559_V2) { } else if (eip1559V2Enabled) {
txMeta.userFeeLevel = PRIORITY_LEVELS.DAPP_SUGGESTED; txMeta.userFeeLevel = PRIORITY_LEVELS.DAPP_SUGGESTED;
} else { } else {
txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE; txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE;
@ -538,7 +560,15 @@ export default class TransactionController extends EventEmitter {
if (defaultGasLimit && !txMeta.txParams.gas) { if (defaultGasLimit && !txMeta.txParams.gas) {
txMeta.txParams.gas = defaultGasLimit; txMeta.txParams.gas = defaultGasLimit;
txMeta.originalGasEstimate = defaultGasLimit;
} }
txMeta.defaultGasEstimates = {
estimateType: txMeta.userFeeLevel,
gas: txMeta.txParams.gas,
gasPrice: txMeta.txParams.gasPrice,
maxFeePerGas: txMeta.txParams.maxFeePerGas,
maxPriorityFeePerGas: txMeta.txParams.maxPriorityFeePerGas,
};
return txMeta; return txMeta;
} }
@ -661,9 +691,8 @@ export default class TransactionController extends EventEmitter {
* which is defined by specifying a numerator. 11 is a 10% bump, 12 would be * which is defined by specifying a numerator. 11 is a 10% bump, 12 would be
* a 20% bump, and so on. * a 20% bump, and so on.
* *
* @param {import( * @param {TransactionMeta} originalTxMeta - Original transaction to use as
* '../../../../shared/constants/transaction' * base
* ).TransactionMeta} originalTxMeta - Original transaction to use as base
* @param {CustomGasSettings} [customGasSettings] - overrides for the gas * @param {CustomGasSettings} [customGasSettings] - overrides for the gas
* fields to use instead of the multiplier * fields to use instead of the multiplier
* @param {number} [incrementNumerator] - Numerator from which to generate a * @param {number} [incrementNumerator] - Numerator from which to generate a
@ -1119,6 +1148,28 @@ export default class TransactionController extends EventEmitter {
this.txStateManager.updateTransaction(txMeta, 'transactions#setTxHash'); this.txStateManager.updateTransaction(txMeta, 'transactions#setTxHash');
} }
/**
* Convenience method for the UI to easily create event fragments when the
* fragment does not exist in state.
*
* @param {number} transactionId - The transaction id to create the event
* fragment for
* @param {valueOf<TRANSACTION_EVENTS>} event - event type to create
*/
async createTransactionEventFragment(transactionId, event) {
const txMeta = this.txStateManager.getTransaction(transactionId);
const {
properties,
sensitiveProperties,
} = await this._buildEventFragmentProperties(txMeta);
this._createTransactionEventFragment(
txMeta,
event,
properties,
sensitiveProperties,
);
}
// //
// PRIVATE METHODS // PRIVATE METHODS
// //
@ -1449,20 +1500,7 @@ export default class TransactionController extends EventEmitter {
} }
} }
/** async _buildEventFragmentProperties(txMeta, extraParams) {
* Extracts relevant properties from a transaction meta
* object and uses them to create and send metrics for various transaction
* events.
*
* @param {Object} txMeta - the txMeta object
* @param {string} event - the name of the transaction event
* @param {Object} extraParams - optional props and values to include in sensitiveProperties
*/
_trackTransactionMetricsEvent(txMeta, event, extraParams = {}) {
if (!txMeta) {
return;
}
const { const {
type, type,
time, time,
@ -1477,6 +1515,7 @@ export default class TransactionController extends EventEmitter {
estimateSuggested, estimateSuggested,
estimateUsed, estimateUsed,
}, },
defaultGasEstimates,
metamaskNetworkId: network, metamaskNetworkId: network,
} = txMeta; } = txMeta;
const source = referrer === 'metamask' ? 'user' : 'dapp'; const source = referrer === 'metamask' ? 'user' : 'dapp';
@ -1490,6 +1529,43 @@ export default class TransactionController extends EventEmitter {
gasParams.gas_price = gasPrice; gasParams.gas_price = gasPrice;
} }
if (defaultGasEstimates) {
const { estimateType } = defaultGasEstimates;
if (estimateType) {
gasParams.default_estimate = estimateType;
let defaultMaxFeePerGas = txMeta.defaultGasEstimates.maxFeePerGas;
let defaultMaxPriorityFeePerGas =
txMeta.defaultGasEstimates.maxPriorityFeePerGas;
if (
[
GAS_RECOMMENDATIONS.LOW,
GAS_RECOMMENDATIONS.MEDIUM,
GAS_RECOMMENDATIONS.MEDIUM.HIGH,
].includes(estimateType)
) {
const { gasFeeEstimates } = await this._getEIP1559GasFeeEstimates();
if (gasFeeEstimates?.[estimateType]?.suggestedMaxFeePerGas) {
defaultMaxFeePerGas =
gasFeeEstimates[estimateType]?.suggestedMaxFeePerGas;
gasParams.default_max_fee_per_gas = defaultMaxFeePerGas;
}
if (gasFeeEstimates?.[estimateType]?.suggestedMaxPriorityFeePerGas) {
defaultMaxPriorityFeePerGas =
gasFeeEstimates[estimateType]?.suggestedMaxPriorityFeePerGas;
gasParams.default_max_priority_fee_per_gas = defaultMaxPriorityFeePerGas;
}
}
}
if (txMeta.defaultGasEstimates.gas) {
gasParams.default_gas = txMeta.defaultGasEstimates.gas;
}
if (txMeta.defaultGasEstimates.gasPrice) {
gasParams.default_gas_price = txMeta.defaultGasEstimates.gasPrice;
}
}
if (estimateSuggested) { if (estimateSuggested) {
gasParams.estimate_suggested = estimateSuggested; gasParams.estimate_suggested = estimateSuggested;
} }
@ -1500,27 +1576,211 @@ export default class TransactionController extends EventEmitter {
const gasParamsInGwei = this._getGasValuesInGWEI(gasParams); const gasParamsInGwei = this._getGasValuesInGWEI(gasParams);
this._trackMetaMetricsEvent({ let eip1559Version = '0';
if (txMeta.txParams.maxFeePerGas) {
const { eip1559V2Enabled } = this.preferencesStore.getState();
eip1559Version = eip1559V2Enabled ? '2' : '1';
}
const properties = {
chain_id: chainId,
referrer,
source,
network,
type,
eip_1559_version: eip1559Version,
gas_edit_type: 'none',
gas_edit_attempted: 'none',
};
const sensitiveProperties = {
status,
transaction_envelope_type: isEIP1559Transaction(txMeta)
? TRANSACTION_ENVELOPE_TYPE_NAMES.FEE_MARKET
: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY,
first_seen: time,
gas_limit: gasLimit,
...gasParamsInGwei,
...extraParams,
};
return { properties, sensitiveProperties };
}
/**
* Helper method that checks for the presence of an existing fragment by id
* appropriate for the type of event that triggered fragment creation. If the
* appropriate fragment exists, then nothing is done. If it does not exist a
* new event fragment is created with the appropriate payload.
*
* @param {TransactionMeta} txMeta - Transaction meta object
* @param {TransactionMetaMetricsEventString} event - The event type that
* triggered fragment creation
* @param {Object} properties - properties to include in the fragment
* @param {Object} [sensitiveProperties] - sensitive properties to include in
* the fragment
*/
_createTransactionEventFragment(
txMeta,
event,
properties,
sensitiveProperties,
) {
const isSubmitted = [
TRANSACTION_EVENTS.FINALIZED,
TRANSACTION_EVENTS.SUBMITTED,
].includes(event);
const uniqueIdentifier = `transaction-${
isSubmitted ? 'submitted' : 'added'
}-${txMeta.id}`;
const fragment = this.getEventFragmentById(uniqueIdentifier);
if (typeof fragment !== 'undefined') {
return;
}
switch (event) {
// When a transaction is added to the controller, we know that the user
// will be presented with a confirmation screen. The user will then
// either confirm or reject that transaction. Each has an associated
// event we want to track. While we don't necessarily need an event
// fragment to model this, having one allows us to record additional
// properties onto the event from the UI. For example, when the user
// edits the transactions gas params we can record that property and
// then get analytics on the number of transactions in which gas edits
// occur.
case TRANSACTION_EVENTS.ADDED:
this.createEventFragment({
category: 'Transactions',
initialEvent: TRANSACTION_EVENTS.ADDED,
successEvent: TRANSACTION_EVENTS.APPROVED,
failureEvent: TRANSACTION_EVENTS.REJECTED,
properties,
sensitiveProperties,
persist: true,
uniqueIdentifier,
});
break;
// If for some reason an approval or rejection occurs without the added
// fragment existing in memory, we create the added fragment but without
// the initialEvent firing. This is to prevent possible duplication of
// events. A good example why this might occur is if the user had
// unapproved transactions in memory when updating to the version that
// includes this change. A migration would have also helped here but this
// implementation hardens against other possible bugs where a fragment
// does not exist.
case TRANSACTION_EVENTS.APPROVED:
case TRANSACTION_EVENTS.REJECTED:
this.createEventFragment({
category: 'Transactions',
successEvent: TRANSACTION_EVENTS.APPROVED,
failureEvent: TRANSACTION_EVENTS.REJECTED,
properties,
sensitiveProperties,
persist: true,
uniqueIdentifier,
});
break;
// When a transaction is submitted it will always result in updating
// to a finalized state (dropped, failed, confirmed) -- eventually.
// However having a fragment started at this stage allows augmenting
// analytics data with user interactions such as speeding up and
// canceling the transactions. From this controllers perspective a new
// transaction with a new id is generated for speed up and cancel
// transactions, but from the UI we could augment the previous ID with
// supplemental data to show user intent. Such as when they open the
// cancel UI but don't submit. We can record that this happened and add
// properties to the transaction event.
case TRANSACTION_EVENTS.SUBMITTED:
this.createEventFragment({
category: 'Transactions',
initialEvent: TRANSACTION_EVENTS.SUBMITTED,
successEvent: TRANSACTION_EVENTS.FINALIZED,
properties,
sensitiveProperties,
persist: true,
uniqueIdentifier,
});
break;
// If for some reason a transaction is finalized without the submitted
// fragment existing in memory, we create the submitted fragment but
// without the initialEvent firing. This is to prevent possible
// duplication of events. A good example why this might occur is if th
// user had pending transactions in memory when updating to the version
// that includes this change. A migration would have also helped here but
// this implementation hardens against other possible bugs where a
// fragment does not exist.
case TRANSACTION_EVENTS.FINALIZED:
this.createEventFragment({
category: 'Transactions',
successEvent: TRANSACTION_EVENTS.FINALIZED,
properties,
sensitiveProperties,
persist: true,
uniqueIdentifier,
});
break;
default:
break;
}
}
/**
* Extracts relevant properties from a transaction meta
* object and uses them to create and send metrics for various transaction
* events.
*
* @param {Object} txMeta - the txMeta object
* @param {TransactionMetaMetricsEventString} event - the name of the transaction event
* @param {Object} extraParams - optional props and values to include in sensitiveProperties
*/
async _trackTransactionMetricsEvent(txMeta, event, extraParams = {}) {
if (!txMeta) {
return;
}
const {
properties,
sensitiveProperties,
} = await this._buildEventFragmentProperties(txMeta, extraParams);
// Create event fragments for event types that spawn fragments, and ensure
// existence of fragments for event types that act upon them.
this._createTransactionEventFragment(
txMeta,
event, event,
category: 'Transactions', properties,
properties: { sensitiveProperties,
chain_id: chainId, );
referrer,
source, let id;
network,
type, switch (event) {
}, // If the user approves a transaction, finalize the transaction added
sensitiveProperties: { // event fragment.
status, case TRANSACTION_EVENTS.APPROVED:
transaction_envelope_type: isEIP1559Transaction(txMeta) id = `transaction-added-${txMeta.id}`;
? TRANSACTION_ENVELOPE_TYPE_NAMES.FEE_MARKET this.updateEventFragment(id, { properties, sensitiveProperties });
: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY, this.finalizeEventFragment(id);
first_seen: time, break;
gas_limit: gasLimit, // If the user rejects a transaction, finalize the transaction added
...gasParamsInGwei, // event fragment. with the abandoned flag set.
...extraParams, case TRANSACTION_EVENTS.REJECTED:
}, id = `transaction-added-${txMeta.id}`;
}); this.updateEventFragment(id, { properties, sensitiveProperties });
this.finalizeEventFragment(id, {
abandoned: true,
});
break;
// When a transaction is finalized, also finalize the transaction
// submitted event fragment.
case TRANSACTION_EVENTS.FINALIZED:
id = `transaction-submitted-${txMeta.id}`;
this.updateEventFragment(id, { properties, sensitiveProperties });
this.finalizeEventFragment(`transaction-submitted-${txMeta.id}`);
break;
default:
break;
}
} }
_getTransactionCompletionTime(submittedTime) { _getTransactionCompletionTime(submittedTime) {

@ -9,10 +9,12 @@ import {
createTestProviderTools, createTestProviderTools,
getTestAccounts, getTestAccounts,
} from '../../../../test/stub/provider'; } from '../../../../test/stub/provider';
import mockEstimates from '../../../../test/data/mock-estimates.json';
import { import {
TRANSACTION_STATUSES, TRANSACTION_STATUSES,
TRANSACTION_TYPES, TRANSACTION_TYPES,
TRANSACTION_ENVELOPE_TYPES, TRANSACTION_ENVELOPE_TYPES,
TRANSACTION_EVENTS,
} from '../../../../shared/constants/transaction'; } from '../../../../shared/constants/transaction';
import { SECOND } from '../../../../shared/constants/time'; import { SECOND } from '../../../../shared/constants/time';
@ -22,7 +24,7 @@ import {
} from '../../../../shared/constants/gas'; } from '../../../../shared/constants/gas';
import { TRANSACTION_ENVELOPE_TYPE_NAMES } from '../../../../ui/helpers/constants/transactions'; import { TRANSACTION_ENVELOPE_TYPE_NAMES } from '../../../../ui/helpers/constants/transactions';
import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller'; import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller';
import TransactionController, { TRANSACTION_EVENTS } from '.'; import TransactionController from '.';
const noop = () => true; const noop = () => true;
const currentNetworkId = '42'; const currentNetworkId = '42';
@ -35,17 +37,21 @@ const VALID_ADDRESS = '0x0000000000000000000000000000000000000000';
const VALID_ADDRESS_TWO = '0x0000000000000000000000000000000000000001'; const VALID_ADDRESS_TWO = '0x0000000000000000000000000000000000000001';
describe('Transaction Controller', function () { describe('Transaction Controller', function () {
let txController, provider, providerResultStub, fromAccount; let txController, provider, providerResultStub, fromAccount, fragmentExists;
beforeEach(function () { beforeEach(function () {
fragmentExists = false;
providerResultStub = { providerResultStub = {
// 1 gwei // 1 gwei
eth_gasPrice: '0x0de0b6b3a7640000', eth_gasPrice: '0x0de0b6b3a7640000',
// by default, all accounts are external accounts (not contracts) // by default, all accounts are external accounts (not contracts)
eth_getCode: '0x', eth_getCode: '0x',
}; };
provider = createTestProviderTools({ scaffold: providerResultStub }) provider = createTestProviderTools({
.provider; scaffold: providerResultStub,
networkId: currentNetworkId,
chainId: currentNetworkId,
}).provider;
fromAccount = getTestAccounts()[0]; fromAccount = getTestAccounts()[0];
const blockTrackerStub = new EventEmitter(); const blockTrackerStub = new EventEmitter();
@ -70,6 +76,11 @@ describe('Transaction Controller', function () {
getCurrentChainId: () => currentChainId, getCurrentChainId: () => currentChainId,
getParticipateInMetrics: () => false, getParticipateInMetrics: () => false,
trackMetaMetricsEvent: () => undefined, trackMetaMetricsEvent: () => undefined,
createEventFragment: () => undefined,
updateEventFragment: () => undefined,
finalizeEventFragment: () => undefined,
getEventFragmentById: () =>
fragmentExists === false ? undefined : { id: 0 },
getEIP1559GasFeeEstimates: () => undefined, getEIP1559GasFeeEstimates: () => undefined,
}); });
txController.nonceTracker.getNonceLock = () => txController.nonceTracker.getNonceLock = () =>
@ -1536,66 +1547,357 @@ describe('Transaction Controller', function () {
describe('#_trackTransactionMetricsEvent', function () { describe('#_trackTransactionMetricsEvent', function () {
let trackMetaMetricsEventSpy; let trackMetaMetricsEventSpy;
let createEventFragmentSpy;
let finalizeEventFragmentSpy;
beforeEach(function () { beforeEach(function () {
trackMetaMetricsEventSpy = sinon.spy( trackMetaMetricsEventSpy = sinon.spy(
txController, txController,
'_trackMetaMetricsEvent', '_trackMetaMetricsEvent',
); );
createEventFragmentSpy = sinon.spy(txController, 'createEventFragment');
finalizeEventFragmentSpy = sinon.spy(
txController,
'finalizeEventFragment',
);
sinon
.stub(txController, '_getEIP1559GasFeeEstimates')
.resolves(mockEstimates['fee-market']);
}); });
afterEach(function () { afterEach(function () {
trackMetaMetricsEventSpy.restore(); trackMetaMetricsEventSpy.restore();
createEventFragmentSpy.restore();
finalizeEventFragmentSpy.restore();
}); });
it('should call _trackMetaMetricsEvent with the correct payload (user source)', function () { describe('On transaction created by the user', function () {
const txMeta = { let txMeta;
id: 1, before(function () {
status: TRANSACTION_STATUSES.UNAPPROVED, txMeta = {
txParams: { id: 1,
from: fromAccount.address, status: TRANSACTION_STATUSES.UNAPPROVED,
to: '0x1678a085c290ebd122dc42cba69373b5953b831d', txParams: {
gasPrice: '0x77359400', from: fromAccount.address,
gas: '0x7b0d', to: '0x1678a085c290ebd122dc42cba69373b5953b831d',
nonce: '0x4b', gasPrice: '0x77359400',
}, gas: '0x7b0d',
type: TRANSACTION_TYPES.SIMPLE_SEND, nonce: '0x4b',
origin: 'metamask', },
chainId: currentChainId,
time: 1624408066355,
metamaskNetworkId: currentNetworkId,
};
const expectedPayload = {
event: 'Transaction Added',
category: 'Transactions',
properties: {
chain_id: '0x2a',
network: '42',
referrer: 'metamask',
source: 'user',
type: TRANSACTION_TYPES.SIMPLE_SEND, type: TRANSACTION_TYPES.SIMPLE_SEND,
}, origin: 'metamask',
sensitiveProperties: { chainId: currentChainId,
gas_price: '2', time: 1624408066355,
gas_limit: '0x7b0d', metamaskNetworkId: currentNetworkId,
first_seen: 1624408066355, defaultGasEstimates: {
transaction_envelope_type: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY, gas: '0x7b0d',
status: 'unapproved', gasPrice: '0x77359400',
}, },
}; };
});
txController._trackTransactionMetricsEvent( it('should create an event fragment when transaction added', async function () {
txMeta, const expectedPayload = {
TRANSACTION_EVENTS.ADDED, initialEvent: 'Transaction Added',
); successEvent: 'Transaction Approved',
assert.equal(trackMetaMetricsEventSpy.callCount, 1); failureEvent: 'Transaction Rejected',
assert.deepEqual( uniqueIdentifier: 'transaction-added-1',
trackMetaMetricsEventSpy.getCall(0).args[0], category: 'Transactions',
expectedPayload, persist: true,
); properties: {
chain_id: '0x2a',
eip_1559_version: '0',
gas_edit_attempted: 'none',
gas_edit_type: 'none',
network: '42',
referrer: 'metamask',
source: 'user',
type: TRANSACTION_TYPES.SIMPLE_SEND,
},
sensitiveProperties: {
default_gas: '0.000031501',
default_gas_price: '2',
gas_price: '2',
gas_limit: '0x7b0d',
first_seen: 1624408066355,
transaction_envelope_type: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY,
status: 'unapproved',
},
};
await txController._trackTransactionMetricsEvent(
txMeta,
TRANSACTION_EVENTS.ADDED,
);
assert.equal(createEventFragmentSpy.callCount, 1);
assert.equal(finalizeEventFragmentSpy.callCount, 0);
assert.deepEqual(
createEventFragmentSpy.getCall(0).args[0],
expectedPayload,
);
});
it('Should finalize the transaction added fragment as abandoned if user rejects transaction', async function () {
fragmentExists = true;
await txController._trackTransactionMetricsEvent(
txMeta,
TRANSACTION_EVENTS.REJECTED,
);
assert.equal(createEventFragmentSpy.callCount, 0);
assert.equal(finalizeEventFragmentSpy.callCount, 1);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[0],
'transaction-added-1',
);
assert.deepEqual(finalizeEventFragmentSpy.getCall(0).args[1], {
abandoned: true,
});
});
it('Should finalize the transaction added fragment if user approves transaction', async function () {
fragmentExists = true;
await txController._trackTransactionMetricsEvent(
txMeta,
TRANSACTION_EVENTS.APPROVED,
);
assert.equal(createEventFragmentSpy.callCount, 0);
assert.equal(finalizeEventFragmentSpy.callCount, 1);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[0],
'transaction-added-1',
);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[1],
undefined,
);
});
it('should create an event fragment when transaction is submitted', async function () {
const expectedPayload = {
initialEvent: 'Transaction Submitted',
successEvent: 'Transaction Finalized',
uniqueIdentifier: 'transaction-submitted-1',
category: 'Transactions',
persist: true,
properties: {
chain_id: '0x2a',
eip_1559_version: '0',
gas_edit_attempted: 'none',
gas_edit_type: 'none',
network: '42',
referrer: 'metamask',
source: 'user',
type: TRANSACTION_TYPES.SIMPLE_SEND,
},
sensitiveProperties: {
default_gas: '0.000031501',
default_gas_price: '2',
gas_price: '2',
gas_limit: '0x7b0d',
first_seen: 1624408066355,
transaction_envelope_type: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY,
status: 'unapproved',
},
};
await txController._trackTransactionMetricsEvent(
txMeta,
TRANSACTION_EVENTS.SUBMITTED,
);
assert.equal(createEventFragmentSpy.callCount, 1);
assert.equal(finalizeEventFragmentSpy.callCount, 0);
assert.deepEqual(
createEventFragmentSpy.getCall(0).args[0],
expectedPayload,
);
});
it('Should finalize the transaction submitted fragment when transaction finalizes', async function () {
fragmentExists = true;
await txController._trackTransactionMetricsEvent(
txMeta,
TRANSACTION_EVENTS.FINALIZED,
);
assert.equal(createEventFragmentSpy.callCount, 0);
assert.equal(finalizeEventFragmentSpy.callCount, 1);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[0],
'transaction-submitted-1',
);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[1],
undefined,
);
});
});
describe('On transaction suggested by dapp', function () {
let txMeta;
before(function () {
txMeta = {
id: 1,
status: TRANSACTION_STATUSES.UNAPPROVED,
txParams: {
from: fromAccount.address,
to: '0x1678a085c290ebd122dc42cba69373b5953b831d',
gasPrice: '0x77359400',
gas: '0x7b0d',
nonce: '0x4b',
},
type: TRANSACTION_TYPES.SIMPLE_SEND,
origin: 'other',
chainId: currentChainId,
time: 1624408066355,
metamaskNetworkId: currentNetworkId,
defaultGasEstimates: {
gas: '0x7b0d',
gasPrice: '0x77359400',
},
};
});
it('should create an event fragment when transaction added', async function () {
const expectedPayload = {
initialEvent: 'Transaction Added',
successEvent: 'Transaction Approved',
failureEvent: 'Transaction Rejected',
uniqueIdentifier: 'transaction-added-1',
category: 'Transactions',
persist: true,
properties: {
chain_id: '0x2a',
eip_1559_version: '0',
gas_edit_attempted: 'none',
gas_edit_type: 'none',
network: '42',
referrer: 'other',
source: 'dapp',
type: TRANSACTION_TYPES.SIMPLE_SEND,
},
sensitiveProperties: {
default_gas: '0.000031501',
default_gas_price: '2',
gas_price: '2',
gas_limit: '0x7b0d',
first_seen: 1624408066355,
transaction_envelope_type: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY,
status: 'unapproved',
},
};
await txController._trackTransactionMetricsEvent(
txMeta,
TRANSACTION_EVENTS.ADDED,
);
assert.equal(createEventFragmentSpy.callCount, 1);
assert.equal(finalizeEventFragmentSpy.callCount, 0);
assert.deepEqual(
createEventFragmentSpy.getCall(0).args[0],
expectedPayload,
);
});
it('Should finalize the transaction added fragment as abandoned if user rejects transaction', async function () {
fragmentExists = true;
await txController._trackTransactionMetricsEvent(
txMeta,
TRANSACTION_EVENTS.REJECTED,
);
assert.equal(createEventFragmentSpy.callCount, 0);
assert.equal(finalizeEventFragmentSpy.callCount, 1);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[0],
'transaction-added-1',
);
assert.deepEqual(finalizeEventFragmentSpy.getCall(0).args[1], {
abandoned: true,
});
});
it('Should finalize the transaction added fragment if user approves transaction', async function () {
fragmentExists = true;
await txController._trackTransactionMetricsEvent(
txMeta,
TRANSACTION_EVENTS.APPROVED,
);
assert.equal(createEventFragmentSpy.callCount, 0);
assert.equal(finalizeEventFragmentSpy.callCount, 1);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[0],
'transaction-added-1',
);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[1],
undefined,
);
});
it('should create an event fragment when transaction is submitted', async function () {
const expectedPayload = {
initialEvent: 'Transaction Submitted',
successEvent: 'Transaction Finalized',
uniqueIdentifier: 'transaction-submitted-1',
category: 'Transactions',
persist: true,
properties: {
chain_id: '0x2a',
eip_1559_version: '0',
gas_edit_attempted: 'none',
gas_edit_type: 'none',
network: '42',
referrer: 'other',
source: 'dapp',
type: TRANSACTION_TYPES.SIMPLE_SEND,
},
sensitiveProperties: {
default_gas: '0.000031501',
default_gas_price: '2',
gas_price: '2',
gas_limit: '0x7b0d',
first_seen: 1624408066355,
transaction_envelope_type: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY,
status: 'unapproved',
},
};
await txController._trackTransactionMetricsEvent(
txMeta,
TRANSACTION_EVENTS.SUBMITTED,
);
assert.equal(createEventFragmentSpy.callCount, 1);
assert.equal(finalizeEventFragmentSpy.callCount, 0);
assert.deepEqual(
createEventFragmentSpy.getCall(0).args[0],
expectedPayload,
);
});
it('Should finalize the transaction submitted fragment when transaction finalizes', async function () {
fragmentExists = true;
await txController._trackTransactionMetricsEvent(
txMeta,
TRANSACTION_EVENTS.FINALIZED,
);
assert.equal(createEventFragmentSpy.callCount, 0);
assert.equal(finalizeEventFragmentSpy.callCount, 1);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[0],
'transaction-submitted-1',
);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[1],
undefined,
);
});
}); });
it('should call _trackMetaMetricsEvent with the correct payload (dapp source)', function () { it('should create missing fragments when events happen out of order or are missing', async function () {
const txMeta = { const txMeta = {
id: 1, id: 1,
status: TRANSACTION_STATUSES.UNAPPROVED, status: TRANSACTION_STATUSES.UNAPPROVED,
@ -1612,11 +1914,18 @@ describe('Transaction Controller', function () {
time: 1624408066355, time: 1624408066355,
metamaskNetworkId: currentNetworkId, metamaskNetworkId: currentNetworkId,
}; };
const expectedPayload = { const expectedPayload = {
event: 'Transaction Added', successEvent: 'Transaction Approved',
failureEvent: 'Transaction Rejected',
uniqueIdentifier: 'transaction-added-1',
category: 'Transactions', category: 'Transactions',
persist: true,
properties: { properties: {
chain_id: '0x2a', chain_id: '0x2a',
eip_1559_version: '0',
gas_edit_attempted: 'none',
gas_edit_type: 'none',
network: '42', network: '42',
referrer: 'other', referrer: 'other',
source: 'dapp', source: 'dapp',
@ -1630,19 +1939,24 @@ describe('Transaction Controller', function () {
status: 'unapproved', status: 'unapproved',
}, },
}; };
await txController._trackTransactionMetricsEvent(
txController._trackTransactionMetricsEvent(
txMeta, txMeta,
TRANSACTION_EVENTS.ADDED, TRANSACTION_EVENTS.APPROVED,
); );
assert.equal(trackMetaMetricsEventSpy.callCount, 1); assert.equal(createEventFragmentSpy.callCount, 1);
assert.deepEqual( assert.deepEqual(
trackMetaMetricsEventSpy.getCall(0).args[0], createEventFragmentSpy.getCall(0).args[0],
expectedPayload, expectedPayload,
); );
assert.equal(finalizeEventFragmentSpy.callCount, 1);
assert.deepEqual(
finalizeEventFragmentSpy.getCall(0).args[0],
'transaction-added-1',
);
assert.deepEqual(finalizeEventFragmentSpy.getCall(0).args[1], undefined);
}); });
it('should call _trackMetaMetricsEvent with the correct payload (extra params)', function () { it('should call _trackMetaMetricsEvent with the correct payload (extra params)', async function () {
const txMeta = { const txMeta = {
id: 1, id: 1,
status: TRANSACTION_STATUSES.UNAPPROVED, status: TRANSACTION_STATUSES.UNAPPROVED,
@ -1660,7 +1974,11 @@ describe('Transaction Controller', function () {
metamaskNetworkId: currentNetworkId, metamaskNetworkId: currentNetworkId,
}; };
const expectedPayload = { const expectedPayload = {
event: 'Transaction Added', initialEvent: 'Transaction Added',
successEvent: 'Transaction Approved',
failureEvent: 'Transaction Rejected',
uniqueIdentifier: 'transaction-added-1',
persist: true,
category: 'Transactions', category: 'Transactions',
properties: { properties: {
network: '42', network: '42',
@ -1668,6 +1986,9 @@ describe('Transaction Controller', function () {
source: 'dapp', source: 'dapp',
type: TRANSACTION_TYPES.SIMPLE_SEND, type: TRANSACTION_TYPES.SIMPLE_SEND,
chain_id: '0x2a', chain_id: '0x2a',
eip_1559_version: '0',
gas_edit_attempted: 'none',
gas_edit_type: 'none',
}, },
sensitiveProperties: { sensitiveProperties: {
baz: 3.0, baz: 3.0,
@ -1680,7 +2001,7 @@ describe('Transaction Controller', function () {
}, },
}; };
txController._trackTransactionMetricsEvent( await txController._trackTransactionMetricsEvent(
txMeta, txMeta,
TRANSACTION_EVENTS.ADDED, TRANSACTION_EVENTS.ADDED,
{ {
@ -1688,14 +2009,15 @@ describe('Transaction Controller', function () {
foo: 'bar', foo: 'bar',
}, },
); );
assert.equal(trackMetaMetricsEventSpy.callCount, 1); assert.equal(createEventFragmentSpy.callCount, 1);
assert.equal(finalizeEventFragmentSpy.callCount, 0);
assert.deepEqual( assert.deepEqual(
trackMetaMetricsEventSpy.getCall(0).args[0], createEventFragmentSpy.getCall(0).args[0],
expectedPayload, expectedPayload,
); );
}); });
it('should call _trackMetaMetricsEvent with the correct payload (EIP-1559)', function () { it('should call _trackMetaMetricsEvent with the correct payload (EIP-1559)', async function () {
const txMeta = { const txMeta = {
id: 1, id: 1,
status: TRANSACTION_STATUSES.UNAPPROVED, status: TRANSACTION_STATUSES.UNAPPROVED,
@ -1714,12 +2036,24 @@ describe('Transaction Controller', function () {
chainId: currentChainId, chainId: currentChainId,
time: 1624408066355, time: 1624408066355,
metamaskNetworkId: currentNetworkId, metamaskNetworkId: currentNetworkId,
defaultGasEstimates: {
estimateType: 'medium',
maxFeePerGas: '0x77359400',
maxPriorityFeePerGas: '0x77359400',
},
}; };
const expectedPayload = { const expectedPayload = {
event: 'Transaction Added', initialEvent: 'Transaction Added',
successEvent: 'Transaction Approved',
failureEvent: 'Transaction Rejected',
uniqueIdentifier: 'transaction-added-1',
persist: true,
category: 'Transactions', category: 'Transactions',
properties: { properties: {
chain_id: '0x2a', chain_id: '0x2a',
eip_1559_version: '1',
gas_edit_attempted: 'none',
gas_edit_type: 'none',
network: '42', network: '42',
referrer: 'other', referrer: 'other',
source: 'dapp', source: 'dapp',
@ -1736,10 +2070,13 @@ describe('Transaction Controller', function () {
status: 'unapproved', status: 'unapproved',
estimate_suggested: GAS_RECOMMENDATIONS.MEDIUM, estimate_suggested: GAS_RECOMMENDATIONS.MEDIUM,
estimate_used: GAS_RECOMMENDATIONS.HIGH, estimate_used: GAS_RECOMMENDATIONS.HIGH,
default_estimate: 'medium',
default_max_fee_per_gas: '70',
default_max_priority_fee_per_gas: '7',
}, },
}; };
txController._trackTransactionMetricsEvent( await txController._trackTransactionMetricsEvent(
txMeta, txMeta,
TRANSACTION_EVENTS.ADDED, TRANSACTION_EVENTS.ADDED,
{ {
@ -1747,9 +2084,10 @@ describe('Transaction Controller', function () {
foo: 'bar', foo: 'bar',
}, },
); );
assert.equal(trackMetaMetricsEventSpy.callCount, 1); assert.equal(createEventFragmentSpy.callCount, 1);
assert.equal(finalizeEventFragmentSpy.callCount, 0);
assert.deepEqual( assert.deepEqual(
trackMetaMetricsEventSpy.getCall(0).args[0], createEventFragmentSpy.getCall(0).args[0],
expectedPayload, expectedPayload,
); );
}); });

@ -117,6 +117,8 @@ export default class TransactionStateManager extends EventEmitter {
time: new Date().getTime(), time: new Date().getTime(),
status: TRANSACTION_STATUSES.UNAPPROVED, status: TRANSACTION_STATUSES.UNAPPROVED,
metamaskNetworkId: netId, metamaskNetworkId: netId,
originalGasEstimate: opts.txParams?.gas,
userEditedGasLimit: false,
chainId, chainId,
loadingDefaults: true, loadingDefaults: true,
dappSuggestedGasFees, dappSuggestedGasFees,

@ -1,75 +0,0 @@
import nock from 'nock';
import {
KOVAN_CHAIN_ID,
MAINNET_CHAIN_ID,
RINKEBY_CHAIN_ID,
ROPSTEN_CHAIN_ID,
} from '../../../shared/constants/network';
import { TRANSAK_API_KEY } from '../constants/on-ramp';
import { SWAPS_API_V2_BASE_URL } from '../../../shared/constants/swaps';
import getBuyEthUrl from './buy-eth-url';
const WYRE_ACCOUNT_ID = 'AC-7AG3W4XH4N2';
const ETH_ADDRESS = '0x0dcd5d886577d5581b0c524242ef2ee70be3e7bc';
const MAINNET = {
chainId: MAINNET_CHAIN_ID,
amount: 5,
address: ETH_ADDRESS,
};
const ROPSTEN = {
chainId: ROPSTEN_CHAIN_ID,
};
const RINKEBY = {
chainId: RINKEBY_CHAIN_ID,
};
const KOVAN = {
chainId: KOVAN_CHAIN_ID,
};
describe('buy-eth-url', () => {
it('returns Wyre url with an ETH address for Ethereum mainnet', async () => {
nock(SWAPS_API_V2_BASE_URL)
.get(
`/networks/1/fiatOnRampUrl?serviceName=wyre&destinationAddress=${ETH_ADDRESS}`,
)
.reply(200, {
url: `https://pay.sendwyre.com/purchase?accountId=${WYRE_ACCOUNT_ID}&utm_campaign=${WYRE_ACCOUNT_ID}&destCurrency=ETH&utm_medium=widget&paymentMethod=debit-card&reservation=MLZVUF8FMXZUMARJC23B&dest=ethereum%3A${ETH_ADDRESS}&utm_source=checkout`,
});
const wyreUrl = await getBuyEthUrl(MAINNET);
expect(wyreUrl).toStrictEqual(
`https://pay.sendwyre.com/purchase?accountId=${WYRE_ACCOUNT_ID}&utm_campaign=${WYRE_ACCOUNT_ID}&destCurrency=ETH&utm_medium=widget&paymentMethod=debit-card&reservation=MLZVUF8FMXZUMARJC23B&dest=ethereum%3A${ETH_ADDRESS}&utm_source=checkout`,
);
nock.cleanAll();
});
it('returns a fallback Wyre url if /orders/reserve API call fails', async () => {
const wyreUrl = await getBuyEthUrl(MAINNET);
expect(wyreUrl).toStrictEqual(
`https://pay.sendwyre.com/purchase?dest=ethereum:${ETH_ADDRESS}&destCurrency=ETH&accountId=${WYRE_ACCOUNT_ID}&paymentMethod=debit-card`,
);
});
it('returns Transak url with an ETH address for Ethereum mainnet', async () => {
const transakUrl = await getBuyEthUrl({ ...MAINNET, service: 'transak' });
expect(transakUrl).toStrictEqual(
`https://global.transak.com/?apiKey=${TRANSAK_API_KEY}&hostURL=https%3A%2F%2Fmetamask.io&defaultCryptoCurrency=ETH&walletAddress=${ETH_ADDRESS}`,
);
});
it('returns metamask ropsten faucet for network 3', async () => {
const ropstenUrl = await getBuyEthUrl(ROPSTEN);
expect(ropstenUrl).toStrictEqual('https://faucet.metamask.io/');
});
it('returns rinkeby dapp for network 4', async () => {
const rinkebyUrl = await getBuyEthUrl(RINKEBY);
expect(rinkebyUrl).toStrictEqual('https://www.rinkeby.io/');
});
it('returns kovan github test faucet for network 42', async () => {
const kovanUrl = await getBuyEthUrl(KOVAN);
expect(kovanUrl).toStrictEqual('https://github.com/kovan-testnet/faucet');
});
});

@ -8,6 +8,7 @@ import {
RINKEBY_CHAIN_ID, RINKEBY_CHAIN_ID,
ROPSTEN_CHAIN_ID, ROPSTEN_CHAIN_ID,
MAINNET_NETWORK_ID, MAINNET_NETWORK_ID,
BUYABLE_CHAINS_MAP,
} from '../../../shared/constants/network'; } from '../../../shared/constants/network';
import { SECOND } from '../../../shared/constants/time'; import { SECOND } from '../../../shared/constants/time';
import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'; import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout';
@ -47,16 +48,22 @@ const createWyrePurchaseUrl = async (address) => {
* Create a Transak Checkout URL. * Create a Transak Checkout URL.
* API docs here: https://www.notion.so/Query-Parameters-9ec523df3b874ec58cef4fa3a906f238 * API docs here: https://www.notion.so/Query-Parameters-9ec523df3b874ec58cef4fa3a906f238
* *
* @param {string} address - Ethereum destination address * @param {string} walletAddress - Ethereum destination address
* @param {string} chainId - Current chain ID
* @returns String * @returns String
*/ */
const createTransakUrl = (address) => { const createTransakUrl = (walletAddress, chainId) => {
const { transakCurrencies, network } = BUYABLE_CHAINS_MAP[chainId];
const queryParams = new URLSearchParams({ const queryParams = new URLSearchParams({
apiKey: TRANSAK_API_KEY, apiKey: TRANSAK_API_KEY,
hostURL: 'https://metamask.io', hostURL: 'https://metamask.io',
defaultCryptoCurrency: 'ETH', cryptoCurrencyList: transakCurrencies.join(','),
walletAddress: address, defaultCryptoCurrency: transakCurrencies[0],
networks: network,
walletAddress,
}); });
return `https://global.transak.com/?${queryParams}`; return `https://global.transak.com/?${queryParams}`;
}; };
@ -70,7 +77,7 @@ const createTransakUrl = (address) => {
* @returns {string|undefined} The url at which the user can access ETH, while in the given chain. If the passed * @returns {string|undefined} The url at which the user can access ETH, while in the given chain. If the passed
* chainId does not match any of the specified cases, or if no chainId is given, returns undefined. * chainId does not match any of the specified cases, or if no chainId is given, returns undefined.
*/ */
export default async function getBuyEthUrl({ chainId, address, service }) { export default async function getBuyUrl({ chainId, address, service }) {
// default service by network if not specified // default service by network if not specified
if (!service) { if (!service) {
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
@ -81,7 +88,7 @@ export default async function getBuyEthUrl({ chainId, address, service }) {
case 'wyre': case 'wyre':
return await createWyrePurchaseUrl(address); return await createWyrePurchaseUrl(address);
case 'transak': case 'transak':
return createTransakUrl(address); return createTransakUrl(address, chainId);
case 'metamask-faucet': case 'metamask-faucet':
return 'https://faucet.metamask.io/'; return 'https://faucet.metamask.io/';
case 'rinkeby-faucet': case 'rinkeby-faucet':

@ -0,0 +1,117 @@
import nock from 'nock';
import {
KOVAN_CHAIN_ID,
MAINNET_CHAIN_ID,
RINKEBY_CHAIN_ID,
ROPSTEN_CHAIN_ID,
BSC_CHAIN_ID,
POLYGON_CHAIN_ID,
ETH_SYMBOL,
BUYABLE_CHAINS_MAP,
} from '../../../shared/constants/network';
import { TRANSAK_API_KEY } from '../constants/on-ramp';
import { SWAPS_API_V2_BASE_URL } from '../../../shared/constants/swaps';
import getBuyUrl from './buy-url';
const WYRE_ACCOUNT_ID = 'AC-7AG3W4XH4N2';
const ETH_ADDRESS = '0x0dcd5d886577d5581b0c524242ef2ee70be3e7bc';
const MAINNET = {
chainId: MAINNET_CHAIN_ID,
amount: 5,
address: ETH_ADDRESS,
};
const ROPSTEN = {
chainId: ROPSTEN_CHAIN_ID,
};
const RINKEBY = {
chainId: RINKEBY_CHAIN_ID,
};
const KOVAN = {
chainId: KOVAN_CHAIN_ID,
};
const BSC = {
chainId: BSC_CHAIN_ID,
amount: 5,
address: ETH_ADDRESS,
};
const POLYGON = {
chainId: POLYGON_CHAIN_ID,
amount: 5,
address: ETH_ADDRESS,
};
describe('buy-url', () => {
it('returns Wyre url with an ETH address for Ethereum mainnet', async () => {
nock(SWAPS_API_V2_BASE_URL)
.get(
`/networks/1/fiatOnRampUrl?serviceName=wyre&destinationAddress=${ETH_ADDRESS}`,
)
.reply(200, {
url: `https://pay.sendwyre.com/purchase?accountId=${WYRE_ACCOUNT_ID}&utm_campaign=${WYRE_ACCOUNT_ID}&destCurrency=${ETH_SYMBOL}&utm_medium=widget&paymentMethod=debit-card&reservation=MLZVUF8FMXZUMARJC23B&dest=ethereum%3A${ETH_ADDRESS}&utm_source=checkout`,
});
const wyreUrl = await getBuyUrl(MAINNET);
expect(wyreUrl).toStrictEqual(
`https://pay.sendwyre.com/purchase?accountId=${WYRE_ACCOUNT_ID}&utm_campaign=${WYRE_ACCOUNT_ID}&destCurrency=${ETH_SYMBOL}&utm_medium=widget&paymentMethod=debit-card&reservation=MLZVUF8FMXZUMARJC23B&dest=ethereum%3A${ETH_ADDRESS}&utm_source=checkout`,
);
nock.cleanAll();
});
it('returns a fallback Wyre url if /orders/reserve API call fails', async () => {
const wyreUrl = await getBuyUrl(MAINNET);
expect(wyreUrl).toStrictEqual(
`https://pay.sendwyre.com/purchase?dest=ethereum:${ETH_ADDRESS}&destCurrency=${ETH_SYMBOL}&accountId=${WYRE_ACCOUNT_ID}&paymentMethod=debit-card`,
);
});
it('returns Transak url with an ETH address for Ethereum mainnet', async () => {
const transakUrl = await getBuyUrl({ ...MAINNET, service: 'transak' });
const buyableChain = BUYABLE_CHAINS_MAP[MAINNET.chainId];
const buyableCurrencies = encodeURIComponent(
buyableChain.transakCurrencies.join(','),
);
expect(transakUrl).toStrictEqual(
`https://global.transak.com/?apiKey=${TRANSAK_API_KEY}&hostURL=https%3A%2F%2Fmetamask.io&cryptoCurrencyList=${buyableCurrencies}&defaultCryptoCurrency=${buyableChain.transakCurrencies[0]}&networks=${buyableChain.network}&walletAddress=${ETH_ADDRESS}`,
);
});
it('returns Transak url with an BNB address for Binance Smart Chain', async () => {
const transakUrl = await getBuyUrl({ ...BSC, service: 'transak' });
const buyableChain = BUYABLE_CHAINS_MAP[BSC.chainId];
const buyableCurrencies = encodeURIComponent(
buyableChain.transakCurrencies.join(','),
);
expect(transakUrl).toStrictEqual(
`https://global.transak.com/?apiKey=${TRANSAK_API_KEY}&hostURL=https%3A%2F%2Fmetamask.io&cryptoCurrencyList=${buyableCurrencies}&defaultCryptoCurrency=${buyableChain.transakCurrencies[0]}&networks=${buyableChain.network}&walletAddress=${ETH_ADDRESS}`,
);
});
it('returns Transak url with an MATIC address for Polygon', async () => {
const transakUrl = await getBuyUrl({ ...POLYGON, service: 'transak' });
const buyableChain = BUYABLE_CHAINS_MAP[POLYGON.chainId];
const buyableCurrencies = encodeURIComponent(
buyableChain.transakCurrencies.join(','),
);
expect(transakUrl).toStrictEqual(
`https://global.transak.com/?apiKey=${TRANSAK_API_KEY}&hostURL=https%3A%2F%2Fmetamask.io&cryptoCurrencyList=${buyableCurrencies}&defaultCryptoCurrency=${buyableChain.transakCurrencies[0]}&networks=${buyableChain.network}&walletAddress=${ETH_ADDRESS}`,
);
});
it('returns metamask ropsten faucet for network 3', async () => {
const ropstenUrl = await getBuyUrl(ROPSTEN);
expect(ropstenUrl).toStrictEqual('https://faucet.metamask.io/');
});
it('returns rinkeby dapp for network 4', async () => {
const rinkebyUrl = await getBuyUrl(RINKEBY);
expect(rinkebyUrl).toStrictEqual('https://www.rinkeby.io/');
});
it('returns kovan github test faucet for network 42', async () => {
const kovanUrl = await getBuyUrl(KOVAN);
expect(kovanUrl).toStrictEqual('https://github.com/kovan-testnet/faucet');
});
});

@ -220,22 +220,22 @@ export default class MetamaskController extends EventEmitter {
onNetworkStateChange: this.networkController.store.subscribe.bind( onNetworkStateChange: this.networkController.store.subscribe.bind(
this.networkController.store, this.networkController.store,
), ),
getAssetName: this.assetsContractController.getAssetName.bind( getERC721AssetName: this.assetsContractController.getERC721AssetName.bind(
this.assetsContractController, this.assetsContractController,
), ),
getAssetSymbol: this.assetsContractController.getAssetSymbol.bind( getERC721AssetSymbol: this.assetsContractController.getERC721AssetSymbol.bind(
this.assetsContractController, this.assetsContractController,
), ),
getCollectibleTokenURI: this.assetsContractController.getCollectibleTokenURI.bind( getERC721TokenURI: this.assetsContractController.getERC721TokenURI.bind(
this.assetsContractController, this.assetsContractController,
), ),
getOwnerOf: this.assetsContractController.getOwnerOf.bind( getERC721OwnerOf: this.assetsContractController.getERC721OwnerOf.bind(
this.assetsContractController, this.assetsContractController,
), ),
balanceOfERC1155Collectible: this.assetsContractController.balanceOfERC1155Collectible.bind( getERC1155BalanceOf: this.assetsContractController.getERC1155BalanceOf.bind(
this.assetsContractController, this.assetsContractController,
), ),
uriERC1155Collectible: this.assetsContractController.uriERC1155Collectible.bind( getERC1155TokenURI: this.assetsContractController.getERC1155TokenURI.bind(
this.assetsContractController, this.assetsContractController,
), ),
}, },
@ -243,6 +243,8 @@ export default class MetamaskController extends EventEmitter {
initState.CollectiblesController, initState.CollectiblesController,
); );
this.collectiblesController.setApiKey(process.env.OPENSEA_KEY);
process.env.COLLECTIBLES_V1 && process.env.COLLECTIBLES_V1 &&
(this.collectibleDetectionController = new CollectibleDetectionController( (this.collectibleDetectionController = new CollectibleDetectionController(
{ {
@ -601,6 +603,18 @@ export default class MetamaskController extends EventEmitter {
), ),
provider: this.provider, provider: this.provider,
blockTracker: this.blockTracker, blockTracker: this.blockTracker,
createEventFragment: this.metaMetricsController.createEventFragment.bind(
this.metaMetricsController,
),
updateEventFragment: this.metaMetricsController.updateEventFragment.bind(
this.metaMetricsController,
),
finalizeEventFragment: this.metaMetricsController.finalizeEventFragment.bind(
this.metaMetricsController,
),
getEventFragmentById: this.metaMetricsController.getEventFragmentById.bind(
this.metaMetricsController,
),
trackMetaMetricsEvent: this.metaMetricsController.trackEvent.bind( trackMetaMetricsEvent: this.metaMetricsController.trackEvent.bind(
this.metaMetricsController, this.metaMetricsController,
), ),
@ -660,8 +674,7 @@ export default class MetamaskController extends EventEmitter {
this.collectiblesController.checkAndUpdateSingleCollectibleOwnershipStatus( this.collectiblesController.checkAndUpdateSingleCollectibleOwnershipStatus(
knownCollectible, knownCollectible,
false, false,
// TODO add this when checkAndUpdateSingleCollectibleOwnershipStatus is updated { userAddress, chainId },
// { userAddress, chainId },
); );
} }
} }
@ -1064,6 +1077,7 @@ export default class MetamaskController extends EventEmitter {
appStateController, appStateController,
collectiblesController, collectiblesController,
collectibleDetectionController, collectibleDetectionController,
assetsContractController,
currencyRateController, currencyRateController,
detectTokensController, detectTokensController,
ensController, ensController,
@ -1212,6 +1226,14 @@ export default class MetamaskController extends EventEmitter {
setAdvancedGasFee: preferencesController.setAdvancedGasFee.bind( setAdvancedGasFee: preferencesController.setAdvancedGasFee.bind(
preferencesController, preferencesController,
), ),
setEIP1559V2Enabled: preferencesController.setEIP1559V2Enabled.bind(
preferencesController,
),
// AssetsContractController
getTokenStandardAndDetails: assetsContractController.getTokenStandardAndDetails.bind(
assetsContractController,
),
// CollectiblesController // CollectiblesController
addCollectible: collectiblesController.addCollectible.bind( addCollectible: collectiblesController.addCollectible.bind(
@ -1270,6 +1292,12 @@ export default class MetamaskController extends EventEmitter {
setCollectiblesDetectionNoticeDismissed: appStateController.setCollectiblesDetectionNoticeDismissed.bind( setCollectiblesDetectionNoticeDismissed: appStateController.setCollectiblesDetectionNoticeDismissed.bind(
appStateController, appStateController,
), ),
setEnableEIP1559V2NoticeDismissed: appStateController.setEnableEIP1559V2NoticeDismissed.bind(
appStateController,
),
updateCollectibleDropDownState: appStateController.updateCollectibleDropDownState.bind(
appStateController,
),
// EnsController // EnsController
tryReverseResolveAddress: ensController.reverseResolveAddress.bind( tryReverseResolveAddress: ensController.reverseResolveAddress.bind(
ensController, ensController,
@ -1294,6 +1322,9 @@ export default class MetamaskController extends EventEmitter {
addUnapprovedTransaction: txController.addUnapprovedTransaction.bind( addUnapprovedTransaction: txController.addUnapprovedTransaction.bind(
txController, txController,
), ),
createTransactionEventFragment: txController.createTransactionEventFragment.bind(
txController,
),
// messageManager // messageManager
signMessage: this.signMessage.bind(this), signMessage: this.signMessage.bind(this),
@ -1426,6 +1457,15 @@ export default class MetamaskController extends EventEmitter {
trackMetaMetricsPage: metaMetricsController.trackPage.bind( trackMetaMetricsPage: metaMetricsController.trackPage.bind(
metaMetricsController, metaMetricsController,
), ),
createEventFragment: metaMetricsController.createEventFragment.bind(
metaMetricsController,
),
updateEventFragment: metaMetricsController.updateEventFragment.bind(
metaMetricsController,
),
finalizeEventFragment: metaMetricsController.finalizeEventFragment.bind(
metaMetricsController,
),
// approval controller // approval controller
resolvePendingApproval: approvalController.accept.bind( resolvePendingApproval: approvalController.accept.bind(
@ -2634,28 +2674,47 @@ export default class MetamaskController extends EventEmitter {
* Used to create a multiplexed stream for connecting to an untrusted context * Used to create a multiplexed stream for connecting to an untrusted context
* like a Dapp or other extension. * like a Dapp or other extension.
* *
* @param {*} connectionStream - The Duplex stream to connect to. * @param options - Options bag.
* @param {MessageSender} sender - The sender of the messages on this stream * @param {ReadableStream} options.connectionStream - The Duplex stream to connect to.
* @param {MessageSender | SnapSender} options.sender - The sender of the messages on this stream.
* @param {string} [options.subjectType] - The type of the sender, i.e. subject.
*/ */
setupUntrustedCommunication(connectionStream, sender) { setupUntrustedCommunication({ connectionStream, sender, subjectType }) {
const { usePhishDetect } = this.preferencesController.store.getState(); const { usePhishDetect } = this.preferencesController.store.getState();
const { hostname } = new URL(sender.url); let _subjectType;
// Check if new connection is blocked if phishing detection is on if (subjectType) {
if (usePhishDetect && this.phishingController.test(hostname)) { _subjectType = subjectType;
log.debug('MetaMask - sending phishing warning for', hostname); } else if (sender.id && sender.id !== this.extension.runtime.id) {
this.sendPhishingWarning(connectionStream, hostname); _subjectType = SUBJECT_TYPES.EXTENSION;
return; } else {
_subjectType = SUBJECT_TYPES.WEBSITE;
}
if (sender.url) {
const { hostname } = new URL(sender.url);
// Check if new connection is blocked if phishing detection is on
if (usePhishDetect && this.phishingController.test(hostname)) {
log.debug('MetaMask - sending phishing warning for', hostname);
this.sendPhishingWarning(connectionStream, hostname);
return;
}
} }
// setup multiplexing // setup multiplexing
const mux = setupMultiplex(connectionStream); const mux = setupMultiplex(connectionStream);
// messages between inpage and background // messages between inpage and background
this.setupProviderConnection(mux.createStream('metamask-provider'), sender); this.setupProviderConnection(
mux.createStream('metamask-provider'),
sender,
_subjectType,
);
// TODO:LegacyProvider: Delete // TODO:LegacyProvider: Delete
// legacy streams if (sender.url) {
this.setupPublicConfig(mux.createStream('publicConfig')); // legacy streams
this.setupPublicConfig(mux.createStream('publicConfig'));
}
} }
/** /**
@ -2672,7 +2731,11 @@ export default class MetamaskController extends EventEmitter {
const mux = setupMultiplex(connectionStream); const mux = setupMultiplex(connectionStream);
// connect features // connect features
this.setupControllerConnection(mux.createStream('controller')); this.setupControllerConnection(mux.createStream('controller'));
this.setupProviderConnection(mux.createStream('provider'), sender, true); this.setupProviderConnection(
mux.createStream('provider'),
sender,
SUBJECT_TYPES.INTERNAL,
);
} }
/** /**
@ -2731,17 +2794,19 @@ export default class MetamaskController extends EventEmitter {
* *
* @param {*} outStream - The stream to provide over. * @param {*} outStream - The stream to provide over.
* @param {MessageSender} sender - The sender of the messages on this stream * @param {MessageSender} sender - The sender of the messages on this stream
* @param {boolean} isInternal - True if this is a connection with an internal process * @param {string} subjectType - The type of the sender, i.e. subject.
*/ */
setupProviderConnection(outStream, sender, isInternal) { setupProviderConnection(outStream, sender, subjectType) {
const origin = isInternal ? 'metamask' : new URL(sender.url).origin; let origin;
let subjectType = isInternal if (subjectType === SUBJECT_TYPES.INTERNAL) {
? SUBJECT_TYPES.INTERNAL origin = 'metamask';
: SUBJECT_TYPES.WEBSITE; } else {
origin = new URL(sender.url).origin;
}
if (sender.id !== this.extension.runtime.id) { if (sender.id && sender.id !== this.extension.runtime.id) {
subjectType = SUBJECT_TYPES.EXTENSION; this.subjectMetadataController.addSubjectMetadata({
this.subjectMetadataController.addSubjectMetadata(origin, { origin,
extensionId: sender.id, extensionId: sender.id,
subjectType: SUBJECT_TYPES.EXTENSION, subjectType: SUBJECT_TYPES.EXTENSION,
}); });
@ -2754,8 +2819,8 @@ export default class MetamaskController extends EventEmitter {
const engine = this.setupProviderEngine({ const engine = this.setupProviderEngine({
origin, origin,
location: sender.url,
tabId, tabId,
sender,
subjectType, subjectType,
}); });
@ -2783,14 +2848,14 @@ export default class MetamaskController extends EventEmitter {
* *
* @param {Object} options - Provider engine options * @param {Object} options - Provider engine options
* @param {string} options.origin - The origin of the sender * @param {string} options.origin - The origin of the sender
* @param {string} options.location - The full URL of the sender * @param {MessageSender | SnapSender} options.sender - The sender object.
* @param {string} options.subjectType - The type of the sender subject. * @param {string} options.subjectType - The type of the sender subject.
* @param {tabId} [options.tabId] - The tab ID of the sender - if the sender is within a tab * @param {tabId} [options.tabId] - The tab ID of the sender - if the sender is within a tab
*/ */
setupProviderEngine({ origin, location, subjectType, tabId }) { setupProviderEngine({ origin, subjectType, sender, tabId }) {
// setup json rpc engine stack // setup json rpc engine stack
const engine = new JsonRpcEngine(); const engine = new JsonRpcEngine();
const { provider, blockTracker } = this; const { blockTracker, provider } = this;
// create filter polyfill middleware // create filter polyfill middleware
const filterMiddleware = createFilterMiddleware({ provider, blockTracker }); const filterMiddleware = createFilterMiddleware({ provider, blockTracker });
@ -2812,13 +2877,16 @@ export default class MetamaskController extends EventEmitter {
} }
// logging // logging
engine.push(createLoggerMiddleware({ origin })); engine.push(createLoggerMiddleware({ origin }));
engine.push(
createOnboardingMiddleware({
location,
registerOnboarding: this.onboardingController.registerOnboarding,
}),
);
engine.push(this.permissionLogController.createMiddleware()); engine.push(this.permissionLogController.createMiddleware());
// onboarding
if (subjectType === SUBJECT_TYPES.WEBSITE) {
engine.push(
createOnboardingMiddleware({
location: sender.url,
registerOnboarding: this.onboardingController.registerOnboarding,
}),
);
}
engine.push( engine.push(
createMethodMiddleware({ createMethodMiddleware({
origin, origin,

@ -995,10 +995,10 @@ describe('MetaMaskController', function () {
cb(); cb();
}); });
metamaskController.setupUntrustedCommunication( metamaskController.setupUntrustedCommunication({
streamTest, connectionStream: streamTest,
phishingMessageSender, sender: phishingMessageSender,
); });
await promise; await promise;
streamTest.end(); streamTest.end();
}); });
@ -1016,7 +1016,10 @@ describe('MetaMaskController', function () {
cb(); cb();
}); });
metamaskController.setupUntrustedCommunication(streamTest, messageSender); metamaskController.setupUntrustedCommunication({
connectionStream: streamTest,
sender: messageSender,
});
const message = { const message = {
id: 1999133338649204, id: 1999133338649204,
@ -1055,7 +1058,10 @@ describe('MetaMaskController', function () {
cb(); cb();
}); });
metamaskController.setupUntrustedCommunication(streamTest, messageSender); metamaskController.setupUntrustedCommunication({
connectionStream: streamTest,
sender: messageSender,
});
const message = { const message = {
id: 1999133338649204, id: 1999133338649204,

@ -34,7 +34,6 @@ const metamaskrc = require('rc')('metamask', {
INFURA_PROD_PROJECT_ID: process.env.INFURA_PROD_PROJECT_ID, INFURA_PROD_PROJECT_ID: process.env.INFURA_PROD_PROJECT_ID,
ONBOARDING_V2: process.env.ONBOARDING_V2, ONBOARDING_V2: process.env.ONBOARDING_V2,
COLLECTIBLES_V1: process.env.COLLECTIBLES_V1, COLLECTIBLES_V1: process.env.COLLECTIBLES_V1,
EIP_1559_V2: process.env.EIP_1559_V2,
SEGMENT_HOST: process.env.SEGMENT_HOST, SEGMENT_HOST: process.env.SEGMENT_HOST,
SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY, SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY,
SEGMENT_BETA_WRITE_KEY: process.env.SEGMENT_BETA_WRITE_KEY, SEGMENT_BETA_WRITE_KEY: process.env.SEGMENT_BETA_WRITE_KEY,
@ -797,7 +796,6 @@ function getEnvironmentVariables({ buildType, devMode, testing }) {
SWAPS_USE_DEV_APIS: process.env.SWAPS_USE_DEV_APIS === '1', SWAPS_USE_DEV_APIS: process.env.SWAPS_USE_DEV_APIS === '1',
ONBOARDING_V2: metamaskrc.ONBOARDING_V2 === '1', ONBOARDING_V2: metamaskrc.ONBOARDING_V2 === '1',
COLLECTIBLES_V1: metamaskrc.COLLECTIBLES_V1 === '1', COLLECTIBLES_V1: metamaskrc.COLLECTIBLES_V1 === '1',
EIP_1559_V2: metamaskrc.EIP_1559_V2 === '1',
}; };
} }

@ -200,9 +200,19 @@ const directiveParsingRegex = /^([A-Z]+):([A-Z_]+)(?:\(((?:\w+,)*\w+)\))?$/u;
* a boolean indicating whether they were modified. * a boolean indicating whether they were modified.
*/ */
function removeFencedCode(filePath, typeOfCurrentBuild, fileContent) { function removeFencedCode(filePath, typeOfCurrentBuild, fileContent) {
const matchedLines = [...fileContent.matchAll(linesWithFenceRegex)]; // Do not modify the file if we detect an inline sourcemap. For reasons
// yet to be determined, the transform receives every file twice while in
// watch mode, the second after Babel has transpiled the file. Babel adds
// inline source maps to the file, something we will never do in our own
// source files, so we use the existence of inline source maps to determine
// whether we should ignore the file.
if (/^\/\/# sourceMappingURL=/gmu.test(fileContent)) {
return [fileContent, false];
}
// If we didn't match any lines, return the unmodified file contents. // If we didn't match any lines, return the unmodified file contents.
const matchedLines = [...fileContent.matchAll(linesWithFenceRegex)];
if (matchedLines.length === 0) { if (matchedLines.length === 0) {
return [fileContent, false]; return [fileContent, false];
} }

@ -610,6 +610,17 @@ describe('build/transforms/remove-fenced-code', () => {
}); });
}); });
it('ignores files with inline source maps', () => {
// This is so that there isn't an unnecessary second execution of
// removeFencedCode with a transpiled version of the same file
const input = getTestData().validInputs.extraContentWithFences.concat(
'\n//# sourceMappingURL=as32e32wcwc2234f2ew32cnin4243f4nv9nsdoivnxzoivnd',
);
expect(
removeFencedCode(mockFileName, BuildType.flask, input),
).toStrictEqual([input, false]);
});
// We can't do this until there's more than one command // We can't do this until there's more than one command
it.todo('rejects directive pairs with mismatched commands'); it.todo('rejects directive pairs with mismatched commands');
}); });

@ -4,7 +4,7 @@ set -e
set -u set -u
set -o pipefail set -o pipefail
ganache_cli="$(yarn bin)/ganache-cli" ganache_cli="$(yarn bin)/ganache"
seed_phrase="${GANACHE_SEED_PHRASE:-phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent}" seed_phrase="${GANACHE_SEED_PHRASE:-phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent}"
_term () { _term () {
@ -23,7 +23,7 @@ trap _term SIGTERM
trap _int SIGINT trap _int SIGINT
# shellcheck disable=SC2086 # shellcheck disable=SC2086
$ganache_cli --noVMErrorsOnRPCResponse --networkId 1337 --mnemonic "$seed_phrase" ${GANACHE_ARGS:-} & $ganache_cli --chain.vmErrorsOnRPCResponse false --networkId 1337 --mnemonic "$seed_phrase" ${GANACHE_ARGS:-} &
child=$! child=$!
wait "$child" wait "$child"

@ -955,7 +955,10 @@
}, },
"abstract-leveldown": { "abstract-leveldown": {
"packages": { "packages": {
"buffer": true,
"immediate": true,
"is-buffer": true, "is-buffer": true,
"level-supports": true,
"process": true, "process": true,
"xtend": true "xtend": true
} }
@ -3042,6 +3045,11 @@
"xtend": true "xtend": true
} }
}, },
"level-supports": {
"packages": {
"xtend": true
}
},
"levelup": { "levelup": {
"packages": { "packages": {
"assert": true, "assert": true,

@ -955,7 +955,10 @@
}, },
"abstract-leveldown": { "abstract-leveldown": {
"packages": { "packages": {
"buffer": true,
"immediate": true,
"is-buffer": true, "is-buffer": true,
"level-supports": true,
"process": true, "process": true,
"xtend": true "xtend": true
} }
@ -3042,6 +3045,11 @@
"xtend": true "xtend": true
} }
}, },
"level-supports": {
"packages": {
"xtend": true
}
},
"levelup": { "levelup": {
"packages": { "packages": {
"assert": true, "assert": true,

@ -955,7 +955,10 @@
}, },
"abstract-leveldown": { "abstract-leveldown": {
"packages": { "packages": {
"buffer": true,
"immediate": true,
"is-buffer": true, "is-buffer": true,
"level-supports": true,
"process": true, "process": true,
"xtend": true "xtend": true
} }
@ -3042,6 +3045,11 @@
"xtend": true "xtend": true
} }
}, },
"level-supports": {
"packages": {
"xtend": true
}
},
"levelup": { "levelup": {
"packages": { "packages": {
"assert": true, "assert": true,

@ -1,6 +1,6 @@
{ {
"name": "metamask-crx", "name": "metamask-crx",
"version": "10.9.3", "version": "10.10.0",
"private": true, "private": true,
"repository": { "repository": {
"type": "git", "type": "git",
@ -87,7 +87,6 @@
"3box/**/libp2p-keychain/node-forge": "^1.0.0", "3box/**/libp2p-keychain/node-forge": "^1.0.0",
"3box/ipfs/libp2p-webrtc-star/socket.io/engine.io": "^4.0.0", "3box/ipfs/libp2p-webrtc-star/socket.io/engine.io": "^4.0.0",
"analytics-node/axios": "^0.21.2", "analytics-node/axios": "^0.21.2",
"analytics-node/axios/follow-redirects": "^1.14.7",
"ganache-core/lodash": "^4.17.21", "ganache-core/lodash": "^4.17.21",
"netmask": "^2.0.1", "netmask": "^2.0.1",
"pubnub/superagent-proxy": "^3.0.0", "pubnub/superagent-proxy": "^3.0.0",
@ -110,9 +109,9 @@
"@keystonehq/metamask-airgapped-keyring": "0.2.1", "@keystonehq/metamask-airgapped-keyring": "0.2.1",
"@material-ui/core": "^4.11.0", "@material-ui/core": "^4.11.0",
"@metamask/contract-metadata": "^1.31.0", "@metamask/contract-metadata": "^1.31.0",
"@metamask/controllers": "^24.0.0", "@metamask/controllers": "^25.0.0",
"@metamask/eth-ledger-bridge-keyring": "^0.10.0", "@metamask/eth-ledger-bridge-keyring": "^0.10.0",
"@metamask/eth-token-tracker": "^3.0.1", "@metamask/eth-token-tracker": "^4.0.0",
"@metamask/etherscan-link": "^2.1.0", "@metamask/etherscan-link": "^2.1.0",
"@metamask/jazzicon": "^2.0.0", "@metamask/jazzicon": "^2.0.0",
"@metamask/logo": "^3.1.1", "@metamask/logo": "^3.1.1",
@ -233,7 +232,7 @@
"@babel/preset-env": "^7.5.5", "@babel/preset-env": "^7.5.5",
"@babel/preset-react": "^7.0.0", "@babel/preset-react": "^7.0.0",
"@babel/register": "^7.5.5", "@babel/register": "^7.5.5",
"@lavamoat/allow-scripts": "^1.0.6", "@lavamoat/allow-scripts": "^2.0.0",
"@lavamoat/lavapack": "^2.0.4", "@lavamoat/lavapack": "^2.0.4",
"@metamask/auto-changelog": "^2.1.0", "@metamask/auto-changelog": "^2.1.0",
"@metamask/eslint-config": "^9.0.0", "@metamask/eslint-config": "^9.0.0",
@ -293,8 +292,7 @@
"fancy-log": "^1.3.3", "fancy-log": "^1.3.3",
"fast-glob": "^3.2.2", "fast-glob": "^3.2.2",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"ganache-cli": "^6.12.1", "ganache": "^v7.0.0-rc.0",
"ganache-core": "^2.13.1",
"geckodriver": "^1.21.0", "geckodriver": "^1.21.0",
"globby": "^11.0.4", "globby": "^11.0.4",
"gulp": "^4.0.2", "gulp": "^4.0.2",
@ -365,30 +363,54 @@
}, },
"lavamoat": { "lavamoat": {
"allowScripts": { "allowScripts": {
"gridplus-sdk": false, "3box>3box-orbitdb-plugins>ipfs-log>orbit-db-identity-provider>orbit-db-keystore>leveldown": false,
"3box>3box-orbitdb-plugins>ipfs-log>orbit-db-identity-provider>orbit-db-keystore>libp2p-crypto-secp256k1>secp256k1": false,
"3box>3box-orbitdb-plugins>ipfs-log>orbit-db-identity-provider>orbit-db-keystore>libp2p-crypto>libp2p-crypto-secp256k1>secp256k1": false,
"3box>3box-orbitdb-plugins>ipfs-log>orbit-db-identity-provider>orbit-db-keystore>libp2p-crypto>ursa-optional": false,
"3box>ipfs-postmsg-proxy>peer-id>libp2p-crypto>libp2p-crypto-secp256k1>secp256k1": false,
"3box>ipfs>ipfs-mfs>ipfs-unixfs-exporter>ipfs-unixfs-importer>rabin-wasm>assemblyscript": false,
"3box>ipfs>ipfs-repo>datastore-level>leveldown": false,
"3box>ipfs>ipld-bitcoin>bitcoinjs-lib>bip32>tiny-secp256k1": false,
"3box>ipfs>ipld-ethereum>ethereumjs-account>ethereumjs-util>keccak": false,
"3box>ipfs>ipld-ethereum>ethereumjs-account>ethereumjs-util>secp256k1": false,
"3box>ipfs>ipld-ethereum>ethereumjs-block>ethereumjs-tx>ethereumjs-util>ethereum-cryptography>keccak": false,
"3box>ipfs>ipld-ethereum>ethereumjs-block>ethereumjs-tx>ethereumjs-util>ethereum-cryptography>secp256k1": false,
"3box>ipfs>ipld-ethereum>ethereumjs-block>ethereumjs-util>keccak": false,
"3box>ipfs>ipld-ethereum>ethereumjs-block>ethereumjs-util>secp256k1": false,
"3box>ipfs>ipld-ethereum>ethereumjs-block>merkle-patricia-tree>ethereumjs-util>keccak": false,
"3box>ipfs>ipld-ethereum>ethereumjs-block>merkle-patricia-tree>ethereumjs-util>secp256k1": false,
"3box>ipfs>ipld-ethereum>ethereumjs-tx>ethereumjs-util>keccak": false,
"3box>ipfs>ipld-ethereum>ethereumjs-tx>ethereumjs-util>secp256k1": false,
"3box>ipfs>ipld-ethereum>merkle-patricia-tree>ethereumjs-util>keccak": false,
"3box>ipfs>ipld-ethereum>merkle-patricia-tree>ethereumjs-util>secp256k1": false,
"3box>orbit-db>orbit-db-cache>leveldown": false,
"@lavamoat/allow-scripts>@lavamoat/preinstall-always-fail": false,
"@metamask/controllers>babel-runtime>core-js": false,
"@metamask/controllers>eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>keccak": false,
"@metamask/controllers>eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>secp256k1": false,
"@metamask/controllers>eth-keyring-controller>eth-hd-keyring>eth-sig-util>ethereumjs-util>keccak": false,
"@metamask/controllers>eth-keyring-controller>eth-hd-keyring>eth-sig-util>ethereumjs-util>secp256k1": false,
"@metamask/controllers>web3-provider-engine>eth-json-rpc-filters>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>keccak": false,
"@metamask/controllers>web3-provider-engine>eth-json-rpc-filters>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>secp256k1": false,
"@metamask/controllers>web3-provider-engine>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>keccak": false,
"@metamask/controllers>web3-provider-engine>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>secp256k1": false,
"@metamask/eth-ledger-bridge-keyring>eth-sig-util>ethereumjs-util>keccak": false,
"@metamask/eth-ledger-bridge-keyring>eth-sig-util>ethereumjs-util>secp256k1": false,
"@sentry/cli": true,
"@storybook/addon-a11y>@storybook/addons>@storybook/api>@storybook/channels>core-js": false,
"@storybook/addon-essentials>@storybook/addon-docs>@storybook/builder-webpack4>@storybook/ui>core-js-pure": false,
"chromedriver": true, "chromedriver": true,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>keccak": false,
"eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>secp256k1": false,
"eth-lattice-keyring>gridplus-sdk": false,
"eth-trezor-keyring>hdkey>secp256k1": false,
"eth-trezor-keyring>trezor-connect>@trezor/utxo-lib>blake-hash": false,
"eth-trezor-keyring>trezor-connect>trezor-link>protobufjs": false,
"ganache>@trufflesuite/bigint-buffer": false,
"ganache>keccak": false,
"ganache>leveldown": false,
"geckodriver": true, "geckodriver": true,
"@sentry/cli": true, "react-devtools>electron": true
"electron": true,
"core-js": false,
"core-js-pure": false,
"keccak": false,
"secp256k1": false,
"web3": false,
"sha3": false,
"bufferutil": false,
"utf-8-validate": false,
"leveldown": false,
"ursa-optional": false,
"gc-stats": false,
"github:assemblyscript/assemblyscript": false,
"tiny-secp256k1": false,
"@lavamoat/preinstall-always-fail": false,
"fsevents": false,
"node-hid": false,
"usb": false,
"blake-hash": false,
"protobufjs": false
} }
} }
} }

@ -17,6 +17,13 @@ export const DEVICE_NAMES = {
LATTICE: 'lattice', LATTICE: 'lattice',
}; };
export const KEYRING_NAMES = {
LEDGER: 'Ledger',
TREZOR: 'Trezor',
QR: 'QR',
LATTICE: 'Lattice1',
};
/** /**
* Used for setting the users preference for ledger transport type * Used for setting the users preference for ledger transport type
*/ */

@ -82,6 +82,46 @@
* segment source that marks the event data as not conforming to our schema * segment source that marks the event data as not conforming to our schema
*/ */
/**
* @typedef {Object} MetaMetricsEventFragment
* @property {string} successEvent - The event name to fire when the fragment
* is closed in an affirmative action.
* @property {string} [failureEvent] - The event name to fire when the fragment
* is closed with a rejection.
* @property {string} [initialEvent] - An event name to fire immediately upon
* fragment creation. This is useful for building funnels in mixpanel and for
* reduction of code duplication.
* @property {string} category - the event category to use for both the success
* and failure events
* @property {boolean} [persist] - Should this fragment be persisted in
* state and progressed after the extension is locked and unlocked.
* @property {number} [timeout] - Time in seconds the event should be persisted
* for. After the timeout the fragment will be closed as abandoned. if not
* supplied the fragment is stored indefinitely.
* @property {number} [lastUpdated] - Date.now() when the fragment was last
* updated. Used to determine if the timeout has expired and the fragment
* should be closed.
* @property {object} [properties] - Object of custom values to track, keys in
* this object must be in snake_case.
* @property {object} [sensitiveProperties] - Object of sensitive values to
* track. Keys in this object must be in snake_case. These properties will be
* sent in an additional event that excludes the user's metaMetricsId
* @property {number} [revenue] - amount of currency that event creates in
* revenue for MetaMask if fragment is successful.
* @property {string} [currency] - ISO 4127 format currency for events with
* revenue, defaults to US dollars
* @property {number} [value] - Abstract business "value" attributable to
* customers who successfully complete this fragment
* @property {MetaMetricsPageObject} [page] - the page/route that the event
* occurred on
* @property {MetaMetricsReferrerObject} [referrer] - the origin of the dapp
* that initiated the event fragment.
* @property {string} [uniqueIdentifier] - optional argument to override the
* automatic generation of UUID for the event fragment. This is useful when
* tracking events for subsystems that already generate UUIDs so to avoid
* unnecessary lookups and reduce accidental duplication.
*/
/** /**
* Represents the shape of data sent to the segment.track method. * Represents the shape of data sent to the segment.track method.
* *

@ -23,6 +23,9 @@ export const BSC_CHAIN_ID = '0x38';
export const OPTIMISM_CHAIN_ID = '0xa'; export const OPTIMISM_CHAIN_ID = '0xa';
export const OPTIMISM_TESTNET_CHAIN_ID = '0x45'; export const OPTIMISM_TESTNET_CHAIN_ID = '0x45';
export const POLYGON_CHAIN_ID = '0x89'; export const POLYGON_CHAIN_ID = '0x89';
export const AVALANCHE_CHAIN_ID = '0xa86a';
export const FANTOM_CHAIN_ID = '0xfa';
export const CELO_CHAIN_ID = '0xa4ec';
/** /**
* The largest possible chain ID we can handle. * The largest possible chain ID we can handle.
@ -53,6 +56,9 @@ export const WETH_SYMBOL = 'WETH';
export const TEST_ETH_SYMBOL = 'TESTETH'; export const TEST_ETH_SYMBOL = 'TESTETH';
export const BNB_SYMBOL = 'BNB'; export const BNB_SYMBOL = 'BNB';
export const MATIC_SYMBOL = 'MATIC'; export const MATIC_SYMBOL = 'MATIC';
export const AVALANCHE_SYMBOL = 'AVAX';
export const FANTOM_SYMBOL = 'FTM';
export const CELO_SYMBOL = 'CELO';
export const ETH_TOKEN_IMAGE_URL = './images/eth_logo.svg'; export const ETH_TOKEN_IMAGE_URL = './images/eth_logo.svg';
export const TEST_ETH_TOKEN_IMAGE_URL = './images/black-eth-logo.svg'; export const TEST_ETH_TOKEN_IMAGE_URL = './images/black-eth-logo.svg';
@ -173,3 +179,55 @@ export const UNSUPPORTED_RPC_METHODS = new Set([
]); ]);
export const IPFS_DEFAULT_GATEWAY_URL = 'dweb.link'; export const IPFS_DEFAULT_GATEWAY_URL = 'dweb.link';
// The first item in transakCurrencies must be the
// default crypto currency for the network
const BUYABLE_CHAIN_ETHEREUM_NETWORK_NAME = 'ethereum';
export const BUYABLE_CHAINS_MAP = {
[MAINNET_CHAIN_ID]: {
nativeCurrency: ETH_SYMBOL,
network: BUYABLE_CHAIN_ETHEREUM_NETWORK_NAME,
transakCurrencies: [ETH_SYMBOL, 'USDT', 'USDC', 'DAI'],
},
[ROPSTEN_CHAIN_ID]: {
nativeCurrency: ETH_SYMBOL,
network: BUYABLE_CHAIN_ETHEREUM_NETWORK_NAME,
},
[RINKEBY_CHAIN_ID]: {
nativeCurrency: ETH_SYMBOL,
network: BUYABLE_CHAIN_ETHEREUM_NETWORK_NAME,
},
[GOERLI_CHAIN_ID]: {
nativeCurrency: ETH_SYMBOL,
network: BUYABLE_CHAIN_ETHEREUM_NETWORK_NAME,
},
[KOVAN_CHAIN_ID]: {
nativeCurrency: ETH_SYMBOL,
network: BUYABLE_CHAIN_ETHEREUM_NETWORK_NAME,
},
[BSC_CHAIN_ID]: {
nativeCurrency: BNB_SYMBOL,
network: 'bsc',
transakCurrencies: [BNB_SYMBOL, 'BUSD'],
},
[POLYGON_CHAIN_ID]: {
nativeCurrency: MATIC_SYMBOL,
network: 'polygon',
transakCurrencies: [MATIC_SYMBOL, 'USDT', 'USDC', 'DAI'],
},
[AVALANCHE_CHAIN_ID]: {
nativeCurrency: AVALANCHE_SYMBOL,
network: 'avaxcchain',
transakCurrencies: [AVALANCHE_SYMBOL],
},
[FANTOM_CHAIN_ID]: {
nativeCurrency: FANTOM_SYMBOL,
network: 'fantom',
transakCurrencies: [FANTOM_SYMBOL],
},
[CELO_CHAIN_ID]: {
nativeCurrency: CELO_SYMBOL,
network: 'celo',
transakCurrencies: [CELO_SYMBOL],
},
};

@ -226,6 +226,10 @@ export const TRANSACTION_GROUP_CATEGORIES = {
* TransactionMeta object. * TransactionMeta object.
* @property {string} origin - A string representing the interface that * @property {string} origin - A string representing the interface that
* suggested the transaction. * suggested the transaction.
* @property {string} originalGasEstimate - A string representing the original
* gas estimation on the transaction metadata.
* @property {boolean} userEditedGasLimit - A boolean representing when the
* user manually edited the gas limit.
* @property {Object} nonceDetails - A metadata object containing information * @property {Object} nonceDetails - A metadata object containing information
* used to derive the suggested nonce, useful for debugging nonce issues. * used to derive the suggested nonce, useful for debugging nonce issues.
* @property {string} rawTx - A hex string of the final signed transaction, * @property {string} rawTx - A hex string of the final signed transaction,
@ -236,3 +240,49 @@ export const TRANSACTION_GROUP_CATEGORIES = {
* the network, in Unix epoch time (ms). * the network, in Unix epoch time (ms).
* @property {TxError} [err] - The error encountered during the transaction * @property {TxError} [err] - The error encountered during the transaction
*/ */
/**
* Defines the possible types
*
* @typedef {Object} TransactionMetaMetricsEvents
* @property {'Transaction Added'} ADDED - All transactions, except incoming
* ones, are added to the controller state in an unapproved status. When this
* happens we fire the Transaction Added event to show that the transaction
* has been added to the user's MetaMask.
* @property {'Transaction Approved'} APPROVED - When an unapproved transaction
* is in the controller state, MetaMask will render a confirmation screen for
* that transaction. If the user approves the transaction we fire this event
* to indicate that the user has approved the transaction for submission to
* the network.
* @property {'Transaction Rejected'} REJECTED - When an unapproved transaction
* is in the controller state, MetaMask will render a confirmation screen for
* that transaction. If the user rejects the transaction we fire this event
* to indicate that the user has rejected the transaction. It will be removed
* from state as a result.
* @property {'Transaction Submitted'} SUBMITTED - After a transaction is
* approved by the user, it is then submitted to the network for inclusion in
* a block. When this happens we fire the Transaction Submitted event to
* indicate that MetaMask is submitting a transaction at the user's request.
* @property {'Transaction Finalized'} FINALIZED - All transactions that are
* submitted will finalized (eventually) by either being dropped, failing
* or being confirmed. When this happens we track this event, along with the
* status.
*/
/**
* This type will work anywhere you expect a string that can be one of the
* above transaction event types.
*
* @typedef {TransactionMetaMetricsEvents[keyof TransactionMetaMetricsEvents]} TransactionMetaMetricsEventString
*/
/**
* @type {TransactionMetaMetricsEvents}
*/
export const TRANSACTION_EVENTS = {
ADDED: 'Transaction Added',
APPROVED: 'Transaction Approved',
FINALIZED: 'Transaction Finalized',
REJECTED: 'Transaction Rejected',
SUBMITTED: 'Transaction Submitted',
};

@ -0,0 +1,145 @@
{
"data": {
"AppStateController": {
"mkrMigrationReminderTimestamp": null,
"swapsWelcomeMessageHasBeenShown": true
},
"CachedBalancesController": {
"cachedBalances": {
"4": {}
}
},
"CurrencyController": {
"conversionDate": 1575697244.188,
"conversionRate": 149.61,
"currentCurrency": "usd",
"nativeCurrency": "ETH"
},
"IncomingTransactionsController": {
"incomingTransactions": {},
"incomingTxLastFetchedBlocksByNetwork": {
"goerli": null,
"kovan": null,
"mainnet": null,
"rinkeby": 5570536
}
},
"KeyringController": {
"vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}"
},
"NetworkController": {
"network": "1337",
"provider": {
"nickname": "Localhost 8545",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"type": "rpc"
}
},
"NotificationController": {
"notifications": {
"1": {
"isShown": true
},
"3": {
"isShown": true
},
"5": {
"isShown": true
},
"6": {
"isShown": true
},
"8": {
"isShown": true
}
}
},
"OnboardingController": {
"onboardingTabs": {},
"seedPhraseBackedUp": false
},
"PermissionsMetadata": {
"domainMetadata": {
"metamask.github.io": {
"icon": null,
"name": "M E T A M A S K M E S H T E S T"
}
},
"permissionsHistory": {},
"permissionsLog": [
{
"id": 746677923,
"method": "eth_accounts",
"methodType": "restricted",
"origin": "metamask.github.io",
"request": {
"id": 746677923,
"jsonrpc": "2.0",
"method": "eth_accounts",
"origin": "metamask.github.io",
"params": []
},
"requestTime": 1575697241368,
"response": {
"id": 746677923,
"jsonrpc": "2.0",
"result": []
},
"responseTime": 1575697241370,
"success": true
}
]
},
"PreferencesController": {
"accountTokens": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"rinkeby": [],
"ropsten": []
}
},
"assetImages": {},
"completedOnboarding": true,
"eip1559V2Enabled": true,
"currentLocale": "en",
"featureFlags": {
"showIncomingTransactions": true,
"transactionTime": false
},
"firstTimeFlowType": "create",
"forgottenPassword": false,
"frequentRpcListDetail": [],
"identities": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"name": "Account 1"
}
},
"knownMethodData": {},
"lostIdentities": {},
"metaMetricsId": null,
"participateInMetaMetrics": false,
"preferences": {
"useNativeCurrencyAsPrimaryCurrency": true
},
"selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"suggestedTokens": {},
"tokens": [],
"useBlockie": false,
"useNonceField": false,
"usePhishDetect": true
},
"TransactionController": {
"transactions": {}
},
"config": {},
"firstTimeInfo": {
"date": 1575697234195,
"version": "7.7.0"
}
},
"meta": {
"version": 40
}
}

@ -0,0 +1,214 @@
{
"data": {
"AppStateController": {
"mkrMigrationReminderTimestamp": null,
"swapsWelcomeMessageHasBeenShown": true
},
"CachedBalancesController": {
"cachedBalances": {
"4": {}
}
},
"CurrencyController": {
"conversionDate": 1575697244.188,
"conversionRate": 149.61,
"currentCurrency": "usd",
"nativeCurrency": "ETH"
},
"IncomingTransactionsController": {
"incomingTransactions": {},
"incomingTxLastFetchedBlocksByNetwork": {
"goerli": null,
"kovan": null,
"mainnet": null,
"rinkeby": 5570536
}
},
"KeyringController": {
"vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}"
},
"NetworkController": {
"network": "1337",
"provider": {
"nickname": "Localhost 8545",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"type": "rpc"
}
},
"NotificationController": {
"notifications": {
"1": {
"isShown": true
},
"3": {
"isShown": true
},
"5": {
"isShown": true
},
"6": {
"isShown": true
},
"8": {
"isShown": true
}
}
},
"OnboardingController": {
"onboardingTabs": {},
"seedPhraseBackedUp": false
},
"PermissionsMetadata": {
"domainMetadata": {
"metamask.github.io": {
"icon": null,
"name": "M E T A M A S K M E S H T E S T"
}
},
"permissionsHistory": {},
"permissionsLog": [
{
"id": 746677923,
"method": "eth_accounts",
"methodType": "restricted",
"origin": "metamask.github.io",
"request": {
"id": 746677923,
"jsonrpc": "2.0",
"method": "eth_accounts",
"origin": "metamask.github.io",
"params": []
},
"requestTime": 1575697241368,
"response": {
"id": 746677923,
"jsonrpc": "2.0",
"result": []
},
"responseTime": 1575697241370,
"success": true
}
]
},
"PreferencesController": {
"accountTokens": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"rinkeby": [],
"ropsten": []
}
},
"assetImages": {},
"completedOnboarding": true,
"eip1559V2Enabled": true,
"currentLocale": "en",
"featureFlags": {
"showIncomingTransactions": true,
"transactionTime": false
},
"firstTimeFlowType": "create",
"forgottenPassword": false,
"frequentRpcListDetail": [],
"identities": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"name": "Account 1"
}
},
"knownMethodData": {},
"lostIdentities": {},
"metaMetricsId": null,
"participateInMetaMetrics": false,
"preferences": {
"useNativeCurrencyAsPrimaryCurrency": true
},
"selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"suggestedTokens": {},
"tokens": [],
"useBlockie": false,
"useNonceField": false,
"usePhishDetect": true
},
"TransactionController": {
"transactions": {
"4046084157914634": {
"chainId": "0x539",
"primaryTransaction": {
"chainId": "0x539",
"id": 4046084157914634,
"loadingDefaults": true,
"metamaskNetworkId": "1337",
"origin": "metamask",
"status": "unapproved",
"time": 1617228030067,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x61a8",
"maxFeePerGas": "0x59682f0c",
"maxPriorityFeePerGas": "0x59682f00",
"type": "0x2",
"to": "0x2f318C334780961FB129D2a6c30D0763d9a5C970",
"value": "0x1e87F85809dc0000"
},
"type": "sentEther"
},
"history": [
{
"chainId": "0x539",
"id": 4046084157914634,
"loadingDefaults": true,
"metamaskNetworkId": "1337",
"origin": "metamask",
"status": "unapproved",
"time": 1617228030067,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x61a8",
"maxFeePerGas": "0x59682f0c",
"maxPriorityFeePerGas": "0x59682f00",
"type": "0x2",
"to": "0x2f318C334780961FB129D2a6c30D0763d9a5C970",
"value": "0x1e87F85809dc0000"
},
"type": "simpleSend"
},
[
{
"note": "Added new unapproved transaction.",
"op": "replace",
"path": "/loadingDefaults",
"timestamp": 1617228030069,
"value": false
}
]
],
"id": 4046084157914634,
"loadingDefaults": false,
"metamaskNetworkId": "1337",
"origin": "metamask",
"status": "unapproved",
"time": 1617228030067,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x61a8",
"maxFeePerGas": "0x59682f0c",
"maxPriorityFeePerGas": "0x59682f00",
"type": "0x2",
"to": "0x2f318C334780961FB129D2a6c30D0763d9a5C970",
"value": "0x1e87F85809dc0000"
},
"type": "simpleSend"
}
}
},
"config": {},
"firstTimeInfo": {
"date": 1575697234195,
"version": "7.7.0"
}
},
"meta": {
"version": 40
}
}

@ -485,6 +485,46 @@
"usePhishDetect": true, "usePhishDetect": true,
"useTokenDetection": true "useTokenDetection": true
}, },
"MetaMetricsController": {
"fragments": {
"transaction-added-7911313280012623": {
"category": "Transactions",
"initialEvent": "Transaction Added",
"successEvent": "Transaction Approved",
"failureEvent": "Transaction Rejected",
"properties": {},
"persist": true,
"uniqueIdentifier": "transaction-added-7911313280012623"
},
"transaction-added-7911313280012624": {
"category": "Transactions",
"initialEvent": "Transaction Added",
"successEvent": "Transaction Approved",
"failureEvent": "Transaction Rejected",
"properties": {},
"persist": true,
"uniqueIdentifier": "transaction-added-7911313280012624"
},
"transaction-added-7911313280012625": {
"category": "Transactions",
"initialEvent": "Transaction Added",
"successEvent": "Transaction Approved",
"failureEvent": "Transaction Rejected",
"properties": {},
"persist": true,
"uniqueIdentifier": "transaction-added-7911313280012625"
},
"transaction-added-7911313280012626": {
"category": "Transactions",
"initialEvent": "Transaction Added",
"successEvent": "Transaction Approved",
"failureEvent": "Transaction Rejected",
"properties": {},
"persist": true,
"uniqueIdentifier": "transaction-added-7911313280012626"
}
}
},
"TransactionController": { "TransactionController": {
"transactions": { "transactions": {
"7911313280012623": { "7911313280012623": {

@ -0,0 +1,214 @@
{
"data": {
"AppStateController": {
"mkrMigrationReminderTimestamp": null,
"swapsWelcomeMessageHasBeenShown": true
},
"CachedBalancesController": {
"cachedBalances": {
"4": {}
}
},
"CurrencyController": {
"conversionDate": 1575697244.188,
"conversionRate": 149.61,
"currentCurrency": "usd",
"nativeCurrency": "ETH"
},
"IncomingTransactionsController": {
"incomingTransactions": {},
"incomingTxLastFetchedBlocksByNetwork": {
"goerli": null,
"kovan": null,
"mainnet": null,
"rinkeby": 5570536
}
},
"KeyringController": {
"vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}"
},
"NetworkController": {
"network": "1337",
"provider": {
"nickname": "Localhost 8545",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"type": "rpc"
}
},
"NotificationController": {
"notifications": {
"1": {
"isShown": true
},
"3": {
"isShown": true
},
"5": {
"isShown": true
},
"6": {
"isShown": true
},
"8": {
"isShown": true
}
}
},
"OnboardingController": {
"onboardingTabs": {},
"seedPhraseBackedUp": false
},
"PermissionsMetadata": {
"domainMetadata": {
"metamask.github.io": {
"icon": null,
"name": "M E T A M A S K M E S H T E S T"
}
},
"permissionsHistory": {},
"permissionsLog": [
{
"id": 746677923,
"method": "eth_accounts",
"methodType": "restricted",
"origin": "metamask.github.io",
"request": {
"id": 746677923,
"jsonrpc": "2.0",
"method": "eth_accounts",
"origin": "metamask.github.io",
"params": []
},
"requestTime": 1575697241368,
"response": {
"id": 746677923,
"jsonrpc": "2.0",
"result": []
},
"responseTime": 1575697241370,
"success": true
}
]
},
"PreferencesController": {
"accountTokens": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"rinkeby": [],
"ropsten": []
}
},
"assetImages": {},
"completedOnboarding": true,
"eip1559V2Enabled": true,
"currentLocale": "en",
"featureFlags": {
"showIncomingTransactions": true,
"transactionTime": false
},
"firstTimeFlowType": "create",
"forgottenPassword": false,
"frequentRpcListDetail": [],
"identities": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"name": "Account 1"
}
},
"knownMethodData": {},
"lostIdentities": {},
"metaMetricsId": null,
"participateInMetaMetrics": false,
"preferences": {
"useNativeCurrencyAsPrimaryCurrency": true
},
"selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"suggestedTokens": {},
"tokens": [],
"useBlockie": false,
"useNonceField": false,
"usePhishDetect": true
},
"TransactionController": {
"transactions": {
"4046084157914634": {
"chainId": "0x539",
"primaryTransaction": {
"chainId": "0x539",
"id": 4046084157914634,
"loadingDefaults": true,
"metamaskNetworkId": "1337",
"origin": "metamask",
"status": "unapproved",
"time": 1617228030067,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x61a8",
"maxFeePerGas": "0x59682f0c",
"maxPriorityFeePerGas": "0x59682f00",
"type": "0x2",
"to": "0x2f318C334780961FB129D2a6c30D0763d9a5C970",
"value": "0xde0b6b3a7640000"
},
"type": "sentEther"
},
"history": [
{
"chainId": "0x539",
"id": 4046084157914634,
"loadingDefaults": true,
"metamaskNetworkId": "1337",
"origin": "metamask",
"status": "unapproved",
"time": 1617228030067,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x61a8",
"maxFeePerGas": "0x59682f0c",
"maxPriorityFeePerGas": "0x59682f00",
"type": "0x2",
"to": "0x2f318C334780961FB129D2a6c30D0763d9a5C970",
"value": "0xde0b6b3a7640000"
},
"type": "simpleSend"
},
[
{
"note": "Added new unapproved transaction.",
"op": "replace",
"path": "/loadingDefaults",
"timestamp": 1617228030069,
"value": false
}
]
],
"id": 4046084157914634,
"loadingDefaults": false,
"metamaskNetworkId": "1337",
"origin": "metamask",
"status": "unapproved",
"time": 1617228030067,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x61a8",
"maxFeePerGas": "0x59682f0c",
"maxPriorityFeePerGas": "0x59682f00",
"type": "0x2",
"to": "0x2f318C334780961FB129D2a6c30D0763d9a5C970",
"value": "0xde0b6b3a7640000"
},
"type": "simpleSend"
}
}
},
"config": {},
"firstTimeInfo": {
"date": 1575697234195,
"version": "7.7.0"
}
},
"meta": {
"version": 40
}
}

@ -129,6 +129,19 @@
"useNonceField": false, "useNonceField": false,
"usePhishDetect": true "usePhishDetect": true
}, },
"MetaMetricsController": {
"fragments": {
"transaction-added-4046084157914634": {
"category": "Transactions",
"initialEvent": "Transaction Added",
"successEvent": "Transaction Approved",
"failureEvent": "Transaction Rejected",
"properties": {},
"persist": true,
"uniqueIdentifier": "transaction-added-4046084157914634"
}
}
},
"TransactionController": { "TransactionController": {
"transactions": { "transactions": {
"4046084157914634": { "4046084157914634": {

@ -1,5 +1,4 @@
const { promisify } = require('util'); const ganache = require('ganache');
const ganache = require('ganache-core');
const defaultOptions = { const defaultOptions = {
blockTime: 2, blockTime: 2,
@ -8,6 +7,7 @@ const defaultOptions = {
'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent', 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent',
port: 8545, port: 8545,
vmErrorsOnRPCResponse: false, vmErrorsOnRPCResponse: false,
hardfork: 'muirGlacier',
}; };
class Ganache { class Ganache {
@ -15,22 +15,14 @@ class Ganache {
const options = { ...defaultOptions, ...opts }; const options = { ...defaultOptions, ...opts };
const { port } = options; const { port } = options;
this._server = ganache.server(options); this._server = ganache.server(options);
await this._server.listen(port);
const listen = promisify(this._server.listen).bind(this._server);
const blockchain = await listen(port);
return {
...blockchain,
port,
};
} }
async quit() { async quit() {
if (!this._server) { if (!this._server) {
throw new Error('Server not running yet'); throw new Error('Server not running yet');
} }
const close = promisify(this._server.close).bind(this._server); await this._server.close();
await close();
} }
} }

@ -1,5 +1,6 @@
const path = require('path'); const path = require('path');
const sinon = require('sinon'); const sinon = require('sinon');
const BigNumber = require('bignumber.js');
const createStaticServer = require('../../development/create-static-server'); const createStaticServer = require('../../development/create-static-server');
const { const {
createSegmentServer, createSegmentServer,
@ -12,9 +13,10 @@ const { ensureXServerIsRunning } = require('./x-server');
const tinyDelayMs = 200; const tinyDelayMs = 200;
const regularDelayMs = tinyDelayMs * 2; const regularDelayMs = tinyDelayMs * 2;
const largeDelayMs = regularDelayMs * 2; const largeDelayMs = regularDelayMs * 2;
const dappPort = 8080; const dappPort = 8080;
const convertToHexValue = (val) => `0x${new BigNumber(val, 10).toString(16)}`;
async function withFixtures(options, testSuite) { async function withFixtures(options, testSuite) {
const { const {
dapp, dapp,
@ -42,7 +44,7 @@ async function withFixtures(options, testSuite) {
secondaryGanacheServer = new Ganache(); secondaryGanacheServer = new Ganache();
await secondaryGanacheServer.start({ await secondaryGanacheServer.start({
blockTime: 2, blockTime: 2,
_chainIdRpc: chainId, chain: { chainId },
port, port,
vmErrorsOnRPCResponse: false, vmErrorsOnRPCResponse: false,
}); });
@ -147,9 +149,55 @@ async function withFixtures(options, testSuite) {
} }
} }
/**
* @param {*} driver - selinium driver
* @param {*} handlesCount - total count of windows that should be loaded
* @returns handles - an object with window handles, properties in object represent windows:
* 1. extension: metamask extension window
* 2. dapp: test-app window
* 3. popup: metsmask extension popup window
*/
const getWindowHandles = async (driver, handlesCount) => {
await driver.waitUntilXWindowHandles(handlesCount);
const windowHandles = await driver.getAllWindowHandles();
const extension = windowHandles[0];
const dapp = await driver.switchToWindowWithTitle(
'E2E Test Dapp',
windowHandles,
);
const popup = windowHandles.find(
(handle) => handle !== extension && handle !== dapp,
);
return { extension, dapp, popup };
};
const connectDappWithExtensionPopup = async (driver) => {
await driver.openNewPage(`http://127.0.0.1:${dappPort}/`);
await driver.delay(regularDelayMs);
await driver.clickElement({ text: 'Connect', tag: 'button' });
await driver.delay(regularDelayMs);
const windowHandles = await getWindowHandles(driver, 3);
// open extension popup and confirm connect
await driver.switchToWindow(windowHandles.popup);
await driver.delay(largeDelayMs);
await driver.clickElement({ text: 'Next', tag: 'button' });
await driver.clickElement({ text: 'Connect', tag: 'button' });
// send from dapp
await driver.waitUntilXWindowHandles(2);
await driver.switchToWindow(windowHandles.dapp);
await driver.delay(regularDelayMs);
};
module.exports = { module.exports = {
getWindowHandles,
convertToHexValue,
tinyDelayMs, tinyDelayMs,
regularDelayMs, regularDelayMs,
largeDelayMs, largeDelayMs,
withFixtures, withFixtures,
connectDappWithExtensionPopup,
}; };

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save