diff --git a/.circleci/config.yml b/.circleci/config.yml index f17e666e8cac..e25e89fa54f2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1097,12 +1097,6 @@ jobs: - checkout - attach_workspace: at: . - - run: - name: Move beta build to dist - command: mv ./dist-beta ./dist - - run: - name: Move beta zips to builds - command: mv ./builds-beta ./builds - run: name: Validate source maps command: | @@ -1157,14 +1151,9 @@ jobs: - attach_workspace: at: . - run: - name: Move beta build to dist - command: mv ./dist-beta ./dist - - run: - name: Move beta zips to builds - command: mv ./builds-beta ./builds - - run: - name: test:mozilla-lint - command: NODE_OPTIONS=--max_old_space_size=3072 yarn mozilla-lint + name: Lint beta for firefox + command: | + .circleci/scripts/mozilla-lint-beta.sh test-mozilla-lint-desktop: executor: node-browsers diff --git a/.circleci/scripts/mozilla-lint-beta.sh b/.circleci/scripts/mozilla-lint-beta.sh new file mode 100755 index 000000000000..1096526b7b50 --- /dev/null +++ b/.circleci/scripts/mozilla-lint-beta.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -e +set -u +set -o pipefail + +current_commit_msg=$(git show -s --format='%s' HEAD) + +if [[ $current_commit_msg =~ Version[[:space:]](v[[:digit:]]+.[[:digit:]]+.[[:digit:]]+[-]beta.[[:digit:]]) ]] +then + # filter the commit message like Version v10.24.1-beta.1 + printf '%s\n' "Linting beta builds for firefox" + # Move beta build to dist + mv ./dist-beta ./dist + # Move beta zips to builds + mv ./builds-beta ./builds + # test:mozilla-lint + export NODE_OPTIONS='--max_old_space_size=3072' + yarn mozilla-lint +else + printf '%s\n' 'Commit message does not match commit message for beta pattern; skipping linting for firefox' + mkdir dist + mkdir builds + exit 0 +fi + +exit 0 diff --git a/.circleci/scripts/validate-changelog-in-rc.sh b/.circleci/scripts/validate-changelog-in-rc.sh old mode 100644 new mode 100755 diff --git a/.circleci/scripts/validate-source-maps-beta.sh b/.circleci/scripts/validate-source-maps-beta.sh index 644ac9fa631b..186aa1548420 100755 --- a/.circleci/scripts/validate-source-maps-beta.sh +++ b/.circleci/scripts/validate-source-maps-beta.sh @@ -10,6 +10,8 @@ current_commit_msg=$(git show -s --format='%s' HEAD) if [[ $current_commit_msg =~ Version[[:space:]](v[[:digit:]]+.[[:digit:]]+.[[:digit:]]+[-]beta.[[:digit:]]) ]] then # filter the commit message like Version v10.24.1-beta.1 + mv ./dist-beta ./dist + mv ./builds-beta ./builds printf '%s\n' "Validate source maps with beta version $current_commit_msg" yarn validate-source-maps else diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index ad9d680ae1db..e5c86c47be59 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Snaps" }, - "snapsInsightError": { - "message": "Ein Fehler ist mit $1: $2 aufgetreten", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "Transaktions-Einsicht wird geladen ..." }, @@ -3375,7 +3371,8 @@ "message": "Ein Snap wird nur ausgeführt, wenn er aktiviert ist" }, "snapsUIError": { - "message": "Die vom Snap spezifizierte UI ist ungültig." + "message": "Die vom Snap spezifizierte UI ist ungültig.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Einige Netzwerke können Sicherheits- und/oder Datenschutzrisiken bergen. Informieren Sie sich über die Risiken, bevor Sie ein Netzwerk hinzufügen und nutzen." diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 6817c89bf469..4c56dcf01b53 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Snaps" }, - "snapsInsightError": { - "message": "Παρουσιάστηκε ένα σφάλμα με $1: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "Φόρτωση πληροφοριών συναλλαγών..." }, @@ -3375,7 +3371,8 @@ "message": "Ένα snap θα εκτελεστεί μόνο εάν είναι ενεργοποιημένο" }, "snapsUIError": { - "message": "Η Διεπαφή Χρήστη (UI) που καθορίζεται από το στιγμιότυπο δεν είναι έγκυρη." + "message": "Η Διεπαφή Χρήστη (UI) που καθορίζεται από το στιγμιότυπο δεν είναι έγκυρη.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Ορισμένα δίκτυα ενδέχεται να ενέχουν κινδύνους για την ασφάλεια ή/και το απόρρητο. Ενημερωθείτε για τους κινδύνους πριν προσθέσετε και χρησιμοποιήσετε ένα δίκτυο." diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 64fe6aa05f2a..fb45872ebebd 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1374,6 +1374,10 @@ "errorWhileConnectingToRPC": { "message": "Error while connecting to the custom network." }, + "errorWithSnap": { + "message": "Error with $1", + "description": "$1 represents the name of the snap" + }, "ethGasPriceFetchWarning": { "message": "Backup gas price is provided as the main gas estimation service is unavailable right now." }, @@ -1801,6 +1805,10 @@ "inputLogicHigherNumber": { "message": "This allows the contract to spend all your token balance until it reaches the cap or you revoke the spending cap. If this is not intended, consider setting a lower spending cap." }, + "insightsFromSnap": { + "message": "Insights from $1", + "description": "$1 represents the name of the snap" + }, "install": { "message": "Install" }, @@ -2446,10 +2454,10 @@ "message": "The Ethereum Merge is here!" }, "notifications16ActionText": { - "message": "Enable security provider" + "message": "Enable security alerts" }, "notifications16DescriptionOne": { - "message": "Get warnings from OpenSea whenever you receive a known malicious request.", + "message": "Get alerts from third parties when you may have received a malicious request.", "description": "Description of a notification in the 'See What's New' popup. Describes Opensea Security Provider feature." }, "notifications16DescriptionThree": { @@ -2457,11 +2465,11 @@ "description": "Description of a notification in the 'See What's New' popup. Describes Opensea Security Provider feature." }, "notifications16DescriptionTwo": { - "message": "OpenSea is the first security provider for this feature. More providers coming soon!", + "message": "OpenSea is the first provider for this feature. More providers coming soon!", "description": "Description of a notification in the 'See What's New' popup. Describes Opensea Security Provider feature." }, "notifications16Title": { - "message": "Stay safe with OpenSea" + "message": "Stay safe with security alerts" }, "notifications17ActionText": { "message": "Enable NFT autodetection" @@ -2919,7 +2927,7 @@ "description": "An extended description for the `snap_getBip32Entropy` permission. $1 is a derivation path (name)" }, "permission_manageBip44Keys": { - "message": "Control your \"$1\" accounts and assets.", + "message": "Control your $1 accounts and assets.", "description": "The description for the `snap_getBip44Entropy` permission. $1 is the name of a protocol, e.g. 'Filecoin'." }, "permission_manageBip44KeysDescription": { @@ -3627,13 +3635,12 @@ "snaps": { "message": "Snaps" }, - "snapsInsightError": { - "message": "An error occured with $1: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "Loading transaction insight..." }, + "snapsInvalidUIError": { + "message": "The UI specified by the snap is invalid." + }, "snapsNoInsight": { "message": "The snap didn't return any insight" }, @@ -3647,7 +3654,8 @@ "message": "A snap will only run if it is enabled" }, "snapsUIError": { - "message": "The UI specified by the snap is invalid." + "message": "Contact the creators of $1 for further support.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Some networks may pose security and/or privacy risks. Understand the risks before adding & using a network." diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 5b580280bcaf..d7d56a93b6eb 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Complementos" }, - "snapsInsightError": { - "message": "Ocurrió un error con $1: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "Cargando información de transacción..." }, @@ -3375,7 +3371,8 @@ "message": "Un complemento solo se ejecutará si está habilitado" }, "snapsUIError": { - "message": "La IU especificada por el complemento no es válida." + "message": "La IU especificada por el complemento no es válida.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Algunas redes pueden presentar riesgos de seguridad y/o privacidad. Comprenda los riesgos antes de agregar y utilizar una red." diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index cd3384918fb8..bbdd98c4add8 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Snaps" }, - "snapsInsightError": { - "message": "Une erreur s’est produite avec $1: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "Chargement de l’aperçu de transaction…" }, @@ -3375,7 +3371,8 @@ "message": "Un snap ne s’exécute que s’il est activé" }, "snapsUIError": { - "message": "L’interface utilisateur (IU) spécifiée par le snap n’est pas valide." + "message": "L’interface utilisateur (IU) spécifiée par le snap n’est pas valide.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Certains réseaux peuvent présenter des risques pour la sécurité et/ou la vie privée. Informez-vous sur les risques avant d’ajouter et d’utiliser un réseau." diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index c6a645cb07c4..f976670c9ffc 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "स्नैप्स" }, - "snapsInsightError": { - "message": "$1: $2 के साथ त्रुटि हुई", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "ट्रांजैक्शन इनसाइट लोड हो रही है..." }, @@ -3375,7 +3371,8 @@ "message": "कोई स्नैप तभी चलेगा जब उसे सक्षम किया गया हो" }, "snapsUIError": { - "message": "स्नैप द्वारा विनिर्दिष्टत UI अमान्य है।" + "message": "स्नैप द्वारा विनिर्दिष्टत UI अमान्य है।", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "कुछ नेटवर्क सुरक्षा और/या गोपनीयता संबंधी जोखिम पैदा कर सकते हैं। नेटवर्क जोड़ने और उपयोग करने से पहले जोखिमों को समझें।" diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index b1b6f1b043c4..c4f6316a23cb 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Snap" }, - "snapsInsightError": { - "message": "Terjadi kesalahan dengan $1: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "Memuat wawasan transaksi..." }, @@ -3375,7 +3371,8 @@ "message": "Snap hanya akan beroperasi jika diaktifkan" }, "snapsUIError": { - "message": "UI yang ditentukan oleh snap tidak valid." + "message": "UI yang ditentukan oleh snap tidak valid.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Beberapa jaringan dapat menimbulkan risiko keamanan dan/atau privasi. Pahami risikonya sebelum menambahkan & menggunakan jaringan." diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 2c01188de7c8..e770df62694c 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "スナップ" }, - "snapsInsightError": { - "message": "$1 でエラーが発生しました: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "トランザクションインサイトを読み込み中..." }, @@ -3375,7 +3371,8 @@ "message": "スナップは有効になっている場合にのみ実行されます" }, "snapsUIError": { - "message": "スナップにより指定された UI が無効です。" + "message": "スナップにより指定された UI が無効です。", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "ネットワークによっては、セキュリティやプライバシーの面でリスクが伴う可能性があります。ネットワークを追加・使用する前にリスクを理解するようにしてください。" diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 7fb0bc692540..ef63aba706d6 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "스냅" }, - "snapsInsightError": { - "message": "$1 관련 오류 발생: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "거래 인사이트를 가져오는 중..." }, @@ -3375,7 +3371,8 @@ "message": "스냅은 활성화된 상태에서만 작동합니다." }, "snapsUIError": { - "message": "스냅에서 지정한 UI가 올바르지 않습니다." + "message": "스냅에서 지정한 UI가 올바르지 않습니다.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "네트워크에 따라 보안이나 개인 정보 유출의 위험이 있을 수 있습니다. 네트워크 추가 및 사용 이전에 위험 요소를 파악하세요." diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index 456fde9d4d97..c32d5525870f 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Snaps" }, - "snapsInsightError": { - "message": "Ocorreu um erro com $1: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "Carregando insight da transação..." }, @@ -3375,7 +3371,8 @@ "message": "O snap só será executado se estiver ativado" }, "snapsUIError": { - "message": "A IU especificada pelo snap é inválida." + "message": "A IU especificada pelo snap é inválida.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Algumas redes podem representar riscos de segurança e/ou privacidade. Tenha os riscos em mente antes de adicionar e usar uma rede." diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 16f65a1556ef..bad7ed48f9e3 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Снапы" }, - "snapsInsightError": { - "message": "Произошла ошибка с $1: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "Загрузка аналитики по транзакции..." }, @@ -3375,7 +3371,8 @@ "message": "Снап будет работать только в том случае, если он включен" }, "snapsUIError": { - "message": "Пользовательский интерфейс, указанный привязкой, недействителен." + "message": "Пользовательский интерфейс, указанный привязкой, недействителен.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Некоторые сети могут представлять угрозу безопасности и/или конфиденциальности. Прежде чем добавлять и использовать сеть, ознакомьтесь с рисками." diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index 80f823d84576..8eea144019d4 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Mga Snap" }, - "snapsInsightError": { - "message": "Nagkaroon ng error sa $1: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "Naglo-load ng insight sa transaksyon..." }, @@ -3375,7 +3371,8 @@ "message": "Tatakbo lamang ang snap kapag pinagana ito" }, "snapsUIError": { - "message": "Ang UI na tinukoy sa pamamagitan ng snap ay hindi wasto." + "message": "Ang UI na tinukoy sa pamamagitan ng snap ay hindi wasto.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Maaaring magdulot ang ilang network ng mga panganib sa seguridad at/o pagkapribado. Unawain ang mga panganib bago idagdag o gamitin ang isang network." diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index 61da042525e5..9fb967075ff6 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Snap'ler" }, - "snapsInsightError": { - "message": "$1: $2 ile ilgili bir hata oldu", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "İşlem ayrıntıları yükleniyor..." }, @@ -3375,7 +3371,8 @@ "message": "Bir snap yalnızca etkinleştirilmişse çalışır" }, "snapsUIError": { - "message": "Snap tarafından belirtilen Kullanıcı Arayüzü geçersiz." + "message": "Snap tarafından belirtilen Kullanıcı Arayüzü geçersiz.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Bazı ağlar güvenlik ve/veya gizlilik riskleri teşkil edebilir. Bir ağ eklemeden ve kullanmadan önce riskleri anlayın." diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index 97eccee87c02..dcfabd1d92e6 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Snap" }, - "snapsInsightError": { - "message": "Đã xảy ra lỗi với $1: $2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "Đang tải thông tin chi tiết về giao dịch..." }, @@ -3375,7 +3371,8 @@ "message": "Snap chỉ hoạt động khi đã bật" }, "snapsUIError": { - "message": "Giao diện người dùng được chỉ định bởi snap không hợp lệ." + "message": "Giao diện người dùng được chỉ định bởi snap không hợp lệ.", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "Một số mạng có thể gây ra rủi ro về bảo mật và/hoặc quyền riêng tư. Bạn cần hiểu rõ các rủi ro này trước khi thêm và sử dụng mạng." diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index d000e0c6b99c..0bce662da545 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -3355,10 +3355,6 @@ "snaps": { "message": "Snap" }, - "snapsInsightError": { - "message": "$1 发生错误:$2", - "description": "This is shown when the insight snap throws an error. $1 is the snap name, $2 is the error message." - }, "snapsInsightLoading": { "message": "正在加载交易洞察……" }, @@ -3375,7 +3371,8 @@ "message": "Snap仅在启用后才会运行" }, "snapsUIError": { - "message": "Snap指定的用户界面无效。" + "message": "Snap指定的用户界面无效。", + "description": "This is shown when the insight snap throws an error. $1 is the snap name" }, "someNetworksMayPoseSecurity": { "message": "某些网络可能会带来安全和/或隐私风险。在添加和使用网络之前,请先了解风险。" diff --git a/app/scripts/background.js b/app/scripts/background.js index 2fdca5a161a0..9e7f65d0d49e 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -24,11 +24,11 @@ import { } from '../../shared/constants/app'; import { SECOND } from '../../shared/constants/time'; import { - REJECT_NOTFICIATION_CLOSE, - REJECT_NOTFICIATION_CLOSE_SIG, - EVENT, - EVENT_NAMES, - TRAITS, + REJECT_NOTIFICATION_CLOSE, + REJECT_NOTIFICATION_CLOSE_SIG, + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsUserTrait, } from '../../shared/constants/metametrics'; import { checkForLastErrorAndLog } from '../../shared/modules/browser-runtime.utils'; import { isManifestV3 } from '../../shared/modules/mv3.utils'; @@ -738,13 +738,13 @@ export function setupController(initState, initLangCode, overrides) { ).forEach((txId) => controller.txController.txStateManager.setTxStatusRejected(txId), ); - controller.signController.rejectUnapproved(REJECT_NOTFICIATION_CLOSE_SIG); + controller.signController.rejectUnapproved(REJECT_NOTIFICATION_CLOSE_SIG); controller.decryptMessageManager.messages .filter((msg) => msg.status === 'unapproved') .forEach((tx) => controller.decryptMessageManager.rejectMsg( tx.id, - REJECT_NOTFICIATION_CLOSE, + REJECT_NOTIFICATION_CLOSE, ), ); controller.encryptionPublicKeyManager.messages @@ -752,7 +752,7 @@ export function setupController(initState, initLangCode, overrides) { .forEach((tx) => controller.encryptionPublicKeyManager.rejectMsg( tx.id, - REJECT_NOTFICIATION_CLOSE, + REJECT_NOTIFICATION_CLOSE, ), ); @@ -848,11 +848,13 @@ async function openPopup() { const addAppInstalledEvent = () => { if (controller) { controller.metaMetricsController.updateTraits({ - [TRAITS.INSTALL_DATE_EXT]: new Date().toISOString().split('T')[0], // yyyy-mm-dd + [MetaMetricsUserTrait.InstallDateExt]: new Date() + .toISOString() + .split('T')[0], // yyyy-mm-dd }); controller.metaMetricsController.addEventBeforeMetricsOptIn({ - category: EVENT.CATEGORIES.APP, - event: EVENT_NAMES.APP_INSTALLED, + category: MetaMetricsEventCategory.App, + event: MetaMetricsEventName.AppInstalled, properties: {}, }); return; diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js index a53bee096c7a..2b23dd71b5d4 100644 --- a/app/scripts/controllers/detect-tokens.js +++ b/app/scripts/controllers/detect-tokens.js @@ -8,7 +8,10 @@ import { AssetType, TokenStandard, } from '../../../shared/constants/transaction'; -import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../shared/constants/metametrics'; // By default, poll every 3 minutes const DEFAULT_INTERVAL = MINUTE * 3; @@ -167,8 +170,8 @@ export default class DetectTokensController { if (tokensWithBalance.length > 0) { this._trackMetaMetricsEvent({ - event: EVENT_NAMES.TOKEN_DETECTED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenDetected, + category: MetaMetricsEventCategory.Wallet, properties: { tokens: eventTokensDetails, token_standard: TokenStandard.ERC20, diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js index a949f3cc7152..c433b3f5e55c 100644 --- a/app/scripts/controllers/metametrics.js +++ b/app/scripts/controllers/metametrics.js @@ -15,7 +15,7 @@ import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; import { METAMETRICS_ANONYMOUS_ID, METAMETRICS_BACKGROUND_PAGE_OBJECT, - TRAITS, + MetaMetricsUserTrait, } from '../../../shared/constants/metametrics'; import { SECOND } from '../../../shared/constants/time'; import { isManifestV3 } from '../../../shared/modules/mv3.utils'; @@ -692,38 +692,44 @@ export default class MetaMetricsController { const { traits, previousUserTraits } = this.store.getState(); /** @type {MetaMetricsTraits} */ const currentTraits = { - [TRAITS.ADDRESS_BOOK_ENTRIES]: sum( + [MetaMetricsUserTrait.AddressBookEntries]: sum( Object.values(metamaskState.addressBook).map(size), ), - [TRAITS.INSTALL_DATE_EXT]: traits[TRAITS.INSTALL_DATE_EXT] || '', - [TRAITS.LEDGER_CONNECTION_TYPE]: metamaskState.ledgerTransportType, - [TRAITS.NETWORKS_ADDED]: Object.values( + [MetaMetricsUserTrait.InstallDateExt]: + traits[MetaMetricsUserTrait.InstallDateExt] || '', + [MetaMetricsUserTrait.LedgerConnectionType]: + metamaskState.ledgerTransportType, + [MetaMetricsUserTrait.NetworksAdded]: Object.values( metamaskState.networkConfigurations, ).map((networkConfiguration) => networkConfiguration.chainId), - [TRAITS.NETWORKS_WITHOUT_TICKER]: Object.values( + [MetaMetricsUserTrait.NetworksWithoutTicker]: Object.values( metamaskState.networkConfigurations, ) .filter(({ ticker }) => !ticker) .map(({ chainId }) => chainId), - [TRAITS.NFT_AUTODETECTION_ENABLED]: metamaskState.useNftDetection, - [TRAITS.NUMBER_OF_ACCOUNTS]: Object.values(metamaskState.identities) - .length, - [TRAITS.NUMBER_OF_NFT_COLLECTIONS]: this._getAllUniqueNFTAddressesLength( + [MetaMetricsUserTrait.NftAutodetectionEnabled]: + metamaskState.useNftDetection, + [MetaMetricsUserTrait.NumberOfAccounts]: Object.values( + metamaskState.identities, + ).length, + [MetaMetricsUserTrait.NumberOfNftCollections]: + this._getAllUniqueNFTAddressesLength(metamaskState.allNfts), + [MetaMetricsUserTrait.NumberOfNfts]: this._getAllNFTsFlattened( metamaskState.allNfts, - ), - [TRAITS.NUMBER_OF_NFTS]: this._getAllNFTsFlattened(metamaskState.allNfts) - .length, - [TRAITS.NUMBER_OF_TOKENS]: this._getNumberOfTokens(metamaskState), - [TRAITS.OPENSEA_API_ENABLED]: metamaskState.openSeaEnabled, - [TRAITS.THREE_BOX_ENABLED]: false, // deprecated, hard-coded as false - [TRAITS.THEME]: metamaskState.theme || 'default', - [TRAITS.TOKEN_DETECTION_ENABLED]: metamaskState.useTokenDetection, + ).length, + [MetaMetricsUserTrait.NumberOfTokens]: + this._getNumberOfTokens(metamaskState), + [MetaMetricsUserTrait.OpenseaApiEnabled]: metamaskState.openSeaEnabled, + [MetaMetricsUserTrait.ThreeBoxEnabled]: false, // deprecated, hard-coded as false + [MetaMetricsUserTrait.Theme]: metamaskState.theme || 'default', + [MetaMetricsUserTrait.TokenDetectionEnabled]: + metamaskState.useTokenDetection, ///: BEGIN:ONLY_INCLUDE_IN(flask) - [TRAITS.DESKTOP_ENABLED]: metamaskState.desktopEnabled || false, + [MetaMetricsUserTrait.DesktopEnabled]: + metamaskState.desktopEnabled || false, ///: END:ONLY_INCLUDE_IN - [TRAITS.SECURITY_PROVIDERS]: metamaskState.transactionSecurityCheckEnabled - ? ['opensea'] - : [], + [MetaMetricsUserTrait.SecurityProviders]: + metamaskState.transactionSecurityCheckEnabled ? ['opensea'] : [], }; if (!previousUserTraits) { diff --git a/app/scripts/controllers/metametrics.test.js b/app/scripts/controllers/metametrics.test.js index 18535c1d77c3..dbd0e56c8598 100644 --- a/app/scripts/controllers/metametrics.test.js +++ b/app/scripts/controllers/metametrics.test.js @@ -5,7 +5,7 @@ import { createSegmentMock } from '../lib/segment'; import { METAMETRICS_ANONYMOUS_ID, METAMETRICS_BACKGROUND_PAGE_OBJECT, - TRAITS, + MetaMetricsUserTrait, } from '../../../shared/constants/metametrics'; import waitUntilCalled from '../../../test/lib/wait-until-called'; import { @@ -953,22 +953,26 @@ describe('MetaMetricsController', function () { }); assert.deepEqual(traits, { - [TRAITS.ADDRESS_BOOK_ENTRIES]: 3, - [TRAITS.INSTALL_DATE_EXT]: '', - [TRAITS.LEDGER_CONNECTION_TYPE]: 'web-hid', - [TRAITS.NETWORKS_ADDED]: [CHAIN_IDS.MAINNET, CHAIN_IDS.GOERLI, '0xaf'], - [TRAITS.NETWORKS_WITHOUT_TICKER]: ['0xaf'], - [TRAITS.NFT_AUTODETECTION_ENABLED]: false, - [TRAITS.NUMBER_OF_ACCOUNTS]: 2, - [TRAITS.NUMBER_OF_NFT_COLLECTIONS]: 3, - [TRAITS.NUMBER_OF_NFTS]: 4, - [TRAITS.NUMBER_OF_TOKENS]: 5, - [TRAITS.OPENSEA_API_ENABLED]: true, - [TRAITS.THREE_BOX_ENABLED]: false, - [TRAITS.THEME]: 'default', - [TRAITS.TOKEN_DETECTION_ENABLED]: true, - [TRAITS.DESKTOP_ENABLED]: false, - [TRAITS.SECURITY_PROVIDERS]: [], + [MetaMetricsUserTrait.AddressBookEntries]: 3, + [MetaMetricsUserTrait.InstallDateExt]: '', + [MetaMetricsUserTrait.LedgerConnectionType]: 'web-hid', + [MetaMetricsUserTrait.NetworksAdded]: [ + CHAIN_IDS.MAINNET, + CHAIN_IDS.GOERLI, + '0xaf', + ], + [MetaMetricsUserTrait.NetworksWithoutTicker]: ['0xaf'], + [MetaMetricsUserTrait.NftAutodetectionEnabled]: false, + [MetaMetricsUserTrait.NumberOfAccounts]: 2, + [MetaMetricsUserTrait.NumberOfNftCollections]: 3, + [MetaMetricsUserTrait.NumberOfNfts]: 4, + [MetaMetricsUserTrait.NumberOfTokens]: 5, + [MetaMetricsUserTrait.OpenseaApiEnabled]: true, + [MetaMetricsUserTrait.ThreeBoxEnabled]: false, + [MetaMetricsUserTrait.Theme]: 'default', + [MetaMetricsUserTrait.TokenDetectionEnabled]: true, + [MetaMetricsUserTrait.DesktopEnabled]: false, + [MetaMetricsUserTrait.SecurityProviders]: [], }); }); @@ -1015,10 +1019,10 @@ describe('MetaMetricsController', function () { }); assert.deepEqual(updatedTraits, { - [TRAITS.ADDRESS_BOOK_ENTRIES]: 4, - [TRAITS.NUMBER_OF_ACCOUNTS]: 3, - [TRAITS.NUMBER_OF_TOKENS]: 1, - [TRAITS.OPENSEA_API_ENABLED]: false, + [MetaMetricsUserTrait.AddressBookEntries]: 4, + [MetaMetricsUserTrait.NumberOfAccounts]: 3, + [MetaMetricsUserTrait.NumberOfTokens]: 1, + [MetaMetricsUserTrait.OpenseaApiEnabled]: false, }); }); diff --git a/app/scripts/controllers/network/network-controller.js b/app/scripts/controllers/network/network-controller.js index ca48d85c4d6d..ad8ded74b1b4 100644 --- a/app/scripts/controllers/network/network-controller.js +++ b/app/scripts/controllers/network/network-controller.js @@ -26,7 +26,7 @@ import { isPrefixedFormattedHexString, isSafeChainId, } from '../../../../shared/modules/network.utils'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import { createNetworkClient } from './create-network-client'; /** @@ -645,7 +645,7 @@ export default class NetworkController extends EventEmitter { if (!oldNetworkConfigurationId) { this._trackMetaMetricsEvent({ event: 'Custom Network Added', - category: EVENT.CATEGORIES.NETWORK, + category: MetaMetricsEventCategory.Network, referrer: { url: referrer, }, diff --git a/app/scripts/controllers/network/network-controller.test.js b/app/scripts/controllers/network/network-controller.test.js index e8684179e6be..a58c563a87f2 100644 --- a/app/scripts/controllers/network/network-controller.test.js +++ b/app/scripts/controllers/network/network-controller.test.js @@ -5,7 +5,7 @@ import nock from 'nock'; import sinon from 'sinon'; import { ControllerMessenger } from '@metamask/base-controller'; import { BUILT_IN_NETWORKS } from '../../../../shared/constants/network'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsNetworkEventSource } from '../../../../shared/constants/metametrics'; import NetworkController from './network-controller'; jest.mock('uuid', () => { @@ -6991,7 +6991,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ), ).toThrow( @@ -7015,7 +7015,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ), ).toThrow( @@ -7038,7 +7038,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ), ).toThrow( @@ -7062,7 +7062,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ), ).toThrow(new Error('rpcUrl must be a valid URL')); @@ -7081,7 +7081,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ), ).toThrow( @@ -7126,7 +7126,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect( @@ -7164,7 +7164,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect( @@ -7213,7 +7213,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect( @@ -7262,7 +7262,7 @@ describe('NetworkController', () => { }; controller.upsertNetworkConfiguration(updatedConfiguration, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect( Object.values(controller.store.getState().networkConfigurations), @@ -7315,7 +7315,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ); @@ -7375,7 +7375,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect(controller.store.getState().provider).toStrictEqual( @@ -7424,7 +7424,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(rpcUrlNetwork, { setActive: true, referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect(controller.store.getState().provider).toStrictEqual({ @@ -7473,7 +7473,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(newNetworkConfiguration, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect( diff --git a/app/scripts/controllers/sign.test.ts b/app/scripts/controllers/sign.test.ts index 9363583fb42c..7212df2ae926 100644 --- a/app/scripts/controllers/sign.test.ts +++ b/app/scripts/controllers/sign.test.ts @@ -7,7 +7,7 @@ import { AbstractMessage, OriginalRequest, } from '@metamask/message-manager/dist/AbstractMessageManager'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import { detectSIWE } from '../../../shared/modules/siwe'; import SignController, { SignControllerMessenger, @@ -270,7 +270,7 @@ describe('SignController', () => { expect(metricsEventMock).toHaveBeenCalledTimes(6); expect(metricsEventMock).toHaveBeenLastCalledWith({ event: 'Test Reason', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { action: 'Sign Request', type: messageMock.type, diff --git a/app/scripts/controllers/sign.ts b/app/scripts/controllers/sign.ts index 13157d502aed..afaeaa4993ce 100644 --- a/app/scripts/controllers/sign.ts +++ b/app/scripts/controllers/sign.ts @@ -32,7 +32,7 @@ import { AddApprovalRequest, RejectRequest, } from '@metamask/approval-controller'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import { detectSIWE } from '../../../shared/modules/siwe'; import PreferencesController from './preferences'; @@ -510,7 +510,7 @@ export default class SignController extends BaseControllerV2< this._metricsEvent({ event: reason, - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { action: 'Sign Request', type: message.type, diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index a98ee441da64..c3026e0434f3 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -1,4 +1,4 @@ -import EventEmitter from 'safe-event-emitter'; +import EventEmitter from '@metamask/safe-event-emitter'; import { ObservableStore } from '@metamask/obs-store'; import { bufferToHex, keccak, toBuffer, isHexString } from 'ethereumjs-util'; import EthQuery from 'ethjs-query'; @@ -39,7 +39,7 @@ import { hexWEIToDecGWEI, } from '../../../../shared/modules/conversion.utils'; import { isSwapsDefaultTokenAddress } from '../../../../shared/modules/swaps.utils'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import { HARDFORKS, CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP, @@ -2027,7 +2027,7 @@ export default class TransactionController extends EventEmitter { this._trackMetaMetricsEvent({ event: 'Swap Failed', sensitiveProperties: { ...txMeta.swapMetaData }, - category: EVENT.CATEGORIES.SWAPS, + category: MetaMetricsEventCategory.Swaps, }); } else { const tokensReceived = getSwapsTokensReceivedFromTxMeta( @@ -2062,7 +2062,7 @@ export default class TransactionController extends EventEmitter { this._trackMetaMetricsEvent({ event: 'Swap Completed', - category: EVENT.CATEGORIES.SWAPS, + category: MetaMetricsEventCategory.Swaps, sensitiveProperties: { ...txMeta.swapMetaData, token_to_amount_received: tokensReceived, @@ -2414,7 +2414,7 @@ export default class TransactionController extends EventEmitter { // occur. case TransactionMetaMetricsEvent.added: this.createEventFragment({ - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, initialEvent: TransactionMetaMetricsEvent.added, successEvent: TransactionMetaMetricsEvent.approved, failureEvent: TransactionMetaMetricsEvent.rejected, @@ -2436,7 +2436,7 @@ export default class TransactionController extends EventEmitter { case TransactionMetaMetricsEvent.approved: case TransactionMetaMetricsEvent.rejected: this.createEventFragment({ - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, successEvent: TransactionMetaMetricsEvent.approved, failureEvent: TransactionMetaMetricsEvent.rejected, properties, @@ -2458,7 +2458,7 @@ export default class TransactionController extends EventEmitter { // properties to the transaction event. case TransactionMetaMetricsEvent.submitted: this.createEventFragment({ - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, initialEvent: TransactionMetaMetricsEvent.submitted, successEvent: TransactionMetaMetricsEvent.finalized, properties, @@ -2478,7 +2478,7 @@ export default class TransactionController extends EventEmitter { // fragment does not exist. case TransactionMetaMetricsEvent.finalized: this.createEventFragment({ - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, successEvent: TransactionMetaMetricsEvent.finalized, properties, sensitiveProperties, diff --git a/app/scripts/controllers/transactions/index.test.js b/app/scripts/controllers/transactions/index.test.js index 99b2cd4b1027..c16f1fa2c7eb 100644 --- a/app/scripts/controllers/transactions/index.test.js +++ b/app/scripts/controllers/transactions/index.test.js @@ -10,7 +10,10 @@ import { getTestAccounts, } from '../../../../test/stub/provider'; import mockEstimates from '../../../../test/data/mock-estimates.json'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsTransactionEventSource, +} from '../../../../shared/constants/metametrics'; import { TransactionStatus, TransactionType, @@ -1772,7 +1775,7 @@ describe('Transaction Controller', function () { successEvent: 'Transaction Approved', failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, persist: true, properties: { chain_id: '0x5', @@ -1781,7 +1784,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: ORIGIN_METAMASK, - source: EVENT.SOURCE.TRANSACTION.USER, + source: MetaMetricsTransactionEventSource.User, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, @@ -1859,7 +1862,7 @@ describe('Transaction Controller', function () { initialEvent: 'Transaction Submitted', successEvent: 'Transaction Finalized', uniqueIdentifier: 'transaction-submitted-1', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, persist: true, properties: { chain_id: '0x5', @@ -1868,7 +1871,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: ORIGIN_METAMASK, - source: EVENT.SOURCE.TRANSACTION.USER, + source: MetaMetricsTransactionEventSource.User, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, @@ -1958,7 +1961,7 @@ describe('Transaction Controller', function () { successEvent: 'Transaction Approved', failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, persist: true, properties: { chain_id: '0x5', @@ -1967,7 +1970,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, @@ -2047,7 +2050,7 @@ describe('Transaction Controller', function () { initialEvent: 'Transaction Submitted', successEvent: 'Transaction Finalized', uniqueIdentifier: 'transaction-submitted-1', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, persist: true, properties: { chain_id: '0x5', @@ -2056,7 +2059,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, @@ -2138,7 +2141,7 @@ describe('Transaction Controller', function () { successEvent: 'Transaction Approved', failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, persist: true, properties: { chain_id: '0x5', @@ -2147,7 +2150,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, @@ -2211,11 +2214,11 @@ describe('Transaction Controller', function () { failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', persist: true, - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, chain_id: '0x5', eip_1559_version: '0', @@ -2285,11 +2288,11 @@ describe('Transaction Controller', function () { failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', persist: true, - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, chain_id: '0x5', eip_1559_version: '0', @@ -2359,11 +2362,11 @@ describe('Transaction Controller', function () { failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', persist: true, - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, chain_id: '0x5', eip_1559_version: '0', @@ -2441,7 +2444,7 @@ describe('Transaction Controller', function () { failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', persist: true, - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { chain_id: '0x5', eip_1559_version: '2', @@ -2449,7 +2452,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, diff --git a/app/scripts/controllers/transactions/pending-tx-tracker.js b/app/scripts/controllers/transactions/pending-tx-tracker.js index 6252727c330f..93b1de2526d5 100644 --- a/app/scripts/controllers/transactions/pending-tx-tracker.js +++ b/app/scripts/controllers/transactions/pending-tx-tracker.js @@ -1,4 +1,4 @@ -import EventEmitter from 'safe-event-emitter'; +import EventEmitter from '@metamask/safe-event-emitter'; import log from 'loglevel'; import EthQuery from 'ethjs-query'; import { TransactionStatus } from '../../../../shared/constants/transaction'; diff --git a/app/scripts/controllers/transactions/tx-state-manager.js b/app/scripts/controllers/transactions/tx-state-manager.js index 98d18bca124f..20e142c6c052 100644 --- a/app/scripts/controllers/transactions/tx-state-manager.js +++ b/app/scripts/controllers/transactions/tx-state-manager.js @@ -1,4 +1,4 @@ -import EventEmitter from 'safe-event-emitter'; +import EventEmitter from '@metamask/safe-event-emitter'; import { ObservableStore } from '@metamask/obs-store'; import log from 'loglevel'; import { values, keyBy, mapValues, omitBy, pickBy, sortBy } from 'lodash'; diff --git a/app/scripts/lib/createRPCMethodTrackingMiddleware.js b/app/scripts/lib/createRPCMethodTrackingMiddleware.js index cec5b3308515..cd3b9720ad30 100644 --- a/app/scripts/lib/createRPCMethodTrackingMiddleware.js +++ b/app/scripts/lib/createRPCMethodTrackingMiddleware.js @@ -4,9 +4,9 @@ import { TransactionStatus } from '../../../shared/constants/transaction'; import { SECOND } from '../../../shared/constants/time'; import { detectSIWE } from '../../../shared/modules/siwe'; import { - EVENT, - EVENT_NAMES, - METAMETRIC_KEY_OPT, + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsEventUiCustomization, } from '../../../shared/constants/metametrics'; /** @@ -46,50 +46,50 @@ const RATE_LIMIT_MAP = { */ const EVENT_NAME_MAP = { [MESSAGE_TYPE.ETH_SIGN]: { - APPROVED: EVENT_NAMES.SIGNATURE_APPROVED, - FAILED: EVENT_NAMES.SIGNATURE_FAILED, - REJECTED: EVENT_NAMES.SIGNATURE_REJECTED, - REQUESTED: EVENT_NAMES.SIGNATURE_REQUESTED, + APPROVED: MetaMetricsEventName.SignatureApproved, + FAILED: MetaMetricsEventName.SignatureFailed, + REJECTED: MetaMetricsEventName.SignatureRejected, + REQUESTED: MetaMetricsEventName.SignatureRequested, }, [MESSAGE_TYPE.ETH_SIGN_TYPED_DATA]: { - APPROVED: EVENT_NAMES.SIGNATURE_APPROVED, - REJECTED: EVENT_NAMES.SIGNATURE_REJECTED, - REQUESTED: EVENT_NAMES.SIGNATURE_REQUESTED, + APPROVED: MetaMetricsEventName.SignatureApproved, + REJECTED: MetaMetricsEventName.SignatureRejected, + REQUESTED: MetaMetricsEventName.SignatureRequested, }, [MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V3]: { - APPROVED: EVENT_NAMES.SIGNATURE_APPROVED, - REJECTED: EVENT_NAMES.SIGNATURE_REJECTED, - REQUESTED: EVENT_NAMES.SIGNATURE_REQUESTED, + APPROVED: MetaMetricsEventName.SignatureApproved, + REJECTED: MetaMetricsEventName.SignatureRejected, + REQUESTED: MetaMetricsEventName.SignatureRequested, }, [MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4]: { - APPROVED: EVENT_NAMES.SIGNATURE_APPROVED, - REJECTED: EVENT_NAMES.SIGNATURE_REJECTED, - REQUESTED: EVENT_NAMES.SIGNATURE_REQUESTED, + APPROVED: MetaMetricsEventName.SignatureApproved, + REJECTED: MetaMetricsEventName.SignatureRejected, + REQUESTED: MetaMetricsEventName.SignatureRequested, }, [MESSAGE_TYPE.PERSONAL_SIGN]: { - APPROVED: EVENT_NAMES.SIGNATURE_APPROVED, - REJECTED: EVENT_NAMES.SIGNATURE_REJECTED, - REQUESTED: EVENT_NAMES.SIGNATURE_REQUESTED, + APPROVED: MetaMetricsEventName.SignatureApproved, + REJECTED: MetaMetricsEventName.SignatureRejected, + REQUESTED: MetaMetricsEventName.SignatureRequested, }, [MESSAGE_TYPE.ETH_DECRYPT]: { - APPROVED: EVENT_NAMES.DECRYPTION_APPROVED, - REJECTED: EVENT_NAMES.DECRYPTION_REJECTED, - REQUESTED: EVENT_NAMES.DECRYPTION_REQUESTED, + APPROVED: MetaMetricsEventName.DecryptionApproved, + REJECTED: MetaMetricsEventName.DecryptionRejected, + REQUESTED: MetaMetricsEventName.DecryptionRequested, }, [MESSAGE_TYPE.ETH_GET_ENCRYPTION_PUBLIC_KEY]: { - APPROVED: EVENT_NAMES.ENCRYPTION_PUBLIC_KEY_APPROVED, - REJECTED: EVENT_NAMES.ENCRYPTION_PUBLIC_KEY_REJECTED, - REQUESTED: EVENT_NAMES.ENCRYPTION_PUBLIC_KEY_REQUESTED, + APPROVED: MetaMetricsEventName.EncryptionPublicKeyApproved, + REJECTED: MetaMetricsEventName.EncryptionPublicKeyRejected, + REQUESTED: MetaMetricsEventName.EncryptionPublicKeyRequested, }, [MESSAGE_TYPE.ETH_REQUEST_ACCOUNTS]: { - APPROVED: EVENT_NAMES.PERMISSIONS_APPROVED, - REJECTED: EVENT_NAMES.PERMISSIONS_REJECTED, - REQUESTED: EVENT_NAMES.PERMISSIONS_REQUESTED, + APPROVED: MetaMetricsEventName.PermissionsApproved, + REJECTED: MetaMetricsEventName.PermissionsRejected, + REQUESTED: MetaMetricsEventName.PermissionsRequested, }, [MESSAGE_TYPE.WALLET_REQUEST_PERMISSIONS]: { - APPROVED: EVENT_NAMES.PERMISSIONS_APPROVED, - REJECTED: EVENT_NAMES.PERMISSIONS_REJECTED, - REQUESTED: EVENT_NAMES.PERMISSIONS_REQUESTED, + APPROVED: MetaMetricsEventName.PermissionsApproved, + REJECTED: MetaMetricsEventName.PermissionsRejected, + REQUESTED: MetaMetricsEventName.PermissionsRequested, }, }; @@ -162,9 +162,9 @@ export default function createRPCMethodTrackingMiddleware({ // 'Provider Method Called'. const event = eventType ? eventType.REQUESTED - : EVENT_NAMES.PROVIDER_METHOD_CALLED; + : MetaMetricsEventName.ProviderMethodCalled; - if (event === EVENT_NAMES.SIGNATURE_REQUESTED) { + if (event === MetaMetricsEventName.SignatureRequested) { eventProperties.signature_type = method; const data = req?.params?.[0]; @@ -190,11 +190,11 @@ export default function createRPCMethodTrackingMiddleware({ if (securityProviderResponse?.flagAsDangerous === 1) { eventProperties.ui_customizations = [ - METAMETRIC_KEY_OPT.ui_customizations.flaggedAsMalicious, + MetaMetricsEventUiCustomization.FlaggedAsMalicious, ]; } else if (securityProviderResponse?.flagAsDangerous === 2) { eventProperties.ui_customizations = [ - METAMETRIC_KEY_OPT.ui_customizations.flaggedAsSafetyUnknown, + MetaMetricsEventUiCustomization.FlaggedAsSafetyUnknown, ]; } @@ -203,7 +203,7 @@ export default function createRPCMethodTrackingMiddleware({ if (isSIWEMessage) { eventProperties.ui_customizations = ( eventProperties.ui_customizations || [] - ).concat(METAMETRIC_KEY_OPT.ui_customizations.SIWE); + ).concat(MetaMetricsEventUiCustomization.Siwe); } } } catch (e) { @@ -217,7 +217,7 @@ export default function createRPCMethodTrackingMiddleware({ trackEvent({ event, - category: EVENT.CATEGORIES.INPAGE_PROVIDER, + category: MetaMetricsEventCategory.InpageProvider, referrer: { url: origin, }, @@ -253,7 +253,7 @@ export default function createRPCMethodTrackingMiddleware({ trackEvent({ event, - category: EVENT.CATEGORIES.INPAGE_PROVIDER, + category: MetaMetricsEventCategory.InpageProvider, referrer: { url: origin, }, diff --git a/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js b/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js index 5be404f43fdd..342fd320aea0 100644 --- a/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js +++ b/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js @@ -1,8 +1,8 @@ import { errorCodes } from 'eth-rpc-errors'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; import { - EVENT_NAMES, - METAMETRIC_KEY_OPT, + MetaMetricsEventName, + MetaMetricsEventUiCustomization, } from '../../../shared/constants/metametrics'; import { SECOND } from '../../../shared/constants/time'; import { detectSIWE } from '../../../shared/modules/siwe'; @@ -111,7 +111,7 @@ describe('createRPCMethodTrackingMiddleware', () => { metricsState.participateInMetaMetrics = true; }); - it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event`, async () => { + it(`should immediately track a ${MetaMetricsEventName.SignatureRequested} event`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN, origin: 'some.dapp', @@ -125,7 +125,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(1); expect(trackEvent.mock.calls[0][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_REQUESTED, + event: MetaMetricsEventName.SignatureRequested, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN, }, @@ -133,7 +133,7 @@ describe('createRPCMethodTrackingMiddleware', () => { }); }); - it(`should track a ${EVENT_NAMES.SIGNATURE_APPROVED} event if the user approves`, async () => { + it(`should track a ${MetaMetricsEventName.SignatureApproved} event if the user approves`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4, origin: 'some.dapp', @@ -148,7 +148,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(2); expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_APPROVED, + event: MetaMetricsEventName.SignatureApproved, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4, }, @@ -156,7 +156,7 @@ describe('createRPCMethodTrackingMiddleware', () => { }); }); - it(`should track a ${EVENT_NAMES.SIGNATURE_REJECTED} event if the user approves`, async () => { + it(`should track a ${MetaMetricsEventName.SignatureRejected} event if the user approves`, async () => { const req = { method: MESSAGE_TYPE.PERSONAL_SIGN, origin: 'some.dapp', @@ -171,7 +171,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(2); expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_REJECTED, + event: MetaMetricsEventName.SignatureRejected, properties: { signature_type: MESSAGE_TYPE.PERSONAL_SIGN, }, @@ -179,7 +179,7 @@ describe('createRPCMethodTrackingMiddleware', () => { }); }); - it(`should track a ${EVENT_NAMES.PERMISSIONS_APPROVED} event if the user approves`, async () => { + it(`should track a ${MetaMetricsEventName.PermissionsApproved} event if the user approves`, async () => { const req = { method: MESSAGE_TYPE.ETH_REQUEST_ACCOUNTS, origin: 'some.dapp', @@ -192,7 +192,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(2); expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.PERMISSIONS_APPROVED, + event: MetaMetricsEventName.PermissionsApproved, properties: { method: MESSAGE_TYPE.ETH_REQUEST_ACCOUNTS }, referrer: { url: 'some.dapp' }, }); @@ -261,17 +261,17 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_APPROVED, + event: MetaMetricsEventName.SignatureApproved, properties: { signature_type: MESSAGE_TYPE.PERSONAL_SIGN, - ui_customizations: [METAMETRIC_KEY_OPT.ui_customizations.SIWE], + ui_customizations: [MetaMetricsEventUiCustomization.Siwe], }, referrer: { url: 'some.dapp' }, }); }); describe(`when '${MESSAGE_TYPE.ETH_SIGN}' is disabled in advanced settings`, () => { - it(`should track ${EVENT_NAMES.SIGNATURE_FAILED} and include error property`, async () => { + it(`should track ${MetaMetricsEventName.SignatureFailed} and include error property`, async () => { const mockError = { code: errorCodes.rpc.methodNotFound }; const req = { method: MESSAGE_TYPE.ETH_SIGN, @@ -289,7 +289,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_FAILED, + event: MetaMetricsEventName.SignatureFailed, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN, error: mockError, @@ -300,7 +300,7 @@ describe('createRPCMethodTrackingMiddleware', () => { }); describe('when request is flagged as safe by security provider', () => { - it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event`, async () => { + it(`should immediately track a ${MetaMetricsEventName.SignatureRequested} event`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN, origin: 'some.dapp', @@ -315,7 +315,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(1); expect(trackEvent.mock.calls[0][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_REQUESTED, + event: MetaMetricsEventName.SignatureRequested, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN, }, @@ -329,7 +329,7 @@ describe('createRPCMethodTrackingMiddleware', () => { flagAsDangerous = 1; }); - it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event which is flagged as malicious`, async () => { + it(`should immediately track a ${MetaMetricsEventName.SignatureRequested} event which is flagged as malicious`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN, origin: 'some.dapp', @@ -344,7 +344,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(1); expect(trackEvent.mock.calls[0][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_REQUESTED, + event: MetaMetricsEventName.SignatureRequested, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN, ui_customizations: ['flagged_as_malicious'], @@ -359,7 +359,7 @@ describe('createRPCMethodTrackingMiddleware', () => { flagAsDangerous = 2; }); - it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event which is flagged as safety unknown`, async () => { + it(`should immediately track a ${MetaMetricsEventName.SignatureRequested} event which is flagged as safety unknown`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN, origin: 'some.dapp', @@ -374,7 +374,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(1); expect(trackEvent.mock.calls[0][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_REQUESTED, + event: MetaMetricsEventName.SignatureRequested, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN, ui_customizations: ['flagged_as_safety_unknown'], diff --git a/app/scripts/lib/decrypt-message-manager.js b/app/scripts/lib/decrypt-message-manager.js index 197b667633eb..9249c907e4c0 100644 --- a/app/scripts/lib/decrypt-message-manager.js +++ b/app/scripts/lib/decrypt-message-manager.js @@ -4,7 +4,7 @@ import { bufferToHex } from 'ethereumjs-util'; import { ethErrors } from 'eth-rpc-errors'; import log from 'loglevel'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; import createId from '../../../shared/modules/random-id'; import { stripHexPrefix } from '../../../shared/modules/hexstring-utils'; @@ -237,7 +237,7 @@ export default class DecryptMessageManager extends EventEmitter { if (reason) { this.metricsEvent({ event: reason, - category: EVENT.CATEGORIES.MESSAGES, + category: MetaMetricsEventCategory.Messages, properties: { action: 'Decrypt Message Request', }, diff --git a/app/scripts/lib/encryption-public-key-manager.js b/app/scripts/lib/encryption-public-key-manager.js index 6230c9224170..9791e0378e95 100644 --- a/app/scripts/lib/encryption-public-key-manager.js +++ b/app/scripts/lib/encryption-public-key-manager.js @@ -3,7 +3,7 @@ import { ObservableStore } from '@metamask/obs-store'; import { ethErrors } from 'eth-rpc-errors'; import log from 'loglevel'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; import createId from '../../../shared/modules/random-id'; @@ -225,7 +225,7 @@ export default class EncryptionPublicKeyManager extends EventEmitter { if (reason) { this.metricsEvent({ event: reason, - category: EVENT.CATEGORIES.MESSAGES, + category: MetaMetricsEventCategory.Messages, properties: { action: 'Encryption public key Request', }, diff --git a/app/scripts/lib/metaRPCClientFactory.js b/app/scripts/lib/metaRPCClientFactory.js index c09f7e38d9db..3aae9962dbdb 100644 --- a/app/scripts/lib/metaRPCClientFactory.js +++ b/app/scripts/lib/metaRPCClientFactory.js @@ -1,5 +1,5 @@ import { EthereumRpcError } from 'eth-rpc-errors'; -import SafeEventEmitter from 'safe-event-emitter'; +import SafeEventEmitter from '@metamask/safe-event-emitter'; import createRandomId from '../../../shared/modules/random-id'; import { TEN_SECONDS_IN_MILLISECONDS } from '../../../shared/lib/transactions-controller-utils'; diff --git a/app/scripts/lib/notification-manager.js b/app/scripts/lib/notification-manager.js index 6ee4e3c124c1..2e4d45ee2cec 100644 --- a/app/scripts/lib/notification-manager.js +++ b/app/scripts/lib/notification-manager.js @@ -1,4 +1,4 @@ -import EventEmitter from 'safe-event-emitter'; +import EventEmitter from '@metamask/safe-event-emitter'; import ExtensionPlatform from '../platforms/extension'; const NOTIFICATION_HEIGHT = 620; diff --git a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js index b35fe1e5c723..f63412b61c62 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js @@ -9,7 +9,7 @@ import { isPrefixedFormattedHexString, isSafeChainId, } from '../../../../../shared/modules/network.utils'; -import { EVENT } from '../../../../../shared/constants/metametrics'; +import { MetaMetricsNetworkEventSource } from '../../../../../shared/constants/metametrics'; const addEthereumChain = { methodNames: [MESSAGE_TYPE.ADD_ETHEREUM_CHAIN], @@ -262,7 +262,7 @@ async function addEthereumChainHandler( rpcUrl: firstValidRPCUrl, ticker, }, - { source: EVENT.SOURCE.NETWORK.DAPP, referrer: origin }, + { source: MetaMetricsNetworkEventSource.Dapp, referrer: origin }, ); // Once the network has been added, the requested is considered successful diff --git a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js index b829e16fa04b..5ea476a4f1af 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js @@ -1,5 +1,5 @@ import { MESSAGE_TYPE } from '../../../../../shared/constants/app'; -import { EVENT } from '../../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../../shared/constants/metametrics'; /** * This RPC method is called by the inpage provider whenever it detects the @@ -49,7 +49,7 @@ function logWeb3ShimUsageHandler( sendMetrics( { event: `Website Accessed window.web3 Shim`, - category: EVENT.CATEGORIES.INPAGE_PROVIDER, + category: MetaMetricsEventCategory.InpageProvider, referrer: { url: origin, }, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 93670073da94..c1b050b3b110 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -104,7 +104,10 @@ import { ///: END:ONLY_INCLUDE_IN POLLING_TOKEN_ENVIRONMENT_TYPES, } from '../../shared/constants/app'; -import { EVENT, EVENT_NAMES } from '../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../shared/constants/metametrics'; import { getTokenIdParam, @@ -399,8 +402,8 @@ export default class MetamaskController extends EventEmitter { ), onNftAdded: ({ address, symbol, tokenId, standard, source }) => this.metaMetricsController.trackEvent({ - event: EVENT_NAMES.NFT_ADDED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.NftAdded, + category: MetaMetricsEventCategory.Wallet, properties: { token_contract_address: address, token_symbol: symbol, @@ -1069,7 +1072,7 @@ export default class MetamaskController extends EventEmitter { this.metaMetricsController.trackEvent( { event: 'Tx Status Update: On-Chain Failure', - category: EVENT.CATEGORIES.BACKGROUND, + category: MetaMetricsEventCategory.Background, properties: { action: 'Transactions', errorMessage: txMeta.simulationFails?.reason, @@ -1196,8 +1199,8 @@ export default class MetamaskController extends EventEmitter { const { serviceWorkerLastActiveTime } = this.appStateController.store.getState(); const metametricsPayload = { - category: EVENT.SOURCE.SERVICE_WORKERS, - event: EVENT_NAMES.SERVICE_WORKER_RESTARTED, + category: MetaMetricsEventCategory.ServiceWorkers, + event: MetaMetricsEventName.ServiceWorkerRestarted, properties: { service_worker_restarted_time: Date.now() - serviceWorkerLastActiveTime, @@ -1619,7 +1622,7 @@ export default class MetamaskController extends EventEmitter { (truncatedSnap) => { this.metaMetricsController.trackEvent({ event: 'Snap Installed', - category: EVENT.CATEGORIES.SNAPS, + category: MetaMetricsEventCategory.Snaps, properties: { snap_id: truncatedSnap.id, version: truncatedSnap.version, @@ -1633,7 +1636,7 @@ export default class MetamaskController extends EventEmitter { (newSnap, oldVersion) => { this.metaMetricsController.trackEvent({ event: 'Snap Updated', - category: EVENT.CATEGORIES.SNAPS, + category: MetaMetricsEventCategory.Snaps, properties: { snap_id: newSnap.id, old_version: oldVersion, @@ -3540,8 +3543,8 @@ export default class MetamaskController extends EventEmitter { if (usePhishDetect && phishingTestResponse?.result) { this.sendPhishingWarning(connectionStream, hostname); this.metaMetricsController.trackEvent({ - event: EVENT_NAMES.PHISHING_PAGE_DISPLAYED, - category: EVENT.CATEGORIES.PHISHING, + event: MetaMetricsEventName.PhishingPageDisplayed, + category: MetaMetricsEventCategory.Phishing, properties: { url: hostname, }, diff --git a/development/generate-lavamoat-policies.js b/development/generate-lavamoat-policies.js index a4004e0b8456..9266091b75e4 100755 --- a/development/generate-lavamoat-policies.js +++ b/development/generate-lavamoat-policies.js @@ -4,6 +4,11 @@ const yargs = require('yargs/yargs'); const { hideBin } = require('yargs/helpers'); const { BuildType } = require('./lib/build-type'); +const stableBuildTypes = Object.values(BuildType).filter( + // Skip generating policy for MMI until that build has stabilized + (buildType) => buildType !== BuildType.mmi, +); + start().catch((error) => { console.error('Policy generation failed.', error); process.exitCode = 1; @@ -20,7 +25,7 @@ async function start() { .option('build-types', { alias: ['t'], choices: Object.values(BuildType), - default: Object.values(BuildType), + default: stableBuildTypes, demandOption: true, description: 'The build type(s) to generate policy files for.', }) diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index cf463cda4f1c..98b889720187 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -469,8 +469,8 @@ "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store": { "packages": { "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store>through2": true, - "browserify>stream-browserify": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "browserify>stream-browserify": true } }, "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store>through2": { @@ -874,10 +874,10 @@ "@metamask/eth-json-rpc-infura>@metamask/utils": true, "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, + "@metamask/safe-event-emitter": true, "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, "lavamoat>json-stable-stringify": true, "vinyl>clone": true } @@ -912,8 +912,8 @@ }, "@metamask/eth-json-rpc-provider": { "packages": { - "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "json-rpc-engine": true } }, "@metamask/eth-keyring-controller": { @@ -968,7 +968,7 @@ }, "@metamask/eth-keyring-controller>obs-store": { "packages": { - "safe-event-emitter": true, + "@metamask/eth-token-tracker>safe-event-emitter": true, "watchify>xtend": true } }, @@ -1056,9 +1056,9 @@ "@metamask/eth-token-tracker>eth-block-tracker": true, "@metamask/eth-token-tracker>ethjs": true, "@metamask/eth-token-tracker>human-standard-token-abi": true, + "@metamask/eth-token-tracker>safe-event-emitter": true, "ethjs-contract": true, - "ethjs-query": true, - "safe-event-emitter": true + "ethjs-query": true } }, "@metamask/eth-token-tracker>deep-equal": { @@ -1090,8 +1090,8 @@ }, "packages": { "@metamask/eth-token-tracker>eth-block-tracker>pify": true, - "eth-query": true, - "safe-event-emitter": true + "@metamask/eth-token-tracker>safe-event-emitter": true, + "eth-query": true } }, "@metamask/eth-token-tracker>ethjs": { @@ -1150,6 +1150,15 @@ "promise-to-callback": true } }, + "@metamask/eth-token-tracker>safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "browserify>util": true, + "webpack>events": true + } + }, "@metamask/etherscan-link": { "globals": { "URL": true @@ -1327,13 +1336,10 @@ } }, "@metamask/obs-store": { - "globals": { - "localStorage": true - }, "packages": { "@metamask/obs-store>through2": true, - "browserify>stream-browserify": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "browserify>stream-browserify": true } }, "@metamask/obs-store>through2": { @@ -1455,6 +1461,14 @@ "crypto.getRandomValues": true } }, + "@metamask/safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "browserify>events": true + } + }, "@metamask/scure-bip39": { "globals": { "TextEncoder": true @@ -2726,10 +2740,10 @@ "setTimeout": true }, "packages": { + "@metamask/safe-event-emitter": true, "eth-block-tracker>@metamask/utils": true, "eth-block-tracker>pify": true, - "eth-query>json-rpc-random-id": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "eth-query>json-rpc-random-id": true } }, "eth-block-tracker>@metamask/utils": { @@ -2772,10 +2786,10 @@ "console.error": true }, "packages": { + "@metamask/safe-event-emitter": true, "eth-json-rpc-filters>async-mutex": true, "eth-query": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, "pify": true } }, @@ -3614,16 +3628,8 @@ }, "json-rpc-engine": { "packages": { - "eth-rpc-errors": true, - "json-rpc-engine>@metamask/safe-event-emitter": true - } - }, - "json-rpc-engine>@metamask/safe-event-emitter": { - "globals": { - "setTimeout": true - }, - "packages": { - "browserify>events": true + "@metamask/safe-event-emitter": true, + "eth-rpc-errors": true } }, "json-rpc-middleware-stream": { @@ -3632,7 +3638,7 @@ "setTimeout": true }, "packages": { - "json-rpc-engine>@metamask/safe-event-emitter": true, + "@metamask/safe-event-emitter": true, "readable-stream": true } }, @@ -4211,15 +4217,6 @@ "@babel/runtime": true } }, - "safe-event-emitter": { - "globals": { - "setTimeout": true - }, - "packages": { - "browserify>util": true, - "webpack>events": true - } - }, "semver": { "globals": { "console.error": true diff --git a/lavamoat/browserify/desktop/policy.json b/lavamoat/browserify/desktop/policy.json index c2acd56f3bc4..167424fd40a2 100644 --- a/lavamoat/browserify/desktop/policy.json +++ b/lavamoat/browserify/desktop/policy.json @@ -469,8 +469,8 @@ "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store": { "packages": { "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store>through2": true, - "browserify>stream-browserify": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "browserify>stream-browserify": true } }, "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store>through2": { @@ -857,9 +857,9 @@ "setTimeout": true }, "packages": { + "@metamask/desktop>@metamask/obs-store": true, "@metamask/desktop>eciesjs": true, "@metamask/desktop>otpauth": true, - "@metamask/obs-store": true, "browserify>buffer": true, "browserify>events": true, "browserify>process": true, @@ -872,6 +872,24 @@ "webextension-polyfill": true } }, + "@metamask/desktop>@metamask/obs-store": { + "globals": { + "localStorage": true + }, + "packages": { + "@metamask/desktop>@metamask/obs-store>through2": true, + "browserify>stream-browserify": true, + "json-rpc-engine>@metamask/safe-event-emitter": true + } + }, + "@metamask/desktop>@metamask/obs-store>through2": { + "packages": { + "browserify>process": true, + "browserify>util": true, + "readable-stream": true, + "watchify>xtend": true + } + }, "@metamask/desktop>eciesjs": { "packages": { "@metamask/desktop>eciesjs>futoin-hkdf": true, @@ -928,10 +946,10 @@ "@metamask/eth-json-rpc-infura>@metamask/utils": true, "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, + "@metamask/safe-event-emitter": true, "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, "lavamoat>json-stable-stringify": true, "vinyl>clone": true } @@ -966,8 +984,8 @@ }, "@metamask/eth-json-rpc-provider": { "packages": { - "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "json-rpc-engine": true } }, "@metamask/eth-keyring-controller": { @@ -1022,7 +1040,7 @@ }, "@metamask/eth-keyring-controller>obs-store": { "packages": { - "safe-event-emitter": true, + "@metamask/eth-token-tracker>safe-event-emitter": true, "watchify>xtend": true } }, @@ -1110,9 +1128,9 @@ "@metamask/eth-token-tracker>eth-block-tracker": true, "@metamask/eth-token-tracker>ethjs": true, "@metamask/eth-token-tracker>human-standard-token-abi": true, + "@metamask/eth-token-tracker>safe-event-emitter": true, "ethjs-contract": true, - "ethjs-query": true, - "safe-event-emitter": true + "ethjs-query": true } }, "@metamask/eth-token-tracker>deep-equal": { @@ -1144,8 +1162,8 @@ }, "packages": { "@metamask/eth-token-tracker>eth-block-tracker>pify": true, - "eth-query": true, - "safe-event-emitter": true + "@metamask/eth-token-tracker>safe-event-emitter": true, + "eth-query": true } }, "@metamask/eth-token-tracker>ethjs": { @@ -1204,6 +1222,15 @@ "promise-to-callback": true } }, + "@metamask/eth-token-tracker>safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "browserify>util": true, + "webpack>events": true + } + }, "@metamask/etherscan-link": { "globals": { "URL": true @@ -1393,13 +1420,10 @@ } }, "@metamask/obs-store": { - "globals": { - "localStorage": true - }, "packages": { "@metamask/obs-store>through2": true, - "browserify>stream-browserify": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "browserify>stream-browserify": true } }, "@metamask/obs-store>through2": { @@ -1610,6 +1634,14 @@ "crypto.getRandomValues": true } }, + "@metamask/safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "browserify>events": true + } + }, "@metamask/scure-bip39": { "globals": { "TextEncoder": true @@ -3121,10 +3153,10 @@ "setTimeout": true }, "packages": { + "@metamask/safe-event-emitter": true, "eth-block-tracker>@metamask/utils": true, "eth-block-tracker>pify": true, - "eth-query>json-rpc-random-id": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "eth-query>json-rpc-random-id": true } }, "eth-block-tracker>@metamask/utils": { @@ -3167,10 +3199,10 @@ "console.error": true }, "packages": { + "@metamask/safe-event-emitter": true, "eth-json-rpc-filters>async-mutex": true, "eth-query": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, "pify": true } }, @@ -4009,16 +4041,8 @@ }, "json-rpc-engine": { "packages": { - "eth-rpc-errors": true, - "json-rpc-engine>@metamask/safe-event-emitter": true - } - }, - "json-rpc-engine>@metamask/safe-event-emitter": { - "globals": { - "setTimeout": true - }, - "packages": { - "browserify>events": true + "@metamask/safe-event-emitter": true, + "eth-rpc-errors": true } }, "json-rpc-middleware-stream": { @@ -4027,7 +4051,7 @@ "setTimeout": true }, "packages": { - "json-rpc-engine>@metamask/safe-event-emitter": true, + "@metamask/safe-event-emitter": true, "readable-stream": true } }, @@ -4738,15 +4762,6 @@ "@babel/runtime": true } }, - "safe-event-emitter": { - "globals": { - "setTimeout": true - }, - "packages": { - "browserify>util": true, - "webpack>events": true - } - }, "semver": { "globals": { "console.error": true diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index c2acd56f3bc4..167424fd40a2 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -469,8 +469,8 @@ "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store": { "packages": { "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store>through2": true, - "browserify>stream-browserify": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "browserify>stream-browserify": true } }, "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store>through2": { @@ -857,9 +857,9 @@ "setTimeout": true }, "packages": { + "@metamask/desktop>@metamask/obs-store": true, "@metamask/desktop>eciesjs": true, "@metamask/desktop>otpauth": true, - "@metamask/obs-store": true, "browserify>buffer": true, "browserify>events": true, "browserify>process": true, @@ -872,6 +872,24 @@ "webextension-polyfill": true } }, + "@metamask/desktop>@metamask/obs-store": { + "globals": { + "localStorage": true + }, + "packages": { + "@metamask/desktop>@metamask/obs-store>through2": true, + "browserify>stream-browserify": true, + "json-rpc-engine>@metamask/safe-event-emitter": true + } + }, + "@metamask/desktop>@metamask/obs-store>through2": { + "packages": { + "browserify>process": true, + "browserify>util": true, + "readable-stream": true, + "watchify>xtend": true + } + }, "@metamask/desktop>eciesjs": { "packages": { "@metamask/desktop>eciesjs>futoin-hkdf": true, @@ -928,10 +946,10 @@ "@metamask/eth-json-rpc-infura>@metamask/utils": true, "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, + "@metamask/safe-event-emitter": true, "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, "lavamoat>json-stable-stringify": true, "vinyl>clone": true } @@ -966,8 +984,8 @@ }, "@metamask/eth-json-rpc-provider": { "packages": { - "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "json-rpc-engine": true } }, "@metamask/eth-keyring-controller": { @@ -1022,7 +1040,7 @@ }, "@metamask/eth-keyring-controller>obs-store": { "packages": { - "safe-event-emitter": true, + "@metamask/eth-token-tracker>safe-event-emitter": true, "watchify>xtend": true } }, @@ -1110,9 +1128,9 @@ "@metamask/eth-token-tracker>eth-block-tracker": true, "@metamask/eth-token-tracker>ethjs": true, "@metamask/eth-token-tracker>human-standard-token-abi": true, + "@metamask/eth-token-tracker>safe-event-emitter": true, "ethjs-contract": true, - "ethjs-query": true, - "safe-event-emitter": true + "ethjs-query": true } }, "@metamask/eth-token-tracker>deep-equal": { @@ -1144,8 +1162,8 @@ }, "packages": { "@metamask/eth-token-tracker>eth-block-tracker>pify": true, - "eth-query": true, - "safe-event-emitter": true + "@metamask/eth-token-tracker>safe-event-emitter": true, + "eth-query": true } }, "@metamask/eth-token-tracker>ethjs": { @@ -1204,6 +1222,15 @@ "promise-to-callback": true } }, + "@metamask/eth-token-tracker>safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "browserify>util": true, + "webpack>events": true + } + }, "@metamask/etherscan-link": { "globals": { "URL": true @@ -1393,13 +1420,10 @@ } }, "@metamask/obs-store": { - "globals": { - "localStorage": true - }, "packages": { "@metamask/obs-store>through2": true, - "browserify>stream-browserify": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "browserify>stream-browserify": true } }, "@metamask/obs-store>through2": { @@ -1610,6 +1634,14 @@ "crypto.getRandomValues": true } }, + "@metamask/safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "browserify>events": true + } + }, "@metamask/scure-bip39": { "globals": { "TextEncoder": true @@ -3121,10 +3153,10 @@ "setTimeout": true }, "packages": { + "@metamask/safe-event-emitter": true, "eth-block-tracker>@metamask/utils": true, "eth-block-tracker>pify": true, - "eth-query>json-rpc-random-id": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "eth-query>json-rpc-random-id": true } }, "eth-block-tracker>@metamask/utils": { @@ -3167,10 +3199,10 @@ "console.error": true }, "packages": { + "@metamask/safe-event-emitter": true, "eth-json-rpc-filters>async-mutex": true, "eth-query": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, "pify": true } }, @@ -4009,16 +4041,8 @@ }, "json-rpc-engine": { "packages": { - "eth-rpc-errors": true, - "json-rpc-engine>@metamask/safe-event-emitter": true - } - }, - "json-rpc-engine>@metamask/safe-event-emitter": { - "globals": { - "setTimeout": true - }, - "packages": { - "browserify>events": true + "@metamask/safe-event-emitter": true, + "eth-rpc-errors": true } }, "json-rpc-middleware-stream": { @@ -4027,7 +4051,7 @@ "setTimeout": true }, "packages": { - "json-rpc-engine>@metamask/safe-event-emitter": true, + "@metamask/safe-event-emitter": true, "readable-stream": true } }, @@ -4738,15 +4762,6 @@ "@babel/runtime": true } }, - "safe-event-emitter": { - "globals": { - "setTimeout": true - }, - "packages": { - "browserify>util": true, - "webpack>events": true - } - }, "semver": { "globals": { "console.error": true diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index cf463cda4f1c..98b889720187 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -469,8 +469,8 @@ "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store": { "packages": { "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store>through2": true, - "browserify>stream-browserify": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "browserify>stream-browserify": true } }, "@keystonehq/metamask-airgapped-keyring>@metamask/obs-store>through2": { @@ -874,10 +874,10 @@ "@metamask/eth-json-rpc-infura>@metamask/utils": true, "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, + "@metamask/safe-event-emitter": true, "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, "lavamoat>json-stable-stringify": true, "vinyl>clone": true } @@ -912,8 +912,8 @@ }, "@metamask/eth-json-rpc-provider": { "packages": { - "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "json-rpc-engine": true } }, "@metamask/eth-keyring-controller": { @@ -968,7 +968,7 @@ }, "@metamask/eth-keyring-controller>obs-store": { "packages": { - "safe-event-emitter": true, + "@metamask/eth-token-tracker>safe-event-emitter": true, "watchify>xtend": true } }, @@ -1056,9 +1056,9 @@ "@metamask/eth-token-tracker>eth-block-tracker": true, "@metamask/eth-token-tracker>ethjs": true, "@metamask/eth-token-tracker>human-standard-token-abi": true, + "@metamask/eth-token-tracker>safe-event-emitter": true, "ethjs-contract": true, - "ethjs-query": true, - "safe-event-emitter": true + "ethjs-query": true } }, "@metamask/eth-token-tracker>deep-equal": { @@ -1090,8 +1090,8 @@ }, "packages": { "@metamask/eth-token-tracker>eth-block-tracker>pify": true, - "eth-query": true, - "safe-event-emitter": true + "@metamask/eth-token-tracker>safe-event-emitter": true, + "eth-query": true } }, "@metamask/eth-token-tracker>ethjs": { @@ -1150,6 +1150,15 @@ "promise-to-callback": true } }, + "@metamask/eth-token-tracker>safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "browserify>util": true, + "webpack>events": true + } + }, "@metamask/etherscan-link": { "globals": { "URL": true @@ -1327,13 +1336,10 @@ } }, "@metamask/obs-store": { - "globals": { - "localStorage": true - }, "packages": { "@metamask/obs-store>through2": true, - "browserify>stream-browserify": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "@metamask/safe-event-emitter": true, + "browserify>stream-browserify": true } }, "@metamask/obs-store>through2": { @@ -1455,6 +1461,14 @@ "crypto.getRandomValues": true } }, + "@metamask/safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "browserify>events": true + } + }, "@metamask/scure-bip39": { "globals": { "TextEncoder": true @@ -2726,10 +2740,10 @@ "setTimeout": true }, "packages": { + "@metamask/safe-event-emitter": true, "eth-block-tracker>@metamask/utils": true, "eth-block-tracker>pify": true, - "eth-query>json-rpc-random-id": true, - "json-rpc-engine>@metamask/safe-event-emitter": true + "eth-query>json-rpc-random-id": true } }, "eth-block-tracker>@metamask/utils": { @@ -2772,10 +2786,10 @@ "console.error": true }, "packages": { + "@metamask/safe-event-emitter": true, "eth-json-rpc-filters>async-mutex": true, "eth-query": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, "pify": true } }, @@ -3614,16 +3628,8 @@ }, "json-rpc-engine": { "packages": { - "eth-rpc-errors": true, - "json-rpc-engine>@metamask/safe-event-emitter": true - } - }, - "json-rpc-engine>@metamask/safe-event-emitter": { - "globals": { - "setTimeout": true - }, - "packages": { - "browserify>events": true + "@metamask/safe-event-emitter": true, + "eth-rpc-errors": true } }, "json-rpc-middleware-stream": { @@ -3632,7 +3638,7 @@ "setTimeout": true }, "packages": { - "json-rpc-engine>@metamask/safe-event-emitter": true, + "@metamask/safe-event-emitter": true, "readable-stream": true } }, @@ -4211,15 +4217,6 @@ "@babel/runtime": true } }, - "safe-event-emitter": { - "globals": { - "setTimeout": true - }, - "packages": { - "browserify>util": true, - "webpack>events": true - } - }, "semver": { "globals": { "console.error": true diff --git a/package.json b/package.json index b6849a24dca5..d53e20a061ce 100644 --- a/package.json +++ b/package.json @@ -248,13 +248,14 @@ "@metamask/message-manager": "^2.0.0", "@metamask/metamask-eth-abis": "^3.0.0", "@metamask/notification-controller": "^1.0.0", - "@metamask/obs-store": "^5.0.0", + "@metamask/obs-store": "^8.0.0", "@metamask/permission-controller": "^3.1.0", "@metamask/phishing-controller": "^2.0.0", "@metamask/post-message-stream": "^6.0.0", "@metamask/providers": "^10.2.1", "@metamask/rate-limit-controller": "^1.0.0", "@metamask/rpc-methods": "^0.32.2", + "@metamask/safe-event-emitter": "^2.0.0", "@metamask/scure-bip39": "^2.0.3", "@metamask/slip44": "^2.1.0", "@metamask/smart-transactions-controller": "^3.1.0", @@ -348,7 +349,6 @@ "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", "single-call-balance-checker-abi": "^1.0.0", "swappable-obj-proxy": "^1.1.0", diff --git a/shared/constants/metametrics.js b/shared/constants/metametrics.js deleted file mode 100644 index 1eeb0a314b3b..000000000000 --- a/shared/constants/metametrics.js +++ /dev/null @@ -1,482 +0,0 @@ -// Type Imports -/** - * @typedef {import('../../shared/constants/app').EnvironmentType} EnvironmentType - */ - -// Type Declarations -/** - * Used to attach context of where the user was at in the application when the - * event was triggered. Also included as full details of the current page in - * page events. - * - * @typedef {object} MetaMetricsPageObject - * @property {string} [path] - the path of the current page (e.g /home) - * @property {string} [title] - the title of the current page (e.g 'home') - * @property {string} [url] - the fully qualified url of the current page - */ - -/** - * For metamask, this is the dapp that triggered an interaction - * - * @typedef {object} MetaMetricsReferrerObject - * @property {string} [url] - the origin of the dapp issuing the - * notification - */ - -/** - * We attach context to every meta metrics event that help to qualify our - * analytics. This type has all optional values because it represents a - * returned object from a method call. Ideally app and userAgent are - * defined on every event. This is confirmed in the getTrackMetaMetricsEvent - * function, but still provides the consumer a way to override these values if - * necessary. - * - * @typedef {object} MetaMetricsContext - * @property {object} app - Application metadata. - * @property {string} app.name - the name of the application tracking the event - * @property {string} app.version - the version of the application - * @property {string} userAgent - the useragent string of the user - * @property {MetaMetricsPageObject} [page] - an object representing details of - * the current page - * @property {MetaMetricsReferrerObject} [referrer] - for metamask, this is the - * dapp that triggered an interaction - */ - -/** - * @typedef {object} MetaMetricsEventPayload - * @property {string} event - event name to track - * @property {string} category - category to associate event to - * @property {number} [actionId] - Action id to deduplicate event requests from - * the UI - * @property {string} [environmentType] - The type of environment this event - * occurred in. Defaults to the background process type - * @property {object} [properties] - object of custom values to track, keys - * in this object must be in snake_case - * @property {object} [sensitiveProperties] - Object of sensitive values to - * track. Keys in this object must be in snake_case. These properties will be - * sent in an additional event that excludes the user's metaMetricsId - * @property {number} [revenue] - amount of currency that event creates in - * revenue for MetaMask - * @property {string} [currency] - ISO 4127 format currency for events with - * revenue, defaults to US dollars - * @property {number} [value] - Abstract business "value" attributable to - * customers who trigger this event - * @property {MetaMetricsPageObject} [page] - the page/route that the event - * occurred on - * @property {MetaMetricsReferrerObject} [referrer] - the origin of the dapp - * that triggered the event - */ - -/** - * @typedef {object} MetaMetricsEventOptions - * @property {boolean} [isOptIn] - happened during opt in/out workflow - * @property {boolean} [flushImmediately] - When true will automatically flush - * the segment queue after tracking the event. Recommended if the result of - * tracking the event must be known before UI transition or update - * @property {boolean} [excludeMetaMetricsId] - whether to exclude the user's - * metametrics id for anonymity - * @property {string} [metaMetricsId] - an override for the metaMetricsId in - * the event one is created as part of an asynchronous workflow, such as - * awaiting the result of the metametrics opt-in function that generates the - * user's metametrics id - * @property {boolean} [matomoEvent] - is this event a holdover from matomo - * that needs further migration? when true, sends the data to a special - * segment source that marks the event data as not conforming to our schema - */ - -/** - * @typedef {object} MetaMetricsEventFragment - * @property {string} successEvent - The event name to fire when the fragment - * is closed in an affirmative action. - * @property {string} [failureEvent] - The event name to fire when the fragment - * is closed with a rejection. - * @property {string} [initialEvent] - An event name to fire immediately upon - * fragment creation. This is useful for building funnels in mixpanel and for - * reduction of code duplication. - * @property {string} category - the event category to use for both the success - * and failure events - * @property {boolean} [persist] - Should this fragment be persisted in - * state and progressed after the extension is locked and unlocked. - * @property {number} [timeout] - Time in seconds the event should be persisted - * for. After the timeout the fragment will be closed as abandoned. if not - * supplied the fragment is stored indefinitely. - * @property {number} [lastUpdated] - Date.now() when the fragment was last - * updated. Used to determine if the timeout has expired and the fragment - * should be closed. - * @property {object} [properties] - Object of custom values to track, keys in - * this object must be in snake_case. - * @property {object} [sensitiveProperties] - Object of sensitive values to - * track. Keys in this object must be in snake_case. These properties will be - * sent in an additional event that excludes the user's metaMetricsId - * @property {number} [revenue] - amount of currency that event creates in - * revenue for MetaMask if fragment is successful. - * @property {string} [currency] - ISO 4127 format currency for events with - * revenue, defaults to US dollars - * @property {number} [value] - Abstract business "value" attributable to - * customers who successfully complete this fragment - * @property {MetaMetricsPageObject} [page] - the page/route that the event - * occurred on - * @property {MetaMetricsReferrerObject} [referrer] - the origin of the dapp - * that initiated the event fragment. - * @property {string} [uniqueIdentifier] - optional argument to override the - * automatic generation of UUID for the event fragment. This is useful when - * tracking events for subsystems that already generate UUIDs so to avoid - * unnecessary lookups and reduce accidental duplication. - */ - -/** - * Represents the shape of data sent to the segment.track method. - * - * @typedef {object} SegmentEventPayload - * @property {string} [userId] - The metametrics id for the user - * @property {string} [anonymousId] - An anonymousId that is used to track - * sensitive data while preserving anonymity. - * @property {string} event - name of the event to track - * @property {object} properties - properties to attach to the event - * @property {MetaMetricsContext} context - the context the event occurred in - */ - -/** - * @typedef {object} MetaMetricsPagePayload - * @property {string} name - The name of the page that was viewed - * @property {object} [params] - The variadic parts of the page url - * example (route: `/asset/:asset`, path: `/asset/ETH`) - * params: { asset: 'ETH' } - * @property {EnvironmentType} environmentType - the environment type that the - * page was viewed in - * @property {MetaMetricsPageObject} [page] - the details of the page - * @property {MetaMetricsReferrerObject} [referrer] - dapp that triggered the page - * view - */ - -/** - * @typedef {object} MetaMetricsPageOptions - * @property {boolean} [isOptInPath] - is the current path one of the pages in - * the onboarding workflow? If true and participateInMetaMetrics is null track - * the page view - */ - -/** - * @typedef {object} Traits - * @property {'address_book_entries'} ADDRESS_BOOK_ENTRIES - When the user - * adds or modifies addresses in address book the address_book_entries trait - * is identified. - * @property {'ledger_connection_type'} LEDGER_CONNECTION_TYPE - when ledger - * live connnection type is changed we identify the ledger_connection_type - * trait - * @property {'networks_added'} NETWORKS_ADDED - when user modifies networks - * we identify the networks_added trait - * @property {'networks_without_ticker'} NETWORKS_WITHOUT_TICKER - when user - * modifies networks we identify the networks_without_ticker trait for - * networks without a ticker. - * @property {'nft_autodetection_enabled'} NFT_AUTODETECTION_ENABLED - when Autodetect NFTs - * feature is toggled we identify the nft_autodetection_enabled trait - * @property {'number_of_accounts'} NUMBER_OF_ACCOUNTS - when identities - * change, we identify the new number_of_accounts trait - * @property {'number_of_nft_collections'} NUMBER_OF_NFT_COLLECTIONS - user - * trait for number of unique NFT addresses - * @property {'number_of_nfts'} NUMBER_OF_NFTS - user trait for number of all NFT addresses - * @property {'number_of_tokens'} NUMBER_OF_TOKENS - when the number of tokens change, we - * 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. 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 - * @property {'install_date_ext'} INSTALL_DATE_EXT - when the user installed the extension - * @property {'desktop_enabled'} [DESKTOP_ENABLED] - optional / does the user have desktop enabled? - * @property {'security_providers'} SECURITY_PROVIDERS - when security provider feature is toggled we - * identify the security_providers trait - */ - -/** - * - * @type {Traits} - */ - -export const TRAITS = { - ADDRESS_BOOK_ENTRIES: 'address_book_entries', - INSTALL_DATE_EXT: 'install_date_ext', - LEDGER_CONNECTION_TYPE: 'ledger_connection_type', - NETWORKS_ADDED: 'networks_added', - NETWORKS_WITHOUT_TICKER: 'networks_without_ticker', - NFT_AUTODETECTION_ENABLED: 'nft_autodetection_enabled', - NUMBER_OF_ACCOUNTS: 'number_of_accounts', - NUMBER_OF_NFT_COLLECTIONS: 'number_of_nft_collections', - NUMBER_OF_NFTS: 'number_of_nfts', - NUMBER_OF_TOKENS: 'number_of_tokens', - OPENSEA_API_ENABLED: 'opensea_api_enabled', - THEME: 'theme', - THREE_BOX_ENABLED: 'three_box_enabled', - TOKEN_DETECTION_ENABLED: 'token_detection_enabled', - DESKTOP_ENABLED: 'desktop_enabled', - SECURITY_PROVIDERS: 'security_providers', -}; - -/** - * @typedef {object} MetaMetricsTraits - * @property {number} [address_book_entries] - The number of entries in the - * user's address book. - * @property {'ledgerLive' | 'webhid' | 'u2f'} [ledger_connection_type] - the - * type of ledger connection set by user preference. - * @property {Array} [networks_added] - An array consisting of chainIds - * that indicate the networks a user has added to their MetaMask. - * @property {Array} [networks_without_ticker] - An array consisting of - * chainIds that indicate the networks added by the user that do not have a - * ticker. - * @property {number} [nft_autodetection_enabled] - does the user have the - * use collection/nft detection enabled? - * @property {number} [number_of_accounts] - A number representing the number - * of identities(accounts) added to the user's MetaMask. - * @property {number} [number_of_nft_collections] - A number representing the - * amount of different NFT collections the user possesses an NFT from. - * @property {number} [number_of_nfts] - A number representing the - * amount of all NFTs the user possesses across all networks and accounts. - * @property {number} [number_of_tokens] - The total number of token contracts - * 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? (deprecated) - * @property {string} [theme] - which theme the user has selected - * @property {boolean} [token_detection_enabled] - does the user have token detection is enabled? - * @property {boolean} [desktop_enabled] - optional / does the user have desktop enabled? - * @property {Array} [security_providers] - whether security provider feature toggle is on or off - */ - -// Mixpanel converts the zero address value to a truly anonymous event, which -// speeds up reporting -export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000'; - -/** - * This object is used to identify events that are triggered by the background - * process. - * - * @type {MetaMetricsPageObject} - */ -export const METAMETRICS_BACKGROUND_PAGE_OBJECT = { - path: '/background-process', - title: 'Background Process', - url: '/background-process', -}; - -/** - * @typedef {object} SegmentInterface - * @property {SegmentEventPayload[]} queue - A queue of events to be sent when - * the flushAt limit has been reached, or flushInterval occurs - * @property {() => void} flush - Immediately flush the queue, resetting it to - * an empty array and sending the pending events to Segment - * @property {( - * payload: SegmentEventPayload, - * callback: (err?: Error) => void - * ) => void} track - Track an event with Segment, using the internal batching - * mechanism to optimize network requests - * @property {(payload: object) => void} page - Track a page view with Segment - * @property {() => void} identify - Identify an anonymous user. We do not - * currently use this method. - */ - -export const REJECT_NOTFICIATION_CLOSE = 'Cancel Via Notification Close'; -export const REJECT_NOTFICIATION_CLOSE_SIG = - 'Cancel Sig Request Via Notification Close'; - -/** - * EVENTS - */ - -export const EVENT_NAMES = { - ACCOUNT_ADDED: 'Account Added', - ACCOUNT_ADD_SELECTED: 'Account Add Selected', - ACCOUNT_ADD_FAILED: 'Account Add Failed', - ACCOUNT_PASSWORD_CREATED: 'Account Password Created', - ACCOUNT_RESET: 'Account Reset', - APP_INSTALLED: 'App Installed', - APP_UNLOCKED: 'App Unlocked', - APP_UNLOCKED_FAILED: 'App Unlocked Failed', - APP_WINDOW_EXPANDED: 'App Window Expanded', - BRIDGE_LINK_CLICKED: 'Bridge Link Clicked', - DECRYPTION_APPROVED: 'Decryption Approved', - DECRYPTION_REJECTED: 'Decryption Rejected', - DECRYPTION_REQUESTED: 'Decryption Requested', - ENCRYPTION_PUBLIC_KEY_APPROVED: 'Encryption Approved', - ENCRYPTION_PUBLIC_KEY_REJECTED: 'Encryption Rejected', - ENCRYPTION_PUBLIC_KEY_REQUESTED: 'Encryption Requested', - EXTERNAL_LINK_CLICKED: 'External Link Clicked', - KEY_EXPORT_SELECTED: 'Key Export Selected', - KEY_EXPORT_REQUESTED: 'Key Export Requested', - KEY_EXPORT_FAILED: 'Key Export Failed', - KEY_EXPORT_CANCELED: 'Key Export Canceled', - KEY_EXPORT_REVEALED: 'Key Material Revealed', - KEY_EXPORT_COPIED: 'Key Material Copied', - KEY_TOKEN_DETECTION_SELECTED: 'Key Token Detection Selected', - KEY_GLOBAL_SECURITY_TOGGLE_SELECTED: 'Key Global Security/Privacy Settings', - KEY_BALANCE_TOKEN_PRICE_CHECKER: - 'Key Show Balance and Token Price Checker Settings', - KEY_GAS_FEE_ESTIMATION_BUY_SWAP_TOKENS: - 'Key Show Gas Fee Estimation, Buy Crypto and Swap Tokens', - KEY_AUTO_DETECT_TOKENS: 'Key Autodetect tokens', - KEY_BATCH_ACCOUNT_BALANCE_REQUESTS: 'Key Batch account balance requests', - METRICS_OPT_IN: 'Metrics Opt In', - METRICS_OPT_OUT: 'Metrics Opt Out', - NAV_ACCOUNT_MENU_OPENED: 'Account Menu Opened', - NAV_ACCOUNT_DETAILS_OPENED: 'Account Details Opened', - NAV_CONNECTED_SITES_OPENED: 'Connected Sites Opened', - NAV_MAIN_MENU_OPENED: 'Main Menu Opened', - NAV_NETWORK_MENU_OPENED: 'Network Menu Opened', - NAV_SETTINGS_OPENED: 'Settings Opened', - NAV_ACCOUNT_SWITCHED: 'Account Switched', - NAV_NETWORK_SWITCHED: 'Network Switched', - NAV_BUY_BUTTON_CLICKED: 'Buy Button Clicked', - NAV_SEND_BUTTON_CLICKED: 'Send Button Clicked', - NAV_SWAP_BUTTON_CLICKED: 'Swap Button Clicked', - SRP_TO_CONFIRM_BACKUP: 'SRP Backup Confirm Displayed', - WALLET_SETUP_STARTED: 'Wallet Setup Selected', - WALLET_SETUP_CANCELED: 'Wallet Setup Canceled', - WALLET_SETUP_FAILED: 'Wallet Setup Failed', - WALLET_CREATED: 'Wallet Created', - NFT_ADDED: 'NFT Added', - ONRAMP_PROVIDER_SELECTED: 'On-ramp Provider Selected', - PERMISSIONS_APPROVED: 'Permissions Approved', - PERMISSIONS_REJECTED: 'Permissions Rejected', - PERMISSIONS_REQUESTED: 'Permissions Requested', - PHISHING_PAGE_DISPLAYED: 'Phishing Page Displayed', - PORTFOLIO_LINK_CLICKED: 'Portfolio Link Clicked', - PUBLIC_ADDRESS_COPIED: 'Public Address Copied', - PROVIDER_METHOD_CALLED: 'Provider Method Called', - SIGNATURE_APPROVED: 'Signature Approved', - SIGNATURE_FAILED: 'Signature Failed', - SIGNATURE_REJECTED: 'Signature Rejected', - SIGNATURE_REQUESTED: 'Signature Requested', - TOKEN_IMPORT_BUTTON_CLICKED: 'Import Token Button Clicked', - TOKEN_SCREEN_OPENED: 'Token Screen Opened', - SUPPORT_LINK_CLICKED: 'Support Link Clicked', - TOKEN_ADDED: 'Token Added', - TOKEN_DETECTED: 'Token Detected', - TOKEN_HIDDEN: 'Token Hidden', - TOKEN_IMPORT_CANCELED: 'Token Import Canceled', - TOKEN_IMPORT_CLICKED: 'Token Import Clicked', - ONBOARDING_WELCOME: 'App Installed', - ONBOARDING_WALLET_CREATION_STARTED: 'Wallet Setup Selected', - ONBOARDING_WALLET_IMPORT_STARTED: 'Wallet Import Started', - ONBOARDING_WALLET_CREATION_ATTEMPTED: 'Wallet Password Created', - ONBOARDING_WALLET_SECURITY_STARTED: 'SRP Backup Selected', - ONBOARDING_WALLET_SECURITY_SKIP_INITIATED: 'SRP Skip Backup Selected', - ONBOARDING_WALLET_SECURITY_SKIP_CONFIRMED: 'SRP Backup Skipped', - ONBOARDING_WALLET_SECURITY_SKIP_CANCELED: 'SRP Skip Backup Canceled', - ONBOARDING_WALLET_SECURITY_PHRASE_REVEALED: 'SRP Revealed', - ONBOARDING_WALLET_SECURITY_PHRASE_WRITTEN_DOWN: 'SRP Backup Confirm Display', - ONBOARDING_WALLET_SECURITY_PHRASE_CONFIRMED: 'SRP Backup Confirmed', - ONBOARDING_WALLET_CREATION_COMPLETE: 'Wallet Created', - ONBOARDING_WALLET_SETUP_COMPLETE: 'Application Opened', - ONBOARDING_WALLET_ADVANCED_SETTINGS: 'Settings Updated', - ONBOARDING_WALLET_IMPORT_ATTEMPTED: 'Wallet Import Attempted', - ONBOARDING_WALLET_VIDEO_PLAY: 'SRP Intro Video Played', - ONBOARDING_TWITTER_CLICK: 'External Link Clicked', - SERVICE_WORKER_RESTARTED: 'Service Worker Restarted', -}; - -export const EVENT = { - ACCOUNT_TYPES: { - DEFAULT: 'metamask', - IMPORTED: 'imported', - HARDWARE: 'hardware', - }, - ACCOUNT_IMPORT_TYPES: { - JSON: 'json', - PRIVATE_KEY: 'private_key', - SRP: 'srp', - }, - CATEGORIES: { - ACCOUNTS: 'Accounts', - APP: 'App', - AUTH: 'Auth', - BACKGROUND: 'Background', - ERROR: 'Error', - FOOTER: 'Footer', - HOME: 'Home', - INPAGE_PROVIDER: 'inpage_provider', - KEYS: 'Keys', - MESSAGES: 'Messages', - NAVIGATION: 'Navigation', - NETWORK: 'Network', - ONBOARDING: 'Onboarding', - PHISHING: 'Phishing', - RETENTION: 'Retention', - SETTINGS: 'Settings', - SNAPS: 'Snaps', - SWAPS: 'Swaps', - TRANSACTIONS: 'Transactions', - WALLET: 'Wallet', - DESKTOP: 'Desktop', - }, - EXTERNAL_LINK_TYPES: { - TRANSACTION_BLOCK_EXPLORER: 'Transaction Block Explorer', - BLOCK_EXPLORER: 'Block Explorer', - ACCOUNT_TRACKER: 'Account Tracker', - TOKEN_TRACKER: 'Token Tracker', - }, - KEY_TYPES: { - PKEY: 'private_key', - SRP: 'srp', - }, - ONRAMP_PROVIDER_TYPES: { - COINBASE: 'coinbase', - MOONPAY: 'moonpay', - WYRE: 'wyre', - TRANSAK: 'transak', - SELF_DEPOSIT: 'direct_deposit', - }, - SOURCE: { - NETWORK: { - CUSTOM_NETWORK_FORM: 'custom_network_form', - POPULAR_NETWORK_LIST: 'popular_network_list', - DAPP: 'dapp', - }, - SWAPS: { - MAIN_VIEW: 'Main View', - TOKEN_VIEW: 'Token View', - }, - TOKEN: { - CUSTOM: 'custom', - DAPP: 'dapp', - DETECTED: 'detected', - LIST: 'list', - }, - TRANSACTION: { - DAPP: 'dapp', - USER: 'user', - }, - SERVICE_WORKERS: 'service_workers', - }, - LOCATION: { - TOKEN_DETAILS: 'token_details', - TOKEN_DETECTION: 'token_detection', - TOKEN_MENU: 'token_menu', - }, -}; - -// Values below (e.g. 'location') can be used in the "properties" -// tracking object as keys, e.g. { location: 'Home' } -export const CONTEXT_PROPS = { - PAGE_TITLE: 'location', -}; - -/** - * These types correspond to the keys in the METAMETRIC_KEY_OPT object - */ -export const METAMETRIC_KEY = { - UI_CUSTOMIZATIONS: `ui_customizations`, -}; - -/** - * This object maps a METAMETRIC_KEY to an object of possible options - */ -export const METAMETRIC_KEY_OPT = { - [METAMETRIC_KEY.UI_CUSTOMIZATIONS]: { - flaggedAsMalicious: 'flagged_as_malicious', - flaggedAsSafetyUnknown: 'flagged_as_safety_unknown', - SIWE: 'sign_in_with_ethereum', - }, -}; diff --git a/shared/constants/metametrics.ts b/shared/constants/metametrics.ts new file mode 100644 index 000000000000..03626ff61389 --- /dev/null +++ b/shared/constants/metametrics.ts @@ -0,0 +1,642 @@ +import type { EnvironmentType } from './app'; +import { LedgerTransportTypes } from './hardware-wallets'; + +/** + * Used to attach context of where the user was at in the application when the + * event was triggered. Also included as full details of the current page in + * page events. + */ +export type MetaMetricsPageObject = { + /** + * The path of the current page (e.g. "/home"). + */ + path?: string; + /** + * The title of the current page (e.g. "home"). + */ + title?: string; + /** + * The fully qualified URL of the current page. + */ + url?: string; +}; + +/** + * The dapp that triggered an interaction (MetaMask only). + */ +export type MetaMetricsReferrerObject = { + /** + * The origin of the dapp issuing the notification. + */ + url?: string; +}; + +/** + * We attach context to every meta metrics event that help to qualify our + * analytics. This type has all optional values because it represents a + * returned object from a method call. Ideally app and userAgent are + * defined on every event. This is confirmed in the getTrackMetaMetricsEvent + * function, but still provides the consumer a way to override these values if + * necessary. + */ +type MetaMetricsContext = { + /** + * Application metadata. + */ + app: { + /** + * The name of the application tracking the event. + */ + name: string; + /** + * The version of the application. + */ + version: string; + }; + /** + * The user agent of the application. + */ + userAgent: string; + /** + * An object representing details of the current page. + */ + page?: MetaMetricsPageObject; + /** + * The dapp that triggered an interaction (MetaMask only). + */ + referrer?: MetaMetricsReferrerObject; +}; + +export type MetaMetricsEventPayload = { + /** + * The event name to track. + */ + event: string; + /** + * The category to associate the event to. + */ + category: string; + /** + * The action ID to deduplicate event requests from the UI. + */ + actionId?: number; + /** + * The type of environment this event occurred in. Defaults to the background + * process type. + */ + environmentType?: string; + /** + * Custom values to track. Keys in this object must be `snake_case`. + */ + properties?: object; + /** + * Sensitive values to track. These properties will be sent in an additional + * event that excludes the user's `metaMetricsId`. Keys in this object must be + * in `snake_case`. + */ + sensitiveProperties?: object; + /** + * Amount of currency that the event creates in revenue for MetaMask. + */ + revenue?: number; + /** + * ISO-4127-formatted currency for events with revenue. Defaults to US + * dollars. + */ + currency?: string; + /** + * Abstract business "value" attributable to customers who trigger this event. + */ + value?: number; + /** + * The page/route that the event occurred on. + */ + page?: MetaMetricsPageObject; + /** + * The origin of the dapp that triggered this event. + */ + referrer?: MetaMetricsReferrerObject; +}; + +export type MetaMetricsEventOptions = { + /** + * Whether or not the event happened during the opt-in workflow. + */ + isOptIn?: boolean; + /** + * Whether the segment queue should be flushed after tracking the event. + * Recommended if the result of tracking the event must be known before UI + * transition or update. + */ + flushImmediately?: boolean; + /** + * Whether to exclude the user's `metaMetricsId` for anonymity. + */ + excludeMetaMetricsId?: boolean; + /** + * An override for the `metaMetricsId` in the event (no pun intended) one is + * created as a part of an asynchronous workflow, such as awaiting the result + * of the MetaMetrics opt-in function that generates the user's + * `metaMetricsId`. + */ + metaMetricsId?: string; + /** + * Is this event a holdover from Matomo that needs further migration? When + * true, sends the data to a special Segment source that marks the event data + * as not conforming to our schema. + */ + matomoEvent?: boolean; +}; + +export type MetaMetricsEventFragment = { + /** + * The event name to fire when the fragment is closed in an affirmative action. + */ + successEvent: string; + /** + * The event name to fire when the fragment is closed with a rejection. + */ + failureEvent?: string; + /** + * An event name to fire immediately upon fragment creation. This is useful + * for building funnels in mixpanel and for reduction of code duplication. + */ + initialEvent?: string; + /** + * The event category to use for both the success and failure events. + */ + category: string; + /** + * Should this fragment be persisted in state and progressed after the + * extension is locked and unlocked. + */ + persist?: boolean; + /** + * Time in seconds the event should be persisted for. After the timeout the + * fragment will be closed as abandoned. If not supplied the fragment is + * stored indefinitely. + */ + timeout?: number; + /** + * `Date.now()` when the fragment was last updated. Used to determine if the + * timeout has expired and the fragment should be closed. + */ + lastUpdated?: number; + /** + * Custom values to track. Keys in this object must be `snake_case`. + */ + properties?: object; + /** + * Sensitive values to track. These properties will be sent in an additional + * event that excludes the user's `metaMetricsId`. Keys in this object must be + * in `snake_case`. + */ + sensitiveProperties?: object; + /** + * Amount of currency that the event creates in revenue for MetaMask. + */ + revenue?: number; + /** + * ISO-4127-formatted currency for events with revenue. Defaults to US + * dollars. + */ + currency?: string; + /** + * Abstract business "value" attributable to customers who trigger this event. + */ + value?: number; + /** + * The page/route that the event occurred on. + */ + page?: MetaMetricsPageObject; + /** + * The origin of the dapp that triggered this event. + */ + referrer?: MetaMetricsReferrerObject; + /** + * Overrides the automatic generation of UUID for the event fragment. This is + * useful when tracking events for subsystems that already generate UUIDs so + * to avoid unnecessary lookups and reduce accidental duplication. + */ + uniqueIdentifier?: string; +}; + +/** + * Data sent to the `segment.track` method. + */ +export type SegmentEventPayload = { + /** + * The MetaMetrics id for the user. + */ + userId?: string; + /** + * An anonymous ID that is used to track sensitive data while preserving + * anonymity. + */ + anonymousId?: string; + /** + * The name of the event to track. + */ + event: string; + /** + * Properties to attach to the event. + */ + properties: object; + /** + * The context the event occurred in. + */ + context: MetaMetricsContext; +}; + +/** + * Data sent to MetaMetrics for page views. + */ +export type MetaMetricsPagePayload = { + /** + * The name of the page that was viewed. + */ + name: string; + /** + * The variadic parts of the page URL. + * + * Example: If the route is `/asset/:asset` and the path is `/asset/ETH`, + * the `params` property would be `{ asset: 'ETH' }`. + */ + params?: object; + /** + * The environment type that the page was viewed in. + */ + environmentType: EnvironmentType; + /** + * The details of the page. + */ + page?: MetaMetricsPageObject; + /** + * The dapp that triggered the page view. + */ + referrer?: MetaMetricsReferrerObject; +}; + +export type MetaMetricsPageOptions = { + /** + * Is the current path one of the pages in the onboarding workflow? (If this + * is true and participateInMetaMetrics is null, then the page view will be + * tracked.) + */ + isOptInPath?: boolean; +}; + +/** + * Data sent to MetaMetrics for user traits. + */ +export type MetaMetricsUserTraits = { + /** + * The number of entries in the user's address book. + */ + address_book_entries?: number; + /** + * The type of ledger connection set by user preference. + */ + ledger_connection_type?: LedgerTransportTypes; + /** + * An array consisting of chain IDs that represent the networks added by the + * user. + */ + networks_added?: string[]; + /** + * An array consisting of chain IDs that represent the networks added by the + * user that do not have a ticker. + */ + networks_without_ticker?: string[]; + /** + * Does the user have the Autodetect NFTs feature enabled? + */ + nft_autodetection_enabled?: number; + /** + * A number representing the number of identities (accounts) added to the + * user's wallet. + */ + number_of_accounts?: number; + /** + * A number representing the amount of NFT collections from which the user + * possesses NFTs. + */ + number_of_nft_collections?: number; + /** + * A number representing the amount of all NFTs the user possesses across all + * networks and accounts. + */ + number_of_nfts?: number; + /** + * The total number of token contracts the user has across all networks and + * accounts. + */ + number_of_tokens?: number; + /** + * Does the user have the OpenSea API enabled? + */ + opensea_api_enabled?: boolean; + /** + * Does the user have 3Box sync enabled? + * + * @deprecated + */ + three_box_enabled?: boolean; + /** + * Which theme the user has selected. + */ + theme?: string; + /** + * Does the user have token detection enabled? + */ + token_detection_enabled?: boolean; + /** + * Does the user have desktop enabled? + */ + desktop_enabled?: boolean; + /** + * Whether the security provider feature has been enabled. + */ + security_providers?: string[]; +}; + +export enum MetaMetricsUserTrait { + /** + * Identified when the user adds or modifies addresses in the address book. + */ + AddressBookEntries = 'address_book_entries', + /** + * Identified when the user installed the extension. + */ + InstallDateExt = 'install_date_ext', + /** + * Identified when the Ledger Live connection type is changed. + */ + LedgerConnectionType = 'ledger_connection_type', + /** + * Identified when the user modifies networks. + */ + NetworksAdded = 'networks_added', + /** + * Identified when the user modifies networks that lack a ticker. + */ + NetworksWithoutTicker = 'networks_without_ticker', + /** + * Identified when the "Autodetect NFTs" feature is toggled. + */ + NftAutodetectionEnabled = 'nft_autodetection_enabled', + /** + * Identified when identities change. + */ + NumberOfAccounts = 'number_of_accounts', + /** + * The number of unique NFT addresses. + */ + NumberOfNftCollections = 'number_of_nft_collections', + /** + * Identified when the number of NFTs owned by the user changes. + */ + NumberOfNfts = 'number_of_nfts', + /** + * Identified when the number of tokens change. + */ + NumberOfTokens = 'number_of_tokens', + /** + * Identified when the OpenSea API is enabled. + */ + OpenSeaApiEnabled = 'opensea_api_enabled', + /** + * Identified when the user's theme changes. + */ + Theme = 'theme', + /** + * Identified when the 3Box feature is toggled. + * + * @deprecated + */ + ThreeBoxEnabled = 'three_box_enabled', + /** + * Identified when the token detection feature is toggled. + */ + TokenDetectionEnabled = 'token_detection_enabled', + /** + * Identified when the user enables desktop. + */ + DesktopEnabled = 'desktop_enabled', + /** + * Identified when the security provider feature is enabled. + */ + SecurityProviders = 'security_providers', +} + +/** + * Mixpanel converts the zero address value to a truly anonymous event, which + * speeds up reporting + */ +export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000'; + +/** + * Used to identify events that are triggered by the background process. + */ +export const METAMETRICS_BACKGROUND_PAGE_OBJECT: MetaMetricsPageObject = { + path: '/background-process', + title: 'Background Process', + url: '/background-process', +}; + +export const REJECT_NOTIFICATION_CLOSE = 'Cancel Via Notification Close'; + +export const REJECT_NOTIFICATION_CLOSE_SIG = + 'Cancel Sig Request Via Notification Close'; + +export enum MetaMetricsEventName { + AccountAdded = 'Account Added', + AccountAddSelected = 'Account Add Selected', + AccountAddFailed = 'Account Add Failed', + AccountPasswordCreated = 'Account Password Created', + AccountReset = 'Account Reset', + AppInstalled = 'App Installed', + AppUnlocked = 'App Unlocked', + AppUnlockedFailed = 'App Unlocked Failed', + AppWindowExpanded = 'App Window Expanded', + BridgeLinkClicked = 'Bridge Link Clicked', + DecryptionApproved = 'Decryption Approved', + DecryptionRejected = 'Decryption Rejected', + DecryptionRequested = 'Decryption Requested', + EncryptionPublicKeyApproved = 'Encryption Approved', + EncryptionPublicKeyRejected = 'Encryption Rejected', + EncryptionPublicKeyRequested = 'Encryption Requested', + ExternalLinkClicked = 'External Link Clicked', + KeyExportSelected = 'Key Export Selected', + KeyExportRequested = 'Key Export Requested', + KeyExportFailed = 'Key Export Failed', + KeyExportCanceled = 'Key Export Canceled', + KeyExportRevealed = 'Key Material Revealed', + KeyExportCopied = 'Key Material Copied', + KeyTokenDetectionSelected = 'Key Token Detection Selected', + KeyGlobalSecurityToggleSelected = 'Key Global Security/Privacy Settings', + KeyBalanceTokenPriceChecker = 'Key Show Balance and Token Price Checker Settings', + KeyGasFeeEstimationBuySwapTokens = 'Key Show Gas Fee Estimation, Buy Crypto and Swap Tokens', + KeyAutoDetectTokens = 'Key Autodetect tokens', + KeyBatchAccountBalanceRequests = 'Key Batch account balance requests', + MetricsOptIn = 'Metrics Opt In', + MetricsOptOut = 'Metrics Opt Out', + NavAccountMenuOpened = 'Account Menu Opened', + NavAccountDetailsOpened = 'Account Details Opened', + NavConnectedSitesOpened = 'Connected Sites Opened', + NavMainMenuOpened = 'Main Menu Opened', + NavNetworkMenuOpened = 'Network Menu Opened', + NavSettingsOpened = 'Settings Opened', + NavAccountSwitched = 'Account Switched', + NavNetworkSwitched = 'Network Switched', + NavBuyButtonClicked = 'Buy Button Clicked', + NavSendButtonClicked = 'Send Button Clicked', + NavSwapButtonClicked = 'Swap Button Clicked', + SrpToConfirmBackup = 'SRP Backup Confirm Displayed', + WalletSetupStarted = 'Wallet Setup Selected', + WalletSetupCanceled = 'Wallet Setup Canceled', + WalletSetupFailed = 'Wallet Setup Failed', + WalletCreated = 'Wallet Created', + NftAdded = 'NFT Added', + OnrampProviderSelected = 'On-ramp Provider Selected', + PermissionsApproved = 'Permissions Approved', + PermissionsRejected = 'Permissions Rejected', + PermissionsRequested = 'Permissions Requested', + PhishingPageDisplayed = 'Phishing Page Displayed', + PortfolioLinkClicked = 'Portfolio Link Clicked', + PublicAddressCopied = 'Public Address Copied', + ProviderMethodCalled = 'Provider Method Called', + SignatureApproved = 'Signature Approved', + SignatureFailed = 'Signature Failed', + SignatureRejected = 'Signature Rejected', + SignatureRequested = 'Signature Requested', + TokenImportButtonClicked = 'Import Token Button Clicked', + TokenScreenOpened = 'Token Screen Opened', + SupportLinkClicked = 'Support Link Clicked', + TokenAdded = 'Token Added', + TokenDetected = 'Token Detected', + TokenHidden = 'Token Hidden', + TokenImportCanceled = 'Token Import Canceled', + TokenImportClicked = 'Token Import Clicked', + OnboardingWelcome = 'App Installed', + OnboardingWalletCreationStarted = 'Wallet Setup Selected', + OnboardingWalletImportStarted = 'Wallet Import Started', + OnboardingWalletCreationAttempted = 'Wallet Password Created', + OnboardingWalletSecurityStarted = 'SRP Backup Selected', + OnboardingWalletSecuritySkipInitiated = 'SRP Skip Backup Selected', + OnboardingWalletSecuritySkipConfirmed = 'SRP Backup Skipped', + OnboardingWalletSecuritySkipCanceled = 'SRP Skip Backup Canceled', + OnboardingWalletSecurityPhraseRevealed = 'SRP Revealed', + OnboardingWalletSecurityPhraseWrittenDown = 'SRP Backup Confirm Display', + OnboardingWalletSecurityPhraseConfirmed = 'SRP Backup Confirmed', + OnboardingWalletCreationComplete = 'Wallet Created', + OnboardingWalletSetupComplete = 'Application Opened', + OnboardingWalletAdvancedSettings = 'Settings Updated', + OnboardingWalletImportAttempted = 'Wallet Import Attempted', + OnboardingWalletVideoPlay = 'SRP Intro Video Played', + OnboardingTwitterClick = 'External Link Clicked', + ServiceWorkerRestarted = 'Service Worker Restarted', +} + +export enum MetaMetricsEventAccountType { + Default = 'metamask', + Imported = 'imported', + Hardware = 'hardware', +} + +export enum MetaMetricsEventAccountImportType { + Json = 'json', + PrivateKey = 'private_key', + Srp = 'srp', +} + +export enum MetaMetricsEventCategory { + Accounts = 'Accounts', + App = 'App', + Auth = 'Auth', + Background = 'Background', + // The TypeScript ESLint rule is incorrectly marking this line. + /* eslint-disable-next-line @typescript-eslint/no-shadow */ + Error = 'Error', + Footer = 'Footer', + Home = 'Home', + InpageProvider = 'inpage_provider', + Keys = 'Keys', + Messages = 'Messages', + Navigation = 'Navigation', + Network = 'Network', + Onboarding = 'Onboarding', + Phishing = 'Phishing', + Retention = 'Retention', + Settings = 'Settings', + Snaps = 'Snaps', + Swaps = 'Swaps', + Transactions = 'Transactions', + Wallet = 'Wallet', + Desktop = 'Desktop', + ServiceWorkers = 'service_workers', +} + +export enum MetaMetricsEventLinkType { + TransactionBlockExplorer = 'Transaction Block Explorer', + BlockExplorer = 'Block Explorer', + AccountTracker = 'Account Tracker', + TokenTracker = 'Token Tracker', +} + +export enum MetaMetricsEventKeyType { + Pkey = 'private_key', + Srp = 'srp', +} + +// NOTE: This doesn't seem to be used at all +export enum MetaMetricsEventOnrampProviderType { + Coinbase = 'coinbase', + Moonpay = 'moonpay', + Wyre = 'wyre', + Transak = 'transak', + SelfDeposit = 'direct_deposit', +} + +export enum MetaMetricsNetworkEventSource { + CustomNetworkForm = 'custom_network_form', + PopularNetworkList = 'popular_network_list', + Dapp = 'dapp', +} + +export enum MetaMetricsSwapsEventSource { + MainView = 'Main View', + TokenView = 'Token View', +} + +export enum MetaMetricsTokenEventSource { + Custom = 'custom', + Dapp = 'dapp', + Detected = 'detected', + List = 'list', +} + +export enum MetaMetricsTransactionEventSource { + Dapp = 'dapp', + User = 'user', +} + +export enum MetaMetricsEventLocation { + TokenDetails = 'token_details', + TokenDetection = 'token_detection', + TokenMenu = 'token_menu', +} + +export enum MetaMetricsEventUiCustomization { + FlaggedAsMalicious = 'flagged_as_malicious', + FlaggedAsSafetyUnknown = 'flagged_as_safety_unknown', + Siwe = 'sign_in_with_ethereum', +} + +/** + * Values that can used in the "properties" tracking object as keys, e.g. `{ + * location: 'Home' }`. + */ +export enum MetaMetricsContextProp { + PageTitle = 'location', +} diff --git a/ui/components/app/account-menu/account-menu.component.js b/ui/components/app/account-menu/account-menu.component.js index c27788402282..c20b83e5c45c 100644 --- a/ui/components/app/account-menu/account-menu.component.js +++ b/ui/components/app/account-menu/account-menu.component.js @@ -6,9 +6,10 @@ import InputAdornment from '@material-ui/core/InputAdornment'; import classnames from 'classnames'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; import { - EVENT, - EVENT_NAMES, - CONTEXT_PROPS, + MetaMetricsContextProp, + MetaMetricsEventAccountType, + MetaMetricsEventCategory, + MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import Identicon from '../../ui/identicon'; @@ -209,8 +210,8 @@ export default class AccountMenu extends Component { className="account-menu__account account-menu__item--clickable" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.NAV_ACCOUNT_SWITCHED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.NavAccountSwitched, properties: { location: 'Main Menu', }, @@ -360,10 +361,10 @@ export default class AccountMenu extends Component { onClick={() => { toggleAccountMenu(); trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.ACCOUNT_ADD_SELECTED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.AccountAddSelected, properties: { - account_type: EVENT.ACCOUNT_TYPES.DEFAULT, + account_type: MetaMetricsEventAccountType.Default, location: 'Main Menu', }, }); @@ -378,10 +379,10 @@ export default class AccountMenu extends Component { onClick={() => { toggleAccountMenu(); trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.ACCOUNT_ADD_SELECTED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.AccountAddSelected, properties: { - account_type: EVENT.ACCOUNT_TYPES.IMPORTED, + account_type: MetaMetricsEventAccountType.Imported, location: 'Main Menu', }, }); @@ -396,10 +397,10 @@ export default class AccountMenu extends Component { onClick={() => { toggleAccountMenu(); trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.ACCOUNT_ADD_SELECTED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.AccountAddSelected, properties: { - account_type: EVENT.ACCOUNT_TYPES.HARDWARE, + account_type: MetaMetricsEventAccountType.Hardware, location: 'Main Menu', }, }); @@ -446,14 +447,16 @@ export default class AccountMenu extends Component { onClick={() => { trackEvent( { - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.SUPPORT_LINK_CLICKED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.SupportLinkClicked, properties: { url: supportLink, }, }, { - contextPropsIntoEventProperties: [CONTEXT_PROPS.PAGE_TITLE], + contextPropsIntoEventProperties: [ + MetaMetricsContextProp.PageTitle, + ], }, ); global.platform.openTab({ url: supportLink }); @@ -472,8 +475,8 @@ export default class AccountMenu extends Component { toggleAccountMenu(); history.push(SETTINGS_ROUTE); this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.NAV_SETTINGS_OPENED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.NavSettingsOpened, properties: { location: 'Main Menu', }, diff --git a/ui/components/app/add-network/add-network.js b/ui/components/app/add-network/add-network.js index 816d1e92cf16..48eaa711d6a7 100644 --- a/ui/components/app/add-network/add-network.js +++ b/ui/components/app/add-network/add-network.js @@ -37,7 +37,7 @@ import { ADD_NETWORK_ROUTE } from '../../../helpers/constants/routes'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; import { Icon, ICON_NAMES, ICON_SIZES, Text } from '../../component-library'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsNetworkEventSource } from '../../../../shared/constants/metametrics'; const AddNetwork = () => { const t = useContext(I18nContext); @@ -267,7 +267,8 @@ const AddNetwork = () => { imageUrl: item.rpcPrefs?.imageUrl, chainName: item.nickname, referrer: ORIGIN_METAMASK, - source: EVENT.SOURCE.NETWORK.POPULAR_NETWORK_LIST, + source: + MetaMetricsNetworkEventSource.PopularNetworkList, }, }), ); diff --git a/ui/components/app/app-components.scss b/ui/components/app/app-components.scss index 9659eaad3083..196ab6c901ad 100644 --- a/ui/components/app/app-components.scss +++ b/ui/components/app/app-components.scss @@ -59,6 +59,7 @@ @import 'permissions-connect-footer/index'; @import 'permissions-connect-header/index'; @import 'permissions-connect-permission-list/index'; +@import 'permission-cell/index'; @import 'recovery-phrase-reminder/index'; @import 'set-approval-for-all-warning/index'; @import 'step-progress-bar/index.scss'; diff --git a/ui/components/app/app-header/app-header.component.js b/ui/components/app/app-header/app-header.component.js index e7178a56f2fa..248dda89f470 100644 --- a/ui/components/app/app-header/app-header.component.js +++ b/ui/components/app/app-header/app-header.component.js @@ -4,7 +4,10 @@ import classnames from 'classnames'; import Identicon from '../../ui/identicon'; import MetaFoxLogo from '../../ui/metafox-logo'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import NetworkDisplay from '../network-display'; ///: BEGIN:ONLY_INCLUDE_IN(beta) @@ -57,8 +60,8 @@ export default class AppHeader extends PureComponent { if (networkDropdownOpen === false) { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.NAV_NETWORK_MENU_OPENED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.NavNetworkMenuOpened, properties: {}, }); showNetworkDropdown(); @@ -90,8 +93,8 @@ export default class AppHeader extends PureComponent { if (!disabled) { !isAccountMenuOpen && this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.NAV_MAIN_MENU_OPENED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.NavMainMenuOpened, properties: {}, }); toggleAccountMenu(); diff --git a/ui/components/app/asset-list-item/asset-list-item.js b/ui/components/app/asset-list-item/asset-list-item.js index c2568235598c..a5cc5051f7d6 100644 --- a/ui/components/app/asset-list-item/asset-list-item.js +++ b/ui/components/app/asset-list-item/asset-list-item.js @@ -13,7 +13,7 @@ import { startNewDraftTransaction } from '../../../ducks/send'; import { SEND_ROUTE } from '../../../helpers/constants/routes'; import { Color, SEVERITIES } from '../../../helpers/constants/design-system'; import { INVALID_ASSET_TYPE } from '../../../helpers/constants/error-keys'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import { AssetType } from '../../../../shared/constants/transaction'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { Icon, ICON_NAMES, ICON_SIZES } from '../../component-library'; @@ -68,7 +68,7 @@ const AssetListItem = ({ e.stopPropagation(); trackEvent({ event: 'Clicked Send: Token', - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, properties: { action: 'Home', legacy_event: true, diff --git a/ui/components/app/asset-list/asset-list.js b/ui/components/app/asset-list/asset-list.js index e83606e8bfe7..5e305dcf9458 100644 --- a/ui/components/app/asset-list/asset-list.js +++ b/ui/components/app/asset-list/asset-list.js @@ -24,7 +24,10 @@ import { } from '../../../helpers/constants/design-system'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import DetectedToken from '../detected-token/detected-token'; import { DetectedTokensBanner, @@ -110,8 +113,8 @@ const AssetList = ({ onClickAsset }) => { onTokenClick={(tokenAddress) => { onClickAsset(tokenAddress); trackEvent({ - event: EVENT_NAMES.TOKEN_SCREEN_OPENED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.TokenScreenOpened, + category: MetaMetricsEventCategory.Navigation, properties: { token_symbol: primaryCurrencyProperties.suffix, location: 'Home', diff --git a/ui/components/app/asset-list/detetcted-tokens-link/detected-tokens-link.js b/ui/components/app/asset-list/detetcted-tokens-link/detected-tokens-link.js index adad64e95c2a..9c9ef6230a82 100644 --- a/ui/components/app/asset-list/detetcted-tokens-link/detected-tokens-link.js +++ b/ui/components/app/asset-list/detetcted-tokens-link/detected-tokens-link.js @@ -9,8 +9,9 @@ import { useI18nContext } from '../../../../hooks/useI18nContext'; import { getDetectedTokensInCurrentNetwork } from '../../../../selectors'; import { MetaMetricsContext } from '../../../../contexts/metametrics'; import { - EVENT, - EVENT_NAMES, + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsTokenEventSource, } from '../../../../../shared/constants/metametrics'; const DetectedTokensLink = ({ className = '', setShowDetectedTokens }) => { @@ -25,10 +26,10 @@ const DetectedTokensLink = ({ className = '', setShowDetectedTokens }) => { const onClick = () => { setShowDetectedTokens(true); trackEvent({ - event: EVENT_NAMES.TOKEN_IMPORT_CLICKED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenImportClicked, + category: MetaMetricsEventCategory.Wallet, properties: { - source: EVENT.SOURCE.TOKEN.DETECTED, + source: MetaMetricsTokenEventSource.Detected, tokens: detectedTokensDetails, }, }); diff --git a/ui/components/app/confirm-page-container/confirm-page-container.component.js b/ui/components/app/confirm-page-container/confirm-page-container.component.js index aa12f0cf5c35..1c9b74d6ad65 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container.component.js +++ b/ui/components/app/confirm-page-container/confirm-page-container.component.js @@ -44,7 +44,10 @@ import { } from '../../../selectors'; import useRamps from '../../../hooks/experiences/useRamps'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { ConfirmPageContainerHeader, ConfirmPageContainerContent, @@ -250,8 +253,8 @@ const ConfirmPageContainer = (props) => { onClick={() => { openBuyCryptoInPdapp(); trackEvent({ - event: EVENT_NAMES.NAV_BUY_BUTTON_CLICKED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.NavBuyButtonClicked, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Transaction Confirmation', text: 'Buy', diff --git a/ui/components/app/confirm-page-container/flask/snap-insight.js b/ui/components/app/confirm-page-container/flask/snap-insight.js index 3cfafd94d3d1..13d182736046 100644 --- a/ui/components/app/confirm-page-container/flask/snap-insight.js +++ b/ui/components/app/confirm-page-container/flask/snap-insight.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; import Preloader from '../../../ui/icon/preloader/preloader-icon.component'; import { Text } from '../../../component-library'; import { @@ -14,8 +15,12 @@ import { import { useI18nContext } from '../../../../hooks/useI18nContext'; import { useTransactionInsightSnap } from '../../../../hooks/flask/useTransactionInsightSnap'; import Box from '../../../ui/box/box'; -import ActionableMessage from '../../../ui/actionable-message/actionable-message'; import { SnapUIRenderer } from '../../flask/snap-ui-renderer'; +import { SnapDelineator } from '../../flask/snap-delineator'; +import { DelineatorType } from '../../../../helpers/constants/flask'; +import { getSnapName } from '../../../../helpers/utils/util'; +import { Copyable } from '../../flask/copyable'; +import { getTargetSubjectMetadata } from '../../../../selectors'; export const SnapInsight = ({ transaction, origin, chainId, selectedSnap }) => { const t = useI18nContext(); @@ -30,6 +35,12 @@ export const SnapInsight = ({ transaction, origin, chainId, selectedSnap }) => { snapId: selectedSnap.id, }); + const targetSubjectMetadata = useSelector((state) => + getTargetSubjectMetadata(state, selectedSnap.id), + ); + + const snapName = getSnapName(selectedSnap.id, targetSubjectMetadata); + const data = response?.content; const hasNoData = @@ -52,7 +63,11 @@ export const SnapInsight = ({ transaction, origin, chainId, selectedSnap }) => { className="snap-insight__container" > {data && Object.keys(data).length > 0 ? ( - + ) : ( { )} {!loading && error && ( - - + + + + {t('snapsUIError', [{snapName}])} + + + )} diff --git a/ui/components/app/desktop-enable-button/desktop-enable-button.component.js b/ui/components/app/desktop-enable-button/desktop-enable-button.component.js index 52099e738295..650e13e600b6 100644 --- a/ui/components/app/desktop-enable-button/desktop-enable-button.component.js +++ b/ui/components/app/desktop-enable-button/desktop-enable-button.component.js @@ -20,7 +20,7 @@ import { } from '../../../store/actions'; import { SECOND } from '../../../../shared/constants/time'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; const DESKTOP_ERROR_DESKTOP_OUTDATED_ROUTE = `${DESKTOP_ERROR_ROUTE}/${EXTENSION_ERROR_PAGE_TYPES.DESKTOP_OUTDATED}`; const DESKTOP_ERROR_EXTENSION_OUTDATED_ROUTE = `${DESKTOP_ERROR_ROUTE}/${EXTENSION_ERROR_PAGE_TYPES.EXTENSION_OUTDATED}`; @@ -45,7 +45,7 @@ export default function DesktopEnableButton() { await disableDesktop(); setDesktopEnabled(false); trackEvent({ - category: EVENT.CATEGORIES.DESKTOP, + category: MetaMetricsEventCategory.Desktop, event: DESKTOP_UPDATE_SETTINGS_EVENT, properties: { desktop_enabled: false, @@ -90,7 +90,7 @@ export default function DesktopEnableButton() { } trackEvent({ - category: EVENT.CATEGORIES.DESKTOP, + category: MetaMetricsEventCategory.Desktop, event: 'Desktop Button Clicked', properties: { button_action: 'Enable MetaMask Desktop', diff --git a/ui/components/app/detected-token/detected-token-selection-popover/detected-token-selection-popover.js b/ui/components/app/detected-token/detected-token-selection-popover/detected-token-selection-popover.js index a726640861f2..4ae5204fc221 100644 --- a/ui/components/app/detected-token/detected-token-selection-popover/detected-token-selection-popover.js +++ b/ui/components/app/detected-token/detected-token-selection-popover/detected-token-selection-popover.js @@ -5,8 +5,9 @@ import { useSelector } from 'react-redux'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../../../contexts/metametrics'; import { - EVENT, - EVENT_NAMES, + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsTokenEventSource, } from '../../../../../shared/constants/metametrics'; import { getDetectedTokensInCurrentNetwork } from '../../../../selectors'; @@ -40,10 +41,10 @@ const DetectedTokenSelectionPopover = ({ ({ address, symbol }) => `${symbol} - ${address}`, ); trackEvent({ - event: EVENT_NAMES.TOKEN_IMPORT_CANCELED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenImportCanceled, + category: MetaMetricsEventCategory.Wallet, properties: { - source: EVENT.SOURCE.TOKEN.DETECTED, + source: MetaMetricsTokenEventSource.Detected, tokens: eventTokensDetails, }, }); diff --git a/ui/components/app/detected-token/detected-token.js b/ui/components/app/detected-token/detected-token.js index feadbab24060..02484563b9fb 100644 --- a/ui/components/app/detected-token/detected-token.js +++ b/ui/components/app/detected-token/detected-token.js @@ -15,7 +15,12 @@ import { AssetType, TokenStandard, } from '../../../../shared/constants/transaction'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventLocation, + MetaMetricsEventName, + MetaMetricsTokenEventSource, +} from '../../../../shared/constants/metametrics'; import DetectedTokenSelectionPopover from './detected-token-selection-popover/detected-token-selection-popover'; import DetectedTokenIgnoredPopover from './detected-token-ignored-popover/detected-token-ignored-popover'; @@ -58,13 +63,13 @@ const DetectedToken = ({ setShowDetectedTokens }) => { const importSelectedTokens = async (selectedTokens) => { selectedTokens.forEach((importedToken) => { trackEvent({ - event: EVENT_NAMES.TOKEN_ADDED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenAdded, + category: MetaMetricsEventCategory.Wallet, sensitiveProperties: { token_symbol: importedToken.symbol, token_contract_address: importedToken.address, token_decimal_precision: importedToken.decimals, - source: EVENT.SOURCE.TOKEN.DETECTED, + source: MetaMetricsTokenEventSource.Detected, token_standard: TokenStandard.ERC20, asset_type: AssetType.token, }, @@ -86,11 +91,11 @@ const DetectedToken = ({ setShowDetectedTokens }) => { ({ symbol, address }) => `${symbol} - ${address}`, ); trackEvent({ - event: EVENT_NAMES.TOKEN_HIDDEN, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenHidden, + category: MetaMetricsEventCategory.Wallet, sensitiveProperties: { tokens: tokensDetailsList, - location: EVENT.LOCATION.TOKEN_DETECTION, + location: MetaMetricsEventLocation.TokenDetection, token_standard: TokenStandard.ERC20, asset_type: AssetType.token, }, diff --git a/ui/components/app/dropdowns/network-dropdown.js b/ui/components/app/dropdowns/network-dropdown.js index c40ccc79d887..d101e5769b10 100644 --- a/ui/components/app/dropdowns/network-dropdown.js +++ b/ui/components/app/dropdowns/network-dropdown.js @@ -23,7 +23,11 @@ import { IconColor, Size } from '../../../helpers/constants/design-system'; import { getShowTestNetworks } from '../../../selectors'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsNetworkEventSource, +} from '../../../../shared/constants/metametrics'; import { ADD_POPULAR_CUSTOM_NETWORK, ADVANCED_ROUTE, @@ -127,8 +131,8 @@ class NetworkDropdown extends Component { const { trackEvent } = this.context; trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.NAV_NETWORK_SWITCHED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.NavNetworkSwitched, properties: { from_network: providerType, to_network: newProviderType, @@ -320,7 +324,7 @@ class NetworkDropdown extends Component { }, { setActive: true, - source: EVENT.SOURCE.NETWORK.CUSTOM_NETWORK_FORM, + source: MetaMetricsNetworkEventSource.CustomNetworkForm, }, ); } diff --git a/ui/components/app/flask/snap-authorship/snap-authorship.js b/ui/components/app/flask/snap-authorship/snap-authorship.js index 4179c5cbfb6b..996c01b77461 100644 --- a/ui/components/app/flask/snap-authorship/snap-authorship.js +++ b/ui/components/app/flask/snap-authorship/snap-authorship.js @@ -14,6 +14,7 @@ import { AlignItems, DISPLAY, BorderRadius, + BLOCK_SIZES, } from '../../../../helpers/constants/design-system'; import { getSnapName, @@ -59,7 +60,7 @@ const SnapAuthorship = ({ snapId, className }) => { paddingRight={4} borderRadius={BorderRadius.pill} display={DISPLAY.FLEX} - style={{ maxWidth: 'fit-content', width: '100%' }} + width={BLOCK_SIZES.FULL} > @@ -87,6 +88,7 @@ const SnapAuthorship = ({ snapId, className }) => { iconName={ICON_NAMES.EXPORT} color={IconColor.infoDefault} size={ICON_SIZES.MD} + style={{ marginLeft: 'auto' }} /> ); diff --git a/ui/components/app/flask/snap-delineator/index.scss b/ui/components/app/flask/snap-delineator/index.scss index 17e5be8b0f5f..697dfb68f3f1 100644 --- a/ui/components/app/flask/snap-delineator/index.scss +++ b/ui/components/app/flask/snap-delineator/index.scss @@ -1,7 +1,7 @@ .snap-delineator { &__header { border-bottom-width: 1px; - border-color: var(--color-border-muted); + border-color: var(--color-border-default); border-style: solid; border-radius: 8px 8px 0 0; diff --git a/ui/components/app/flask/snap-delineator/snap-delineator.js b/ui/components/app/flask/snap-delineator/snap-delineator.js index dd10170455bf..a397f5bc9bdb 100644 --- a/ui/components/app/flask/snap-delineator/snap-delineator.js +++ b/ui/components/app/flask/snap-delineator/snap-delineator.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import { BorderStyle, - Size, BorderColor, BorderRadius, AlignItems, @@ -13,37 +12,60 @@ import { TextColor, } from '../../../../helpers/constants/design-system'; import Box from '../../../ui/box'; -import { Icon, Text } from '../../../component-library'; +import { + AvatarIcon, + ICON_NAMES, + ICON_SIZES, + Text, +} from '../../../component-library'; +import { + DelineatorType, + getDelineatorTitle, +} from '../../../../helpers/constants/flask'; -export const SnapDelineator = ({ snapName, children }) => { +export const SnapDelineator = ({ + snapName, + type = DelineatorType.default, + children, +}) => { const t = useI18nContext(); - + const isError = type === DelineatorType.Error; return ( - + - {t('contentFromSnap', [snapName])} + {t(getDelineatorTitle(type), [snapName])} @@ -55,5 +77,6 @@ export const SnapDelineator = ({ snapName, children }) => { SnapDelineator.propTypes = { snapName: PropTypes.string, + type: PropTypes.string, children: PropTypes.ReactNode, }; diff --git a/ui/components/app/flask/snap-delineator/snap-delineator.stories.js b/ui/components/app/flask/snap-delineator/snap-delineator.stories.js index e2e60e685c58..563232426c18 100644 --- a/ui/components/app/flask/snap-delineator/snap-delineator.stories.js +++ b/ui/components/app/flask/snap-delineator/snap-delineator.stories.js @@ -6,5 +6,5 @@ export default { }; export const DefaultStory = () => ( - Children + Children ); diff --git a/ui/components/app/flask/snap-delineator/snap-delineator.test.js b/ui/components/app/flask/snap-delineator/snap-delineator.test.js new file mode 100644 index 000000000000..e9553c7308ad --- /dev/null +++ b/ui/components/app/flask/snap-delineator/snap-delineator.test.js @@ -0,0 +1,35 @@ +import React from 'react'; +import { DelineatorType } from '../../../../helpers/constants/flask'; +import { renderWithLocalization } from '../../../../../test/lib/render-helpers'; +import { SnapDelineator } from './snap-delineator'; + +describe('SnapDelineator', () => { + const args = { + snapName: 'Test Snap', + type: DelineatorType.Content, + children: 'This is some test content', + }; + + it('should render the SnapDelineator with content inside', () => { + const { getByText } = renderWithLocalization(); + + expect(getByText(/Content from Test Snap/u)).toBeDefined(); + expect(getByText(args.children)).toBeDefined(); + }); + + it('should render an insight title', () => { + args.type = DelineatorType.Insights; + + const { getByText } = renderWithLocalization(); + + expect(getByText(/Insights from Test Snap/u)).toBeDefined(); + }); + + it('should render an error title', () => { + args.type = DelineatorType.Error; + + const { getByText } = renderWithLocalization(); + + expect(getByText(/Error with Test Snap/u)).toBeDefined(); + }); +}); diff --git a/ui/components/app/flask/snap-ui-renderer/snap-ui-renderer.js b/ui/components/app/flask/snap-ui-renderer/snap-ui-renderer.js index 731bd599fabd..20197923f5a2 100644 --- a/ui/components/app/flask/snap-ui-renderer/snap-ui-renderer.js +++ b/ui/components/app/flask/snap-ui-renderer/snap-ui-renderer.js @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { useSelector } from 'react-redux'; import nanoid from 'nanoid'; import { isComponent } from '@metamask/snaps-ui'; +import { useSelector } from 'react-redux'; import MetaMaskTemplateRenderer from '../../metamask-template-renderer/metamask-template-renderer'; import { TypographyVariant, @@ -10,12 +10,16 @@ import { DISPLAY, FLEX_DIRECTION, OVERFLOW_WRAP, + TextVariant, } from '../../../../helpers/constants/design-system'; import { SnapDelineator } from '../snap-delineator'; import { useI18nContext } from '../../../../hooks/useI18nContext'; -import ActionableMessage from '../../../ui/actionable-message/actionable-message'; import Box from '../../../ui/box'; -import { getSnap } from '../../../../selectors'; +import { getSnapName } from '../../../../helpers/utils/util'; +import { getTargetSubjectMetadata } from '../../../../selectors'; +import { Text } from '../../../component-library'; +import { Copyable } from '../copyable'; +import { DelineatorType } from '../../../../helpers/constants/flask'; export const UI_MAPPING = { panel: (props) => ({ @@ -70,22 +74,25 @@ export const mapToTemplate = (data) => { }; // Component that maps Snaps UI JSON format to MetaMask Template Renderer format -export const SnapUIRenderer = ({ snapId, data }) => { +export const SnapUIRenderer = ({ + snapId, + delineatorType = DelineatorType.Content, + data, +}) => { const t = useI18nContext(); - const snap = useSelector((state) => getSnap(state, snapId)); + const targetSubjectMetadata = useSelector((state) => + getTargetSubjectMetadata(state, snapId), + ); - const snapName = snap.manifest.proposedName; + const snapName = getSnapName(snapId, targetSubjectMetadata); if (!isComponent(data)) { return ( - - + + + {t('snapsUIError', [{snapName}])} + + ); } @@ -93,7 +100,7 @@ export const SnapUIRenderer = ({ snapId, data }) => { const sections = mapToTemplate(data); return ( - + @@ -103,5 +110,6 @@ export const SnapUIRenderer = ({ snapId, data }) => { SnapUIRenderer.propTypes = { snapId: PropTypes.string, + delineatorType: PropTypes.string, data: PropTypes.object, }; diff --git a/ui/components/app/flask/update-snap-permission-list/update-snap-permission-list.js b/ui/components/app/flask/update-snap-permission-list/update-snap-permission-list.js index f787628e99b2..85f3373d421c 100644 --- a/ui/components/app/flask/update-snap-permission-list/update-snap-permission-list.js +++ b/ui/components/app/flask/update-snap-permission-list/update-snap-permission-list.js @@ -1,14 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { isFunction } from 'lodash'; -import { - getRightIcon, - getWeightedPermissions, -} from '../../../../helpers/utils/permission'; +import { getWeightedPermissions } from '../../../../helpers/utils/permission'; import { useI18nContext } from '../../../../hooks/useI18nContext'; -import { formatDate } from '../../../../helpers/utils/util'; -import Typography from '../../../ui/typography/typography'; -import { TextColor } from '../../../../helpers/constants/design-system'; +import PermissionCell from '../../permission-cell'; +import Box from '../../../ui/box'; export default function UpdateSnapPermissionList({ approvedPermissions, @@ -17,52 +12,50 @@ export default function UpdateSnapPermissionList({ }) { const t = useI18nContext(); - const Permissions = ({ className, permissions, subText }) => { - return getWeightedPermissions(t, permissions).map((permission) => { - const { label, permissionName, permissionValue } = permission; - return ( -
- -
- {label} - - {isFunction(subText) - ? subText(permissionName, permissionValue) - : subText} - -
- {getRightIcon(permission)} -
- ); - }); - }; - return ( -
- - { - const { date } = permissionValue; - const formattedDate = formatDate(date, 'yyyy-MM-dd'); - return t('approvedOn', [formattedDate]); - }} - /> - -
+ + {getWeightedPermissions(t, newPermissions).map((permission, index) => { + return ( + + ); + })} + {getWeightedPermissions(t, approvedPermissions).map( + (permission, index) => { + return ( + + ); + }, + )} + {getWeightedPermissions(t, revokedPermissions).map( + (permission, index) => { + return ( + + ); + }, + )} + ); } diff --git a/ui/components/app/import-token-link/import-token-link.component.js b/ui/components/app/import-token-link/import-token-link.component.js index 6f5e93a1bb76..cf7ebae1f970 100644 --- a/ui/components/app/import-token-link/import-token-link.component.js +++ b/ui/components/app/import-token-link/import-token-link.component.js @@ -8,7 +8,10 @@ import Box from '../../ui/box/box'; import { TEXT_ALIGN } from '../../../helpers/constants/design-system'; import { detectNewTokens } from '../../../store/actions'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { getIsTokenDetectionSupported, getIsTokenDetectionInactiveOnMainnet, @@ -51,8 +54,8 @@ export default function ImportTokenLink() { onClick={() => { history.push(IMPORT_TOKEN_ROUTE); trackEvent({ - event: EVENT_NAMES.TOKEN_IMPORT_BUTTON_CLICKED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.TokenImportButtonClicked, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Home', }, diff --git a/ui/components/app/menu-bar/account-options-menu.js b/ui/components/app/menu-bar/account-options-menu.js index deeb4e0a3473..b5469687b75a 100644 --- a/ui/components/app/menu-bar/account-options-menu.js +++ b/ui/components/app/menu-bar/account-options-menu.js @@ -22,7 +22,11 @@ import { useI18nContext } from '../../../hooks/useI18nContext'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../shared/constants/app'; import { KeyringType } from '../../../../shared/constants/keyring'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventLinkType, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { ICON_NAMES } from '../../component-library'; @@ -50,10 +54,10 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { const openBlockExplorer = () => { trackEvent({ - event: EVENT_NAMES.EXTERNAL_LINK_CLICKED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.ExternalLinkClicked, + category: MetaMetricsEventCategory.Navigation, properties: { - link_type: EVENT.EXTERNAL_LINK_TYPES.ACCOUNT_TRACKER, + link_type: MetaMetricsEventLinkType.AccountTracker, location: 'Account Options', url_domain: getURLHostName(addressLink), }, @@ -96,8 +100,8 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { { trackEvent({ - event: EVENT_NAMES.APP_WINDOW_EXPANDED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.AppWindowExpanded, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Account Options', }, @@ -115,8 +119,8 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { onClick={() => { dispatch(showModal({ name: 'ACCOUNT_DETAILS' })); trackEvent({ - event: EVENT_NAMES.NAV_ACCOUNT_DETAILS_OPENED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.NavAccountDetailsOpened, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Account Options', }, @@ -131,8 +135,8 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { data-testid="account-options-menu__connected-sites" onClick={() => { trackEvent({ - event: EVENT_NAMES.NAV_CONNECTED_SITES_OPENED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.NavConnectedSitesOpened, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Account Options', }, diff --git a/ui/components/app/menu-bar/menu-bar.js b/ui/components/app/menu-bar/menu-bar.js index 3ddc301af563..99afdf1c6f40 100644 --- a/ui/components/app/menu-bar/menu-bar.js +++ b/ui/components/app/menu-bar/menu-bar.js @@ -6,7 +6,10 @@ import SelectedAccount from '../selected-account'; import ConnectedStatusIndicator from '../connected-status-indicator'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { CONNECTED_ACCOUNTS_ROUTE } from '../../../helpers/constants/routes'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { getOriginOfCurrentTab } from '../../../selectors'; @@ -44,8 +47,8 @@ export default function MenuBar() { ariaLabel={t('accountOptions')} onClick={() => { trackEvent({ - event: EVENT_NAMES.NAV_ACCOUNT_MENU_OPENED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.NavAccountMenuOpened, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Home', }, diff --git a/ui/components/app/modals/account-details-modal/account-details-modal.component.js b/ui/components/app/modals/account-details-modal/account-details-modal.component.js index 189b18fbcce7..f1ad623c6fcf 100644 --- a/ui/components/app/modals/account-details-modal/account-details-modal.component.js +++ b/ui/components/app/modals/account-details-modal/account-details-modal.component.js @@ -9,8 +9,10 @@ import Button from '../../../ui/button'; import { getURLHostName } from '../../../../helpers/utils/util'; import { isHardwareKeyring } from '../../../../helpers/utils/hardware'; import { - EVENT, - EVENT_NAMES, + MetaMetricsEventCategory, + MetaMetricsEventLinkType, + MetaMetricsEventKeyType, + MetaMetricsEventName, } from '../../../../../shared/constants/metametrics'; import { NETWORKS_ROUTE } from '../../../../helpers/constants/routes'; @@ -65,10 +67,10 @@ export default class AccountDetailsModal extends Component { const openBlockExplorer = () => { const accountLink = getAccountLink(address, chainId, rpcPrefs); this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.EXTERNAL_LINK_CLICKED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.ExternalLinkClicked, properties: { - link_type: EVENT.EXTERNAL_LINK_TYPES.ACCOUNT_TRACKER, + link_type: MetaMetricsEventLinkType.AccountTracker, location: 'Account Details Modal', url_domain: getURLHostName(accountLink), }, @@ -115,10 +117,10 @@ export default class AccountDetailsModal extends Component { className="account-details-modal__button" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.ACCOUNTS, - event: EVENT_NAMES.KEY_EXPORT_SELECTED, + category: MetaMetricsEventCategory.Accounts, + event: MetaMetricsEventName.KeyExportSelected, properties: { - key_type: EVENT.KEY_TYPES.PKEY, + key_type: MetaMetricsEventKeyType.Pkey, location: 'Account Details Modal', }, }); diff --git a/ui/components/app/modals/confirm-remove-account/confirm-remove-account.component.js b/ui/components/app/modals/confirm-remove-account/confirm-remove-account.component.js index 4d1faea86da1..e8d8c25cda26 100644 --- a/ui/components/app/modals/confirm-remove-account/confirm-remove-account.component.js +++ b/ui/components/app/modals/confirm-remove-account/confirm-remove-account.component.js @@ -4,7 +4,7 @@ import { getAccountLink } from '@metamask/etherscan-link'; import Modal from '../../modal'; import { addressSummary, getURLHostName } from '../../../../helpers/utils/util'; import Identicon from '../../../ui/identicon'; -import { EVENT } from '../../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../../shared/constants/metametrics'; import ZENDESK_URLS from '../../../../helpers/constants/zendesk-url'; export default class ConfirmRemoveAccount extends Component { @@ -62,7 +62,7 @@ export default class ConfirmRemoveAccount extends Component { rpcPrefs, ); this.context.trackEvent({ - category: EVENT.CATEGORIES.ACCOUNTS, + category: MetaMetricsEventCategory.Accounts, event: 'Clicked Block Explorer Link', properties: { link_type: 'Account Tracker', diff --git a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js index fcd2dde85379..81e0dfc4c944 100644 --- a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js +++ b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js @@ -10,8 +10,9 @@ import { stripHexPrefix, } from '../../../../../shared/modules/hexstring-utils'; import { - EVENT, - EVENT_NAMES, + MetaMetricsEventCategory, + MetaMetricsEventKeyType, + MetaMetricsEventName, } from '../../../../../shared/constants/metametrics'; export default class ExportPrivateKeyModal extends Component { @@ -53,10 +54,10 @@ export default class ExportPrivateKeyModal extends Component { exportAccount(password, address) .then((privateKey) => { this.context.trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_REVEALED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportRevealed, properties: { - key_type: EVENT.KEY_TYPES.PKEY, + key_type: MetaMetricsEventKeyType.Pkey, }, }); @@ -67,10 +68,10 @@ export default class ExportPrivateKeyModal extends Component { }) .catch((e) => { this.context.trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_FAILED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportFailed, properties: { - key_type: EVENT.KEY_TYPES.PKEY, + key_type: MetaMetricsEventKeyType.Pkey, reason: 'incorrect_password', }, }); @@ -108,10 +109,10 @@ export default class ExportPrivateKeyModal extends Component { onClick={() => { copyToClipboard(plainKey); this.context.trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_COPIED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportCopied, properties: { - key_type: EVENT.KEY_TYPES.PKEY, + key_type: MetaMetricsEventKeyType.Pkey, copy_method: 'clipboard', }, }); @@ -132,10 +133,10 @@ export default class ExportPrivateKeyModal extends Component { className="export-private-key-modal__button export-private-key-modal__button--cancel" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_CANCELED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportCanceled, properties: { - key_type: EVENT.KEY_TYPES.PKEY, + key_type: MetaMetricsEventKeyType.Pkey, }, }); hideModal(); @@ -159,10 +160,10 @@ export default class ExportPrivateKeyModal extends Component { - + + {name} + +
); }; diff --git a/ui/components/ui/tabs/tabs.component.js b/ui/components/ui/tabs/tabs.component.js index 47e402e3fa4b..e96576711ceb 100644 --- a/ui/components/ui/tabs/tabs.component.js +++ b/ui/components/ui/tabs/tabs.component.js @@ -1,109 +1,101 @@ -import React, { Component } from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; +import Box from '../box'; +import { + BackgroundColor, + DISPLAY, + JustifyContent, +} from '../../../helpers/constants/design-system'; -export default class Tabs extends Component { - static defaultProps = { - defaultActiveTabKey: null, - onTabClick: null, - tabsClassName: undefined, - subHeader: null, - }; - - static propTypes = { - defaultActiveTabKey: PropTypes.string, - onTabClick: PropTypes.func, - children: PropTypes.node.isRequired, - tabsClassName: PropTypes.string, - subHeader: PropTypes.node, +const Tabs = ({ + defaultActiveTabKey, + onTabClick, + children, + tabsClassName, + subHeader, +}) => { + // This ignores any 'null' child elements that are a result of a conditional + // based on a feature flag setting. + const _getValidChildren = () => { + return React.Children.toArray(children).filter(Boolean); }; - state = { - activeTabIndex: Math.max( - this._findChildByKey(this.props.defaultActiveTabKey), - 0, - ), + /** + * Returns the index of the child with the given key + * + * @param {string} tabKey - the name to search for + * @returns {number} the index of the child with the given name + * @private + */ + const _findChildByKey = (tabKey) => { + return _getValidChildren().findIndex((c) => c?.props.tabKey === tabKey); }; - handleTabClick(tabIndex, tabKey) { - const { onTabClick } = this.props; - const { activeTabIndex } = this.state; + const [activeTabIndex, setActiveTabIndex] = useState(() => + Math.max(_findChildByKey(defaultActiveTabKey), 0), + ); + const handleTabClick = (tabIndex, tabKey) => { if (tabIndex !== activeTabIndex) { - this.setState( - { - activeTabIndex: tabIndex, - }, - () => { - if (onTabClick) { - onTabClick(tabKey); - } - }, - ); + setActiveTabIndex(tabIndex); + onTabClick?.(tabKey); } - } + }; - renderTabs() { - const numberOfTabs = React.Children.count(this._getValidChildren()); + const renderTabs = () => { + const numberOfTabs = React.Children.count(_getValidChildren()); - return React.Children.map(this._getValidChildren(), (child, index) => { + return React.Children.map(_getValidChildren(), (child, index) => { const tabKey = child?.props.tabKey; return ( child && React.cloneElement(child, { - onClick: (idx) => this.handleTabClick(idx, tabKey), + onClick: (idx) => handleTabClick(idx, tabKey), tabIndex: index, - isActive: numberOfTabs > 1 && index === this.state.activeTabIndex, + isActive: numberOfTabs > 1 && index === activeTabIndex, }) ); }); - } - - renderActiveTabContent() { - const children = this._getValidChildren(); - const { activeTabIndex } = this.state; + }; + const renderActiveTabContent = () => { + const validChildren = _getValidChildren(); if ( - (Array.isArray(children) && !children[activeTabIndex]) || - (!Array.isArray(children) && activeTabIndex !== 0) + (Array.isArray(validChildren) && !validChildren[activeTabIndex]) || + (!Array.isArray(validChildren) && activeTabIndex !== 0) ) { throw new Error(`Tab at index '${activeTabIndex}' does not exist`); } - return children[activeTabIndex] - ? children[activeTabIndex].props.children - : children.props.children; - } + return validChildren[activeTabIndex] + ? validChildren[activeTabIndex].props.children + : validChildren.props.children; + }; - render() { - const { tabsClassName, subHeader } = this.props; - return ( -
-
    - {this.renderTabs()} -
- {subHeader} -
{this.renderActiveTabContent()}
-
- ); - } + return ( + + + {renderTabs()} + + {subHeader} + {renderActiveTabContent()} + + ); +}; - /** - * Returns the index of the child with the given key - * - * @param {string} tabKey - the name to search for - * @returns {number} the index of the child with the given name - * @private - */ - _findChildByKey(tabKey) { - return this._getValidChildren().findIndex( - (c) => c?.props.tabKey === tabKey, - ); - } - - // This ignores any 'null' child elements that are a result of a conditional - // based on a feature flag setting. - _getValidChildren() { - return React.Children.toArray(this.props.children).filter(Boolean); - } -} +export default Tabs; +Tabs.propTypes = { + defaultActiveTabKey: PropTypes.string, + onTabClick: PropTypes.func, + children: PropTypes.node.isRequired, + tabsClassName: PropTypes.string, + subHeader: PropTypes.node, +}; diff --git a/ui/components/ui/tabs/tabs.stories.js b/ui/components/ui/tabs/tabs.stories.js index 1b12d462be6e..d8d4c4b39d7a 100644 --- a/ui/components/ui/tabs/tabs.stories.js +++ b/ui/components/ui/tabs/tabs.stories.js @@ -17,6 +17,7 @@ export default { }, }, onTabClick: { action: 'onTabClick' }, + onChange: { action: 'onChange' }, }, args: { tabs: [ @@ -42,16 +43,24 @@ export const DefaultStory = (args) => { onTabClick={args.onTabClick} > {args.tabs.map((tabProps, i) => renderTab(tabProps, i, args.t))} + + ); +}; + +DefaultStory.storyName = 'Default'; + +export const DropdownStory = (args) => { + return ( + This is a dropdown Tab ); }; - -DefaultStory.storyName = 'Default'; diff --git a/ui/contexts/metametrics.js b/ui/contexts/metametrics.js index fd3d1526575e..ac1f0c776a8b 100644 --- a/ui/contexts/metametrics.js +++ b/ui/contexts/metametrics.js @@ -17,7 +17,7 @@ import { captureException, captureMessage } from '@sentry/browser'; import { omit } from 'lodash'; import { getEnvironmentType } from '../../app/scripts/lib/util'; import { PATH_NAME_MAP } from '../helpers/constants/routes'; -import { CONTEXT_PROPS } from '../../shared/constants/metametrics'; +import { MetaMetricsContextProp } from '../../shared/constants/metametrics'; import { useSegmentContext } from '../hooks/useSegmentContext'; import { trackMetaMetricsEvent, trackMetaMetricsPage } from '../store/actions'; @@ -67,8 +67,9 @@ export function MetaMetricsProvider({ children }) { if (!payload.properties) { payload.properties = {}; } - if (fields.includes(CONTEXT_PROPS.PAGE_TITLE)) { - payload.properties[CONTEXT_PROPS.PAGE_TITLE] = context.page?.title; + if (fields.includes(MetaMetricsContextProp.PageTitle)) { + payload.properties[MetaMetricsContextProp.PageTitle] = + context.page?.title; } }; diff --git a/ui/ducks/swaps/swaps.js b/ui/ducks/swaps/swaps.js index 803d1a19d350..6f5252bc27e9 100644 --- a/ui/ducks/swaps/swaps.js +++ b/ui/ducks/swaps/swaps.js @@ -69,7 +69,7 @@ import { checkNetworkAndAccountSupports1559, } from '../../selectors'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import { ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, @@ -726,7 +726,7 @@ export const fetchQuotesAndSetQuoteState = ( getCurrentSmartTransactionsEnabled(state); trackEvent({ event: 'Quotes Requested', - category: EVENT.CATEGORIES.SWAPS, + category: MetaMetricsEventCategory.Swaps, sensitiveProperties: { token_from: fromTokenSymbol, token_from_amount: String(inputValue), @@ -780,7 +780,7 @@ export const fetchQuotesAndSetQuoteState = ( if (Object.values(fetchedQuotes)?.length === 0) { trackEvent({ event: 'No Quotes Available', - category: EVENT.CATEGORIES.SWAPS, + category: MetaMetricsEventCategory.Swaps, sensitiveProperties: { token_from: fromTokenSymbol, token_from_amount: String(inputValue), @@ -801,7 +801,7 @@ export const fetchQuotesAndSetQuoteState = ( trackEvent({ event: 'Quotes Received', - category: EVENT.CATEGORIES.SWAPS, + category: MetaMetricsEventCategory.Swaps, sensitiveProperties: { token_from: fromTokenSymbol, token_from_amount: String(inputValue), @@ -902,7 +902,7 @@ export const signAndSendSwapsSmartTransaction = ({ }; trackEvent({ event: 'STX Swap Started', - category: EVENT.CATEGORIES.SWAPS, + category: MetaMetricsEventCategory.Swaps, sensitiveProperties: swapMetaData, }); @@ -1159,7 +1159,7 @@ export const signAndSendTransactions = ( trackEvent({ event: 'Swap Started', - category: EVENT.CATEGORIES.SWAPS, + category: MetaMetricsEventCategory.Swaps, sensitiveProperties: swapMetaData, }); diff --git a/ui/helpers/constants/flask/delineator.test.ts b/ui/helpers/constants/flask/delineator.test.ts new file mode 100644 index 000000000000..285d89dfd19c --- /dev/null +++ b/ui/helpers/constants/flask/delineator.test.ts @@ -0,0 +1,23 @@ +import { DelineatorType, getDelineatorTitle } from './delineator'; + +describe('delineator utils', () => { + describe('getDelineatorTitle', () => { + it('should return the good key for an error delineator type', () => { + const result = getDelineatorTitle(DelineatorType.Error); + + expect(result).toStrictEqual('errorWithSnap'); + }); + + it('should return the good key for an insights delineator type', () => { + const result = getDelineatorTitle(DelineatorType.Insights); + + expect(result).toStrictEqual('insightsFromSnap'); + }); + + it('should return the content key for any other types', () => { + const result = getDelineatorTitle(DelineatorType.Content); + + expect(result).toStrictEqual('contentFromSnap'); + }); + }); +}); diff --git a/ui/helpers/constants/flask/delineator.ts b/ui/helpers/constants/flask/delineator.ts new file mode 100644 index 000000000000..ce5d5002b15a --- /dev/null +++ b/ui/helpers/constants/flask/delineator.ts @@ -0,0 +1,17 @@ +export enum DelineatorType { + Content = 'content', + // eslint-disable-next-line @typescript-eslint/no-shadow + Error = 'error', + Insights = 'insights', +} + +export const getDelineatorTitle = (type: DelineatorType) => { + switch (type) { + case DelineatorType.Error: + return 'errorWithSnap'; + case DelineatorType.Insights: + return 'insightsFromSnap'; + default: + return 'contentFromSnap'; + } +}; diff --git a/ui/helpers/constants/flask/index.js b/ui/helpers/constants/flask/index.js new file mode 100644 index 000000000000..cafa4fe135f2 --- /dev/null +++ b/ui/helpers/constants/flask/index.js @@ -0,0 +1 @@ +export * from './delineator'; diff --git a/ui/helpers/utils/accounts.js b/ui/helpers/utils/accounts.js index 102d22075230..6bfa68d8636b 100644 --- a/ui/helpers/utils/accounts.js +++ b/ui/helpers/utils/accounts.js @@ -1,4 +1,4 @@ -import { INVISIBLE_CHARACTER } from '../../components/component-library'; +import { INVISIBLE_CHARACTER } from '../../components/component-library/text/deprecated'; export function getAccountNameErrorMessage( accounts, diff --git a/ui/helpers/utils/permission.js b/ui/helpers/utils/permission.js index 6987b1d7fff4..2d54064aaefe 100644 --- a/ui/helpers/utils/permission.js +++ b/ui/helpers/utils/permission.js @@ -15,21 +15,13 @@ import { } from '../../../shared/constants/permissions'; import Tooltip from '../../components/ui/tooltip'; import { - AvatarIcon, ///: BEGIN:ONLY_INCLUDE_IN(flask) - Icon, Text, ///: END:ONLY_INCLUDE_IN ICON_NAMES, - ICON_SIZES, } from '../../components/component-library'; ///: BEGIN:ONLY_INCLUDE_IN(flask) -import { - IconColor, - Color, - FONT_WEIGHT, - TextVariant, -} from '../constants/design-system'; +import { Color, FONT_WEIGHT, TextVariant } from '../constants/design-system'; import { coinTypeToProtocolName, getSnapDerivationPathName, @@ -39,63 +31,29 @@ import { const UNKNOWN_PERMISSION = Symbol('unknown'); -///: BEGIN:ONLY_INCLUDE_IN(flask) -const RIGHT_WARNING_ICON = ( - -); - -const RIGHT_INFO_ICON = ( - -); -///: END:ONLY_INCLUDE_IN - -function getLeftIcon(iconName) { - return ( - - ); -} - export const PERMISSION_DESCRIPTIONS = deepFreeze({ [RestrictedMethods.eth_accounts]: ({ t }) => ({ label: t('permission_ethereumAccounts'), - leftIcon: getLeftIcon(ICON_NAMES.EYE), - rightIcon: null, + leftIcon: ICON_NAMES.EYE, weight: 2, }), ///: BEGIN:ONLY_INCLUDE_IN(flask) [RestrictedMethods.snap_confirm]: ({ t }) => ({ label: t('permission_customConfirmation'), description: t('permission_customConfirmationDescription'), - leftIcon: getLeftIcon(ICON_NAMES.SECURITY_TICK), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.SECURITY_TICK, weight: 3, }), [RestrictedMethods.snap_dialog]: ({ t }) => ({ label: t('permission_dialog'), description: t('permission_dialogDescription'), - leftIcon: getLeftIcon(ICON_NAMES.MESSAGES), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.MESSAGES, weight: 3, }), [RestrictedMethods.snap_notify]: ({ t }) => ({ label: t('permission_notifications'), description: t('permission_notificationsDescription'), - leftIcon: getLeftIcon(ICON_NAMES.NOTIFICATION), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.NOTIFICATION, weight: 3, }), [RestrictedMethods.snap_getBip32PublicKey]: ({ @@ -105,8 +63,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ }) => permissionValue.caveats[0].value.map(({ path, curve }, i) => { const baseDescription = { - leftIcon: getLeftIcon(ICON_NAMES.SECURITY_SEARCH), - rightIcon: RIGHT_WARNING_ICON, + leftIcon: ICON_NAMES.SECURITY_SEARCH, weight: 1, id: `public-key-access-bip32-${path .join('-') @@ -176,8 +133,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ }) => permissionValue.caveats[0].value.map(({ path, curve }, i) => { const baseDescription = { - leftIcon: getLeftIcon(ICON_NAMES.KEY), - rightIcon: RIGHT_WARNING_ICON, + leftIcon: ICON_NAMES.KEY, weight: 1, id: `key-access-bip32-${path .join('-') @@ -261,8 +217,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ t('unrecognizedProtocol', [coinType])} , ]), - leftIcon: getLeftIcon(ICON_NAMES.KEY), - rightIcon: RIGHT_WARNING_ICON, + leftIcon: ICON_NAMES.KEY, weight: 1, id: `key-access-bip44-${coinType}-${i}`, message: t('snapInstallWarningKeyAccess', [ @@ -284,22 +239,19 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ [RestrictedMethods.snap_getEntropy]: ({ t }) => ({ label: t('permission_getEntropy'), description: t('permission_getEntropyDescription'), - leftIcon: getLeftIcon(ICON_NAMES.SECURITY_KEY), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.SECURITY_KEY, weight: 3, }), [RestrictedMethods.snap_manageState]: ({ t }) => ({ label: t('permission_manageState'), description: t('permission_manageStateDescription'), - leftIcon: getLeftIcon(ICON_NAMES.ADD_SQUARE), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.ADD_SQUARE, weight: 3, }), [RestrictedMethods.wallet_snap]: ({ t, permissionValue }) => { const snaps = permissionValue.caveats[0].value; const baseDescription = { - leftIcon: getLeftIcon(ICON_NAMES.FLASH), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.FLASH, }; return Object.keys(snaps).map((snapId) => { @@ -326,8 +278,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ [EndowmentPermissions['endowment:network-access']]: ({ t }) => ({ label: t('permission_accessNetwork'), description: t('permission_accessNetworkDescription'), - leftIcon: getLeftIcon(ICON_NAMES.GLOBAL), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.GLOBAL, weight: 2, }), [EndowmentPermissions['endowment:webassembly']]: ({ t }) => ({ @@ -340,8 +291,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ [EndowmentPermissions['endowment:long-running']]: ({ t }) => ({ label: t('permission_longRunning'), description: t('permission_longRunningDescription'), - leftIcon: getLeftIcon(ICON_NAMES.LINK), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.LINK, weight: 3, }), [EndowmentPermissions['endowment:transaction-insight']]: ({ @@ -349,8 +299,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ permissionValue, }) => { const baseDescription = { - leftIcon: getLeftIcon(ICON_NAMES.SPEEDOMETER), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.SPEEDOMETER, weight: 3, }; @@ -371,7 +320,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ ...baseDescription, label: t('permission_transactionInsightOrigin'), description: t('permission_transactionInsightOriginDescription'), - leftIcon: getLeftIcon(ICON_NAMES.EXPLORE), + leftIcon: ICON_NAMES.EXPLORE, }); } @@ -380,8 +329,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ [EndowmentPermissions['endowment:cronjob']]: ({ t }) => ({ label: t('permission_cronjob'), description: t('permission_cronjobDescription'), - leftIcon: getLeftIcon(ICON_NAMES.CLOCK), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.CLOCK, weight: 2, }), [EndowmentPermissions['endowment:ethereum-provider']]: ({ @@ -390,16 +338,14 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ }) => ({ label: t('permission_ethereumProvider'), description: t('permission_ethereumProviderDescription'), - leftIcon: getLeftIcon(ICON_NAMES.ETHEREUM), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.ETHEREUM, weight: 1, id: 'ethereum-provider-access', message: t('ethereumProviderAccess', [targetSubjectMetadata?.origin]), }), [EndowmentPermissions['endowment:rpc']]: ({ t, permissionValue }) => { const baseDescription = { - leftIcon: getLeftIcon(ICON_NAMES.HIERARCHY), - rightIcon: RIGHT_INFO_ICON, + leftIcon: ICON_NAMES.HIERARCHY, weight: 2, }; @@ -427,8 +373,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({ ///: END:ONLY_INCLUDE_IN [UNKNOWN_PERMISSION]: ({ t, permissionName }) => ({ label: t('permission_unknown', [permissionName ?? 'undefined']), - leftIcon: getLeftIcon(ICON_NAMES.QUESTION), - rightIcon: null, + leftIcon: ICON_NAMES.QUESTION, weight: 4, }), }); diff --git a/ui/pages/add-nft/add-nft.js b/ui/pages/add-nft/add-nft.js index 138ba3b9978c..963c7b61ae3d 100644 --- a/ui/pages/add-nft/add-nft.js +++ b/ui/pages/add-nft/add-nft.js @@ -32,7 +32,10 @@ import { getNftsDropdownState } from '../../ducks/metamask/metamask'; import NftsDetectionNotice from '../../components/app/nfts-detection-notice'; import { MetaMetricsContext } from '../../contexts/metametrics'; import { AssetType } from '../../../shared/constants/transaction'; -import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics'; +import { + MetaMetricsEventName, + MetaMetricsTokenEventSource, +} from '../../../shared/constants/metametrics'; import { ButtonIcon, ICON_NAMES, @@ -101,7 +104,7 @@ export default function AddNft() { ); trackEvent({ - event: EVENT_NAMES.TOKEN_ADDED, + event: MetaMetricsEventName.TokenAdded, category: 'Wallet', sensitiveProperties: { token_contract_address: nftAddress, @@ -109,7 +112,7 @@ export default function AddNft() { tokenId: tokenId.toString(), asset_type: AssetType.NFT, token_standard: tokenDetails?.standard, - source: EVENT.SOURCE.TOKEN.CUSTOM, + source: MetaMetricsTokenEventSource.Custom, }, }); diff --git a/ui/pages/asset/components/native-asset.js b/ui/pages/asset/components/native-asset.js index 7d59816b9cf2..0d5d6f98bc24 100644 --- a/ui/pages/asset/components/native-asset.js +++ b/ui/pages/asset/components/native-asset.js @@ -16,7 +16,7 @@ import { showModal } from '../../../store/actions'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import { getURLHostName } from '../../../helpers/utils/util'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import AssetNavigation from './asset-navigation'; import AssetOptions from './asset-options'; @@ -46,7 +46,7 @@ export default function NativeAsset({ nativeCurrency }) { onClickBlockExplorer={() => { trackEvent({ event: 'Clicked Block Explorer Link', - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, properties: { link_type: 'Account Tracker', action: 'Asset Options', diff --git a/ui/pages/asset/components/token-asset.js b/ui/pages/asset/components/token-asset.js index 3b26cb359c8c..2df9c17ac92e 100644 --- a/ui/pages/asset/components/token-asset.js +++ b/ui/pages/asset/components/token-asset.js @@ -18,7 +18,7 @@ import { import { getURLHostName } from '../../../helpers/utils/util'; import { showModal } from '../../../store/actions'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import AssetNavigation from './asset-navigation'; import AssetOptions from './asset-options'; @@ -58,7 +58,7 @@ export default function TokenAsset({ token }) { onClickBlockExplorer={() => { trackEvent({ event: 'Clicked Block Explorer Link', - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, properties: { link_type: 'Token Tracker', action: 'Token Options', diff --git a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js index 979193b09c83..bba7aedc58dd 100644 --- a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js +++ b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js @@ -14,7 +14,11 @@ import ZENDESK_URLS from '../../helpers/constants/zendesk-url'; import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils'; import { getSuggestedAssets } from '../../selectors'; import { rejectWatchAsset, acceptWatchAsset } from '../../store/actions'; -import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsTokenEventSource, +} from '../../../shared/constants/metametrics'; import { AssetType, TokenStandard, @@ -118,14 +122,14 @@ const ConfirmAddSuggestedToken = () => { await dispatch(acceptWatchAsset(id)); trackEvent({ - event: EVENT_NAMES.TOKEN_ADDED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenAdded, + category: MetaMetricsEventCategory.Wallet, sensitiveProperties: { token_symbol: asset.symbol, token_contract_address: asset.address, token_decimal_precision: asset.decimals, unlisted: asset.unlisted, - source: EVENT.SOURCE.TOKEN.DAPP, + source: MetaMetricsTokenEventSource.Dapp, token_standard: TokenStandard.ERC20, asset_type: AssetType.token, }, diff --git a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js index 49e0acb97a4d..31828f2185c0 100644 --- a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js +++ b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js @@ -9,7 +9,7 @@ import Identicon from '../../components/ui/identicon'; import Tooltip from '../../components/ui/tooltip'; import { PageContainerFooter } from '../../components/ui/page-container'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import { SECOND } from '../../../shared/constants/time'; import { Numeric } from '../../../shared/modules/Numeric'; import { EtherDenomination } from '../../../shared/constants/common'; @@ -52,7 +52,7 @@ export default class ConfirmDecryptMessage extends Component { copyMessage = () => { copyToClipboard(this.state.rawMessage); this.context.trackEvent({ - category: EVENT.CATEGORIES.MESSAGES, + category: MetaMetricsEventCategory.Messages, event: 'Copy', properties: { action: 'Decrypt Message Copy', @@ -286,7 +286,7 @@ export default class ConfirmDecryptMessage extends Component { onCancel={async (event) => { await cancelDecryptMessage(txData, event); trackEvent({ - category: EVENT.CATEGORIES.MESSAGES, + category: MetaMetricsEventCategory.Messages, event: 'Cancel', properties: { action: 'Decrypt Message Request', @@ -299,7 +299,7 @@ export default class ConfirmDecryptMessage extends Component { onSubmit={async (event) => { await decryptMessage(txData, event); trackEvent({ - category: EVENT.CATEGORIES.MESSAGES, + category: MetaMetricsEventCategory.Messages, event: 'Confirm', properties: { action: 'Decrypt Message Request', diff --git a/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js b/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js index 262fd2958305..1595576a4fac 100644 --- a/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js +++ b/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js @@ -6,7 +6,7 @@ import AccountListItem from '../../components/app/account-list-item'; import Identicon from '../../components/ui/identicon'; import { PageContainerFooter } from '../../components/ui/page-container'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import SiteOrigin from '../../components/ui/site-origin'; import { Numeric } from '../../../shared/modules/Numeric'; import { EtherDenomination } from '../../../shared/constants/common'; @@ -185,7 +185,7 @@ export default class ConfirmEncryptionPublicKey extends Component { onCancel={async (event) => { await cancelEncryptionPublicKey(txData, event); trackEvent({ - category: EVENT.CATEGORIES.MESSAGES, + category: MetaMetricsEventCategory.Messages, event: 'Cancel', properties: { action: 'Encryption public key Request', @@ -198,7 +198,7 @@ export default class ConfirmEncryptionPublicKey extends Component { onSubmit={async (event) => { await encryptionPublicKey(txData, event); this.context.trackEvent({ - category: EVENT.CATEGORIES.MESSAGES, + category: MetaMetricsEventCategory.Messages, event: 'Confirm', properties: { action: 'Encryption public key Request', diff --git a/ui/pages/confirm-import-token/confirm-import-token.js b/ui/pages/confirm-import-token/confirm-import-token.js index 5a340cbb1e51..61bc41ff46b4 100644 --- a/ui/pages/confirm-import-token/confirm-import-token.js +++ b/ui/pages/confirm-import-token/confirm-import-token.js @@ -13,7 +13,11 @@ import { MetaMetricsContext } from '../../contexts/metametrics'; import { getMostRecentOverviewPage } from '../../ducks/history/history'; import { getPendingTokens } from '../../ducks/metamask/metamask'; import { addTokens, clearPendingTokens } from '../../store/actions'; -import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsTokenEventSource, +} from '../../../shared/constants/metametrics'; import { AssetType, TokenStandard, @@ -40,16 +44,16 @@ const ConfirmImportToken = () => { addedTokenValues.forEach((pendingToken) => { trackEvent({ - event: EVENT_NAMES.TOKEN_ADDED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenAdded, + category: MetaMetricsEventCategory.Wallet, sensitiveProperties: { token_symbol: pendingToken.symbol, token_contract_address: pendingToken.address, token_decimal_precision: pendingToken.decimals, unlisted: pendingToken.unlisted, source: pendingToken.isCustom - ? EVENT.SOURCE.TOKEN.CUSTOM - : EVENT.SOURCE.TOKEN.LIST, + ? MetaMetricsTokenEventSource.Custom + : MetaMetricsTokenEventSource.List, token_standard: TokenStandard.ERC20, asset_type: AssetType.token, }, diff --git a/ui/pages/confirm-transaction-base/__snapshots__/confirm-transaction-base.test.js.snap b/ui/pages/confirm-transaction-base/__snapshots__/confirm-transaction-base.test.js.snap index 922adf6c5763..0cfbc28bb6b4 100644 --- a/ui/pages/confirm-transaction-base/__snapshots__/confirm-transaction-base.test.js.snap +++ b/ui/pages/confirm-transaction-base/__snapshots__/confirm-transaction-base.test.js.snap @@ -278,35 +278,41 @@ exports[`Confirm Transaction Base should match snapshot 1`] = `
  • -
  • -
  • -
- getSnap(state, pendingConfirmation?.origin), + const targetSubjectMetadata = useSelector((state) => + getTargetSubjectMetadata(state, pendingConfirmation?.origin), ); // When pendingConfirmation is undefined, this will also be undefined - const proposedName = snap?.manifest.proposedName; + const snapName = + targetSubjectMetadata && + getSnapName(pendingConfirmation?.origin, targetSubjectMetadata); const SNAP_DIALOG_TYPE = [ MESSAGE_TYPE.SNAP_DIALOG_ALERT, @@ -213,7 +220,7 @@ export default function ConfirmationPage({ ? getTemplateValues( { ///: BEGIN:ONLY_INCLUDE_IN(flask) - snapName: isSnapDialog && proposedName, + snapName: isSnapDialog && snapName, ///: END:ONLY_INCLUDE_IN ...pendingConfirmation, }, @@ -230,7 +237,7 @@ export default function ConfirmationPage({ history, ///: BEGIN:ONLY_INCLUDE_IN(flask) isSnapDialog, - proposedName, + snapName, ///: END:ONLY_INCLUDE_IN ]); @@ -327,25 +334,42 @@ export default function ConfirmationPage({ /> ) : null} - {pendingConfirmation.origin === 'metamask' ? null : ( - - - - )} + { + ///: BEGIN:ONLY_INCLUDE_IN(flask) + !isSnapDialog && + ///: END:ONLY_INCLUDE_IN + pendingConfirmation.origin === 'metamask' && ( + + + + ) + } + { + ///: BEGIN:ONLY_INCLUDE_IN(flask) + isSnapDialog && ( + + + + ) + ///: END:ONLY_INCLUDE_IN + } {showWarningModal && ( { this.context.trackEvent({ - category: EVENT.CATEGORIES.ACCOUNTS, - event: EVENT_NAMES.ACCOUNT_ADDED, + category: MetaMetricsEventCategory.Accounts, + event: MetaMetricsEventName.AccountAdded, properties: { - account_type: EVENT.ACCOUNT_TYPES.HARDWARE, + account_type: MetaMetricsEventAccountType.Hardware, account_hardware_type: device, }, }); @@ -264,10 +268,10 @@ class ConnectHardwareForm extends Component { }) .catch((e) => { this.context.trackEvent({ - category: EVENT.CATEGORIES.ACCOUNTS, - event: EVENT_NAMES.ACCOUNT_ADD_FAILED, + category: MetaMetricsEventCategory.Accounts, + event: MetaMetricsEventName.AccountAddFailed, properties: { - account_type: EVENT.ACCOUNT_TYPES.HARDWARE, + account_type: MetaMetricsEventAccountType.Hardware, account_hardware_type: device, error: e.message, }, diff --git a/ui/pages/create-account/connect-hardware/select-hardware.js b/ui/pages/create-account/connect-hardware/select-hardware.js index f5cc5c338a89..9cb027eb932e 100644 --- a/ui/pages/create-account/connect-hardware/select-hardware.js +++ b/ui/pages/create-account/connect-hardware/select-hardware.js @@ -14,7 +14,7 @@ import { HardwareAffiliateTutorialLinks, } from '../../../../shared/constants/hardware-wallets'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import { isManifestV3 } from '../../../../shared/modules/mv3.utils'; import { openWindow } from '../../../helpers/utils/window'; @@ -242,7 +242,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked Ledger Buy Now', }); openWindow(HardwareAffiliateLinks.ledger); @@ -255,7 +255,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked Ledger Tutorial', }); openWindow(HardwareAffiliateTutorialLinks.ledger); @@ -310,7 +310,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked GridPlus Buy Now', }); openWindow(HardwareAffiliateLinks.gridplus); @@ -323,7 +323,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked GidPlus Tutorial', }); openWindow(HardwareAffiliateTutorialLinks.gridplus); @@ -376,7 +376,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked Trezor Buy Now', }); openWindow(HardwareAffiliateLinks.trezor); @@ -389,7 +389,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked Trezor Tutorial', }); openWindow(HardwareAffiliateTutorialLinks.trezor); @@ -430,7 +430,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked Keystone Buy Now', }); openWindow(HardwareAffiliateLinks.keystone); @@ -443,7 +443,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked Keystone Tutorial', }); openWindow(HardwareAffiliateTutorialLinks.keystone); @@ -465,7 +465,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked AirGap Vault Buy Now', }); openWindow(HardwareAffiliateLinks.airgap); @@ -478,7 +478,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked AirGap Vault Tutorial', }); openWindow(HardwareAffiliateTutorialLinks.airgap); @@ -500,7 +500,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked CoolWallet Buy Now', }); openWindow(HardwareAffiliateLinks.coolwallet); @@ -513,7 +513,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked CoolWallet Tutorial', }); openWindow(HardwareAffiliateTutorialLinks.coolwallet); @@ -533,7 +533,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked DCent Buy Now', }); openWindow(HardwareAffiliateLinks.dcent); @@ -546,7 +546,7 @@ export default class SelectHardware extends Component { type="secondary" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, event: 'Clicked DCent Tutorial', }); openWindow(HardwareAffiliateTutorialLinks.dcent); diff --git a/ui/pages/create-account/import-account/import-account.js b/ui/pages/create-account/import-account/import-account.js index fdba6f563abb..d47e7fc5f0f7 100644 --- a/ui/pages/create-account/import-account/import-account.js +++ b/ui/pages/create-account/import-account/import-account.js @@ -1,6 +1,11 @@ import React, { useContext, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventAccountImportType, + MetaMetricsEventAccountType, + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { ButtonLink, Label, Text } from '../../../components/component-library'; import Box from '../../../components/ui/box'; import Dropdown from '../../../components/ui/dropdown'; @@ -52,18 +57,18 @@ export default function NewAccountImportForm() { function trackImportEvent(strategy, wasSuccessful) { const accountImportType = strategy === 'Private Key' - ? EVENT.ACCOUNT_IMPORT_TYPES.PRIVATE_KEY - : EVENT.ACCOUNT_IMPORT_TYPES.JSON; + ? MetaMetricsEventAccountImportType.PrivateKey + : MetaMetricsEventAccountImportType.Json; const event = wasSuccessful - ? EVENT_NAMES.ACCOUNT_ADDED - : EVENT_NAMES.ACCOUNT_ADD_FAILED; + ? MetaMetricsEventName.AccountAdded + : MetaMetricsEventName.AccountAddFailed; trackEvent({ - category: EVENT.CATEGORIES.ACCOUNTS, + category: MetaMetricsEventCategory.Accounts, event, properties: { - account_type: EVENT.ACCOUNT_TYPES.IMPORTED, + account_type: MetaMetricsEventAccountType.Imported, account_import_type: accountImportType, }, }); diff --git a/ui/pages/create-account/new-account.component.js b/ui/pages/create-account/new-account.component.js index a9974d46de96..0c219d7c359a 100644 --- a/ui/pages/create-account/new-account.component.js +++ b/ui/pages/create-account/new-account.component.js @@ -2,7 +2,11 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import Button from '../../components/ui/button'; -import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics'; +import { + MetaMetricsEventAccountType, + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../shared/constants/metametrics'; import { getAccountNameErrorMessage } from '../../helpers/utils/accounts'; export default class NewAccountCreateForm extends Component { @@ -27,20 +31,20 @@ export default class NewAccountCreateForm extends Component { createAccount(newAccountName || defaultAccountName) .then(() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.ACCOUNTS, - event: EVENT_NAMES.ACCOUNT_ADDED, + category: MetaMetricsEventCategory.Accounts, + event: MetaMetricsEventName.AccountAdded, properties: { - account_type: EVENT.ACCOUNT_TYPES.DEFAULT, + account_type: MetaMetricsEventAccountType.Default, }, }); history.push(mostRecentOverviewPage); }) .catch((e) => { this.context.trackEvent({ - category: EVENT.CATEGORIES.ACCOUNTS, - event: EVENT_NAMES.ACCOUNT_ADD_FAILED, + category: MetaMetricsEventCategory.Accounts, + event: MetaMetricsEventName.AccountAddFailed, properties: { - account_type: EVENT.ACCOUNT_TYPES.DEFAULT, + account_type: MetaMetricsEventAccountType.Default, error: e.message, }, }); diff --git a/ui/pages/desktop-error/render-desktop-error.js b/ui/pages/desktop-error/render-desktop-error.js index fcb8cd9b8398..810a118e9a87 100644 --- a/ui/pages/desktop-error/render-desktop-error.js +++ b/ui/pages/desktop-error/render-desktop-error.js @@ -16,7 +16,7 @@ import Typography from '../../components/ui/typography'; import Button from '../../components/ui/button'; import Box from '../../components/ui/box'; import { openCustomProtocol } from '../../../shared/lib/deep-linking'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; export function renderDesktopError({ type, @@ -84,7 +84,7 @@ export function renderDesktopError({ onClick(); if (typeof trackEvent === 'function') { trackEvent({ - category: EVENT.CATEGORIES.DESKTOP, + category: MetaMetricsEventCategory.Desktop, event: 'Desktop Button Clicked', properties: { button_action: action, diff --git a/ui/pages/error/error.component.js b/ui/pages/error/error.component.js index 888a64a07851..04095cec4ce1 100644 --- a/ui/pages/error/error.component.js +++ b/ui/pages/error/error.component.js @@ -4,9 +4,9 @@ import { getEnvironmentType } from '../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_POPUP } from '../../../shared/constants/app'; import { SUPPORT_REQUEST_LINK } from '../../helpers/constants/common'; import { - EVENT, - EVENT_NAMES, - CONTEXT_PROPS, + MetaMetricsContextProp, + MetaMetricsEventCategory, + MetaMetricsEventName, } from '../../../shared/constants/metametrics'; class ErrorPage extends PureComponent { @@ -50,14 +50,16 @@ class ErrorPage extends PureComponent { onClick={() => { this.context.trackEvent( { - category: EVENT.CATEGORIES.ERROR, - event: EVENT_NAMES.SUPPORT_LINK_CLICKED, + category: MetaMetricsEventCategory.Error, + event: MetaMetricsEventName.SupportLinkClicked, properties: { url: SUPPORT_REQUEST_LINK, }, }, { - contextPropsIntoEventProperties: [CONTEXT_PROPS.PAGE_TITLE], + contextPropsIntoEventProperties: [ + MetaMetricsContextProp.PageTitle, + ], }, ); }} diff --git a/ui/pages/home/beta/beta-home-footer.component.js b/ui/pages/home/beta/beta-home-footer.component.js index 3456ebf4212f..d4077e402921 100644 --- a/ui/pages/home/beta/beta-home-footer.component.js +++ b/ui/pages/home/beta/beta-home-footer.component.js @@ -3,9 +3,9 @@ import React, { useContext } from 'react'; import { SUPPORT_REQUEST_LINK } from '../../../helpers/constants/common'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { - EVENT, - EVENT_NAMES, - CONTEXT_PROPS, + MetaMetricsContextProp, + MetaMetricsEventCategory, + MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; @@ -25,14 +25,16 @@ const BetaHomeFooter = () => { onClick={() => { trackEvent( { - category: EVENT.CATEGORIES.FOOTER, - event: EVENT_NAMES.SUPPORT_LINK_CLICKED, + category: MetaMetricsEventCategory.Footer, + event: MetaMetricsEventName.SupportLinkClicked, properties: { url: SUPPORT_REQUEST_LINK, }, }, { - contextPropsIntoEventProperties: [CONTEXT_PROPS.PAGE_TITLE], + contextPropsIntoEventProperties: [ + MetaMetricsContextProp.PageTitle, + ], }, ); }} diff --git a/ui/pages/home/flask/flask-home-footer.component.js b/ui/pages/home/flask/flask-home-footer.component.js index 0925d9f12fcf..317b09578600 100644 --- a/ui/pages/home/flask/flask-home-footer.component.js +++ b/ui/pages/home/flask/flask-home-footer.component.js @@ -3,9 +3,9 @@ import React, { useContext } from 'react'; import { SUPPORT_REQUEST_LINK } from '../../../helpers/constants/common'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { - EVENT, - EVENT_NAMES, - CONTEXT_PROPS, + MetaMetricsContextProp, + MetaMetricsEventCategory, + MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; @@ -22,14 +22,16 @@ const FlaskHomeFooter = () => { onClick={() => { trackEvent( { - category: EVENT.CATEGORIES.FOOTER, - event: EVENT_NAMES.SUPPORT_LINK_CLICKED, + category: MetaMetricsEventCategory.Footer, + event: MetaMetricsEventName.SupportLinkClicked, properties: { url: SUPPORT_REQUEST_LINK, }, }, { - contextPropsIntoEventProperties: [CONTEXT_PROPS.PAGE_TITLE], + contextPropsIntoEventProperties: [ + MetaMetricsContextProp.PageTitle, + ], }, ); }} diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index cdc6663178cb..5893fe0cd20f 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -3,9 +3,9 @@ import PropTypes from 'prop-types'; import { Redirect, Route } from 'react-router-dom'; ///: BEGIN:ONLY_INCLUDE_IN(main) import { - EVENT, - EVENT_NAMES, - CONTEXT_PROPS, + MetaMetricsContextProp, + MetaMetricsEventCategory, + MetaMetricsEventName, } from '../../../shared/constants/metametrics'; ///: END:ONLY_INCLUDE_IN import AssetList from '../../components/app/asset-list'; @@ -699,15 +699,15 @@ export default class Home extends PureComponent { onClick={() => { this.context.trackEvent( { - category: EVENT.CATEGORIES.HOME, - event: EVENT_NAMES.SUPPORT_LINK_CLICKED, + category: MetaMetricsEventCategory.Home, + event: MetaMetricsEventName.SupportLinkClicked, properties: { url: SUPPORT_LINK, }, }, { contextPropsIntoEventProperties: [ - CONTEXT_PROPS.PAGE_TITLE, + MetaMetricsContextProp.PageTitle, ], }, ); diff --git a/ui/pages/home/index.scss b/ui/pages/home/index.scss index cee94a94306f..5b14a79dc315 100644 --- a/ui/pages/home/index.scss +++ b/ui/pages/home/index.scss @@ -23,7 +23,7 @@ // TODO: fix style import order so this isn't required to override specificity of `tab` class &__main-view &__tabs { border: none; - box-shadow: var(--shadow-size-xs) var(--color-shadow-default); + padding: 0 16px; } &__main-view &__tab { @@ -39,7 +39,7 @@ } &__main-view &__tab button { - padding: 16px 8px; + padding: 8px; } &__connect-status-text { diff --git a/ui/pages/keychains/restore-vault.js b/ui/pages/keychains/restore-vault.js index 708f4d824774..9ffc11e4afe4 100644 --- a/ui/pages/keychains/restore-vault.js +++ b/ui/pages/keychains/restore-vault.js @@ -15,7 +15,7 @@ import { TextColor, TypographyVariant, } from '../../helpers/constants/design-system'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; class RestoreVaultPage extends Component { static contextTypes = { @@ -41,7 +41,7 @@ class RestoreVaultPage extends Component { leaveImportSeedScreenState(); await createNewVaultAndRestore(password, seedPhrase); this.context.trackEvent({ - category: EVENT.CATEGORIES.RETENTION, + category: MetaMetricsEventCategory.Retention, event: 'onboardingRestoredVault', properties: { action: 'userEntersSeedPhrase', diff --git a/ui/pages/keychains/reveal-seed.js b/ui/pages/keychains/reveal-seed.js index 82d4b90a5e81..54633840ff50 100644 --- a/ui/pages/keychains/reveal-seed.js +++ b/ui/pages/keychains/reveal-seed.js @@ -5,7 +5,11 @@ import qrCode from 'qrcode-generator'; import { requestRevealSeedWords, showModal } from '../../store/actions'; import ExportTextContainer from '../../components/ui/export-text-container'; import { getMostRecentOverviewPage } from '../../ducks/history/history'; -import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventKeyType, + MetaMetricsEventName, +} from '../../../shared/constants/metametrics'; import { TextVariant, SEVERITIES, @@ -72,10 +76,10 @@ const RevealSeedPage = () => { dispatch(requestRevealSeedWords(password)) .then((revealedSeedWords) => { trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_REVEALED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportRevealed, properties: { - key_type: EVENT.KEY_TYPES.SRP, + key_type: MetaMetricsEventKeyType.Srp, }, }); setSeedWords(revealedSeedWords); @@ -92,10 +96,10 @@ const RevealSeedPage = () => { }) .catch((e) => { trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_FAILED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportFailed, properties: { - key_type: EVENT.KEY_TYPES.SRP, + key_type: MetaMetricsEventKeyType.Srp, reason: e.message, // 'incorrect_password', }, }); @@ -158,10 +162,10 @@ const RevealSeedPage = () => { text={seedWords} onClickCopy={() => { trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_COPIED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportCopied, properties: { - key_type: EVENT.KEY_TYPES.SRP, + key_type: MetaMetricsEventKeyType.Srp, copy_method: 'clipboard', }, }); @@ -201,10 +205,10 @@ const RevealSeedPage = () => { type={BUTTON_TYPES.SECONDARY} onClick={() => { trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_CANCELED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportCanceled, properties: { - key_type: EVENT.KEY_TYPES.SRP, + key_type: MetaMetricsEventKeyType.Srp, }, }); history.push(mostRecentOverviewPage); @@ -217,10 +221,10 @@ const RevealSeedPage = () => { size={Size.LG} onClick={(event) => { trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_REQUESTED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportRequested, properties: { - key_type: EVENT.KEY_TYPES.SRP, + key_type: MetaMetricsEventKeyType.Srp, }, }); handleSubmit(event); diff --git a/ui/pages/onboarding-flow/create-password/create-password.js b/ui/pages/onboarding-flow/create-password/create-password.js index 6fa0b5f66e83..daf223fcdf23 100644 --- a/ui/pages/onboarding-flow/create-password/create-password.js +++ b/ui/pages/onboarding-flow/create-password/create-password.js @@ -31,7 +31,10 @@ import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; import { getFirstTimeFlowType, getCurrentKeyring } from '../../../selectors'; import { FIRST_TIME_FLOW_TYPES } from '../../../helpers/constants/onboarding'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { Icon, ICON_NAMES } from '../../../components/component-library'; export default function CreatePassword({ @@ -141,8 +144,8 @@ export default function CreatePassword({ } trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_WALLET_CREATION_ATTEMPTED, + category: MetaMetricsEventCategory.Onboarding, + event: MetaMetricsEventName.OnboardingWalletCreationAttempted, }); // If secretRecoveryPhrase is defined we are in import wallet flow diff --git a/ui/pages/onboarding-flow/creation-successful/creation-successful.js b/ui/pages/onboarding-flow/creation-successful/creation-successful.js index 0a8b1682349f..73fc31f0e059 100644 --- a/ui/pages/onboarding-flow/creation-successful/creation-successful.js +++ b/ui/pages/onboarding-flow/creation-successful/creation-successful.js @@ -18,7 +18,10 @@ import { } from '../../../helpers/constants/routes'; import { isBeta } from '../../../helpers/utils/build-types'; import { getFirstTimeFlowType } from '../../../selectors'; -import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; export default function CreationSuccessful() { @@ -101,8 +104,8 @@ export default function CreationSuccessful() { rounded onClick={() => { trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_WALLET_CREATION_COMPLETE, + category: MetaMetricsEventCategory.Onboarding, + event: MetaMetricsEventName.OnboardingWalletCreationComplete, properties: { method: firstTimeFlowType, }, diff --git a/ui/pages/onboarding-flow/import-srp/import-srp.js b/ui/pages/onboarding-flow/import-srp/import-srp.js index 63fc3af07e44..6abc7e5e3d22 100644 --- a/ui/pages/onboarding-flow/import-srp/import-srp.js +++ b/ui/pages/onboarding-flow/import-srp/import-srp.js @@ -20,7 +20,10 @@ import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; import SrpInput from '../../../components/app/srp-input'; import { getCurrentKeyring } from '../../../selectors'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; export default function ImportSRP({ submitSecretRecoveryPhrase }) { const [secretRecoveryPhrase, setSecretRecoveryPhrase] = useState(''); @@ -78,8 +81,9 @@ export default function ImportSRP({ submitSecretRecoveryPhrase }) { onClick={() => { submitSecretRecoveryPhrase(secretRecoveryPhrase); trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_WALLET_SECURITY_PHRASE_CONFIRMED, + category: MetaMetricsEventCategory.Onboarding, + event: + MetaMetricsEventName.OnboardingWalletSecurityPhraseConfirmed, }); history.replace(ONBOARDING_CREATE_PASSWORD_ROUTE); }} diff --git a/ui/pages/onboarding-flow/metametrics/metametrics.js b/ui/pages/onboarding-flow/metametrics/metametrics.js index 5cb133c22f07..c79851970816 100644 --- a/ui/pages/onboarding-flow/metametrics/metametrics.js +++ b/ui/pages/onboarding-flow/metametrics/metametrics.js @@ -17,7 +17,11 @@ import { getFirstTimeFlowType, } from '../../../selectors'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventAccountType, + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { @@ -43,13 +47,13 @@ export default function OnboardingMetametrics() { try { trackEvent( { - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.WALLET_SETUP_STARTED, + category: MetaMetricsEventCategory.Onboarding, + event: MetaMetricsEventName.WalletSetupStarted, properties: { account_type: firstTimeFlowType === 'create' - ? EVENT.ACCOUNT_TYPES.DEFAULT - : EVENT.ACCOUNT_TYPES.IMPORTED, + ? MetaMetricsEventAccountType.Default + : MetaMetricsEventAccountType.Imported, }, }, { diff --git a/ui/pages/onboarding-flow/onboarding-flow.js b/ui/pages/onboarding-flow/onboarding-flow.js index 46a331172369..4ce73f933a2f 100644 --- a/ui/pages/onboarding-flow/onboarding-flow.js +++ b/ui/pages/onboarding-flow/onboarding-flow.js @@ -30,7 +30,10 @@ import { getFirstTimeFlowTypeRoute } from '../../selectors'; import { MetaMetricsContext } from '../../contexts/metametrics'; import Button from '../../components/ui/button'; import { useI18nContext } from '../../hooks/useI18nContext'; -import { EVENT_NAMES, EVENT } from '../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../shared/constants/metametrics'; ///: BEGIN:ONLY_INCLUDE_IN(flask) import ExperimentalArea from '../../components/app/flask/experimental-area'; ///: END:ONLY_INCLUDE_IN @@ -191,11 +194,11 @@ export default function OnboardingFlow() { href={TWITTER_URL} onClick={() => { trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_TWITTER_CLICK, + category: MetaMetricsEventCategory.Onboarding, + event: MetaMetricsEventName.OnboardingTwitterClick, properties: { text: t('followUsOnTwitter'), - location: EVENT_NAMES.ONBOARDING_WALLET_CREATION_COMPLETE, + location: MetaMetricsEventName.OnboardingWalletCreationComplete, url: TWITTER_URL, }, }); diff --git a/ui/pages/onboarding-flow/pin-extension/pin-extension.js b/ui/pages/onboarding-flow/pin-extension/pin-extension.js index 2797224a954d..cc058967e970 100644 --- a/ui/pages/onboarding-flow/pin-extension/pin-extension.js +++ b/ui/pages/onboarding-flow/pin-extension/pin-extension.js @@ -12,7 +12,10 @@ import { } from '../../../helpers/constants/design-system'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import { setCompletedOnboarding } from '../../../store/actions'; -import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { FIRST_TIME_FLOW_TYPES } from '../../../helpers/constants/onboarding'; import { getFirstTimeFlowType } from '../../../selectors'; @@ -32,8 +35,8 @@ export default function OnboardingPinExtension() { } else { await dispatch(setCompletedOnboarding()); trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_WALLET_SETUP_COMPLETE, + category: MetaMetricsEventCategory.Onboarding, + event: MetaMetricsEventName.OnboardingWalletSetupComplete, properties: { wallet_setup_type: firstTimeFlowType === FIRST_TIME_FLOW_TYPES.IMPORT diff --git a/ui/pages/onboarding-flow/privacy-settings/privacy-settings.js b/ui/pages/onboarding-flow/privacy-settings/privacy-settings.js index 3c23c51b850c..4f28dc791e7a 100644 --- a/ui/pages/onboarding-flow/privacy-settings/privacy-settings.js +++ b/ui/pages/onboarding-flow/privacy-settings/privacy-settings.js @@ -34,7 +34,10 @@ import { PRIVACY_POLICY_LINK, } from '../../../../shared/lib/ui-utils'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { Setting } from './setting'; @@ -77,8 +80,8 @@ export default function PrivacySettings() { } trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_WALLET_ADVANCED_SETTINGS, + category: MetaMetricsEventCategory.Onboarding, + event: MetaMetricsEventName.OnboardingWalletAdvancedSettings, properties: { show_incoming_tx: showIncomingTransactions, use_phising_detection: usePhishingDetection, diff --git a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.js b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.js index 60a35732dce8..c933bd561af1 100644 --- a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.js +++ b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.js @@ -20,7 +20,10 @@ import { ONBOARDING_COMPLETION_ROUTE } from '../../../helpers/constants/routes'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { setSeedPhraseBackedUp } from '../../../store/actions'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import RecoveryPhraseChips from './recovery-phrase-chips'; export default function ConfirmRecoveryPhrase({ secretRecoveryPhrase = '' }) { @@ -105,8 +108,9 @@ export default function ConfirmRecoveryPhrase({ secretRecoveryPhrase = '' }) { onClick={async () => { await dispatch(setSeedPhraseBackedUp(true)); trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_WALLET_SECURITY_PHRASE_CONFIRMED, + category: MetaMetricsEventCategory.Onboarding, + event: + MetaMetricsEventName.OnboardingWalletSecurityPhraseConfirmed, }); history.push(ONBOARDING_COMPLETION_ROUTE); }} diff --git a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.js b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.js index 5e39d46ca0c2..b7fa4f789747 100644 --- a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.js +++ b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.js @@ -18,7 +18,10 @@ import { ThreeStepProgressBar, threeStepStages, } from '../../../components/app/step-progress-bar'; -import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { Icon, ICON_NAMES } from '../../../components/component-library'; import RecoveryPhraseChips from './recovery-phrase-chips'; @@ -136,9 +139,9 @@ export default function RecoveryPhrase({ secretRecoveryPhrase }) { className="recovery-phrase__footer--button" onClick={() => { trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, + category: MetaMetricsEventCategory.Onboarding, event: - EVENT_NAMES.ONBOARDING_WALLET_SECURITY_PHRASE_WRITTEN_DOWN, + MetaMetricsEventName.OnboardingWalletSecurityPhraseWrittenDown, }); history.push( `${ONBOARDING_CONFIRM_SRP_ROUTE}${isFromReminderParam}`, @@ -155,8 +158,9 @@ export default function RecoveryPhrase({ secretRecoveryPhrase }) { className="recovery-phrase__footer--button" onClick={() => { trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_WALLET_SECURITY_PHRASE_REVEALED, + category: MetaMetricsEventCategory.Onboarding, + event: + MetaMetricsEventName.OnboardingWalletSecurityPhraseRevealed, }); setPhraseRevealed(true); }} diff --git a/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.js b/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.js index 475bcf7c2658..a5891c63a5a0 100644 --- a/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.js +++ b/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.js @@ -19,7 +19,10 @@ import { useI18nContext } from '../../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { ONBOARDING_REVIEW_SRP_ROUTE } from '../../../helpers/constants/routes'; import { getCurrentLocale } from '../../../ducks/locale/locale'; -import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import SkipSRPBackup from './skip-srp-backup-popover'; export default function SecureYourWallet() { @@ -38,16 +41,16 @@ export default function SecureYourWallet() { const handleClickRecommended = () => { trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_WALLET_SECURITY_STARTED, + category: MetaMetricsEventCategory.Onboarding, + event: MetaMetricsEventName.OnboardingWalletSecurityStarted, }); history.push(`${ONBOARDING_REVIEW_SRP_ROUTE}${isFromReminderParam}`); }; const handleClickNotRecommended = () => { trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_WALLET_SECURITY_SKIP_INITIATED, + category: MetaMetricsEventCategory.Onboarding, + event: MetaMetricsEventName.OnboardingWalletSecuritySkipInitiated, }); setShowSkipSRPBackupPopover(true); }; @@ -105,8 +108,8 @@ export default function SecureYourWallet() { className="secure-your-wallet__video" onPlay={() => { trackEvent({ - category: EVENT.CATEGORIES.ONBOARDING, - event: EVENT_NAMES.ONBOARDING_WALLET_VIDEO_PLAY, + category: MetaMetricsEventCategory.Onboarding, + event: MetaMetricsEventName.OnboardingWalletVideoPlay, }); }} controls diff --git a/ui/pages/onboarding-flow/secure-your-wallet/skip-srp-backup-popover.js b/ui/pages/onboarding-flow/secure-your-wallet/skip-srp-backup-popover.js index bd64f93474f7..9820949066e1 100644 --- a/ui/pages/onboarding-flow/secure-your-wallet/skip-srp-backup-popover.js +++ b/ui/pages/onboarding-flow/secure-your-wallet/skip-srp-backup-popover.js @@ -18,7 +18,10 @@ import { import { setSeedPhraseBackedUp } from '../../../store/actions'; import Checkbox from '../../../components/ui/check-box'; import { ONBOARDING_COMPLETION_ROUTE } from '../../../helpers/constants/routes'; -import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { Icon, @@ -45,8 +48,9 @@ export default function SkipSRPBackup({ handleClose }) {