Merge remote-tracking branch 'origin/develop' into master-sync

feature/default_network_editable
Alex 3 years ago
commit b751cf80b9
  1. 4
      .circleci/config.yml
  2. 6
      .circleci/scripts/chrome-install.sh
  3. 7
      .depcheckrc.yml
  4. 38
      .eslintrc.js
  5. 2
      .github/workflows/cla.yml
  6. BIN
      .storybook/images/UNI.png
  7. 65
      .storybook/initial-states/approval-screens/add-suggested-token.js
  8. 56
      .storybook/initial-states/approval-screens/add-token.js
  9. 4
      .storybook/main.js
  10. 4
      .storybook/preview.js
  11. 1959
      .storybook/test-data.js
  12. 4
      README.md
  13. 13
      app/_locales/am/messages.json
  14. 11
      app/_locales/ar/messages.json
  15. 13
      app/_locales/bg/messages.json
  16. 11
      app/_locales/bn/messages.json
  17. 13
      app/_locales/ca/messages.json
  18. 7
      app/_locales/cs/messages.json
  19. 13
      app/_locales/da/messages.json
  20. 17
      app/_locales/de/messages.json
  21. 13
      app/_locales/el/messages.json
  22. 183
      app/_locales/en/messages.json
  23. 21
      app/_locales/es/messages.json
  24. 21
      app/_locales/es_419/messages.json
  25. 11
      app/_locales/et/messages.json
  26. 13
      app/_locales/fa/messages.json
  27. 13
      app/_locales/fi/messages.json
  28. 13
      app/_locales/fil/messages.json
  29. 15
      app/_locales/fr/messages.json
  30. 13
      app/_locales/he/messages.json
  31. 23
      app/_locales/hi/messages.json
  32. 5
      app/_locales/hn/messages.json
  33. 11
      app/_locales/hr/messages.json
  34. 8
      app/_locales/ht/messages.json
  35. 13
      app/_locales/hu/messages.json
  36. 21
      app/_locales/id/messages.json
  37. 21
      app/_locales/it/messages.json
  38. 21
      app/_locales/ja/messages.json
  39. 11
      app/_locales/kn/messages.json
  40. 21
      app/_locales/ko/messages.json
  41. 11
      app/_locales/lt/messages.json
  42. 13
      app/_locales/lv/messages.json
  43. 11
      app/_locales/ms/messages.json
  44. 9
      app/_locales/nl/messages.json
  45. 13
      app/_locales/no/messages.json
  46. 23
      app/_locales/ph/messages.json
  47. 13
      app/_locales/pl/messages.json
  48. 7
      app/_locales/pt/messages.json
  49. 21
      app/_locales/pt_BR/messages.json
  50. 13
      app/_locales/ro/messages.json
  51. 25
      app/_locales/ru/messages.json
  52. 13
      app/_locales/sk/messages.json
  53. 11
      app/_locales/sl/messages.json
  54. 13
      app/_locales/sr/messages.json
  55. 13
      app/_locales/sv/messages.json
  56. 13
      app/_locales/sw/messages.json
  57. 5
      app/_locales/ta/messages.json
  58. 9
      app/_locales/th/messages.json
  59. 23
      app/_locales/tl/messages.json
  60. 9
      app/_locales/tr/messages.json
  61. 13
      app/_locales/uk/messages.json
  62. 21
      app/_locales/vi/messages.json
  63. 21
      app/_locales/zh_CN/messages.json
  64. 11
      app/_locales/zh_TW/messages.json
  65. 337
      app/build-types/beta/beta-mascot.json
  66. BIN
      app/build-types/beta/icon-128.png
  67. BIN
      app/build-types/beta/icon-16.png
  68. BIN
      app/build-types/beta/icon-19.png
  69. BIN
      app/build-types/beta/icon-32.png
  70. BIN
      app/build-types/beta/icon-38.png
  71. BIN
      app/build-types/beta/icon-48.png
  72. BIN
      app/build-types/beta/icon-512.png
  73. BIN
      app/build-types/beta/icon-64.png
  74. BIN
      app/build-types/beta/info-logo.png
  75. 130
      app/build-types/beta/logo/metamask-fox.svg
  76. 148
      app/build-types/beta/logo/metamask-logo-horizontal-dark.svg
  77. 148
      app/build-types/beta/logo/metamask-logo-horizontal.svg
  78. 322
      app/images/mascot.json
  79. 0
      app/images/videos/recovery-onboarding/subtitles/en.vtt
  80. 115
      app/images/videos/recovery-onboarding/subtitles/es.vtt
  81. 115
      app/images/videos/recovery-onboarding/subtitles/hi.vtt
  82. 115
      app/images/videos/recovery-onboarding/subtitles/id.vtt
  83. 115
      app/images/videos/recovery-onboarding/subtitles/ja.vtt
  84. 115
      app/images/videos/recovery-onboarding/subtitles/ko.vtt
  85. 115
      app/images/videos/recovery-onboarding/subtitles/pt.vtt
  86. 115
      app/images/videos/recovery-onboarding/subtitles/ru.vtt
  87. 115
      app/images/videos/recovery-onboarding/subtitles/tl.vtt
  88. 115
      app/images/videos/recovery-onboarding/subtitles/vi.vtt
  89. 27
      app/manifest/_beta_modifications.json
  90. 2
      app/manifest/chrome.json
  91. 4
      app/phishing.html
  92. 3
      app/scripts/background.js
  93. 159
      app/scripts/controllers/detect-tokens.js
  94. 209
      app/scripts/controllers/detect-tokens.test.js
  95. 9
      app/scripts/controllers/network/util.test.js
  96. 1
      app/scripts/controllers/permissions/enums.js
  97. 387
      app/scripts/controllers/preferences.js
  98. 635
      app/scripts/controllers/preferences.test.js
  99. 104
      app/scripts/controllers/swaps.js
  100. 28
      app/scripts/controllers/swaps.test.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -304,7 +304,7 @@ jobs:
steps:
- run:
name: Validate changelog
command: yarn auto-changelog validate
command: yarn lint:changelog
- when:
condition:
matches:
@ -313,7 +313,7 @@ jobs:
steps:
- run:
name: Validate release candidate changelog
command: yarn auto-changelog validate --rc
command: yarn lint:changelog:rc
test-deps-audit:

@ -4,11 +4,13 @@ set -e
set -u
set -o pipefail
CHROME_VERSION='87.0.4280.88-1'
# To get the latest version, see <https://www.ubuntuupdates.org/ppa/google_chrome?dist=stable>
CHROME_VERSION='93.0.4577.63-1'
CHROME_BINARY="google-chrome-stable_${CHROME_VERSION}_amd64.deb"
CHROME_BINARY_URL="https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/${CHROME_BINARY}"
CHROME_BINARY_SHA512SUM='19eea1d1be171cab60ce5135572da9388b4b72e313118478b53f65c0bf2293733809282736b98ef828a208b7426e5191258f8c666cba7510b8bf5c92d0010a47'
# To retrieve this checksum, run the `wget` and `shasum` commands below
CHROME_BINARY_SHA512SUM='4102ba417b41820da68b7e8e12018ed2268f30e0210f8f227aeeabf6bd9265dd95ad206993d5626ac1c70a07185fd3ed4eef8a71ee2f5b0770015302c0d26f58'
wget -O "${CHROME_BINARY}" -t 5 "${CHROME_BINARY_URL}"

@ -18,14 +18,15 @@ ignores:
- "@metamask/auto-changelog" # invoked as `auto-changelog`
- "@metamask/forwarder"
- "@metamask/test-dapp"
- "@sentry/cli" # invoked as `sentry-cli`
- "chromedriver"
- "geckodriver"
- "depcheck" # ooo meta
- "ganache-cli"
- "geckodriver"
- "jest"
- "lavamoat-viz"
- "@sentry/cli" # invoked as `sentry-cli`
- "prettier-plugin-sort-json" # automatically imported by prettier
- "source-map-explorer"
- "depcheck" # ooo meta
# development tool
- "yarn-deduplicate"
# storybook

@ -53,6 +53,26 @@ module.exports = {
'prefer-object-spread': 'error',
'require-atomic-updates': 'off',
// This is the same as our default config, but for the noted exceptions
'spaced-comment': [
'error',
'always',
{
markers: [
'global',
'globals',
'eslint',
'eslint-disable',
'*package',
'!',
',',
// Local additions
'/:', // This is for our code fences
],
exceptions: ['=', '-'],
},
],
'import/no-unassigned-import': 'off',
'no-invalid-this': 'off',
@ -112,6 +132,7 @@ module.exports = {
'ui/**/*.test.js',
'ui/__mocks__/*.js',
'shared/**/*.test.js',
'development/**/*.test.js',
],
extends: ['@metamask/eslint-config-mocha'],
rules: {
@ -129,7 +150,12 @@ module.exports = {
},
},
{
files: ['ui/**/*.test.js', 'ui/__mocks__/*.js', 'shared/**/*.test.js'],
files: [
'ui/**/*.test.js',
'ui/__mocks__/*.js',
'shared/**/*.test.js',
'development/**/*.test.js',
],
extends: ['@metamask/eslint-config-jest'],
rules: {
'jest/no-restricted-matchers': 'off',
@ -166,6 +192,16 @@ module.exports = {
sourceType: 'script',
},
},
{
files: [
'app/scripts/lockdown-run.js',
'test/unit-global/protect-intrinsics.test.js',
],
globals: {
harden: 'readonly',
Compartment: 'readonly',
},
},
],
settings: {

@ -22,6 +22,6 @@ jobs:
url-to-cladocument: 'https://metamask.io/cla.html'
# This branch can't have protections, commits are made directly to the specified branch.
branch: 'cla-signatures'
allowlist: 'dependabot[bot],metamaskbot,muji'
allowlist: 'dependabot[bot],metamaskbot'
allow-organization-members: true
blockchain-storage-flag: false

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

@ -0,0 +1,65 @@
export const suggestedTokens = {
"0x6b175474e89094c44da98b954eedeac495271d0f": {
"address": "0x6b175474e89094c44da98b954eedeac495271d0f",
"symbol": "META",
"decimals": 18,
"image": "metamark.svg",
"unlisted": false
},
"0xB8c77482e45F1F44dE1745F52C74426C631bDD52": {
"address": "0xB8c77482e45F1F44dE1745F52C74426C631bDD52",
"symbol": "0X",
"decimals": 18,
"image": "0x.svg",
"unlisted": false
},
"0x1f9840a85d5af5bf1d1762f925bdaddc4201f984": {
"address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
"symbol": "AST",
"decimals": 18,
"image": "ast.png",
"unlisted": false
},
"0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2": {
"address": "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2",
"symbol": "BAT",
"decimals": 18,
"image": "BAT_icon.svg",
"unlisted": false
},
"0xe83cccfabd4ed148903bf36d4283ee7c8b3494d1": {
"address": "0xe83cccfabd4ed148903bf36d4283ee7c8b3494d1",
"symbol": "CVL",
"decimals": 18,
"image": "CVL_token.svg",
"unlisted": false
},
"0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e": {
"address": "0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e",
"symbol": "GLA",
"decimals": 18,
"image": "gladius.svg",
"unlisted": false
},
"0x467Bccd9d29f223BcE8043b84E8C8B282827790F": {
"address": "0x467Bccd9d29f223BcE8043b84E8C8B282827790F",
"symbol": "GNO",
"decimals": 18,
"image": "gnosis.svg",
"unlisted": false
},
"0xff20817765cb7f73d4bde2e66e067e58d11095c2": {
"address": "0xff20817765cb7f73d4bde2e66e067e58d11095c2",
"symbol": "OMG",
"decimals": 18,
"image": "omg.jpg",
"unlisted": false
},
"0x8e870d67f660d95d5be530380d0ec0bd388289e1": {
"address": "0x8e870d67f660d95d5be530380d0ec0bd388289e1",
"symbol": "WED",
"decimals": 18,
"image": "wed.png",
"unlisted": false
},
}

@ -0,0 +1,56 @@
export const tokens = {
"0x33f90dee07c6e8b9682dd20f73e6c358b2ed0f03": {
"address": "0x33f90dee07c6e8b9682dd20f73e6c358b2ed0f03",
"symbol": "TRDT",
"decimals": 18,
"unlisted": false
},
"0x39013f961c378f02c2b82a6e1d31e9812786fd9d": {
"address": "0x39013f961c378f02c2b82a6e1d31e9812786fd9d",
"symbol": "SMS",
"decimals": 18,
"unlisted": false
},
"0x78b7fada55a64dd895d8c8c35779dd8b67fa8a05": {
"address": "0x78b7fada55a64dd895d8c8c35779dd8b67fa8a05",
"symbol": "ATL",
"decimals": 18,
"unlisted": false
},
"0xfd8971d5e8e1740ce2d0a84095fca4de729d0c16": {
"address": "0xfd8971d5e8e1740ce2d0a84095fca4de729d0c16",
"symbol": "ZLA",
"decimals": 18,
"unlisted": false
},
"0xe83cccfabd4ed148903bf36d4283ee7c8b3494d1": {
"address": "0xe83cccfabd4ed148903bf36d4283ee7c8b3494d1",
"symbol": "BTT",
"decimals": 18,
"unlisted": false
},
"0x7a07e1a0c2514d51132183ecfea2a880ec3b7648": {
"address": "0x7a07e1a0c2514d51132183ecfea2a880ec3b7648",
"symbol": "IXE",
"decimals": 18,
"unlisted": false
},
"0x467Bccd9d29f223BcE8043b84E8C8B282827790F": {
"address": "0x467Bccd9d29f223BcE8043b84E8C8B282827790F",
"symbol": "TEL",
"decimals": 18,
"unlisted": false
},
"0xff20817765cb7f73d4bde2e66e067e58d11095c2": {
"address": "0xff20817765cb7f73d4bde2e66e067e58d11095c2",
"symbol": "AMP",
"decimals": 18,
"unlisted": false
},
"0x15bda08c3afbf5955d6e9b235fd55a1fd0dbc829": {
"address": "0x15bda08c3afbf5955d6e9b235fd55a1fd0dbc829",
"symbol": "APC",
"decimals": 18,
"unlisted": false
},
}

@ -12,6 +12,10 @@ module.exports = {
'./i18n-party-addon/register.js',
],
webpackFinal: async (config) => {
config.context = process.cwd()
config.node = {
__filename: true
}
config.module.strictExportPresence = true;
config.module.rules.push({
test: /\.scss$/,

@ -45,6 +45,10 @@ const styles = {
alignItems: 'center',
};
export const getNewState = (state, props) => {
return Object.assign(state, props);
}
export const store = configureStore(testData);
const history = createBrowserHistory();
const proxiedBackground = new Proxy({}, {

File diff suppressed because it is too large Load Diff

@ -28,13 +28,15 @@ To learn how to contribute to the MetaMask project itself, visit our [Internal D
Uncompressed builds can be found in `/dist`, compressed builds can be found in `/builds` once they're built.
See the [build system readme](./development/build/README.md) for build system usage information.
## Contributing
### Development builds
To start a development build (e.g. with logging and file watching) run `yarn start`.
To start the [React DevTools](https://github.com/facebook/react-devtools) and [Redux DevTools Extension](http://extension.remotedev.io)
To start the [React DevTools](https://github.com/facebook/react-devtools) and [Redux DevTools Extension](https://github.com/reduxjs/redux-devtools/tree/main/extension)
alongside the app, use `yarn start:dev`.
- React DevTools will open in a separate window; no browser extension is required
- Redux DevTools will need to be installed as a browser extension. Open the Redux Remote Devtools to access Redux state logs. This can be done by either right clicking within the web browser to bring up the context menu, expanding the Redux DevTools panel and clicking Open Remote DevTools OR clicking the Redux DevTools extension icon and clicking Open Remote DevTools.

@ -38,9 +38,6 @@
"addNetwork": {
"message": "አውታረ መረብ አክል"
},
"addRecipient": {
"message": "ተቀባይ አክል"
},
"addSuggestedTokens": {
"message": "የተጠቆሙ ተለዋጭ ስሞችን አክል"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "ተለዋጭ ስም አክል"
},
"addTokens": {
"message": "ተለዋጭ ስሞችን አክል"
},
"advanced": {
"message": "የላቀ"
},
@ -276,7 +270,7 @@
"message": "አስርዮሽ ቢያንስ 0 ቢበዛ ደግሞ 36 መሆን አለባቸው።"
},
"defaultNetwork": {
"message": "የ Ether ግብይቶች ንቡር አውታረ መረብ Main Net ነው።"
"message": "የ Ether ግብይቶች ንቡር አውታረ መረብ Mainnet ነው።"
},
"delete": {
"message": "ሰርዝ"
@ -543,7 +537,7 @@
"letsGoSetUp": {
"message": "አዎ፣ እናደራጅ!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "እነዚህን ተለዋጭ ስሞች ለማከል ይፈልጋሉ?"
},
"links": {
@ -892,9 +886,6 @@
"sendTokens": {
"message": "ተለዋጭ ስሞችን ላክ"
},
"sentEther": {
"message": "የተላከ ether"
},
"separateEachWord": {
"message": "እያንዳንዱን ቃል በነጠላ ክፍት ቦታ ይለያዩ"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "أضف شبكة"
},
"addRecipient": {
"message": "إضافة مستلم"
},
"addSuggestedTokens": {
"message": "أضف العملات الرمزية المقترحة"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "إضافة عملة رمزية"
},
"addTokens": {
"message": "إضافة عملات رمزية"
},
"advanced": {
"message": "إعدادات متقدمة"
},
@ -539,7 +533,7 @@
"letsGoSetUp": {
"message": "نعم، دعنا نبدأ التثبيت!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "هل ترغب في إضافة هذه الرموز؟"
},
"links": {
@ -888,9 +882,6 @@
"sendTokens": {
"message": "إرسال عملات رمزية"
},
"sentEther": {
"message": "أرسل عملة إيثير"
},
"separateEachWord": {
"message": "افصل كل كلمة بمسافة واحدة"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Добавяне на мрежа"
},
"addRecipient": {
"message": "Добавете получател"
},
"addSuggestedTokens": {
"message": "Добавете препоръчани жетони"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Добавяне на жетон"
},
"addTokens": {
"message": "Добавяне на жетони"
},
"advanced": {
"message": "Разширени"
},
@ -276,7 +270,7 @@
"message": "Десетичните знаци трябва да бъдат най-малко 0 и не повече от 36."
},
"defaultNetwork": {
"message": "Мрежата по подразбиране за Ether транзакции е Main Net."
"message": "Мрежата по подразбиране за Ether транзакции е Mainnet."
},
"delete": {
"message": "Изтриване"
@ -539,7 +533,7 @@
"letsGoSetUp": {
"message": "Да, нека да настроим нещата!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Искате ли да добавите тези жетони?"
},
"links": {
@ -891,9 +885,6 @@
"sendTokens": {
"message": "Изпращане на жетони"
},
"sentEther": {
"message": "изпратен етер"
},
"separateEachWord": {
"message": "Отделете всяка дума с интервал"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "নটওযক যগ করন"
},
"addRecipient": {
"message": "পপক যগ করন"
},
"addSuggestedTokens": {
"message": "পরসিত টনগিগ করন"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "টন যগ করন"
},
"addTokens": {
"message": "টনগিগ করন"
},
"advanced": {
"message": "উননত"
},
@ -543,7 +537,7 @@
"letsGoSetUp": {
"message": "হ, তহলট আপ করওয়ক!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "আপনিি এই টনগিগ করতন?"
},
"links": {
@ -895,9 +889,6 @@
"sendTokens": {
"message": "টনগিন"
},
"sentEther": {
"message": "প ইথর "
},
"separateEachWord": {
"message": "পরতিি শবদক একটিস দি আল করন"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Afegir Xarxa"
},
"addRecipient": {
"message": "Afegeix un recipient"
},
"addSuggestedTokens": {
"message": "Afegir Fitxes Suggerides"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Afegir Fitxa"
},
"addTokens": {
"message": "Afegeix tokens"
},
"advanced": {
"message": "Configuració avançada"
},
@ -273,7 +267,7 @@
"message": "Els decimals han de ser al menys 0, i no més de 36."
},
"defaultNetwork": {
"message": "La xarxa per defecte per a les transaccions Ether és Main Net."
"message": "La xarxa per defecte per a les transaccions Ether és Mainnet."
},
"delete": {
"message": "Suprimeix"
@ -530,7 +524,7 @@
"letsGoSetUp": {
"message": "Sí, posem-nos en marxa!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "T'agradaria afegir aquestes fitxes?"
},
"links": {
@ -873,9 +867,6 @@
"sendTokens": {
"message": "Enviar Fitxes"
},
"sentEther": {
"message": "envia ether"
},
"separateEachWord": {
"message": "Separa cada paraula amb un sol espai"
},

@ -11,9 +11,6 @@
"addToken": {
"message": "Přidat token"
},
"addTokens": {
"message": "Přidat tokeny"
},
"amount": {
"message": "Částka"
},
@ -104,7 +101,7 @@
"message": "Desetinných míst musí být od 0 do 36."
},
"defaultNetwork": {
"message": "Výchozí síť pro Etherové transakce je Main Net."
"message": "Výchozí síť pro Etherové transakce je Mainnet."
},
"depositEther": {
"message": "Vložit Ether"
@ -214,7 +211,7 @@
"learnMore": {
"message": "Zjistěte více."
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Chcete přidat tyto tokeny?"
},
"links": {

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Tilføj netværk"
},
"addRecipient": {
"message": "Tilføj modtager"
},
"addSuggestedTokens": {
"message": "Tilføj foreslåede tokens"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Tilføj Polet"
},
"addTokens": {
"message": "Tilføj tokens"
},
"advanced": {
"message": "Avanceret"
},
@ -276,7 +270,7 @@
"message": "Decimaler skal være mindst 0 og højst 36."
},
"defaultNetwork": {
"message": "Standardnetværket for Ether-transaktioner er Main Net."
"message": "Standardnetværket for Ether-transaktioner er Mainnet."
},
"delete": {
"message": "Slet"
@ -536,7 +530,7 @@
"letsGoSetUp": {
"message": "Ja, lad os komme i gang!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Ønsker du at tilføje disse tokens?"
},
"loadMore": {
@ -873,9 +867,6 @@
"sendTokens": {
"message": "Send tokens"
},
"sentEther": {
"message": "sendte ether"
},
"separateEachWord": {
"message": "Separer hvert ord med et enkelt mellemrum"
},

@ -35,9 +35,6 @@
"addNetwork": {
"message": "Netzwerk hinzufügen"
},
"addRecipient": {
"message": "Empfänger hinzufügen"
},
"addSuggestedTokens": {
"message": "Vorgeschlagene Token hinzufügen"
},
@ -50,9 +47,6 @@
"addToken": {
"message": "Token hinzufügen"
},
"addTokens": {
"message": "Token hinzufügen"
},
"advanced": {
"message": "Erweitert"
},
@ -195,7 +189,7 @@
"message": " Verbinde zum Kovan Testnetzwerk"
},
"connectingToMainnet": {
"message": "Verbinde zum Ethereum Main Net"
"message": "Verbinde zum Ethereum Mainnet"
},
"connectingToRinkeby": {
"message": " Verbinde zum Rinkeby Testnetzwerk"
@ -267,7 +261,7 @@
"message": "Die Dezimalangabe muss mindestens 0 und nicht höher als 36 sein."
},
"defaultNetwork": {
"message": "Das Standardnetzwerk für Ether Transaktionen ist das Main Net."
"message": "Das Standardnetzwerk für Ether Transaktionen ist das Mainnet."
},
"delete": {
"message": "Löschen"
@ -531,7 +525,7 @@
"letsGoSetUp": {
"message": "Ja, legen wir los!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Möchtest du diese Token hinzufügen?"
},
"loadMore": {
@ -547,7 +541,7 @@
"message": "Ausloggen"
},
"mainnet": {
"message": "Ethereum Main Net"
"message": "Ethereum Mainnet"
},
"memo": {
"message": " Memo"
@ -864,9 +858,6 @@
"sendTokens": {
"message": "Token senden"
},
"sentEther": {
"message": "Ether senden"
},
"separateEachWord": {
"message": "Trennen Sie die Wörter mit einem einzelnen Leerzeichen voneinander"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Προσθήκη Δικτύου"
},
"addRecipient": {
"message": "Προσθήκη Παραλήπτη"
},
"addSuggestedTokens": {
"message": "Προσθέστε τα Προτεινόμενα Tokens"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Προσθήκη Token"
},
"addTokens": {
"message": "Προσθήκη Token"
},
"advanced": {
"message": "Σύνθετες"
},
@ -273,7 +267,7 @@
"message": "Τα δεκαδικά πρέπει να είναι τουλάχιστον 0 και όχι πάνω από 36."
},
"defaultNetwork": {
"message": "Το προεπιλεγμένο δίκτυο για συναλλαγές Ether είναι το Main Net."
"message": "Το προεπιλεγμένο δίκτυο για συναλλαγές Ether είναι το Mainnet."
},
"delete": {
"message": "Διαγραφή"
@ -540,7 +534,7 @@
"letsGoSetUp": {
"message": "Ναι, ας το εγκαταστήσουμε!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Θέλετε να προσθέσετε αυτά τα token;"
},
"links": {
@ -892,9 +886,6 @@
"sendTokens": {
"message": "Στείλτε Tokens"
},
"sentEther": {
"message": "απεσταλμένα ether"
},
"separateEachWord": {
"message": "Διαχωρίστε κάθε λέξη με ένα μόνο κενό"
},

@ -52,6 +52,9 @@
"addContact": {
"message": "Add contact"
},
"addCustomToken": {
"message": "Add Custom Token"
},
"addCustomTokenByContractAddress": {
"message": "Can’t find a token? You can manually add any token by pasting its address. Token contract addresses can be found on $1.",
"description": "$1 is a blockchain explorer for a specific network, e.g. Etherscan for Ethereum"
@ -79,9 +82,6 @@
"addNetwork": {
"message": "Add Network"
},
"addRecipient": {
"message": "Add Recipient"
},
"addSuggestedTokens": {
"message": "Add Suggested Tokens"
},
@ -94,9 +94,6 @@
"addToken": {
"message": "Add Token"
},
"addTokens": {
"message": "Add Tokens"
},
"addressBookIcon": {
"message": "Address book icon"
},
@ -243,6 +240,25 @@
"basic": {
"message": "Basic"
},
"betaMetamaskDescription": {
"message": "Trusted by millions, MetaMask is a secure wallet making the world of web3 accessible to all."
},
"betaMetamaskDescriptionExplanation": {
"message": "Use this version to test upcoming features before they’re released. Your use and feedback helps us build the best version of MetaMask possible. Your use of MetaMask Beta is subject to our standard $1 as well as our $2. As a Beta, there may be an increased risk of bugs. By proceeding, you accept and acknowledge these risks, as well as those risks found in our Terms and Beta Terms.",
"description": "$1 represents localization item betaMetamaskDescriptionExplanationTermsLinkText. $2 represents localization item betaMetamaskDescriptionExplanationBetaTermsLinkText"
},
"betaMetamaskDescriptionExplanationBetaTermsLinkText": {
"message": "Supplemental Beta Terms"
},
"betaMetamaskDescriptionExplanationTermsLinkText": {
"message": "Terms"
},
"betaMetamaskVersion": {
"message": "MetaMask Beta Version"
},
"betaWelcome": {
"message": "Welcome to MetaMask Beta"
},
"blockExplorerUrl": {
"message": "Block Explorer URL"
},
@ -289,6 +305,9 @@
"cancel": {
"message": "Cancel"
},
"cancelEdit": {
"message": "Cancel Edit"
},
"cancelPopoverTitle": {
"message": "Cancel transaction"
},
@ -323,10 +342,10 @@
"message": "Confirm password"
},
"confirmSecretBackupPhrase": {
"message": "Confirm your Secret Backup Phrase"
"message": "Confirm your Secret Recovery Phrase"
},
"confirmSeedPhrase": {
"message": "Confirm Seed Phrase"
"message": "Confirm Secret Recovery Phrase"
},
"confirmed": {
"message": "Confirmed"
@ -501,6 +520,9 @@
"currentLanguage": {
"message": "Current Language"
},
"currentlyUnavailable": {
"message": "Unavailable on this network"
},
"customGas": {
"message": "Customize Gas"
},
@ -549,7 +571,7 @@
"message": "Decrypt request"
},
"defaultNetwork": {
"message": "The default network for Ether transactions is Main Net."
"message": "The default network for Ether transactions is Mainnet."
},
"delete": {
"message": "Delete"
@ -594,10 +616,10 @@
"message": "Dismiss"
},
"dismissReminderDescriptionField": {
"message": "Turn this on to dismiss the recovery phrase backup reminder message. We highly recommend that you back up your Secret Recovery Phrase to avoid loss of funds"
"message": "Turn this on to dismiss the Secret Recovery Phrase backup reminder message. We highly recommend that you back up your Secret Recovery Phrase to avoid loss of funds"
},
"dismissReminderField": {
"message": "Dismiss recovery phrase backup reminder"
"message": "Dismiss Secret Recovery Phrase backup reminder"
},
"domain": {
"message": "Domain"
@ -612,7 +634,7 @@
"message": "Download Google Chrome"
},
"downloadSecretBackup": {
"message": "Download this Secret Backup Phrase and keep it stored safely on an external encrypted hard drive or storage medium."
"message": "Download this Secret Recovery Phrase and keep it stored safely on an external encrypted hard drive or storage medium."
},
"downloadStateLogs": {
"message": "Download State Logs"
@ -630,16 +652,16 @@
"message": "How should I choose?"
},
"editGasEducationHighExplanation": {
"message": "This is best for swaps or other time sensitive transactions. If a swap takes too long to process it will often fail and you may lose funds."
"message": "This is best for time sensitive transactions (like Swaps) as it increases the likelihood of a successful transaction. If a Swap takes too long to process it may fail and result in losing some of your gas fee."
},
"editGasEducationLowExplanation": {
"message": "A lower gas fee should only be selected for transactions where processing time is less important. With a lower fee, it can be hard to predict when (or if) your transaction will be successful."
"message": "A lower gas fee should only be used when processing time is less important. Lower fees make it hard predict when (or if) your transaction will be successful."
},
"editGasEducationMediumExplanation": {
"message": "A medium gas fee is good for sending, withdrawing or other non-time sensitive but important transactions."
"message": "A medium gas fee is good for sending, withdrawing or other non-time sensitive transactions. This setting will most often result in a successful transaction."
},
"editGasEducationModalIntro": {
"message": "The right gas amount to select depends on the type of transaction and how important it is."
"message": "Selecting the right gas fee depends on the type of transaction and how important it is to you."
},
"editGasEducationModalTitle": {
"message": "How to choose?"
@ -675,7 +697,7 @@
"message": "Max priority fee is higher than necessary. You may pay more than needed."
},
"editGasMaxPriorityFeeLow": {
"message": "Max priority fee extremely low for network conditions"
"message": "Max priority fee is low for current network conditions"
},
"editGasMaxPriorityFeeTooltip": {
"message": "Max priority fee (aka “miner tip”) goes directly to miners and incentivizes them to prioritize your transaction. You’ll most often pay your max setting"
@ -714,9 +736,8 @@
"editGasTooLowTooltip": {
"message": "Your max fee or max priority fee may be low for current market conditions. We don't know when (or if) your transaction will be processed. "
},
"editGasTotalBannerSubtitle": {
"message": "Up to $1 ($2)",
"display": "$1 represents a fiat value"
"editGasTooLowWarningTooltip": {
"message": "This lowers your maximum fee but if network traffic increases your transaction may be delayed or fail."
},
"editNonceField": {
"message": "Edit Nonce"
@ -727,6 +748,9 @@
"editPermission": {
"message": "Edit Permission"
},
"enableFromSettings": {
"message": " Enable it from Settings."
},
"encryptionPublicKeyNotice": {
"message": "$1 would like your public encryption key. By consenting, this site will be able to compose encrypted messages to you.",
"description": "$1 is the web3 site name"
@ -850,6 +874,12 @@
"expandView": {
"message": "Expand view"
},
"experimental": {
"message": "Experimental"
},
"experimentalSettingsDescription": {
"message": "Token detection & more"
},
"exportPrivateKey": {
"message": "Export Private Key"
},
@ -869,6 +899,9 @@
"failureMessage": {
"message": "Something went wrong, and we were unable to complete the action"
},
"fakeTokenWarning": {
"message": "Anyone can create a token, including creating fake versions of existing tokens. Learn more about $1"
},
"fast": {
"message": "Fast"
},
@ -1048,6 +1081,9 @@
"importAccount": {
"message": "Import Account"
},
"importAccountError": {
"message": "Error importing account."
},
"importAccountLinkText": {
"message": "import using Secret Recovery Phrase"
},
@ -1055,7 +1091,7 @@
"message": " Imported accounts will not be associated with your originally created MetaMask account Secret Recovery Phrase. Learn more about imported accounts "
},
"importAccountSeedPhrase": {
"message": "Import an account with Secret Recovery Phrase"
"message": "Import a wallet with Secret Recovery Phrase"
},
"importAccountText": {
"message": "or $1",
@ -1067,6 +1103,12 @@
"importTokenWarning": {
"message": "Anyone can create a token with any name, including fake versions of existing tokens. Add and trade at your own risk!"
},
"importTokens": {
"message": "import tokens"
},
"importTokensCamelCase": {
"message": "Import Tokens"
},
"importWallet": {
"message": "Import wallet"
},
@ -1168,6 +1210,9 @@
"learnMore": {
"message": "Learn more"
},
"learnScamRisk": {
"message": "scams and security risks."
},
"ledgerAccountRestriction": {
"message": "You need to make use your last account before you can add a new one."
},
@ -1204,8 +1249,8 @@
"letsGoSetUp": {
"message": "Yes, let’s get set up!"
},
"likeToAddTokens": {
"message": "Would you like to add these tokens?"
"likeToImportTokens": {
"message": "Would you like to import these tokens?"
},
"links": {
"message": "Links"
@ -1236,7 +1281,7 @@
},
"makeSureNoOneWatching": {
"message": "Make sure no one is watching your screen",
"description": "Warning to users to be care while creating and saving their new seed phrase"
"description": "Warning to users to be care while creating and saving their new Secret Recovery Phrase"
},
"max": {
"message": "Max"
@ -1313,8 +1358,11 @@
"message": "verify the network details",
"description": "Serves as link text for the 'mismatchedChain' key. This text will be embedded inside the translation for that key."
},
"missingToken": {
"message": "Don't see your token?"
},
"mobileSyncWarning": {
"message": "The 'Sync with extension' feature is temporarily disabled. If you want to use your extension wallet on MetaMask mobile, then on your mobile app: go back to the wallet setup options and select the 'Import with Secret Recovery Phrase' option. Use your extension wallet’s secret phrase to then import your wallet into mobile."
"message": " Proceeding will display a secret QR code that allows access to your accounts. Do not share it with anyone. Support staff will never ask you for it."
},
"mustSelectOne": {
"message": "Must select at least 1 token."
@ -1332,9 +1380,15 @@
"message": "Need help? Contact $1",
"description": "$1 represents `needHelpLinkText`, the text which goes in the help link"
},
"needHelpFeedback": {
"message": "Share your Feedback"
},
"needHelpLinkText": {
"message": "MetaMask Support"
},
"needHelpSubmitTicket": {
"message": "Submit a Ticket"
},
"needImportFile": {
"message": "You must select a file to import.",
"description": "User is important an account and needs to add a file to continue"
@ -1550,9 +1604,6 @@
"onlyAddTrustedNetworks": {
"message": "A malicious network provider can lie about the state of the blockchain and record your network activity. Only add custom networks you trust."
},
"onlyAvailableOnMainnet": {
"message": "Only available on mainnet"
},
"onlyConnectTrust": {
"message": "Only connect with sites you trust."
},
@ -1653,7 +1704,7 @@
"message": "Queued"
},
"readdToken": {
"message": "You can add this token back in the future by going to “Add token” in your accounts options menu."
"message": "You can add this token back in the future by going to “Import token” in your accounts options menu."
},
"receive": {
"message": "Receive"
@ -1691,6 +1742,9 @@
"recoveryPhraseReminderTitle": {
"message": "Protect your funds"
},
"refreshList": {
"message": "Refresh list"
},
"reject": {
"message": "Reject"
},
@ -1801,16 +1855,16 @@
"message": "Search Tokens"
},
"secretBackupPhrase": {
"message": "Secret Backup Phrase"
"message": "Secret Recovery Phrase"
},
"secretBackupPhraseDescription": {
"message": "Your secret backup phrase makes it easy to back up and restore your account."
"message": "Your Secret Recovery Phrase makes it easy to back up and restore your account."
},
"secretBackupPhraseWarning": {
"message": "WARNING: Never disclose your backup phrase. Anyone with this phrase can take your Ether forever."
"message": "WARNING: Never disclose your Secret Recovery Phrase. Anyone with this phrase can take your Ether forever."
},
"secretPhrase": {
"message": "Enter your secret phrase here to restore your vault."
"message": "Only the first account on this wallet will auto load. After completing this process, to add additional accounts, click the drop down menu, then select Create Account."
},
"secureWallet": {
"message": "Secure Wallet"
@ -1840,28 +1894,28 @@
"message": "Store in a bank vault."
},
"seedPhraseIntroSidebarCopyOne": {
"message": "Your recovery phrase is the “master key” to your wallet and funds."
"message": "Your Secret Recovery Phrase is the “master key” to your wallet and funds."
},
"seedPhraseIntroSidebarCopyThree": {
"message": "If someone asks for your recovery phrase, they are most likely trying to scam you."
"message": "If someone asks for your Secret Recovery Phrase, they are most likely trying to scam you."
},
"seedPhraseIntroSidebarCopyTwo": {
"message": "Never, ever share your recovery phrase, even with MetaMask!"
"message": "Never, ever share your Secret Recovery Phrase, even with MetaMask!"
},
"seedPhraseIntroSidebarTitleOne": {
"message": "What is a recovery phrase?"
"message": "What is a Secret Recovery Phrase?"
},
"seedPhraseIntroSidebarTitleThree": {
"message": "Should I share my recovery phrase?"
"message": "Should I share my Secret Recovery Phrase?"
},
"seedPhraseIntroSidebarTitleTwo": {
"message": "How do I save my recovery phrase?"
"message": "How do I save my Secret Recovery Phrase?"
},
"seedPhraseIntroTitle": {
"message": "Secure your wallet"
},
"seedPhraseIntroTitleCopy": {
"message": "Before getting started, watch this short video to learn about your recovery phrase and how to keep your wallet safe."
"message": "Before getting started, watch this short video to learn about your Secret Recovery Phrase and how to keep your wallet safe."
},
"seedPhrasePlaceholder": {
"message": "Separate each word with a single space"
@ -1925,11 +1979,15 @@
"message": "Send $1",
"description": "Symbol of the specified token"
},
"sendTo": {
"message": "Send to"
},
"sendTokens": {
"message": "Send Tokens"
},
"sentEther": {
"message": "sent ether"
"sendingNativeAsset": {
"message": "Sending $1",
"description": "$1 represents the native currency symbol for the current network (e.g. ETH or BNB)"
},
"separateEachWord": {
"message": "Separate each word with a single space"
@ -1983,7 +2041,7 @@
"message": "Sign"
},
"signNotice": {
"message": "Signing this message can have \ndangerous side effects. Only sign messages from \nsites you fully trust with your entire account.\n This dangerous method will be removed in a future version. "
"message": "Signing this message can be dangerous. This signature could potentially perform any operation on your account's behalf, including granting complete control of your account and all of its assets to the requesting site. Only sign this message if you know what you're doing or completely trust the requesting site."
},
"signatureRequest": {
"message": "Signature Request"
@ -2125,10 +2183,6 @@
"message": "No tokens available matching $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "Checking $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "Confirm with your hardware wallet"
},
@ -2144,6 +2198,9 @@
"swapDecentralizedExchange": {
"message": "Decentralized exchange"
},
"swapDirectContract": {
"message": "Direct contract"
},
"swapEditLimit": {
"message": "Edit limit"
},
@ -2171,6 +2228,9 @@
"swapFailedErrorTitle": {
"message": "Swap failed"
},
"swapFetchingQuotes": {
"message": "Fetching quotes"
},
"swapFetchingQuotesErrorDescription": {
"message": "Hmmm... something went wrong. Try again, or if errors persist, contact customer support."
},
@ -2180,9 +2240,6 @@
"swapFetchingTokens": {
"message": "Fetching tokens..."
},
"swapFinalizing": {
"message": "Finalizing..."
},
"swapFromTo": {
"message": "The swap of $1 to $2",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"
@ -2443,6 +2500,9 @@
"symbolBetweenZeroTwelve": {
"message": "Symbol must be 11 characters or fewer."
},
"syncFailed": {
"message": "Sync failed"
},
"syncInProgress": {
"message": "Sync in progress"
},
@ -2513,6 +2573,9 @@
"tokenDecimalFetchFailed": {
"message": "Token decimal required."
},
"tokenDetectionAnnouncement": {
"message": "New! Improved token detection is available on Ethereum Mainnet as an experimental feature. $1"
},
"tokenSymbol": {
"message": "Token Symbol"
},
@ -2537,9 +2600,8 @@
"transactionCreated": {
"message": "Transaction created with a value of $1 at $2."
},
"transactionDetailDappGasHeading": {
"message": "$1 suggested gas fee",
"description": "$1 represents a dapp origin"
"transactionDetailDappGasMoreInfo": {
"message": "Site suggested"
},
"transactionDetailDappGasTooltip": {
"message": "Edit to use MetaMask's recommended gas fee based on the latest block."
@ -2554,7 +2616,7 @@
"message": "Gas fees are set by the network and fluctuate based on network traffic and transaction complexity."
},
"transactionDetailGasTooltipIntro": {
"message": "Gas fees are paid to crypto miners who process transactions on the Ethereum network. MetaMask does not profit from gas fees."
"message": "Gas fees are paid to crypto miners who process transactions on the $1 network. MetaMask does not profit from gas fees."
},
"transactionDetailGasTotalSubtitle": {
"message": "Amount + gas fee"
@ -2575,10 +2637,13 @@
"message": "Transaction Fee"
},
"transactionHistoryBaseFee": {
"message": "Base fee (GWEI)"
"message": "Base Fee (GWEI)"
},
"transactionHistoryMaxFeePerGas": {
"message": "Max Fee Per Gas"
},
"transactionHistoryPriorityFee": {
"message": "Priority fee (GWEI)"
"message": "Priority Fee (GWEI)"
},
"transactionHistoryTotalGasFee": {
"message": "Total Gas Fee"
@ -2676,6 +2741,12 @@
"usePhishingDetectionDescription": {
"message": "Display a warning for phishing domains targeting Ethereum users"
},
"useTokenDetection": {
"message": "Use Token Detection"
},
"useTokenDetectionDescription": {
"message": "We use third-party APIs to detect and display new tokens sent to your wallet. Turn off if you don’t want MetaMask to pull data from those services."
},
"usedByClients": {
"message": "Used by a variety of different clients"
},

@ -79,9 +79,6 @@
"addNetwork": {
"message": "Agregar red"
},
"addRecipient": {
"message": "Agregar destinatario"
},
"addSuggestedTokens": {
"message": "Agregar tokens sugeridos"
},
@ -94,9 +91,6 @@
"addToken": {
"message": "Agregar token"
},
"addTokens": {
"message": "Agregar tokens"
},
"advanced": {
"message": "Avanzado"
},
@ -1028,7 +1022,7 @@
"letsGoSetUp": {
"message": "Sí, vamos a establecer la configuración."
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "¿Le gustaría agregar estos tokens?"
},
"links": {
@ -1343,9 +1337,6 @@
"onlyAddTrustedNetworks": {
"message": "Un proveedor de red malintencionado puede mentir sobre el estado de la cadena de bloques y registrar su actividad de red. Agregue solo redes personalizadas de confianza."
},
"onlyAvailableOnMainnet": {
"message": "Solo disponible en la red principal"
},
"onlyConnectTrust": {
"message": "Conéctese solo con sitios de confianza."
},
@ -1694,9 +1685,6 @@
"sendTokens": {
"message": "Enviar tokens"
},
"sentEther": {
"message": "enviar ether"
},
"separateEachWord": {
"message": "Separar cada palabra con un solo espacio"
},
@ -1876,10 +1864,6 @@
"message": "No hay tokens disponibles que coincidan con $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "Comprobando $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "Confirmar con la cartera de hardware"
},
@ -1931,9 +1915,6 @@
"swapFetchingTokens": {
"message": "Capturando tokens…"
},
"swapFinalizing": {
"message": "Finalizando…"
},
"swapFromTo": {
"message": "El canje de $1 por $2",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"

@ -79,9 +79,6 @@
"addNetwork": {
"message": "Agregar red"
},
"addRecipient": {
"message": "Agregar destinatario"
},
"addSuggestedTokens": {
"message": "Agregar tokens sugeridos"
},
@ -94,9 +91,6 @@
"addToken": {
"message": "Agregar token"
},
"addTokens": {
"message": "Agregar tokens"
},
"advanced": {
"message": "Avanzado"
},
@ -1028,7 +1022,7 @@
"letsGoSetUp": {
"message": "Sí, vamos a establecer la configuración."
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "¿Le gustaría agregar estos tokens?"
},
"links": {
@ -1343,9 +1337,6 @@
"onlyAddTrustedNetworks": {
"message": "Un proveedor de red malintencionado puede mentir sobre el estado de la cadena de bloques y registrar su actividad de red. Agregue solo redes personalizadas de confianza."
},
"onlyAvailableOnMainnet": {
"message": "Solo disponible en la red principal"
},
"onlyConnectTrust": {
"message": "Conéctese solo con sitios de confianza."
},
@ -1694,9 +1685,6 @@
"sendTokens": {
"message": "Enviar tokens"
},
"sentEther": {
"message": "enviar ether"
},
"separateEachWord": {
"message": "Separar cada palabra con un solo espacio"
},
@ -1876,10 +1864,6 @@
"message": "No hay tokens disponibles que coincidan con $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "Comprobando $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "Confirmar con la cartera de hardware"
},
@ -1931,9 +1915,6 @@
"swapFetchingTokens": {
"message": "Capturando tokens…"
},
"swapFinalizing": {
"message": "Finalizando…"
},
"swapFromTo": {
"message": "El canje de $1 por $2",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Lisage võrk"
},
"addRecipient": {
"message": "Lisa saaja"
},
"addSuggestedTokens": {
"message": "Lisa soovitatud lube"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Lisage luba"
},
"addTokens": {
"message": "Lisa lube"
},
"advanced": {
"message": "Täpsemad"
},
@ -539,7 +533,7 @@
"letsGoSetUp": {
"message": "Jah, hakkame pihta!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Kas soovite need load lisada?"
},
"links": {
@ -885,9 +879,6 @@
"sendTokens": {
"message": "Saada lube"
},
"sentEther": {
"message": "saadetud eeter"
},
"separateEachWord": {
"message": "Eraldage iga sõna ühe tühikuga"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "اضافه شبکه"
},
"addRecipient": {
"message": "اضافه کردن دریافت کننده"
},
"addSuggestedTokens": {
"message": "اضافه رمزیاب های پیشنهاد شده"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "یک رمز یاب اضافه کنید"
},
"addTokens": {
"message": "اضافه رمزیاب ها"
},
"advanced": {
"message": "پیشرفته"
},
@ -276,7 +270,7 @@
"message": "اعشاریه ها باید حد اقل 0، و بیشتر از 36 نباشند."
},
"defaultNetwork": {
"message": "شبکه خودکار برای معاملات Ether عبارت است از Main Net."
"message": "شبکه خودکار برای معاملات Ether عبارت است از Mainnet."
},
"delete": {
"message": "حذف"
@ -543,7 +537,7 @@
"letsGoSetUp": {
"message": "بلی، درست شد!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "آیا میخواهید این رمزیاب ها را اضافه نمایید؟"
},
"links": {
@ -895,9 +889,6 @@
"sendTokens": {
"message": "رمزیاب ها را ارسال کنید"
},
"sentEther": {
"message": "ایتر ارسال شد"
},
"separateEachWord": {
"message": "هر کلمه را با یک فاصله واحد جدا سازید"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Lisää verkko"
},
"addRecipient": {
"message": "Lisää vastaanottaja"
},
"addSuggestedTokens": {
"message": "Lisää ehdotetut käyttötunnukset"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Lisää tietue"
},
"addTokens": {
"message": "Lisää poletteja"
},
"advanced": {
"message": "Lisäasetukset"
},
@ -276,7 +270,7 @@
"message": "Desimaalien on oltava vähintään 0 ja korkeintaan 36."
},
"defaultNetwork": {
"message": "Oletusverkko Ether-tapahtumille on Main Net."
"message": "Oletusverkko Ether-tapahtumille on Mainnet."
},
"delete": {
"message": "Poista"
@ -543,7 +537,7 @@
"letsGoSetUp": {
"message": "Kyllä, valmistaudutaan!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Haluaisitko lisätä nämä poletit?"
},
"links": {
@ -892,9 +886,6 @@
"sendTokens": {
"message": "Lähetä tietueita"
},
"sentEther": {
"message": "lähetä etheriä"
},
"separateEachWord": {
"message": "Erottele sanat toisistaan yhdellä välilyönnillä"
},

@ -35,9 +35,6 @@
"addNetwork": {
"message": "Magdagdag ng Network"
},
"addRecipient": {
"message": "Magdagdag ng Recipient"
},
"addSuggestedTokens": {
"message": "Magdagdag ng Mga Iminungkahing Token"
},
@ -50,9 +47,6 @@
"addToken": {
"message": "Magdagdag ng Token"
},
"addTokens": {
"message": "Magdagdag ng Mga Token"
},
"advancedOptions": {
"message": "Mga Advanced na Opsyon"
},
@ -252,7 +246,7 @@
"message": "Ang mga decimal ay hindi dapat bumaba sa 0, at hindi lumampas sa 36."
},
"defaultNetwork": {
"message": "Ang default na network para sa mga transaksyon ng Ether ay Main Net."
"message": "Ang default na network para sa mga transaksyon ng Ether ay Mainnet."
},
"delete": {
"message": "I-delete"
@ -493,7 +487,7 @@
"letsGoSetUp": {
"message": "Oo, i-set up natin ito!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Gusto mo bang idagdag ang mga token na ito?"
},
"links": {
@ -807,9 +801,6 @@
"sendTokens": {
"message": "Magpadala ng Mga Token"
},
"sentEther": {
"message": "nagpadala ng ether"
},
"separateEachWord": {
"message": "Paghiwa-hiwalayin ang bawat salita gamit ang isang space"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Ajouter un réseau"
},
"addRecipient": {
"message": "Ajouter destinataire"
},
"addSuggestedTokens": {
"message": "Ajouter les jetons suggérés"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Ajouter un jeton"
},
"addTokens": {
"message": "Ajouter des jetons"
},
"advanced": {
"message": "Paramètres avancés"
},
@ -537,7 +531,7 @@
"letsGoSetUp": {
"message": "Oui, passons à la configuration !"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Souhaitez-vous ajouter ces jetons ?"
},
"links": {
@ -657,7 +651,7 @@
"message": "de"
},
"off": {
"message": "Déconnecté"
"message": "Désactivé"
},
"on": {
"message": "Activé"
@ -877,9 +871,6 @@
"sendTokens": {
"message": "Envoyer des jetons"
},
"sentEther": {
"message": "Ether envoyé"
},
"separateEachWord": {
"message": "Separez chaque mot avec un espace simple"
},
@ -1113,7 +1104,7 @@
"message": "Voir contact"
},
"viewOnCustomBlockExplorer": {
"message": "Afficher à $1"
"message": "Afficher sur $1"
},
"viewOnEtherscan": {
"message": "Voir sur Etherscan"

@ -38,9 +38,6 @@
"addNetwork": {
"message": "הוסף/י רשת"
},
"addRecipient": {
"message": "הוסף נמען"
},
"addSuggestedTokens": {
"message": "הוסף/י אסימונים מוצעים"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "הוסף/י אסימון"
},
"addTokens": {
"message": "הוסף סמלים"
},
"advanced": {
"message": "מתקדם"
},
@ -276,7 +270,7 @@
"message": "מספרים עשרוניים חייבים להיות לפחות 0 ולא מעל 36."
},
"defaultNetwork": {
"message": "רשת ברירת המחדל לעסקאות Ether היא Main Net."
"message": "רשת ברירת המחדל לעסקאות Ether היא Mainnet."
},
"delete": {
"message": "מחיקה"
@ -543,7 +537,7 @@
"letsGoSetUp": {
"message": "כן, בוא נתקין!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "האם ברצונך להוסיף טוקנים אלה?"
},
"links": {
@ -889,9 +883,6 @@
"sendTokens": {
"message": "שלח טוקנים"
},
"sentEther": {
"message": "את'ר שנשלח"
},
"separateEachWord": {
"message": "יש להפריד כל מילה עם רווח יחיד"
},

@ -79,9 +79,6 @@
"addNetwork": {
"message": "नटवरक ज"
},
"addRecipient": {
"message": "पतकर"
},
"addSuggestedTokens": {
"message": "सए गए टकन ज"
},
@ -94,9 +91,6 @@
"addToken": {
"message": "टकन ज"
},
"addTokens": {
"message": "टकन ज"
},
"advanced": {
"message": "उननत"
},
@ -519,7 +513,7 @@
"message": "अनध डििट कर"
},
"defaultNetwork": {
"message": "Ether कनदन किए डिट नटवरक Main Net ह।"
"message": "Ether कनदन किए डिट नटवरक Mainnet ह।"
},
"delete": {
"message": "हट"
@ -1028,7 +1022,7 @@
"letsGoSetUp": {
"message": "ह, आइए सट करत!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "क आप इन टकन कहत?"
},
"links": {
@ -1343,9 +1337,6 @@
"onlyAddTrustedNetworks": {
"message": "एक दवनण नटवरक परदकचन कििठ बल सकत और आपकटवरक गतििििड कर सकत। कवल उन कसटम नटवरक क, जिन पर आप भर करत।"
},
"onlyAvailableOnMainnet": {
"message": "कवल मननट पर उपलबध ह"
},
"onlyConnectTrust": {
"message": "कवल उन सइट कनट कर, जिन पर आप भर करत।"
},
@ -1694,9 +1685,6 @@
"sendTokens": {
"message": "टकन भ"
},
"sentEther": {
"message": "Ether भ गय"
},
"separateEachWord": {
"message": "परतक शबद क एक रिि अलग कर"
},
@ -1876,10 +1864,6 @@
"message": "$1 किन वई भकन उपलबध नह",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "$1 कच क रह",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "अपनडवयर वट सि कर"
},
@ -1931,9 +1915,6 @@
"swapFetchingTokens": {
"message": "टकन पत किए ज रह..."
},
"swapFinalizing": {
"message": "अिम रप दि रह..."
},
"swapFromTo": {
"message": "$1 स $2 कप",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"

@ -11,9 +11,6 @@
"addToken": {
"message": "टकन ज"
},
"addTokens": {
"message": "टकन"
},
"amount": {
"message": "रि"
},
@ -194,7 +191,7 @@
"kovan": {
"message": "कन टट नटवरक"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "क आप इन टकनहत?"
},
"loading": {

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Dodaj mrežu"
},
"addRecipient": {
"message": "Dodaj primatelja"
},
"addSuggestedTokens": {
"message": "Dodaj predložene tokene"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Dodaj token"
},
"addTokens": {
"message": "Dodaj tokene"
},
"advanced": {
"message": "Napredno"
},
@ -539,7 +533,7 @@
"letsGoSetUp": {
"message": "Da, obavimo postavljanje!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Želite li dodati ove tokene?"
},
"links": {
@ -888,9 +882,6 @@
"sendTokens": {
"message": "Pošalji tokene"
},
"sentEther": {
"message": "pošalji ether"
},
"separateEachWord": {
"message": "Odvojite pojedinačne riječi jednim razmakom"
},

@ -29,9 +29,6 @@
"addToken": {
"message": "Ajoute Token"
},
"addTokens": {
"message": "Ajoute Token"
},
"amount": {
"message": "Kantite lajan"
},
@ -311,7 +308,7 @@
"ledgerAccountRestriction": {
"message": "Ou bezwen sèvi ak dènye kont ou anvan ou ka ajoute yon nouvo."
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Èske ou ta renmen ajoute sa nan tokens?"
},
"links": {
@ -555,9 +552,6 @@
"sendTokens": {
"message": "Voye Tokens"
},
"sentEther": {
"message": "Voye ether"
},
"separateEachWord": {
"message": "Separe chak mo ak yon sèl espas"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Hálózat hozzáadása"
},
"addRecipient": {
"message": "Címzett hozzáadása"
},
"addSuggestedTokens": {
"message": "Javasolt tokenek hozzáadása"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Token hozzáadása"
},
"addTokens": {
"message": "Érmék hozzáadása"
},
"advanced": {
"message": "Speciális"
},
@ -276,7 +270,7 @@
"message": "A tizedesjegyek száma 0 és 36 között legyen . "
},
"defaultNetwork": {
"message": "Az Ether tranzakciók alapértelmezett hálózata a Main Net."
"message": "Az Ether tranzakciók alapértelmezett hálózata a Mainnet."
},
"delete": {
"message": "Törlés"
@ -539,7 +533,7 @@
"letsGoSetUp": {
"message": "Igen, hozzuk létre!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Hozzá szeretné adni ezeket az érméket?"
},
"links": {
@ -888,9 +882,6 @@
"sendTokens": {
"message": "Token küldése"
},
"sentEther": {
"message": "elküldött ether"
},
"separateEachWord": {
"message": "Minden egyes szavat szóközzel válasszon el"
},

@ -79,9 +79,6 @@
"addNetwork": {
"message": "Tambahkan Jaringan"
},
"addRecipient": {
"message": "Tambahkan Penerima"
},
"addSuggestedTokens": {
"message": "Tambahkan Token yang Disarankan"
},
@ -94,9 +91,6 @@
"addToken": {
"message": "Tambahkan Token"
},
"addTokens": {
"message": "Tambahkan Token"
},
"advanced": {
"message": "Tingkat Lanjut"
},
@ -1028,7 +1022,7 @@
"letsGoSetUp": {
"message": "Ya, mari siap-siap!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Apakah Anda ingin menambahkan token ini?"
},
"links": {
@ -1343,9 +1337,6 @@
"onlyAddTrustedNetworks": {
"message": "Penyedia jaringan jahat dapat berbohong tentang status blockchain dan merekam aktivitas jaringan Anda. Hanya tambahkan jaringan kustom yang Anda percayai."
},
"onlyAvailableOnMainnet": {
"message": "Hanya tersedia di mainnet"
},
"onlyConnectTrust": {
"message": "Hanya hubungkan ke situs yang Anda percayai."
},
@ -1694,9 +1685,6 @@
"sendTokens": {
"message": "Kirim Token"
},
"sentEther": {
"message": "ether terkirim"
},
"separateEachWord": {
"message": "Pisahkan setiap kata dengan satu spasi"
},
@ -1876,10 +1864,6 @@
"message": "Tidak ada token yang cocok yang tersedia $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "Memeriksa $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "Konfirmasikan dengan dompet perangkat keras Anda"
},
@ -1931,9 +1915,6 @@
"swapFetchingTokens": {
"message": "Mengambil token..."
},
"swapFinalizing": {
"message": "Menyelesaikan..."
},
"swapFromTo": {
"message": "Penukaran dari $1 ke $2",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"

@ -52,9 +52,6 @@
"addNetwork": {
"message": "Aggiungi Rete"
},
"addRecipient": {
"message": "Aggiungi destinatario"
},
"addSuggestedTokens": {
"message": "Aggiungi Token Suggeriti"
},
@ -67,9 +64,6 @@
"addToken": {
"message": "Aggiungi Token"
},
"addTokens": {
"message": "Aggiungi token"
},
"advanced": {
"message": "Avanzate"
},
@ -878,7 +872,7 @@
"letsGoSetUp": {
"message": "Si, iniziamo!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Vorresti aggiungere questi token?"
},
"links": {
@ -1096,9 +1090,6 @@
"onlyAddTrustedNetworks": {
"message": "Una rete malevola può mentire sullo stato della blockchain e registrare le tue azioni. Aggiungi solo reti fidate."
},
"onlyAvailableOnMainnet": {
"message": "Disponibile solo nella rete principale"
},
"onlyConnectTrust": {
"message": "Connettiti solo con siti di cui ti fidi."
},
@ -1374,9 +1365,6 @@
"sendTokens": {
"message": "Invia Tokens"
},
"sentEther": {
"message": "ether inviati"
},
"separateEachWord": {
"message": "Separa ogni parola con un solo spazio"
},
@ -1528,10 +1516,6 @@
"message": "Non ci sono token disponibile con questo nome $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "Verificando $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapCustom": {
"message": "personalizza"
},
@ -1570,9 +1554,6 @@
"swapFetchingTokens": {
"message": "Recuperando i token..."
},
"swapFinalizing": {
"message": "Finalizzando..."
},
"swapLowSlippageError": {
"message": "La transazione può fallire, il massimo slippage è troppo basso."
},

@ -79,9 +79,6 @@
"addNetwork": {
"message": "ネットワークの追加"
},
"addRecipient": {
"message": "受信者の追加"
},
"addSuggestedTokens": {
"message": "推奨されたトークンの追加"
},
@ -94,9 +91,6 @@
"addToken": {
"message": "トークンの追加"
},
"addTokens": {
"message": "トークンの追加"
},
"advanced": {
"message": "詳細"
},
@ -1028,7 +1022,7 @@
"letsGoSetUp": {
"message": "さあセットアップしましょう!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "これらのトークンを追加しますか?"
},
"links": {
@ -1343,9 +1337,6 @@
"onlyAddTrustedNetworks": {
"message": "悪意のあるネットワーク プロバイダは、ブロックチェーンの状態を偽り、お客様のネットワーク行動を記録することがあります。信頼するカスタム ネットワークのみを追加してください。"
},
"onlyAvailableOnMainnet": {
"message": "メインネットのみで使用可能"
},
"onlyConnectTrust": {
"message": "信頼するサイトにのみ接続します。"
},
@ -1694,9 +1685,6 @@
"sendTokens": {
"message": "トークンの送信"
},
"sentEther": {
"message": "Ether の送金"
},
"separateEachWord": {
"message": "単語ごとにスペースを 1 つ置いて分離します"
},
@ -1876,10 +1864,6 @@
"message": "$1 と一致するトークンがありません",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "$1 をチェック中",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "ハードウェア ウォレットで確認する"
},
@ -1931,9 +1915,6 @@
"swapFetchingTokens": {
"message": "トークンを取り出し中..."
},
"swapFinalizing": {
"message": "終了中..."
},
"swapFromTo": {
"message": "$1 から $2 のスワップ",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"

@ -38,9 +38,6 @@
"addNetwork": {
"message": "ನವರಿಿ"
},
"addRecipient": {
"message": "ಸಿರರನಿಿ"
},
"addSuggestedTokens": {
"message": "ಸಿಸಲದ ಟಕನಗಳನಿಿ"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "ಟಕನಿಿ"
},
"addTokens": {
"message": "ಟಕನಗಳನಿಿ"
},
"advanced": {
"message": "ಸಿತ"
},
@ -543,7 +537,7 @@
"letsGoSetUp": {
"message": "ಹ, ಹಿಣ!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "ನ ಈ ಟಕನಗಳನಿಸಲ ಬಯಸ?"
},
"links": {
@ -895,9 +889,6 @@
"sendTokens": {
"message": "ಟಕನಗಳನ ಕಳಿಿ"
},
"sentEther": {
"message": "ಕಳಿಸಲದ ಎಥರ"
},
"separateEachWord": {
"message": "ಒಲಕ ಪರತಿ ಪದವನಪಡಿಿ"
},

@ -79,9 +79,6 @@
"addNetwork": {
"message": "네트워크 추가"
},
"addRecipient": {
"message": "수신인 추가"
},
"addSuggestedTokens": {
"message": "추천 토큰 추가"
},
@ -94,9 +91,6 @@
"addToken": {
"message": "토큰 추가"
},
"addTokens": {
"message": "토큰 추가"
},
"advanced": {
"message": "고급"
},
@ -1028,7 +1022,7 @@
"letsGoSetUp": {
"message": "설정을 시작하죠!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "이 토큰을 추가하시겠어요?"
},
"links": {
@ -1343,9 +1337,6 @@
"onlyAddTrustedNetworks": {
"message": "악성 네트워크 공급업체는 블록체인 상태를 거짓으로 보고하고 네트워크 활동을 기록할 수 있습니다. 신뢰하는 맞춤형 네트워크만 추가하세요."
},
"onlyAvailableOnMainnet": {
"message": "메인넷에서만 사용 가능"
},
"onlyConnectTrust": {
"message": "신뢰하는 사이트만 연결하세요."
},
@ -1694,9 +1685,6 @@
"sendTokens": {
"message": "토큰 보내기"
},
"sentEther": {
"message": "Ether 보냄"
},
"separateEachWord": {
"message": "공백 한 칸으로 각 단어를 구분하세요."
},
@ -1876,10 +1864,6 @@
"message": "$1와(과) 일치하는 토큰이 없습니다.",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "$1 확인 중",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "하드웨어 지갑으로 확인합니다."
},
@ -1931,9 +1915,6 @@
"swapFetchingTokens": {
"message": "토큰 가져오는 중..."
},
"swapFinalizing": {
"message": "마무리 중..."
},
"swapFromTo": {
"message": "$1을(를) $2(으)로 스왑",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Pridėti tinklą"
},
"addRecipient": {
"message": "Pridėti gavėją"
},
"addSuggestedTokens": {
"message": "Pridėti siūlomų žetonų"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Pridėti žetoną"
},
"addTokens": {
"message": "Pridėti žetonų"
},
"advanced": {
"message": "Išplėstiniai"
},
@ -543,7 +537,7 @@
"letsGoSetUp": {
"message": "Taip, pradėkime!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Ar norėtumėte pridėti šiuos žetonus?"
},
"links": {
@ -895,9 +889,6 @@
"sendTokens": {
"message": "Siųsti žetonus"
},
"sentEther": {
"message": "siųsti eterių"
},
"separateEachWord": {
"message": "Kiekvieną žodį atskirkite viengubu tarpu"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Pievienot tīklu"
},
"addRecipient": {
"message": "Pievienot saņēmēju"
},
"addSuggestedTokens": {
"message": "Pievienot ieteiktos marķierus"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Pievienot žetonu"
},
"addTokens": {
"message": "Pievienot marķierus"
},
"advanced": {
"message": "Papildu"
},
@ -276,7 +270,7 @@
"message": "Daļskaitļiem jābūt diapazonā no 0 līdz 36."
},
"defaultNetwork": {
"message": "Galvenais Ether darījumu tīkls ir Main Net."
"message": "Galvenais Ether darījumu tīkls ir Mainnet."
},
"delete": {
"message": "Dzēst"
@ -539,7 +533,7 @@
"letsGoSetUp": {
"message": "Jā, sāksim iestatīšanu!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Vai vēlaties pievienot šos marķierus?"
},
"links": {
@ -891,9 +885,6 @@
"sendTokens": {
"message": "Nosūtīt marķierus"
},
"sentEther": {
"message": "nosūtītie ether"
},
"separateEachWord": {
"message": "Atdaliet katru vārdu ar vienu atstarpi"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Tambah Rangkaian"
},
"addRecipient": {
"message": "Tambah Penerima"
},
"addSuggestedTokens": {
"message": "Tambah Token yang Disyorkan"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Tambah Token"
},
"addTokens": {
"message": "Tambah Token"
},
"advanced": {
"message": "Lanjutan"
},
@ -529,7 +523,7 @@
"letsGoSetUp": {
"message": "Ya, mari sediakannya!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Adakah anda ingin menambah token ini?"
},
"links": {
@ -872,9 +866,6 @@
"sendTokens": {
"message": "Hantar Token"
},
"sentEther": {
"message": "menghantar ether"
},
"separateEachWord": {
"message": "Pisahkan setiap perkataan dengan ruang tunggal"
},

@ -8,9 +8,6 @@
"addToken": {
"message": "Voeg token toe"
},
"addTokens": {
"message": "Tokens toevoegen"
},
"amount": {
"message": "Bedrag"
},
@ -80,7 +77,7 @@
"message": "Decimalen moeten minimaal 0 en niet meer dan 36 zijn."
},
"defaultNetwork": {
"message": "Het standaardnetwerk voor Ether-transacties is Main Net."
"message": "Het standaardnetwerk voor Ether-transacties is Mainnet."
},
"depositEther": {
"message": "Stort Ether"
@ -188,7 +185,7 @@
"kovan": {
"message": "Kovan-testnetwerk"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Wil je deze tokens toevoegen?"
},
"loading": {
@ -201,7 +198,7 @@
"message": "Uitloggen"
},
"mainnet": {
"message": "Main Netwerk"
"message": "Mainnetwerk"
},
"message": {
"message": "Bericht"

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Legg til nettverk"
},
"addRecipient": {
"message": "Legg til mottaker "
},
"addSuggestedTokens": {
"message": "Legg til foreslåtte tokener "
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Legg til token "
},
"addTokens": {
"message": "Legg til sjetonger"
},
"advanced": {
"message": "Avansert"
},
@ -273,7 +267,7 @@
"message": "Desimaler må være minst 0, og ikke flere enn 36."
},
"defaultNetwork": {
"message": "Standardnettverket for Ether-transaksjoner er Main Net."
"message": "Standardnettverket for Ether-transaksjoner er Mainnet."
},
"delete": {
"message": "Slett"
@ -530,7 +524,7 @@
"letsGoSetUp": {
"message": "Ja, la oss komme i gang!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Ønsker du å legge til disse tokenene"
},
"links": {
@ -876,9 +870,6 @@
"sendTokens": {
"message": "Send tokener"
},
"sentEther": {
"message": "sendt ether"
},
"separateEachWord": {
"message": "Del hvert ord med et enkelt mellomrom "
},

@ -79,9 +79,6 @@
"addNetwork": {
"message": "Magdagdag ng Network"
},
"addRecipient": {
"message": "Magdagdag ng Recipient"
},
"addSuggestedTokens": {
"message": "Magdagdag ng Mga Iminumungkahing Token"
},
@ -94,9 +91,6 @@
"addToken": {
"message": "Magdagdag ng Token"
},
"addTokens": {
"message": "Magdagdag ng Mga Token"
},
"advanced": {
"message": "Advanced"
},
@ -519,7 +513,7 @@
"message": "I-decrypt ang request"
},
"defaultNetwork": {
"message": "Ang default na network para sa mga transaksyon ng Ether ay ang Main Net."
"message": "Ang default na network para sa mga transaksyon ng Ether ay ang Mainnet."
},
"delete": {
"message": "I-delete"
@ -1028,7 +1022,7 @@
"letsGoSetUp": {
"message": "Sige, simulan na nating mag-set up!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Gusto mo bang idagdag ang mga token na ito?"
},
"links": {
@ -1343,9 +1337,6 @@
"onlyAddTrustedNetworks": {
"message": "Magagawa ng nakakapinsalang network provider na magsinungaling tungkol sa status ng blockchain at itala ang aktibidad ng iyong network. Magdagdag lang ng mga custom na network na pinagkakatiwalaan mo."
},
"onlyAvailableOnMainnet": {
"message": "Available lang sa mainnet"
},
"onlyConnectTrust": {
"message": "Kumonekta lang sa mga site na pinagkakatiwalaan mo."
},
@ -1694,9 +1685,6 @@
"sendTokens": {
"message": "Magpadala ng Mga Token"
},
"sentEther": {
"message": "nagpadala ng ether"
},
"separateEachWord": {
"message": "Paghiwa-hiwalayin ang bawat salita gamit ang isang space"
},
@ -1876,10 +1864,6 @@
"message": "Walang available na token na tumutugma sa $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "Sinusuri ang $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "Kumpirmahin ang iyong hardware wallet"
},
@ -1931,9 +1915,6 @@
"swapFetchingTokens": {
"message": "Kinukuha ang mga token..."
},
"swapFinalizing": {
"message": "Isinasapinal..."
},
"swapFromTo": {
"message": "Ang pag-swap ng $1 sa $2",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Dodaj sieć"
},
"addRecipient": {
"message": "Dodaj odbiorcę"
},
"addSuggestedTokens": {
"message": "Dodaj sugerowane tokeny."
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Dodaj token"
},
"addTokens": {
"message": "Dodaj tokeny"
},
"advanced": {
"message": "Zaawansowane"
},
@ -276,7 +270,7 @@
"message": "Liczb po przecinku musi być co najmniej 0 i nie więcej niż 36."
},
"defaultNetwork": {
"message": "Domyślna sieć dla Eteru to Main Net."
"message": "Domyślna sieć dla Eteru to Mainnet."
},
"delete": {
"message": "Usuń"
@ -543,7 +537,7 @@
"letsGoSetUp": {
"message": "Tak, zacznijmy od początku!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Czy chcesz dodać te tokeny?"
},
"links": {
@ -889,9 +883,6 @@
"sendTokens": {
"message": "Wyślij tokeny"
},
"sentEther": {
"message": "wyślij eter"
},
"separateEachWord": {
"message": "Oddziel słowa pojedynczą spacją"
},

@ -11,9 +11,6 @@
"addToken": {
"message": "Adicionar Token"
},
"addTokens": {
"message": "Adicionar Tokens"
},
"amount": {
"message": "Valor"
},
@ -83,7 +80,7 @@
"message": "Decimais devem ser no mínimo 0 e não passar de 36."
},
"defaultNetwork": {
"message": "A rede pré definida para transações em Ether é a Main Net."
"message": "A rede pré definida para transações em Ether é a Mainnet."
},
"depositEther": {
"message": "Depositar Ether"
@ -194,7 +191,7 @@
"kovan": {
"message": "Rede de Teste Kovan"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Gostaria de adicionar estes tokens?"
},
"loading": {

@ -79,9 +79,6 @@
"addNetwork": {
"message": "Adicionar rede"
},
"addRecipient": {
"message": "Adicionar destinatário"
},
"addSuggestedTokens": {
"message": "Adicionar tokens sugeridos"
},
@ -94,9 +91,6 @@
"addToken": {
"message": "Adicionar token"
},
"addTokens": {
"message": "Adicionar tokens"
},
"advanced": {
"message": "Avançadas"
},
@ -1028,7 +1022,7 @@
"letsGoSetUp": {
"message": "Sim, vamos fazer a configuração!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Você gostaria de adicionar esses tokens?"
},
"links": {
@ -1343,9 +1337,6 @@
"onlyAddTrustedNetworks": {
"message": "Um provedor de rede mal-intencionado pode mentir sobre o estado do blockchain e gravar a atividade da sua rede. Adicione somente as redes em que você confia."
},
"onlyAvailableOnMainnet": {
"message": "Disponível somente na mainnet"
},
"onlyConnectTrust": {
"message": "Conecte-se somente com sites em quem você confia."
},
@ -1694,9 +1685,6 @@
"sendTokens": {
"message": "Enviar tokens"
},
"sentEther": {
"message": "ether enviado"
},
"separateEachWord": {
"message": "Separe cada palavra com um único espaço"
},
@ -1876,10 +1864,6 @@
"message": "Nenhum token disponível correspondente a $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "Verificando $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "Confirme com sua carteira de hardware"
},
@ -1931,9 +1915,6 @@
"swapFetchingTokens": {
"message": "Fetch dos tokens..."
},
"swapFinalizing": {
"message": "Finalizando..."
},
"swapFromTo": {
"message": "O swap de $1 para $2",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Adăugați rețea"
},
"addRecipient": {
"message": "Adăugați destinatarul"
},
"addSuggestedTokens": {
"message": "Adăugați indicativele sugerate"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Adăugare simbol"
},
"addTokens": {
"message": "Adăugați token-uri"
},
"advanced": {
"message": "Avansate"
},
@ -276,7 +270,7 @@
"message": "Zecimalele trebuie să fie cel puțin 0, dar nu peste 36."
},
"defaultNetwork": {
"message": "Rețeaua implicită pentru tranzacțiile cu Ether este Main Net."
"message": "Rețeaua implicită pentru tranzacțiile cu Ether este Mainnet."
},
"delete": {
"message": "Șterge"
@ -533,7 +527,7 @@
"letsGoSetUp": {
"message": "Da, hai să configurăm!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Adăugați aceste indicative?"
},
"links": {
@ -882,9 +876,6 @@
"sendTokens": {
"message": "Trimiteți indicative"
},
"sentEther": {
"message": "trimiteți ether"
},
"separateEachWord": {
"message": "Despărțiți fiecare cuvânt cu un spațiu"
},

@ -79,9 +79,6 @@
"addNetwork": {
"message": "Добавить сеть"
},
"addRecipient": {
"message": "Добавить получателя"
},
"addSuggestedTokens": {
"message": "Добавить предложенные токены"
},
@ -94,9 +91,6 @@
"addToken": {
"message": "Добавить токен"
},
"addTokens": {
"message": "Добавить токены"
},
"advanced": {
"message": "Дополнительно"
},
@ -519,7 +513,7 @@
"message": "Расшифровать запрос"
},
"defaultNetwork": {
"message": "Сетью по умолчанию для транзакций Ether является Main Net."
"message": "Сетью по умолчанию для транзакций Ether является Mainnet."
},
"delete": {
"message": "Удалить"
@ -1028,7 +1022,7 @@
"letsGoSetUp": {
"message": "Да, давайте настроим!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Вы хотели бы добавить эти токены?"
},
"links": {
@ -1343,9 +1337,6 @@
"onlyAddTrustedNetworks": {
"message": "Вредоносный сетевой провайдер может дезинформировать о состоянии блокчейна и записывать ваши действия в сети. Добавляйте только те пользовательские сети, которым доверяете."
},
"onlyAvailableOnMainnet": {
"message": "Доступно только в mainnet"
},
"onlyConnectTrust": {
"message": "Подключайтесь только к сайтам, которым доверяете."
},
@ -1555,7 +1546,7 @@
"message": "Новый URL RPC"
},
"save": {
"message": "«»Сохранить"
"message": "Сохранить"
},
"saveAsCsvFile": {
"message": "Сохранить как файл CSV"
@ -1694,9 +1685,6 @@
"sendTokens": {
"message": "Отправить токены"
},
"sentEther": {
"message": "отправленный Ether"
},
"separateEachWord": {
"message": "Отделяйте каждое слово одним пробелом"
},
@ -1876,10 +1864,6 @@
"message": "Нет доступных токенов соответствующих $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "Проверка $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "Подтвердить с помощью аппаратного кошелька"
},
@ -1931,9 +1915,6 @@
"swapFetchingTokens": {
"message": "Получение токенов..."
},
"swapFinalizing": {
"message": "Завершение..."
},
"swapFromTo": {
"message": "Своп $1 на $2",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Pridať sieť"
},
"addRecipient": {
"message": "Pridať príjemcu"
},
"addSuggestedTokens": {
"message": "Pridať navrhované tokeny"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Přidat token"
},
"addTokens": {
"message": "Přidat tokeny"
},
"advanced": {
"message": "Rozšírené"
},
@ -270,7 +264,7 @@
"message": "Desetinných míst musí být od 0 do 36."
},
"defaultNetwork": {
"message": "Výchozí síť pro Etherové transakce je Main Net."
"message": "Výchozí síť pro Etherové transakce je Mainnet."
},
"delete": {
"message": "Odstrániť"
@ -527,7 +521,7 @@
"letsGoSetUp": {
"message": "Áno, poďme to nastaviť!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Chcete přidat tyto tokeny?"
},
"links": {
@ -858,9 +852,6 @@
"sendTokens": {
"message": "Odeslat tokeny"
},
"sentEther": {
"message": "poslaný ether"
},
"separateEachWord": {
"message": "Každé slovo oddeľte jednou medzerou"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Dodaj omrežje"
},
"addRecipient": {
"message": "Dodaj prejemnika"
},
"addSuggestedTokens": {
"message": "Dodaj priporočene žetone"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Dodaj žeton"
},
"addTokens": {
"message": "Dodaj žetone"
},
"advanced": {
"message": "Napredno"
},
@ -537,7 +531,7 @@
"letsGoSetUp": {
"message": "Lotimo se nastavitev!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Želite dodati te žetone?"
},
"links": {
@ -880,9 +874,6 @@
"sendTokens": {
"message": "Pošlji žetone"
},
"sentEther": {
"message": "poslani ether"
},
"separateEachWord": {
"message": "Vsako besedo ločite z enim presledkom"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Dodajte mrežu"
},
"addRecipient": {
"message": "Dodaj primaoca"
},
"addSuggestedTokens": {
"message": "Dodajte sugerisane tokene"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Dodaj token"
},
"addTokens": {
"message": "Dodaj tokene"
},
"advanced": {
"message": "Напредне опције"
},
@ -273,7 +267,7 @@
"message": "Decimalni broj mora biti najmanje 0, a ne veći od 36."
},
"defaultNetwork": {
"message": "Podrazumevana mreža za Ether transakcije je Main Net."
"message": "Podrazumevana mreža za Ether transakcije je Mainnet."
},
"delete": {
"message": "Избриши"
@ -540,7 +534,7 @@
"letsGoSetUp": {
"message": "Da, hajde da sve podesimo!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Želite li da dodate ove tokene?"
},
"links": {
@ -886,9 +880,6 @@
"sendTokens": {
"message": "Pošalji tokene"
},
"sentEther": {
"message": "ether je poslat"
},
"separateEachWord": {
"message": "Razdvojite svaku reč jednim mestom razmaka"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Lägg till nätverk"
},
"addRecipient": {
"message": "Lägg till mottagare"
},
"addSuggestedTokens": {
"message": "Lägg till föreslagna tokens"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Lägg till token"
},
"addTokens": {
"message": "Lägg till tokens"
},
"advanced": {
"message": "Avancerat"
},
@ -270,7 +264,7 @@
"message": "Decimalerna måste vara minst 0 och inte över 36."
},
"defaultNetwork": {
"message": "Standardnätverket för Ether-transaktioner är Main Net."
"message": "Standardnätverket för Ether-transaktioner är Mainnet."
},
"delete": {
"message": "Radera"
@ -533,7 +527,7 @@
"letsGoSetUp": {
"message": "Ja, kör igång!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Vill du lägga till dessa tokens?"
},
"links": {
@ -879,9 +873,6 @@
"sendTokens": {
"message": "Skicka tokens"
},
"sentEther": {
"message": "skickat ether"
},
"separateEachWord": {
"message": "Lägg in ett mellanslag mellan varje ord"
},

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Ongeza Mtandao"
},
"addRecipient": {
"message": "Ongeza Mpokeaji"
},
"addSuggestedTokens": {
"message": "Ongeza Vianzio Vilivyopendekezwa"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Ongeza Kianzio"
},
"addTokens": {
"message": "Ongeza Vianzio"
},
"advanced": {
"message": "Mipangilio ya kina"
},
@ -270,7 +264,7 @@
"message": "Desimali zinapaswa kuwa angalau 0, na si zaidi ya 36."
},
"defaultNetwork": {
"message": "Mtandao chaguomsingi wa miamala ya Ether ni Main Net."
"message": "Mtandao chaguomsingi wa miamala ya Ether ni Mainnet."
},
"delete": {
"message": "Futa"
@ -530,7 +524,7 @@
"letsGoSetUp": {
"message": "Ndiyo, hebu tuweke mipangilio!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Je, ungependa kuongeza vianzio hivi?"
},
"links": {
@ -873,9 +867,6 @@
"sendTokens": {
"message": "Tuma Vianzio"
},
"sentEther": {
"message": "ether iliyotumwa"
},
"separateEachWord": {
"message": "Tenganisha kila neno kwa nafasi moja"
},

@ -14,9 +14,6 @@
"addToken": {
"message": "டகன"
},
"addTokens": {
"message": "டகனகள"
},
"advanced": {
"message": "மபடடவ"
},
@ -251,7 +248,7 @@
"learnMore": {
"message": "ம அறிக"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "இநத டகனகளக விிகள?"
},
"links": {

@ -14,9 +14,6 @@
"addToken": {
"message": "เพมโทเคน"
},
"addTokens": {
"message": "เพมหลายโทเคน"
},
"amount": {
"message": "จำนวน"
},
@ -122,7 +119,7 @@
"message": "จำนวนตองมากกวา 0 และไมเกน 36"
},
"defaultNetwork": {
"message": "คาเรมตนของเครอขายสำหรบทำรายการธรกรรมอเธอรอ Main Net"
"message": "คาเรมตนของเครอขายสำหรบทำรายการธรกรรมอเธอรอ Mainnet"
},
"delete": {
"message": "ลบ"
@ -269,7 +266,7 @@
"learnMore": {
"message": "เรยนรเพมเตม"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "คณตองการเพมโทเคนเหลานหรอไม?"
},
"loading": {
@ -282,7 +279,7 @@
"message": "ออกจากระบบ"
},
"mainnet": {
"message": "เครอขาย Main Net"
"message": "เครอขาย Mainnet"
},
"message": {
"message": "ขอความ"

@ -52,9 +52,6 @@
"addNetwork": {
"message": "Magdagdag ng Network"
},
"addRecipient": {
"message": "Magdagdag ng Recipient"
},
"addSuggestedTokens": {
"message": "Magdagdag ng Mga Iminumungkahing Token"
},
@ -67,9 +64,6 @@
"addToken": {
"message": "Magdagdag ng Token"
},
"addTokens": {
"message": "Magdagdag ng Mga Token"
},
"advanced": {
"message": "Advanced"
},
@ -441,7 +435,7 @@
"message": "I-decrypt ang request"
},
"defaultNetwork": {
"message": "Ang default na network para sa mga transaksyon ng Ether ay ang Main Net."
"message": "Ang default na network para sa mga transaksyon ng Ether ay ang Mainnet."
},
"delete": {
"message": "I-delete"
@ -872,7 +866,7 @@
"letsGoSetUp": {
"message": "Sige, simulan na nating mag-set up!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Gusto mo bang idagdag ang mga token na ito?"
},
"links": {
@ -1087,9 +1081,6 @@
"message": "Isasara ng \"$1\" ang tab na ito at ididirekta ka pabalik sa $2",
"description": "Return the user to the site that initiated onboarding"
},
"onlyAvailableOnMainnet": {
"message": "Available lang sa mainnet"
},
"onlyConnectTrust": {
"message": "Kumonekta lang sa mga site na pinagkakatiwalaan mo."
},
@ -1365,9 +1356,6 @@
"sendTokens": {
"message": "Magpadala ng Mga Token"
},
"sentEther": {
"message": "nagpadala ng ether"
},
"separateEachWord": {
"message": "Paghiwa-hiwalayin ang bawat salita gamit ang espasyo"
},
@ -1516,10 +1504,6 @@
"message": "Walang available na token na tumutugma sa $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "Sinusuri ang $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapCustom": {
"message": "custom"
},
@ -1558,9 +1542,6 @@
"swapFetchingTokens": {
"message": "Kinukuha ang mga token..."
},
"swapFinalizing": {
"message": "Isinasapinal..."
},
"swapLowSlippageError": {
"message": "Maaaring hindi magtagumpay ang transaksyon, masyadong mababa ang max na slippage."
},

@ -11,9 +11,6 @@
"addToken": {
"message": "Jeton ekle"
},
"addTokens": {
"message": "Jetonlar ekle"
},
"amount": {
"message": "Tutar"
},
@ -104,7 +101,7 @@
"message": "Ondalıklar en azından 0 olmalı ve 36'dan büyük olmamalı."
},
"defaultNetwork": {
"message": "Ether işlemleri için varsayılan ağ Main Net."
"message": "Ether işlemleri için varsayılan ağ Mainnet."
},
"depositEther": {
"message": "Ether yatır"
@ -221,7 +218,7 @@
"learnMore": {
"message": "Daha fazla bilgi."
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Bu jetonlara adres eklemek ister misiniz?"
},
"links": {
@ -322,7 +319,7 @@
"message": "Gelecekte Bu jetonu hesap seçenekleri menüsünde “Jeton ekle”'ye giderek geri ekleyebilirsiniz."
},
"reject": {
"message": "Reddetmek"
"message": "Reddet"
},
"rejected": {
"message": "Rededildi"

@ -38,9 +38,6 @@
"addNetwork": {
"message": "Додати мережу"
},
"addRecipient": {
"message": "Додати отримувача"
},
"addSuggestedTokens": {
"message": "Додати рекомендовані токени"
},
@ -53,9 +50,6 @@
"addToken": {
"message": "Додати токен"
},
"addTokens": {
"message": "Додати токени"
},
"advanced": {
"message": "Розширені"
},
@ -276,7 +270,7 @@
"message": "Кількість розрядів після коми: від 0 до 36."
},
"defaultNetwork": {
"message": "Мережа для транзакцій з Ether за замовчуванням - Main Net."
"message": "Мережа для транзакцій з Ether за замовчуванням - Mainnet."
},
"delete": {
"message": "Видалити"
@ -543,7 +537,7 @@
"letsGoSetUp": {
"message": "Так, давайте налаштуємо!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Ви б хотіли додати ці токени?"
},
"links": {
@ -895,9 +889,6 @@
"sendTokens": {
"message": "Надіслати токени"
},
"sentEther": {
"message": "надісланий ефір"
},
"separateEachWord": {
"message": "Відділіть кожне слово одним пробілом"
},

@ -79,9 +79,6 @@
"addNetwork": {
"message": "Thêm mạng"
},
"addRecipient": {
"message": "Thêm người nhận"
},
"addSuggestedTokens": {
"message": "Thêm token được đề xuất"
},
@ -94,9 +91,6 @@
"addToken": {
"message": "Thêm token"
},
"addTokens": {
"message": "Thêm token"
},
"advanced": {
"message": "Nâng cao"
},
@ -1028,7 +1022,7 @@
"letsGoSetUp": {
"message": "Có, hãy thiết lập!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "Bạn có muốn thêm những token này không?"
},
"links": {
@ -1343,9 +1337,6 @@
"onlyAddTrustedNetworks": {
"message": "Một nhà cung cấp mạng độc hại có thể nói dối về trạng thái của chuỗi khối và ghi lại hoạt động của bạn trên mạng. Chỉ thêm các mạng tùy chỉnh mà bạn tin tưởng."
},
"onlyAvailableOnMainnet": {
"message": "Chỉ có trên mạng chính thức"
},
"onlyConnectTrust": {
"message": "Chỉ kết nối với các trang web mà bạn tin tưởng."
},
@ -1694,9 +1685,6 @@
"sendTokens": {
"message": "Gửi token"
},
"sentEther": {
"message": "đã gửi ether"
},
"separateEachWord": {
"message": "Phân tách mỗi từ bằng một dấu cách"
},
@ -1876,10 +1864,6 @@
"message": "Không có token nào khớp với $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "Đang kiểm tra $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapConfirmWithHwWallet": {
"message": "Xác nhận ví cứng của bạn"
},
@ -1931,9 +1915,6 @@
"swapFetchingTokens": {
"message": "Đang tìm nạp token..."
},
"swapFinalizing": {
"message": "Đang hoàn tất..."
},
"swapFromTo": {
"message": "Giao dịch hoán đổi $1 sang $2",
"description": "Tells a user that they need to confirm on their hardware wallet a swap of 2 tokens. $1 is a source token and $2 is a destination token"

@ -52,9 +52,6 @@
"addNetwork": {
"message": "添加网络"
},
"addRecipient": {
"message": "添加接收方"
},
"addSuggestedTokens": {
"message": "添加推荐代币"
},
@ -67,9 +64,6 @@
"addToken": {
"message": "添加代币"
},
"addTokens": {
"message": "添加代币"
},
"advanced": {
"message": "高级"
},
@ -875,7 +869,7 @@
"letsGoSetUp": {
"message": "第一次,立即开始设置!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "您想添加这些代币吗?"
},
"links": {
@ -1090,9 +1084,6 @@
"message": "“$1”会关闭此标签,直接回到 $2",
"description": "Return the user to the site that initiated onboarding"
},
"onlyAvailableOnMainnet": {
"message": "仅在主网(mainnet)上提供"
},
"onlyConnectTrust": {
"message": "只连接您信任的网站。"
},
@ -1368,9 +1359,6 @@
"sendTokens": {
"message": "发送代币"
},
"sentEther": {
"message": "发送 Ether"
},
"separateEachWord": {
"message": "用空格分隔每个单词"
},
@ -1522,10 +1510,6 @@
"message": "没有匹配的代币符合 $1",
"description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text"
},
"swapCheckingQuote": {
"message": "正在检查 $1",
"description": "Shown to the user during quote loading. $1 is the name of an aggregator. The message indicates that metamask is currently checking if that aggregator has a trade/quote for their requested swap."
},
"swapCustom": {
"message": "自定义"
},
@ -1564,9 +1548,6 @@
"swapFetchingTokens": {
"message": "获取代币中……"
},
"swapFinalizing": {
"message": "确定中……"
},
"swapLowSlippageError": {
"message": "交易可能失败,最大滑点过低。"
},

@ -41,9 +41,6 @@
"addNetwork": {
"message": "新增網路"
},
"addRecipient": {
"message": "新增接收人"
},
"addSuggestedTokens": {
"message": "加入建議的代幣"
},
@ -56,9 +53,6 @@
"addToken": {
"message": "加入代幣"
},
"addTokens": {
"message": "加入代幣"
},
"advanced": {
"message": "進階"
},
@ -552,7 +546,7 @@
"letsGoSetUp": {
"message": "好,我們開始吧!"
},
"likeToAddTokens": {
"likeToImportTokens": {
"message": "確定要加入代幣?"
},
"links": {
@ -883,9 +877,6 @@
"sendTokens": {
"message": "發送代幣"
},
"sentEther": {
"message": "發送以太幣"
},
"separateEachWord": {
"message": "單詞之間請以空白間隔"
},

@ -0,0 +1,337 @@
{
"chunks": [
{
"color": [0, 0, 0],
"faces": [
[11, 12, 13],
[36, 15, 37],
[37, 38, 36],
[31, 39, 22],
[22, 21, 31],
[31, 15, 36],
[36, 39, 31],
[64, 65, 66],
[75, 69, 26],
[26, 80, 75],
[75, 80, 38],
[38, 37, 75],
[38, 80, 39],
[39, 36, 38],
[39, 80, 26],
[26, 22, 39]
]
},
{
"color": [236, 229, 220],
"faces": [
[19, 20, 21],
[21, 22, 19],
[20, 19, 23],
[23, 24, 20],
[23, 25, 24],
[19, 22, 26],
[26, 27, 19],
[23, 28, 29],
[23, 29, 30],
[25, 23, 30],
[21, 20, 24],
[24, 31, 21],
[24, 25, 30],
[29, 51, 52],
[52, 30, 29],
[27, 26, 69],
[69, 70, 27],
[70, 71, 72],
[72, 27, 70],
[72, 71, 73],
[51, 74, 72],
[52, 51, 72],
[73, 52, 72],
[69, 71, 70],
[71, 69, 75],
[52, 73, 71],
[19, 27, 74],
[74, 28, 19],
[51, 29, 28],
[28, 74, 51],
[74, 27, 72],
[28, 23, 19]
]
},
{
"color": [119, 228, 171],
"faces": [
[5, 4, 35],
[57, 59, 79]
]
},
{
"color": [80, 157, 116],
"faces": [
[4, 5, 2],
[2, 5, 6],
[57, 56, 55],
[58, 59, 55],
[2, 1, 4],
[55, 59, 57]
]
},
{
"color": [67, 127, 95],
"faces": [
[0, 1, 2],
[2, 3, 0],
[6, 3, 2],
[7, 8, 9],
[10, 3, 6],
[10, 50, 7],
[7, 3, 10],
[7, 9, 3],
[49, 0, 9],
[3, 9, 0],
[53, 54, 55],
[55, 56, 53],
[55, 54, 58],
[60, 61, 62],
[63, 58, 54],
[63, 60, 89],
[60, 63, 54],
[60, 54, 61],
[88, 61, 53],
[54, 53, 61]
]
},
{
"color": [119, 228, 207],
"faces": [
[59, 5, 35],
[35, 79, 59]
]
},
{
"color": [163, 230, 235],
"faces": [
[14, 15, 11],
[11, 16, 14],
[16, 13, 12],
[17, 33, 10],
[17, 18, 34],
[34, 33, 17],
[11, 15, 31],
[18, 12, 11],
[41, 64, 37],
[64, 41, 40],
[66, 65, 40],
[67, 63, 77],
[67, 77, 76],
[76, 68, 67],
[75, 37, 64],
[68, 64, 66]
]
},
{
"color": [204, 237, 236],
"faces": [
[10, 6, 17],
[31, 18, 11],
[14, 16, 40],
[40, 41, 14],
[63, 67, 58],
[64, 68, 75],
[14, 41, 37],
[37, 15, 14],
[5, 59, 40],
[40, 16, 5]
]
},
{
"color": [207, 248, 247],
"faces": [
[6, 5, 16],
[16, 17, 6],
[12, 17, 16],
[58, 67, 40],
[40, 59, 58],
[40, 67, 66]
]
},
{
"color": [127, 185, 228],
"faces": [
[33, 34, 24],
[71, 76, 77]
]
},
{
"color": [119, 200, 228],
"faces": [
[31, 24, 18],
[24, 34, 18],
[35, 4, 42],
[4, 1, 42],
[42, 43, 44],
[44, 35, 42],
[45, 43, 42],
[42, 10, 45],
[30, 32, 24],
[30, 33, 32],
[33, 30, 10],
[44, 43, 46],
[43, 45, 47],
[47, 46, 43],
[48, 47, 45],
[45, 30, 48],
[30, 45, 10],
[49, 42, 0],
[8, 7, 42],
[50, 42, 7],
[50, 10, 42],
[1, 0, 42],
[42, 9, 8],
[42, 49, 9],
[75, 68, 71],
[71, 68, 76],
[79, 81, 57],
[57, 81, 56],
[82, 79, 35],
[35, 44, 82],
[81, 79, 82],
[82, 83, 81],
[84, 63, 81],
[81, 83, 84],
[44, 46, 85],
[85, 82, 44],
[71, 78, 52],
[52, 78, 77],
[77, 63, 52],
[82, 85, 83],
[83, 85, 86],
[86, 84, 83],
[87, 52, 84],
[84, 86, 87],
[52, 63, 84],
[88, 53, 81],
[62, 81, 60],
[89, 60, 81],
[89, 81, 63],
[56, 81, 53],
[81, 62, 61],
[81, 61, 88],
[48, 87, 86],
[86, 47, 48],
[47, 86, 85],
[85, 46, 47],
[48, 30, 52],
[52, 87, 48]
]
},
{
"color": [95, 167, 211],
"faces": [
[24, 32, 33],
[77, 78, 71]
]
},
{
"color": [119, 222, 228],
"faces": [
[17, 12, 18],
[13, 16, 11],
[67, 68, 66],
[65, 64, 40]
]
}
],
"positions": [
[111.024597, 52.604599, 46.225899],
[114.025002, 87.673302, 58.9818],
[66.192001, 80.898003, 55.394299],
[72.113297, 35.491798, 30.871401],
[97.804497, 116.560997, 73.978798],
[16.7623, 58.010899, 58.078201],
[52.608898, 30.3641, 42.556099],
[106.881401, 31.945499, 46.9133],
[113.484596, 38.6049, 49.121498],
[108.6633, 43.2332, 46.315399],
[101.216599, 15.9822, 46.308201],
[16.6605, -16.2883, 93.618698],
[40.775002, -10.2288, 85.276398],
[23.926901, -2.5103, 86.736504],
[11.1691, -7.0037, 99.377602],
[9.5692, -34.393902, 141.671997],
[12.596, 7.1655, 88.740997],
[61.180901, 8.8142, 76.996803],
[39.719501, -28.927099, 88.963799],
[13.7962, -68.575699, 132.057007],
[15.2674, -62.32, 129.688004],
[14.8446, -52.6096, 140.113007],
[12.8917, -49.771599, 144.740997],
[35.604198, -71.758003, 81.063904],
[47.462502, -68.606102, 63.369701],
[38.2486, -64.730202, 38.909901],
[-12.8917, -49.771599, 144.740997],
[-13.7962, -68.575699, 132.057007],
[17.802099, -71.758003, 81.063904],
[19.1243, -69.0168, 49.420101],
[38.2486, -66.275597, 17.776199],
[12.8928, -36.703499, 141.671997],
[109.283997, -93.589897, 27.824301],
[122.117996, -36.8894, 35.025002],
[67.7668, -30.197001, 78.417801],
[33.180698, 101.851997, 25.3186],
[9.4063, -35.589802, 150.722],
[-9.5692, -34.393902, 141.671997],
[-9.4063, -35.589802, 150.722],
[11.4565, -37.899399, 150.722],
[-12.596, 7.1655, 88.740997],
[-11.1691, -7.0037, 99.377602],
[70.236504, 62.836201, -3.9475],
[47.263401, 54.293999, -27.414801],
[28.7302, 91.731102, -24.972601],
[69.167603, 6.5862, -12.7757],
[28.7302, 49.1003, -48.3596],
[31.903, 5.692, -47.821999],
[35.075802, -34.432899, -16.280899],
[115.284103, 48.681499, 48.684101],
[110.842796, 28.4821, 49.176201],
[-19.1243, -69.0168, 49.420101],
[-38.2486, -66.275597, 17.776199],
[-111.024597, 52.604599, 46.225899],
[-72.113297, 35.491798, 30.871401],
[-66.192001, 80.898003, 55.394299],
[-114.025002, 87.673302, 58.9818],
[-97.804497, 116.560997, 73.978798],
[-52.608898, 30.3641, 42.556099],
[-16.7623, 58.010899, 58.078201],
[-106.881401, 31.945499, 46.9133],
[-108.6633, 43.2332, 46.315399],
[-113.484596, 38.6049, 49.121498],
[-101.216599, 15.9822, 46.308201],
[-16.6605, -16.2883, 93.618698],
[-23.926901, -2.5103, 86.736504],
[-40.775002, -10.2288, 85.276398],
[-61.180901, 8.8142, 76.996803],
[-39.719501, -28.927099, 88.963799],
[-14.8446, -52.6096, 140.113007],
[-15.2674, -62.32, 129.688004],
[-47.462502, -68.606102, 63.369701],
[-35.604198, -71.758003, 81.063904],
[-38.2486, -64.730202, 38.909901],
[-17.802099, -71.758003, 81.063904],
[-12.8928, -36.703499, 141.671997],
[-67.7668, -30.197001, 78.417801],
[-122.117996, -36.8894, 35.025002],
[-109.283997, -93.589897, 27.824301],
[-33.180698, 101.851997, 25.3186],
[-11.4565, -37.899399, 150.722],
[-70.236504, 62.836201, -3.9475],
[-28.7302, 91.731102, -24.972601],
[-47.263401, 54.293999, -27.414801],
[-69.167603, 6.5862, -12.7757],
[-28.7302, 49.1003, -48.3596],
[-31.903, 5.692, -47.821999],
[-35.075802, -34.432899, -16.280899],
[-115.284103, 48.681499, 48.684101],
[-110.842796, 28.4821, 49.176201]
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -0,0 +1,130 @@
<svg width="35" height="33" viewBox="0 0 35 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M19.5938 17.6064L20.1705 9.73742L22.5185 4.13232H12.4812L14.8292 9.73742L15.4059 17.6064L15.5844 20.0884L15.5981 26.1981H19.4016L19.4153 20.0884L19.5938 17.6064Z" fill="url(#paint0_linear)"/>
<path d="M32.3226 16.0925L25.1413 14.006L27.3108 17.2654L24.0703 23.5387L28.3543 23.4842H34.7255L32.3226 16.0925Z" fill="url(#paint1_linear)"/>
<path d="M9.85875 14.006L2.6775 16.0925L0.28833 23.4842H6.65946L10.9298 23.5387L7.68927 17.2654L9.85875 14.006Z" fill="url(#paint2_linear)"/>
<path d="M20.3078 21.5476L19.4016 26.198L20.0607 26.6481L24.0701 23.5387L24.1937 20.4156L20.3078 21.5476Z" fill="url(#paint3_linear)"/>
<path d="M10.8198 20.4156L10.9297 23.5387L14.9391 26.6481L15.5982 26.198L14.6919 21.5476L10.8198 20.4156Z" fill="url(#paint4_linear)"/>
<path d="M33.8466 10.7329L35 5.16869L33.2699 0L20.0608 9.73731L24.9902 14.1286L32.3225 16.0925L33.9015 14.2514L33.215 13.7604L34.3134 12.7649L33.4759 12.1103L34.5743 11.2784L33.8466 10.7329Z" fill="url(#paint5_linear)"/>
<path d="M0 5.16869L1.16712 10.7329L0.425657 11.2784L1.52413 12.1103L0.686544 12.7649L1.78501 13.7604L1.09847 14.2514L2.67752 16.0925L10.0235 14.1286L14.9392 9.73731L1.73009 0L0 5.16869Z" fill="url(#paint6_linear)"/>
<path d="M7.68921 17.2653L10.8198 20.4156L10.9297 23.5386L7.68921 17.2653Z" fill="url(#paint7_linear)"/>
<path d="M27.3105 17.2653L24.0701 23.5386L24.1936 20.4156L27.3105 17.2653Z" fill="url(#paint8_linear)"/>
<path d="M24.7156 28.8983L20.0608 26.6481L20.4315 29.662L20.3903 30.9303L24.7156 28.8983Z" fill="#D7C1B3"/>
<path d="M10.2844 28.8983L14.6096 30.9303L14.5822 29.662L14.9392 26.6481L10.2844 28.8983Z" fill="#D7C1B3"/>
<path d="M28.3543 23.484L24.7156 28.8982L32.501 31.0256L34.7254 23.484H28.3543Z" fill="url(#paint9_linear)"/>
<path d="M0.28833 23.484L2.499 31.0256L10.2844 28.8982L6.65946 23.484H0.28833Z" fill="url(#paint10_linear)"/>
<path d="M1.72998 0L14.9391 9.73731L12.8657 4.13222L1.72998 0Z" fill="url(#paint11_linear)"/>
<path d="M22.1339 4.13222L20.0605 9.73731L33.2697 0L22.1339 4.13222Z" fill="url(#paint12_linear)"/>
<path d="M9.85869 14.0059L7.68921 17.2653L15.406 17.6063L14.9391 9.7373L9.85869 14.0059Z" fill="url(#paint13_linear)"/>
<path d="M25.141 14.0059L20.0606 9.7373L19.5938 17.6063L27.3105 17.2653L25.141 14.0059Z" fill="url(#paint14_linear)"/>
<path d="M10.2844 28.8983L14.9392 26.6481L10.9298 23.5387L10.2844 28.8983Z" fill="url(#paint15_linear)"/>
<path d="M20.0608 26.6481L24.7156 28.8983L24.0702 23.5387L20.0608 26.6481Z" fill="url(#paint16_linear)"/>
<path d="M10.2844 28.8982L10.9297 23.5386L6.65942 23.484L10.2844 28.8982Z" fill="url(#paint17_linear)"/>
<path d="M24.0701 23.5386L24.7154 28.8982L28.3541 23.484L24.0701 23.5386Z" fill="url(#paint18_linear)"/>
<path d="M27.3107 17.2653L19.594 17.6062L20.308 21.5475L21.4477 19.1745L24.1938 20.4156L27.3107 17.2653Z" fill="url(#paint19_linear)"/>
<path d="M10.8198 20.4156L13.5523 19.1745L14.692 21.5475L15.406 17.6062L7.68921 17.2653L10.8198 20.4156Z" fill="url(#paint20_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.4156 20.0884L20.3081 21.5476L19.5941 17.6063L19.4156 20.0884ZM20.3081 21.5476L19.4156 20.0884L19.4019 26.1981L20.3081 21.5476Z" fill="url(#paint21_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.4061 17.6063L14.6921 21.5476V21.5476L15.5984 26.1981L15.5846 20.0884L14.6921 21.5476L15.5846 20.0884L15.4061 17.6063Z" fill="url(#paint22_linear)"/>
<path d="M20.4151 30.914L20.4315 29.662L20.0883 29.362H14.9117L14.5822 29.662L14.6096 30.9303L10.2844 28.8983L11.7948 30.1257L14.8705 32.2396H20.1295L23.2052 30.1257L24.7156 28.8983L20.4151 30.914Z" fill="#C0AD9E"/>
<path d="M20.0606 26.648L19.4016 26.198H15.5981L14.939 26.648L14.582 29.662L14.9116 29.3619H20.0881L20.4314 29.662L20.0606 26.648Z" fill="#161616" stroke="#161616" stroke-width="0.142167" stroke-miterlimit="10" stroke-linejoin="round"/>
<path d="M21.4475 19.1746L20.3079 21.5475L24.1937 20.4156L21.4475 19.1746Z" fill="#161616"/>
<path d="M13.5525 19.1746L14.6922 21.5475L10.8201 20.4156L13.5525 19.1746Z" fill="#161616"/>
</g>
<defs>
<linearGradient id="paint0_linear" x1="17.4998" y1="4.13232" x2="17.4998" y2="26.1981" gradientUnits="userSpaceOnUse">
<stop stop-color="#21FF47"/>
<stop offset="1" stop-color="#BCD8F0"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="29.3979" y1="14.006" x2="29.3979" y2="23.5387" gradientUnits="userSpaceOnUse">
<stop stop-color="#1CAD68"/>
<stop offset="1" stop-color="#77BDD4"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="5.60904" y1="14.006" x2="5.60904" y2="23.5387" gradientUnits="userSpaceOnUse">
<stop stop-color="#1CAD68"/>
<stop offset="1" stop-color="#77BDD4"/>
</linearGradient>
<linearGradient id="paint3_linear" x1="21.7977" y1="20.4156" x2="21.7977" y2="26.6481" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BCBC8"/>
<stop offset="1" stop-color="#87B9E6"/>
</linearGradient>
<linearGradient id="paint4_linear" x1="13.209" y1="20.4156" x2="13.209" y2="26.6481" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BCBC8"/>
<stop offset="1" stop-color="#87B9E6"/>
</linearGradient>
<linearGradient id="paint5_linear" x1="27.5304" y1="0" x2="27.5304" y2="16.0925" gradientUnits="userSpaceOnUse">
<stop stop-color="#007715"/>
<stop offset="1" stop-color="#0A3424"/>
</linearGradient>
<linearGradient id="paint6_linear" x1="7.4696" y1="0" x2="7.4696" y2="16.0925" gradientUnits="userSpaceOnUse">
<stop stop-color="#007715"/>
<stop offset="1" stop-color="#0A3424"/>
</linearGradient>
<linearGradient id="paint7_linear" x1="9.30945" y1="17.2653" x2="9.30945" y2="23.5386" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<linearGradient id="paint8_linear" x1="25.6903" y1="17.2653" x2="25.6903" y2="23.5386" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<linearGradient id="paint9_linear" x1="29.7205" y1="23.484" x2="29.7205" y2="31.0256" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint10_linear" x1="5.28637" y1="23.484" x2="5.28637" y2="31.0256" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint11_linear" x1="8.33453" y1="0" x2="8.33453" y2="9.73731" gradientUnits="userSpaceOnUse">
<stop stop-color="#01EA28"/>
<stop offset="1" stop-color="#10D24F"/>
</linearGradient>
<linearGradient id="paint12_linear" x1="26.6651" y1="0" x2="26.6651" y2="9.73731" gradientUnits="userSpaceOnUse">
<stop stop-color="#01EA28"/>
<stop offset="1" stop-color="#10D24F"/>
</linearGradient>
<linearGradient id="paint13_linear" x1="11.5476" y1="9.7373" x2="11.5476" y2="17.6063" gradientUnits="userSpaceOnUse">
<stop stop-color="#12DB56"/>
<stop offset="1" stop-color="#4CC9A3"/>
</linearGradient>
<linearGradient id="paint14_linear" x1="23.4521" y1="9.7373" x2="23.4521" y2="17.6063" gradientUnits="userSpaceOnUse">
<stop stop-color="#12DB56"/>
<stop offset="1" stop-color="#4CC9A3"/>
</linearGradient>
<linearGradient id="paint15_linear" x1="12.6118" y1="23.5387" x2="12.6118" y2="28.8983" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint16_linear" x1="22.3882" y1="23.5387" x2="22.3882" y2="28.8983" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint17_linear" x1="8.79458" y1="23.484" x2="8.79458" y2="28.8982" gradientUnits="userSpaceOnUse">
<stop stop-color="#32809D"/>
<stop offset="1" stop-color="#477DD5"/>
</linearGradient>
<linearGradient id="paint18_linear" x1="26.2121" y1="23.484" x2="26.2121" y2="28.8982" gradientUnits="userSpaceOnUse">
<stop stop-color="#32809D"/>
<stop offset="1" stop-color="#477DD5"/>
</linearGradient>
<linearGradient id="paint19_linear" x1="23.4524" y1="17.2653" x2="23.4524" y2="21.5475" gradientUnits="userSpaceOnUse">
<stop stop-color="#239777"/>
<stop offset="1" stop-color="#2C8A8D"/>
</linearGradient>
<linearGradient id="paint20_linear" x1="11.5476" y1="17.2653" x2="11.5476" y2="21.5475" gradientUnits="userSpaceOnUse">
<stop stop-color="#239777"/>
<stop offset="1" stop-color="#2C8A8D"/>
</linearGradient>
<linearGradient id="paint21_linear" x1="19.855" y1="17.6063" x2="19.855" y2="26.1981" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<linearGradient id="paint22_linear" x1="15.1453" y1="17.6063" x2="15.1453" y2="26.1981" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<clipPath id="clip0">
<rect width="35" height="33" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

@ -0,0 +1,148 @@
<svg width="1533" height="242" viewBox="0 0 1533 242" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M1157.95 121.694C1151.15 117.195 1143.65 113.996 1136.55 109.997C1131.95 107.398 1127.05 105.098 1123.05 101.799C1116.24 96.2 1117.64 85.2024 1124.75 80.4035C1134.95 73.605 1151.85 77.4042 1153.65 91.3011C1153.65 91.601 1153.95 91.801 1154.25 91.801H1169.66C1170.06 91.801 1170.36 91.501 1170.26 91.1011C1169.46 81.5033 1165.75 73.505 1158.95 68.4062C1152.45 63.5073 1145.05 60.9078 1137.15 60.9078C1096.44 60.9078 1092.74 103.998 1114.64 117.595C1117.14 119.195 1138.65 129.992 1146.25 134.691C1153.85 139.39 1156.25 147.988 1152.95 154.787C1149.95 160.986 1142.15 165.285 1134.35 164.785C1125.85 164.285 1119.24 159.686 1116.94 152.487C1116.54 151.188 1116.34 148.688 1116.34 147.589C1116.34 147.289 1116.04 146.989 1115.74 146.989H1099.04C1098.74 146.989 1098.44 147.289 1098.44 147.589C1098.44 159.686 1101.44 166.384 1109.64 172.483C1117.34 178.282 1125.75 180.681 1134.45 180.681C1157.25 180.681 1169.06 167.784 1171.46 154.387C1173.56 141.29 1169.66 129.493 1157.95 121.694V121.694Z" fill="#24292E"/>
<path d="M432.694 63.1091H425.293H417.191C416.891 63.1091 416.691 63.3091 416.591 63.509L402.888 108.698C402.688 109.298 401.888 109.298 401.688 108.698L387.985 63.509C387.885 63.2091 387.685 63.1091 387.384 63.1091H379.283H371.881H361.879C361.579 63.1091 361.279 63.4091 361.279 63.709V179.082C361.279 179.382 361.579 179.682 361.879 179.682H378.583C378.883 179.682 379.183 179.382 379.183 179.082V91.4025C379.183 90.7027 380.183 90.6027 380.383 91.2025L394.186 136.692L395.186 139.891C395.286 140.191 395.486 140.291 395.786 140.291H408.589C408.889 140.291 409.089 140.091 409.189 139.891L410.189 136.692L423.992 91.2025C424.192 90.5027 425.193 90.7027 425.193 91.4025V179.082C425.193 179.382 425.493 179.682 425.793 179.682H442.496C442.796 179.682 443.097 179.382 443.097 179.082V63.709C443.097 63.4091 442.796 63.1091 442.496 63.1091H432.694Z" fill="#24292E"/>
<path d="M902.197 63.1091C901.897 63.1091 901.697 63.3091 901.597 63.509L887.894 108.698C887.694 109.298 886.894 109.298 886.694 108.698L872.991 63.509C872.891 63.2091 872.691 63.1091 872.39 63.1091H846.985C846.685 63.1091 846.385 63.4091 846.385 63.709V179.082C846.385 179.382 846.685 179.682 846.985 179.682H863.689C863.989 179.682 864.289 179.382 864.289 179.082V91.4025C864.289 90.7027 865.289 90.6027 865.489 91.2025L879.292 136.692L880.292 139.891C880.392 140.191 880.592 140.291 880.892 140.291H893.695C893.995 140.291 894.195 140.091 894.295 139.891L895.295 136.692L909.098 91.2025C909.299 90.5027 910.299 90.7027 910.299 91.4025V179.082C910.299 179.382 910.599 179.682 910.899 179.682H927.603C927.903 179.682 928.203 179.382 928.203 179.082V63.709C928.203 63.4091 927.903 63.1091 927.603 63.1091H902.197Z" fill="#24292E"/>
<path d="M686.749 63.1091H655.642H638.938H607.832C607.532 63.1091 607.231 63.4091 607.231 63.709V78.1056C607.231 78.4055 607.532 78.7055 607.832 78.7055H638.338V179.082C638.338 179.382 638.638 179.682 638.938 179.682H655.642C655.942 179.682 656.242 179.382 656.242 179.082V78.7055H686.749C687.049 78.7055 687.349 78.4055 687.349 78.1056V63.709C687.349 63.4091 687.149 63.1091 686.749 63.1091V63.1091Z" fill="#24292E"/>
<path d="M785.272 179.681H800.475C800.875 179.681 801.175 179.281 801.075 178.881L769.668 63.1082C769.568 62.8082 769.368 62.7083 769.068 62.7083H763.267H753.065H747.264C746.964 62.7083 746.763 62.9082 746.663 63.1082L715.257 178.881C715.157 179.281 715.457 179.681 715.857 179.681H731.06C731.36 179.681 731.56 179.481 731.66 179.281L740.762 145.589C740.862 145.289 741.062 145.189 741.362 145.189H774.97C775.27 145.189 775.47 145.389 775.57 145.589L784.672 179.281C784.772 179.481 785.072 179.681 785.272 179.681V179.681ZM745.363 128.693L757.566 83.6034C757.766 83.0035 758.566 83.0035 758.766 83.6034L770.969 128.693C771.069 129.093 770.769 129.493 770.369 129.493H745.963C745.563 129.493 745.263 129.093 745.363 128.693V128.693Z" fill="#24292E"/>
<path d="M1044.53 179.681H1059.73C1060.13 179.681 1060.43 179.281 1060.33 178.881L1028.93 63.1082C1028.83 62.8082 1028.63 62.7083 1028.33 62.7083H1022.52H1012.32H1006.52C1006.22 62.7083 1006.02 62.9082 1005.92 63.1082L974.514 178.881C974.414 179.281 974.714 179.681 975.114 179.681H990.317C990.618 179.681 990.818 179.481 990.918 179.281L1000.02 145.589C1000.12 145.289 1000.32 145.189 1000.62 145.189H1034.23C1034.53 145.189 1034.73 145.389 1034.83 145.589L1043.93 179.281C1044.03 179.481 1044.23 179.681 1044.53 179.681V179.681ZM1004.62 128.693L1016.82 83.6034C1017.02 83.0035 1017.82 83.0035 1018.02 83.6034L1030.23 128.693C1030.33 129.093 1030.03 129.493 1029.63 129.493H1005.22C1004.82 129.493 1004.52 129.093 1004.62 128.693V128.693Z" fill="#24292E"/>
<path d="M510.909 162.584V126.793C510.909 126.493 511.209 126.193 511.509 126.193H556.019C556.319 126.193 556.619 125.893 556.619 125.593V111.196C556.619 110.896 556.319 110.596 556.019 110.596H511.509C511.209 110.596 510.909 110.296 510.909 109.997V79.4037C510.909 79.1038 511.209 78.8039 511.509 78.8039H562.121C562.421 78.8039 562.721 78.5039 562.721 78.204V63.8074C562.721 63.5074 562.421 63.2075 562.121 63.2075H510.909H493.606C493.305 63.2075 493.005 63.5074 493.005 63.8074V78.8039V110.696V126.293V163.284V179.08C493.005 179.38 493.305 179.68 493.606 179.68H510.909H564.221C564.521 179.68 564.821 179.38 564.821 179.08V163.884C564.821 163.584 564.521 163.284 564.221 163.284H511.409C511.109 163.184 510.909 162.984 510.909 162.584Z" fill="#24292E"/>
<path d="M1310.58 178.681L1252.77 118.995C1252.57 118.795 1252.57 118.395 1252.77 118.195L1304.78 64.2074C1305.18 63.8075 1304.88 63.2076 1304.38 63.2076H1283.08C1282.88 63.2076 1282.78 63.3076 1282.68 63.4076L1238.57 109.197C1238.17 109.597 1237.57 109.297 1237.57 108.797V63.8075C1237.57 63.5076 1237.27 63.2076 1236.97 63.2076H1220.26C1219.96 63.2076 1219.66 63.5076 1219.66 63.8075V179.181C1219.66 179.48 1219.96 179.78 1220.26 179.78H1236.97C1237.27 179.78 1237.57 179.48 1237.57 179.181V128.392C1237.57 127.893 1238.27 127.593 1238.57 127.993L1288.58 179.58C1288.68 179.68 1288.88 179.78 1288.98 179.78H1310.28C1310.68 179.68 1310.98 178.981 1310.58 178.681V178.681Z" fill="#24292E"/>
<path d="M1512.38 110.091H1359.98C1348.59 110.091 1339.36 100.86 1339.36 89.4845V44.6061C1339.36 33.231 1348.59 24 1359.98 24H1512.38C1523.76 24 1533 33.231 1533 44.6061V89.4845C1533 100.876 1523.76 110.091 1512.38 110.091Z" fill="#F66A0A"/>
<path d="M1371.47 48.027H1386.48C1388.08 48.027 1389.62 48.3377 1391.06 48.9592C1392.5 49.5807 1393.76 50.4149 1394.86 51.478C1395.94 52.5411 1396.79 53.8004 1397.41 55.2397C1398.04 56.679 1398.35 58.2164 1398.35 59.8683C1398.35 61.2912 1398.09 62.567 1397.56 63.7118C1397.04 64.8567 1396.35 65.8544 1395.48 66.7213C1397.17 67.5881 1398.53 68.8311 1399.59 70.483C1400.64 72.1349 1401.17 74.0158 1401.17 76.1583C1401.17 77.8102 1400.85 79.3313 1400.23 80.7542C1399.61 82.1771 1398.76 83.4202 1397.68 84.4833C1396.6 85.5464 1395.3 86.3805 1393.83 86.9856C1392.35 87.5908 1390.75 87.8852 1389.03 87.8852H1371.49V48.027H1371.47ZM1385.46 64.1371C1386.66 64.1371 1387.65 63.7609 1388.44 62.9922C1389.23 62.2235 1389.62 61.3076 1389.62 60.2118C1389.62 59.1323 1389.23 58.1837 1388.44 57.3823C1387.65 56.5809 1386.66 56.172 1385.46 56.172H1380.4V64.1371H1385.46V64.1371ZM1388.28 79.6748C1389.47 79.6748 1390.47 79.2986 1391.26 78.5299C1392.04 77.7612 1392.44 76.8126 1392.44 75.7004C1392.44 74.6209 1392.03 73.6723 1391.22 72.8873C1390.42 72.1022 1389.42 71.7097 1388.21 71.7097H1380.4V79.6748H1388.28Z" fill="white"/>
<path d="M1407.16 48.0112H1432.45V56.5488H1416.08V63.6798H1429.07V72.2173H1416.08V79.3483H1432.45V87.8858H1407.16V48.0112Z" fill="white"/>
<path d="M1446.43 56.5311H1436.26V47.9935H1465.71V56.5311H1455.42V87.8518H1446.43V56.5311Z" fill="white"/>
<path d="M1479.92 48.0112H1488.01L1505.09 87.8531H1495.76L1492.22 79.43H1475.69L1472.16 87.8531H1462.82L1479.92 48.0112ZM1478.92 71.6939H1488.98L1483.98 59.7381L1478.92 71.6939Z" fill="white"/>
<g clip-path="url(#clip1)">
<path d="M145.555 130.761L149.839 72.3187L167.281 30.6899H92.7188L110.161 72.3187L114.445 130.761L115.771 149.195L115.873 194.572H144.127L144.229 149.195L145.555 130.761Z" fill="url(#paint0_linear)"/>
<path d="M240.11 119.518L186.764 104.021L202.88 128.229L178.808 174.821L210.632 174.416H257.96L240.11 119.518Z" fill="url(#paint1_linear)"/>
<path d="M73.2366 104.021L19.8902 119.518L2.14209 174.416H49.4705L81.1927 174.821L57.1205 128.229L73.2366 104.021Z" fill="url(#paint2_linear)"/>
<path d="M150.859 160.033L144.127 194.572L149.023 197.914L178.807 174.821L179.725 151.626L150.859 160.033Z" fill="url(#paint3_linear)"/>
<path d="M80.3765 151.626L81.1925 174.821L110.977 197.914L115.873 194.572L109.141 160.033L80.3765 151.626Z" fill="url(#paint4_linear)"/>
<path d="M251.432 79.7125L260 38.3876L247.148 0L149.023 72.3186L185.642 104.933L240.11 119.518L251.84 105.844L246.74 102.198L254.9 94.8042L248.678 89.9425L256.838 83.764L251.432 79.7125Z" fill="url(#paint5_linear)"/>
<path d="M0 38.3876L8.67007 79.7125L3.16202 83.764L11.3221 89.9425L5.10004 94.8042L13.2601 102.198L8.16006 105.844L19.8902 119.518L74.4606 104.933L110.977 72.3186L12.8521 0L0 38.3876Z" fill="url(#paint6_linear)"/>
<path d="M57.1206 128.229L80.3768 151.626L81.1928 174.821L57.1206 128.229Z" fill="url(#paint7_linear)"/>
<path d="M202.88 128.229L178.808 174.821L179.726 151.626L202.88 128.229Z" fill="url(#paint8_linear)"/>
<path d="M183.602 214.626L149.023 197.914L151.777 220.298L151.471 229.718L183.602 214.626Z" fill="#D7C1B3" stroke="#D7C1B3" stroke-width="1.42167" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M76.3989 214.626L108.529 229.718L108.325 220.298L110.977 197.914L76.3989 214.626Z" fill="#D7C1B3" stroke="#D7C1B3" stroke-width="1.42167" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M210.632 174.415L183.602 214.626L241.436 230.427L257.96 174.415H210.632Z" fill="url(#paint9_linear)"/>
<path d="M2.14209 174.415L18.5642 230.427L76.3987 214.626L49.4705 174.415H2.14209Z" fill="url(#paint10_linear)"/>
<path d="M12.8521 0L110.977 72.3186L95.5747 30.6898L12.8521 0Z" fill="url(#paint11_linear)"/>
<path d="M164.425 30.6898L149.023 72.3186L247.148 0L164.425 30.6898Z" fill="url(#paint12_linear)"/>
<path d="M73.2367 104.021L57.1206 128.229L114.445 130.761L110.977 72.3186L73.2367 104.021Z" fill="url(#paint13_linear)"/>
<path d="M186.763 104.021L149.023 72.3186L145.555 130.761L202.879 128.229L186.763 104.021Z" fill="url(#paint14_linear)"/>
<path d="M76.3989 214.626L110.977 197.914L81.193 174.821L76.3989 214.626Z" fill="url(#paint15_linear)"/>
<path d="M149.023 197.914L183.602 214.626L178.808 174.821L149.023 197.914Z" fill="url(#paint16_linear)"/>
<path d="M76.3989 214.626L81.1929 174.82L49.4707 174.415L76.3989 214.626Z" fill="url(#paint17_linear)"/>
<path d="M178.808 174.82L183.602 214.626L210.632 174.415L178.808 174.82Z" fill="url(#paint18_linear)"/>
<path d="M202.88 128.229L145.556 130.761L150.86 160.033L159.326 142.409L179.726 151.626L202.88 128.229Z" fill="url(#paint19_linear)"/>
<path d="M80.3773 151.626L100.675 142.409L109.141 160.033L114.446 130.761L57.1211 128.229L80.3773 151.626Z" fill="url(#paint20_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M144.229 149.195L150.859 160.033L145.555 130.761L144.229 149.195ZM144.229 149.195L144.229 149.195L144.127 194.571L150.859 160.033L144.229 149.195Z" fill="url(#paint21_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M114.445 130.761L109.141 160.033L115.873 194.571L115.771 149.195L115.771 149.195L114.445 130.761Z" fill="url(#paint22_linear)"/>
<path d="M151.655 229.596L151.778 220.298L149.228 218.07H110.773L108.325 220.298L108.529 229.718L76.3989 214.626L87.619 223.742L110.467 239.441H149.534L172.382 223.742L183.602 214.626L151.655 229.596Z" fill="#C0AD9E" stroke="#C0AD9E" stroke-width="1.42167" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M149.023 197.914L144.127 194.571H115.873L110.977 197.914L108.325 220.298L110.773 218.07H149.227L151.777 220.298L149.023 197.914Z" fill="#161616" stroke="#161616" stroke-width="0.142167" stroke-miterlimit="10" stroke-linejoin="round"/>
<path d="M159.325 142.409L150.859 160.033L179.726 151.626L159.325 142.409Z" fill="#161616"/>
<path d="M100.675 142.409L109.141 160.033L80.377 151.626L100.675 142.409Z" fill="#161616"/>
</g>
</g>
<defs>
<linearGradient id="paint0_linear" x1="130" y1="30.6899" x2="130" y2="194.572" gradientUnits="userSpaceOnUse">
<stop stop-color="#21FF47"/>
<stop offset="1" stop-color="#BCD8F0"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="218.384" y1="104.021" x2="218.384" y2="174.821" gradientUnits="userSpaceOnUse">
<stop stop-color="#1CAD68"/>
<stop offset="1" stop-color="#77BDD4"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="41.6674" y1="104.021" x2="41.6674" y2="174.821" gradientUnits="userSpaceOnUse">
<stop stop-color="#1CAD68"/>
<stop offset="1" stop-color="#77BDD4"/>
</linearGradient>
<linearGradient id="paint3_linear" x1="161.926" y1="151.626" x2="161.926" y2="197.914" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BCBC8"/>
<stop offset="1" stop-color="#87B9E6"/>
</linearGradient>
<linearGradient id="paint4_linear" x1="98.1246" y1="151.626" x2="98.1246" y2="197.914" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BCBC8"/>
<stop offset="1" stop-color="#87B9E6"/>
</linearGradient>
<linearGradient id="paint5_linear" x1="204.512" y1="0" x2="204.512" y2="119.518" gradientUnits="userSpaceOnUse">
<stop stop-color="#007715"/>
<stop offset="1" stop-color="#0A3424"/>
</linearGradient>
<linearGradient id="paint6_linear" x1="55.4884" y1="0" x2="55.4884" y2="119.518" gradientUnits="userSpaceOnUse">
<stop stop-color="#007715"/>
<stop offset="1" stop-color="#0A3424"/>
</linearGradient>
<linearGradient id="paint7_linear" x1="69.1567" y1="128.229" x2="69.1567" y2="174.821" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<linearGradient id="paint8_linear" x1="190.844" y1="128.229" x2="190.844" y2="174.821" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<linearGradient id="paint9_linear" x1="220.781" y1="174.415" x2="220.781" y2="230.427" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint10_linear" x1="39.2704" y1="174.415" x2="39.2704" y2="230.427" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint11_linear" x1="61.9144" y1="0" x2="61.9144" y2="72.3186" gradientUnits="userSpaceOnUse">
<stop stop-color="#01EA28"/>
<stop offset="1" stop-color="#10D24F"/>
</linearGradient>
<linearGradient id="paint12_linear" x1="198.085" y1="0" x2="198.085" y2="72.3186" gradientUnits="userSpaceOnUse">
<stop stop-color="#01EA28"/>
<stop offset="1" stop-color="#10D24F"/>
</linearGradient>
<linearGradient id="paint13_linear" x1="85.7828" y1="72.3186" x2="85.7828" y2="130.761" gradientUnits="userSpaceOnUse">
<stop stop-color="#12DB56"/>
<stop offset="1" stop-color="#4CC9A3"/>
</linearGradient>
<linearGradient id="paint14_linear" x1="174.217" y1="72.3186" x2="174.217" y2="130.761" gradientUnits="userSpaceOnUse">
<stop stop-color="#12DB56"/>
<stop offset="1" stop-color="#4CC9A3"/>
</linearGradient>
<linearGradient id="paint15_linear" x1="93.6881" y1="174.821" x2="93.6881" y2="214.626" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint16_linear" x1="166.313" y1="174.821" x2="166.313" y2="214.626" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint17_linear" x1="65.3318" y1="174.415" x2="65.3318" y2="214.626" gradientUnits="userSpaceOnUse">
<stop stop-color="#32809D"/>
<stop offset="1" stop-color="#477DD5"/>
</linearGradient>
<linearGradient id="paint18_linear" x1="194.72" y1="174.415" x2="194.72" y2="214.626" gradientUnits="userSpaceOnUse">
<stop stop-color="#32809D"/>
<stop offset="1" stop-color="#477DD5"/>
</linearGradient>
<linearGradient id="paint19_linear" x1="174.218" y1="128.229" x2="174.218" y2="160.033" gradientUnits="userSpaceOnUse">
<stop stop-color="#239777"/>
<stop offset="1" stop-color="#2C8A8D"/>
</linearGradient>
<linearGradient id="paint20_linear" x1="85.7833" y1="128.229" x2="85.7833" y2="160.033" gradientUnits="userSpaceOnUse">
<stop stop-color="#239777"/>
<stop offset="1" stop-color="#2C8A8D"/>
</linearGradient>
<linearGradient id="paint21_linear" x1="147.493" y1="130.761" x2="147.493" y2="194.571" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<linearGradient id="paint22_linear" x1="112.507" y1="130.761" x2="112.507" y2="194.571" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<clipPath id="clip0">
<rect width="1533" height="242" fill="white"/>
</clipPath>
<clipPath id="clip1">
<rect width="260" height="239.948" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

@ -0,0 +1,148 @@
<svg width="1533" height="242" viewBox="0 0 1533 242" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M1157.95 121.694C1151.15 117.195 1143.65 113.996 1136.55 109.997C1131.95 107.398 1127.05 105.098 1123.05 101.799C1116.24 96.2 1117.64 85.2024 1124.75 80.4035C1134.95 73.605 1151.85 77.4042 1153.65 91.3011C1153.65 91.601 1153.95 91.801 1154.25 91.801H1169.66C1170.06 91.801 1170.36 91.501 1170.26 91.1011C1169.46 81.5033 1165.75 73.505 1158.95 68.4062C1152.45 63.5073 1145.05 60.9078 1137.15 60.9078C1096.44 60.9078 1092.74 103.998 1114.64 117.595C1117.14 119.195 1138.65 129.992 1146.25 134.691C1153.85 139.39 1156.25 147.988 1152.95 154.787C1149.95 160.986 1142.15 165.285 1134.35 164.785C1125.85 164.285 1119.24 159.686 1116.94 152.487C1116.54 151.188 1116.34 148.688 1116.34 147.589C1116.34 147.289 1116.04 146.989 1115.74 146.989H1099.04C1098.74 146.989 1098.44 147.289 1098.44 147.589C1098.44 159.686 1101.44 166.384 1109.64 172.483C1117.34 178.282 1125.75 180.681 1134.45 180.681C1157.25 180.681 1169.06 167.784 1171.46 154.387C1173.56 141.29 1169.66 129.493 1157.95 121.694V121.694Z" fill="white"/>
<path d="M432.694 63.1091H425.293H417.191C416.891 63.1091 416.691 63.3091 416.591 63.509L402.888 108.698C402.688 109.298 401.888 109.298 401.688 108.698L387.985 63.509C387.885 63.2091 387.685 63.1091 387.384 63.1091H379.283H371.881H361.879C361.579 63.1091 361.279 63.4091 361.279 63.709V179.082C361.279 179.382 361.579 179.682 361.879 179.682H378.583C378.883 179.682 379.183 179.382 379.183 179.082V91.4025C379.183 90.7027 380.183 90.6027 380.383 91.2025L394.186 136.692L395.186 139.891C395.286 140.191 395.486 140.291 395.786 140.291H408.589C408.889 140.291 409.089 140.091 409.189 139.891L410.189 136.692L423.992 91.2025C424.192 90.5027 425.193 90.7027 425.193 91.4025V179.082C425.193 179.382 425.493 179.682 425.793 179.682H442.496C442.796 179.682 443.097 179.382 443.097 179.082V63.709C443.097 63.4091 442.796 63.1091 442.496 63.1091H432.694Z" fill="white"/>
<path d="M902.197 63.1091C901.897 63.1091 901.697 63.3091 901.597 63.509L887.894 108.698C887.694 109.298 886.894 109.298 886.694 108.698L872.991 63.509C872.891 63.2091 872.691 63.1091 872.39 63.1091H846.985C846.685 63.1091 846.385 63.4091 846.385 63.709V179.082C846.385 179.382 846.685 179.682 846.985 179.682H863.689C863.989 179.682 864.289 179.382 864.289 179.082V91.4025C864.289 90.7027 865.289 90.6027 865.489 91.2025L879.292 136.692L880.292 139.891C880.392 140.191 880.592 140.291 880.892 140.291H893.695C893.995 140.291 894.195 140.091 894.295 139.891L895.295 136.692L909.098 91.2025C909.299 90.5027 910.299 90.7027 910.299 91.4025V179.082C910.299 179.382 910.599 179.682 910.899 179.682H927.603C927.903 179.682 928.203 179.382 928.203 179.082V63.709C928.203 63.4091 927.903 63.1091 927.603 63.1091H902.197Z" fill="white"/>
<path d="M686.749 63.1091H655.642H638.938H607.832C607.532 63.1091 607.231 63.4091 607.231 63.709V78.1056C607.231 78.4055 607.532 78.7055 607.832 78.7055H638.338V179.082C638.338 179.382 638.638 179.682 638.938 179.682H655.642C655.942 179.682 656.242 179.382 656.242 179.082V78.7055H686.749C687.049 78.7055 687.349 78.4055 687.349 78.1056V63.709C687.349 63.4091 687.149 63.1091 686.749 63.1091V63.1091Z" fill="white"/>
<path d="M785.272 179.681H800.475C800.875 179.681 801.175 179.281 801.075 178.881L769.668 63.1082C769.568 62.8082 769.368 62.7083 769.068 62.7083H763.267H753.065H747.264C746.964 62.7083 746.763 62.9082 746.663 63.1082L715.257 178.881C715.157 179.281 715.457 179.681 715.857 179.681H731.06C731.36 179.681 731.56 179.481 731.66 179.281L740.762 145.589C740.862 145.289 741.062 145.189 741.362 145.189H774.97C775.27 145.189 775.47 145.389 775.57 145.589L784.672 179.281C784.772 179.481 785.072 179.681 785.272 179.681V179.681ZM745.363 128.693L757.566 83.6034C757.766 83.0035 758.566 83.0035 758.766 83.6034L770.969 128.693C771.069 129.093 770.769 129.493 770.369 129.493H745.963C745.563 129.493 745.263 129.093 745.363 128.693V128.693Z" fill="white"/>
<path d="M1044.53 179.681H1059.73C1060.13 179.681 1060.43 179.281 1060.33 178.881L1028.93 63.1082C1028.83 62.8082 1028.63 62.7083 1028.33 62.7083H1022.52H1012.32H1006.52C1006.22 62.7083 1006.02 62.9082 1005.92 63.1082L974.514 178.881C974.414 179.281 974.714 179.681 975.114 179.681H990.317C990.618 179.681 990.818 179.481 990.918 179.281L1000.02 145.589C1000.12 145.289 1000.32 145.189 1000.62 145.189H1034.23C1034.53 145.189 1034.73 145.389 1034.83 145.589L1043.93 179.281C1044.03 179.481 1044.23 179.681 1044.53 179.681V179.681ZM1004.62 128.693L1016.82 83.6034C1017.02 83.0035 1017.82 83.0035 1018.02 83.6034L1030.23 128.693C1030.33 129.093 1030.03 129.493 1029.63 129.493H1005.22C1004.82 129.493 1004.52 129.093 1004.62 128.693V128.693Z" fill="white"/>
<path d="M510.909 162.584V126.793C510.909 126.493 511.209 126.193 511.509 126.193H556.019C556.319 126.193 556.619 125.893 556.619 125.593V111.196C556.619 110.896 556.319 110.596 556.019 110.596H511.509C511.209 110.596 510.909 110.296 510.909 109.997V79.4037C510.909 79.1038 511.209 78.8039 511.509 78.8039H562.121C562.421 78.8039 562.721 78.5039 562.721 78.204V63.8074C562.721 63.5074 562.421 63.2075 562.121 63.2075H510.909H493.606C493.305 63.2075 493.005 63.5074 493.005 63.8074V78.8039V110.696V126.293V163.284V179.08C493.005 179.38 493.305 179.68 493.606 179.68H510.909H564.221C564.521 179.68 564.821 179.38 564.821 179.08V163.884C564.821 163.584 564.521 163.284 564.221 163.284H511.409C511.109 163.184 510.909 162.984 510.909 162.584Z" fill="white"/>
<path d="M1310.58 178.681L1252.77 118.995C1252.57 118.795 1252.57 118.395 1252.77 118.195L1304.78 64.2074C1305.18 63.8075 1304.88 63.2076 1304.38 63.2076H1283.08C1282.88 63.2076 1282.78 63.3076 1282.68 63.4076L1238.57 109.197C1238.17 109.597 1237.57 109.297 1237.57 108.797V63.8075C1237.57 63.5076 1237.27 63.2076 1236.97 63.2076H1220.26C1219.96 63.2076 1219.66 63.5076 1219.66 63.8075V179.181C1219.66 179.48 1219.96 179.78 1220.26 179.78H1236.97C1237.27 179.78 1237.57 179.48 1237.57 179.181V128.392C1237.57 127.893 1238.27 127.593 1238.57 127.993L1288.58 179.58C1288.68 179.68 1288.88 179.78 1288.98 179.78H1310.28C1310.68 179.68 1310.98 178.981 1310.58 178.681V178.681Z" fill="white"/>
<path d="M1512.38 110.091H1359.98C1348.59 110.091 1339.36 100.86 1339.36 89.4845V44.6061C1339.36 33.231 1348.59 24 1359.98 24H1512.38C1523.76 24 1533 33.231 1533 44.6061V89.4845C1533 100.876 1523.76 110.091 1512.38 110.091Z" fill="#F66A0A"/>
<path d="M1371.47 48.027H1386.48C1388.08 48.027 1389.62 48.3377 1391.06 48.9592C1392.5 49.5807 1393.76 50.4149 1394.86 51.478C1395.94 52.5411 1396.79 53.8004 1397.41 55.2397C1398.04 56.679 1398.35 58.2164 1398.35 59.8683C1398.35 61.2912 1398.09 62.567 1397.56 63.7118C1397.04 64.8567 1396.35 65.8544 1395.48 66.7213C1397.17 67.5881 1398.53 68.8311 1399.59 70.483C1400.64 72.1349 1401.17 74.0158 1401.17 76.1583C1401.17 77.8102 1400.85 79.3313 1400.23 80.7542C1399.61 82.1771 1398.76 83.4202 1397.68 84.4833C1396.6 85.5464 1395.3 86.3805 1393.83 86.9856C1392.35 87.5908 1390.75 87.8852 1389.03 87.8852H1371.49V48.027H1371.47ZM1385.46 64.1371C1386.66 64.1371 1387.65 63.7609 1388.44 62.9922C1389.23 62.2235 1389.62 61.3076 1389.62 60.2118C1389.62 59.1323 1389.23 58.1837 1388.44 57.3823C1387.65 56.5809 1386.66 56.172 1385.46 56.172H1380.4V64.1371H1385.46V64.1371ZM1388.28 79.6748C1389.47 79.6748 1390.47 79.2986 1391.26 78.5299C1392.04 77.7612 1392.44 76.8126 1392.44 75.7004C1392.44 74.6209 1392.03 73.6723 1391.22 72.8873C1390.42 72.1022 1389.42 71.7097 1388.21 71.7097H1380.4V79.6748H1388.28Z" fill="white"/>
<path d="M1407.16 48.0112H1432.45V56.5488H1416.08V63.6798H1429.07V72.2173H1416.08V79.3483H1432.45V87.8858H1407.16V48.0112Z" fill="white"/>
<path d="M1446.43 56.5311H1436.26V47.9935H1465.71V56.5311H1455.42V87.8518H1446.43V56.5311Z" fill="white"/>
<path d="M1479.92 48.0112H1488.01L1505.09 87.8531H1495.76L1492.22 79.43H1475.69L1472.16 87.8531H1462.82L1479.92 48.0112ZM1478.92 71.6939H1488.98L1483.98 59.7381L1478.92 71.6939Z" fill="white"/>
<g clip-path="url(#clip1)">
<path d="M145.555 130.761L149.839 72.3187L167.281 30.6899H92.7188L110.161 72.3187L114.445 130.761L115.771 149.195L115.873 194.572H144.127L144.229 149.195L145.555 130.761Z" fill="url(#paint0_linear)"/>
<path d="M240.11 119.518L186.764 104.021L202.88 128.229L178.808 174.821L210.632 174.416H257.96L240.11 119.518Z" fill="url(#paint1_linear)"/>
<path d="M73.2366 104.021L19.8902 119.518L2.14209 174.416H49.4705L81.1927 174.821L57.1205 128.229L73.2366 104.021Z" fill="url(#paint2_linear)"/>
<path d="M150.859 160.033L144.127 194.572L149.023 197.914L178.807 174.821L179.725 151.626L150.859 160.033Z" fill="url(#paint3_linear)"/>
<path d="M80.3765 151.626L81.1925 174.821L110.977 197.914L115.873 194.572L109.141 160.033L80.3765 151.626Z" fill="url(#paint4_linear)"/>
<path d="M251.432 79.7125L260 38.3876L247.148 0L149.023 72.3186L185.642 104.933L240.11 119.518L251.84 105.844L246.74 102.198L254.9 94.8042L248.678 89.9425L256.838 83.764L251.432 79.7125Z" fill="url(#paint5_linear)"/>
<path d="M0 38.3876L8.67007 79.7125L3.16202 83.764L11.3221 89.9425L5.10004 94.8042L13.2601 102.198L8.16006 105.844L19.8902 119.518L74.4606 104.933L110.977 72.3186L12.8521 0L0 38.3876Z" fill="url(#paint6_linear)"/>
<path d="M57.1206 128.229L80.3768 151.626L81.1928 174.821L57.1206 128.229Z" fill="url(#paint7_linear)"/>
<path d="M202.88 128.229L178.808 174.821L179.726 151.626L202.88 128.229Z" fill="url(#paint8_linear)"/>
<path d="M183.602 214.626L149.023 197.914L151.777 220.298L151.471 229.718L183.602 214.626Z" fill="#D7C1B3" stroke="#D7C1B3" stroke-width="1.42167" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M76.3989 214.626L108.529 229.718L108.325 220.298L110.977 197.914L76.3989 214.626Z" fill="#D7C1B3" stroke="#D7C1B3" stroke-width="1.42167" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M210.632 174.415L183.602 214.626L241.436 230.427L257.96 174.415H210.632Z" fill="url(#paint9_linear)"/>
<path d="M2.14209 174.415L18.5642 230.427L76.3987 214.626L49.4705 174.415H2.14209Z" fill="url(#paint10_linear)"/>
<path d="M12.8521 0L110.977 72.3186L95.5747 30.6898L12.8521 0Z" fill="url(#paint11_linear)"/>
<path d="M164.425 30.6898L149.023 72.3186L247.148 0L164.425 30.6898Z" fill="url(#paint12_linear)"/>
<path d="M73.2367 104.021L57.1206 128.229L114.445 130.761L110.977 72.3186L73.2367 104.021Z" fill="url(#paint13_linear)"/>
<path d="M186.763 104.021L149.023 72.3186L145.555 130.761L202.879 128.229L186.763 104.021Z" fill="url(#paint14_linear)"/>
<path d="M76.3989 214.626L110.977 197.914L81.193 174.821L76.3989 214.626Z" fill="url(#paint15_linear)"/>
<path d="M149.023 197.914L183.602 214.626L178.808 174.821L149.023 197.914Z" fill="url(#paint16_linear)"/>
<path d="M76.3989 214.626L81.1929 174.82L49.4707 174.415L76.3989 214.626Z" fill="url(#paint17_linear)"/>
<path d="M178.808 174.82L183.602 214.626L210.632 174.415L178.808 174.82Z" fill="url(#paint18_linear)"/>
<path d="M202.88 128.229L145.556 130.761L150.86 160.033L159.326 142.409L179.726 151.626L202.88 128.229Z" fill="url(#paint19_linear)"/>
<path d="M80.3773 151.626L100.675 142.409L109.141 160.033L114.446 130.761L57.1211 128.229L80.3773 151.626Z" fill="url(#paint20_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M144.229 149.195L150.859 160.033L145.555 130.761L144.229 149.195ZM144.229 149.195L144.229 149.195L144.127 194.571L150.859 160.033L144.229 149.195Z" fill="url(#paint21_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M114.445 130.761L109.141 160.033L115.873 194.571L115.771 149.195L115.771 149.195L114.445 130.761Z" fill="url(#paint22_linear)"/>
<path d="M151.655 229.596L151.778 220.298L149.228 218.07H110.773L108.325 220.298L108.529 229.718L76.3989 214.626L87.619 223.742L110.467 239.441H149.534L172.382 223.742L183.602 214.626L151.655 229.596Z" fill="#C0AD9E" stroke="#C0AD9E" stroke-width="1.42167" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M149.023 197.914L144.127 194.571H115.873L110.977 197.914L108.325 220.298L110.773 218.07H149.227L151.777 220.298L149.023 197.914Z" fill="#161616" stroke="#161616" stroke-width="0.142167" stroke-miterlimit="10" stroke-linejoin="round"/>
<path d="M159.325 142.409L150.859 160.033L179.726 151.626L159.325 142.409Z" fill="#161616"/>
<path d="M100.675 142.409L109.141 160.033L80.377 151.626L100.675 142.409Z" fill="#161616"/>
</g>
</g>
<defs>
<linearGradient id="paint0_linear" x1="130" y1="30.6899" x2="130" y2="194.572" gradientUnits="userSpaceOnUse">
<stop stop-color="#21FF47"/>
<stop offset="1" stop-color="#BCD8F0"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="218.384" y1="104.021" x2="218.384" y2="174.821" gradientUnits="userSpaceOnUse">
<stop stop-color="#1CAD68"/>
<stop offset="1" stop-color="#77BDD4"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="41.6674" y1="104.021" x2="41.6674" y2="174.821" gradientUnits="userSpaceOnUse">
<stop stop-color="#1CAD68"/>
<stop offset="1" stop-color="#77BDD4"/>
</linearGradient>
<linearGradient id="paint3_linear" x1="161.926" y1="151.626" x2="161.926" y2="197.914" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BCBC8"/>
<stop offset="1" stop-color="#87B9E6"/>
</linearGradient>
<linearGradient id="paint4_linear" x1="98.1246" y1="151.626" x2="98.1246" y2="197.914" gradientUnits="userSpaceOnUse">
<stop stop-color="#7BCBC8"/>
<stop offset="1" stop-color="#87B9E6"/>
</linearGradient>
<linearGradient id="paint5_linear" x1="204.512" y1="0" x2="204.512" y2="119.518" gradientUnits="userSpaceOnUse">
<stop stop-color="#007715"/>
<stop offset="1" stop-color="#0A3424"/>
</linearGradient>
<linearGradient id="paint6_linear" x1="55.4884" y1="0" x2="55.4884" y2="119.518" gradientUnits="userSpaceOnUse">
<stop stop-color="#007715"/>
<stop offset="1" stop-color="#0A3424"/>
</linearGradient>
<linearGradient id="paint7_linear" x1="69.1567" y1="128.229" x2="69.1567" y2="174.821" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<linearGradient id="paint8_linear" x1="190.844" y1="128.229" x2="190.844" y2="174.821" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<linearGradient id="paint9_linear" x1="220.781" y1="174.415" x2="220.781" y2="230.427" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint10_linear" x1="39.2704" y1="174.415" x2="39.2704" y2="230.427" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint11_linear" x1="61.9144" y1="0" x2="61.9144" y2="72.3186" gradientUnits="userSpaceOnUse">
<stop stop-color="#01EA28"/>
<stop offset="1" stop-color="#10D24F"/>
</linearGradient>
<linearGradient id="paint12_linear" x1="198.085" y1="0" x2="198.085" y2="72.3186" gradientUnits="userSpaceOnUse">
<stop stop-color="#01EA28"/>
<stop offset="1" stop-color="#10D24F"/>
</linearGradient>
<linearGradient id="paint13_linear" x1="85.7828" y1="72.3186" x2="85.7828" y2="130.761" gradientUnits="userSpaceOnUse">
<stop stop-color="#12DB56"/>
<stop offset="1" stop-color="#4CC9A3"/>
</linearGradient>
<linearGradient id="paint14_linear" x1="174.217" y1="72.3186" x2="174.217" y2="130.761" gradientUnits="userSpaceOnUse">
<stop stop-color="#12DB56"/>
<stop offset="1" stop-color="#4CC9A3"/>
</linearGradient>
<linearGradient id="paint15_linear" x1="93.6881" y1="174.821" x2="93.6881" y2="214.626" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint16_linear" x1="166.313" y1="174.821" x2="166.313" y2="214.626" gradientUnits="userSpaceOnUse">
<stop stop-color="#5BAECB"/>
<stop offset="1" stop-color="#4160C1"/>
</linearGradient>
<linearGradient id="paint17_linear" x1="65.3318" y1="174.415" x2="65.3318" y2="214.626" gradientUnits="userSpaceOnUse">
<stop stop-color="#32809D"/>
<stop offset="1" stop-color="#477DD5"/>
</linearGradient>
<linearGradient id="paint18_linear" x1="194.72" y1="174.415" x2="194.72" y2="214.626" gradientUnits="userSpaceOnUse">
<stop stop-color="#32809D"/>
<stop offset="1" stop-color="#477DD5"/>
</linearGradient>
<linearGradient id="paint19_linear" x1="174.218" y1="128.229" x2="174.218" y2="160.033" gradientUnits="userSpaceOnUse">
<stop stop-color="#239777"/>
<stop offset="1" stop-color="#2C8A8D"/>
</linearGradient>
<linearGradient id="paint20_linear" x1="85.7833" y1="128.229" x2="85.7833" y2="160.033" gradientUnits="userSpaceOnUse">
<stop stop-color="#239777"/>
<stop offset="1" stop-color="#2C8A8D"/>
</linearGradient>
<linearGradient id="paint21_linear" x1="147.493" y1="130.761" x2="147.493" y2="194.571" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<linearGradient id="paint22_linear" x1="112.507" y1="130.761" x2="112.507" y2="194.571" gradientUnits="userSpaceOnUse">
<stop stop-color="#42C4A0"/>
<stop offset="1" stop-color="#51ACC7"/>
</linearGradient>
<clipPath id="clip0">
<rect width="1533" height="242" fill="white"/>
</clipPath>
<clipPath id="clip1">
<rect width="260" height="239.948" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

@ -0,0 +1,322 @@
{
"chunks": [
{
"color": [246, 133, 27],
"faces": [
[17, 33, 10],
[17, 18, 34],
[34, 33, 17],
[10, 6, 17],
[11, 15, 31],
[31, 18, 11],
[18, 12, 11],
[14, 16, 40],
[40, 41, 14],
[59, 5, 35],
[35, 79, 59],
[67, 63, 77],
[67, 77, 76],
[76, 68, 67],
[63, 67, 58],
[64, 68, 75],
[75, 37, 64],
[68, 64, 66],
[14, 41, 37],
[37, 15, 14],
[5, 59, 40],
[40, 16, 5]
]
},
{
"color": [228, 118, 27],
"faces": [
[31, 24, 18],
[6, 5, 16],
[16, 17, 6],
[24, 32, 33],
[33, 34, 24],
[5, 4, 35],
[75, 68, 71],
[58, 67, 40],
[40, 59, 58],
[71, 76, 77],
[77, 78, 71]
]
},
{
"color": [118, 61, 22],
"faces": [
[0, 1, 2],
[2, 3, 0],
[4, 5, 2],
[6, 3, 2],
[2, 5, 6],
[7, 8, 9],
[10, 3, 6],
[10, 50, 7],
[7, 3, 10],
[7, 9, 3],
[49, 0, 9],
[3, 9, 0],
[53, 54, 55],
[55, 56, 53],
[57, 56, 55],
[58, 59, 55],
[55, 54, 58],
[60, 61, 62],
[63, 58, 54],
[63, 60, 89],
[60, 63, 54],
[60, 54, 61],
[88, 61, 53],
[54, 53, 61],
[2, 1, 4],
[55, 59, 57]
]
},
{
"color": [22, 22, 22],
"faces": [
[36, 15, 37],
[37, 38, 36],
[31, 39, 22],
[22, 21, 31],
[31, 15, 36],
[36, 39, 31],
[75, 69, 26],
[26, 80, 75],
[75, 80, 38],
[38, 37, 75],
[38, 80, 39],
[39, 36, 38],
[39, 80, 26],
[26, 22, 39]
]
},
{
"color": [215, 193, 179],
"faces": [
[21, 20, 24],
[24, 31, 21],
[69, 71, 70],
[71, 69, 75]
]
},
{
"color": [192, 173, 158],
"faces": [
[19, 20, 21],
[21, 22, 19],
[20, 19, 23],
[23, 24, 20],
[23, 25, 24],
[19, 22, 26],
[26, 27, 19],
[23, 28, 29],
[23, 29, 30],
[25, 23, 30],
[29, 51, 52],
[52, 30, 29],
[27, 26, 69],
[69, 70, 27],
[70, 71, 72],
[72, 27, 70],
[72, 71, 73],
[51, 74, 72],
[52, 51, 72],
[73, 52, 72],
[19, 27, 74],
[74, 28, 19],
[51, 29, 28],
[28, 74, 51],
[74, 27, 72],
[28, 23, 19]
]
},
{
"color": [205, 97, 22],
"faces": [
[24, 34, 18],
[16, 13, 12],
[12, 17, 16],
[13, 16, 11],
[71, 68, 76],
[40, 67, 66],
[66, 65, 40],
[65, 64, 40]
]
},
{
"color": [35, 52, 71],
"faces": [
[11, 12, 13],
[64, 65, 66]
]
},
{
"color": [228, 117, 31],
"faces": [
[14, 15, 11],
[11, 16, 14],
[17, 12, 18],
[41, 64, 37],
[67, 68, 66]
]
},
{
"color": [226, 118, 27],
"faces": [
[35, 4, 42],
[4, 1, 42],
[42, 43, 44],
[44, 35, 42],
[45, 43, 42],
[42, 10, 45],
[30, 32, 24],
[24, 25, 30],
[30, 33, 32],
[33, 30, 10],
[44, 43, 46],
[43, 45, 47],
[47, 46, 43],
[48, 47, 45],
[45, 30, 48],
[30, 45, 10],
[49, 42, 0],
[8, 7, 42],
[50, 42, 7],
[50, 10, 42],
[1, 0, 42],
[42, 9, 8],
[42, 49, 9],
[64, 41, 40],
[57, 59, 79],
[79, 81, 57],
[57, 81, 56],
[82, 79, 35],
[35, 44, 82],
[81, 79, 82],
[82, 83, 81],
[84, 63, 81],
[81, 83, 84],
[44, 46, 85],
[85, 82, 44],
[52, 73, 71],
[71, 78, 52],
[52, 78, 77],
[77, 63, 52],
[82, 85, 83],
[83, 85, 86],
[86, 84, 83],
[87, 52, 84],
[84, 86, 87],
[52, 63, 84],
[88, 53, 81],
[62, 81, 60],
[89, 60, 81],
[89, 81, 63],
[56, 81, 53],
[81, 62, 61],
[81, 61, 88],
[48, 87, 86],
[86, 47, 48],
[47, 86, 85],
[85, 46, 47],
[48, 30, 52],
[52, 87, 48]
]
}
],
"positions": [
[111.0246, 52.6046, 46.2259],
[114.025, 87.6733, 58.9818],
[66.192, 80.898, 55.3943],
[72.1133, 35.4918, 30.8714],
[97.8045, 116.561, 73.9788],
[16.7623, 58.0109, 58.0782],
[52.6089, 30.3641, 42.5561],
[106.8814, 31.9455, 46.9133],
[113.4846, 38.6049, 49.1215],
[108.6633, 43.2332, 46.3154],
[101.2166, 15.9822, 46.3082],
[16.6605, -16.2883, 93.6187],
[40.775, -10.2288, 85.2764],
[23.9269, -2.5103, 86.7365],
[11.1691, -7.0037, 99.3776],
[9.5692, -34.3939, 141.672],
[12.596, 7.1655, 88.741],
[61.1809, 8.8142, 76.9968],
[39.7195, -28.9271, 88.9638],
[13.7962, -68.5757, 132.057],
[15.2674, -62.32, 129.688],
[14.8446, -52.6096, 140.113],
[12.8917, -49.7716, 144.741],
[35.6042, -71.758, 81.0639],
[47.4625, -68.6061, 63.3697],
[38.2486, -64.7302, 38.9099],
[-12.8917, -49.7716, 144.741],
[-13.7962, -68.5757, 132.057],
[17.8021, -71.758, 81.0639],
[19.1243, -69.0168, 49.4201],
[38.2486, -66.2756, 17.7762],
[12.8928, -36.7035, 141.672],
[109.284, -93.5899, 27.8243],
[122.118, -36.8894, 35.025],
[67.7668, -30.197, 78.4178],
[33.1807, 101.852, 25.3186],
[9.4063, -35.5898, 150.722],
[-9.5692, -34.3939, 141.672],
[-9.4063, -35.5898, 150.722],
[11.4565, -37.8994, 150.722],
[-12.596, 7.1655, 88.741],
[-11.1691, -7.0037, 99.3776],
[70.2365, 62.8362, -3.9475],
[47.2634, 54.294, -27.4148],
[28.7302, 91.7311, -24.9726],
[69.1676, 6.5862, -12.7757],
[28.7302, 49.1003, -48.3596],
[31.903, 5.692, -47.822],
[35.0758, -34.4329, -16.2809],
[115.2841, 48.6815, 48.6841],
[110.8428, 28.4821, 49.1762],
[-19.1243, -69.0168, 49.4201],
[-38.2486, -66.2756, 17.7762],
[-111.0246, 52.6046, 46.2259],
[-72.1133, 35.4918, 30.8714],
[-66.192, 80.898, 55.3943],
[-114.025, 87.6733, 58.9818],
[-97.8045, 116.561, 73.9788],
[-52.6089, 30.3641, 42.5561],
[-16.7623, 58.0109, 58.0782],
[-106.8814, 31.9455, 46.9133],
[-108.6633, 43.2332, 46.3154],
[-113.4846, 38.6049, 49.1215],
[-101.2166, 15.9822, 46.3082],
[-16.6605, -16.2883, 93.6187],
[-23.9269, -2.5103, 86.7365],
[-40.775, -10.2288, 85.2764],
[-61.1809, 8.8142, 76.9968],
[-39.7195, -28.9271, 88.9638],
[-14.8446, -52.6096, 140.113],
[-15.2674, -62.32, 129.688],
[-47.4625, -68.6061, 63.3697],
[-35.6042, -71.758, 81.0639],
[-38.2486, -64.7302, 38.9099],
[-17.8021, -71.758, 81.0639],
[-12.8928, -36.7035, 141.672],
[-67.7668, -30.197, 78.4178],
[-122.118, -36.8894, 35.025],
[-109.284, -93.5899, 27.8243],
[-33.1807, 101.852, 25.3186],
[-11.4565, -37.8994, 150.722],
[-70.2365, 62.8362, -3.9475],
[-28.7302, 91.7311, -24.9726],
[-47.2634, 54.294, -27.4148],
[-69.1676, 6.5862, -12.7757],
[-28.7302, 49.1003, -48.3596],
[-31.903, 5.692, -47.822],
[-35.0758, -34.4329, -16.2809],
[-115.2841, 48.6815, 48.6841],
[-110.8428, 28.4821, 49.1762]
]
}

@ -0,0 +1,115 @@
WEBVTT
1
00:00:00.780 --> 00:00:04.580
MetaMask es una nueva forma de conectarse
a sitios y aplicaciones.
2
00:00:04.580 --> 00:00:08.860
En los sitios web tradicionales, una base de datos
o un banco central es responsable de controlar y
3
00:00:08.860 --> 00:00:10.179
recuperar sus cuentas.
4
00:00:10.179 --> 00:00:15.050
Pero con MetaMask, todo el control lo tiene
el titular de la clave maestra.
5
00:00:15.050 --> 00:00:18.460
La persona que tenga esta clave controlará las cuentas.
6
00:00:18.460 --> 00:00:21.110
La “clave maestra”
es su frase secreta de recuperación.
7
00:00:21.110 --> 00:00:26.070
Esta frase está compuesta por 12 palabras y se crea
la primera vez que se configura MetaMask; le permite
8
00:00:26.070 --> 00:00:30.120
recuperar su cartera y los fondos en caso de que
alguna vez pierda su clave de acceso.
9
00:00:30.120 --> 00:00:33.451
Es fundamental que proteja
su cartera
10
00:00:33.451 --> 00:00:37.510
guardando la frase secreta de recuperación
en un lugar sumamente seguro y secreto.
11
00:00:37.510 --> 00:00:41.429
Si alguna persona llegara a encontrarla, accederá
a la “clave maestra” de su cartera y podrá
12
00:00:41.429 --> 00:00:45.190
ingresar a todos sus fondos y tomarlos libremente.
13
00:00:45.190 --> 00:00:50.109
Para proteger su cartera en MetaMask,
guarde en un lugar seguro su frase secreta de recuperación.
14
00:00:50.109 --> 00:00:54.930
Puede anotarla, esconderla en algún lugar,
guardarla en una caja de seguridad
15
00:00:54.930 --> 00:00:57.729
o utilizar un administrador seguro de contraseñas.
16
00:00:57.729 --> 00:01:01.050
Inclusive, algunos usuarios graban
la frase en una placa metálica.
17
00:01:01.050 --> 00:01:04.440
Si llegara a perder su frase secreta de recuperación,
ninguna persona, ni siquiera el equipo de MetaMask, podrá ayudarlo
18
00:01:04.440 --> 00:01:07.820
a recuperar
su cartera.
19
00:01:07.820 --> 00:01:12.072
Si aún no ha anotado ni guardado en un lugar seguro su
frase secreta de recuperación,
20
00:01:12.072 --> 00:01:15.492
hágalo ahora mismo. Lo esperamos.
21
00:01:15.500 --> 00:01:20.780
Y recuerde no compartir nunca su
frase secreta de recuperación con nadie; ni siquiera con nosotros.
22
00:01:20.780 --> 00:01:24.910
Si alguien se la pide alguna vez,
será con intenciones de estafarlo.
23
00:01:24.910 --> 00:01:26.250
¡Eso es todo!
24
00:01:26.250 --> 00:01:31.020
Ahora ya sabe qué es una frase secreta de recuperación
y qué debe hacer para mantener protegida su cartera.

@ -0,0 +1,115 @@
WEBVTT
1
00:00:00.780 --> 00:00:04.580
MetaMask सइट और एपिशन स
एक नय तर
2
00:00:04.580 --> 00:00:08.860
परिक वबसइट पर, आपकिित करन और
नरत करनिए एक कय डस य
3
00:00:08.860 --> 00:00:10.179
क जिर ह
4
00:00:10.179 --> 00:00:15.050
िन MetaMask पर, स शकि
टर करक क
5
00:00:15.050 --> 00:00:18.460
रखत, वह खिित करत
6
00:00:18.460 --> 00:00:21.110
आपकत रिकवर
आपक "मटर क" ह
7
00:00:21.110 --> 00:00:26.070
यह 12 शब एक स, ज
आपक पहलर MetaMask सट करन पर जनरट ह, जिसस
8
00:00:26.070 --> 00:00:30.120
आप कभ एकस ख पर अपनट और धन क
नरत कर सकत
9
00:00:30.120 --> 00:00:33.451
यह महतवपण हि आप
अपनत रिकवर
10
00:00:33.451 --> 00:00:37.510
बहत सरकित और बहत गत रखकर
अपनट करकित रख
11
00:00:37.510 --> 00:00:41.429
अगर कि इसकि एकस मिल ज, त
उनकस आपकट क "मटर क" ह और
12
00:00:41.429 --> 00:00:45.190
आपक धन क आस एकस कर सकत
13
00:00:45.190 --> 00:00:50.109
अपन MetaMask वट करकित करनिए आप अपन
त रिकवररकित रप स सहजन
14
00:00:50.109 --> 00:00:54.930
आप इसिख सकत, इस कह सकत,
इसििट बस म रख सकत
15
00:00:54.930 --> 00:00:57.729
रकित पसवरड मजर क उपयग कर सकत
16
00:00:57.729 --> 00:01:01.050
छ उपयगकर अपन
ट पर भ उकर कर रखत!
17
00:01:01.050 --> 00:01:04.440
यदि आप अपनत रिकवर, त
ई भ, यह तक कि MetaMask कम भ,
18
00:01:04.440 --> 00:01:07.820
आपकट कनरत करन आपक
सहयत नह कर सकत
19
00:01:07.820 --> 00:01:12.072
यदि आपन अपनत रिकवर
ि नह और इस कहरकित सरहत नहि,
20
00:01:12.072 --> 00:01:15.492
अभ कर। हम इतजर कर
21
00:01:15.500 --> 00:01:20.780
और यद रख, कभ अपनत रिकवर
िथ स न कर: हमस नह
22
00:01:20.780 --> 00:01:24.910
यदिई आपस कभ इसगत, त
आपकथ धधड करनिश कर सकत
23
00:01:24.910 --> 00:01:26.250
बस इतन!
24
00:01:26.250 --> 00:01:31.020
अब आपक पत चल गयित रिकवर
और अपनट क सकशल और सरकित रखए।

@ -0,0 +1,115 @@
WEBVTT
1
00:00:00.780 --> 00:00:04.580
MetaMask adalah cara baru untuk terhubung
ke situs dan aplikasi.
2
00:00:04.580 --> 00:00:08.860
Di situs web tradisional, database sentral
atau bank bertanggung jawab untuk mengontrol dan
3
00:00:08.860 --> 00:00:10.179
memulihkan akun Anda.
4
00:00:10.179 --> 00:00:15.050
Tetapi di MetaMask, semua kuasa milik
pemegang kunci induk.
5
00:00:15.050 --> 00:00:18.460
Siapa pun yang memegang kunci tersebut, akan mengontrol akun.
6
00:00:18.460 --> 00:00:21.110
Frasa pemulihan rahasia
adalah "kunci induk" Anda.
7
00:00:21.110 --> 00:00:26.070
Ini adalah rangkaian 12 kata yang dibuat
saat Anda menyiapkan MetaMask pertama kali, yang memungkinkan
8
00:00:26.070 --> 00:00:30.120
Anda memulihkan dompet dan dana jika Anda
kehilangan akses.
9
00:00:30.120 --> 00:00:33.451
Penting agar Anda mengamankan
dompet Anda dengan menjaga
10
00:00:33.451 --> 00:00:37.510
frasa pemulihan rahasia
Anda dengan sangat aman dan sangat rahasia.
11
00:00:37.510 --> 00:00:41.429
Jika seseorang mendapatkan aksesnya, mereka akan memiliki
"kunci induk" ke dompet Anda dan dapat
12
00:00:41.429 --> 00:00:45.190
mengakses secara bebas dan mengambil semua dana Anda.
13
00:00:45.190 --> 00:00:50.109
Untuk mengamankan dompet MetaMask, Anda pasti ingin
menyimpan frasa pemulihan rahasia Anda secara aman.
14
00:00:50.109 --> 00:00:54.930
Anda dapat menuliskannya, menyembunyikannya di suatu tempat,
menempatkannya di kotak deposit yang aman
15
00:00:54.930 --> 00:00:57.729
atau menggunakan pengelola kata sandi yang aman.
16
00:00:57.729 --> 00:01:01.050
Beberapa pengguna bahkan mengukir frasa
mereka pada pelat logam!
17
00:01:01.050 --> 00:01:04.440
Tidak ada seorang pun, bahkan tidak juga tim
di MetaMask, dapat membantu Anda
18
00:01:04.440 --> 00:01:07.820
memulihkan dompet Anda jika Anda menghilangkan
frasa pemulihan rahasia Anda.
19
00:01:07.820 --> 00:01:12.072
Jika belum menuliskan frasa pemulihan rahasia Anda
dan menyimpannya di suatu tempat yang aman,
20
00:01:12.072 --> 00:01:15.492
lakukan sekarang. Kami akan menunggu.
21
00:01:15.500 --> 00:01:20.780
Dan ingat, jangan membagikan frasa pemulihan rahasia
Anda kepada siapa pun: bahkan tidak kepada kami.
22
00:01:20.780 --> 00:01:24.910
Jika ada yang menanyakannya,
mereka akan mencoba menipu Anda.
23
00:01:24.910 --> 00:01:26.250
Begitulah!
24
00:01:26.250 --> 00:01:31.020
Sekarang, Anda tahu apa itu frasa pemulihan rahasia
dan cara menjaga dompet Anda tetap aman.

@ -0,0 +1,115 @@
WEBVTT
1
00:00:00.780 --> 00:00:04.580
MetaMask は
をサイトとアプリケーションにつなぐ新たな方法です。
2
00:00:04.580 --> 00:00:08.860
従来のウェブサイト上では、中央データベース
または銀行がアカウントの制御と
3
00:00:08.860 --> 00:00:10.179
回復の責任を負います。
4
00:00:10.179 --> 00:00:15.050
しかし、MetaMask 上では、全ての権限は
マスターキーの保持者に属します。
5
00:00:15.050 --> 00:00:18.460
当該のキーの保持者が、アカウントを制御します。
6
00:00:18.460 --> 00:00:21.110
あなたのシークレット リカバリー フレーズ
があなたの「マスターキー」です。
7
00:00:21.110 --> 00:00:26.070
これは一連の 12 の単語で
あなたが最初に MetaMask を設定した際に自動生成され、これにより
8
00:00:26.070 --> 00:00:30.120
あなたは万が一アクセス出来なくなった場合に
ウォレットと資金を復元できます。
9
00:00:30.120 --> 00:00:33.451
ウォレットの安全性を確保することは非常に重要
であり、あなたの
10
00:00:33.451 --> 00:00:37.510
シークレット リカバリー フレーズ
を非常に安全かつ秘密に保つことで実現します。
11
00:00:37.510 --> 00:00:41.429
誰かがそれにアクセスすれば、彼らは
あなたのウォレットの「マスターキー」を得て、
12
00:00:41.429 --> 00:00:45.190
あなたの資金に自由にアクセスして全てを奪えます。
13
00:00:45.190 --> 00:00:50.109
MetaMask ウォレットの安全性を確保するため
あなたは シークレット リカバリー フレーズを安全に保存したくなるでしょう。
14
00:00:50.109 --> 00:00:54.930
それを書き留めたり、どこかへ隠したり、
セーフティボックスに入れたり
15
00:00:54.930 --> 00:00:57.729
または安全確保のためのパスワードマネジャーを使用できます。
16
00:00:57.729 --> 00:01:01.050
自分たちの
フレーズをメタルプレートに彫るユーザーさえいます!
17
00:01:01.050 --> 00:01:04.440
何者も、
MetaMask のチームのメンバーですら、あなたが
18
00:01:04.440 --> 00:01:07.820
シークレット リカバリー フレーズを無くしたら
あなたのウォレットを復元する手助けはできません。
19
00:01:07.820 --> 00:01:12.072
あなたがシークレット リカバリー
フレーズを書き留め安全な場所に保管していないのならば、
20
00:01:12.072 --> 00:01:15.492
ぜひ今それを実行してください。お待ちしております。
21
00:01:15.500 --> 00:01:20.780
さらに、あなたのシークレット リカバリー
フレーズを誰とも決して共有しないことを忘れないでください。私たちでさえも。
22
00:01:20.780 --> 00:01:24.910
それを尋ねる者がいたら、
彼らはあなたを騙そうとしているのです。
23
00:01:24.910 --> 00:01:26.250
以上です!
24
00:01:26.250 --> 00:01:31.020
これでシークレット リカバリ フレーズ
が何であるか、あなたのウォレットと資金の安全を確保する方法が判りました。

@ -0,0 +1,115 @@
WEBVTT
1
00:00:00.780 --> 00:00:04.580
MetaMask는 사이트와 애플리케이션에
연결할 수 있는 새로운 방법입니다.
2
00:00:04.580 --> 00:00:08.860
전통적인 웹사이트에서는 중앙 데이터베이스
또는 은행에게 계정을 제어 및
3
00:00:08.860 --> 00:00:10.179
복구할 책임이 있습니다.
4
00:00:10.179 --> 00:00:15.050
하지만 MetaMask에서는 모든 권한이
마스터 키의 소유자에게 있습니다.
5
00:00:15.050 --> 00:00:18.460
키를 보유하고 있는 사람은 계정을 제어합니다.
6
00:00:18.460 --> 00:00:21.110
계정 시드 구문은
"마스터 키"입니다.
7
00:00:21.110 --> 00:00:26.070
먼저 MetaMask를 설정하면, 일련의
12단어가 생성되어,
8
00:00:26.070 --> 00:00:30.120
접근 권한을 상실했을 때 지갑과
자금을 복구할 수 있습니다.
9
00:00:30.120 --> 00:00:33.451
계정 시드 구문을
안전하게 비밀을
10
00:00:33.451 --> 00:00:37.510
유지하여 지갑을 안전하게
지키는 것이 중요합니다.
11
00:00:37.510 --> 00:00:41.429
계정 시드 구문에 액세스하는 사람에게는
지갑에 대한 "마스터 키"가 있어 자유롭게
12
00:00:41.429 --> 00:00:45.190
액세스하여 모든 자금을 가져갈 수 있습니다.
13
00:00:45.190 --> 00:00:50.109
MetaMask 지갑을 안전하게 보호하려면, 계정 시드
구문을 저장할 수 있습니다.
14
00:00:50.109 --> 00:00:54.930
계정 시드 구문을 적어서 어딘가에 숨겨두거나
대여 금고에 두거나
15
00:00:54.930 --> 00:00:57.729
보안 암호 관리자를 사용할 수 있습니다.
16
00:00:57.729 --> 00:01:01.050
일부 사용자는 자신의 구문을
금속판에 새겨두기도 합니다!
17
00:01:01.050 --> 00:01:04.440
계정 시드 구문을 잊으면,
MetaMask의 팀이라고
18
00:01:04.440 --> 00:01:07.820
해도 지갑을
복구할 수 없습니다.
19
00:01:07.820 --> 00:01:12.072
게정 시드 구문을 적어두지
않으면, 안전한 장소에
20
00:01:12.072 --> 00:01:15.492
보관하십시오. 기다리겠습니다.
21
00:01:15.500 --> 00:01:20.780
다른 사람과 계정 시드 구문을
고유하면 안 됩니다. 당사하고도 공유하지 마십시오.
22
00:01:20.780 --> 00:01:24.910
계정 시드 구문을 요청하는 사람은
사기를 치려고 하는 것입니다.
23
00:01:24.910 --> 00:01:26.250
이제 다 됐습니다.
24
00:01:26.250 --> 00:01:31.020
이제 여러분은 계정 시드 구문이 무엇이고
지갑을 안전하게 보관하는 방법을 알고 있습니다.

@ -0,0 +1,115 @@
WEBVTT
1
00:00:00.780 --> 00:00:04.580
O MetaMask é um novo jeito de se conectar
a sites e aplicativos.
2
00:00:04.580 --> 00:00:08.860
Em websites tradicionais, um banco ou base de dados central
é responsável por controlar e
3
00:00:08.860 --> 00:00:10.179
recuperar as suas contas.
4
00:00:10.179 --> 00:00:15.050
Mas, no MetaMask, todo o poder pertence
ao titular de uma chave-mestra.
5
00:00:15.050 --> 00:00:18.460
Quem quer que detenha a chave controla as contas.
6
00:00:18.460 --> 00:00:21.110
A sua frase de recuperação secreta
é a sua "chave-mestra".
7
00:00:21.110 --> 00:00:26.070
É uma série de 12 palavras que são geradas
quando você configura o MetaMask na primeira vez, o que permite que
8
00:00:26.070 --> 00:00:30.120
você recupere a sua carteira e recursos, caso você
venha a perder o acesso.
9
00:00:30.120 --> 00:00:33.451
É importante que você mantenha protegida
a sua carteira ao manter a sua
10
00:00:33.451 --> 00:00:37.510
frase de recuperação secreta
muito segura e muito secreta.
11
00:00:37.510 --> 00:00:41.429
Caso alguém obtenha acesso a ela, essa pessoa terá
a "chave-mestra" para a sua carteira e poderá
12
00:00:41.429 --> 00:00:45.190
acessá-la livremente e tome todos os seus recursos.
13
00:00:45.190 --> 00:00:50.109
A fim de proteger a sua carteira MetaMask, você desejará
manter em segurança a sua frase de recuperação secreta.
14
00:00:50.109 --> 00:00:54.930
Você pode escrevê-la, escondê-la em algum lugar,
colocá-la em um cofre
15
00:00:54.930 --> 00:00:57.729
ou usar um gerenciador de senhas seguras.
16
00:00:57.729 --> 00:01:01.050
Alguns usuários até mesmo gravam sua
frase em uma placa de metal!
17
00:01:01.050 --> 00:01:04.440
Ninguém, nem mesmo a equipe
na MetaMask, pode lhe ajudar
18
00:01:04.440 --> 00:01:07.820
a recuperar a sua carteira, caso você perca
a sua frase de recuperação secreta.
19
00:01:07.820 --> 00:01:12.072
Caso você não tenha escrito a sua frase de recuperação
secreta e a tenha armazenado em algum lugar seguro,
20
00:01:12.072 --> 00:01:15.492
faça isso agora. Iremos aguardar.
21
00:01:15.500 --> 00:01:20.780
E lembre-se de jamais compartilhar a sua frase de recuperação
secreta com ninguém: nem mesmo conosco.
22
00:01:20.780 --> 00:01:24.910
Caso alguém venha a lhe pedir a sua frase de recuperação secreta,
essa pessoa está tentando dar um golpe em você.
23
00:01:24.910 --> 00:01:26.250
É isso!
24
00:01:26.250 --> 00:01:31.020
Agora, você sabe o que é uma frase de recuperação secreta
e como manter a sua carteira protegida e segura.

@ -0,0 +1,115 @@
WEBVTT
1
00:00:00.780 --> 00:00:04.580
MetaMask — это новый способ подключения
к сайтам и приложениям.
2
00:00:04.580 --> 00:00:08.860
На традиционных сайтах центральная база данных
или банк несет ответственность за контроль и
3
00:00:08.860 --> 00:00:10.179
восстановление ваших счетов.
4
00:00:10.179 --> 00:00:15.050
На MetaMask все полномочия находятся
в руках владельца мастер-ключа.
5
00:00:15.050 --> 00:00:18.460
Тот, в чьих руках находится ключ, контролирует счета.
6
00:00:18.460 --> 00:00:21.110
Ваша секретная фраза восстановления
— это ваш «мастер-ключ».
7
00:00:21.110 --> 00:00:26.070
Это набор из 12 слов, которые генерируются
при первой настройке MetaMask, он позволяет
8
00:00:26.070 --> 00:00:30.120
вам восстанавливать ваш кошелек и средства, если вы
теряете к ним доступ.
9
00:00:30.120 --> 00:00:33.451
Важно, чтобы вы обезопасили
свой кошелек, храня вашу
10
00:00:33.451 --> 00:00:37.510
секретную фразу восстановления
в очень надежном и тайном месте.
11
00:00:37.510 --> 00:00:41.429
Если кто-то получит доступ к ней, у этого человека окажется в руках
«мастер-ключ» от вашего кошелька, и он сможет
12
00:00:41.429 --> 00:00:45.190
распоряжаться им и завладеть всеми вашими средствами.
13
00:00:45.190 --> 00:00:50.109
Чтобы обезопасить ваш кошелек MetaMask,
сохраните секретную фразу восстановления в безопасном месте.
14
00:00:50.109 --> 00:00:54.930
Вы можете записать ее, спрятать ее где-то,
положить ее в банковский сейф
15
00:00:54.930 --> 00:00:57.729
или воспользоваться безопасным диспетчером паролей.
16
00:00:57.729 --> 00:01:01.050
Некоторые пользователи даже гравируют свою
фразу на металлической пластине!
17
00:01:01.050 --> 00:01:04.440
Никто, даже команда
MetaMask, не сможет помочь вам
18
00:01:04.440 --> 00:01:07.820
восстановить ваш кошелек, если вы потеряете
вашу секретную фразу восстановления.
19
00:01:07.820 --> 00:01:12.072
Если вы еще не записали секретную фразу
восстановления и не поместили ее в надежное место,
20
00:01:12.072 --> 00:01:15.492
сделайте это сейчас. Мы подождем.
21
00:01:15.500 --> 00:01:20.780
И помните, никогда не сообщайте свою секретную фразу
восстановления никому: даже нам.
22
00:01:20.780 --> 00:01:24.910
Если кто-нибудь когда-либо спросит у вас ее,
этот человек пытается вас обмануть.
23
00:01:24.910 --> 00:01:26.250
Вот и все!
24
00:01:26.250 --> 00:01:31.020
Теперь вы знаете, что такое секретная фраза восстановления
и как обезопасить ваш кошелек.

@ -0,0 +1,115 @@
WEBVTT
1
00:00:00.780 --> 00:00:04.580
Ang MetaMask ay isang bagong paraan para kumonekta
sa mga site at application.
2
00:00:04.580 --> 00:00:08.860
Sa mga tradisyonal na website, ang isang central database
o bangko ang magiging responsable sa pagkontrol at
3
00:00:08.860 --> 00:00:10.179
pag-recover ng iyong mga account.
4
00:00:10.179 --> 00:00:15.050
Pero sa MetaMask, ang lahat ng kakayahan ay nasa
may hawak ng master key.
5
00:00:15.050 --> 00:00:18.460
Kung sino man ang may hawak ng key, siya ang magkokontrol sa mga account.
6
00:00:18.460 --> 00:00:21.110
Ang iyong lihim na recovery phrase
ay ang iyong "master key".
7
00:00:21.110 --> 00:00:26.070
Isa itong 12 salita na nagagawa
sa unang pagkakataong i-set up mo ang MetaMask, na magbibigay-daan sa iyo
8
00:00:26.070 --> 00:00:30.120
na maibalik ang iyong wallet at pera kung sakaling
mawalan ka ng access.
9
00:00:30.120 --> 00:00:33.451
Mahalagang i-secure
ang iyong wallet sa pamamagitan ng pagpapanatiling sobrang ligtas at walang nakakaalam ng iyong
10
00:00:33.451 --> 00:00:37.510
lihim na recovery phrase
.
11
00:00:37.510 --> 00:00:41.429
Kung may ibang taong makaka-access nito, makukuha nila
ang "master key" sa iyong wallet at
12
00:00:41.429 --> 00:00:45.190
madali nilang maa-access at makukuha ang lahat ng pera mo.
13
00:00:45.190 --> 00:00:50.109
Para ma-secure ang iyong MetaMask wallet,
ligtas na i-save ang iyong lihim na recovery phrase.
14
00:00:50.109 --> 00:00:54.930
Puwede mo itong isulat, itago,
ilagay sa isang safe deposit box
15
00:00:54.930 --> 00:00:57.729
o kaya ay gumamit ng ligtas na password manager.
16
00:00:57.729 --> 00:01:01.050
Ang ilang user nga ay inuukit pa ang kanilang
phrase sa isang metal plate!
17
00:01:01.050 --> 00:01:04.440
Walang sinuman, maging ang team
sa MetaMask, ang makakatulong sa iyong
18
00:01:04.440 --> 00:01:07.820
maibalik ang wallet mo kung maiwawala mo
iyong lihim na recovery phrase.
19
00:01:07.820 --> 00:01:12.072
Kung hindi mo pa naisusulat ang iyong lihim na recovery
phrase at hindi pa naitatago sa ligtas na lugar,
20
00:01:12.072 --> 00:01:15.492
gawin mo na ngayon. Hihintayin ka namin.
21
00:01:15.500 --> 00:01:20.780
At tandaan, huwag kailanman ipaalam sa iba ang iyong lihim na recovery
phrase: maging sa amin.
22
00:01:20.780 --> 00:01:24.910
Kung may magtatanong man sa iyo,
sinusubukan ka nilang i-scam.
23
00:01:24.910 --> 00:01:26.250
´Yun lang!
24
00:01:26.250 --> 00:01:31.020
Ngayon ay alam mo na kung ano ang lihim na recovery phrase
at kung paano mapapanatiling ligtas ang iyong wallet.

@ -0,0 +1,115 @@
WEBVTT
1
00:00:00.780 --> 00:00:04.580
MetaMask là cách thức mới để kết nối
với các trang web và ứng dụng.
2
00:00:04.580 --> 00:00:08.860
Trên các trang web truyền thống, một cơ sở dữ liệu trung tâm
hay ngân hàng sẽ chịu trách nhiệm kiểm soát và
3
00:00:08.860 --> 00:00:10.179
khôi phục các tài khoản của bạn.
4
00:00:10.179 --> 00:00:15.050
Tuy nhiên, trên MetaMask, toàn bộ quyền sẽ thuộc về
người nắm giữ khóa chính.
5
00:00:15.050 --> 00:00:18.460
Người có khóa chính sẽ kiểm soát được tài khoản.
6
00:00:18.460 --> 00:00:21.110
Cụm mật khẩu khôi phục bí mật
là “khóa chính” của bạn.
7
00:00:21.110 --> 00:00:26.070
Đây là chuỗi gồm 12 từ được tạo
vào lần đầu tiên bạn thiết lập MetaMask, chuỗi này cho phép
8
00:00:26.070 --> 00:00:30.120
bạn khôi phục ví và tiền của mình nếu
bạn bị mất quyền truy cập.
9
00:00:30.120 --> 00:00:33.451
Bạn cần phải bảo vệ an toàn cho
ví của mình bằng cách lưu giữ
10
00:00:33.451 --> 00:00:37.510
cụm mật khẩu khôi phục bí mật
thật an toàn và bí mật.
11
00:00:37.510 --> 00:00:41.429
Nếu ai đó có được cụm mật khẩu khôi phục bí mật của bạn thì người đó sẽ có
“khóa chính” cho ví của bạn và có thể
12
00:00:41.429 --> 00:00:45.190
tự do truy cập và lấy toàn bộ tiền của bạn.
13
00:00:45.190 --> 00:00:50.109
Để bảo vệ an toàn cho ví MetaMask, bạn cần
lưu giữ cụm mật khẩu khôi phục bí mật một cách an toàn.
14
00:00:50.109 --> 00:00:54.930
Bạn có thể chép lại và giấu ở một nơi nào đó,
cất trong hộp ký gửi an toàn
15
00:00:54.930 --> 00:00:57.729
hoặc dùng một trình quản lý mật khẩu an toàn.
16
00:00:57.729 --> 00:01:01.050
Một số người dùng thậm chí còn khắc
cụm mật khẩu của họ lên một tấm kim loại!
17
00:01:01.050 --> 00:01:04.440
Không một ai, kể cả đội ngũ
tại MetaMask, có thể giúp bạn
18
00:01:04.440 --> 00:01:07.820
khôi phục lại ví nếu bạn đánh mất
cụm mật khẩu khôi phục bí mật của mình.
19
00:01:07.820 --> 00:01:12.072
Nếu chưa ghi lại cụm mật khẩu khôi phục bí mật
của mình và lưu giữ ở nơi an toàn,
20
00:01:12.072 --> 00:01:15.492
thì bạn hãy thực hiện ngay bây giờ. Chúng tôi sẽ chờ bạn.
21
00:01:15.500 --> 00:01:20.780
Và đừng bao giờ chia sẻ cụm mật khẩu khôi phục
bí mật với bất kỳ ai: kể cả chúng tôi.
22
00:01:20.780 --> 00:01:24.910
Nếu ai đó hỏi bạn cụm mật khẩu khôi phục bí mật,
thì họ đang cố gắng lừa đảo bạn.
23
00:01:24.910 --> 00:01:26.250
Xin hãy ghi nhớ!
24
00:01:26.250 --> 00:01:31.020
Bây giờ bạn đã biết cụm mật khẩu khôi phục bí mật
là gì và cách bảo vệ ví của bạn an toàn và bảo mật.

@ -0,0 +1,27 @@
{
"browser_action": {
"default_icon": {
"16": "images/icon-16.png",
"19": "images/icon-19.png",
"32": "images/icon-32.png",
"38": "images/icon-38.png",
"64": "images/icon-64.png",
"128": "images/icon-128.png",
"512": "images/icon-512.png"
},
"default_title": "MetaMask Beta"
},
"icons": {
"16": "images/icon-16.png",
"19": "images/icon-19.png",
"32": "images/icon-32.png",
"38": "images/icon-38.png",
"48": "images/icon-48.png",
"64": "images/icon-64.png",
"128": "images/icon-128.png",
"512": "images/icon-512.png"
},
"name": "__MSG_appName__ Beta",
"short_name": "__MSG_appName__ Beta",
"version": ""
}

@ -3,5 +3,5 @@
"matches": ["https://metamask.io/*"],
"ids": ["*"]
},
"minimum_chrome_version": "63"
"minimum_chrome_version": "66"
}

@ -51,7 +51,7 @@
<a href="https://github.com/metamask/eth-phishing-detect">Ethereum Phishing Detector</a>.
Domains on these warning lists may include outright malicious websites and legitimate websites that have been compromised by a malicious actor.
</p>
<p>To read more about this site <a id="csdbLink">please search for the domain on CryptoScamDB</a>.</p>
<p>To read more about this site <a id="csdbLink" href="https://cryptoscamdb.org/search">please search for the domain on CryptoScamDB</a>.</p>
<p>
Note that this warning list is compiled on a voluntary basis. This list may be inaccurate or incomplete.
Just because a domain does not appear on this list is not an implicit guarantee of that domain's safety.
@ -60,7 +60,7 @@
</p>
<p>
If you think this domain is incorrectly flagged or if a blocked legitimate website has resolved its security issues,
<a href="https://github.com/metamask/eth-phishing-detect/issues/new">please file an issue</a>.
<a id="new-issue-link" href="https://github.com/metamask/eth-phishing-detect/issues/new">please file an issue</a>.
</p>
</div>
</div>

@ -2,9 +2,6 @@
* @file The entry point for the web extension singleton process.
*/
// polyfills
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch';
import endOfStream from 'end-of-stream';
import pump from 'pump';
import debounce from 'debounce-stream';

@ -1,10 +1,9 @@
import Web3 from 'web3';
import contracts from '@metamask/contract-metadata';
import { warn } from 'loglevel';
import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi';
import { MAINNET_CHAIN_ID } from '../../../shared/constants/network';
import { SINGLE_CALL_BALANCES_ADDRESS } from '../constants/contracts';
import { MINUTE } from '../../../shared/constants/time';
import { isEqualCaseInsensitive } from '../../../ui/helpers/utils/util';
// By default, poll every 3 minutes
const DEFAULT_INTERVAL = MINUTE * 3;
@ -24,71 +23,111 @@ export default class DetectTokensController {
preferences,
network,
keyringMemStore,
tokenList,
tokensController,
} = {}) {
this.tokensController = tokensController;
this.preferences = preferences;
this.interval = interval;
this.network = network;
this.keyringMemStore = keyringMemStore;
this.tokenList = tokenList;
this.selectedAddress = this.preferences?.store.getState().selectedAddress;
this.tokenAddresses = this.tokensController?.state.tokens.map((token) => {
return token.address;
});
this.hiddenTokens = this.tokensController?.state.ignoredTokens;
preferences?.store.subscribe(({ selectedAddress, useTokenDetection }) => {
if (
this.selectedAddress !== selectedAddress ||
this.useTokenDetection !== useTokenDetection
) {
this.selectedAddress = selectedAddress;
this.useTokenDetection = useTokenDetection;
this.restartTokenDetection();
}
});
tokensController?.subscribe(({ tokens = [], ignoredTokens = [] }) => {
this.tokenAddresses = tokens.map((token) => {
return token.address;
});
this.hiddenTokens = ignoredTokens;
});
}
async _getTokenBalances(tokens) {
const ethContract = this.web3.eth
.contract(SINGLE_CALL_BALANCES_ABI)
.at(SINGLE_CALL_BALANCES_ADDRESS);
return new Promise((resolve, reject) => {
ethContract.balances([this.selectedAddress], tokens, (error, result) => {
if (error) {
return reject(error);
}
return resolve(result);
});
});
}
/**
* For each token in @metamask/contract-metadata, find check selectedAddress balance.
* For each token in the tokenlist provided by the TokenListController, check selectedAddress balance.
*/
async detectNewTokens() {
if (!this.isActive) {
return;
}
if (this._network.store.getState().provider.chainId !== MAINNET_CHAIN_ID) {
const { tokenList } = this._tokenList.state;
if (Object.keys(tokenList).length === 0) {
return;
}
const tokensToDetect = [];
this.web3.setProvider(this._network._provider);
for (const contractAddress in contracts) {
for (const tokenAddress in tokenList) {
if (
contracts[contractAddress].erc20 &&
!this.tokenAddresses.includes(contractAddress.toLowerCase()) &&
!this.hiddenTokens.includes(contractAddress.toLowerCase())
!this.tokenAddresses.find((address) =>
isEqualCaseInsensitive(address, tokenAddress),
) &&
!this.hiddenTokens.find((address) =>
isEqualCaseInsensitive(address, tokenAddress),
)
) {
tokensToDetect.push(contractAddress);
tokensToDetect.push(tokenAddress);
}
}
let result;
try {
result = await this._getTokenBalances(tokensToDetect);
} catch (error) {
warn(
`MetaMask - DetectTokensController single call balance fetch failed`,
error,
);
return;
}
tokensToDetect.forEach((tokenAddress, index) => {
const balance = result[index];
if (balance && !balance.isZero()) {
this._preferences.addToken(
tokenAddress,
contracts[tokenAddress].symbol,
contracts[tokenAddress].decimals,
const sliceOfTokensToDetect = [
tokensToDetect.slice(0, 1000),
tokensToDetect.slice(1000, tokensToDetect.length - 1),
];
for (const tokensSlice of sliceOfTokensToDetect) {
let result;
try {
result = await this._getTokenBalances(tokensSlice);
} catch (error) {
warn(
`MetaMask - DetectTokensController single call balance fetch failed`,
error,
);
return;
}
});
}
async _getTokenBalances(tokens) {
const ethContract = this.web3.eth
.contract(SINGLE_CALL_BALANCES_ABI)
.at(SINGLE_CALL_BALANCES_ADDRESS);
return new Promise((resolve, reject) => {
ethContract.balances([this.selectedAddress], tokens, (error, result) => {
if (error) {
return reject(error);
}
return resolve(result);
const tokensWithBalance = tokensSlice.filter((_, index) => {
const balance = result[index];
return balance && !balance.isZero();
});
});
await Promise.all(
tokensWithBalance.map((tokenAddress) => {
return this.tokensController.addToken(
tokenAddress,
tokenList[tokenAddress].symbol,
tokenList[tokenAddress].decimals,
);
}),
);
}
}
/**
@ -118,34 +157,6 @@ export default class DetectTokensController {
}, interval);
}
/**
* In setter when selectedAddress is changed, detectNewTokens and restart polling
* @type {Object}
*/
set preferences(preferences) {
if (!preferences) {
return;
}
this._preferences = preferences;
const currentTokens = preferences.store.getState().tokens;
this.tokenAddresses = currentTokens
? currentTokens.map((token) => token.address)
: [];
this.hiddenTokens = preferences.store.getState().hiddenTokens;
preferences.store.subscribe(({ tokens = [], hiddenTokens = [] }) => {
this.tokenAddresses = tokens.map((token) => {
return token.address;
});
this.hiddenTokens = hiddenTokens;
});
preferences.store.subscribe(({ selectedAddress }) => {
if (this.selectedAddress !== selectedAddress) {
this.selectedAddress = selectedAddress;
this.restartTokenDetection();
}
});
}
/**
* @type {Object}
*/
@ -176,6 +187,16 @@ export default class DetectTokensController {
});
}
/**
* @type {Object}
*/
set tokenList(tokenList) {
if (!tokenList) {
return;
}
this._tokenList = tokenList;
}
/**
* Internal isActive state
* @type {Object}

@ -1,17 +1,23 @@
import { strict as assert } from 'assert';
import sinon from 'sinon';
import nock from 'nock';
import { ObservableStore } from '@metamask/obs-store';
import contracts from '@metamask/contract-metadata';
import BigNumber from 'bignumber.js';
import {
ControllerMessenger,
TokenListController,
TokensController,
} from '@metamask/controllers';
import { MAINNET, ROPSTEN } from '../../../shared/constants/network';
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
import DetectTokensController from './detect-tokens';
import NetworkController from './network';
import PreferencesController from './preferences';
describe('DetectTokensController', function () {
let tokenListController;
const sandbox = sinon.createSandbox();
let keyringMemStore, network, preferences, provider;
let keyringMemStore, network, preferences, provider, tokensController;
const noop = () => undefined;
@ -26,6 +32,12 @@ describe('DetectTokensController', function () {
network.initializeProvider(networkControllerProviderConfig);
provider = network.getProviderAndBlockTracker().provider;
preferences = new PreferencesController({ network, provider });
tokensController = new TokensController({
onPreferencesStateChange: preferences.store.subscribe.bind(
preferences.store,
),
onNetworkStateChange: network.store.subscribe.bind(network.store),
});
preferences.setAddresses([
'0x7e57e2',
'0xbc86727e770de68b1060c91f6bb6945c73e10388',
@ -34,8 +46,92 @@ describe('DetectTokensController', function () {
.stub(network, 'getLatestBlock')
.callsFake(() => Promise.resolve({}));
sandbox
.stub(preferences, '_detectIsERC721')
.stub(tokensController, '_instantiateNewEthersProvider')
.returns(null);
sandbox
.stub(tokensController, '_detectIsERC721')
.returns(Promise.resolve(false));
nock('https://token-api.metaswap.codefi.network')
.get(`/tokens/1`)
.reply(200, [
{
address: '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f',
symbol: 'SNX',
decimals: 18,
occurrences: 11,
aggregators: [
'paraswap',
'pmm',
'airswapLight',
'zeroEx',
'bancor',
'coinGecko',
'zapper',
'kleros',
'zerion',
'cmc',
'oneInch',
],
name: 'Synthetix',
iconUrl: 'https://airswap-token-images.s3.amazonaws.com/SNX.png',
},
{
address: '0x514910771af9ca656af840dff83e8264ecf986ca',
symbol: 'LINK',
decimals: 18,
occurrences: 11,
aggregators: [
'paraswap',
'pmm',
'airswapLight',
'zeroEx',
'bancor',
'coinGecko',
'zapper',
'kleros',
'zerion',
'cmc',
'oneInch',
],
name: 'Chainlink',
iconUrl: 'https://s3.amazonaws.com/airswap-token-images/LINK.png',
},
{
address: '0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c',
symbol: 'BNT',
decimals: 18,
occurrences: 11,
aggregators: [
'paraswap',
'pmm',
'airswapLight',
'zeroEx',
'bancor',
'coinGecko',
'zapper',
'kleros',
'zerion',
'cmc',
'oneInch',
],
name: 'Bancor',
iconUrl: 'https://s3.amazonaws.com/airswap-token-images/BNT.png',
},
])
.get(`/tokens/3`)
.reply(200, { error: 'ChainId 3 is not supported' })
.persist();
const tokenListMessenger = new ControllerMessenger().getRestricted({
name: 'TokenListController',
});
tokenListController = new TokenListController({
chainId: '1',
useStaticTokenList: false,
onNetworkStateChange: sinon.spy(),
onPreferencesStateChange: sinon.spy(),
messenger: tokenListMessenger,
});
await tokenListController.start();
});
after(function () {
@ -56,6 +152,8 @@ describe('DetectTokensController', function () {
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
});
controller.isOpen = true;
controller.isUnlocked = true;
@ -75,10 +173,23 @@ describe('DetectTokensController', function () {
it('should not check tokens while on test network', async function () {
sandbox.useFakeTimers();
network.setProviderType(ROPSTEN);
const tokenListMessengerRopsten = new ControllerMessenger().getRestricted({
name: 'TokenListController',
});
tokenListController = new TokenListController({
chainId: '3',
useStaticTokenList: false,
onNetworkStateChange: sinon.spy(),
onPreferencesStateChange: sinon.spy(),
messenger: tokenListMessengerRopsten,
});
await tokenListController.start();
const controller = new DetectTokensController({
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
});
controller.isOpen = true;
controller.isUnlocked = true;
@ -96,24 +207,30 @@ describe('DetectTokensController', function () {
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
});
controller.isOpen = true;
controller.isUnlocked = true;
const contractAddresses = Object.keys(contracts);
const erc20ContractAddresses = contractAddresses.filter(
(contractAddress) => contracts[contractAddress].erc20 === true,
);
const { tokenList } = tokenListController.state;
const erc20ContractAddresses = Object.keys(tokenList);
const existingTokenAddress = erc20ContractAddresses[0];
const existingToken = contracts[existingTokenAddress];
await preferences.addToken(
const existingToken = tokenList[existingTokenAddress];
await tokensController.addToken(
existingTokenAddress,
existingToken.symbol,
existingToken.decimals,
);
const tokenAddressToSkip = erc20ContractAddresses[1];
const tokenToSkip = tokenList[tokenAddressToSkip];
await tokensController.addToken(
tokenAddressToSkip,
tokenToSkip.symbol,
tokenToSkip.decimals,
);
sandbox
.stub(controller, '_getTokenBalances')
@ -123,15 +240,15 @@ describe('DetectTokensController', function () {
),
);
await preferences.removeToken(tokenAddressToSkip);
await tokensController.removeAndIgnoreToken(tokenAddressToSkip);
await controller.detectNewTokens();
assert.deepEqual(preferences.store.getState().tokens, [
assert.deepEqual(tokensController.state.tokens, [
{
address: existingTokenAddress.toLowerCase(),
address: toChecksumHexAddress(existingTokenAddress),
decimals: existingToken.decimals,
symbol: existingToken.symbol,
image: undefined,
isERC721: false,
},
]);
@ -144,34 +261,34 @@ describe('DetectTokensController', function () {
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
});
controller.isOpen = true;
controller.isUnlocked = true;
const contractAddresses = Object.keys(contracts);
const erc20ContractAddresses = contractAddresses.filter(
(contractAddress) => contracts[contractAddress].erc20 === true,
);
const { tokenList } = tokenListController.state;
const erc20ContractAddresses = Object.keys(tokenList);
const existingTokenAddress = erc20ContractAddresses[0];
const existingToken = contracts[existingTokenAddress];
await preferences.addToken(
const existingToken = tokenList[existingTokenAddress];
await tokensController.addToken(
existingTokenAddress,
existingToken.symbol,
existingToken.decimals,
);
const tokenAddressToAdd = erc20ContractAddresses[1];
const tokenToAdd = contracts[tokenAddressToAdd];
const tokenToAdd = tokenList[tokenAddressToAdd];
const contractAddresssesToDetect = contractAddresses.filter(
const contractAddressesToDetect = erc20ContractAddresses.filter(
(address) => address !== existingTokenAddress,
);
const indexOfTokenToAdd = contractAddresssesToDetect.indexOf(
const indexOfTokenToAdd = contractAddressesToDetect.indexOf(
tokenAddressToAdd,
);
const balances = new Array(contractAddressesToDetect.length);
const balances = new Array(contractAddresssesToDetect.length);
balances[indexOfTokenToAdd] = new BigNumber(10);
sandbox
@ -179,18 +296,19 @@ describe('DetectTokensController', function () {
.returns(Promise.resolve(balances));
await controller.detectNewTokens();
assert.deepEqual(preferences.store.getState().tokens, [
assert.deepEqual(tokensController.state.tokens, [
{
address: existingTokenAddress.toLowerCase(),
address: toChecksumHexAddress(existingTokenAddress),
decimals: existingToken.decimals,
symbol: existingToken.symbol,
isERC721: false,
image: undefined,
},
{
address: tokenAddressToAdd.toLowerCase(),
address: toChecksumHexAddress(tokenAddressToAdd),
decimals: tokenToAdd.decimals,
symbol: tokenToAdd.symbol,
image: undefined,
isERC721: false,
},
]);
@ -203,34 +321,34 @@ describe('DetectTokensController', function () {
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
});
controller.isOpen = true;
controller.isUnlocked = true;
const contractAddresses = Object.keys(contracts);
const erc20ContractAddresses = contractAddresses.filter(
(contractAddress) => contracts[contractAddress].erc20 === true,
);
const { tokenList } = tokenListController.state;
const erc20ContractAddresses = Object.keys(tokenList);
const existingTokenAddress = erc20ContractAddresses[0];
const existingToken = contracts[existingTokenAddress];
await preferences.addToken(
const existingToken = tokenList[existingTokenAddress];
await tokensController.addToken(
existingTokenAddress,
existingToken.symbol,
existingToken.decimals,
);
const tokenAddressToAdd = erc20ContractAddresses[1];
const tokenToAdd = contracts[tokenAddressToAdd];
const tokenToAdd = tokenList[tokenAddressToAdd];
const contractAddresssesToDetect = contractAddresses.filter(
const contractAddressesToDetect = erc20ContractAddresses.filter(
(address) => address !== existingTokenAddress,
);
const indexOfTokenToAdd = contractAddresssesToDetect.indexOf(
const indexOfTokenToAdd = contractAddressesToDetect.indexOf(
tokenAddressToAdd,
);
const balances = new Array(contractAddresssesToDetect.length);
const balances = new Array(contractAddressesToDetect.length);
balances[indexOfTokenToAdd] = new BigNumber(10);
sandbox
@ -239,17 +357,19 @@ describe('DetectTokensController', function () {
await controller.detectNewTokens();
assert.deepEqual(preferences.store.getState().tokens, [
assert.deepEqual(tokensController.state.tokens, [
{
address: existingTokenAddress.toLowerCase(),
address: toChecksumHexAddress(existingTokenAddress),
decimals: existingToken.decimals,
symbol: existingToken.symbol,
image: undefined,
isERC721: false,
},
{
address: tokenAddressToAdd.toLowerCase(),
address: toChecksumHexAddress(tokenAddressToAdd),
decimals: tokenToAdd.decimals,
symbol: tokenToAdd.symbol,
image: undefined,
isERC721: false,
},
]);
@ -261,6 +381,8 @@ describe('DetectTokensController', function () {
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
});
controller.isOpen = true;
controller.isUnlocked = true;
@ -277,6 +399,8 @@ describe('DetectTokensController', function () {
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
});
controller.isOpen = true;
controller.selectedAddress = '0x0';
@ -292,6 +416,8 @@ describe('DetectTokensController', function () {
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
});
controller.isOpen = true;
controller.isUnlocked = false;
@ -307,6 +433,7 @@ describe('DetectTokensController', function () {
preferences,
network,
keyringMemStore,
tokensController,
});
// trigger state update from preferences controller
await preferences.setSelectedAddress(

@ -1,5 +1,8 @@
import { strict as assert } from 'assert';
import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction';
import {
TRANSACTION_STATUSES,
TRANSACTION_TYPES,
} from '../../../../shared/constants/transaction';
import { formatTxMetaForRpcResult } from './util';
describe('network utils', function () {
@ -16,7 +19,7 @@ describe('network utils', function () {
gas: '0x7b0d',
nonce: '0x4b',
},
type: 'sentEther',
type: TRANSACTION_TYPES.SIMPLE_SEND,
origin: 'other',
chainId: '0x3',
time: 1624408066355,
@ -63,7 +66,7 @@ describe('network utils', function () {
gas: '0x7b0d',
nonce: '0x4b',
},
type: 'sentEther',
type: TRANSACTION_TYPES.SIMPLE_SEND,
origin: 'other',
chainId: '0x3',
time: 1624408066355,

@ -40,6 +40,7 @@ export const SAFE_METHODS = [
'eth_coinbase',
'eth_decrypt',
'eth_estimateGas',
'eth_feeHistory',
'eth_gasPrice',
'eth_getBalance',
'eth_getBlockByHash',

@ -1,22 +1,12 @@
import { strict as assert } from 'assert';
import { ObservableStore } from '@metamask/obs-store';
import { ethErrors } from 'eth-rpc-errors';
import { normalize as normalizeAddress } from 'eth-sig-util';
import { ethers } from 'ethers';
import log from 'loglevel';
import abiERC721 from 'human-standard-collectible-abi';
import contractsMap from '@metamask/contract-metadata';
import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens';
import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network';
import { isPrefixedFormattedHexString } from '../../../shared/modules/network.utils';
import {
isValidHexAddress,
toChecksumHexAddress,
} from '../../../shared/modules/hexstring-utils';
import { NETWORK_EVENTS } from './network';
const ERC721_INTERFACE_ID = '0x80ac58cd';
export default class PreferencesController {
/**
*
@ -24,9 +14,6 @@ export default class PreferencesController {
* @param {Object} opts - Overrides the defaults for the initial state of this.store
* @property {Object} store The stored object containing a users preferences, stored in local storage
* @property {Array} store.frequentRpcList A list of custom rpcs to provide the user
* @property {Array} store.tokens The tokens the user wants display in their token lists
* @property {Object} store.accountTokens The tokens stored per account and then per network type
* @property {Object} store.assetImages Contains assets objects related to assets added
* @property {boolean} store.useBlockie The users preference for blockie identicons within the UI
* @property {boolean} store.useNonceField The users preference for nonce field within the UI
* @property {Object} store.featureFlags A key-boolean map, where keys refer to features and booleans to whether the
@ -41,17 +28,14 @@ export default class PreferencesController {
constructor(opts = {}) {
const initState = {
frequentRpcListDetail: [],
accountTokens: {},
accountHiddenTokens: {},
assetImages: {},
tokens: [],
hiddenTokens: [],
suggestedTokens: {},
useBlockie: false,
useNonceField: false,
usePhishDetect: true,
dismissSeedBackUpReminder: false,
useStaticTokenList: false,
// set to true means the dynamic list from the API is being used
// set to false will be using the static list from contract-metadata
useTokenDetection: false,
// WARNING: Do not use feature flags for security-sensitive things.
// Feature flag toggling is available in the global namespace
@ -87,12 +71,6 @@ export default class PreferencesController {
this.openPopup = opts.openPopup;
this.migrateAddressBookState = opts.migrateAddressBookState;
this.network.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => {
const { tokens, hiddenTokens } = this._getTokenRelatedStates();
this.ethersProvider = new ethers.providers.Web3Provider(opts.provider);
this._updateAccountTokens(tokens, this.getAssetImages(), hiddenTokens);
});
this._subscribeToInfuraAvailability();
global.setPreference = (key, value) => {
@ -140,13 +118,13 @@ export default class PreferencesController {
}
/**
* Setter for the `useStaticTokenList` property
* Setter for the `useTokenDetection` property
*
* @param {boolean} val - Whether or not the user prefers to use the static token list or dynamic token list from the API
*
*/
setUseStaticTokenList(val) {
this.store.updateState({ useStaticTokenList: val });
setUseTokenDetection(val) {
this.store.updateState({ useTokenDetection: val });
}
/**
@ -159,14 +137,6 @@ export default class PreferencesController {
this.store.updateState({ firstTimeFlowType: type });
}
getSuggestedTokens() {
return this.store.getState().suggestedTokens;
}
getAssetImages() {
return this.store.getState().assetImages;
}
/**
* Add new methodData to state, to avoid requesting this information again through Infura
*
@ -179,24 +149,6 @@ export default class PreferencesController {
this.store.updateState({ knownMethodData });
}
/**
* wallet_watchAsset request handler.
*
* @param {Object} req - The watchAsset JSON-RPC request object.
*/
async requestWatchAsset(req) {
const { type, options } = req.params;
switch (type) {
case 'ERC20':
return await this._handleWatchAssetERC20(options);
default:
throw ethErrors.rpc.invalidParams(
`Asset of type "${type}" not supported.`,
);
}
}
/**
* Setter for the `currentLocale` property
*
@ -223,25 +175,14 @@ export default class PreferencesController {
*/
setAddresses(addresses) {
const oldIdentities = this.store.getState().identities;
const oldAccountTokens = this.store.getState().accountTokens;
const oldAccountHiddenTokens = this.store.getState().accountHiddenTokens;
const identities = addresses.reduce((ids, address, index) => {
const oldId = oldIdentities[address] || {};
ids[address] = { name: `Account ${index + 1}`, address, ...oldId };
return ids;
}, {});
const accountTokens = addresses.reduce((tokens, address) => {
const oldTokens = oldAccountTokens[address] || {};
tokens[address] = oldTokens;
return tokens;
}, {});
const accountHiddenTokens = addresses.reduce((hiddenTokens, address) => {
const oldHiddenTokens = oldAccountHiddenTokens[address] || {};
hiddenTokens[address] = oldHiddenTokens;
return hiddenTokens;
}, {});
this.store.updateState({ identities, accountTokens, accountHiddenTokens });
this.store.updateState({ identities });
}
/**
@ -251,19 +192,13 @@ export default class PreferencesController {
* @returns {string} the address that was removed
*/
removeAddress(address) {
const {
identities,
accountTokens,
accountHiddenTokens,
} = this.store.getState();
const { identities } = this.store.getState();
if (!identities[address]) {
throw new Error(`${address} can't be deleted cause it was not found`);
}
delete identities[address];
delete accountTokens[address];
delete accountHiddenTokens[address];
this.store.updateState({ identities, accountTokens, accountHiddenTokens });
this.store.updateState({ identities });
// If the selected account is no longer valid,
// select an arbitrary other account:
@ -281,11 +216,7 @@ export default class PreferencesController {
*
*/
addAddresses(addresses) {
const {
identities,
accountTokens,
accountHiddenTokens,
} = this.store.getState();
const { identities } = this.store.getState();
addresses.forEach((address) => {
// skip if already exists
if (identities[address]) {
@ -294,11 +225,9 @@ export default class PreferencesController {
// add missing identity
const identityCount = Object.keys(identities).length;
accountTokens[address] = {};
accountHiddenTokens[address] = {};
identities[address] = { name: `Account ${identityCount + 1}`, address };
});
this.store.updateState({ identities, accountTokens, accountHiddenTokens });
this.store.updateState({ identities });
}
/**
@ -345,25 +274,16 @@ export default class PreferencesController {
return selected;
}
removeSuggestedTokens() {
return new Promise((resolve) => {
this.store.updateState({ suggestedTokens: {} });
resolve({});
});
}
/**
* Setter for the `selectedAddress` property
*
* @param {string} _address - A new hex address for an account
* @returns {Promise<void>} Promise resolves with tokens
*
*/
setSelectedAddress(_address) {
const address = normalizeAddress(_address);
this._updateTokens(address);
const { identities, tokens } = this.store.getState();
const { identities } = this.store.getState();
const selectedIdentity = identities[address];
if (!selectedIdentity) {
throw new Error(`Identity for '${address} not found`);
@ -371,7 +291,6 @@ export default class PreferencesController {
selectedIdentity.lastSelected = Date.now();
this.store.updateState({ identities, selectedAddress: address });
return Promise.resolve(tokens);
}
/**
@ -384,99 +303,6 @@ export default class PreferencesController {
return this.store.getState().selectedAddress;
}
/**
* Contains data about tokens users add to their account.
* @typedef {Object} AddedToken
* @property {string} address - The hex address for the token contract. Will be all lower cased and hex-prefixed.
* @property {string} symbol - The symbol of the token, usually 3 or 4 capitalized letters
* {@link https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#symbol}
* @property {boolean} decimals - The number of decimals the token uses.
* {@link https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#decimals}
*/
/**
* Adds a new token to the token array and removes it from the hiddenToken array, or updates the token if passed an address that already exists.
* Modifies the existing tokens array from the store. All objects in the tokens array array AddedToken objects.
* @see AddedToken {@link AddedToken}
*
* @param {string} rawAddress - Hex address of the token contract. May or may not be a checksum address.
* @param {string} symbol - The symbol of the token
* @param {number} decimals - The number of decimals the token uses.
* @returns {Promise<array>} Promises the new array of AddedToken objects.
*
*/
async addToken(rawAddress, symbol, decimals, image) {
const address = normalizeAddress(rawAddress);
const newEntry = { address, symbol, decimals: Number(decimals) };
const { tokens, hiddenTokens } = this.store.getState();
const assetImages = this.getAssetImages();
const updatedHiddenTokens = hiddenTokens.filter(
(tokenAddress) => tokenAddress !== rawAddress.toLowerCase(),
);
const previousEntry = tokens.find((token) => {
return token.address === address;
});
const previousIndex = tokens.indexOf(previousEntry);
newEntry.isERC721 = await this._detectIsERC721(newEntry.address);
if (previousEntry) {
tokens[previousIndex] = newEntry;
} else {
tokens.push(newEntry);
}
assetImages[address] = image;
this._updateAccountTokens(tokens, assetImages, updatedHiddenTokens);
return Promise.resolve(tokens);
}
/**
* Adds isERC721 field to token object
* (Called when a user attempts to add tokens that were previously added which do not yet had isERC721 field)
*
* @param {string} tokenAddress - The contract address of the token requiring the isERC721 field added.
* @returns {Promise<object>} The new token object with the added isERC721 field.
*
*/
async updateTokenType(tokenAddress) {
const { tokens } = this.store.getState();
const tokenIndex = tokens.findIndex((token) => {
return token.address === tokenAddress;
});
tokens[tokenIndex].isERC721 = await this._detectIsERC721(tokenAddress);
this.store.updateState({ tokens });
return Promise.resolve(tokens[tokenIndex]);
}
/**
* Removes a specified token from the tokens array and adds it to hiddenTokens array
*
* @param {string} rawAddress - Hex address of the token contract to remove.
* @returns {Promise<array>} The new array of AddedToken objects
*
*/
removeToken(rawAddress) {
const { tokens, hiddenTokens } = this.store.getState();
const assetImages = this.getAssetImages();
const updatedTokens = tokens.filter(
(token) => token.address !== rawAddress,
);
const updatedHiddenTokens = [...hiddenTokens, rawAddress.toLowerCase()];
delete assetImages[rawAddress];
this._updateAccountTokens(updatedTokens, assetImages, updatedHiddenTokens);
return Promise.resolve(updatedTokens);
}
/**
* A getter for the `tokens` property
*
* @returns {Array} The current array of AddedToken objects
*
*/
getTokens() {
return this.store.getState().tokens;
}
/**
* Sets a custom label for an account
* @param {string} account - the account to set a label for
@ -767,189 +593,4 @@ export default class PreferencesController {
this.store.updateState({ infuraBlocked: isBlocked });
}
/**
* Updates `accountTokens`, `tokens`, `accountHiddenTokens` and `hiddenTokens` of current account and network according to it.
*
* @param {array} tokens - Array of tokens to be updated.
* @param {array} assetImages - Array of assets objects related to assets added
* @param {array} hiddenTokens - Array of tokens hidden by user
*
*/
_updateAccountTokens(tokens, assetImages, hiddenTokens) {
const {
accountTokens,
chainId,
selectedAddress,
accountHiddenTokens,
} = this._getTokenRelatedStates();
accountTokens[selectedAddress][chainId] = tokens;
accountHiddenTokens[selectedAddress][chainId] = hiddenTokens;
this.store.updateState({
accountTokens,
tokens,
assetImages,
accountHiddenTokens,
hiddenTokens,
});
}
/**
* Detects whether or not a token is ERC-721 compatible.
*
* @param {string} tokensAddress - the token contract address.
*
*/
async _detectIsERC721(tokenAddress) {
const checksumAddress = toChecksumHexAddress(tokenAddress);
// if this token is already in our contract metadata map we don't need
// to check against the contract
if (contractsMap[checksumAddress]?.erc721 === true) {
return Promise.resolve(true);
}
const tokenContract = await this._createEthersContract(
tokenAddress,
abiERC721,
this.ethersProvider,
);
return await tokenContract
.supportsInterface(ERC721_INTERFACE_ID)
.catch((error) => {
console.log('error', error);
log.debug(error);
return false;
});
}
async _createEthersContract(tokenAddress, abi, ethersProvider) {
const tokenContract = await new ethers.Contract(
tokenAddress,
abi,
ethersProvider,
);
return tokenContract;
}
/**
* Updates `tokens` and `hiddenTokens` of current account and network.
*
* @param {string} selectedAddress - Account address to be updated with.
*
*/
_updateTokens(selectedAddress) {
const { tokens, hiddenTokens } = this._getTokenRelatedStates(
selectedAddress,
);
this.store.updateState({ tokens, hiddenTokens });
}
/**
* A getter for `tokens`, `accountTokens`, `hiddenTokens` and `accountHiddenTokens` related states.
*
* @param {string} [selectedAddress] - A new hex address for an account
* @returns {Object.<array, object, string, string>} States to interact with tokens in `accountTokens`
*
*/
_getTokenRelatedStates(selectedAddress) {
const { accountTokens, accountHiddenTokens } = this.store.getState();
if (!selectedAddress) {
// eslint-disable-next-line no-param-reassign
selectedAddress = this.store.getState().selectedAddress;
}
const chainId = this.network.getCurrentChainId();
if (!(selectedAddress in accountTokens)) {
accountTokens[selectedAddress] = {};
}
if (!(selectedAddress in accountHiddenTokens)) {
accountHiddenTokens[selectedAddress] = {};
}
if (!(chainId in accountTokens[selectedAddress])) {
accountTokens[selectedAddress][chainId] = [];
}
if (!(chainId in accountHiddenTokens[selectedAddress])) {
accountHiddenTokens[selectedAddress][chainId] = [];
}
const tokens = accountTokens[selectedAddress][chainId];
const hiddenTokens = accountHiddenTokens[selectedAddress][chainId];
return {
tokens,
accountTokens,
hiddenTokens,
accountHiddenTokens,
chainId,
selectedAddress,
};
}
/**
* Handle the suggestion of an ERC20 asset through `watchAsset`
* *
* @param {Object} tokenMetadata - Token metadata
*
*/
async _handleWatchAssetERC20(tokenMetadata) {
this._validateERC20AssetParams(tokenMetadata);
const address = normalizeAddress(tokenMetadata.address);
const { symbol, decimals, image } = tokenMetadata;
this._addSuggestedERC20Asset(address, symbol, decimals, image);
await this.openPopup();
const tokenAddresses = this.getTokens().filter(
(token) => token.address === address,
);
return tokenAddresses.length > 0;
}
/**
* Validates that the passed options for suggested token have all required properties.
*
* @param {Object} opts - The options object to validate
* @throws {string} Throw a custom error indicating that address, symbol and/or decimals
* doesn't fulfill requirements
*
*/
_validateERC20AssetParams({ address, symbol, decimals }) {
if (!address || !symbol || typeof decimals === 'undefined') {
throw ethErrors.rpc.invalidParams(
`Must specify address, symbol, and decimals.`,
);
}
if (typeof symbol !== 'string') {
throw ethErrors.rpc.invalidParams(`Invalid symbol: not a string.`);
}
if (!(symbol.length > 0)) {
throw ethErrors.rpc.invalidParams(
`Invalid symbol "${symbol}": shorter than a character.`,
);
}
if (!(symbol.length < 12)) {
throw ethErrors.rpc.invalidParams(
`Invalid symbol "${symbol}": longer than 11 characters.`,
);
}
const numDecimals = parseInt(decimals, 10);
if (isNaN(numDecimals) || numDecimals > 36 || numDecimals < 0) {
throw ethErrors.rpc.invalidParams(
`Invalid decimals "${decimals}": must be 0 <= 36.`,
);
}
if (!isValidHexAddress(address, { allowNonPrefixed: false })) {
throw ethErrors.rpc.invalidParams(`Invalid address "${address}".`);
}
}
_addSuggestedERC20Asset(address, symbol, decimals, image) {
const newEntry = {
address,
symbol,
decimals,
image,
unlisted: !LISTED_CONTRACT_ADDRESSES.includes(address),
};
const suggested = this.getSuggestedTokens();
suggested[address] = newEntry;
this.store.updateState({ suggestedTokens: suggested });
}
}

@ -1,11 +1,6 @@
import { strict as assert } from 'assert';
import sinon from 'sinon';
import contractMaps from '@metamask/contract-metadata';
import abiERC721 from 'human-standard-collectible-abi';
import {
MAINNET_CHAIN_ID,
RINKEBY_CHAIN_ID,
} from '../../../shared/constants/network';
import { MAINNET_CHAIN_ID } from '../../../shared/constants/network';
import PreferencesController from './preferences';
import NetworkController from './network';
@ -13,9 +8,6 @@ describe('preferences controller', function () {
let preferencesController;
let network;
let currentChainId;
let triggerNetworkChange;
let switchToMainnet;
let switchToRinkeby;
let provider;
const migrateAddressBookState = sinon.stub();
@ -37,22 +29,12 @@ describe('preferences controller', function () {
sandbox
.stub(network, 'getProviderConfig')
.callsFake(() => ({ type: 'mainnet' }));
const spy = sandbox.spy(network, 'on');
preferencesController = new PreferencesController({
migrateAddressBookState,
network,
provider,
});
triggerNetworkChange = spy.firstCall.args[1];
switchToMainnet = () => {
currentChainId = MAINNET_CHAIN_ID;
triggerNetworkChange();
};
switchToRinkeby = () => {
currentChainId = RINKEBY_CHAIN_ID;
triggerNetworkChange();
};
});
afterEach(function () {
@ -76,17 +58,6 @@ describe('preferences controller', function () {
});
});
it('should create account tokens for each account in the store', function () {
preferencesController.setAddresses(['0xda22le', '0x7e57e2']);
const { accountTokens } = preferencesController.store.getState();
assert.deepEqual(accountTokens, {
'0xda22le': {},
'0x7e57e2': {},
});
});
it('should replace its list of addresses', function () {
preferencesController.setAddresses(['0xda22le', '0x7e57e2']);
preferencesController.setAddresses(['0xda22le77', '0x7e57e277']);
@ -105,104 +76,6 @@ describe('preferences controller', function () {
});
});
describe('updateTokenType', function () {
it('should add isERC721 = true to token object in state when token is collectible and in our contract-metadata repo', async function () {
const contractAddresses = Object.keys(contractMaps);
const erc721ContractAddresses = contractAddresses.filter(
(contractAddress) => contractMaps[contractAddress].erc721 === true,
);
const address = erc721ContractAddresses[0];
const { symbol, decimals } = contractMaps[address];
preferencesController.store.updateState({
tokens: [{ address, symbol, decimals }],
});
const result = await preferencesController.updateTokenType(address);
assert.equal(result.isERC721, true);
});
it('should add isERC721 = true to token object in state when token is collectible and not in our contract-metadata repo', async function () {
const tokenAddress = '0xda5584cc586d07c7141aa427224a4bd58e64af7d';
preferencesController.store.updateState({
tokens: [
{
address: tokenAddress,
symbol: 'TESTNFT',
decimals: '0',
},
],
});
sinon
.stub(preferencesController, '_detectIsERC721')
.callsFake(() => true);
const result = await preferencesController.updateTokenType(tokenAddress);
assert.equal(
preferencesController._detectIsERC721.getCall(0).args[0],
tokenAddress,
);
assert.equal(result.isERC721, true);
});
});
describe('_detectIsERC721', function () {
it('should return true when token is in our contract-metadata repo', async function () {
const tokenAddress = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d';
const result = await preferencesController._detectIsERC721(tokenAddress);
assert.equal(result, true);
});
it('should return true when the token is not in our contract-metadata repo but tokenContract.supportsInterface returns true', async function () {
const tokenAddress = '0xda5584cc586d07c7141aa427224a4bd58e64af7d';
const supportsInterfaceStub = sinon.stub().returns(Promise.resolve(true));
sinon
.stub(preferencesController, '_createEthersContract')
.callsFake(() => ({ supportsInterface: supportsInterfaceStub }));
const result = await preferencesController._detectIsERC721(tokenAddress);
assert.equal(
preferencesController._createEthersContract.getCall(0).args[0],
tokenAddress,
);
assert.deepEqual(
preferencesController._createEthersContract.getCall(0).args[1],
abiERC721,
);
assert.equal(
preferencesController._createEthersContract.getCall(0).args[2],
preferencesController.ethersProvider,
);
assert.equal(result, true);
});
it('should return false when the token is not in our contract-metadata repo and tokenContract.supportsInterface returns false', async function () {
const tokenAddress = '0xda5584cc586d07c7141aa427224a4bd58e64af7d';
const supportsInterfaceStub = sinon
.stub()
.returns(Promise.resolve(false));
sinon
.stub(preferencesController, '_createEthersContract')
.callsFake(() => ({ supportsInterface: supportsInterfaceStub }));
const result = await preferencesController._detectIsERC721(tokenAddress);
assert.equal(
preferencesController._createEthersContract.getCall(0).args[0],
tokenAddress,
);
assert.deepEqual(
preferencesController._createEthersContract.getCall(0).args[1],
abiERC721,
);
assert.equal(
preferencesController._createEthersContract.getCall(0).args[2],
preferencesController.ethersProvider,
);
assert.equal(result, false);
});
});
describe('removeAddress', function () {
it('should remove an address from state', function () {
preferencesController.setAddresses(['0xda22le', '0x7e57e2']);
@ -215,17 +88,6 @@ describe('preferences controller', function () {
);
});
it('should remove an address from state and respective tokens', function () {
preferencesController.setAddresses(['0xda22le', '0x7e57e2']);
preferencesController.removeAddress('0xda22le');
assert.equal(
preferencesController.store.getState().accountTokens['0xda22le'],
undefined,
);
});
it('should switch accounts if the selected address is removed', function () {
preferencesController.setAddresses(['0xda22le', '0x7e57e2']);
@ -259,489 +121,6 @@ describe('preferences controller', function () {
});
});
describe('getTokens', function () {
it('should return an empty list initially', async function () {
preferencesController.setAddresses(['0x7e57e2']);
await preferencesController.setSelectedAddress('0x7e57e2');
const tokens = preferencesController.getTokens();
assert.equal(tokens.length, 0, 'empty list of tokens');
});
});
describe('addToken', function () {
it('should add that token to its state', async function () {
const address = '0xabcdef1234567';
const symbol = 'ABBR';
const decimals = 5;
preferencesController.setAddresses(['0x7e57e2']);
await preferencesController.setSelectedAddress('0x7e57e2');
await preferencesController.addToken(address, symbol, decimals);
const tokens = preferencesController.getTokens();
assert.equal(tokens.length, 1, 'one token added');
const added = tokens[0];
assert.equal(added.address, address, 'set address correctly');
assert.equal(added.symbol, symbol, 'set symbol correctly');
assert.equal(added.decimals, decimals, 'set decimals correctly');
});
it('should allow updating a token value', async function () {
const address = '0xabcdef1234567';
const symbol = 'ABBR';
const decimals = 5;
preferencesController.setAddresses(['0x7e57e2']);
await preferencesController.setSelectedAddress('0x7e57e2');
await preferencesController.addToken(address, symbol, decimals);
const newDecimals = 6;
await preferencesController.addToken(address, symbol, newDecimals);
const tokens = preferencesController.getTokens();
assert.equal(tokens.length, 1, 'one token added');
const added = tokens[0];
assert.equal(added.address, address, 'set address correctly');
assert.equal(added.symbol, symbol, 'set symbol correctly');
assert.equal(added.decimals, newDecimals, 'updated decimals correctly');
});
it('should allow adding tokens to two separate addresses', async function () {
const address = '0xabcdef1234567';
const symbol = 'ABBR';
const decimals = 5;
preferencesController.setAddresses(['0x7e57e2', '0xda22le']);
await preferencesController.setSelectedAddress('0x7e57e2');
await preferencesController.addToken(address, symbol, decimals);
assert.equal(
preferencesController.getTokens().length,
1,
'one token added for 1st address',
);
await preferencesController.setSelectedAddress('0xda22le');
await preferencesController.addToken(address, symbol, decimals);
assert.equal(
preferencesController.getTokens().length,
1,
'one token added for 2nd address',
);
});
it('should add token per account', async function () {
const addressFirst = '0xabcdef1234567';
const addressSecond = '0xabcdef1234568';
const symbolFirst = 'ABBR';
const symbolSecond = 'ABBB';
const decimals = 5;
preferencesController.setAddresses(['0x7e57e2', '0xda22le']);
await preferencesController.setSelectedAddress('0x7e57e2');
await preferencesController.addToken(addressFirst, symbolFirst, decimals);
const tokensFirstAddress = preferencesController.getTokens();
await preferencesController.setSelectedAddress('0xda22le');
await preferencesController.addToken(
addressSecond,
symbolSecond,
decimals,
);
const tokensSeconAddress = preferencesController.getTokens();
assert.notEqual(
tokensFirstAddress,
tokensSeconAddress,
'add different tokens for two account and tokens are equal',
);
});
it('should add token per network', async function () {
const addressFirst = '0xabcdef1234567';
const addressSecond = '0xabcdef1234568';
const symbolFirst = 'ABBR';
const symbolSecond = 'ABBB';
const decimals = 5;
await preferencesController.addToken(addressFirst, symbolFirst, decimals);
const tokensFirstAddress = preferencesController.getTokens();
switchToRinkeby();
await preferencesController.addToken(
addressSecond,
symbolSecond,
decimals,
);
const tokensSeconAddress = preferencesController.getTokens();
assert.notEqual(
tokensFirstAddress,
tokensSeconAddress,
'add different tokens for two networks and tokens are equal',
);
});
});
describe('removeToken', function () {
it('should remove the only token from its state', async function () {
preferencesController.setAddresses(['0x7e57e2']);
await preferencesController.setSelectedAddress('0x7e57e2');
await preferencesController.addToken('0xa', 'A', 5);
await preferencesController.removeToken('0xa');
const tokens = preferencesController.getTokens();
assert.equal(tokens.length, 0, 'one token removed');
});
it('should remove a token from its state', async function () {
preferencesController.setAddresses(['0x7e57e2']);
await preferencesController.setSelectedAddress('0x7e57e2');
await preferencesController.addToken('0xa', 'A', 4);
await preferencesController.addToken('0xb', 'B', 5);
await preferencesController.removeToken('0xa');
const tokens = preferencesController.getTokens();
assert.equal(tokens.length, 1, 'one token removed');
const [token1] = tokens;
assert.deepEqual(token1, {
address: '0xb',
symbol: 'B',
decimals: 5,
isERC721: false,
});
});
it('should remove a token from its state on corresponding address', async function () {
preferencesController.setAddresses(['0x7e57e2', '0x7e57e3']);
await preferencesController.setSelectedAddress('0x7e57e2');
await preferencesController.addToken('0xa', 'A', 4);
await preferencesController.addToken('0xb', 'B', 5);
await preferencesController.setSelectedAddress('0x7e57e3');
await preferencesController.addToken('0xa', 'A', 4);
await preferencesController.addToken('0xb', 'B', 5);
const initialTokensSecond = preferencesController.getTokens();
await preferencesController.setSelectedAddress('0x7e57e2');
await preferencesController.removeToken('0xa');
const tokensFirst = preferencesController.getTokens();
assert.equal(tokensFirst.length, 1, 'one token removed in account');
const [token1] = tokensFirst;
assert.deepEqual(token1, {
address: '0xb',
symbol: 'B',
decimals: 5,
isERC721: false,
});
await preferencesController.setSelectedAddress('0x7e57e3');
const tokensSecond = preferencesController.getTokens();
assert.deepEqual(
tokensSecond,
initialTokensSecond,
'token deleted for account',
);
});
it('should remove a token from its state on corresponding network', async function () {
await preferencesController.addToken('0xa', 'A', 4);
await preferencesController.addToken('0xb', 'B', 5);
switchToRinkeby();
await preferencesController.addToken('0xa', 'A', 4);
await preferencesController.addToken('0xb', 'B', 5);
const initialTokensSecond = preferencesController.getTokens();
switchToMainnet();
await preferencesController.removeToken('0xa');
const tokensFirst = preferencesController.getTokens();
assert.equal(tokensFirst.length, 1, 'one token removed in network');
const [token1] = tokensFirst;
assert.deepEqual(token1, {
address: '0xb',
symbol: 'B',
decimals: 5,
isERC721: false,
});
switchToRinkeby();
const tokensSecond = preferencesController.getTokens();
assert.deepEqual(
tokensSecond,
initialTokensSecond,
'token deleted for network',
);
});
});
describe('on setSelectedAddress', function () {
it('should update tokens from its state on corresponding address', async function () {
preferencesController.setAddresses(['0x7e57e2', '0x7e57e3']);
await preferencesController.setSelectedAddress('0x7e57e2');
await preferencesController.addToken('0xa', 'A', 4);
await preferencesController.addToken('0xb', 'B', 5);
await preferencesController.setSelectedAddress('0x7e57e3');
await preferencesController.addToken('0xa', 'C', 4);
await preferencesController.addToken('0xb', 'D', 5);
await preferencesController.setSelectedAddress('0x7e57e2');
const initialTokensFirst = preferencesController.getTokens();
await preferencesController.setSelectedAddress('0x7e57e3');
const initialTokensSecond = preferencesController.getTokens();
assert.notDeepEqual(
initialTokensFirst,
initialTokensSecond,
'tokens not equal for different accounts and tokens',
);
await preferencesController.setSelectedAddress('0x7e57e2');
const tokensFirst = preferencesController.getTokens();
await preferencesController.setSelectedAddress('0x7e57e3');
const tokensSecond = preferencesController.getTokens();
assert.deepEqual(
tokensFirst,
initialTokensFirst,
'tokens equal for same account',
);
assert.deepEqual(
tokensSecond,
initialTokensSecond,
'tokens equal for same account',
);
});
});
describe('on updateStateNetworkType', function () {
it('should remove a token from its state on corresponding network', async function () {
await preferencesController.addToken('0xa', 'A', 4);
await preferencesController.addToken('0xb', 'B', 5);
const initialTokensFirst = preferencesController.getTokens();
switchToRinkeby();
await preferencesController.addToken('0xa', 'C', 4);
await preferencesController.addToken('0xb', 'D', 5);
const initialTokensSecond = preferencesController.getTokens();
assert.notDeepEqual(
initialTokensFirst,
initialTokensSecond,
'tokens not equal for different networks and tokens',
);
switchToMainnet();
const tokensFirst = preferencesController.getTokens();
switchToRinkeby();
const tokensSecond = preferencesController.getTokens();
assert.deepEqual(
tokensFirst,
initialTokensFirst,
'tokens equal for same network',
);
assert.deepEqual(
tokensSecond,
initialTokensSecond,
'tokens equal for same network',
);
});
});
describe('on watchAsset', function () {
let req, stubHandleWatchAssetERC20;
const sandbox = sinon.createSandbox();
beforeEach(function () {
req = { method: 'wallet_watchAsset', params: {} };
stubHandleWatchAssetERC20 = sandbox.stub(
preferencesController,
'_handleWatchAssetERC20',
);
});
after(function () {
sandbox.restore();
});
it('should error if passed no type', async function () {
await assert.rejects(
() => preferencesController.requestWatchAsset(req),
{ message: 'Asset of type "undefined" not supported.' },
'should have errored',
);
});
it('should error if method is not supported', async function () {
req.params.type = 'someasset';
await assert.rejects(
() => preferencesController.requestWatchAsset(req),
{ message: 'Asset of type "someasset" not supported.' },
'should have errored',
);
});
it('should handle ERC20 type', async function () {
req.params.type = 'ERC20';
await preferencesController.requestWatchAsset(req);
sandbox.assert.called(stubHandleWatchAssetERC20);
});
});
describe('on watchAsset of type ERC20', function () {
let req;
const sandbox = sinon.createSandbox();
beforeEach(function () {
req = { params: { type: 'ERC20' } };
});
after(function () {
sandbox.restore();
});
it('should add suggested token', async function () {
const address = '0xabcdef1234567';
const symbol = 'ABBR';
const decimals = 5;
const image = 'someimage';
req.params.options = { address, symbol, decimals, image };
sandbox
.stub(preferencesController, '_validateERC20AssetParams')
.returns(true);
preferencesController.openPopup = async () => undefined;
await preferencesController._handleWatchAssetERC20(req.params.options);
const suggested = preferencesController.getSuggestedTokens();
assert.equal(
Object.keys(suggested).length,
1,
`one token added ${Object.keys(suggested)}`,
);
assert.equal(
suggested[address].address,
address,
'set address correctly',
);
assert.equal(suggested[address].symbol, symbol, 'set symbol correctly');
assert.equal(
suggested[address].decimals,
decimals,
'set decimals correctly',
);
assert.equal(suggested[address].image, image, 'set image correctly');
});
it('should add token correctly if user confirms', async function () {
const address = '0xabcdef1234567';
const symbol = 'ABBR';
const decimals = 5;
const image = 'someimage';
req.params.options = { address, symbol, decimals, image };
sandbox
.stub(preferencesController, '_validateERC20AssetParams')
.returns(true);
preferencesController.openPopup = async () => {
await preferencesController.addToken(address, symbol, decimals, image);
};
await preferencesController._handleWatchAssetERC20(req.params.options);
const tokens = preferencesController.getTokens();
assert.equal(tokens.length, 1, `one token added`);
const added = tokens[0];
assert.equal(added.address, address, 'set address correctly');
assert.equal(added.symbol, symbol, 'set symbol correctly');
assert.equal(added.decimals, decimals, 'set decimals correctly');
const assetImages = preferencesController.getAssetImages();
assert.ok(assetImages[address], `set image correctly`);
});
it('should validate ERC20 asset correctly', async function () {
const validate = preferencesController._validateERC20AssetParams;
assert.doesNotThrow(() =>
validate({
address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07',
symbol: 'ABC',
decimals: 0,
}),
);
assert.doesNotThrow(() =>
validate({
address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07',
symbol: 'ABCDEFGHIJK',
decimals: 0,
}),
);
assert.throws(
() => validate({ symbol: 'ABC', decimals: 0 }),
'missing address should fail',
);
assert.throws(
() =>
validate({
address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07',
decimals: 0,
}),
'missing symbol should fail',
);
assert.throws(
() =>
validate({
address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07',
symbol: 'ABC',
}),
'missing decimals should fail',
);
assert.throws(
() =>
validate({
address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07',
symbol: 'ABCDEFGHIJKLM',
decimals: 0,
}),
'long symbol should fail',
);
assert.throws(
() =>
validate({
address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07',
symbol: '',
decimals: 0,
}),
'empty symbol should fail',
);
assert.throws(
() =>
validate({
address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07',
symbol: 'ABC',
decimals: -1,
}),
'decimals < 0 should fail',
);
assert.throws(
() =>
validate({
address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07',
symbol: 'ABC',
decimals: 38,
}),
'decimals > 36 should fail',
);
assert.throws(
() => validate({ address: '0x123', symbol: 'ABC', decimals: 0 }),
'invalid address should fail',
);
});
});
describe('setPasswordForgotten', function () {
it('should default to false', function () {
const state = preferencesController.store.getState();
@ -869,20 +248,20 @@ describe('preferences controller', function () {
);
});
});
describe('setUseStaticTokenList', function () {
describe('setUseTokenDetection', function () {
it('should default to false', function () {
const state = preferencesController.store.getState();
assert.equal(state.useStaticTokenList, false);
assert.equal(state.useTokenDetection, false);
});
it('should set the useStaticTokenList property in state', function () {
it('should set the useTokenDetection property in state', function () {
assert.equal(
preferencesController.store.getState().useStaticTokenList,
preferencesController.store.getState().useTokenDetection,
false,
);
preferencesController.setUseStaticTokenList(true);
preferencesController.setUseTokenDetection(true);
assert.equal(
preferencesController.store.getState().useStaticTokenList,
preferencesController.store.getState().useTokenDetection,
true,
);
});

@ -24,8 +24,9 @@ import { isSwapsDefaultTokenAddress } from '../../../shared/modules/swaps.utils'
import {
fetchTradesInfo as defaultFetchTradesInfo,
fetchSwapsQuoteRefreshTime as defaultFetchSwapsQuoteRefreshTime,
getBaseApi,
} from '../../../ui/pages/swaps/swaps.util';
import fetchWithCache from '../../../ui/helpers/utils/fetch-with-cache';
import { MINUTE, SECOND } from '../../../shared/constants/time';
import { NETWORK_EVENTS } from './network';
@ -40,10 +41,6 @@ const POLL_COUNT_LIMIT = 3;
// provide a reasonable fallback to avoid further errors
const FALLBACK_QUOTE_REFRESH_TIME = MINUTE;
// This is the amount of time to wait, after successfully fetching quotes
// and their gas estimates, before fetching for new quotes
const QUOTE_POLLING_DIFFERENCE_INTERVAL = SECOND * 10;
function calculateGasEstimateWithRefund(
maxGas = MAX_GAS_LIMIT,
estimatedRefund = 0,
@ -64,6 +61,7 @@ function calculateGasEstimateWithRefund(
const initialState = {
swapsState: {
quotes: {},
quotesPollingLimitEnabled: false,
fetchParams: null,
tokens: null,
tradeTxId: null,
@ -82,6 +80,7 @@ const initialState = {
swapsFeatureIsLive: true,
useNewSwapsApi: false,
swapsQuoteRefreshTime: FALLBACK_QUOTE_REFRESH_TIME,
swapsQuotePrefetchingRefreshTime: FALLBACK_QUOTE_REFRESH_TIME,
},
};
@ -93,7 +92,6 @@ export default class SwapsController {
getProviderConfig,
tokenRatesStore,
fetchTradesInfo = defaultFetchTradesInfo,
fetchSwapsQuoteRefreshTime = defaultFetchSwapsQuoteRefreshTime,
getCurrentChainId,
getEIP1559GasFeeEstimates,
}) {
@ -102,7 +100,6 @@ export default class SwapsController {
});
this._fetchTradesInfo = fetchTradesInfo;
this._fetchSwapsQuoteRefreshTime = fetchSwapsQuoteRefreshTime;
this._getCurrentChainId = getCurrentChainId;
this._getEIP1559GasFeeEstimates = getEIP1559GasFeeEstimates;
@ -124,38 +121,70 @@ export default class SwapsController {
});
}
async fetchSwapsRefreshRates(chainId, useNewSwapsApi) {
const response = await fetchWithCache(
getBaseApi('network', chainId, useNewSwapsApi),
{ method: 'GET' },
{ cacheRefreshTime: 600000 },
);
const { refreshRates } = response || {};
if (
!refreshRates ||
typeof refreshRates.quotes !== 'number' ||
typeof refreshRates.quotesPrefetching !== 'number'
) {
throw new Error(
`MetaMask - invalid response for refreshRates: ${response}`,
);
}
// We presently use milliseconds in the UI.
return {
quotes: refreshRates.quotes * 1000,
quotesPrefetching: refreshRates.quotesPrefetching * 1000,
};
}
// Sets the refresh rate for quote updates from the MetaSwap API
async _setSwapsQuoteRefreshTime() {
async _setSwapsRefreshRates() {
const chainId = this._getCurrentChainId();
const { swapsState } = this.store.getState();
// Default to fallback time unless API returns valid response
let swapsQuoteRefreshTime = FALLBACK_QUOTE_REFRESH_TIME;
let swapsRefreshRates;
try {
swapsQuoteRefreshTime = await this._fetchSwapsQuoteRefreshTime(
swapsRefreshRates = await this.fetchSwapsRefreshRates(
chainId,
swapsState.useNewSwapsApi,
);
} catch (e) {
console.error('Request for swaps quote refresh time failed: ', e);
}
const { swapsState: latestSwapsState } = this.store.getState();
this.store.updateState({
swapsState: { ...latestSwapsState, swapsQuoteRefreshTime },
swapsState: {
...latestSwapsState,
swapsQuoteRefreshTime:
swapsRefreshRates?.quotes || FALLBACK_QUOTE_REFRESH_TIME,
swapsQuotePrefetchingRefreshTime:
swapsRefreshRates?.quotesPrefetching || FALLBACK_QUOTE_REFRESH_TIME,
},
});
}
// Once quotes are fetched, we poll for new ones to keep the quotes up to date. Market and aggregator contract conditions can change fast enough
// that quotes will no longer be available after 1 or 2 minutes. When fetchAndSetQuotes is first called it, receives fetch that parameters are stored in
// that quotes will no longer be available after 1 or 2 minutes. When fetchAndSetQuotes is first called, it receives fetch parameters that are stored in
// state. These stored parameters are used on subsequent calls made during polling.
// Note: we stop polling after 3 requests, until new quotes are explicitly asked for. The logic that enforces that maximum is in the body of fetchAndSetQuotes
pollForNewQuotes() {
const {
swapsState: { swapsQuoteRefreshTime },
swapsState: {
swapsQuoteRefreshTime,
swapsQuotePrefetchingRefreshTime,
quotesPollingLimitEnabled,
},
} = this.store.getState();
// swapsQuoteRefreshTime is used on the View Quote page, swapsQuotePrefetchingRefreshTime is used on the Build Quote page.
const quotesRefreshRateInMs = quotesPollingLimitEnabled
? swapsQuoteRefreshTime
: swapsQuotePrefetchingRefreshTime;
this.pollingTimeout = setTimeout(() => {
const { swapsState } = this.store.getState();
this.fetchAndSetQuotes(
@ -163,11 +192,13 @@ export default class SwapsController {
swapsState.fetchParams?.metaData,
true,
);
}, swapsQuoteRefreshTime - QUOTE_POLLING_DIFFERENCE_INTERVAL);
}, quotesRefreshRateInMs);
}
stopPollingForQuotes() {
clearTimeout(this.pollingTimeout);
if (this.pollingTimeout) {
clearTimeout(this.pollingTimeout);
}
}
async fetchAndSetQuotes(
@ -177,7 +208,7 @@ export default class SwapsController {
) {
const { chainId } = fetchParamsMetaData;
const {
swapsState: { useNewSwapsApi },
swapsState: { useNewSwapsApi, quotesPollingLimitEnabled },
} = this.store.getState();
if (!fetchParams) {
@ -203,7 +234,7 @@ export default class SwapsController {
...fetchParamsMetaData,
useNewSwapsApi,
}),
this._setSwapsQuoteRefreshTime(),
this._setSwapsRefreshRates(),
]);
newQuotes = mapValues(newQuotes, (quote) => ({
@ -292,9 +323,13 @@ export default class SwapsController {
},
});
// We only want to do up to a maximum of three requests from polling.
this.pollCount += 1;
if (this.pollCount < POLL_COUNT_LIMIT + 1) {
if (quotesPollingLimitEnabled) {
// We only want to do up to a maximum of three requests from polling if polling limit is enabled.
// Otherwise we won't increase pollCount, so polling will run without a limit.
this.pollCount += 1;
}
if (!quotesPollingLimitEnabled || this.pollCount < POLL_COUNT_LIMIT + 1) {
this.pollForNewQuotes();
} else {
this.resetPostFetchState();
@ -322,6 +357,11 @@ export default class SwapsController {
this.store.updateState({ swapsState: { ...swapsState, tokens } });
}
clearSwapsQuotes() {
const { swapsState } = this.store.getState();
this.store.updateState({ swapsState: { ...swapsState, quotes: {} } });
}
setSwapsErrorKey(errorKey) {
const { swapsState } = this.store.getState();
this.store.updateState({ swapsState: { ...swapsState, errorKey } });
@ -464,6 +504,13 @@ export default class SwapsController {
});
}
setSwapsQuotesPollingLimitEnabled(quotesPollingLimitEnabled) {
const { swapsState } = this.store.getState();
this.store.updateState({
swapsState: { ...swapsState, quotesPollingLimitEnabled },
});
}
setSwapsTxMaxFeePriorityPerGas(maxPriorityFeePerGas) {
const { swapsState } = this.store.getState();
this.store.updateState({
@ -511,6 +558,8 @@ export default class SwapsController {
swapsFeatureIsLive: swapsState.swapsFeatureIsLive,
useNewSwapsApi: swapsState.useNewSwapsApi,
swapsQuoteRefreshTime: swapsState.swapsQuoteRefreshTime,
swapsQuotePrefetchingRefreshTime:
swapsState.swapsQuotePrefetchingRefreshTime,
},
});
clearTimeout(this.pollingTimeout);
@ -523,14 +572,15 @@ export default class SwapsController {
...initialState.swapsState,
tokens: swapsState.tokens,
swapsQuoteRefreshTime: swapsState.swapsQuoteRefreshTime,
swapsQuotePrefetchingRefreshTime:
swapsState.swapsQuotePrefetchingRefreshTime,
},
});
clearTimeout(this.pollingTimeout);
}
async _findTopQuoteAndCalculateSavings(quotes = {}) {
const tokenConversionRates = this.tokenRatesStore.getState()
.contractExchangeRates;
const tokenConversionRates = this.tokenRatesStore.contractExchangeRates;
const {
swapsState: { customGasPrice, customMaxPriorityFeePerGas },
} = this.store.getState();

@ -4,7 +4,6 @@ import sinon from 'sinon';
import { ethers } from 'ethers';
import { mapValues } from 'lodash';
import BigNumber from 'bignumber.js';
import { ObservableStore } from '@metamask/obs-store';
import {
ROPSTEN_NETWORK_ID,
MAINNET_NETWORK_ID,
@ -83,12 +82,12 @@ const MOCK_FETCH_METADATA = {
chainId: MAINNET_CHAIN_ID,
};
const MOCK_TOKEN_RATES_STORE = new ObservableStore({
const MOCK_TOKEN_RATES_STORE = {
contractExchangeRates: {
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': 2,
'0x1111111111111111111111111111111111111111': 0.1,
},
});
};
const MOCK_GET_PROVIDER_CONFIG = () => ({ type: 'FAKE_NETWORK' });
@ -116,6 +115,7 @@ function getMockNetworkController() {
const EMPTY_INIT_STATE = {
swapsState: {
quotes: {},
quotesPollingLimitEnabled: false,
fetchParams: null,
tokens: null,
tradeTxId: null,
@ -133,13 +133,13 @@ const EMPTY_INIT_STATE = {
swapsFeatureIsLive: true,
useNewSwapsApi: false,
swapsQuoteRefreshTime: 60000,
swapsQuotePrefetchingRefreshTime: 60000,
swapsUserFeeLevel: '',
},
};
const sandbox = sinon.createSandbox();
const fetchTradesInfoStub = sandbox.stub();
const fetchSwapsQuoteRefreshTimeStub = sandbox.stub();
const getCurrentChainIdStub = sandbox.stub();
getCurrentChainIdStub.returns(MAINNET_CHAIN_ID);
const getEIP1559GasFeeEstimatesStub = sandbox.stub(() => {
@ -162,7 +162,6 @@ describe('SwapsController', function () {
getProviderConfig: MOCK_GET_PROVIDER_CONFIG,
tokenRatesStore: MOCK_TOKEN_RATES_STORE,
fetchTradesInfo: fetchTradesInfoStub,
fetchSwapsQuoteRefreshTime: fetchSwapsQuoteRefreshTimeStub,
getCurrentChainId: getCurrentChainIdStub,
getEIP1559GasFeeEstimates: getEIP1559GasFeeEstimatesStub,
});
@ -670,7 +669,6 @@ describe('SwapsController', function () {
it('calls fetchTradesInfo with the given fetchParams and returns the correct quotes', async function () {
fetchTradesInfoStub.resolves(getMockQuotes());
fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime());
// Make it so approval is not required
sandbox
@ -716,7 +714,6 @@ describe('SwapsController', function () {
it('performs the allowance check', async function () {
fetchTradesInfoStub.resolves(getMockQuotes());
fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime());
// Make it so approval is not required
const allowanceStub = sandbox
@ -740,7 +737,6 @@ describe('SwapsController', function () {
it('gets the gas limit if approval is required', async function () {
fetchTradesInfoStub.resolves(MOCK_QUOTES_APPROVAL_REQUIRED);
fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime());
// Ensure approval is required
sandbox
@ -766,7 +762,6 @@ describe('SwapsController', function () {
it('marks the best quote', async function () {
fetchTradesInfoStub.resolves(getMockQuotes());
fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime());
// Make it so approval is not required
sandbox
@ -797,7 +792,6 @@ describe('SwapsController', function () {
};
const quotes = { ...getMockQuotes(), [bestAggId]: bestQuote };
fetchTradesInfoStub.resolves(quotes);
fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime());
// Make it so approval is not required
sandbox
@ -815,16 +809,15 @@ describe('SwapsController', function () {
it('does not mark as best quote if no conversion rate exists for destination token', async function () {
fetchTradesInfoStub.resolves(getMockQuotes());
fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime());
// Make it so approval is not required
sandbox
.stub(swapsController, '_getERC20Allowance')
.resolves(ethers.BigNumber.from(1));
swapsController.tokenRatesStore.updateState({
swapsController.tokenRatesStore = {
contractExchangeRates: {},
});
};
const [newQuotes, topAggId] = await swapsController.fetchAndSetQuotes(
MOCK_FETCH_PARAMS,
MOCK_FETCH_METADATA,
@ -843,6 +836,8 @@ describe('SwapsController', function () {
...EMPTY_INIT_STATE.swapsState,
tokens: old.tokens,
swapsQuoteRefreshTime: old.swapsQuoteRefreshTime,
swapsQuotePrefetchingRefreshTime:
old.swapsQuotePrefetchingRefreshTime,
});
});
@ -890,6 +885,7 @@ describe('SwapsController', function () {
const swapsFeatureIsLive = false;
const useNewSwapsApi = false;
const swapsQuoteRefreshTime = 0;
const swapsQuotePrefetchingRefreshTime = 0;
swapsController.store.updateState({
swapsState: {
tokens,
@ -897,6 +893,7 @@ describe('SwapsController', function () {
swapsFeatureIsLive,
useNewSwapsApi,
swapsQuoteRefreshTime,
swapsQuotePrefetchingRefreshTime,
},
});
@ -909,6 +906,7 @@ describe('SwapsController', function () {
fetchParams,
swapsFeatureIsLive,
swapsQuoteRefreshTime,
swapsQuotePrefetchingRefreshTime,
});
});
});
@ -1387,7 +1385,3 @@ function getTopQuoteAndSavingsBaseExpectedResults() {
},
};
}
function getMockQuoteRefreshTime() {
return 45000;
}

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

Loading…
Cancel
Save