Revert "Revert "Merge pull request #16353 from MetaMask/Version-v10.22.0""

This reverts commit d91ce9c4b5.
feature/default_network_editable
Mark Stacey 2 years ago
parent 205d60f3bd
commit ace7b0cda9
  1. 35
      .circleci/config.yml
  2. 22
      .circleci/scripts/bundle-stats-commit.sh
  3. 4
      .circleci/scripts/chrome-install.sh
  4. 2
      .github/workflows/cla.yml
  5. 2
      .github/workflows/codeql-analysis.yml
  6. 2
      .github/workflows/crowdin_action.yml
  7. 3
      .iyarc
  8. 8
      .storybook/test-data.js
  9. 1
      CHANGELOG.md
  10. 20
      app/_locales/de/messages.json
  11. 20
      app/_locales/el/messages.json
  12. 51
      app/_locales/en/messages.json
  13. 20
      app/_locales/es/messages.json
  14. 16
      app/_locales/es_419/messages.json
  15. 20
      app/_locales/fr/messages.json
  16. 20
      app/_locales/hi/messages.json
  17. 20
      app/_locales/id/messages.json
  18. 16
      app/_locales/it/messages.json
  19. 20
      app/_locales/ja/messages.json
  20. 20
      app/_locales/ko/messages.json
  21. 16
      app/_locales/ph/messages.json
  22. 20
      app/_locales/pt/messages.json
  23. 16
      app/_locales/pt_BR/messages.json
  24. 20
      app/_locales/ru/messages.json
  25. 20
      app/_locales/tl/messages.json
  26. 20
      app/_locales/tr/messages.json
  27. 20
      app/_locales/vi/messages.json
  28. 4114
      app/_locales/zh/messages.json
  29. 20
      app/_locales/zh_CN/messages.json
  30. BIN
      app/images/aurora.png
  31. 2
      app/images/icons/icon-search-filled.svg
  32. 55
      app/scripts/background.js
  33. 42
      app/scripts/controllers/metametrics.js
  34. 5
      app/scripts/controllers/metametrics.test.js
  35. 305
      app/scripts/controllers/threebox.js
  36. 2
      app/scripts/controllers/transactions/index.js
  37. 7
      app/scripts/lib/createMetaRPCHandler.js
  38. 4
      app/scripts/lib/get-first-preferred-lang-code.js
  39. 50
      app/scripts/lib/local-store.js
  40. 79
      app/scripts/lib/local-store.test.js
  41. 25
      app/scripts/lib/network-store.js
  42. 275
      app/scripts/lib/segment/analytics.js
  43. 116
      app/scripts/lib/segment/analytics.test.js
  44. 4
      app/scripts/lib/segment/index.js
  45. 7
      app/scripts/lib/setupSentry.js
  46. 12
      app/scripts/lib/util.js
  47. 138
      app/scripts/metamask-controller.actions.test.js
  48. 152
      app/scripts/metamask-controller.js
  49. 55
      app/scripts/metamask-controller.test.js
  50. 23
      app/scripts/migrations/075.js
  51. 63
      app/scripts/migrations/075.test.js
  52. 2
      app/scripts/migrations/index.js
  53. 107
      app/scripts/ui.js
  54. 13
      development/generate-lavamoat-policies.js
  55. 68
      development/mock-3box.js
  56. 1
      development/ts-migration-dashboard/files-to-convert.json
  57. 7
      docs/generating-fixture-data.md
  58. 2
      jest.config.js
  59. 2813
      lavamoat/browserify/beta/policy.json
  60. 2844
      lavamoat/browserify/flask/policy.json
  61. 2813
      lavamoat/browserify/main/policy.json
  62. 5
      lavamoat/browserify/policy-override.json
  63. 76
      lavamoat/build-system/policy.json
  64. 47
      package.json
  65. 301
      patches/@keystonehq+bc-ur-registry+0.5.0-alpha.5.patch
  66. 37
      patches/secp256k1+3.8.0.patch
  67. 2
      shared/constants/alarms.js
  68. 8
      shared/constants/metametrics.js
  69. 20
      shared/constants/network.ts
  70. 1
      shared/modules/provider-injection.js
  71. 8
      test/e2e/benchmark.js
  72. 1103
      test/e2e/fixture-builder.js
  73. 18
      test/e2e/fixture-server.js
  74. 169
      test/e2e/fixtures/address-entry/state.json
  75. 200
      test/e2e/fixtures/connected-state/state.json
  76. 170
      test/e2e/fixtures/custom-rpc/state.json
  77. 178
      test/e2e/fixtures/custom-token/state.json
  78. 160
      test/e2e/fixtures/eip-1559-v2-dapp/state.json
  79. 229
      test/e2e/fixtures/eip-1559-v2/state.json
  80. 272
      test/e2e/fixtures/import-ui/state.json
  81. 157
      test/e2e/fixtures/imported-account/state.json
  82. 156
      test/e2e/fixtures/localization/state.json
  83. 200
      test/e2e/fixtures/metrics-enabled/state.json
  84. 442
      test/e2e/fixtures/navigate-transactions/state.json
  85. 59
      test/e2e/fixtures/onboarding/state.json
  86. 229
      test/e2e/fixtures/send-edit-v2/state.json
  87. 235
      test/e2e/fixtures/send-edit/state.json
  88. 158
      test/e2e/fixtures/special-settings/state.json
  89. 155
      test/e2e/fixtures/threebox-enabled/state.json
  90. 23
      test/e2e/helpers.js
  91. 0
      test/e2e/import-utc-json/test-json-import-account-file.json
  92. 8
      test/e2e/lavamoat-stats.js
  93. 57
      test/e2e/mock-3box/threebox-mock-server.js
  94. 13
      test/e2e/mock-e2e.js
  95. 8
      test/e2e/mv3-perf-stats/init-load-stats.js
  96. 8
      test/e2e/mv3-stats.js
  97. 50
      test/e2e/restore/MetaMaskUserData.json
  98. 19
      test/e2e/run-all.js
  99. 2
      test/e2e/snaps/enums.js
  100. 157
      test/e2e/snaps/test-snap-bip-32.spec.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -90,6 +90,9 @@ workflows:
- test-e2e-firefox-snaps:
requires:
- prep-build-test-flask
- test-e2e-chrome-mv3:
requires:
- prep-build-test-mv3
- test-unit:
requires:
- prep-deps
@ -386,7 +389,7 @@ jobs:
- builds-test
prep-build-storybook:
executor: node-browsers
executor: node-browsers-medium-plus
steps:
- checkout
- attach_workspace:
@ -538,6 +541,33 @@ jobs:
path: test-artifacts
destination: test-artifacts
test-e2e-chrome-mv3:
executor: node-browsers
steps:
- checkout
- run:
name: Re-Install Chrome
command: ./.circleci/scripts/chrome-install.sh
- attach_workspace:
at: .
- run:
name: Move test build to dist
command: mv ./dist-test-mv3 ./dist
- run:
name: Move test zips to builds
command: mv ./builds-test-mv3 ./builds
- run:
name: test:e2e:chrome
command: |
if .circleci/scripts/test-run-e2e.sh
then
yarn test:e2e:chrome --retries 2 || echo "Temporarily suppressing MV3 e2e test failures"
fi
no_output_timeout: 20m
- store_artifacts:
path: test-artifacts
destination: test-artifacts
test-e2e-firefox-snaps:
executor: node-browsers
steps:
@ -697,6 +727,9 @@ jobs:
- run:
name: Run page load benchmark
command: yarn mv3:stats:chrome --out test-artifacts/chrome/mv3
- run:
name: Install jq
command: sudo apt install jq -y
- run:
name: Record bundle size at commit
command: ./.circleci/scripts/bundle-stats-commit.sh

@ -50,6 +50,28 @@ cp temp/stats/bundle_size_data.temp.js temp/stats/bundle_size_data.js
echo " }" >> temp/stats/bundle_size_data.js
if [ -f temp/stats/bundle_size_data.json ]; then
# copy bundle_size_data.json in bundle_size_data.temp.json without last 2 lines
head -$(($(wc -l < temp/stats/bundle_size_data.json) - 2)) temp/stats/bundle_size_data.json > bundle_size_stats.temp.json
{
echo "},";
echo "\"$CIRCLE_SHA1\":";
cat test-artifacts/chrome/mv3/bundle_size_stats.json;
echo "}";
} >> bundle_size_stats.temp.json
else
{
echo "{";
echo "\"$CIRCLE_SHA1\":";
cat test-artifacts/chrome/mv3/bundle_size_stats.json;
echo "}";
} > bundle_size_stats.temp.json
fi
jq . bundle_size_stats.temp.json > temp/stats/bundle_size_data.json
rm bundle_size_stats.temp.json
cd temp
git add .

@ -5,12 +5,12 @@ set -u
set -o pipefail
# To get the latest version, see <https://www.ubuntuupdates.org/ppa/google_chrome?dist=stable>
CHROME_VERSION='105.0.5195.102-1'
CHROME_VERSION='107.0.5304.87-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}"
# To retrieve this checksum, run the `wget` and `shasum` commands below
CHROME_BINARY_SHA512SUM='3a1f2267ae009424ee8c623c3f78760d969dc1f3acb490e103e667d11e52cf0d955f201aeb3892dd41f33e68625af77ca5a20244b5be718f794eccb07a4c0413'
CHROME_BINARY_SHA512SUM='07b443bc1382431da84f6812b7e19f1149aa195fb8b3d28834630cc5964fb9d12124abbf4ec1c98d5c0513cdf16c2a3f16a74518c984aaf57ca418b3cd36a4e2'
wget -O "${CHROME_BINARY}" -t 5 "${CHROME_BINARY_URL}"

@ -8,7 +8,7 @@ on:
jobs:
CLABot:
if: github.event_name == 'pull_request_target' || contains(github.event.comment.html_url, '/pull/')
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
permissions:
pull-requests: write
contents: write

@ -23,7 +23,7 @@ on:
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
permissions:
actions: read
contents: read

@ -13,7 +13,7 @@ on:
jobs:
synchronize-with-crowdin:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:

@ -1,5 +1,2 @@
# improved-yarn-audit advisory exclusions
GHSA-93q8-gq69-wqmw
GHSA-257v-vj4p-3w2h
GHSA-wm7h-9275-46v2
GHSA-pfrx-2q88-qq97

@ -1383,12 +1383,6 @@ const state = {
},
},
},
threeBoxSyncingAllowed: false,
showRestorePrompt: true,
threeBoxLastUpdated: 0,
threeBoxAddress: null,
threeBoxSynced: false,
threeBoxDisabled: false,
swapsState: {
quotes: {},
fetchParams: null,
@ -1479,8 +1473,6 @@ const state = {
},
networksTabSelectedRpcUrl: '',
loadingMethodData: false,
show3BoxModalAfterImport: false,
threeBoxLastUpdated: null,
requestAccountTabs: {},
openMetaMaskTabs: {},
currentWindowTab: {},

@ -3298,6 +3298,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.22.1...HEAD
[10.22.1]: https://github.com/MetaMask/metamask-extension/compare/v10.22.0...v10.22.1
[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.22.0...HEAD
[10.22.0]: https://github.com/MetaMask/metamask-extension/compare/v10.21.2...v10.22.0
[10.21.2]: https://github.com/MetaMask/metamask-extension/compare/v10.21.1...v10.21.2
[10.21.1]: https://github.com/MetaMask/metamask-extension/compare/v10.21.0...v10.21.1

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "Die Adresse in der Anmeldeanfrage entspricht nicht der Adresse des Kontos, mit dem Sie sich anmelden."
},
"SIWEDomainInvalid": {
"message": "Die Webseite, auf der Sie sich anmelden möchten ($1) entspricht nicht der Domain der Anmeldeanfrage. Bitte seien Sie vorsichtig.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "Die Webseite ($1) bittet Sie, sich in der falschen Domain anzumelden. Dies könnte ein Phishing-Angriff sein.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "Daten"
},
"dataBackupFoundInfo": {
"message": "Einige Ihrer Kontodaten wurden während einer früheren MetaMask-Installation gesichert. Dies könnte Ihre Einstellungen, Kontakte und Token umfassen. Möchten Sie diese Daten jetzt wiederherstellen?"
},
"dataBackupSeemsCorrupt": {
"message": "Ihre Daten konnten nicht wiederhergestellt werden. Die Datei scheint beschädigt zu sein."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "Sie können die Benutzereinstellungen, die bevorzugte Einstellungen und Kontoadressen umfassen, aus einer vormals gesicherten JSON-Datei wiederherstellen."
},
"restoreWalletPreferences": {
"message": "$1 hat ein Backup Ihrer Daten gefunden. Möchten Sie die Präferenzen Ihrer Wallet wiederherstellen?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Transaktion wiederholen"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "Mit Mobilgerät synchronisieren"
},
"syncWithThreeBox": {
"message": "Daten mit 3Box synchronisieren (experimentell)"
},
"syncWithThreeBoxDescription": {
"message": "Aktivieren Sie, um Ihre Einstellungen mit 3Box zu sichern. Diese Funktion ist derzeit experimentell; verwenden Sie diese auf eigene Gefahr."
},
"syncWithThreeBoxDisabled": {
"message": "3Box wurde aufgrund eines Fehlers während der ersten Synchronisation deaktiviert"
},
"tenPercentIncreased": {
"message": "10% Erhöhung"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "Η διεύθυνση στο αίτημα σύνδεσης δεν ταιριάζει με τη διεύθυνση του λογαριασμού που χρησιμοποιείτε για να συνδεθείτε."
},
"SIWEDomainInvalid": {
"message": "Ο ιστότοπος στον οποίο προσπαθείτε να συνδεθείτε ($1) δεν ταιριάζει με τον τομέα στο αίτημα σύνδεσης. Προχωρήστε με προσοχή.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "Ο ιστότοπος ($1) σάς ζητά να συνδεθείτε σε λάθος τομέα. Μπορεί να πρόκειται για επίθεση ηλεκτρονικού ψαρέματος.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "Δεδομένα"
},
"dataBackupFoundInfo": {
"message": "Ορισμένα από τα δεδομένα του λογαριασμού σας δημιουργήθηκαν σε προηγούμενη εγκατάσταση του MetaMask. Αυτό θα μπορούσε να περιλαμβάνει τις ρυθμίσεις, τις επαφές και τα διακριτικά σας. Θα θέλατε να επαναφέρετε αυτά τα δεδομένα τώρα;"
},
"dataBackupSeemsCorrupt": {
"message": "Δεν μπορείτε να επαναφέρετε τα δεδομένα σας. Το αρχείο φαίνεται να είναι κατεστραμμένο."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "Μπορείτε να επαναφέρετε τις ρυθμίσεις χρήστη που περιλαμβάνουν τις προτιμήσεις και τις διευθύνσεις λογαριασμών από ένα αρχείο JSON για το οποίο έχει δημιουργηθεί στο παρελθόν αντίγραφο ασφαλείας."
},
"restoreWalletPreferences": {
"message": "Βρέθηκε ένα αντίγραφο ασφαλείας των δεδομένων σας από το $1. Θα θέλατε να επαναφέρετε τις προτιμήσεις του πορτοφολιού σας;",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Επανάληψη Συναλλαγής"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "Συγχρονισμός με κινητό"
},
"syncWithThreeBox": {
"message": "Συγχρονισμός δεδομένων με 3Box (πειραματικό)"
},
"syncWithThreeBoxDescription": {
"message": "Ενεργοποιήστε για να δημιουργηθούν αντίγραφα ασφαλείας των ρυθμίσεων σας με το 3Box. Αυτή η λειτουργία είναι επί του παρόντος πειραματική. Χρησιμοποιήστε τη με δική σας ευθύνη."
},
"syncWithThreeBoxDisabled": {
"message": "Το 3Box έχει απενεργοποιηθεί λόγω σφάλματος κατά τον αρχικό συγχρονισμό"
},
"tenPercentIncreased": {
"message": "10% αύξηση"
},

@ -47,14 +47,19 @@
"SIWEAddressInvalid": {
"message": "The address in the sign-in request does not match the address of the account you are using to sign in."
},
"SIWEDomainInvalid": {
"message": "The website you are attempting to sign in to ($1) does not match the domain in the sign-in request. Proceed with caution.",
"description": "$1 represents the website domain"
"SIWEDomainInvalidText": {
"message": "The site you're attempting to sign into doesn't match the domain in the request. Proceed with caution."
},
"SIWEDomainInvalidTitle": {
"message": "Deceptive site request."
},
"SIWEDomainWarningBody": {
"message": "The website ($1) is asking you to sign in to the wrong domain. This may be a phishing attack.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningLabel": {
"message": "Unsafe"
},
"SIWELabelChainID": {
"message": "Chain ID:"
},
@ -448,6 +453,15 @@
"betaPortfolioSite": {
"message": "beta portfolio site"
},
"betaTerms": {
"message": "BETA Terms of use"
},
"betaWalletCreationSuccessReminder1": {
"message": "MetaMask BETA can’t recover your Secret Recovery Phrase."
},
"betaWalletCreationSuccessReminder2": {
"message": "MetaMask BETA will never ask you for your Secret Recovery Phrase."
},
"betaWelcome": {
"message": "Welcome to MetaMask Beta"
},
@ -891,9 +905,6 @@
"data": {
"message": "Data"
},
"dataBackupFoundInfo": {
"message": "Some of your account data was backed up during a previous installation of MetaMask. This could include your settings, contacts, and tokens. Would you like to restore this data now?"
},
"dataBackupSeemsCorrupt": {
"message": "Can not restore your data. The file appears to be corrupt."
},
@ -2897,10 +2908,6 @@
"restoreUserDataDescription": {
"message": "You can restore user settings containing preferences and account addresses from a previously backed up JSON file."
},
"restoreWalletPreferences": {
"message": "A backup of your data from $1 has been found. Would you like to restore your wallet preferences?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Retry transaction"
},
@ -2922,6 +2929,9 @@
"revealTheSeedPhrase": {
"message": "Reveal seed phrase"
},
"reviewSpendingCap": {
"message": "Review your spending cap"
},
"revokeAllTokensTitle": {
"message": "Revoke permission to access all of your $1?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3117,6 +3127,9 @@
"message": "Approve $1 with no spend limit",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Set a spending cap for your"
},
"settings": {
"message": "Settings"
},
@ -3880,15 +3893,6 @@
"syncWithMobileTitle": {
"message": "Sync with mobile"
},
"syncWithThreeBox": {
"message": "Sync data with 3Box (experimental)"
},
"syncWithThreeBoxDescription": {
"message": "Turn on to have your settings backed up with 3Box. This feature is currently experimental; use at your own risk."
},
"syncWithThreeBoxDisabled": {
"message": "3Box has been disabled due to an error during the initial sync"
},
"tenPercentIncreased": {
"message": "10% increase"
},
@ -4219,6 +4223,9 @@
"userName": {
"message": "Username"
},
"verifyContractDetails": {
"message": "Verify contract details"
},
"verifyThisTokenDecimalOn": {
"message": "Token decimal can be found on $1",
"description": "Points the user to etherscan as a place they can verify information about a token. $1 is replaced with the translation for \"etherscan\""
@ -4231,6 +4238,9 @@
"message": "Verify this token on $1 and make sure this is the token you want to trade.",
"description": "Points the user to etherscan as a place they can verify information about a token. $1 is replaced with the translation for \"etherscan\""
},
"view": {
"message": "View"
},
"viewAccount": {
"message": "View account"
},
@ -4240,6 +4250,9 @@
"viewContact": {
"message": "View contact"
},
"viewDetails": {
"message": "View details"
},
"viewFullTransactionDetails": {
"message": "View full transaction details"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "La dirección de la solicitud de inicio de sesión no coincide con la dirección de la cuenta que está utilizando para iniciar sesión."
},
"SIWEDomainInvalid": {
"message": "El sitio web en el que intenta iniciar sesión ($1) no coincide con el dominio de la solicitud de inicio de sesión. Proceda con precaución.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "El sitio web ($1) le pide que inicie sesión en un dominio incorrecto. Esto puede ser un ataque de phishing.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "Datos"
},
"dataBackupFoundInfo": {
"message": "Se crearon copias de seguridad de algunos de los datos de la cuenta durante una instalación anterior de MetaMask. Esto podría incluir configuraciones, contactos y tokens. ¿Le gustaría restaurar estos datos ahora?"
},
"dataBackupSeemsCorrupt": {
"message": "No se pueden restaurar sus datos. El archivo parece estar corrupto."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "Puede restaurar la configuración del usuario que contiene preferencias y direcciones de cuenta desde en un archivo JSON previamente respaldado."
},
"restoreWalletPreferences": {
"message": "Se encontró una copia de seguridad de los datos de $1. ¿Desea restaurar las preferencias de cartera?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Reintentar transacción"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "Sincronizar con dispositivo móvil"
},
"syncWithThreeBox": {
"message": "Sincronizar datos con 3Box (experimental)"
},
"syncWithThreeBoxDescription": {
"message": "Active esta opción para crear una copia de seguridad de la configuración con 3Box. Actualmente, esta función es experimental. Úsela bajo su propio riesgo."
},
"syncWithThreeBoxDisabled": {
"message": "3Box se deshabilitó debido a un error durante la sincronización inicial"
},
"tenPercentIncreased": {
"message": "10% de aumento"
},

@ -627,9 +627,6 @@
"data": {
"message": "Datos"
},
"dataBackupFoundInfo": {
"message": "Se crearon copias de seguridad de algunos de los datos de la cuenta durante una instalación anterior de MetaMask. Esto podría incluir configuraciones, contactos y tokens. ¿Quiere restaurar estos datos ahora?"
},
"dataHex": {
"message": "Hex"
},
@ -2188,10 +2185,6 @@
"restore": {
"message": "Restaurar"
},
"restoreWalletPreferences": {
"message": "Se encontró una copia de seguridad de los datos de $1. ¿Desea restaurar las preferencias de cartera?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Reintentar transacción"
},
@ -2903,15 +2896,6 @@
"syncWithMobileTitle": {
"message": "Sincronizar con dispositivo móvil"
},
"syncWithThreeBox": {
"message": "Sincronizar datos con 3Box (experimental)"
},
"syncWithThreeBoxDescription": {
"message": "Active esta opción para crear una copia de seguridad de la configuración con 3Box. Actualmente, esta función es experimental. Úsela bajo su propio riesgo."
},
"syncWithThreeBoxDisabled": {
"message": "3Box se deshabilitó debido a un error durante la sincronización inicial"
},
"tenPercentIncreased": {
"message": "10% de aumento"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "L'adresse figurant dans la demande de connexion ne correspond pas à l'adresse du compte que vous utilisez pour vous connecter."
},
"SIWEDomainInvalid": {
"message": "Le nom de domaine du site Web auquel vous tentez de vous connecter ($1) ne correspond pas au nom de domaine indiqué dans la demande de connexion. Procédez avec prudence.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "Le site Web ($1) vous demande de vous connecter au mauvais nom domaine. Il peut s'agir d'une tentative d'hameçonnage.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "Données"
},
"dataBackupFoundInfo": {
"message": "Certaines données de votre compte ont été sauvegardées lors d’une précédente installation de MetaMask. Il peut s’agir de vos paramètres, contacts et jetons. Souhaitez-vous restaurer ces données maintenant?"
},
"dataBackupSeemsCorrupt": {
"message": "Impossible de restaurer vos données. Le fichier semble corrompu."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "Vous pouvez restaurer les paramètres de l’utilisateur qui contiennent les préférences et les adresses de compte à partir d’un fichier JSON précédemment sauvegardé."
},
"restoreWalletPreferences": {
"message": "Une sauvegarde de vos données de $1 a été trouvée. Voulez-vous restaurer vos préférences de portefeuille?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Retenter la transaction"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "Synchroniser avec le mobile"
},
"syncWithThreeBox": {
"message": "Synchronisation des données avec 3Box (expérimental)"
},
"syncWithThreeBoxDescription": {
"message": "Activez cette fonction pour que vos paramètres soient sauvegardés avec 3Box. Cette fonction est actuellement expérimentale; utilisez-la avec prudence."
},
"syncWithThreeBoxDisabled": {
"message": "3Box a été désactivé en raison d’une erreur lors de la synchronisation initiale"
},
"tenPercentIncreased": {
"message": "Augmentation de 10 %"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "सइन-इन अनध क पत उस अकट क पतल नहिसक उपयग आप सइन इन करनिए कर रह।"
},
"SIWEDomainInvalid": {
"message": "जिस वबसइट म ($1) आप सइन इन करनिश कर रह वह सइन-इन अनध कन सल नह। सवधथ आग बढ।",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "वबसइट ($1) आपस गलत डन मइन इन करनिए कह रह। यह एक फििग अटक ह सकत।",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "ड"
},
"dataBackupFoundInfo": {
"message": "MetaMask किछलपनन आपकछ खकअप लि गय। इसम आपकिग, सपरक और टकन शिल ह सकत। क आप अब इस डनरित करन?"
},
"dataBackupSeemsCorrupt": {
"message": "आपकर नहि सकत। लगतइल करपट हई ह।"
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "वरयत और अकट एडस सत यजर सिस क आप पहलकअप क गई JSON फइल सर सकत।"
},
"restoreWalletPreferences": {
"message": "$1 स आपककअप मि। क आप अपनट वरयतनरित करनहत?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "लनदन करयस कर"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "मइल कथ सिक कर"
},
"syncWithThreeBox": {
"message": "3Box कथ डिक कर (परयमक)"
},
"syncWithThreeBoxDescription": {
"message": "3Box कथ अपनिग ककअप लिए च कर। यह सि वरतमन मरयमक ह; अपनिम पर इसल कर।"
},
"syncWithThreeBoxDisabled": {
"message": "पिक सिक कन एक तिरण 3Box क अकषम कर दि गय"
},
"tenPercentIncreased": {
"message": "10% बढतर"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "Alamat pada permintaan masuk tidak sesuai dengan alamat akun yang Anda gunakan untuk masuk."
},
"SIWEDomainInvalid": {
"message": "Situs web yang Anda coba masuki ($1) tidak sesuai dengan domain pada permintaan masuk. Lanjutkan dengan hati-hati.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "Situs web ($1) meminta Anda untuk masuk ke domain yang salah. Kemungkinan ini merupakan serangan pengelabuan.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "Data"
},
"dataBackupFoundInfo": {
"message": "Beberapa data akun Anda telah dicadangkan selama pemasangan MetaMask yang lalu. Ini bisa mencakup pengaturan, kontak, dan token Anda. Apakah Anda ingin memulihkan data ini sekarang?"
},
"dataBackupSeemsCorrupt": {
"message": "Tidak dapat memulihkan data Anda. File tampaknya rusak."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "Anda dapat memulihkan pengaturan pengguna yang berisi preferensi dan alamat akun dari berkas JSON yang dicadangkan sebelumnya."
},
"restoreWalletPreferences": {
"message": "Cadangan data Anda dari $1 telah ditemukan. Pulihkan preferensi dompet Anda?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Coba lagi transaksi"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "Sinkronkan dengan seluler"
},
"syncWithThreeBox": {
"message": "Sinkronkan data dengan 3Box (eksperimen)"
},
"syncWithThreeBoxDescription": {
"message": "Aktifkan agar pengaturan Anda dicadangkan dengan 3Box. Fitur ini sekarang sedang dalam masa percobaan; risiko ditanggung sendiri."
},
"syncWithThreeBoxDisabled": {
"message": "3Box telah dinonaktifkan karena terjadi galat selama sinkronisasi awal"
},
"tenPercentIncreased": {
"message": "Meningkat 10%"
},

@ -361,9 +361,6 @@
"customToken": {
"message": "Token Personalizzato"
},
"dataBackupFoundInfo": {
"message": "Alcuni dati sul tuo account sono state salvate durante una installazione precedente di MetaMask. Questi includono le impostazioni, i contatti, e i token. Vuoi ripristinare questi dati?"
},
"decimal": {
"message": "Precisione Decimali"
},
@ -1100,10 +1097,6 @@
"restore": {
"message": "Ripristina"
},
"restoreWalletPreferences": {
"message": "È stato trovato un backup dei tuoi dati da $1. Vuoi ripristinare le preferenze del portafoglio?",
"description": "$1 is the date at which the data was backed up"
},
"reusedTokenNameWarning": {
"message": "Un token usa un simbolo già usato da un altro token, ciò può confondere o ingannare."
},
@ -1533,15 +1526,6 @@
"syncWithMobileTitle": {
"message": "Sincronizza con dispositivo mobile"
},
"syncWithThreeBox": {
"message": "Sincronizza dati con 3Box (sperimentale)"
},
"syncWithThreeBoxDescription": {
"message": "Attiva per avere le tue impostazioni salvate su 3Box. Questa funzionalità è attualmente sperimentale; usala a tuo rischio."
},
"syncWithThreeBoxDisabled": {
"message": "3Box è stato disabilitato a causa di un errore durante la sincronizzazione iniziale"
},
"terms": {
"message": "Termini di Uso"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "サインインリクエストのアドレスが、サインインに使用しているアカウントのアドレスと一致していません。"
},
"SIWEDomainInvalid": {
"message": "サインインしようとしている Web サイト ($1) が、サインインリクエストのドメインと一致していません。慎重に進めてください。",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "Web サイト ($1) が正しくないドメインへのサインインを要求しています。フィッシング攻撃の可能性があります。",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "データ"
},
"dataBackupFoundInfo": {
"message": "一部のアカウントデータはMetaMaskの前回のインストール時にバックアップされました。これには、設定、連絡先、およびトークンが含まれている可能性があります。このデータを今すぐ復元しますか?"
},
"dataBackupSeemsCorrupt": {
"message": "データを復元できません。ファイルが破損しているようです。"
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "以前バックアップされた JSON ファイルから、設定とアカウントアドレスを含むユーザー設定を復元できます。"
},
"restoreWalletPreferences": {
"message": "$1のデータのバックアップが見つかりました。ウォレットの基本設定を復元しますか?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "トランザクションを再試行"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "モバイルと同期"
},
"syncWithThreeBox": {
"message": "データを3Boxと同期 (試験的機能)"
},
"syncWithThreeBoxDescription": {
"message": "これをオンにすると、設定が3Boxでバックアップされます。この機能は現在試験段階にあります。自己責任でご利用ください。"
},
"syncWithThreeBoxDisabled": {
"message": "3Boxは、最初の同期中のエラーのため、無効化されました"
},
"tenPercentIncreased": {
"message": "10% の増加"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "로그인 요청 주소가 현재 로그인 계정의 주소와 일치하지 않습니다."
},
"SIWEDomainInvalid": {
"message": "($1) 로그인을 시도하는 웹사이트가 로그인 요청 도메인과 일치하지 않습니다. 주의하여 진행하세요.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "($1) 웹사이트가 잘못된 도메인에 로그인하도록 요청하고 있습니다. 이는 피싱 공격일 수도 있습니다.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "데이터"
},
"dataBackupFoundInfo": {
"message": "일부 계정 데이터가 이전의 MetaMask 설치 도중에 백업되었습니다. 여기에는 설정, 연락처, 토큰이 포함될 수 있습니다. 지금 이 데이터를 복구할까요?"
},
"dataBackupSeemsCorrupt": {
"message": "사용자 데이터를 복원할 수 없습니다. 파일이 손상된 것 같습니다."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "이전에 백업한 JSON 파일에서 기본 설정과 계정 주소가 포함된 사용자 설정을 복원할 수 있습니다."
},
"restoreWalletPreferences": {
"message": "$1의 데이터 백업이 발견되었습니다. 지갑 환경설정을 복원할까요?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "트랜잭션 재시도"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "모바일과 동기화"
},
"syncWithThreeBox": {
"message": "3Box로 데이터 동기화(실험적 기능)"
},
"syncWithThreeBoxDescription": {
"message": "이 기능을 켜면 3Box를 이용해 설정을 백업합니다. 현재 실험 중인 기능이므로 본인의 책임 하에 사용해야 합니다."
},
"syncWithThreeBoxDisabled": {
"message": "초기 동기화 도중 오류가 발생하여 3Box가 비활성화되었습니다."
},
"tenPercentIncreased": {
"message": "10% 인상"
},

@ -430,9 +430,6 @@
"customToken": {
"message": "Custom na Token"
},
"dataBackupFoundInfo": {
"message": "Ang ilan sa data ng iyong account ay na-back up sa nakaraang pag-install ng MetaMask. Maaaring kasama rito ang iyong mga setting, contact, at token. Gusto mo na bang i-restore ang data na ito ngayon?"
},
"decimal": {
"message": "Decimal ng Token"
},
@ -1380,10 +1377,6 @@
"restore": {
"message": "I-restore"
},
"restoreWalletPreferences": {
"message": "Nakita ang backup ng iyong data mula sa $1. Gusto mo bang i-restore ang mga kagustuhan mo sa wallet?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Subukan Ulit ang Transaksyon"
},
@ -1952,15 +1945,6 @@
"syncWithMobileTitle": {
"message": "I-sync sa mobile"
},
"syncWithThreeBox": {
"message": "I-sync ang data sa 3Box (pinag-eeksperimentuhan)"
},
"syncWithThreeBoxDescription": {
"message": "I-on para ma-back up ang iyong mga setting sa 3Box. Kasalukuyang pinag-eeksperimentuhan ang feature na ito; gamitin sa sarili mong pagpapasya."
},
"syncWithThreeBoxDisabled": {
"message": "Na-disable ang 3Box dahil sa isang error sa unang pag-sync"
},
"terms": {
"message": "Mga Tuntunin ng Paggamit"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "O endereço na solicitação de entrada não coincide com o endereço da conta que você está usando para entrar."
},
"SIWEDomainInvalid": {
"message": "O site em que você está tentando entrar ($1) não coincide com o domínio na solicitação de entrada. Prossiga com cautela.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "O site ($1) está solicitando que você entre no domínio incorreto. Pode-se tratar de um ataque de phishing.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "Dados"
},
"dataBackupFoundInfo": {
"message": "Foi feito o backup de alguns dos dados da sua conta durante uma instalação anterior da MetaMask. Isso pode incluir configurações, contatos e tokens. Gostaria de restaurar esses dados agora?"
},
"dataBackupSeemsCorrupt": {
"message": "Não é possível restaurar seus dados. O arquivo parece estar corrompido."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "Você pode restaurar as configurações do usuário contendo preferências e endereços de contas a partir de um arquivo de backup JSON."
},
"restoreWalletPreferences": {
"message": "Encontramos um backup dos seus dados de $1. Gostaria de restaurar as preferências da sua carteira?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Tentar transação novamente"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "Sincronizar com dispositivo móvel"
},
"syncWithThreeBox": {
"message": "Sincronizar dados com 3Box (experimental)"
},
"syncWithThreeBoxDescription": {
"message": "Ative para fazer backup das suas configurações com o 3Box. Esse recurso é experimental; use por sua conta e risco."
},
"syncWithThreeBoxDisabled": {
"message": "O 3Box foi desabilitado por conta de um erro durante a sincronização inicial"
},
"tenPercentIncreased": {
"message": "10% de aumento"
},

@ -627,9 +627,6 @@
"data": {
"message": "Dados"
},
"dataBackupFoundInfo": {
"message": "Foi feito o backup de alguns dos dados da sua conta durante uma instalação anterior da MetaMask. Isso pode incluir configurações, contatos e tokens. Gostaria de restaurar esses dados agora?"
},
"dataHex": {
"message": "Hex"
},
@ -2172,10 +2169,6 @@
"restore": {
"message": "Restaurar"
},
"restoreWalletPreferences": {
"message": "Encontramos um backup dos seus dados de $1. Gostaria de restaurar as preferências da sua carteira?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Tentar transação novamente"
},
@ -2887,15 +2880,6 @@
"syncWithMobileTitle": {
"message": "Sincronizar com dispositivo móvel"
},
"syncWithThreeBox": {
"message": "Sincronizar dados com 3Box (experimental)"
},
"syncWithThreeBoxDescription": {
"message": "Ative para fazer backup das suas configurações com o 3Box. Esse recurso é experimental; use por sua conta e risco."
},
"syncWithThreeBoxDisabled": {
"message": "O 3Box foi desabilitado por conta de um erro durante a sincronização inicial"
},
"tenPercentIncreased": {
"message": "10% de aumento"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "Адрес в запросе на вход не соответствует адресу счета, который вы используете для входа."
},
"SIWEDomainInvalid": {
"message": "Веб-сайт, на который вы пытаетесь войти ($1), не соответствует домену в запросе на вход. Действуйте с осторожностью.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "Веб-сайт ($1) просит вас войти в неправильный домен. Это может быть фишинговая атака.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "Данные"
},
"dataBackupFoundInfo": {
"message": "Некоторые данные вашего счета были скопированы во время предыдущей установки MetaMask. Они могли включать ваши настройки, контакты и токены. Хотите восстановить эти данные сейчас?"
},
"dataBackupSeemsCorrupt": {
"message": "Не удается восстановить ваши данные. Файл, по-видимому, поврежден."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "Вы можете восстановить пользовательские настройки, содержащие настройки и адреса аккаунтов, из ранее сохраненного файла JSON."
},
"restoreWalletPreferences": {
"message": "Найдена резервная копия ваших данных из $1. Хотите восстановить настройки кошелька?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Повторить транзакцию"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "Синхронизировать с мобильным устройством"
},
"syncWithThreeBox": {
"message": "Синхронизировать данные с 3Box (экспериментальная функция)"
},
"syncWithThreeBoxDescription": {
"message": "Включите, чтобы скопировать ваши настройки с помощью 3Box. Эта функция в настоящее время является экспериментальной. Используйте ее на свой страх и риск."
},
"syncWithThreeBoxDisabled": {
"message": "3Box отключен из-за ошибки во время первоначальной синхронизации"
},
"tenPercentIncreased": {
"message": "Увеличение на 10%"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "Ang address sa request sa pag-sign in ay hindi tugma sa address ng account na ginagamit mo sa pag-sign in."
},
"SIWEDomainInvalid": {
"message": "Ang website kung saan mo sinusubukang mag-sign in sa ($1) ay hindi tugma sa domain sa request sa pag-sign in. Magpatuloy nang may pag-iingat.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "Hinihiling sa iyo ng website ($1) na mag-sign in sa maling domain. Posibleng phishing na pag-atake ito.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "Datos"
},
"dataBackupFoundInfo": {
"message": "Ang ilan sa data ng iyong account ay na-back up sa nakaraang pag-install ng MetaMask. Maaaring kasama rito ang iyong mga setting, contact, at token. Gusto mo bang i-restore na ang data na ito?"
},
"dataBackupSeemsCorrupt": {
"message": "Hindi maibalik ang iyong datos. Mukhang sira ang file."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "Maaari mong ibalik ang mga setting ng user na naglalaman ng mga kagustuhan at mga address ng account mula sa isang dating na-back up na JSON file."
},
"restoreWalletPreferences": {
"message": "Nakita ang backup ng iyong data mula sa $1. Gusto mo bang i-restore ang mga kagustuhan mo sa wallet?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Subukan Ulit ang Transaksyon"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "I-sync sa mobile"
},
"syncWithThreeBox": {
"message": "I-sync ang data sa 3Box (pinag-eeksperimentuhan)"
},
"syncWithThreeBoxDescription": {
"message": "I-on para ma-back up ang iyong mga setting sa 3Box. Kasalukuyang pinag-eeksperimentuhan ang feature na ito; gamitin sa sarili mong pagpapasya."
},
"syncWithThreeBoxDisabled": {
"message": "Na-disable ang 3Box dahil sa isang error sa unang pag-sync"
},
"tenPercentIncreased": {
"message": "10% na dagdag"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "Giriş talebindeki adres, giriş yapmak için kullandığınız hesapla uyumlu değil."
},
"SIWEDomainInvalid": {
"message": "Giriş yapmaya çalıştığınız web sitesi ($1) giriş talebindeki alan ile uyumlu değil. Dikkati olarak ilerleyin.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "Web sitesi ($1) yanlış alana giriş yapmanızı istiyor. Bu bir dolandırıcılık saldırısı olabilir.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "Veri"
},
"dataBackupFoundInfo": {
"message": "MetaMask'ın önceki bir kurulumu sırasında hesap verilerinizden bazıları yedeklenmiştir. Buna ayarlar, kişiler ve tokenler dahil olabilir. Bu verileri şimdi geri yüklemek ister misiniz?"
},
"dataBackupSeemsCorrupt": {
"message": "Verileriniz geri yüklenemedi. Dosyanın bozuk olduğu algılandı."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "Tercihleri ve hesap adreslerini içeren kullanıcı ayarlarını daha önce yedeklenmiş bir JSON dosyasından geri yükleyebilirsiniz."
},
"restoreWalletPreferences": {
"message": "Verilerinizin $1 tarihinden bir yedeği bulundu. Cüzdan tercihlerinizi geri yüklemek ister misiniz?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "İşlemi Tekrar Dene"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "Mobil ile senkronize et"
},
"syncWithThreeBox": {
"message": "Verileri 3Box ile senkronize et (deneysel)"
},
"syncWithThreeBoxDescription": {
"message": "Ayarlarınızın 3Box ile yedeklenmesini sağlamak için açın. Bu özellik şu anda deney aşamasındadır; kullanım riski size aittir."
},
"syncWithThreeBoxDisabled": {
"message": "İlk senkronizasyon işlemi sırasındaki bir hata nedeniyle 3Box devre dışı bırakıldı"
},
"tenPercentIncreased": {
"message": "%10 artış"
},

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "Địa chỉ trong yêu cầu đăng nhập không trùng khớp với địa chỉ của tài khoản bạn đang sử dụng để đăng nhập."
},
"SIWEDomainInvalid": {
"message": "Trang web bạn đang cố gắng đăng nhập vào ($1) không trùng khớp với tên miền trong yêu cầu đăng nhập. Hãy thực hiện cẩn thận.",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "Trang web ($1) đang yêu cầu bạn đăng nhập vào một tên miền không đúng. Đây có thể là một cuộc tấn công lừa đảo.",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "Dữ liệu"
},
"dataBackupFoundInfo": {
"message": "Một số dữ liệu tài khoản của bạn đã được sao lưu trong lần cài đặt MetaMask trước đó. Dữ liệu này có thể bao gồm các tùy chọn cài đặt, danh bạ và token. Bạn có muốn khôi phục dữ liệu này bây giờ không?"
},
"dataBackupSeemsCorrupt": {
"message": "Không thể khôi phục dữ liệu của bạn. Tập tin có vẻ đã bị hỏng."
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "Bạn có thể khôi phục cài đặt người dùng chứa các tùy chọn và địa chỉ tài khoản từ tập tin JSON đã sao lưu trước đó."
},
"restoreWalletPreferences": {
"message": "Đã tìm thấy bản sao lưu dữ liệu của bạn từ $1. Bạn có muốn khôi phục các tùy chọn ưu tiên trong ví của mình không?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "Thử lại giao dịch"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "Đồng bộ với thiết bị di động"
},
"syncWithThreeBox": {
"message": "Đồng bộ dữ liệu với 3Box (thử nghiệm)"
},
"syncWithThreeBoxDescription": {
"message": "Bật để sao lưu các tùy chọn cài đặt của bạn với 3Box. Tính năng này hiện đang trong giai đoạn thử nghiệm; bạn tự chịu rủi ro khi sử dụng."
},
"syncWithThreeBoxDisabled": {
"message": "Đã tắt 3Box do có lỗi xảy ra trong quá trình đồng bộ ban đầu"
},
"tenPercentIncreased": {
"message": "Tăng 10%"
},

File diff suppressed because it is too large Load Diff

@ -47,10 +47,6 @@
"SIWEAddressInvalid": {
"message": "登录请求中的地址与您用于登录的账户地址不匹配。"
},
"SIWEDomainInvalid": {
"message": "您尝试登录的网站($1)与登录请求中的域名不匹配。请谨慎行事。",
"description": "$1 represents the website domain"
},
"SIWEDomainWarningBody": {
"message": "网站($1)要求您登录到错误的域名。这可能是网络钓鱼攻击。",
"description": "$1 represents the website domain"
@ -882,9 +878,6 @@
"data": {
"message": "数据"
},
"dataBackupFoundInfo": {
"message": "您的部分账户数据已在之前安装 MetaMask 时备份。其中可能包括您的设置、联系人和代币。您现在想恢复这些数据吗?"
},
"dataBackupSeemsCorrupt": {
"message": "无法还原数据。文件似乎已损坏。"
},
@ -2869,10 +2862,6 @@
"restoreUserDataDescription": {
"message": "您可以使用以前备份的JSON文件来恢复包含首选项和账户地址的用户设置。"
},
"restoreWalletPreferences": {
"message": "已找到 $1 的数据备份。您想恢复您的钱包偏好设置吗?",
"description": "$1 is the date at which the data was backed up"
},
"retryTransaction": {
"message": "重试交易"
},
@ -3845,15 +3834,6 @@
"syncWithMobileTitle": {
"message": "与移动设备同步"
},
"syncWithThreeBox": {
"message": "与 3Box 同步数据(实验功能)"
},
"syncWithThreeBoxDescription": {
"message": "开启以使用 3Box 备份您的设置。此功能目前是实验功能,使用时风险自负。"
},
"syncWithThreeBoxDisabled": {
"message": "由于初始同步过程中出现错误,3Box 已被禁用"
},
"tenPercentIncreased": {
"message": "增加10%"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-search-filled" viewBox="0 0 512 512">
<path d="m241 440c108 0 195-87 195-194 0-108-87-195-195-195-107 0-194 87-194 195 0 107 87 194 194 194z m201 21c-4 0-7-2-10-4l-38-38c-6-6-6-15 0-21 5-5 14-5 20 0l38 38c6 6 6 15 0 21-3 2-6 4-10 4z"/>
<path d="m450 469c-5 0-10-2-14-5l-38-39c-4-4-6-9-6-14 0-5 2-10 6-13 3-4 8-6 13-6 5 0 10 2 14 6l39 38c3 4 5 9 5 14 0 5-2 10-5 14-4 3-9 5-14 5z m-204-19c-112 0-203-91-203-204 0-112 91-203 203-203 113 0 204 91 204 203 0 113-91 204-204 204z m0-369c-43 0-85 18-116 49-31 31-49 73-49 116 0 44 18 86 49 117 31 31 73 48 116 48 44 0 86-17 117-48 31-31 48-73 48-117 0-43-17-85-48-116-31-31-73-49-117-49z"/>
</svg>

Before

Width:  |  Height:  |  Size: 294 B

After

Width:  |  Height:  |  Size: 493 B

@ -7,9 +7,8 @@ import pump from 'pump';
import debounce from 'debounce-stream';
import log from 'loglevel';
import browser from 'webextension-polyfill';
import { storeAsStream, storeTransformStream } from '@metamask/obs-store';
import { storeAsStream } from '@metamask/obs-store';
import PortStream from 'extension-port-stream';
import { captureException } from '@sentry/browser';
import { ethErrors } from 'eth-rpc-errors';
import {
@ -289,16 +288,11 @@ async function loadStateFromPersistence() {
if (!versionedData) {
throw new Error('MetaMask - migrator returned undefined');
}
// this initializes the meta/version data as a class variable to be used for future writes
localStore.setMetadata(versionedData.meta);
// write to disk
if (localStore.isSupported) {
localStore.set(versionedData);
} else {
// throw in setTimeout so as to not block boot
setTimeout(() => {
throw new Error('MetaMask - Localstore not supported');
});
}
localStore.set(versionedData.data);
// return just the data
return versionedData.data;
@ -338,6 +332,7 @@ function setupController(initState, initLangCode, remoteSourcePort) {
getOpenMetamaskTabsIds: () => {
return openMetamaskTabsIDs;
},
localStore,
});
setupEnsIpfsResolver({
@ -354,8 +349,7 @@ function setupController(initState, initLangCode, remoteSourcePort) {
pump(
storeAsStream(controller.store),
debounce(1000),
storeTransformStream(versionifyData),
createStreamSink(persistData),
createStreamSink((state) => localStore.set(state)),
(error) => {
log.error('MetaMask - Persistence pipeline failed', error);
},
@ -363,43 +357,6 @@ function setupController(initState, initLangCode, remoteSourcePort) {
setupSentryGetStateGlobal(controller);
/**
* Assigns the given state to the versioned object (with metadata), and returns that.
*
* @param {object} state - The state object as emitted by the MetaMaskController.
* @returns {VersionedData} The state object wrapped in an object that includes a metadata key.
*/
function versionifyData(state) {
versionedData.data = state;
return versionedData;
}
let dataPersistenceFailing = false;
async function persistData(state) {
if (!state) {
throw new Error('MetaMask - updated state is missing');
}
if (!state.data) {
throw new Error('MetaMask - updated state does not have data');
}
if (localStore.isSupported) {
try {
await localStore.set(state);
if (dataPersistenceFailing) {
dataPersistenceFailing = false;
}
} catch (err) {
// log error so we dont break the pipeline
if (!dataPersistenceFailing) {
dataPersistenceFailing = true;
captureException(err);
}
log.error('error setting state in local store:', err);
}
}
}
//
// connect to other contexts
//

@ -18,6 +18,9 @@ import {
TRAITS,
} from '../../../shared/constants/metametrics';
import { SECOND } from '../../../shared/constants/time';
import { isManifestV3 } from '../../../shared/modules/mv3.utils';
import { METAMETRICS_FINALIZE_EVENT_FRAGMENT_ALARM } from '../../../shared/constants/alarms';
import { checkAlarmExists } from '../lib/util';
const EXTENSION_UNINSTALL_URL = 'https://metamask.io/uninstalled';
@ -62,7 +65,7 @@ const exceptionsToFilter = {
export default class MetaMetricsController {
/**
* @param {object} options
* @param {object} options.segment - an instance of analytics-node for tracking
* @param {object} options.segment - an instance of analytics for tracking
* events that conform to the new MetaMetrics tracking plan.
* @param {object} options.preferencesStore - The preferences controller store, used
* to access and subscribe to preferences that will be attached to events
@ -144,7 +147,41 @@ export default class MetaMetricsController {
// within the fragment's timeout window. When creating a new event fragment
// a timeout can be specified that will cause an abandoned event to be
// tracked if the event isn't progressed within that amount of time.
if (isManifestV3) {
/* eslint-disable no-undef */
chrome.alarms.getAll((alarms) => {
const hasAlarm = checkAlarmExists(
alarms,
METAMETRICS_FINALIZE_EVENT_FRAGMENT_ALARM,
);
if (!hasAlarm) {
chrome.alarms.create(METAMETRICS_FINALIZE_EVENT_FRAGMENT_ALARM, {
delayInMinutes: 1,
periodInMinutes: 1,
});
}
});
chrome.alarms.onAlarm.addListener(() => {
chrome.alarms.getAll((alarms) => {
const hasAlarm = checkAlarmExists(
alarms,
METAMETRICS_FINALIZE_EVENT_FRAGMENT_ALARM,
);
if (hasAlarm) {
this.finalizeAbandonedFragments();
}
});
});
} else {
setInterval(() => {
this.finalizeAbandonedFragments();
}, SECOND * 30);
}
}
finalizeAbandonedFragments() {
Object.values(this.store.getState().fragments).forEach((fragment) => {
if (
fragment.timeout &&
@ -153,7 +190,6 @@ export default class MetaMetricsController {
this.finalizeEventFragment(fragment.id, { abandoned: true });
}
});
}, SECOND * 30);
}
generateMetaMetricsId() {
@ -678,7 +714,7 @@ export default class MetaMetricsController {
).length,
[TRAITS.NUMBER_OF_TOKENS]: this._getNumberOfTokens(metamaskState),
[TRAITS.OPENSEA_API_ENABLED]: metamaskState.openSeaEnabled,
[TRAITS.THREE_BOX_ENABLED]: metamaskState.threeBoxSyncingAllowed,
[TRAITS.THREE_BOX_ENABLED]: false, // deprecated, hard-coded as false
[TRAITS.THEME]: metamaskState.theme || 'default',
[TRAITS.TOKEN_DETECTION_ENABLED]: metamaskState.useTokenDetection,
};

@ -675,7 +675,6 @@ describe('MetaMetricsController', function () {
identities: [{}, {}],
ledgerTransportType: 'web-hid',
openSeaEnabled: true,
threeBoxSyncingAllowed: false,
useCollectibleDetection: false,
theme: 'default',
useTokenDetection: true,
@ -714,7 +713,6 @@ describe('MetaMetricsController', function () {
ledgerTransportType: 'web-hid',
openSeaEnabled: true,
identities: [{}, {}],
threeBoxSyncingAllowed: false,
useCollectibleDetection: false,
theme: 'default',
useTokenDetection: true,
@ -735,7 +733,6 @@ describe('MetaMetricsController', function () {
ledgerTransportType: 'web-hid',
openSeaEnabled: false,
identities: [{}, {}, {}],
threeBoxSyncingAllowed: false,
useCollectibleDetection: false,
theme: 'default',
useTokenDetection: true,
@ -764,7 +761,6 @@ describe('MetaMetricsController', function () {
ledgerTransportType: 'web-hid',
openSeaEnabled: true,
identities: [{}, {}],
threeBoxSyncingAllowed: false,
useCollectibleDetection: true,
theme: 'default',
useTokenDetection: true,
@ -783,7 +779,6 @@ describe('MetaMetricsController', function () {
ledgerTransportType: 'web-hid',
openSeaEnabled: true,
identities: [{}, {}],
threeBoxSyncingAllowed: false,
useCollectibleDetection: true,
theme: 'default',
useTokenDetection: true,

@ -1,305 +0,0 @@
import { ObservableStore } from '@metamask/obs-store';
/* eslint-disable import/first,import/order */
const Box = process.env.IN_TEST
? require('../../../development/mock-3box')
: require('3box');
/* eslint-enable import/order */
import log from 'loglevel';
import { JsonRpcEngine } from 'json-rpc-engine';
import { providerFromEngine } from 'eth-json-rpc-middleware';
import Migrator from '../lib/migrator';
import migrations from '../migrations';
import createOriginMiddleware from '../lib/createOriginMiddleware';
import createMetamaskMiddleware from './network/createMetamaskMiddleware';
/* eslint-enable import/first */
const SYNC_TIMEOUT = 60 * 1000; // one minute
export default class ThreeBoxController {
constructor(opts = {}) {
const {
preferencesController,
keyringController,
addressBookController,
version,
getKeyringControllerState,
trackMetaMetricsEvent,
} = opts;
this.preferencesController = preferencesController;
this.addressBookController = addressBookController;
this.keyringController = keyringController;
this.provider = this._createProvider({
version,
getAccounts: async ({ origin }) => {
if (origin !== '3Box') {
return [];
}
const { isUnlocked } = getKeyringControllerState();
const accounts = await this.keyringController.getAccounts();
if (isUnlocked && accounts[0]) {
const appKeyAddress = await this.keyringController.getAppKeyAddress(
accounts[0],
'wallet://3box.metamask.io',
);
return [appKeyAddress];
}
return [];
},
processPersonalMessage: async (msgParams) => {
const accounts = await this.keyringController.getAccounts();
return keyringController.signPersonalMessage(
{ ...msgParams, from: accounts[0] },
{
withAppKeyOrigin: 'wallet://3box.metamask.io',
},
);
},
});
this._trackMetaMetricsEvent = trackMetaMetricsEvent;
const initState = {
threeBoxSyncingAllowed: false,
showRestorePrompt: true,
threeBoxLastUpdated: 0,
...opts.initState,
threeBoxAddress: null,
threeBoxSynced: false,
threeBoxDisabled: false,
};
this.store = new ObservableStore(initState);
this.registeringUpdates = false;
this.lastMigration = migrations
.sort((a, b) => a.version - b.version)
.slice(-1)[0];
if (initState.threeBoxSyncingAllowed) {
this.init();
}
}
async init() {
const accounts = await this.keyringController.getAccounts();
this.address = accounts[0];
this._trackMetaMetricsEvent({
event: '3Box Initiated',
category: '3Box',
});
if (this.address && !(this.box && this.store.getState().threeBoxSynced)) {
await this.new3Box();
}
}
async _update3Box() {
try {
const { threeBoxSyncingAllowed, threeBoxSynced } = this.store.getState();
if (threeBoxSyncingAllowed && threeBoxSynced) {
const newState = {
preferences: this.preferencesController.store.getState(),
addressBook: this.addressBookController.state,
lastUpdated: Date.now(),
lastMigration: this.lastMigration,
};
await this.space.private.set(
'metamaskBackup',
JSON.stringify(newState),
);
await this.setShowRestorePromptToFalse();
}
} catch (error) {
console.error(error);
}
}
_createProvider(providerOpts) {
const metamaskMiddleware = createMetamaskMiddleware(providerOpts);
const engine = new JsonRpcEngine();
engine.push(createOriginMiddleware({ origin: '3Box' }));
engine.push(metamaskMiddleware);
const provider = providerFromEngine(engine);
return provider;
}
_waitForOnSyncDone() {
return new Promise((resolve) => {
this.box.onSyncDone(() => {
log.debug('3Box box sync done');
return resolve();
});
});
}
async new3Box() {
const accounts = await this.keyringController.getAccounts();
this.address = await this.keyringController.getAppKeyAddress(
accounts[0],
'wallet://3box.metamask.io',
);
let backupExists;
try {
const threeBoxConfig = await Box.getConfig(this.address);
backupExists = threeBoxConfig.spaces && threeBoxConfig.spaces.metamask;
} catch (e) {
if (e.message.match(/^Error: Invalid response \(404\)/u)) {
this._trackMetaMetricsEvent({
event: '3Box Backup does not exist',
category: '3Box',
});
backupExists = false;
} else {
this._trackMetaMetricsEvent({
event: '3Box Config Error',
category: '3Box',
});
throw e;
}
}
if (this.getThreeBoxSyncingState() || backupExists) {
this.store.updateState({ threeBoxSynced: false });
let timedOut = false;
const syncTimeout = setTimeout(() => {
log.error(`3Box sync timed out after ${SYNC_TIMEOUT} ms`);
timedOut = true;
this.store.updateState({
threeBoxDisabled: true,
threeBoxSyncingAllowed: false,
});
}, SYNC_TIMEOUT);
try {
this.box = await Box.openBox(this.address, this.provider);
await this._waitForOnSyncDone();
this.space = await this.box.openSpace('metamask', {
onSyncDone: async () => {
const stateUpdate = {
threeBoxSynced: true,
threeBoxAddress: this.address,
};
if (timedOut) {
log.info(`3Box sync completed after timeout; no longer disabled`);
stateUpdate.threeBoxDisabled = false;
}
clearTimeout(syncTimeout);
this.store.updateState(stateUpdate);
log.debug('3Box space sync done');
this._trackMetaMetricsEvent({
event: '3Box Synced',
category: '3Box',
});
},
});
} catch (e) {
this._trackMetaMetricsEvent({
event: '3Box Initiation Error',
category: '3Box',
});
console.error(e);
throw e;
}
}
}
async getLastUpdated() {
const res = await this.space.private.get('metamaskBackup');
const parsedRes = JSON.parse(res || '{}');
return parsedRes.lastUpdated;
}
async migrateBackedUpState(backedUpState) {
const migrator = new Migrator({ migrations });
const { preferences, addressBook } = JSON.parse(backedUpState);
const formattedStateBackup = {
PreferencesController: preferences,
AddressBookController: addressBook,
};
const initialMigrationState =
migrator.generateInitialState(formattedStateBackup);
const migratedState = await migrator.migrateData(initialMigrationState);
return {
preferences: migratedState.data.PreferencesController,
addressBook: migratedState.data.AddressBookController,
};
}
async restoreFromThreeBox() {
const backedUpState = await this.space.private.get('metamaskBackup');
const { preferences, addressBook } = await this.migrateBackedUpState(
backedUpState,
);
this.store.updateState({ threeBoxLastUpdated: backedUpState.lastUpdated });
preferences && this.preferencesController.store.updateState(preferences);
addressBook && this.addressBookController.update(addressBook, true);
this.setShowRestorePromptToFalse();
this._trackMetaMetricsEvent({
event: '3Box Restored Data',
category: '3Box',
});
}
turnThreeBoxSyncingOn() {
this._trackMetaMetricsEvent({
event: '3Box Sync Turned On',
category: '3Box',
});
this._registerUpdates();
}
turnThreeBoxSyncingOff() {
this._trackMetaMetricsEvent({
event: '3Box Sync Turned Off',
category: '3Box',
});
this.box.logout();
}
setShowRestorePromptToFalse() {
this.store.updateState({ showRestorePrompt: false });
}
setThreeBoxSyncingPermission(newThreeboxSyncingState) {
if (this.store.getState().threeBoxDisabled) {
return;
}
this.store.updateState({
threeBoxSyncingAllowed: newThreeboxSyncingState,
});
if (newThreeboxSyncingState && this.box) {
this.turnThreeBoxSyncingOn();
}
if (!newThreeboxSyncingState && this.box) {
this.turnThreeBoxSyncingOff();
}
}
getThreeBoxSyncingState() {
return this.store.getState().threeBoxSyncingAllowed;
}
_registerUpdates() {
if (!this.registeringUpdates) {
const updatePreferences = this._update3Box.bind(this);
this.preferencesController.store.subscribe(updatePreferences);
const updateAddressBook = this._update3Box.bind(this);
this.addressBookController.subscribe(updateAddressBook);
this.registeringUpdates = true;
}
}
}

@ -161,7 +161,6 @@ export default class TransactionController extends EventEmitter {
getNetwork: this.getNetwork.bind(this),
getCurrentChainId: opts.getCurrentChainId,
});
this._onBootCleanUp();
this.store = this.txStateManager.store;
this.nonceTracker = new NonceTracker({
@ -208,6 +207,7 @@ export default class TransactionController extends EventEmitter {
// request state update to finalize initialization
this._updatePendingTxsAfterFirstBlock();
this._onBootCleanUp();
}
/**

@ -1,6 +1,7 @@
import { ethErrors, serializeError } from 'eth-rpc-errors';
import { isManifestV3 } from '../../../shared/modules/mv3.utils';
const createMetaRPCHandler = (api, outStream) => {
const createMetaRPCHandler = (api, outStream, store, localStoreApiWrapper) => {
return async (data) => {
if (outStream._writableState.ended) {
return;
@ -22,6 +23,10 @@ const createMetaRPCHandler = (api, outStream) => {
result = await api[data.method](...data.params);
} catch (err) {
error = err;
} finally {
if (isManifestV3 && store && data.method !== 'getState') {
localStoreApiWrapper.set(store.getState());
}
}
if (outStream._writableState.ended) {

@ -1,8 +1,10 @@
import browser from 'webextension-polyfill';
import allLocales from '../../_locales/index.json';
// ensure that we default users with browser language code 'zh' to the supported 'zh_CN' language code
const existingLocaleCodes = { zh: 'zh_CN' };
// mapping some browsers return hyphen instead underscore in locale codes (e.g. zh_TW -> zh-tw)
const existingLocaleCodes = {};
allLocales.forEach((locale) => {
if (locale && locale.code) {
existingLocaleCodes[locale.code.toLowerCase().replace('_', '-')] =

@ -1,5 +1,6 @@
import browser from 'webextension-polyfill';
import log from 'loglevel';
import { captureException } from '@sentry/browser';
import { checkForError } from './util';
/**
@ -11,6 +12,45 @@ export default class ExtensionStore {
if (!this.isSupported) {
log.error('Storage local API not available.');
}
// we use this flag to avoid flooding sentry with a ton of errors:
// once data persistence fails once and it flips true we don't send further
// data persistence errors to sentry
this.dataPersistenceFailing = false;
}
setMetadata(initMetaData) {
this.metadata = initMetaData;
}
async set(state) {
if (!this.isSupported) {
throw new Error(
'Metamask- cannot persist state to local store as this browser does not support this action',
);
}
if (!state) {
throw new Error('MetaMask - updated state is missing');
}
if (!this.metadata) {
throw new Error(
'MetaMask - metadata must be set on instance of ExtensionStore before calling "set"',
);
}
try {
// we format the data for storage as an object with the "data" key for the controller state object
// and the "meta" key for a metadata object containing a version number that tracks how the data shape
// has changed using migrations to adapt to backwards incompatible changes
await this._set({ data: state, meta: this.metadata });
if (this.dataPersistenceFailing) {
this.dataPersistenceFailing = false;
}
} catch (err) {
if (!this.dataPersistenceFailing) {
this.dataPersistenceFailing = true;
captureException(err);
}
log.error('error setting state in local store:', err);
}
}
/**
@ -31,16 +71,6 @@ export default class ExtensionStore {
return result;
}
/**
* Sets the key in local state
*
* @param {object} state - The state to set
* @returns {Promise<void>}
*/
async set(state) {
return this._set(state);
}
/**
* Returns all of the keys currently saved
*

@ -0,0 +1,79 @@
import browser from 'webextension-polyfill';
import LocalStore from './local-store';
jest.mock('webextension-polyfill', () => ({
storage: { local: true },
}));
const setup = ({ isSupported }) => {
browser.storage.local = isSupported;
return new LocalStore();
};
describe('LocalStore', () => {
afterEach(() => {
jest.resetModules();
});
describe('contructor', () => {
it('should set isSupported property to false when browser does not support local storage', () => {
const localStore = setup({ isSupported: false });
expect(localStore.isSupported).toBe(false);
});
it('should set isSupported property to true when browser supports local storage', () => {
const localStore = setup({ isSupported: true });
expect(localStore.isSupported).toBe(true);
});
});
describe('setMetadata', () => {
it('should set the metadata property on LocalStore', () => {
const metadata = { version: 74 };
const localStore = setup({ isSupported: true });
localStore.setMetadata(metadata);
expect(localStore.metadata).toStrictEqual(metadata);
});
});
describe('set', () => {
it('should throw an error if called in a browser that does not support local storage', async () => {
const localStore = setup({ isSupported: false });
await expect(() => localStore.set()).rejects.toThrow(
'Metamask- cannot persist state to local store as this browser does not support this action',
);
});
it('should throw an error if not passed a truthy value as an argument', async () => {
const localStore = setup({ isSupported: true });
await expect(() => localStore.set()).rejects.toThrow(
'MetaMask - updated state is missing',
);
});
it('should throw an error if passed a valid argument but metadata has not yet been set', async () => {
const localStore = setup({ isSupported: true });
await expect(() =>
localStore.set({ appState: { test: true } }),
).rejects.toThrow(
'MetaMask - metadata must be set on instance of ExtensionStore before calling "set"',
);
});
it('should not throw if passed a valid argument and metadata has been set', async () => {
const localStore = setup({ isSupported: true });
localStore.setMetadata({ version: 74 });
await expect(async function () {
localStore.set({ appState: { test: true } });
}).not.toThrow();
});
});
describe('get', () => {
it('should return undefined if called in a browser that does not support local storage', async () => {
const localStore = setup({ isSupported: false });
const result = await localStore.get();
expect(result).toStrictEqual(undefined);
});
});
});

@ -50,16 +50,37 @@ export default class ReadOnlyNetworkStore {
return this._state;
}
/**
* Set metadata/version state
*
* @param {object} metadata - The metadata/version data to set
*/
setMetadata(metadata) {
this.metadata = metadata;
}
/**
* Set state
*
* @param {object} state - The state to set
* @returns {Promise<void>}
*/
async set(state) {
if (!this.isSupported) {
throw new Error(
'Metamask- cannot persist state to local store as this browser does not support this action',
);
}
if (!state) {
throw new Error('MetaMask - updated state is missing');
}
if (!this.metadata) {
throw new Error(
'MetaMask - metadata must be set on instance of ExtensionStore before calling "set"',
);
}
if (!this._initialized) {
await this._initializing;
}
this._state = state;
this._state = { data: state, meta: this._metadata };
}
}

@ -0,0 +1,275 @@
import removeSlash from 'remove-trailing-slash';
import looselyValidate from '@segment/loosely-validate-event';
import { isString } from 'lodash';
import isRetryAllowed from 'is-retry-allowed';
const noop = () => ({});
// Taken from https://stackoverflow.com/a/1349426/3696652
const characters =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const generateRandomId = () => {
let result = '';
const charactersLength = characters.length;
for (let i = 0; i < 20; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
};
// Method below is inspired from axios-retry https://github.com/softonic/axios-retry
function isNetworkError(error) {
return (
!error.response &&
Boolean(error.code) && // Prevents retrying cancelled requests
error.code !== 'ECONNABORTED' && // Prevents retrying timed out requests
isRetryAllowed(error)
); // Prevents retrying unsafe errors
}
export default class Analytics {
/**
* Initialize a new `Analytics` with Segment project's `writeKey` and an
* optional dictionary of `options`.
*
* @param {string} writeKey
* @param {object} [options] - (optional)
* @property {number} [flushAt] (default: 20)
* @property {number} [flushInterval] (default: 10000)
* @property {string} [host] (default: 'https://api.segment.io')
*/
constructor(writeKey, options = {}) {
this.writeKey = writeKey;
this.host = removeSlash(options.host || 'https://api.segment.io');
this.flushInterval = options.flushInterval || 10000;
this.flushAt = options.flushAt || Math.max(options.flushAt, 1) || 20;
this.queue = [];
this.path = '/v1/batch';
this.maxQueueSize = 1024 * 450;
this.flushed = false;
this.retryCount = 3;
Object.defineProperty(this, 'enable', {
configurable: false,
writable: false,
enumerable: true,
value: true,
});
}
_validate(message, type) {
looselyValidate(message, type);
}
_message(type, message, callback) {
this._validate(message, type);
this.enqueue(type, message, callback);
return this;
}
/**
* Send an identify `message`.
*
* @param {object} message
* @param {Function} [callback] - (optional)
* @returns {Analytics}
*/
identify(message, callback) {
return this._message('identify', message, callback);
}
/**
* Send a track `message`.
*
* @param {object} message
* @param {Function} [callback] - (optional)
* @returns {Analytics}
*/
track(message, callback) {
return this._message('track', message, callback);
}
/**
* Send a page `message`.
*
* @param {object} message
* @param {Function} [callback] - (optional)
* @returns {Analytics}
*/
page(message, callback) {
return this._message('page', message, callback);
}
/**
* Add a `message` of type `type` to the queue and
* check whether it should be flushed.
*
* @param {string} type
* @param {object} msg
* @param {Function} [callback] - (optional)
*/
enqueue(type, msg, callback = noop) {
if (!this.enable) {
setImmediate(callback);
return;
}
const message = { ...msg, type };
// Specifying library here helps segment to understand structure of request.
// Currently segment seems to support these source libraries only.
message.context = {
...message.context,
library: {
name: 'analytics-node',
},
};
if (!message.timestamp) {
message.timestamp = new Date();
}
if (!message.messageId) {
message.messageId = generateRandomId();
}
if (message.anonymousId && !isString(message.anonymousId)) {
message.anonymousId = JSON.stringify(message.anonymousId);
}
if (message.userId && !isString(message.userId)) {
message.userId = JSON.stringify(message.userId);
}
this.queue.push({ message, callback });
if (!this.flushed) {
this.flushed = true;
this.flush();
return;
}
const hasReachedFlushAt = this.queue.length >= this.flushAt;
const hasReachedQueueSize =
this.queue.reduce((acc, item) => acc + JSON.stringify(item).length, 0) >=
this.maxQueueSize;
if (hasReachedFlushAt || hasReachedQueueSize) {
this.flush();
}
if (this.flushInterval && !this.timer) {
this.timer = setTimeout(this.flush.bind(this), this.flushInterval);
}
}
/**
* Flush the current queue
*
* @param {Function} [callback] - (optional)
*/
flush(callback = noop) {
if (!this.enable) {
setImmediate(callback);
return Promise.resolve();
}
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
if (!this.queue.length) {
setImmediate(callback);
return Promise.resolve();
}
const items = this.queue.splice(0, this.flushAt);
const callbacks = items.map((item) => item.callback);
const messages = items.map((item) => item.message);
const data = {
batch: messages,
timestamp: new Date(),
sentAt: new Date(),
};
const done = (err) => {
setImmediate(() => {
callbacks.forEach((fn) => fn(err, data));
callback(err, data);
});
};
const headers = {
Authorization: `Basic ${Buffer.from(this.writeKey, 'utf8').toString(
'base64',
)}`,
};
return this._sendRequest(
`${this.host}${this.path}`,
{
method: 'POST',
body: JSON.stringify(data),
headers,
},
done,
0,
);
}
_retryRequest(url, body, done, retryNo) {
const delay = Math.pow(2, retryNo) * 100;
setTimeout(() => {
this._sendRequest(url, body, done, retryNo + 1);
}, delay);
}
async _sendRequest(url, body, done, retryNo) {
return fetch(url, body)
.then(async (response) => {
if (response.ok) {
done();
} else if (
this._isErrorRetryable({ response }) &&
retryNo <= this.retryCount
) {
this._retryRequest(url, body, done, retryNo);
} else {
const error = new Error(response.statusText);
done(error);
}
})
.catch((error) => {
if (this._isErrorRetryable(error) && retryNo <= this.retryCount) {
this._retryRequest(url, body, done, retryNo);
} else {
done(error);
}
});
}
_isErrorRetryable(error) {
// Retry Network Errors.
if (isNetworkError(error)) {
return true;
}
if (!error.response) {
// Cannot determine if the request can be retried
return false;
}
// Retry Server Errors (5xx).
if (error.response.status >= 500 && error.response.status <= 599) {
return true;
}
// Retry if rate limited.
if (error.response.status === 429) {
return true;
}
return false;
}
}

@ -0,0 +1,116 @@
import Analytics from './analytics';
const DUMMY_KEY = 'DUMMY_KEY';
const DUMMY_MESSAGE = {
userId: 'userId',
idValue: 'idValue',
event: 'event',
};
const FLUSH_INTERVAL = 10000;
global.setImmediate = (arg) => {
arg();
};
global.fetch = () =>
Promise.resolve({
ok: true,
json: () => Promise.resolve({ success: true }),
});
describe('Analytics', function () {
let analytics;
beforeEach(() => {
analytics = new Analytics(DUMMY_KEY);
});
describe('#flush', function () {
it('first message is immediately flushed', function () {
const mock = jest.fn(analytics.flush);
analytics.flush = mock;
analytics.track(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(0);
expect(mock).toHaveBeenCalledTimes(1);
});
it('after first message it is called when queue size equals flushAt value', function () {
analytics = new Analytics(DUMMY_KEY, { flushAt: 3 });
const mock = jest.fn(analytics.flush);
analytics.flush = mock;
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(0);
expect(mock).toHaveBeenCalledTimes(2);
});
it('except for first message it is called until queue size is less than flushAt value', function () {
analytics = new Analytics(DUMMY_KEY, { flushAt: 3 });
const mock = jest.fn(analytics.flush);
analytics.flush = mock;
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(2);
expect(mock).toHaveBeenCalledTimes(1);
});
it('after first message it is called after flushInterval is elapsed', function () {
jest.useFakeTimers();
analytics = new Analytics(DUMMY_KEY, { flushInterval: FLUSH_INTERVAL });
const mock = jest.fn(analytics.flush);
analytics.flush = mock;
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
jest.advanceTimersByTime(FLUSH_INTERVAL);
expect(analytics.queue).toHaveLength(0);
expect(mock).toHaveBeenCalledTimes(2);
});
it('after first message it is not called until flushInterval is elapsed', function () {
jest.useFakeTimers();
analytics = new Analytics(DUMMY_KEY, { flushInterval: FLUSH_INTERVAL });
const mock = jest.fn(analytics.flush);
analytics.flush = mock;
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
jest.advanceTimersByTime(FLUSH_INTERVAL - 100);
expect(analytics.queue).toHaveLength(1);
expect(mock).toHaveBeenCalledTimes(1);
});
it('invokes callbacks', async function () {
const callback = jest.fn();
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE, callback);
await analytics.flush();
expect(callback).toHaveBeenCalledTimes(1);
});
});
describe('#track', function () {
it('adds messages to ququq', function () {
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(1);
});
});
describe('#page', function () {
it('adds messages to ququq', function () {
analytics.page(DUMMY_MESSAGE);
analytics.page(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(1);
});
});
describe('#identify', function () {
it('adds messages to ququq', function () {
analytics.identify(DUMMY_MESSAGE);
analytics.identify(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(1);
});
});
});

@ -1,5 +1,5 @@
import Analytics from 'analytics-node';
import { SECOND } from '../../../shared/constants/time';
import { SECOND } from '../../../../shared/constants/time';
import Analytics from './analytics';
const SEGMENT_WRITE_KEY = process.env.SEGMENT_WRITE_KEY ?? null;
const SEGMENT_HOST = process.env.SEGMENT_HOST ?? null;

@ -53,11 +53,6 @@ export const SENTRY_STATE = {
type: true,
},
seedPhraseBackedUp: true,
showRestorePrompt: true,
threeBoxDisabled: true,
threeBoxLastUpdated: true,
threeBoxSynced: true,
threeBoxSyncingAllowed: true,
unapprovedDecryptMsgCount: true,
unapprovedEncryptionPublicKeyMsgCount: true,
unapprovedMsgCount: true,
@ -226,7 +221,7 @@ function rewriteReportUrls(report) {
}
function toMetamaskUrl(origUrl) {
const filePath = origUrl.split(window.location.origin)[1];
const filePath = origUrl.split(globalThis.location.origin)[1];
if (!filePath) {
return origUrl;
}

@ -152,6 +152,17 @@ function getChainType(chainId) {
return 'custom';
}
/**
* Checks if the alarmname exists in the list
*
* @param {Array} alarmList
* @param alarmName
* @returns
*/
function checkAlarmExists(alarmList, alarmName) {
return alarmList.some((alarm) => alarm.name === alarmName);
}
export {
getPlatform,
getEnvironmentType,
@ -161,4 +172,5 @@ export {
addHexPrefix,
bnToHex,
getChainType,
checkAlarmExists,
};

@ -1,6 +1,11 @@
import { strict as assert } from 'assert';
import sinon from 'sinon';
import proxyquire from 'proxyquire';
import {
ApprovalRequestNotFoundError,
PermissionsRequestNotFoundError,
} from '@metamask/controllers';
import { ORIGIN_METAMASK } from '../../shared/constants/app';
const Ganache = require('../../test/e2e/ganache');
@ -238,4 +243,137 @@ describe('MetaMaskController', function () {
assert.deepEqual(transaction1, transaction2);
});
});
describe('#removePermissionsFor', function () {
it('should not propagate PermissionsRequestNotFoundError', function () {
const error = new PermissionsRequestNotFoundError('123');
metamaskController.permissionController = {
revokePermissions: () => {
throw error;
},
};
// Line below will not throw error, in case it throws this test case will fail.
metamaskController.removePermissionsFor({ subject: 'test_subject' });
});
it('should propagate Error other than PermissionsRequestNotFoundError', function () {
const error = new Error();
metamaskController.permissionController = {
revokePermissions: () => {
throw error;
},
};
assert.throws(() => {
metamaskController.removePermissionsFor({ subject: 'test_subject' });
}, error);
});
});
describe('#rejectPermissionsRequest', function () {
it('should not propagate PermissionsRequestNotFoundError', function () {
const error = new PermissionsRequestNotFoundError('123');
metamaskController.permissionController = {
rejectPermissionsRequest: () => {
throw error;
},
};
// Line below will not throw error, in case it throws this test case will fail.
metamaskController.rejectPermissionsRequest('DUMMY_ID');
});
it('should propagate Error other than PermissionsRequestNotFoundError', function () {
const error = new Error();
metamaskController.permissionController = {
rejectPermissionsRequest: () => {
throw error;
},
};
assert.throws(() => {
metamaskController.rejectPermissionsRequest('DUMMY_ID');
}, error);
});
});
describe('#acceptPermissionsRequest', function () {
it('should not propagate PermissionsRequestNotFoundError', function () {
const error = new PermissionsRequestNotFoundError('123');
metamaskController.permissionController = {
acceptPermissionsRequest: () => {
throw error;
},
};
// Line below will not throw error, in case it throws this test case will fail.
metamaskController.acceptPermissionsRequest('DUMMY_ID');
});
it('should propagate Error other than PermissionsRequestNotFoundError', function () {
const error = new Error();
metamaskController.permissionController = {
acceptPermissionsRequest: () => {
throw error;
},
};
assert.throws(() => {
metamaskController.acceptPermissionsRequest('DUMMY_ID');
}, error);
});
});
describe('#resolvePendingApproval', function () {
it('should not propagate ApprovalRequestNotFoundError', function () {
const error = new ApprovalRequestNotFoundError('123');
metamaskController.approvalController = {
accept: () => {
throw error;
},
};
// Line below will not throw error, in case it throws this test case will fail.
metamaskController.resolvePendingApproval('DUMMY_ID', 'DUMMY_VALUE');
});
it('should propagate Error other than ApprovalRequestNotFoundError', function () {
const error = new Error();
metamaskController.approvalController = {
accept: () => {
throw error;
},
};
assert.throws(() => {
metamaskController.resolvePendingApproval('DUMMY_ID', 'DUMMY_VALUE');
}, error);
});
});
describe('#rejectPendingApproval', function () {
it('should not propagate ApprovalRequestNotFoundError', function () {
const error = new ApprovalRequestNotFoundError('123');
metamaskController.approvalController = {
reject: () => {
throw error;
},
};
// Line below will not throw error, in case it throws this test case will fail.
metamaskController.rejectPendingApproval('DUMMY_ID', {
code: 1,
message: 'DUMMY_MESSAGE',
data: 'DUMMY_DATA',
});
});
it('should propagate Error other than ApprovalRequestNotFoundError', function () {
const error = new Error();
metamaskController.approvalController = {
reject: () => {
throw error;
},
};
assert.throws(() => {
metamaskController.rejectPendingApproval('DUMMY_ID', {
code: 1,
message: 'DUMMY_MESSAGE',
data: 'DUMMY_DATA',
});
}, error);
});
});
});

@ -39,6 +39,8 @@ import {
CollectibleDetectionController,
PermissionController,
SubjectMetadataController,
PermissionsRequestNotFoundError,
ApprovalRequestNotFoundError,
///: BEGIN:ONLY_INCLUDE_IN(flask)
RateLimitController,
NotificationController,
@ -123,7 +125,6 @@ import AppStateController from './controllers/app-state';
import CachedBalancesController from './controllers/cached-balances';
import AlertController from './controllers/alert';
import OnboardingController from './controllers/onboarding';
import ThreeBoxController from './controllers/threebox';
import BackupController from './controllers/backup';
import IncomingTransactionsController from './controllers/incoming-transactions';
import MessageManager, { normalizeMsgData } from './lib/message-manager';
@ -201,6 +202,9 @@ export default class MetamaskController extends EventEmitter {
this.controllerMessenger = new ControllerMessenger();
// instance of a class that wraps the extension's storage local API.
this.localStoreApiWrapper = opts.localStore;
// observable state store
this.store = new ComposableObservableStore({
state: initState,
@ -247,7 +251,9 @@ export default class MetamaskController extends EventEmitter {
this.tokenListController = new TokenListController({
chainId: hexToDecimal(this.networkController.getCurrentChainId()),
preventPollingOnNetworkRestart: true,
preventPollingOnNetworkRestart: initState.TokenListController
? initState.TokenListController.preventPollingOnNetworkRestart
: true,
onNetworkStateChange: (cb) => {
this.networkController.store.subscribe((networkState) => {
const modifiedNetworkState = {
@ -767,20 +773,6 @@ export default class MetamaskController extends EventEmitter {
preferencesStore: this.preferencesController.store,
});
this.threeBoxController = new ThreeBoxController({
preferencesController: this.preferencesController,
addressBookController: this.addressBookController,
keyringController: this.keyringController,
initState: initState.ThreeBoxController,
getKeyringControllerState: this.keyringController.memStore.getState.bind(
this.keyringController.memStore,
),
version,
trackMetaMetricsEvent: this.metaMetricsController.trackEvent.bind(
this.metaMetricsController,
),
});
this.backupController = new BackupController({
preferencesController: this.preferencesController,
addressBookController: this.addressBookController,
@ -1038,7 +1030,6 @@ export default class MetamaskController extends EventEmitter {
PermissionController: this.permissionController,
PermissionLogController: this.permissionLogController.store,
SubjectMetadataController: this.subjectMetadataController,
ThreeBoxController: this.threeBoxController.store,
BackupController: this.backupController,
AnnouncementController: this.announcementController,
GasFeeController: this.gasFeeController,
@ -1077,7 +1068,6 @@ export default class MetamaskController extends EventEmitter {
PermissionController: this.permissionController,
PermissionLogController: this.permissionLogController.store,
SubjectMetadataController: this.subjectMetadataController,
ThreeBoxController: this.threeBoxController.store,
BackupController: this.backupController,
SwapsController: this.swapsController.store,
EnsController: this.ensController.store,
@ -1493,7 +1483,6 @@ export default class MetamaskController extends EventEmitter {
const {
addressBookController,
alertController,
approvalController,
appStateController,
collectiblesController,
collectibleDetectionController,
@ -1510,7 +1499,6 @@ export default class MetamaskController extends EventEmitter {
preferencesController,
qrHardwareKeyring,
swapsController,
threeBoxController,
tokensController,
smartTransactionsController,
txController,
@ -1799,32 +1787,10 @@ export default class MetamaskController extends EventEmitter {
setWeb3ShimUsageAlertDismissed:
alertController.setWeb3ShimUsageAlertDismissed.bind(alertController),
// 3Box
setThreeBoxSyncingPermission:
threeBoxController.setThreeBoxSyncingPermission.bind(
threeBoxController,
),
restoreFromThreeBox:
threeBoxController.restoreFromThreeBox.bind(threeBoxController),
setShowRestorePromptToFalse:
threeBoxController.setShowRestorePromptToFalse.bind(threeBoxController),
getThreeBoxLastUpdated:
threeBoxController.getLastUpdated.bind(threeBoxController),
turnThreeBoxSyncingOn:
threeBoxController.turnThreeBoxSyncingOn.bind(threeBoxController),
initializeThreeBox: this.initializeThreeBox.bind(this),
// permissions
removePermissionsFor:
permissionController.revokePermissions.bind(permissionController),
approvePermissionsRequest:
permissionController.acceptPermissionsRequest.bind(
permissionController,
),
rejectPermissionsRequest:
permissionController.rejectPermissionsRequest.bind(
permissionController,
),
removePermissionsFor: this.removePermissionsFor,
approvePermissionsRequest: this.acceptPermissionsRequest,
rejectPermissionsRequest: this.rejectPermissionsRequest,
...getPermissionBackgroundApiMethods(permissionController),
///: BEGIN:ONLY_INCLUDE_IN(flask)
@ -1942,14 +1908,8 @@ export default class MetamaskController extends EventEmitter {
),
// approval controller
resolvePendingApproval:
approvalController.accept.bind(approvalController),
rejectPendingApproval: async (id, error) => {
approvalController.reject(
id,
new EthereumRpcError(error.code, error.message, error.data),
);
},
resolvePendingApproval: this.resolvePendingApproval,
rejectPendingApproval: this.rejectPendingApproval,
// Notifications
updateViewedNotifications: announcementController.updateViewed.bind(
@ -2139,6 +2099,11 @@ export default class MetamaskController extends EventEmitter {
// clear permissions
this.permissionController.clearState();
///: BEGIN:ONLY_INCLUDE_IN(flask)
// Clear snap state
this.snapController.clearState();
///: END:ONLY_INCLUDE_IN
// clear accounts in accountTracker
this.accountTracker.clearAccounts();
@ -2345,20 +2310,6 @@ export default class MetamaskController extends EventEmitter {
log.error('Error while unlocking extension.', error);
}
try {
const threeBoxSyncingAllowed =
this.threeBoxController.getThreeBoxSyncingState();
if (threeBoxSyncingAllowed && !this.threeBoxController.box) {
// 'await' intentionally omitted to avoid waiting for initialization
this.threeBoxController.init();
this.threeBoxController.turnThreeBoxSyncingOn();
} else if (threeBoxSyncingAllowed && this.threeBoxController.box) {
this.threeBoxController.turnThreeBoxSyncingOn();
}
} catch (error) {
log.error('Error while unlocking extension.', error);
}
// This must be set as soon as possible to communicate to the
// keyring's iframe and have the setting initialized properly
// Optimistically called to not block MetaMask login due to
@ -3484,7 +3435,15 @@ export default class MetamaskController extends EventEmitter {
this.emit('controllerConnectionChanged', this.activeControllerConnections);
// set up postStream transport
outStream.on('data', createMetaRPCHandler(api, outStream));
outStream.on(
'data',
createMetaRPCHandler(
api,
outStream,
this.store,
this.localStoreApiWrapper,
),
);
const handleUpdate = (update) => {
if (outStream._writableState.ended) {
return;
@ -4226,10 +4185,6 @@ export default class MetamaskController extends EventEmitter {
return null;
}
async initializeThreeBox() {
await this.threeBoxController.init();
}
/**
* Sets the Ledger Live preference to use for Ledger hardware wallet support
*
@ -4343,4 +4298,57 @@ export default class MetamaskController extends EventEmitter {
return this.keyringController.setLocked();
}
removePermissionsFor = (subjects) => {
try {
this.permissionController.revokePermissions(subjects);
} catch (exp) {
if (!(exp instanceof PermissionsRequestNotFoundError)) {
throw exp;
}
}
};
rejectPermissionsRequest = (requestId) => {
try {
this.permissionController.rejectPermissionsRequest(requestId);
} catch (exp) {
if (!(exp instanceof PermissionsRequestNotFoundError)) {
throw exp;
}
}
};
acceptPermissionsRequest = (request) => {
try {
this.permissionController.acceptPermissionsRequest(request);
} catch (exp) {
if (!(exp instanceof PermissionsRequestNotFoundError)) {
throw exp;
}
}
};
resolvePendingApproval = (id, value) => {
try {
this.approvalController.accept(id, value);
} catch (exp) {
if (!(exp instanceof ApprovalRequestNotFoundError)) {
throw exp;
}
}
};
rejectPendingApproval = (id, error) => {
try {
this.approvalController.reject(
id,
new EthereumRpcError(error.code, error.message, error.data),
);
} catch (exp) {
if (!(exp instanceof ApprovalRequestNotFoundError)) {
throw exp;
}
}
};
}

@ -49,36 +49,6 @@ const firstTimeState = {
const ganacheServer = new Ganache();
const threeBoxSpies = {
_registerUpdates: sinon.spy(),
init: sinon.stub(),
getLastUpdated: sinon.stub(),
getThreeBoxSyncingState: sinon.stub().returns(true),
restoreFromThreeBox: sinon.stub(),
setShowRestorePromptToFalse: sinon.stub(),
setThreeBoxSyncingPermission: sinon.stub(),
turnThreeBoxSyncingOn: sinon.stub(),
};
class ThreeBoxControllerMock {
constructor() {
this._registerUpdates = threeBoxSpies._registerUpdates;
this.init = threeBoxSpies.init;
this.getLastUpdated = threeBoxSpies.getLastUpdated;
this.getThreeBoxSyncingState = threeBoxSpies.getThreeBoxSyncingState;
this.restoreFromThreeBox = threeBoxSpies.restoreFromThreeBox;
this.setShowRestorePromptToFalse =
threeBoxSpies.setShowRestorePromptToFalse;
this.setThreeBoxSyncingPermission =
threeBoxSpies.setThreeBoxSyncingPermission;
this.store = {
subscribe: () => undefined,
getState: () => ({}),
};
this.turnThreeBoxSyncingOn = threeBoxSpies.turnThreeBoxSyncingOn;
}
}
const browserPolyfillMock = {
runtime: {
id: 'fake-extension-id',
@ -116,7 +86,6 @@ const createLoggerMiddlewareMock = () => (req, res, next) => {
};
const MetaMaskController = proxyquire('./metamask-controller', {
'./controllers/threebox': { default: ThreeBoxControllerMock },
'./lib/createLoggerMiddleware': { default: createLoggerMiddlewareMock },
}).default;
@ -245,15 +214,10 @@ describe('MetaMaskController', function () {
});
describe('submitPassword', function () {
it('removes any identities that do not correspond to known accounts.', async function () {
const password = 'password';
beforeEach(async function () {
await metamaskController.createNewVaultAndKeychain(password);
threeBoxSpies.init.reset();
threeBoxSpies.turnThreeBoxSyncingOn.reset();
});
it('removes any identities that do not correspond to known accounts.', async function () {
const fakeAddress = '0xbad0';
metamaskController.preferencesController.addAddresses([fakeAddress]);
await metamaskController.submitPassword(password);
@ -278,23 +242,6 @@ describe('MetaMaskController', function () {
);
});
});
it('gets the address from threebox and creates a new 3box instance', async function () {
await metamaskController.submitPassword(password);
assert(threeBoxSpies.init.calledOnce);
assert(threeBoxSpies.turnThreeBoxSyncingOn.calledOnce);
});
it('succeeds even if blockTracker or threeBoxController throw', async function () {
const throwErr = sinon.fake.throws('foo');
metamaskController.blockTracker.checkForLatestBlock = throwErr;
metamaskController.threeBoxController.getThreeBoxSyncingState = throwErr;
await metamaskController.submitPassword(password);
assert.ok(
throwErr.calledTwice,
'should have called checkForLatestBlock and getThreeBoxSyncingState',
);
});
});
describe('#createNewVaultAndKeychain', function () {

@ -0,0 +1,23 @@
import { cloneDeep } from 'lodash';
const version = 75;
/**
* Delete the ThreeBoxController.
*/
export default {
version,
async migrate(originalVersionedData) {
const versionedData = cloneDeep(originalVersionedData);
versionedData.meta.version = version;
const state = versionedData.data;
const newState = transformState(state);
versionedData.data = newState;
return versionedData;
},
};
function transformState(state) {
delete state.ThreeBoxController;
return state;
}

@ -0,0 +1,63 @@
import migration75 from './075';
describe('migration #75', () => {
it('should update the version metadata', async () => {
const oldStorage = {
meta: {
version: 74,
},
data: {},
};
const newStorage = await migration75.migrate(oldStorage);
expect(newStorage.meta).toStrictEqual({
version: 75,
});
});
it('should delete the ThreeBoxController', async () => {
const oldStorage = {
meta: {
version: 74,
},
data: {
FooController: { a: 'b' },
ThreeBoxController: {
stuff: 'stuff!',
moreStuff: { moreStuff: ['stuff', 'stuff', 'stuff'] },
},
},
};
const newStorage = await migration75.migrate(oldStorage);
expect(newStorage).toStrictEqual({
meta: {
version: 75,
},
data: {
FooController: { a: 'b' },
},
});
});
it('should handle missing ThreeBoxController', async () => {
const oldStorage = {
meta: {
version: 74,
},
data: {
FooController: { a: 'b' },
},
};
const newStorage = await migration75.migrate(oldStorage);
expect(newStorage).toStrictEqual({
meta: {
version: 75,
},
data: {
FooController: { a: 'b' },
},
});
});
});

@ -78,6 +78,7 @@ import m071 from './071';
import m072 from './072';
import m073 from './073';
import m074 from './074';
import m075 from './075';
const migrations = [
m002,
@ -153,6 +154,7 @@ const migrations = [
m072,
m073,
m074,
m075,
];
export default migrations;

@ -15,20 +15,28 @@ import launchMetaMaskUi, { updateBackgroundConnection } from '../../ui';
import {
ENVIRONMENT_TYPE_FULLSCREEN,
ENVIRONMENT_TYPE_POPUP,
PLATFORM_FIREFOX,
} from '../../shared/constants/app';
import { isManifestV3 } from '../../shared/modules/mv3.utils';
import { SUPPORT_LINK } from '../../shared/lib/ui-utils';
import { getErrorHtml } from '../../shared/lib/error-utils';
import ExtensionPlatform from './platforms/extension';
import { setupMultiplex } from './lib/stream-utils';
import { getEnvironmentType } from './lib/util';
import { getEnvironmentType, getPlatform } from './lib/util';
import metaRPCClientFactory from './lib/metaRPCClientFactory';
const container = document.getElementById('app-content');
const WORKER_KEEP_ALIVE_INTERVAL = 1000;
const ONE_SECOND_IN_MILLISECONDS = 1_000;
const WORKER_KEEP_ALIVE_INTERVAL = ONE_SECOND_IN_MILLISECONDS;
const WORKER_KEEP_ALIVE_MESSAGE = 'WORKER_KEEP_ALIVE_MESSAGE';
// Timeout for initializing phishing warning page.
const PHISHING_WARNING_PAGE_TIMEOUT = ONE_SECOND_IN_MILLISECONDS;
const PHISHING_WARNING_SW_STORAGE_KEY = 'phishing-warning-sw-registered';
/*
* As long as UI is open it will keep sending messages to service worker
* In service worker as this message is received
@ -58,6 +66,7 @@ async function start() {
const activeTab = await queryCurrentActiveTab(windowType);
let loadPhishingWarningPage;
/**
* In case of MV3 the issue of blank screen was very frequent, it is caused by UI initialising before background is ready to send state.
* Code below ensures that UI is rendered only after background is ready.
@ -68,7 +77,7 @@ async function start() {
* Code below ensures that UI is rendered only after CONNECTION_READY message is received thus background is ready.
* In case the UI is already rendered, only update the streams.
*/
const messageListener = (message) => {
const messageListener = async (message) => {
if (message?.name === 'CONNECTION_READY') {
if (isUIInitialised) {
// Currently when service worker is revived we create new streams
@ -77,6 +86,98 @@ async function start() {
} else {
initializeUiWithTab(activeTab);
}
await loadPhishingWarningPage();
}
};
/**
* An error thrown if the phishing warning page takes too long to load.
*/
class PhishingWarningPageTimeoutError extends Error {
constructor() {
super('Timeout failed');
}
}
/**
* Load the phishing warning page temporarily to ensure the service
* worker has been registered, so that the warning page works offline.
*/
loadPhishingWarningPage = async function () {
const currentPlatform = getPlatform();
// Check session storage for whether we've already initalized the phishing warning
// service worker this browser session and do not attempt to re-initialize if so.
const phishingSWMemoryFetch = await browser.storage.session.get(
PHISHING_WARNING_SW_STORAGE_KEY,
);
if (phishingSWMemoryFetch[PHISHING_WARNING_SW_STORAGE_KEY]) {
return;
}
let iframe;
try {
const extensionStartupPhishingPageUrl = new URL(
process.env.PHISHING_WARNING_PAGE_URL,
);
// The `extensionStartup` hash signals to the phishing warning page that it should not bother
// setting up streams for user interaction. Otherwise this page load would cause a console
// error.
extensionStartupPhishingPageUrl.hash = '#extensionStartup';
iframe = window.document.createElement('iframe');
iframe.setAttribute('src', extensionStartupPhishingPageUrl.href);
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
// Create "deferred Promise" to allow passing resolve/reject to event handlers
let deferredResolve;
let deferredReject;
const loadComplete = new Promise((resolve, reject) => {
deferredResolve = resolve;
deferredReject = reject;
});
// The load event is emitted once loading has completed, even if the loading failed.
// If loading failed we can't do anything about it, so we don't need to check.
iframe.addEventListener('load', deferredResolve);
// This step initiates the page loading.
window.document.body.appendChild(iframe);
// This timeout ensures that this iframe gets cleaned up in a reasonable
// timeframe, and ensures that the "initialization complete" message
// doesn't get delayed too long.
setTimeout(
() => deferredReject(new PhishingWarningPageTimeoutError()),
PHISHING_WARNING_PAGE_TIMEOUT,
);
await loadComplete;
// store a flag in sessions storage that we've already loaded the service worker
// and don't need to try again
if (currentPlatform === PLATFORM_FIREFOX) {
// Firefox does not yet support the storage.session API introduced in MV3
// Tracked here: https://bugzilla.mozilla.org/show_bug.cgi?id=1687778
console.error(
'Firefox does not support required MV3 APIs: Phishing warning page iframe and service worker will reload each page refresh',
);
} else {
browser.storage.session.set({
[PHISHING_WARNING_SW_STORAGE_KEY]: true,
});
}
} catch (error) {
if (error instanceof PhishingWarningPageTimeoutError) {
console.warn(
'Phishing warning page timeout; page not guaranteed to work offline.',
);
} else {
console.error('Failed to initialize phishing warning page', error);
}
} finally {
if (iframe) {
iframe.remove();
}
}
};

@ -11,7 +11,7 @@ start().catch((error) => {
async function start() {
const {
argv: { buildTypes, parallel },
argv: { buildTypes, parallel, devMode },
} = yargs(hideBin(process.argv)).usage(
'$0 [options]',
'Generate the LavaMoat policy file for one more more build types.',
@ -31,13 +31,22 @@ async function start() {
description: 'Whether to generate policies in parallel.',
type: 'boolean',
})
.option('devMode', {
alias: ['d'],
default: false,
demandOption: true,
description:
'Whether to run the process under lavamoat (devMode=false) or node (devMode=true)',
type: 'boolean',
})
.strict(),
);
const buildCommand = devMode ? 'build:dev' : 'build';
await concurrently(
(Array.isArray(buildTypes) ? buildTypes : [buildTypes]).map(
(buildType) => ({
command: `yarn build scripts:dist --policy-only --build-type=${buildType}`,
command: `yarn ${buildCommand} scripts:dist --policy-only --lint-fence-files=false --build-type=${buildType}`,
env: {
WRITE_AUTO_POLICY: 1,
},

@ -1,68 +0,0 @@
function delay(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
async function loadFromMock3Box(key) {
const res = await window.fetch(`http://localhost:8889?key=${key}`);
const text = await res.text();
return text.length ? JSON.parse(text) : null;
}
async function saveToMock3Box(key, newDataAtKey) {
const res = await window.fetch('http://localhost:8889', {
method: 'POST',
body: JSON.stringify({
key,
data: newDataAtKey,
}),
});
return res.text();
}
class Mock3Box {
static openBox(address) {
this.address = address;
return Promise.resolve({
onSyncDone: (cb) => {
setTimeout(cb, 200);
},
openSpace: async (spaceName, config) => {
const { onSyncDone } = config;
this.spaceName = spaceName;
setTimeout(onSyncDone, 150);
await delay(50);
return {
private: {
get: async (key) => {
await delay(50);
const res = await loadFromMock3Box(
`${this.address}-${this.spaceName}-${key}`,
);
return res;
},
set: async (key, data) => {
await saveToMock3Box(
`${this.address}-${this.spaceName}-${key}`,
data,
);
await delay(50);
return null;
},
},
};
},
logout: () => undefined,
});
}
static async getConfig(address) {
const backup = await loadFromMock3Box(`${address}-metamask-metamaskBackup`);
return backup ? { spaces: { metamask: {} } } : {};
}
}
module.exports = Mock3Box;

@ -48,7 +48,6 @@
"app/scripts/controllers/preferences.test.js",
"app/scripts/controllers/swaps.js",
"app/scripts/controllers/swaps.test.js",
"app/scripts/controllers/threebox.js",
"app/scripts/controllers/transactions/index.js",
"app/scripts/controllers/transactions/index.test.js",
"app/scripts/controllers/transactions/lib/tx-state-history-helpers.js",

@ -1,10 +1,3 @@
# End-to-end tests
This directory contains the fixture data used to bootstrap the individual e2e tests. Each sub-directory contains
one thing:
1. A `state.json` file that represents a the saved state for the extension (see _Generating fixture data_ below)
## Generating fixture data
Fixture data can be generated by following these steps:

@ -11,7 +11,7 @@ module.exports = {
coverageThreshold: {
global: {
branches: 44,
functions: 42,
functions: 46,
lines: 52,
statements: 52,
},

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -20,11 +20,6 @@
"fetch": true
}
},
"3box>graphql-request>cross-fetch>node-fetch": {
"globals": {
"fetch": true
}
},
"lodash": {
"globals": {
"setTimeout": true,

@ -1,11 +1,5 @@
{
"resources": {
"3box>ipfs>superstruct>clone-deep>shallow-clone>mixin-object": {
"packages": {
"3box>ipfs>superstruct>clone-deep>shallow-clone>mixin-object>for-in": true,
"webpack>micromatch>extglob>extend-shallow>is-extendable": true
}
},
"@babel/code-frame": {
"globals": {
"console.warn": true,
@ -2279,7 +2273,7 @@
"process": true
},
"packages": {
"analytics-node>ms": true,
"gulp-livereload>debug>ms": true,
"sinon>supports-color": true
}
},
@ -2392,7 +2386,7 @@
"process": true
},
"packages": {
"analytics-node>ms": true,
"gulp-livereload>debug>ms": true,
"sinon>supports-color": true
}
},
@ -2873,21 +2867,7 @@
},
"packages": {
"eslint>file-entry-cache>flat-cache>flatted": true,
"eslint>file-entry-cache>flat-cache>rimraf": true
}
},
"eslint>file-entry-cache>flat-cache>rimraf": {
"builtin": {
"assert": true,
"fs": true,
"path.join": true
},
"globals": {
"process.platform": true,
"setTimeout": true
},
"packages": {
"nyc>glob": true
"nyc>rimraf": true
}
},
"eslint>glob-parent": {
@ -3456,8 +3436,8 @@
"process": true
},
"packages": {
"analytics-node>ms": true,
"gulp-livereload>chalk>supports-color": true
"gulp-livereload>chalk>supports-color": true,
"gulp-livereload>debug>ms": true
}
},
"gulp-livereload>event-stream": {
@ -3583,7 +3563,7 @@
"process": true
},
"packages": {
"analytics-node>ms": true,
"gulp-livereload>debug>ms": true,
"sinon>supports-color": true
}
},
@ -3908,7 +3888,7 @@
"process": true
},
"packages": {
"analytics-node>ms": true,
"gulp-livereload>debug>ms": true,
"sinon>supports-color": true
}
},
@ -4124,9 +4104,9 @@
},
"gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic": {
"packages": {
"3box>ipfs>kind-of": true,
"gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic>math-random": true,
"gulp>undertaker>bach>array-last>is-number": true
"gulp>undertaker>bach>array-last>is-number": true,
"webpack>micromatch>kind-of": true
}
},
"gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic>math-random": {
@ -4796,7 +4776,6 @@
"process.platform": true
},
"packages": {
"3box>ipfs>kind-of": true,
"gulp>glob-watcher>anymatch>micromatch>define-property": true,
"gulp>glob-watcher>anymatch>micromatch>extend-shallow": true,
"gulp>glob-watcher>chokidar>braces": true,
@ -4804,6 +4783,7 @@
"webpack>micromatch>array-unique": true,
"webpack>micromatch>extglob": true,
"webpack>micromatch>fragment-cache": true,
"webpack>micromatch>kind-of": true,
"webpack>micromatch>nanomatch": true,
"webpack>micromatch>object.pick": true,
"webpack>micromatch>regex-not": true,
@ -5018,7 +4998,7 @@
},
"gulp>undertaker>arr-map>make-iterator": {
"packages": {
"3box>ipfs>kind-of": true
"webpack>micromatch>kind-of": true
}
},
"gulp>undertaker>bach": {
@ -5644,9 +5624,9 @@
},
"lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone": {
"packages": {
"3box>ipfs>superstruct>clone-deep>shallow-clone>mixin-object": true,
"lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>kind-of": true,
"lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>lazy-cache": true,
"lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>mixin-object": true,
"webpack>micromatch>extglob>extend-shallow>is-extendable": true
}
},
@ -5663,6 +5643,12 @@
"process.env.UNLAZY": true
}
},
"lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>mixin-object": {
"packages": {
"lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>mixin-object>for-in": true,
"webpack>micromatch>extglob>extend-shallow>is-extendable": true
}
},
"lavamoat>lavamoat-core>merge-deep>kind-of": {
"packages": {
"browserify>insert-module-globals>is-buffer": true
@ -5871,6 +5857,20 @@
"path.resolve": true
}
},
"nyc>rimraf": {
"builtin": {
"assert": true,
"fs": true,
"path.join": true
},
"globals": {
"process.platform": true,
"setTimeout": true
},
"packages": {
"nyc>glob": true
}
},
"nyc>signal-exit": {
"builtin": {
"assert.equal": true,
@ -7216,19 +7216,19 @@
},
"webpack>micromatch>define-property>is-descriptor": {
"packages": {
"3box>ipfs>kind-of": true,
"webpack>micromatch>define-property>is-descriptor>is-accessor-descriptor": true,
"webpack>micromatch>define-property>is-descriptor>is-data-descriptor": true
"webpack>micromatch>define-property>is-descriptor>is-data-descriptor": true,
"webpack>micromatch>kind-of": true
}
},
"webpack>micromatch>define-property>is-descriptor>is-accessor-descriptor": {
"packages": {
"3box>ipfs>kind-of": true
"webpack>micromatch>kind-of": true
}
},
"webpack>micromatch>define-property>is-descriptor>is-data-descriptor": {
"packages": {
"3box>ipfs>kind-of": true
"webpack>micromatch>kind-of": true
}
},
"webpack>micromatch>extglob": {
@ -7331,11 +7331,11 @@
"util.inspect": true
},
"packages": {
"3box>ipfs>kind-of": true,
"nyc>spawn-wrap>is-windows": true,
"webpack>micromatch>arr-diff": true,
"webpack>micromatch>array-unique": true,
"webpack>micromatch>fragment-cache": true,
"webpack>micromatch>kind-of": true,
"webpack>micromatch>nanomatch>define-property": true,
"webpack>micromatch>nanomatch>extend-shallow": true,
"webpack>micromatch>nanomatch>is-odd": true,
@ -7648,7 +7648,7 @@
},
"webpack>micromatch>snapdragon>use": {
"packages": {
"3box>ipfs>kind-of": true
"webpack>micromatch>kind-of": true
}
},
"webpack>micromatch>to-regex": {

@ -73,10 +73,10 @@
"lavamoat:build": "lavamoat development/build/index.js --policy lavamoat/build-system/policy.json --policyOverride lavamoat/build-system/policy-override.json",
"lavamoat:build:auto": "yarn lavamoat:build --writeAutoPolicy",
"lavamoat:debug:build": "yarn lavamoat:build --writeAutoPolicyDebug --policydebug lavamoat/build-system/policy-debug.json",
"lavamoat:background:auto": "node ./development/generate-lavamoat-policies.js",
"lavamoat:background:auto:ci": "node ./development/generate-lavamoat-policies.js --parallel=false",
"lavamoat:auto": "yarn lavamoat:build:auto && yarn lavamoat:background:auto",
"lavamoat:auto:ci": "yarn lavamoat:build:auto && yarn lavamoat:background:auto:ci",
"lavamoat:webapp:auto": "node ./development/generate-lavamoat-policies.js --devMode=true",
"lavamoat:webapp:auto:ci": "node ./development/generate-lavamoat-policies.js --parallel=false",
"lavamoat:auto": "yarn lavamoat:build:auto && yarn lavamoat:webapp:auto",
"lavamoat:auto:ci": "yarn lavamoat:build:auto && yarn lavamoat:webapp:auto:ci",
"ts-migration:enumerate": "ts-node development/ts-migration-dashboard/scripts/write-list-of-files-to-convert.ts",
"ts-migration:dashboard:watch": "ts-node development/ts-migration-dashboard/scripts/build.ts --watch",
"ts-migration:dashboard:build": "ts-node development/ts-migration-dashboard/scripts/build.ts",
@ -91,25 +91,15 @@
"**/redux/symbol-observable": "^2.0.3",
"**/redux-devtools-instrument/symbol-observable": "^2.0.3",
"**/rxjs/symbol-observable": "^2.0.3",
"**/xmlhttprequest-ssl": "^1.6.2",
"3box/ipfs/ipld-zcash/zcash-bitcore-lib/lodash": "^4.17.21",
"3box/ipfs/ipld-zcash/zcash-bitcore-lib/elliptic": "^6.5.4",
"3box/ipfs/libp2p-mdns/multicast-dns/dns-packet": "^5.2.2",
"3box/ipfs/prometheus-gc-stats/gc-stats/node-pre-gyp/tar": "^6.1.2",
"3box/**/libp2p-crypto/node-forge": "^1.3.0",
"3box/**/libp2p-keychain/node-forge": "^1.3.0",
"3box/ipfs/libp2p-webrtc-star/socket.io/engine.io": "^4.0.0",
"3box/**/@hapi/hoek": "^8.5.1",
"analytics-node/axios": "^0.21.2",
"ganache-core/lodash": "^4.17.21",
"netmask": "^2.0.1",
"pubnub/superagent-proxy": "^3.0.0",
"pull-ws": "^3.3.2",
"json-schema": "^0.4.0",
"simple-get": "^4.0.1"
"simple-get": "^4.0.1",
"@storybook/**/ast-types": "^0.14.2"
},
"dependencies": {
"3box": "^1.10.2",
"@babel/runtime": "^7.5.5",
"@download/blockies": "^1.0.3",
"@ensdomains/content-hash": "^2.5.6",
@ -142,6 +132,7 @@
"@ngraveio/bc-ur": "^1.1.6",
"@popperjs/core": "^2.4.0",
"@reduxjs/toolkit": "^1.6.2",
"@segment/loosely-validate-event": "^2.0.0",
"@sentry/browser": "^6.0.0",
"@sentry/integrations": "^6.0.0",
"@sentry/types": "^6.0.1",
@ -151,7 +142,6 @@
"@truffle/decoder": "^5.1.0",
"@zxing/browser": "^0.0.10",
"@zxing/library": "0.8.0",
"analytics-node": "^3.4.0-beta.3",
"await-semaphore": "^0.1.1",
"base32-encode": "^1.2.0",
"base64-js": "^1.5.1",
@ -168,7 +158,7 @@
"eth-json-rpc-filters": "^4.2.1",
"eth-json-rpc-middleware": "^9.0.1",
"eth-keyring-controller": "^7.0.2",
"eth-lattice-keyring": "^0.12.0",
"eth-lattice-keyring": "^0.12.3",
"eth-method-registry": "^2.0.0",
"eth-query": "^2.1.2",
"eth-rpc-errors": "^4.0.2",
@ -188,6 +178,7 @@
"globalthis": "^1.0.1",
"human-standard-token-abi": "^2.0.0",
"immer": "^9.0.6",
"is-retry-allowed": "^2.2.0",
"jest-junit": "^14.0.1",
"json-rpc-engine": "^6.1.0",
"json-rpc-middleware-stream": "^2.1.1",
@ -225,6 +216,7 @@
"readable-stream": "^2.3.3",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"remove-trailing-slash": "^0.1.1",
"reselect": "^3.0.1",
"safe-event-emitter": "^1.0.1",
"ses": "^0.12.4",
@ -303,7 +295,7 @@
"browserify": "^16.5.1",
"chalk": "^3.0.0",
"chokidar": "^3.5.3",
"chromedriver": "^105.0.0",
"chromedriver": "^107.0.0",
"concurrently": "^5.2.0",
"copy-webpack-plugin": "^6.0.3",
"cross-spawn": "^7.0.3",
@ -417,23 +409,6 @@
"chromedriver": true,
"geckodriver": true,
"react-devtools>electron": true,
"3box>ipfs-postmsg-proxy>peer-id>libp2p-crypto>libp2p-crypto-secp256k1>secp256k1": false,
"3box>ipfs>ipfs-repo>datastore-level>leveldown": false,
"3box>ipfs>ipfs-unixfs-importer>rabin-wasm>assemblyscript": false,
"3box>ipfs>ipld-ethereum>ethereumjs-account>ethereumjs-util>keccak": false,
"3box>ipfs>ipld-ethereum>ethereumjs-account>ethereumjs-util>secp256k1": false,
"3box>ipfs>ipld-ethereum>ethereumjs-block>ethereumjs-util>keccak": false,
"3box>ipfs>ipld-ethereum>ethereumjs-block>ethereumjs-util>secp256k1": false,
"3box>ipfs>ipld-ethereum>ethereumjs-tx>ethereumjs-util>keccak": false,
"3box>ipfs>ipld-ethereum>ethereumjs-tx>ethereumjs-util>secp256k1": false,
"3box>ipfs>ipld-ethereum>merkle-patricia-tree>ethereumjs-util>keccak": false,
"3box>ipfs>ipld-ethereum>merkle-patricia-tree>ethereumjs-util>secp256k1": false,
"3box>ipfs>libp2p-crypto>libp2p-crypto-secp256k1>secp256k1": false,
"3box>ipfs>libp2p-crypto>ursa-optional": false,
"3box>ipfs>prometheus-gc-stats>gc-stats": false,
"3box>orbit-db>orbit-db-cache>leveldown": false,
"3box>orbit-db>orbit-db-keystore>leveldown": false,
"3box>orbit-db>orbit-db-keystore>libp2p-crypto-secp256k1>secp256k1": false,
"@eth-optimism/contracts>@ethersproject/hardware-wallets>@ledgerhq/hw-transport-node-hid>@ledgerhq/hw-transport-node-hid-noevents>node-hid": false,
"@eth-optimism/contracts>@ethersproject/hardware-wallets>@ledgerhq/hw-transport-node-hid>node-hid": false,
"@eth-optimism/contracts>@ethersproject/hardware-wallets>@ledgerhq/hw-transport-node-hid>usb": false,

@ -40,14 +40,15 @@ index a5f9f7d..0000000
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/CryptoAccount.ts b/node_modules/@keystonehq/bc-ur-registry/src/CryptoAccount.ts
deleted file mode 100644
index 753e535..0000000
index e6efeeb..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/CryptoAccount.ts
+++ /dev/null
@@ -1,57 +0,0 @@
@@ -1,58 +0,0 @@
-import { CryptoOutput } from '.';
-import { decodeToDataItem, DataItem } from './lib';
-import { RegistryItem } from './RegistryItem';
-import { RegistryTypes } from './RegistryType';
-import { DataItemMap } from './types';
-
-enum Keys {
- masterFingerprint = 1,
@ -70,7 +71,7 @@ index 753e535..0000000
- public getOutputDescriptors = () => this.outputDescriptors;
-
- public toDataItem = () => {
- const map = {};
- const map: DataItemMap = {};
- if (this.masterFingerprint) {
- map[Keys.masterFingerprint] = this.masterFingerprint.readUInt32BE(0);
- }
@ -103,13 +104,14 @@ index 753e535..0000000
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/CryptoCoinInfo.ts b/node_modules/@keystonehq/bc-ur-registry/src/CryptoCoinInfo.ts
deleted file mode 100644
index 0201682..0000000
index 843b50c..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/CryptoCoinInfo.ts
+++ /dev/null
@@ -1,58 +0,0 @@
@@ -1,59 +0,0 @@
-import { decodeToDataItem, DataItem } from './lib';
-import { RegistryItem } from './RegistryItem';
-import { RegistryTypes } from './RegistryType';
-import { DataItemMap } from './types';
-
-enum Keys {
- type = '1',
@ -143,7 +145,7 @@ index 0201682..0000000
- };
-
- public toDataItem = () => {
- const map = {};
- const map: DataItemMap = {};
- if (this.type) {
- map[Keys.type] = this.type;
- }
@ -167,13 +169,14 @@ index 0201682..0000000
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/CryptoECKey.ts b/node_modules/@keystonehq/bc-ur-registry/src/CryptoECKey.ts
deleted file mode 100644
index 1e964fc..0000000
index 54c3c4b..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/CryptoECKey.ts
+++ /dev/null
@@ -1,59 +0,0 @@
@@ -1,68 +0,0 @@
-import { decodeToDataItem, DataItem } from './lib';
-import { RegistryItem } from './RegistryItem';
-import { RegistryTypes } from './RegistryType';
-import { DataItemMap, ICryptoKey } from './types';
-
-enum Keys {
- curve = 1,
@ -181,17 +184,21 @@ index 1e964fc..0000000
- data,
-}
-
-export class CryptoECKey extends RegistryItem {
-export class CryptoECKey extends RegistryItem implements ICryptoKey {
- private data: Buffer;
- private curve: number;
- private privateKey: boolean;
- private curve: number | undefined;
- private privateKey: boolean | undefined;
- constructor(args: { data: Buffer; curve?: number; privateKey?: boolean }) {
- super();
- this.data = args.data;
- this.curve = args.curve;
- this.privateKey = args.privateKey;
- this.privateKey = args.privateKey || undefined;
- }
-
- isECKey = () => {
- return true;
- };
-
- public getCurve = () => this.curve || 0;
- public isPrivateKey = () => this.privateKey || false;
- public getData = () => this.data;
@ -201,7 +208,7 @@ index 1e964fc..0000000
- };
-
- toDataItem = () => {
- const map = {};
- const map: DataItemMap = {};
- if (this.curve) {
- map[Keys.curve] = this.curve;
- }
@ -212,6 +219,10 @@ index 1e964fc..0000000
- return new DataItem(map);
- };
-
- getOutputDescriptorContent = () => {
- return this.data.toString('hex');
- }
-
- static fromDataItem = (dataItem: DataItem) => {
- const map = dataItem.getData();
- const curve = map[Keys.curve];
@ -232,16 +243,20 @@ index 1e964fc..0000000
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/CryptoHDKey.ts b/node_modules/@keystonehq/bc-ur-registry/src/CryptoHDKey.ts
deleted file mode 100644
index bbfd331..0000000
index 8fc2a82..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/CryptoHDKey.ts
+++ /dev/null
@@ -1,210 +0,0 @@
@@ -1,237 +0,0 @@
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-import { encode } from 'bs58check';
-import { CryptoCoinInfo } from './CryptoCoinInfo';
-import { CryptoKeypath } from './CryptoKeypath';
-import { decodeToDataItem, DataItem } from './lib';
-import { RegistryItem } from './RegistryItem';
-import { RegistryTypes } from './RegistryType';
-import { DataItemMap, ICryptoKey } from './types';
-import { PathComponent } from './PathComponent';
-
-enum Keys {
- is_master = 1,
@ -274,17 +289,22 @@ index bbfd331..0000000
- name?: string;
- note?: string;
-};
-export class CryptoHDKey extends RegistryItem {
- private master: boolean;
- private privateKey: boolean;
- private key: Buffer;
- private chainCode: Buffer;
- private useInfo: CryptoCoinInfo;
- private origin: CryptoKeypath;
- private children: CryptoKeypath;
- private parentFingerprint: Buffer;
- private name: string;
- private note: string;
-
-export class CryptoHDKey extends RegistryItem implements ICryptoKey {
- private master?: boolean;
- private privateKey?: boolean;
- private key?: Buffer;
- private chainCode?: Buffer;
- private useInfo?: CryptoCoinInfo;
- private origin?: CryptoKeypath;
- private children?: CryptoKeypath;
- private parentFingerprint?: Buffer;
- private name?: string;
- private note?: string;
-
- isECKey = () => {
- return false;
- };
-
- public getKey = () => this.key;
- public getChainCode = () => this.chainCode;
@ -299,20 +319,22 @@ index bbfd331..0000000
- public getBip32Key = () => {
- let version: Buffer;
- let depth: number;
- let index: number;
- let index = 0;
- let parentFingerprint: Buffer = Buffer.alloc(4).fill(0);
- if (this.isMaster()) {
- // version bytes defined on https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#serialization-format
- version = Buffer.from("0488ADE4", "hex")
- version = Buffer.from('0488ADE4', 'hex');
- depth = 0;
- index = 0;
- } else {
- depth = this.getOrigin().getComponents().length || this.getOrigin().getDepth();
- const paths = this.getOrigin().getComponents();
- depth = this.getOrigin()?.getComponents().length || this.getOrigin()?.getDepth() as number;
- const paths = this.getOrigin()?.getComponents() as PathComponent[];
- const lastPath = paths[paths.length - 1];
- if (lastPath) {
- index = lastPath.isHardened() ? lastPath.getIndex()! + 0x80000000 : lastPath.getIndex()!;
- parentFingerprint = this.getParentFingerprint();
- if (this.getParentFingerprint()) {
- parentFingerprint = this.getParentFingerprint() as Buffer;
- }
- }
- if (this.isPrivateKey()) {
- version = Buffer.from('0488ADE4', 'hex');
@ -326,13 +348,29 @@ index bbfd331..0000000
- indexBuffer.writeUInt32BE(index, 0);
- const chainCode = this.getChainCode();
- const key = this.getKey();
- return encode(Buffer.concat([version, depthBuffer, parentFingerprint, indexBuffer, chainCode, key]));
- }
- return encode(Buffer.concat([version, depthBuffer, parentFingerprint, indexBuffer, chainCode as Buffer, key as Buffer]));
- };
-
- public getRegistryType = () => {
- return RegistryTypes.CRYPTO_HDKEY;
- };
-
- public getOutputDescriptorContent = () => {
- let result = '';
- if (this.getOrigin()) {
- if (this.getOrigin()?.getSourceFingerprint() && this.getOrigin()?.getPath()) {
- result += `${this.getOrigin()?.getSourceFingerprint()?.toString('hex')}/${this.getOrigin()?.getPath()}`;
- }
- }
- result += this.getBip32Key();
- if (this.getChildren()) {
- if (this.getChildren()?.getPath()) {
- result += `/${this.getChildren()?.getPath()}`;
- }
- }
- return result;
- };
-
- constructor(args: DeriveKeyProps | MasterKeyProps) {
- super();
- if (args.isMaster) {
@ -362,7 +400,7 @@ index bbfd331..0000000
- };
-
- public toDataItem = () => {
- const map = {};
- const map: DataItemMap = {};
- if (this.master) {
- map[Keys.is_master] = true;
- map[Keys.key_data] = this.key;
@ -418,8 +456,8 @@ index bbfd331..0000000
- const children = map[Keys.children]
- ? CryptoKeypath.fromDataItem(map[Keys.children])
- : undefined;
- let _parentFingerprint = map[Keys.parent_fingerprint];
- let parentFingerprint: Buffer;
- const _parentFingerprint = map[Keys.parent_fingerprint];
- let parentFingerprint: Buffer | undefined = undefined;
- if (_parentFingerprint) {
- parentFingerprint = Buffer.alloc(4);
- parentFingerprint.writeUInt32BE(_parentFingerprint, 0);
@ -448,14 +486,15 @@ index bbfd331..0000000
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/CryptoKeypath.ts b/node_modules/@keystonehq/bc-ur-registry/src/CryptoKeypath.ts
deleted file mode 100644
index 4babe91..0000000
index 00146ce..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/CryptoKeypath.ts
+++ /dev/null
@@ -1,95 +0,0 @@
@@ -1,96 +0,0 @@
-import { decodeToDataItem, DataItem } from './lib';
-import { PathComponent } from './PathComponent';
-import { RegistryItem } from './RegistryItem';
-import { RegistryTypes } from './RegistryType';
-import { DataItemMap } from './types';
-
-enum Keys {
- components = 1,
@ -494,16 +533,16 @@ index 4babe91..0000000
- public getDepth = () => this.depth;
-
- toDataItem = () => {
- const map: Record<string, any> = {};
- const components = [];
- const map: DataItemMap = {};
- const components: (number | boolean | any[])[] = [];
- this.components &&
- this.components.forEach((component) => {
- if (component.isWildcard()) {
- components.push([]);
- } else {
- components.push(component.getIndex());
- components.push(component.getIndex() as number);
- }
- components.push(component.isHardened() ? true : false);
- components.push(component.isHardened());
- });
- map[Keys.components] = components;
- if (this.sourceFingerprint) {
@ -533,7 +572,7 @@ index 4babe91..0000000
- }
- }
- const _sourceFingerprint = map[Keys.source_fingerprint];
- let sourceFingerprint: Buffer;
- let sourceFingerprint: Buffer | undefined;
- if (_sourceFingerprint) {
- sourceFingerprint = Buffer.alloc(4);
- sourceFingerprint.writeUInt32BE(_sourceFingerprint, 0);
@ -549,10 +588,10 @@ index 4babe91..0000000
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/CryptoOutput.ts b/node_modules/@keystonehq/bc-ur-registry/src/CryptoOutput.ts
deleted file mode 100644
index cd3009c..0000000
index 90abf6f..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/CryptoOutput.ts
+++ /dev/null
@@ -1,114 +0,0 @@
@@ -1,127 +0,0 @@
-import { CryptoECKey } from './CryptoECKey';
-import { CryptoHDKey } from './CryptoHDKey';
-import { decodeToDataItem, DataItem } from './lib';
@ -599,6 +638,18 @@ index cd3009c..0000000
-
- public getScriptExpressions = () => this.scriptExpressions;
-
- private _toOutputDescriptor = (seIndex: number): string => {
- if (seIndex >= this.scriptExpressions.length) {
- return this.cryptoKey.getOutputDescriptorContent();
- } else {
- return `${this.scriptExpressions[seIndex].getExpression()}(${this._toOutputDescriptor(seIndex + 1)})`;
- }
- };
-
- public toString = () => {
- return this._toOutputDescriptor(0);
- };
-
- toDataItem = () => {
- let dataItem = this.cryptoKey.toDataItem();
- if (
@ -625,9 +676,10 @@ index cd3009c..0000000
- public static fromDataItem = (dataItem: DataItem) => {
- const scriptExpressions: ScriptExpression[] = [];
- let _dataItem = dataItem;
- // eslint-disable-next-line no-constant-condition
- while (true) {
- let _tag = _dataItem.getTag() || undefined;
- const se = ScriptExpression.fromTag(_tag);
- let _tag = _dataItem.getTag();
- const se = ScriptExpression.fromTag(_tag as number);
- if (se) {
- scriptExpressions.push(se);
- if (_dataItem.getData() instanceof DataItem) {
@ -707,10 +759,10 @@ index 626b647..0000000
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/Decoder/index.ts b/node_modules/@keystonehq/bc-ur-registry/src/Decoder/index.ts
deleted file mode 100644
index 0460694..0000000
index 5d7e3fe..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/Decoder/index.ts
+++ /dev/null
@@ -1,40 +0,0 @@
@@ -1,41 +0,0 @@
-import { URDecoder } from '@ngraveio/bc-ur';
-import {
- Bytes,
@ -723,6 +775,7 @@ index 0460694..0000000
- CryptoPSBT,
-} from '..';
-import { RegistryTypes } from '../RegistryType';
-import { UnknownURTypeError } from '../errors';
-
-export class URRegistryDecoder extends URDecoder {
- public resultRegistryType = () => {
@ -745,7 +798,7 @@ index 0460694..0000000
- case RegistryTypes.CRYPTO_ACCOUNT.getType():
- return CryptoAccount.fromCBOR(ur.cbor);
- default:
- throw new Error(
- throw new UnknownURTypeError(
- `#[ur-registry][Decoder][fn.resultRegistryType]: registry type ${ur.type} is not supported now`,
- );
- }
@ -753,15 +806,16 @@ index 0460694..0000000
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/MultiKey.ts b/node_modules/@keystonehq/bc-ur-registry/src/MultiKey.ts
deleted file mode 100644
index 0522fbd..0000000
index ced19dc..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/MultiKey.ts
+++ /dev/null
@@ -1,54 +0,0 @@
@@ -1,60 +0,0 @@
-import { CryptoECKey } from './CryptoECKey';
-import { CryptoHDKey } from './CryptoHDKey';
-import { DataItem } from './lib/DataItem';
-import { RegistryItem } from './RegistryItem';
-import { RegistryType, RegistryTypes } from './RegistryType';
-import { DataItemMap } from './types';
-
-enum Keys {
- threshold = 1,
@ -769,24 +823,24 @@ index 0522fbd..0000000
-}
-
-export class MultiKey extends RegistryItem {
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- getRegistryType: () => RegistryType;
-
- constructor(
- private threshold: number,
- private ecKeys: CryptoECKey[],
- private hdKeys: CryptoHDKey[],
- private keys: (CryptoECKey | CryptoHDKey)[],
- ) {
- super();
- }
-
- getThreshold = () => this.threshold;
- getEcKeys = () => this.ecKeys as CryptoECKey[];
- getHdKeys = () => this.hdKeys as CryptoHDKey[];
- getKeys = () => this.keys;
-
- toDataItem = () => {
- const map = {};
- const map: DataItemMap = {};
- map[Keys.threshold] = this.threshold;
- const keys: DataItem[] = [...this.ecKeys, ...this.hdKeys].map((k) => {
- const keys: DataItem[] = this.keys.map((k) => {
- const dataItem = k.toDataItem();
- dataItem.setTag(k.getRegistryType().getTag());
- return dataItem;
@ -795,20 +849,25 @@ index 0522fbd..0000000
- return new DataItem(map);
- };
-
- getOutputDescriptorContent = () => {
- return [this.getThreshold(),
- this.keys.map(k => k.getOutputDescriptorContent()).join(','),
- ].join(',');
- };
-
- static fromDataItem = (dataItem: DataItem) => {
- const map = dataItem.getData();
- const threshold = map[Keys.threshold];
- const keys = map[Keys.keys] as DataItem[];
- const ecKeys = [];
- const hdKeys = [];
- keys.forEach((k) => {
- const _keys = map[Keys.keys] as DataItem[];
- const keys: (CryptoECKey | CryptoHDKey)[] = [];
- _keys.forEach((k) => {
- if (k.getTag() === RegistryTypes.CRYPTO_HDKEY.getTag()) {
- hdKeys.push(CryptoHDKey.fromDataItem(k));
- keys.push(CryptoHDKey.fromDataItem(k));
- } else if (k.getTag() === RegistryTypes.CRYPTO_ECKEY.getTag()) {
- ecKeys.push(CryptoECKey.fromDataItem(k));
- keys.push(CryptoECKey.fromDataItem(k));
- }
- });
- return new MultiKey(threshold, ecKeys, hdKeys);
- return new MultiKey(threshold, keys);
- };
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/PathComponent.ts b/node_modules/@keystonehq/bc-ur-registry/src/PathComponent.ts
@ -914,7 +973,7 @@ index 64637bc..0000000
-};
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/ScriptExpression.ts b/node_modules/@keystonehq/bc-ur-registry/src/ScriptExpression.ts
deleted file mode 100644
index fdd3f05..0000000
index 8fbf0db..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/ScriptExpression.ts
+++ /dev/null
@@ -1,26 +0,0 @@
@ -940,16 +999,27 @@ index fdd3f05..0000000
- WITNESS_PUBLIC_KEY_HASH: new ScriptExpression(404, 'wpkh'),
- COMBO: new ScriptExpression(405, 'combo'),
- MULTISIG: new ScriptExpression(406, 'multi'),
- SORTED_MULTISIG: new ScriptExpression(407, 'sorted'),
- SORTED_MULTISIG: new ScriptExpression(407, 'sortedmulti'),
- ADDRESS: new ScriptExpression(307, 'addr'),
- RAW_SCRIPT: new ScriptExpression(408, 'raw'),
-};
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/errors/index.ts b/node_modules/@keystonehq/bc-ur-registry/src/errors/index.ts
deleted file mode 100644
index dd2b0bd..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/errors/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export class UnknownURTypeError extends Error {
- constructor(message: string) {
- super(message);
- }
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/index.ts b/node_modules/@keystonehq/bc-ur-registry/src/index.ts
deleted file mode 100644
index 172a1e5..0000000
index bb07bc8..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/index.ts
+++ /dev/null
@@ -1,89 +0,0 @@
@@ -1,110 +0,0 @@
-import './patchCBOR';
-
-import { CryptoHDKey } from './CryptoHDKey';
@ -971,6 +1041,7 @@ index 172a1e5..0000000
-import { ScriptExpressions } from './ScriptExpression';
-import { PathComponent } from './PathComponent';
-
-import { RegistryItem } from './RegistryItem';
-import { RegistryTypes, RegistryType } from './RegistryType';
-
-import {
@ -983,7 +1054,6 @@ index 172a1e5..0000000
-} from './lib';
-
-export { DataItem } from './lib';
-export { RegistryItem } from './RegistryItem';
-
-import { patchTags } from './utils';
-
@ -1014,9 +1084,12 @@ index 172a1e5..0000000
-
-const extend = {
- RegistryTypes,
- RegistryItem,
- RegistryType,
-
- decodeToDataItem,
- encodeDataItem,
-
- cbor,
-};
-
@ -1038,6 +1111,24 @@ index 172a1e5..0000000
- extend,
-};
-
-export * from './errors';
-export * from './Decoder';
-export * from './lib';
-export * from './CryptoAccount'
-export * from './CryptoPSBT'
-export * from './CryptoHDKey'
-export * from './CryptoOutput'
-export * from './CryptoCoinInfo'
-export * from './CryptoECKey'
-export * from './MultiKey'
-export * from './CryptoKeypath'
-export * from './patchCBOR'
-export * from './PathComponent'
-export * from './RegistryItem'
-export * from './RegistryType'
-export * from './types'
-export * from './utils'
-
-export default URlib;
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/lib/DataItem.ts b/node_modules/@keystonehq/bc-ur-registry/src/lib/DataItem.ts
deleted file mode 100644
@ -1070,12 +1161,54 @@ index 9727f7e..0000000
- return this.data;
- };
-}
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/lib/cbor-sync.d.ts b/node_modules/@keystonehq/bc-ur-registry/src/lib/cbor-sync.d.ts
deleted file mode 100644
index 6374ba7..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/lib/cbor-sync.d.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-export namespace config {
- const useToJSON: boolean;
-}
-export function addWriter(format: any, writerFunction: any): void;
-export function addReader(format: any, readerFunction: any): void;
-export function encode(data: any, format: any): any;
-export function encodeDataItem(data: any, format?: any): any;
-export function decode(data: any, format: any): any;
-export function decodeToDataItem(data: any, format?: any): import("./DataItem").DataItem;
-export function addSemanticEncode(tag: any, fn: any): {
- config: {
- useToJSON: boolean;
- };
- addWriter: (format: any, writerFunction: any) => void;
- addReader: (format: any, readerFunction: any) => void;
- encode: (data: any, format: any) => any;
- encodeDataItem: (data: any, format: any) => any;
- decode: (data: any, format: any) => any;
- decodeToDataItem: (data: any, format: any) => import("./DataItem").DataItem;
- addSemanticEncode: (tag: any, fn: any) => any;
- addSemanticDecode: (tag: any, fn: any) => any;
-};
-export function addSemanticDecode(tag: any, fn: any): {
- config: {
- useToJSON: boolean;
- };
- addWriter: (format: any, writerFunction: any) => void;
- addReader: (format: any, readerFunction: any) => void;
- encode: (data: any, format: any) => any;
- encodeDataItem: (data: any, format: any) => any;
- decode: (data: any, format: any) => any;
- decodeToDataItem: (data: any, format: any) => import("./DataItem").DataItem;
- addSemanticEncode: (tag: any, fn: any) => any;
- addSemanticDecode: (tag: any, fn: any) => any;
-};
-//# sourceMappingURL=cbor-sync.d.ts.map
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/lib/cbor-sync.js b/node_modules/@keystonehq/bc-ur-registry/src/lib/cbor-sync.js
deleted file mode 100644
index 63e5b3a..0000000
index df8db90..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/lib/cbor-sync.js
+++ /dev/null
@@ -1,695 +0,0 @@
@@ -1,693 +0,0 @@
-(function (global, factory) {
- if (typeof define === 'function' && define.amd) {
- define([], factory);
@ -1531,8 +1664,6 @@ index 63e5b3a..0000000
- semanticDecoders[tag] = fn;
- return this;
- },
- Reader: Reader,
- Writer: Writer,
- };
-
- /** Node.js Buffers **/
@ -1788,7 +1919,7 @@ index deb0156..0000000
-export { DataItem } from './DataItem';
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/patchCBOR.ts b/node_modules/@keystonehq/bc-ur-registry/src/patchCBOR.ts
deleted file mode 100644
index b9909a7..0000000
index 218e912..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/patchCBOR.ts
+++ /dev/null
@@ -1,11 +0,0 @@
@ -1802,17 +1933,29 @@ index b9909a7..0000000
-const scriptExpressionTags = Object.values(ScriptExpressions).map((se) =>
- se.getTag(),
-);
-patchTags(registryTags.concat(scriptExpressionTags));
-patchTags(registryTags.concat(scriptExpressionTags) as number[]);
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/types.ts b/node_modules/@keystonehq/bc-ur-registry/src/types.ts
deleted file mode 100644
index 29aa370..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/types.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export interface ICryptoKey {
- isECKey: () => boolean;
- getOutputDescriptorContent: () => string;
-}
-
-export type DataItemMap = Record<string, any>;
diff --git a/node_modules/@keystonehq/bc-ur-registry/src/utils.ts b/node_modules/@keystonehq/bc-ur-registry/src/utils.ts
deleted file mode 100644
index ee39b78..0000000
index e38112b..0000000
--- a/node_modules/@keystonehq/bc-ur-registry/src/utils.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { addSemanticDecode, addSemanticEncode, DataItem } from './lib';
-
-const alreadyPatchedTag = [];
-export const patchTags = (tags: number[]) => {
-const alreadyPatchedTag: number[] = [];
-export const patchTags = (tags: number[]): void => {
- tags.forEach((tag) => {
- if (alreadyPatchedTag.find((i) => i === tag)) return;
- addSemanticEncode(tag, (data: any) => {

@ -1,37 +0,0 @@
lazy precompute for faster module initialization
diff --git a/node_modules/secp256k1/lib/js/ecpointg.js b/node_modules/secp256k1/lib/js/ecpointg.js
index 0144364..09a87c5 100644
--- a/node_modules/secp256k1/lib/js/ecpointg.js
+++ b/node_modules/secp256k1/lib/js/ecpointg.js
@@ -8,11 +8,12 @@ function ECPointG () {
this.x = BN.fromBuffer(Buffer.from('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 'hex'))
this.y = BN.fromBuffer(Buffer.from('483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8', 'hex'))
this.inf = false
-
- this._precompute()
+ this.precomputed = undefined
}
ECPointG.prototype._precompute = function () {
+ if (this.precomputed !== undefined) return
+
var ecpoint = new ECPoint(this.x, this.y)
var dstep = 4
@@ -34,6 +35,7 @@ ECPointG.prototype._precompute = function () {
}
ECPointG.prototype.mul = function (num) {
+ this._precompute()
// Algorithm 3.42 Fixed-base NAF windowing method for point multiplication
var step = this.precomputed.doubles.step
var points = this.precomputed.doubles.points
@@ -68,6 +70,7 @@ ECPointG.prototype.mul = function (num) {
}
ECPointG.prototype.mulAdd = function (k1, p2, k2) {
+ this._precompute()
var nafPointsP1 = this.precomputed.naf
var nafPointsP2 = p2._getNAFPoints1()
var wnd = [nafPointsP1.points, nafPointsP2.points]

@ -1 +1,3 @@
export const AUTO_LOCK_TIMEOUT_ALARM = 'AUTO_LOCK_TIMEOUT_ALARM';
export const METAMETRICS_FINALIZE_EVENT_FRAGMENT_ALARM =
'METAMETRICS_FINALIZE_EVENT_FRAGMENT_ALARM';

@ -178,8 +178,8 @@
* identify the new number_of_tokens trait
* @property {'opensea_api_enabled'} OPENSEA_API_ENABLED - when the OpenSea API is enabled
* we identify the opensea_api_enabled trait
* @property {'three_box_enabled'} THREE_BOX_ENABLED - when 3box feature is
* toggled we identify the 3box_enabled trait
* @property {'three_box_enabled'} THREE_BOX_ENABLED - When 3Box feature is
* toggled we identify the 3box_enabled trait. This trait has been deprecated.
* @property {'theme'} THEME - when the user's theme changes we identify the theme trait
* @property {'token_detection_enabled'} TOKEN_DETECTION_ENABLED - when token detection feature is toggled we
* identify the token_detection_enabled trait
@ -231,8 +231,8 @@ export const TRAITS = {
* the user has across all networks and accounts.
* @property {boolean} [opensea_api_enabled] - does the user have the OpenSea
* API enabled?
* @property {boolean} [three_box_enabled] - does the user have 3box sync
* enabled?
* @property {boolean} [three_box_enabled] - Does the user have 3box sync
* enabled? (deprecated)
* @property {string} [theme] - which theme the user has selected
* @property {boolean} [token_detection_enabled] - does the user have token detection is enabled?
*/

@ -210,6 +210,7 @@ export const CHAIN_IDS = {
HARMONY: '0x63564c40',
PALM: '0x2a15c308d',
SEPOLIA: '0xaa36a7',
AURORA: '0x4e454152',
} as const;
/**
@ -232,6 +233,7 @@ export const OPTIMISM_DISPLAY_NAME = 'Optimism';
export const FANTOM_DISPLAY_NAME = 'Fantom Opera';
export const HARMONY_DISPLAY_NAME = 'Harmony Mainnet Shard 0';
export const PALM_DISPLAY_NAME = 'Palm';
export const AURORA_DISPLAY_NAME = 'Aurora Mainnet';
export const infuraProjectId = process.env.INFURA_PROJECT_ID;
export const getRpcUrl = ({
@ -257,6 +259,7 @@ export const LOCALHOST_RPC_URL = 'http://localhost:8545';
*/
export const CURRENCY_SYMBOLS = {
ARBITRUM: 'ETH',
AURORA: 'Aurora ETH',
AVALANCHE: 'AVAX',
BNB: 'BNB',
BUSD: 'BUSD',
@ -410,6 +413,7 @@ export const FTM_TOKEN_IMAGE_URL = './images/fantom-opera.svg';
export const HARMONY_ONE_TOKEN_IMAGE_URL = './images/harmony-one.svg';
export const OPTIMISM_TOKEN_IMAGE_URL = './images/optimism.svg';
export const PALM_TOKEN_IMAGE_URL = './images/palm.svg';
export const AURORA_TOKEN_IMAGE_URL = './images/aurora.png';
export const INFURA_PROVIDER_TYPES = [
NETWORK_TYPES.MAINNET,
@ -505,6 +509,7 @@ export const CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP = {
[CHAIN_IDS.HARMONY]: HARMONY_ONE_TOKEN_IMAGE_URL,
[CHAIN_IDS.OPTIMISM]: OPTIMISM_TOKEN_IMAGE_URL,
[CHAIN_IDS.PALM]: PALM_TOKEN_IMAGE_URL,
[CHAIN_IDS.AURORA]: AURORA_TOKEN_IMAGE_URL,
} as const;
export const NETWORK_ID_TO_ETHERS_NETWORK_NAME_MAP = {
@ -861,6 +866,11 @@ export const BUYABLE_CHAINS_MAP: {
SUPPORTED_CURRENCY_SYMBOLS.USDS,
],
},
[CHAIN_IDS.AURORA]: {
nativeCurrency: CURRENCY_SYMBOLS.AURORA,
network: 'aurora',
transakCurrencies: [SUPPORTED_CURRENCY_SYMBOLS.AURORA],
},
};
export const FEATURED_RPCS: RPCDefinition[] = [
@ -874,6 +884,16 @@ export const FEATURED_RPCS: RPCDefinition[] = [
imageUrl: AETH_TOKEN_IMAGE_URL,
},
},
{
chainId: CHAIN_IDS.AURORA,
nickname: AURORA_DISPLAY_NAME,
rpcUrl: `https://aurora-mainnet.infura.io/v3/${infuraProjectId}`,
ticker: CURRENCY_SYMBOLS.AURORA,
rpcPrefs: {
blockExplorerUrl: 'https://aurorascan.dev/',
imageUrl: AURORA_TOKEN_IMAGE_URL,
},
},
{
chainId: CHAIN_IDS.AVALANCHE,
nickname: AVALANCHE_DISPLAY_NAME,

@ -71,7 +71,6 @@ function blockedDomainCheck() {
'cdn.shopify.com/s/javascripts/tricorder/xtld-read-only-frame.html',
'adyen.com',
'gravityforms.com',
'docs.google.com',
'harbourair.com',
'ani.gamer.com.tw',
'blueskybooking.com',

@ -13,13 +13,16 @@ const {
} = require('../helpers/file');
const { withFixtures, tinyDelayMs } = require('./helpers');
const { PAGES } = require('./webdriver/driver');
const FixtureBuilder = require('./fixture-builder');
const DEFAULT_NUM_SAMPLES = 20;
const ALL_PAGES = Object.values(PAGES);
async function measurePage(pageName) {
let metrics;
await withFixtures({ fixtures: 'imported-account' }, async ({ driver }) => {
await withFixtures(
{ fixtures: new FixtureBuilder().build() },
async ({ driver }) => {
await driver.delay(tinyDelayMs);
await driver.navigate();
await driver.fill('#password', 'correct horse battery staple');
@ -28,7 +31,8 @@ async function measurePage(pageName) {
await driver.navigate(pageName);
await driver.delay(1000);
metrics = await driver.collectMetrics();
});
},
);
return metrics;
}

File diff suppressed because it is too large Load Diff

@ -1,5 +1,3 @@
const { promises: fs } = require('fs');
const path = require('path');
const Koa = require('koa');
const { isObject, mapValues } = require('lodash');
@ -57,7 +55,6 @@ class FixtureServer {
constructor() {
this._app = new Koa();
this._stateMap = new Map([[DEFAULT_STATE_KEY, Object.create(null)]]);
this._initialStateCache = new Map();
this._app.use(async (ctx) => {
// Firefox is _super_ strict about needing CORS headers
@ -94,19 +91,8 @@ class FixtureServer {
});
}
async loadState(directory) {
const statePath = path.resolve(__dirname, directory, 'state.json');
let state;
if (this._initialStateCache.has(statePath)) {
state = this._initialStateCache.get(statePath);
} else {
const data = await fs.readFile(statePath);
const rawState = JSON.parse(data.toString('utf-8'));
state = performStateSubstitutions(rawState);
this._initialStateCache.set(statePath, state);
}
loadJsonState(rawState) {
const state = performStateSubstitutions(rawState);
this._stateMap.set(CURRENT_STATE_KEY, state);
}

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

@ -1,200 +0,0 @@
{
"data": {
"AppStateController": {
"connectedStatusPopoverHasBeenShown": false,
"showPortfolioTooltip": false
},
"CachedBalancesController": {
"cachedBalances": {
"4": {},
"1337": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": "0x15af1d78b58c40000"
}
}
},
"CurrencyController": {
"conversionDate": 1594348502.519,
"conversionRate": 240.09,
"currentCurrency": "usd",
"nativeCurrency": "ETH"
},
"IncomingTransactionsController": {
"incomingTransactions": {},
"incomingTxLastFetchedBlocksByNetwork": {
"goerli": null,
"mainnet": null,
"sepolia": null,
"localhost": 98
}
},
"KeyringController": {
"vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}"
},
"NetworkController": {
"provider": {
"nickname": "Localhost 8545",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"type": "rpc"
},
"network": "1337"
},
"NotificationController": {
"notifications": {
"1": {
"isShown": true
},
"3": {
"isShown": true
},
"5": {
"isShown": true
},
"6": {
"isShown": true
},
"8": {
"isShown": true
},
"10": {
"isShown": true
},
"11": {
"isShown": true
},
"12": {
"isShown": true
},
"14": {
"isShown": true
},
"15": {
"isShown": true
}
}
},
"OnboardingController": {
"onboardingTabs": {},
"seedPhraseBackedUp": false
},
"PermissionsMetadata": {
"permissionsLog": [
{
"id": 1764280960,
"method": "eth_requestAccounts",
"methodType": "restricted",
"origin": "http://127.0.0.1:8080",
"request": {
"method": "eth_requestAccounts",
"jsonrpc": "2.0",
"id": 1764280960,
"origin": "http://127.0.0.1:8080",
"tabId": 2
},
"requestTime": 1594348329232,
"response": {
"id": 1764280960,
"jsonrpc": "2.0",
"result": ["0x5cfe73b6021e818b776b421b1c4db2474086a7e1"]
},
"responseTime": 1594348332276,
"success": true
}
],
"permissionsHistory": {
"http://127.0.0.1:8080": {
"eth_accounts": {
"accounts": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": 1594348332276
},
"lastApproved": 1594348332276
}
}
},
"domainMetadata": {
"http://127.0.0.1:8080": {
"name": "E2E Test Dapp",
"icon": "http://127.0.0.1:8080/metamask-fox.svg",
"lastUpdated": 1594348323811,
"host": "127.0.0.1:8080"
}
}
},
"PreferencesController": {
"frequentRpcListDetail": [],
"accountTokens": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"goerli": [],
"sepolia": []
}
},
"assetImages": {},
"tokens": [],
"suggestedTokens": {},
"useBlockie": false,
"useNonceField": false,
"usePhishDetect": true,
"featureFlags": {
"showIncomingTransactions": true,
"transactionTime": false
},
"knownMethodData": {},
"participateInMetaMetrics": false,
"firstTimeFlowType": "create",
"currentLocale": "en",
"identities": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"name": "Account 1"
}
},
"lostIdentities": {},
"forgottenPassword": false,
"preferences": {
"useNativeCurrencyAsPrimaryCurrency": true
},
"completedOnboarding": true,
"metaMetricsId": null,
"ipfsGateway": "dweb.link",
"selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1"
},
"config": {},
"firstTimeInfo": {
"date": 1575697234195,
"version": "7.7.0"
},
"PermissionsController": {
"permissionsRequests": [],
"permissionsDescriptions": {},
"domains": {
"http://127.0.0.1:8080": {
"permissions": [
{
"@context": ["https://github.com/MetaMask/rpc-cap"],
"parentCapability": "eth_accounts",
"id": "f55a1c15-ea48-4088-968e-63be474d42fa",
"date": 1594348332268,
"invoker": "http://127.0.0.1:8080",
"caveats": [
{
"type": "limitResponseLength",
"value": 1,
"name": "primaryAccountOnly"
},
{
"type": "filterResponse",
"value": ["0x5cfe73b6021e818b776b421b1c4db2474086a7e1"],
"name": "exposedAccounts"
}
]
}
]
}
}
}
},
"meta": {
"version": 47
}
}

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

@ -1,178 +0,0 @@
{
"data": {
"AlertController": {
"alertEnabledness": {
"unconnectedAccount": true,
"web3ShimUsage": true
},
"unconnectedAccountAlertShownOrigins": {},
"web3ShimUsageOrigins": {}
},
"AppStateController": {
"connectedStatusPopoverHasBeenShown": true,
"defaultHomeActiveTabName": null,
"recoveryPhraseReminderHasBeenShown": true,
"recoveryPhraseReminderLastShown": "__FIXTURE_SUBSTITUTION__currentDateInMilliseconds",
"showPortfolioTooltip": false
},
"CachedBalancesController": {
"cachedBalances": {
"0x5": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": "0x0"
}
}
},
"CurrencyController": {
"conversionDate": 1626907353.891,
"conversionRate": 1968.5,
"currentCurrency": "usd",
"nativeCurrency": "ETH",
"pendingCurrentCurrency": null,
"pendingNativeCurrency": null,
"usdConversionRate": 1968.5
},
"IncomingTransactionsController": {
"incomingTransactions": {},
"incomingTxLastFetchedBlockByChainId": {
"0x1": null,
"0x5": 8977934
}
},
"KeyringController": {
"vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}"
},
"MetaMetricsController": {
"metaMetricsId": "0xff3e952b9f5a27ffcab42b0b4abf689e77dcc1f9f441871dc962d622b089fb51",
"participateInMetaMetrics": true
},
"NetworkController": {
"network": "1337",
"networkDetails": {
"EIPS": {}
},
"previousProviderStore": {
"chainId": "0x5",
"ticker": "ETH",
"type": "goerli"
},
"provider": {
"chainId": "0x539",
"nickname": "Localhost 8545",
"rpcPrefs": {},
"rpcUrl": "http://localhost:8545",
"ticker": "ETH",
"type": "rpc"
}
},
"NotificationController": {
"notifications": {
"8": {
"isShown": true
},
"10": {
"isShown": true
},
"11": {
"isShown": true
},
"12": {
"isShown": true
},
"14": {
"isShown": true
},
"15": {
"isShown": true
}
}
},
"OnboardingController": {
"onboardingTabs": {},
"seedPhraseBackedUp": true
},
"PermissionsController": {
"domains": {},
"permissionsDescriptions": {},
"permissionsRequests": []
},
"PreferencesController": {
"completedOnboarding": true,
"currentLocale": "en",
"dismissSeedBackUpReminder": true,
"featureFlags": {
"showIncomingTransactions": true
},
"firstTimeFlowType": "import",
"forgottenPassword": false,
"frequentRpcListDetail": [
{
"chainId": "0x539",
"nickname": "Localhost 8545",
"rpcPrefs": {},
"rpcUrl": "http://localhost:8545",
"ticker": "ETH"
}
],
"identities": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"lastSelected": 1626907346643,
"name": "Account 1"
}
},
"infuraBlocked": false,
"ipfsGateway": "dweb.link",
"knownMethodData": {},
"lostIdentities": {},
"preferences": {
"hideZeroBalanceTokens": false,
"showFiatInTestnets": false,
"useNativeCurrencyAsPrimaryCurrency": true
},
"selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"useBlockie": false,
"useLedgerLive": false,
"useNonceField": false,
"usePhishDetect": true,
"useStaticTokenList": false
},
"TokensController": {
"allTokens": {
"0x539": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": [
{
"address": "0x86002be4cdd922de1ccb831582bf99284b99ac12",
"decimals": 4,
"image": null,
"isERC721": false,
"symbol": "TST"
}
]
}
},
"ignoredTokens": [],
"suggestedAssets": [],
"allIgnoredTokens": {},
"tokens": [
{
"address": "0x86002be4cdd922de1ccb831582bf99284b99ac12",
"decimals": 4,
"image": null,
"isERC721": false,
"symbol": "TST"
}
]
},
"TransactionController": {
"transactions": {}
},
"config": {},
"firstTimeInfo": {
"date": 1626907328205,
"version": "9.8.1"
}
},
"meta": {
"version": 63
}
}

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

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

@ -1,272 +0,0 @@
{
"data": {
"config": {},
"PreferencesController": {
"frequentRpcListDetail": [
{
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"nickname": "Localhost 8545",
"rpcPrefs": {}
}
],
"accountTokens": {
"0x0cc5261ab8ce458dc977078a3623e2badd27afd3": {
"0x539": []
},
"0x3ed0ee22e0685ebbf07b2360a8331693c413cc59": {},
"0xd38d853771fb546bd8b18b2f3638491bc0b0e906": {
"0x539": []
}
},
"accountHiddenTokens": {
"0x0cc5261ab8ce458dc977078a3623e2badd27afd3": {
"0x539": []
},
"0x3ed0ee22e0685ebbf07b2360a8331693c413cc59": {},
"0xd38d853771fb546bd8b18b2f3638491bc0b0e906": {
"0x539": []
}
},
"assetImages": {},
"tokens": [],
"hiddenTokens": [],
"suggestedTokens": {},
"useBlockie": false,
"useNonceField": false,
"usePhishDetect": true,
"featureFlags": {
"showIncomingTransactions": true
},
"knownMethodData": {},
"firstTimeFlowType": "import",
"currentLocale": "en",
"identities": {
"0x0cc5261ab8ce458dc977078a3623e2badd27afd3": {
"name": "Account 1",
"address": "0x0cc5261ab8ce458dc977078a3623e2badd27afd3",
"lastSelected": 1618940443499
},
"0x3ed0ee22e0685ebbf07b2360a8331693c413cc59": {
"name": "Account 2",
"address": "0x3ed0ee22e0685ebbf07b2360a8331693c413cc59"
},
"0xd38d853771fb546bd8b18b2f3638491bc0b0e906": {
"name": "2nd account",
"address": "0xd38d853771fb546bd8b18b2f3638491bc0b0e906",
"lastSelected": 1618940443010
}
},
"lostIdentities": {},
"forgottenPassword": false,
"preferences": {
"showFiatInTestnets": false,
"useNativeCurrencyAsPrimaryCurrency": true,
"hideZeroBalanceTokens": false
},
"completedOnboarding": true,
"ipfsGateway": "dweb.link",
"infuraBlocked": false,
"selectedAddress": "0x0cc5261ab8ce458dc977078a3623e2badd27afd3"
},
"firstTimeInfo": {
"version": "9.3.0",
"date": 1617927806790
},
"NetworkController": {
"provider": {
"ticker": "ETH",
"type": "rpc",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"nickname": "Localhost 8545"
},
"previousProviderStore": {
"ticker": "ETH",
"type": "rpc",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"nickname": "Localhost 8545"
},
"network": "1337"
},
"NotificationController": {
"notifications": {
"1": {
"isShown": true
},
"3": {
"isShown": true
},
"5": {
"isShown": true
},
"6": {
"isShown": true
},
"8": {
"isShown": true
},
"10": {
"isShown": true
},
"11": {
"isShown": true
},
"12": {
"isShown": true
},
"14": {
"isShown": true
},
"15": {
"isShown": true
}
}
},
"CurrencyController": {
"conversionDate": 1618940438.187,
"conversionRate": 2254.54,
"currentCurrency": "usd",
"nativeCurrency": "ETH",
"usdConversionRate": 2254.54
},
"CachedBalancesController": {
"cachedBalances": {
"0x539": {
"0x0cc5261ab8ce458dc977078a3623e2badd27afd3": "0x14cffbeaf5a7d3000",
"0x3ed0ee22e0685ebbf07b2360a8331693c413cc59": "0x0",
"0xd38d853771fb546bd8b18b2f3638491bc0b0e906": "0x0"
}
}
},
"MetaMetricsController": {
"participateInMetaMetrics": false,
"metaMetricsId": null
},
"PermissionsController": {
"permissionsRequests": [],
"permissionsDescriptions": {},
"domains": {}
},
"TransactionController": {
"transactions": {
"1374812123920442": {
"id": 1374812123920442,
"time": 1618940444708,
"status": "confirmed",
"metamaskNetworkId": "1337",
"chainId": "0x539",
"loadingDefaults": false,
"txParams": {
"from": "0x0cc5261ab8ce458dc977078a3623e2badd27afd3",
"to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970",
"nonce": "0x0",
"value": "0xde0b6b3a7640000",
"gas": "0x5208",
"gasPrice": "0x363fe1da00"
},
"origin": "metamask",
"type": "simpleSend",
"history": [],
"nonceDetails": {
"params": {
"highestLocallyConfirmed": 0,
"highestSuggested": 0,
"nextNetworkNonce": 0
},
"local": {
"name": "local",
"nonce": 0,
"details": {
"startPoint": 0,
"highest": 0
}
},
"network": {
"name": "network",
"nonce": 0,
"details": {
"blockNumber": "0x5",
"baseCount": 0
}
}
},
"r": "0x035de1d588f67547bd9c7bb9b34a8330c10085155e42af0017986911ca922e61",
"s": "0x36c3c12a323121afe6d63bc8c5929766d385e2e7b7fc892ecd0f10a7ec4ab59e",
"v": "0x0a95",
"rawTx": "0xf86e8085363fe1da00825208942f318c334780961fb129d2a6c30d0763d9a5c970880de0b6b3a764000080820a95a0035de1d588f67547bd9c7bb9b34a8330c10085155e42af0017986911ca922e61a036c3c12a323121afe6d63bc8c5929766d385e2e7b7fc892ecd0f10a7ec4ab59e",
"hash": "0xaba403a1dff459d7549b57369cfdd323c70fc79a307ed8f9cae811ddd6883a74",
"submittedTime": 1618940445208,
"txReceipt": {
"transactionHash": "0xaba403a1dff459d7549b57369cfdd323c70fc79a307ed8f9cae811ddd6883a74",
"transactionIndex": {
"negative": 0,
"words": [0, null],
"length": 1,
"red": null
},
"blockHash": "0x734618e63369e7ea10872e68cec4d400d77c55ed525cbc295802d00d7b4bd1d2",
"blockNumber": {
"negative": 0,
"words": [6, null],
"length": 1,
"red": null
},
"from": "0x0cc5261ab8ce458dc977078a3623e2badd27afd3",
"to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970",
"gasUsed": "5208",
"cumulativeGasUsed": {
"negative": 0,
"words": [21000, null],
"length": 1,
"red": null
},
"contractAddress": null,
"logs": [],
"status": "0x1",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
}
}
},
"KeyringController": {
"vault": "{\"data\":\"Ot+BTtJPag0xubdiv1nO9bsSvTHivHCd6CD7Lxgb1McYw3VqMjgp5rPMZmblJ1lscuMxyiqp99G52uXO9S0em6F9htpa+t/wn6qubRKTTNG9fxNzQrKXRDNhdgfYckVk5VAZ4fgl2iMZcRDvS8H/+gucVKJ33Sl6mXyPofdexXhWDCU6uR2YecnfaIum9cL2u/GqOMPE3jxzy0Wip0x2Jyp3QOKhvu8A3GIjzagLOaQ7a1APdl8=\",\"iv\":\"lbsyPeGYWU6U1+jvmW9UHg==\",\"salt\":\"Zmbhpskwxe4rYfXtELBvlcvW4HISPBATRmMqzsnZPMg=\"}"
},
"AlertController": {
"alertEnabledness": {
"unconnectedAccount": true,
"web3ShimUsage": true
},
"unconnectedAccountAlertShownOrigins": {},
"web3ShimUsageOrigins": {}
},
"OnboardingController": {
"seedPhraseBackedUp": true,
"onboardingTabs": {}
},
"AddressBookController": {
"addressBook": {
"0x539": {
"0x2f318C334780961FB129D2a6c30D0763d9a5C970": {
"address": "0x2f318C334780961FB129D2a6c30D0763d9a5C970",
"chainId": "0x539",
"isEns": false,
"memo": "",
"name": ""
}
}
}
},
"AppStateController": {
"connectedStatusPopoverHasBeenShown": true,
"swapsWelcomeMessageHasBeenShown": false,
"defaultHomeActiveTabName": "Activity",
"showPortfolioTooltip": false
}
},
"meta": {
"version": 57
}
}

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

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

@ -1,200 +0,0 @@
{
"data": {
"AppStateController": {
"connectedStatusPopoverHasBeenShown": false,
"showPortfolioTooltip": false
},
"CachedBalancesController": {
"cachedBalances": {
"4": {},
"1337": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": "0x15af1d78b58c40000"
}
}
},
"CurrencyController": {
"conversionDate": 1594348502.519,
"conversionRate": 240.09,
"currentCurrency": "usd",
"nativeCurrency": "ETH"
},
"IncomingTransactionsController": {
"incomingTransactions": {},
"incomingTxLastFetchedBlocksByNetwork": {
"goerli": null,
"mainnet": null,
"sepolia": null,
"localhost": 98
}
},
"KeyringController": {
"vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}"
},
"NetworkController": {
"provider": {
"nickname": "Localhost 8545",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"type": "rpc"
},
"network": "1337"
},
"NotificationController": {
"notifications": {
"1": {
"isShown": true
},
"3": {
"isShown": true
},
"5": {
"isShown": true
},
"6": {
"isShown": true
},
"8": {
"isShown": true
},
"10": {
"isShown": true
},
"11": {
"isShown": true
},
"12": {
"isShown": true
},
"14": {
"isShown": true
},
"15": {
"isShown": true
}
}
},
"OnboardingController": {
"onboardingTabs": {},
"seedPhraseBackedUp": false
},
"PermissionsMetadata": {
"permissionsLog": [
{
"id": 1764280960,
"method": "eth_requestAccounts",
"methodType": "restricted",
"origin": "http://127.0.0.1:8080",
"request": {
"method": "eth_requestAccounts",
"jsonrpc": "2.0",
"id": 1764280960,
"origin": "http://127.0.0.1:8080",
"tabId": 2
},
"requestTime": 1594348329232,
"response": {
"id": 1764280960,
"jsonrpc": "2.0",
"result": ["0x5cfe73b6021e818b776b421b1c4db2474086a7e1"]
},
"responseTime": 1594348332276,
"success": true
}
],
"permissionsHistory": {
"http://127.0.0.1:8080": {
"eth_accounts": {
"accounts": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": 1594348332276
},
"lastApproved": 1594348332276
}
}
},
"domainMetadata": {
"http://127.0.0.1:8080": {
"name": "E2E Test Dapp",
"icon": "http://127.0.0.1:8080/metamask-fox.svg",
"lastUpdated": 1594348323811,
"host": "127.0.0.1:8080"
}
}
},
"PreferencesController": {
"frequentRpcListDetail": [],
"accountTokens": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"goerli": [],
"sepolia": []
}
},
"assetImages": {},
"tokens": [],
"suggestedTokens": {},
"useBlockie": false,
"useNonceField": false,
"usePhishDetect": true,
"featureFlags": {
"showIncomingTransactions": true,
"transactionTime": false
},
"knownMethodData": {},
"participateInMetaMetrics": true,
"firstTimeFlowType": "create",
"currentLocale": "en",
"identities": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"name": "Account 1"
}
},
"lostIdentities": {},
"forgottenPassword": false,
"preferences": {
"useNativeCurrencyAsPrimaryCurrency": true
},
"completedOnboarding": true,
"metaMetricsId": "fake-metrics-id",
"ipfsGateway": "dweb.link",
"selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1"
},
"config": {},
"firstTimeInfo": {
"date": 1575697234195,
"version": "7.7.0"
},
"PermissionsController": {
"permissionsRequests": [],
"permissionsDescriptions": {},
"domains": {
"http://127.0.0.1:8080": {
"permissions": [
{
"@context": ["https://github.com/MetaMask/rpc-cap"],
"parentCapability": "eth_accounts",
"id": "f55a1c15-ea48-4088-968e-63be474d42fa",
"date": 1594348332268,
"invoker": "http://127.0.0.1:8080",
"caveats": [
{
"type": "limitResponseLength",
"value": 1,
"name": "primaryAccountOnly"
},
{
"type": "filterResponse",
"value": ["0x5cfe73b6021e818b776b421b1c4db2474086a7e1"],
"name": "exposedAccounts"
}
]
}
]
}
}
}
},
"meta": {
"version": 47
}
}

@ -1,442 +0,0 @@
{
"data": {
"AppStateController": {
"mkrMigrationReminderTimestamp": null,
"showPortfolioTooltip": false
},
"CachedBalancesController": {
"cachedBalances": {
"4": {}
}
},
"CurrencyController": {
"conversionDate": 1575697244.188,
"conversionRate": 149.61,
"currentCurrency": "usd",
"nativeCurrency": "ETH"
},
"IncomingTransactionsController": {
"incomingTransactions": {},
"incomingTxLastFetchedBlocksByNetwork": {
"goerli": null,
"mainnet": null,
"sepolia": null
}
},
"KeyringController": {
"vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}"
},
"NetworkController": {
"network": "1337",
"provider": {
"nickname": "Localhost 8545",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"type": "rpc"
}
},
"NotificationController": {
"notifications": {
"1": {
"isShown": true
},
"3": {
"isShown": true
},
"5": {
"isShown": true
},
"6": {
"isShown": true
},
"8": {
"isShown": true
},
"10": {
"isShown": true
},
"11": {
"isShown": true
},
"12": {
"isShown": true
},
"14": {
"isShown": true
},
"15": {
"isShown": true
}
}
},
"OnboardingController": {
"onboardingTabs": {},
"seedPhraseBackedUp": false
},
"PermissionsMetadata": {
"domainMetadata": {
"metamask.github.io": {
"icon": null,
"name": "M E T A M A S K M E S H T E S T"
}
},
"permissionsHistory": {},
"permissionsLog": [
{
"id": 746677923,
"method": "eth_accounts",
"methodType": "restricted",
"origin": "metamask.github.io",
"request": {
"id": 746677923,
"jsonrpc": "2.0",
"method": "eth_accounts",
"origin": "metamask.github.io",
"params": []
},
"requestTime": 1575697241368,
"response": {
"id": 746677923,
"jsonrpc": "2.0",
"result": []
},
"responseTime": 1575697241370,
"success": true
}
]
},
"PreferencesController": {
"accountTokens": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"goerli": [],
"sepolia": []
}
},
"assetImages": {},
"completedOnboarding": true,
"dismissSeedBackUpReminder": true,
"currentLocale": "en",
"featureFlags": {
"showIncomingTransactions": true,
"transactionTime": false
},
"firstTimeFlowType": "create",
"forgottenPassword": false,
"frequentRpcListDetail": [],
"identities": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"name": "Account 1"
}
},
"knownMethodData": {},
"lostIdentities": {},
"metaMetricsId": null,
"participateInMetaMetrics": false,
"preferences": {
"useNativeCurrencyAsPrimaryCurrency": true
},
"selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"suggestedTokens": {},
"tokens": [],
"useBlockie": false,
"useNonceField": false,
"usePhishDetect": true,
"useTokenDetection": true
},
"MetaMetricsController": {
"fragments": {
"transaction-added-7911313280012623": {
"category": "Transactions",
"initialEvent": "Transaction Added",
"successEvent": "Transaction Approved",
"failureEvent": "Transaction Rejected",
"properties": {},
"persist": true,
"uniqueIdentifier": "transaction-added-7911313280012623"
},
"transaction-added-7911313280012624": {
"category": "Transactions",
"initialEvent": "Transaction Added",
"successEvent": "Transaction Approved",
"failureEvent": "Transaction Rejected",
"properties": {},
"persist": true,
"uniqueIdentifier": "transaction-added-7911313280012624"
},
"transaction-added-7911313280012625": {
"category": "Transactions",
"initialEvent": "Transaction Added",
"successEvent": "Transaction Approved",
"failureEvent": "Transaction Rejected",
"properties": {},
"persist": true,
"uniqueIdentifier": "transaction-added-7911313280012625"
},
"transaction-added-7911313280012626": {
"category": "Transactions",
"initialEvent": "Transaction Added",
"successEvent": "Transaction Approved",
"failureEvent": "Transaction Rejected",
"properties": {},
"persist": true,
"uniqueIdentifier": "transaction-added-7911313280012626"
}
}
},
"TransactionController": {
"transactions": {
"7911313280012623": {
"chainId": "0x539",
"dappSuggestedGasFees": {
"gas": "0x5208",
"gasPrice": "0x4a817c800"
},
"history": [
{
"chainId": "0x539",
"dappSuggestedGasFees": {
"gas": "0x5208",
"gasPrice": "0x4a817c800"
},
"id": 7911313280012623,
"loadingDefaults": true,
"metamaskNetworkId": "1337",
"origin": "https://metamask.github.io",
"status": "unapproved",
"time": 1631545991949,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x5208",
"gasPrice": "0x4a817c800",
"to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970",
"value": "0x29a2241af62c0000"
},
"type": "sentEther"
},
[
{
"note": "Added new unapproved transaction.",
"op": "replace",
"path": "/loadingDefaults",
"timestamp": 1631545992244,
"value": false
}
]
],
"id": 7911313280012623,
"loadingDefaults": false,
"metamaskNetworkId": "1337",
"origin": "https://metamask.github.io",
"status": "unapproved",
"time": 1631545991949,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x5208",
"gasPrice": "0x4a817c800",
"to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970",
"value": "0x29a2241af62c0000"
},
"type": "sentEther"
},
"7911313280012624": {
"chainId": "0x539",
"dappSuggestedGasFees": {
"gas": "0x5208",
"gasPrice": "0x4a817c800"
},
"history": [
{
"chainId": "0x539",
"dappSuggestedGasFees": {
"gas": "0x5208",
"gasPrice": "0x4a817c800"
},
"id": 7911313280012624,
"loadingDefaults": true,
"metamaskNetworkId": "1337",
"origin": "https://metamask.github.io",
"status": "unapproved",
"time": 1631545994578,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x5208",
"gasPrice": "0x4a817c800",
"to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970",
"value": "0x29a2241af62c0000"
},
"type": "sentEther"
},
[
{
"note": "Added new unapproved transaction.",
"op": "replace",
"path": "/loadingDefaults",
"timestamp": 1631545994695,
"value": false
}
]
],
"id": 7911313280012624,
"loadingDefaults": false,
"metamaskNetworkId": "1337",
"origin": "https://metamask.github.io",
"status": "unapproved",
"time": 1631545994578,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x5208",
"gasPrice": "0x4a817c800",
"to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970",
"value": "0x29a2241af62c0000"
},
"type": "sentEther"
},
"7911313280012625": {
"chainId": "0x539",
"dappSuggestedGasFees": {
"gas": "0x5208",
"gasPrice": "0x4a817c800"
},
"history": [
{
"chainId": "0x539",
"dappSuggestedGasFees": {
"gas": "0x5208",
"gasPrice": "0x4a817c800"
},
"id": 7911313280012625,
"loadingDefaults": true,
"metamaskNetworkId": "1337",
"origin": "https://metamask.github.io",
"status": "unapproved",
"time": 1631545996673,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x5208",
"gasPrice": "0x4a817c800",
"to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970",
"value": "0x29a2241af62c0000"
},
"type": "sentEther"
},
[
{
"note": "Added new unapproved transaction.",
"op": "replace",
"path": "/loadingDefaults",
"timestamp": 1631545996678,
"value": false
}
]
],
"id": 7911313280012625,
"loadingDefaults": false,
"metamaskNetworkId": "1337",
"origin": "https://metamask.github.io",
"status": "unapproved",
"time": 1631545996673,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x5208",
"gasPrice": "0x4a817c800",
"to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970",
"value": "0x29a2241af62c0000"
},
"type": "sentEther"
},
"7911313280012626": {
"chainId": "0x539",
"dappSuggestedGasFees": {
"gas": "0x5208",
"gasPrice": "0x4a817c800"
},
"history": [
{
"chainId": "0x539",
"dappSuggestedGasFees": {
"gas": "0x5208",
"gasPrice": "0x4a817c800"
},
"id": 7911313280012626,
"loadingDefaults": true,
"metamaskNetworkId": "1337",
"origin": "https://metamask.github.io",
"status": "unapproved",
"time": 1631545998675,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x5208",
"gasPrice": "0x4a817c800",
"to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970",
"value": "0x29a2241af62c0000"
},
"type": "sentEther"
},
[
{
"note": "Added new unapproved transaction.",
"op": "replace",
"path": "/loadingDefaults",
"timestamp": 1631545998677,
"value": false
}
]
],
"id": 7911313280012626,
"loadingDefaults": false,
"metamaskNetworkId": "1337",
"origin": "https://metamask.github.io",
"status": "unapproved",
"time": 1631545998675,
"txParams": {
"from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"gas": "0x5208",
"gasPrice": "0x4a817c800",
"to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970",
"value": "0x29a2241af62c0000"
},
"type": "sentEther"
}
}
},
"PermissionsController": {
"permissionsRequests": [],
"permissionsDescriptions": {},
"domains": {
"http://127.0.0.1:8080": {
"permissions": [
{
"@context": ["https://github.com/MetaMask/rpc-cap"],
"parentCapability": "eth_accounts",
"id": "f55a1c15-ea48-4088-968e-63be474d42fa",
"date": 1594348332268,
"invoker": "http://127.0.0.1:8080",
"caveats": [
{
"type": "limitResponseLength",
"value": 1,
"name": "primaryAccountOnly"
},
{
"type": "filterResponse",
"value": ["0x5cfe73b6021e818b776b421b1c4db2474086a7e1"],
"name": "exposedAccounts"
}
]
}
]
}
}
},
"config": {},
"firstTimeInfo": {
"date": 1575697234195,
"version": "7.7.0"
}
},
"meta": {
"version": 40
}
}

@ -1,59 +0,0 @@
{
"data": {
"config": {},
"PreferencesController": {
"frequentRpcListDetail": [
{
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"nickname": "Localhost 8545",
"rpcPrefs": {}
}
]
},
"firstTimeInfo": {
"version": "9.3.0",
"date": 1617927806790
},
"NetworkController": {
"provider": {
"ticker": "ETH",
"type": "rpc",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"nickname": "Localhost 8545"
},
"network": "1337"
},
"NotificationController": {
"notifications": {
"10": {
"isShown": true
},
"11": {
"isShown": true
},
"12": {
"isShown": true
},
"14": {
"isShown": true
},
"15": {
"isShown": true
}
}
},
"CurrencyController": {
"conversionDate": 1617927806.941,
"conversionRate": 2084.64,
"currentCurrency": "usd",
"nativeCurrency": "ETH",
"usdConversionRate": 2084.64
}
},
"meta": {
"version": 57
}
}

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

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

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

@ -1,155 +0,0 @@
{
"data": {
"AppStateController": {
"swapsWelcomeMessageHasBeenShown": true,
"connectedStatusPopoverHasBeenShown": false,
"showPortfolioTooltip": false
},
"CachedBalancesController": {
"cachedBalances": {
"0x539": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": "0x15af1d78b58c40000"
}
}
},
"CurrencyController": {
"conversionDate": 1617897791.928,
"conversionRate": 2072.49,
"currentCurrency": "usd",
"nativeCurrency": "ETH",
"usdConversionRate": 2072.49
},
"IncomingTransactionsController": {
"incomingTransactions": {},
"incomingTxLastFetchedBlockByChainId": {
"0xaa36a7": null,
"0x1": null,
"0x5": 5570536
}
},
"KeyringController": {
"vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}"
},
"NetworkController": {
"provider": {
"nickname": "Localhost 8545",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"type": "rpc"
},
"previousProviderStore": {
"nickname": "Localhost 8545",
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"type": "rpc"
},
"network": "1337"
},
"NotificationController": {
"notifications": {
"1": {
"isShown": true
},
"3": {
"isShown": true
},
"5": {
"isShown": true
},
"6": {
"isShown": true
},
"8": {
"isShown": true
},
"10": {
"isShown": true
},
"11": {
"isShown": true
},
"12": {
"isShown": true
},
"14": {
"isShown": true
},
"15": {
"isShown": true
}
}
},
"OnboardingController": {
"onboardingTabs": {},
"seedPhraseBackedUp": true
},
"PreferencesController": {
"frequentRpcListDetail": [
{
"rpcUrl": "http://localhost:8545",
"chainId": "0x539",
"ticker": "ETH",
"nickname": "Localhost 8545",
"rpcPrefs": {}
}
],
"accountTokens": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"0x5": [],
"0xaa36a7": []
}
},
"accountHiddenTokens": {},
"assetImages": {},
"tokens": [],
"hiddenTokens": [],
"suggestedTokens": {},
"useBlockie": true,
"useNonceField": false,
"usePhishDetect": true,
"featureFlags": {
"showIncomingTransactions": true,
"transactionTime": false
},
"knownMethodData": {},
"firstTimeFlowType": "create",
"currentLocale": "en",
"identities": {
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": {
"address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1",
"name": "Account 1"
}
},
"lostIdentities": {},
"forgottenPassword": false,
"preferences": {
"useNativeCurrencyAsPrimaryCurrency": true
},
"completedOnboarding": true,
"ipfsGateway": "dweb.link",
"selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1"
},
"config": {},
"firstTimeInfo": {
"date": 1575697234195,
"version": "7.7.0"
},
"MetaMetricsController": {
"metaMetricsId": null,
"participateInMetaMetrics": false
},
"ThreeBoxController": {
"threeBoxSyncingAllowed": true,
"showRestorePrompt": true,
"threeBoxLastUpdated": 0,
"threeBoxAddress": "0x64480aa2768ef12f3f19c5a01206ceb0f82d06b9",
"threeBoxSynced": true,
"threeBoxDisabled": false
}
},
"meta": {
"version": 57
}
}

@ -73,7 +73,7 @@ async function withFixtures(options, testSuite) {
});
}
await fixtureServer.start();
await fixtureServer.loadState(path.join(__dirname, 'fixtures', fixtures));
fixtureServer.loadJsonState(fixtures);
await phishingPageServer.start();
if (dapp) {
if (dappOptions?.numberOfDapps) {
@ -198,26 +198,6 @@ const getWindowHandles = async (driver, handlesCount) => {
return { extension, dapp, popup };
};
const connectDappWithExtensionPopup = async (driver) => {
await driver.openNewPage(`http://127.0.0.1:${dappBasePort}/`);
await driver.delay(regularDelayMs);
await driver.clickElement({ text: 'Connect', tag: 'button' });
await driver.delay(regularDelayMs);
const windowHandles = await getWindowHandles(driver, 3);
// open extension popup and confirm connect
await driver.switchToWindow(windowHandles.popup);
await driver.delay(largeDelayMs);
await driver.clickElement({ text: 'Next', tag: 'button' });
await driver.clickElement({ text: 'Connect', tag: 'button' });
// send from dapp
await driver.waitUntilXWindowHandles(2);
await driver.switchToWindow(windowHandles.dapp);
await driver.delay(regularDelayMs);
};
const completeImportSRPOnboardingFlow = async (
driver,
seedPhrase,
@ -333,7 +313,6 @@ module.exports = {
largeDelayMs,
veryLargeDelayMs,
withFixtures,
connectDappWithExtensionPopup,
completeImportSRPOnboardingFlow,
completeImportSRPOnboardingFlowWordByWord,
createDownloadFolder,

@ -7,11 +7,14 @@ const yargs = require('yargs/yargs');
const { hideBin } = require('yargs/helpers');
const { exitWithError } = require('../../development/lib/exit-with-error');
const { withFixtures, tinyDelayMs } = require('./helpers');
const FixtureBuilder = require('./fixture-builder');
async function measurePage() {
let metrics;
try {
await withFixtures({ fixtures: 'imported-account' }, async ({ driver }) => {
await withFixtures(
{ fixtures: new FixtureBuilder().build() },
async ({ driver }) => {
await driver.delay(tinyDelayMs);
await driver.navigate();
await driver.findElement('#password');
@ -41,7 +44,8 @@ async function measurePage() {
});
metrics = parsedLogs.map((pl) => JSON.parse(pl));
});
},
);
} catch (error) {
// do nothing
}

@ -1,57 +0,0 @@
const http = require('http');
const PORT = 8889;
class ThreeboxMockServer {
constructor() {
this.server = http.createServer(this.requestHandler);
this.database = {};
}
async start() {
return new Promise((resolve, reject) => {
this.server = this.server.listen(PORT);
this.server.once('error', reject);
this.server.once('listening', resolve);
});
}
async stop() {
if (!this.server) {
return;
}
await new Promise((resolve, reject) => {
this.server.close();
this.server.once('error', reject);
this.server.once('close', resolve);
});
}
requestHandler = (request, response) => {
response.setHeader('Content-Type', 'application/json');
if (request.method === 'POST') {
let body = '';
request.on('data', (chunk) => {
body += chunk.toString(); // convert Buffer to string
});
request.on('end', () => {
const { key, data } = JSON.parse(body);
this.database[key] = data;
response.setHeader('Access-Control-Allow-Headers', '*');
response.end('ok');
});
} else if (request.method === 'GET') {
const key = new URL(request.url, 'https://example.org/').searchParams.get(
'key',
);
response.setHeader('Access-Control-Allow-Headers', '*');
response.end(JSON.stringify(this.database[key] || ''));
} else {
response.end('unknown request');
}
};
}
module.exports = ThreeboxMockServer;

@ -189,19 +189,10 @@ async function setupMocking(server, testSpecificMock) {
};
});
// It disables loading of token icons, e.g. this URL: https://static.metaswap.codefi.network/api/v1/tokenIcons/1337/0x0000000000000000000000000000000000000000.png
await server
.forGet(
'https://static.metaswap.codefi.network/api/v1/tokenIcons/1337/0x0d8775f648430679a709e98d2b0cb6250d2887ef.png',
)
.thenCallback(() => {
return {
statusCode: 200,
};
});
await server
.forGet(
'https://static.metaswap.codefi.network/api/v1/tokenIcons/1337/0x2efa2cb29c2341d8e5ba7d3262c9e9d6f1bf3711.png',
/^https:\/\/static\.metaswap\.codefi\.network\/api\/v1\/tokenIcons\/1337\/.*\.png/u,
)
.thenCallback(() => {
return {

@ -12,6 +12,7 @@ const {
getFirstParentDirectoryThatExists,
} = require('../../helpers/file');
const { withFixtures, tinyDelayMs } = require('../helpers');
const FixtureBuilder = require('../fixture-builder');
/**
* The e2e test case is used to capture load and initialisation time statistics for extension in MV3 environment.
@ -20,7 +21,9 @@ const { withFixtures, tinyDelayMs } = require('../helpers');
async function profilePageLoad() {
const parsedLogs = {};
try {
await withFixtures({ fixtures: 'imported-account' }, async ({ driver }) => {
await withFixtures(
{ fixtures: new FixtureBuilder().build() },
async ({ driver }) => {
await driver.delay(tinyDelayMs);
await driver.navigate();
await driver.delay(1000);
@ -55,7 +58,8 @@ async function profilePageLoad() {
logType = 'loadTime';
}
});
});
},
);
} catch (error) {
console.log('Error in trying to parse logs.');
}

@ -12,6 +12,7 @@ const {
getFirstParentDirectoryThatExists,
} = require('../helpers/file');
const { withFixtures, tinyDelayMs } = require('./helpers');
const FixtureBuilder = require('./fixture-builder');
/**
* The e2e test case is used to capture load and initialisation time statistics for extension in MV3 environment.
@ -20,7 +21,9 @@ const { withFixtures, tinyDelayMs } = require('./helpers');
async function profilePageLoad() {
const parsedLogs = {};
try {
await withFixtures({ fixtures: 'imported-account' }, async ({ driver }) => {
await withFixtures(
{ fixtures: new FixtureBuilder().build() },
async ({ driver }) => {
await driver.delay(tinyDelayMs);
await driver.navigate();
await driver.delay(1000);
@ -55,7 +58,8 @@ async function profilePageLoad() {
logType = 'loadTime';
}
});
});
},
);
} catch (error) {
console.log('Error in trying to parse logs.');
}

@ -0,0 +1,50 @@
{
"addressBook": {
"addressBook": {
"0x539": {
"0x0c54FcCd2e384b4BB6f2E405Bf5Cbc15a017AaFb": {
"address": "0x0c54FcCd2e384b4BB6f2E405Bf5Cbc15a017AaFb",
"chainId": "0x539",
"isEns": false,
"memo": "",
"name": "Test Account"
}
}
}
},
"preferences": {
"advancedGasFee": null,
"currentLocale": "en",
"dismissSeedBackUpReminder": true,
"featureFlags": {
"showIncomingTransactions": true
},
"forgottenPassword": false,
"frequentRpcListDetail": [
{
"chainId": "0x539",
"nickname": "Localhost 8545",
"rpcPrefs": {},
"rpcUrl": "http://localhost:8545",
"ticker": "ETH"
}
],
"infuraBlocked": false,
"ipfsGateway": "dweb.link",
"knownMethodData": {},
"ledgerTransportType": "webhid",
"openSeaEnabled": false,
"preferences": {
"hideZeroBalanceTokens": false,
"showFiatInTestnets": false,
"showTestNetworks": false,
"useNativeCurrencyAsPrimaryCurrency": true
},
"theme": "light",
"useBlockie": false,
"useCollectibleDetection": false,
"useNonceField": false,
"usePhishDetect": true,
"useTokenDetection": false
}
}

@ -5,6 +5,14 @@ const { hideBin } = require('yargs/helpers');
const { runInShell } = require('../../development/lib/run-command');
const { exitWithError } = require('../../development/lib/exit-with-error');
const getTestPathsForTestDir = async (testDir) => {
const testFilenames = await fs.readdir(testDir);
const testPaths = testFilenames.map((filename) =>
path.join(testDir, filename),
);
return testPaths;
};
async function main() {
const { argv } = yargs(hideBin(process.argv))
.usage(
@ -38,13 +46,14 @@ async function main() {
testDir = path.join(__dirname, 'snaps');
}
const testFilenames = await fs.readdir(testDir);
const testPaths = testFilenames.map((filename) =>
path.join(testDir, filename),
);
let testPaths = await getTestPathsForTestDir(testDir);
if (!snaps) {
testPaths.push(path.join(__dirname, 'metamask-ui.spec.js'));
testPaths = [
...testPaths,
...(await getTestPathsForTestDir(path.join(__dirname, 'swaps'))),
path.join(__dirname, 'metamask-ui.spec.js'),
];
}
const runE2eTestPath = path.join(__dirname, 'run-e2e-test.js');

@ -1,3 +1,3 @@
module.exports = {
TEST_SNAPS_WEBSITE_URL: 'https://metamask.github.io/test-snaps/3.0.1',
TEST_SNAPS_WEBSITE_URL: 'https://metamask.github.io/test-snaps/3.1.0',
};

@ -0,0 +1,157 @@
const { strict: assert } = require('assert');
const { withFixtures } = require('../helpers');
const FixtureBuilder = require('../fixture-builder');
const { TEST_SNAPS_WEBSITE_URL } = require('./enums');
describe('Test Snap bip-32', function () {
it('tests various functions of bip-32', async function () {
const ganacheOptions = {
accounts: [
{
secretKey:
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
},
],
};
await withFixtures(
{
fixtures: new FixtureBuilder()
.withPermissionControllerConnectedToSnapDapp()
.build(),
ganacheOptions,
title: this.test.title,
},
async ({ driver }) => {
await driver.navigate();
// enter pw into extension
await driver.fill('#password', 'correct horse battery staple');
await driver.press('#password', driver.Key.ENTER);
// navigate to test snaps page and connect
await driver.driver.get(TEST_SNAPS_WEBSITE_URL);
await driver.delay(1000);
// find and scroll to the correct card and click first
const snapButton = await driver.findElement('#sendUpdateHello');
await driver.scrollToElement(snapButton);
await driver.delay(500);
await driver.fill('#snapId6', 'npm:@metamask/test-snap-bip32');
await driver.clickElement('#connectBip32');
// approve install of snap
await driver.waitUntilXWindowHandles(2, 5000, 10000);
let windowHandles = await driver.getAllWindowHandles();
await driver.switchToWindowWithTitle(
'MetaMask Notification',
windowHandles,
);
await driver.clickElement({
text: 'Approve & install',
tag: 'button',
});
// wait for permissions popover, click checkboxes and confirm
await driver.delay(1000);
await driver.clickElement('#key-access-bip32-m-44h-0h-secp256k1-0');
await driver.clickElement('#key-access-bip32-m-44h-0h-ed25519-0');
await driver.clickElement({
text: 'Confirm',
tag: 'button',
});
// switch back to test-snaps window
await driver.waitUntilXWindowHandles(1, 5000, 10000);
windowHandles = await driver.getAllWindowHandles();
await driver.switchToWindowWithTitle('Test Snaps', windowHandles);
// wait then run SECP256K1 test
await driver.delay(1000);
await driver.fill('#bip32SignMessage', 'foo bar');
await driver.clickElement('#sendBip32Secp256k1');
// hit 'approve' on the custom confirm
await driver.waitUntilXWindowHandles(2, 5000, 10000);
windowHandles = await driver.getAllWindowHandles();
await driver.switchToWindowWithTitle(
'MetaMask Notification',
windowHandles,
);
await driver.clickElement({
text: 'Approve',
tag: 'button',
});
await driver.waitUntilXWindowHandles(1, 5000, 10000);
windowHandles = await driver.getAllWindowHandles();
await driver.switchToWindowWithTitle('Test Snaps', windowHandles);
// check result
await driver.delay(1000);
const secp256k1Result = await driver.findElement(
'#bip32Secp256k1Result',
);
assert.equal(
await secp256k1Result.getText(),
'Signature: "0xd30561eb9e3195e47d49198fb0bc66eda867a7dff4c5e8b60c2ec13851aa7d8cc3d485da177de63dad331f315d440cbb693a629efe228389c4693ea90465b101"',
);
// wait then run ed25519 test
await driver.delay(1000);
await driver.clickElement('#sendBip32Ed25519');
// hit 'approve' on the custom confirm
await driver.waitUntilXWindowHandles(2, 5000, 10000);
windowHandles = await driver.getAllWindowHandles();
await driver.switchToWindowWithTitle(
'MetaMask Notification',
windowHandles,
);
await driver.clickElement({
text: 'Approve',
tag: 'button',
});
await driver.waitUntilXWindowHandles(1, 5000, 10000);
windowHandles = await driver.getAllWindowHandles();
await driver.switchToWindowWithTitle('Test Snaps', windowHandles);
// check result
await driver.delay(1000);
const ed25519Result = await driver.findElement('#bip32Ed25519Result');
assert.equal(
await ed25519Result.getText(),
'Signature: "0xf3215b4d6c59aac7e01b4ceef530d1e2abf4857926b85a81aaae3894505699243768a887b7da4a8c2e0f25196196ba290b6531050db8dc15c252bdd508532a0a"',
);
const publicKeyButton = await driver.findElement('#sendBip32PublicKey');
await driver.scrollToElement(publicKeyButton);
// wait then run public key test
await driver.delay(1000);
await driver.clickElement('#sendBip32PublicKey');
// check result
await driver.delay(1000);
const publicKeyResult = await driver.findElement(
'#bip32PublicKeyResult',
);
assert.equal(
await publicKeyResult.getText(),
'Public key: "043e98d696ae15caef75fa8dd204a7c5c08d1272b2218ba3c20feeb4c691eec366606ece56791c361a2320e7fad8bcbb130f66d51c591fc39767ab2856e93f8dfb"',
);
// wait then run compressed public key test
await driver.delay(1000);
await driver.clickElement('#sendBip32CompressedPublicKey');
// check result
await driver.delay(1000);
const compressedPublicKeyResult = await driver.findElement(
'#bip32CompressedPublicKeyResult',
);
assert.equal(
await compressedPublicKeyResult.getText(),
'Public key: "033e98d696ae15caef75fa8dd204a7c5c08d1272b2218ba3c20feeb4c691eec366"',
);
},
);
});
});

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

Loading…
Cancel
Save