From 0cb53f74f2cee22bbfbb866891f0d9987e8c40b2 Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Thu, 6 Apr 2023 15:14:11 +0000 Subject: [PATCH 01/25] Version v10.28.2 --- CHANGELOG.md | 5 ++++- package.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e2ed30bb..5ad912f33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.28.2] + ## [10.28.1] ### Changed - Fix release automation ([#18427](https://github.com/MetaMask/metamask-extension/pull/18427)) @@ -3643,7 +3645,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Uncategorized - Added the ability to restore accounts from seed words. -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.28.1...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.28.2...HEAD +[10.28.2]: https://github.com/MetaMask/metamask-extension/compare/v10.28.1...v10.28.2 [10.28.1]: https://github.com/MetaMask/metamask-extension/compare/v10.28.0...v10.28.1 [10.28.0]: https://github.com/MetaMask/metamask-extension/compare/v10.27.0...v10.28.0 [10.27.0]: https://github.com/MetaMask/metamask-extension/compare/v10.26.2...v10.27.0 diff --git a/package.json b/package.json index c0a26aa2b..787b6d747 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "10.28.1", + "version": "10.28.2", "private": true, "repository": { "type": "git", From 43d5bf152c213b8d0033c1cde1c4c311883e8ccd Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Thu, 6 Apr 2023 08:07:34 -0700 Subject: [PATCH 02/25] =?UTF-8?q?Fix=20switch-ethereum-chain=20handler=20b?= =?UTF-8?q?y=20passing=20configuration=20id=20to=20setA=E2=80=A6=20(#18483?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix switch-ethereum-chain handler by passing configuration id to setActiveNetwork * fix e2e test * Fix e2e tests * Update test/e2e/tests/switch-custom-network.spec.js Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> * Revert "Update test/e2e/tests/switch-custom-network.spec.js" This reverts commit be533ff7f25e1fd42e951d9b817b8438035ae256. --------- Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- .../handlers/switch-ethereum-chain.js | 2 +- test/e2e/tests/switch-custom-network.spec.js | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 test/e2e/tests/switch-custom-network.spec.js diff --git a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js index 935b9ec60..81c6887e0 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js @@ -115,7 +115,7 @@ async function switchEthereumChainHandler( ) { setProviderType(approvedRequestData.type); } else { - await setActiveNetwork(approvedRequestData); + await setActiveNetwork(approvedRequestData.id); } res.result = null; } catch (error) { diff --git a/test/e2e/tests/switch-custom-network.spec.js b/test/e2e/tests/switch-custom-network.spec.js new file mode 100644 index 000000000..9da4eedc1 --- /dev/null +++ b/test/e2e/tests/switch-custom-network.spec.js @@ -0,0 +1,102 @@ +const { strict: assert } = require('assert'); +const FixtureBuilder = require('../fixture-builder'); +const { convertToHexValue, withFixtures } = require('../helpers'); + +describe('Swtich ethereum chain', function () { + const ganacheOptions = { + accounts: [ + { + secretKey: + '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: convertToHexValue(25000000000000000000), + }, + ], + concurrent: { port: 8546, chainId: 1338, ganacheOptions2: {} }, + }; + + it('should successfully change the network in response to wallet_switchEthereumChain', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions, + title: this.test.title, + failOnConsoleError: false, + }, + async ({ driver }) => { + await driver.navigate(); + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + const windowHandles = await driver.getAllWindowHandles(); + const extension = windowHandles[0]; + + await driver.openNewPage('http://127.0.0.1:8080/'); + + await driver.clickElement({ + tag: 'button', + text: 'Add Localhost 8546', + }); + + await driver.waitUntilXWindowHandles(3); + + await driver.switchToWindowWithTitle( + 'MetaMask Notification', + windowHandles, + ); + + await driver.clickElement({ + tag: 'button', + text: 'Approve', + }); + + await driver.findElement({ + tag: 'h3', + text: 'Allow this site to switch the network?', + }); + + // Don't switch to network now, because we will click the 'Switch to Localhost 8546' button below + await driver.clickElement({ + tag: 'button', + text: 'Cancel', + }); + + await driver.waitUntilXWindowHandles(2); + + await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); + await driver.clickElement({ + tag: 'button', + text: 'Switch to Localhost 8546', + }); + + await driver.waitUntilXWindowHandles(3); + + await driver.switchToWindowWithTitle( + 'MetaMask Notification', + windowHandles, + ); + + await driver.clickElement({ + tag: 'button', + text: 'Switch network', + }); + + await driver.waitUntilXWindowHandles(2); + + await driver.switchToWindow(extension); + + const currentNetworkName = await driver.findElement({ + tag: 'span', + text: 'Localhost 8546', + }); + + assert.ok( + Boolean(currentNetworkName), + 'Failed to switch to custom network', + ); + }, + ); + }); +}); From 227af24483fffc15c179f6ef79dcb4b9ccba409b Mon Sep 17 00:00:00 2001 From: vthomas13 <10986371+vthomas13@users.noreply.github.com> Date: Thu, 6 Apr 2023 11:08:11 -0400 Subject: [PATCH 03/25] Bumping notification id's to 18 & 19 (#18460) Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> Co-authored-by: Dan J Miller --- app/_locales/de/messages.json | 6 --- app/_locales/el/messages.json | 6 --- app/_locales/en/messages.json | 21 ++++---- app/_locales/es/messages.json | 6 --- app/_locales/fr/messages.json | 6 --- app/_locales/hi/messages.json | 6 --- app/_locales/id/messages.json | 6 --- app/_locales/ja/messages.json | 6 --- app/_locales/ko/messages.json | 6 --- app/_locales/pt/messages.json | 6 --- app/_locales/ru/messages.json | 6 --- app/_locales/tl/messages.json | 6 --- app/_locales/tr/messages.json | 6 --- app/_locales/vi/messages.json | 6 --- app/_locales/zh_CN/messages.json | 6 --- shared/notifications/index.js | 48 +++++++++++-------- test/e2e/fixture-builder.js | 12 ++++- .../app/whats-new-popup/whats-new-popup.js | 12 +++-- ui/selectors/selectors.js | 6 ++- 19 files changed, 61 insertions(+), 122 deletions(-) diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index 3e07daae6..6f4cf6e25 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "Ethereum Merge ist da!" }, - "notifications17ActionText": { - "message": "Sicherheits- und Datenschutzeinstellungen anzeigen" - }, - "notifications17Title": { - "message": "Sicherheits- und Datenschutzeinstellungen" - }, "notifications1Description": { "message": "Mobile MetaMask-Anwender können jetzt Token in ihren mobilen Wallets swappen. Scannen Sie den QR-Code, um die mobile App zu erhalten und mit dem Swapping zu beginnen.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index e05037db0..50f603838 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "Η συγχώνευση στο Ethereum είναι εδώ!" }, - "notifications17ActionText": { - "message": "Εμφάνιση ρυθμίσεων Ασφάλειας & Απορρήτου" - }, - "notifications17Title": { - "message": "Ρυθμίσεις Ασφάλειας & Απορρήτου" - }, "notifications1Description": { "message": "Οι χρήστες του MetaMask Mobile μπορούν τώρα να ανταλλάξουν tokens μέσα στο κινητό τους πορτοφόλι. Σαρώστε τον κωδικό QR για να πάρετε την εφαρμογή για κινητά και να αρχίσετε να ανταλλάζετε.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 0288955e6..9846fad1c 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -2366,40 +2366,37 @@ "notifications15Title": { "message": "The Ethereum Merge is here!" }, - "notifications16ActionText": { + "notifications18ActionText": { "message": "Enable security alerts" }, - "notifications16DescriptionOne": { + "notifications18DescriptionOne": { "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": { + "notifications18DescriptionThree": { "message": "Always be sure to do your own due diligence before approving any requests.", "description": "Description of a notification in the 'See What's New' popup. Describes Opensea Security Provider feature." }, - "notifications16DescriptionTwo": { + "notifications18DescriptionTwo": { "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 security alerts" - }, - "notifications17ActionText": { + "notifications19ActionText": { "message": "Enable NFT autodetection" }, - "notifications17DescriptionOne": { + "notifications19DescriptionOne": { "message": "Two ways you can get started:", "description": "Description of a notification in the 'See What's New' popup. Describes NFT autodetection feature." }, - "notifications17DescriptionThree": { + "notifications19DescriptionThree": { "message": "We only support ERC-721 at the moment.", "description": "Description of a notification in the 'See What's New' popup. Describes NFT autodetection feature." }, - "notifications17DescriptionTwo": { + "notifications19DescriptionTwo": { "message": "Manually add your NFTs, or turn on NFT autodetection in Settings > Experimental.", "description": "Description of a notification in the 'See What's New' popup. Describes NFT autodetection feature." }, - "notifications17Title": { + "notifications19Title": { "message": "See your NFTs like never before" }, "notifications1Description": { diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 9fa598d90..3ff6332bc 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "¡La Fusión de Ethereum está aquí!" }, - "notifications17ActionText": { - "message": "Mostrar configuración de seguridad y privacidad" - }, - "notifications17Title": { - "message": "Configuración de Seguridad y privacidad" - }, "notifications1Description": { "message": "Los usuarios de la aplicación móvil de MetaMask ahora pueden canjear tokens en su cartera móvil. Escanee el código QR para obtener la aplicación móvil y comience a canjear.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index 904c3b7f1..90a701e7a 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "La fusion Ethereum est en marche !" }, - "notifications17ActionText": { - "message": "Afficher les paramètres de sécurité et de confidentialité" - }, - "notifications17Title": { - "message": "Paramètres de sécurité et de confidentialité" - }, "notifications1Description": { "message": "Les utilisateurs de MetaMask Mobile peuvent désormais échanger des jetons dans leur portefeuille mobile. Scannez le code QR pour obtenir l’application mobile et commencez à échanger.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index bb826f5ec..78cf97f61 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "इथेरियम मर्ज यहाँ है!" }, - "notifications17ActionText": { - "message": "सुरक्षा और गोपनीयता सेटिंग्स को दिखाएं" - }, - "notifications17Title": { - "message": "सुरक्षा और गोपनीयता सेटिंग्स" - }, "notifications1Description": { "message": "MetaMask Mobile उपयोगकर्ता अब अपने मोबाइल वॉलेट के अंदर टोकन स्वैप कर सकते हैं। मोबाइल ऐप प्राप्त करने के लिए QR कोड को स्कैन करें और स्वैप करना शुरू करें।", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 8df3e4908..9a6997cab 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "Penggabungan Ethereum telah tiba!" }, - "notifications17ActionText": { - "message": "Tampilkan pengaturan Keamanan & Privasi" - }, - "notifications17Title": { - "message": "Pengaturan Keamanan & Privasi" - }, "notifications1Description": { "message": "Pengguna MetaMask Mobile kini bisa menukar token di dalam dompet seluler mereka. Pindai kode QR untuk mendapatkan aplikasi seluler dan mulai menukar.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 0eec323b6..41796f382 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "Ethereum のマージ (Merge) が完了しました!" }, - "notifications17ActionText": { - "message": "セキュリティおよびプライバシー設定を表示" - }, - "notifications17Title": { - "message": "セキュリティおよびプライバシー設定" - }, "notifications1Description": { "message": "MetaMask Mobileのユーザーが、モバイルウォレット内でトークンを交換できるようになりました。QRコードをスキャンしてモバイルアプリを取得し、スワップを開始します。", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 0b0c9cf3d..f46b0ff36 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "이더리움 머지가 완료되었습니다!" }, - "notifications17ActionText": { - "message": "보안 및 개인정보 설정 표시" - }, - "notifications17Title": { - "message": "보안 및 개인정보 설정 표시" - }, "notifications1Description": { "message": "MetaMask 모바일 사용자는 이제 모바일 지갑에서 토큰을 스왑할 수 있습니다. QR 코드를 스캔하여 모바일 앱을 설치하고 스왑을 시작하세요.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index 58c17c518..5b73c1ab8 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "A fusão do Ethereum chegou!" }, - "notifications17ActionText": { - "message": "Mostrar configurações de segurança e privacidade" - }, - "notifications17Title": { - "message": "Configurações de segurança e privacidade" - }, "notifications1Description": { "message": "Usuários da MetaMask Mobile agora podem trocar tokens dentro de sua carteira mobile. Leia o QR code para obter o aplicativo para dispositivos móveis e comece a trocar.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 6e1f9e794..37f138a27 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "Ethereum Merge уже досутпно!" }, - "notifications17ActionText": { - "message": "Показать настройки безопасности и конфиденциальности" - }, - "notifications17Title": { - "message": "Настройки безопасности и конфиденциальности" - }, "notifications1Description": { "message": "Теперь пользователи MetaMask Mobile могут обменивать токены в своем мобильном кошельке. Отсканируйте QR-код, чтобы скачать мобильное приложение и начать обмен.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index 477ba8b5c..a6394c2ed 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "Narito na ang Ethereum Merge!" }, - "notifications17ActionText": { - "message": "Ipakita ang mga setting ng Seguridad at Pagkapribado" - }, - "notifications17Title": { - "message": "Mga Setting ng Seguridad at Pagkapribado" - }, "notifications1Description": { "message": "Ang mga user ng MetaMask Mobile ay maaari na ngayong mag-swap ng mga token sa loob ng kanilang mobile wallet. I-scan ang QR code para makuha ang mobile app at magsimulang mag-swap.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index 5f1c5b4f9..17114accc 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "Ethereum Birleşmesi başladı!" }, - "notifications17ActionText": { - "message": "Güvenlik ve Gizlilik ayarlarını göster" - }, - "notifications17Title": { - "message": "Güvenlik ve Gizlilik Ayarları" - }, "notifications1Description": { "message": "MetaMask Mobil kullanıcıları artık mobil cüzdanları içinde token takas edebilirler. Mobil uygulamayı edinmek ve takas yapmaya başlamak için QR kodunu tarayın.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index e72945347..a3acb4703 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "Hợp nhất Ethereum đã được triển khai!" }, - "notifications17ActionText": { - "message": "Hiển thị cài đặt Bảo mật và Quyền riêng tư" - }, - "notifications17Title": { - "message": "Cài đặt Bảo mật và Quyền riêng tư" - }, "notifications1Description": { "message": "Giờ đây, người dùng MetaMask trên điện thoại di động có thể hoán đổi token trong ví di động của họ. Quét mã QR để tải ứng dụng di động và bắt đầu hoán đổi.", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index 63f207f8f..b6b057c41 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -2336,12 +2336,6 @@ "notifications15Title": { "message": "以太坊合并来了!" }, - "notifications17ActionText": { - "message": "显示安全和隐私设置" - }, - "notifications17Title": { - "message": "安全和隐私设置" - }, "notifications1Description": { "message": "MetaMask Mobile 用户现在可以在他们的移动钱包中交换代币。扫描二维码以获取移动应用程序并开始交换。", "description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature." diff --git a/shared/notifications/index.js b/shared/notifications/index.js index f1a5ff738..10c24bbfe 100644 --- a/shared/notifications/index.js +++ b/shared/notifications/index.js @@ -81,13 +81,21 @@ export const UI_NOTIFICATIONS = { 16: { id: 16, date: null, + }, + 17: { + id: 17, + date: null, + }, + 18: { + id: 18, + date: null, image: { src: 'images/open-sea-security-provider.svg', width: '100%', }, }, - 17: { - id: 17, + 19: { + id: 19, date: null, image: { src: 'images/nfts.svg', @@ -240,34 +248,34 @@ export const getTranslatedUINotifications = (t, locale) => { ) : '', }, - 16: { - ...UI_NOTIFICATIONS[16], - title: t('notifications16Title'), + 18: { + ...UI_NOTIFICATIONS[18], + title: t('notifications18Title'), description: [ - t('notifications16DescriptionOne'), - t('notifications16DescriptionTwo'), - t('notifications16DescriptionThree'), + t('notifications18DescriptionOne'), + t('notifications18DescriptionTwo'), + t('notifications18DescriptionThree'), ], - actionText: t('notifications16ActionText'), - date: UI_NOTIFICATIONS[16].date + actionText: t('notifications18ActionText'), + date: UI_NOTIFICATIONS[18].date ? new Intl.DateTimeFormat(formattedLocale).format( - new Date(UI_NOTIFICATIONS[16].date), + new Date(UI_NOTIFICATIONS[18].date), ) : '', }, - 17: { - ...UI_NOTIFICATIONS[17], - title: t('notifications17Title'), + 19: { + ...UI_NOTIFICATIONS[19], + title: t('notifications19Title'), description: [ - t('notifications17DescriptionOne'), - t('notifications17DescriptionTwo'), - t('notifications17DescriptionThree'), + t('notifications19DescriptionOne'), + t('notifications19DescriptionTwo'), + t('notifications19DescriptionThree'), ], - actionText: t('notifications17ActionText'), - date: UI_NOTIFICATIONS[17].date + actionText: t('notifications19ActionText'), + date: UI_NOTIFICATIONS[19].date ? new Intl.DateTimeFormat(formattedLocale).format( - new Date(UI_NOTIFICATIONS[17].date), + new Date(UI_NOTIFICATIONS[19].date), ) : '', }, diff --git a/test/e2e/fixture-builder.js b/test/e2e/fixture-builder.js index 7661a726c..5771feb0c 100644 --- a/test/e2e/fixture-builder.js +++ b/test/e2e/fixture-builder.js @@ -114,11 +114,21 @@ function defaultFixture() { 16: { date: null, id: 16, - isShown: true, + isShown: false, }, 17: { date: null, id: 17, + isShown: false, + }, + 18: { + date: null, + id: 18, + isShown: true, + }, + 19: { + date: null, + id: 19, isShown: true, }, }, diff --git a/ui/components/app/whats-new-popup/whats-new-popup.js b/ui/components/app/whats-new-popup/whats-new-popup.js index 7d644a372..98c636e50 100644 --- a/ui/components/app/whats-new-popup/whats-new-popup.js +++ b/ui/components/app/whats-new-popup/whats-new-popup.js @@ -61,10 +61,16 @@ function getActionFunctionById(id, history) { }, 16: () => { updateViewedNotifications({ 16: true }); - history.push(`${EXPERIMENTAL_ROUTE}#transaction-security-check`); }, 17: () => { updateViewedNotifications({ 17: true }); + }, + 18: () => { + updateViewedNotifications({ 18: true }); + history.push(`${EXPERIMENTAL_ROUTE}#transaction-security-check`); + }, + 19: () => { + updateViewedNotifications({ 19: true }); history.push(`${EXPERIMENTAL_ROUTE}#autodetect-nfts`); }, }; @@ -266,8 +272,8 @@ export default function WhatsNewPopup({ onClose }) { const notification = getTranslatedUINotifications(t, locale)[id]; const isLast = index === notifications.length - 1; // Display the swaps notification with full image - // Displays the NFTs & OpenSea notifications 16,17 with full image - return index === 0 || id === 1 || id === 16 || id === 17 + // Displays the NFTs & OpenSea notifications 18,19 with full image + return index === 0 || id === 1 || id === 18 || id === 19 ? renderFirstNotification(notification, idRefMap, history, isLast) : renderSubsequentNotification( notification, diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index d3900e0a8..d374cd6e1 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -963,8 +963,10 @@ function getAllowedAnnouncementIds(state) { 13: false, 14: false, 15: false, - 16: true, - 17: true, + 16: false, + 17: false, + 18: true, + 19: true, }; } From d8e79188a55f4e7f118b752a8f0a57db33777600 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Thu, 6 Apr 2023 10:19:42 -0700 Subject: [PATCH 04/25] Fix locale file issues on chrome store (#18487) --- app/_locales/hi/messages.json | 4 ++-- app/_locales/ja/messages.json | 4 ++-- app/_locales/tr/messages.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index 78cf97f61..500bc48fc 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -1604,11 +1604,11 @@ "description": "Is the bolded text in 'holdToRevealContent1'" }, "holdToRevealContent3": { - "message": "इसे किसी के साथ साझा न करें। $1$2", + "message": "इसे किसी के साथ साझा न करें। $1,$2", "description": "$1 is a message from 'holdToRevealContent4' and $2 is a text link with the message from 'holdToRevealContent5'" }, "holdToRevealContent4": { - "message": "MetaMask सपोर्ट इसका अनुरोध नहीं करेगा,", + "message": "MetaMask सपोर्ट इसका अनुरोध नहीं करेगा", "description": "Part of 'holdToRevealContent3'" }, "holdToRevealContent5": { diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 41796f382..6e1a716a9 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -1604,11 +1604,11 @@ "description": "Is the bolded text in 'holdToRevealContent1'" }, "holdToRevealContent3": { - "message": "これは誰にも教えないでください。$1$2", + "message": "これは誰にも教えないでください。$1、$2", "description": "$1 is a message from 'holdToRevealContent4' and $2 is a text link with the message from 'holdToRevealContent5'" }, "holdToRevealContent4": { - "message": "MetaMask サポートがこの情報を尋ねることはなく、", + "message": "MetaMask サポートがこの情報を尋ねることはなく", "description": "Part of 'holdToRevealContent3'" }, "holdToRevealContent5": { diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index 17114accc..f8a4b63cd 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -1596,7 +1596,7 @@ "message": "GKİ'yi göstermek için basılı tut" }, "holdToRevealContent1": { - "message": "Gizli Kurtarma İfadeniz: $1$", + "message": "Gizli Kurtarma İfadeniz: $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" }, "holdToRevealContent2": { From afc7ec3a6a107c94268985d4b2b539ec257739e1 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Thu, 6 Apr 2023 15:18:17 -0230 Subject: [PATCH 05/25] Update change log --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ad912f33..cdec2e759 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ## [10.28.2] +### Fixed +- Fix network switching prompted by dapps by fixing the `wallet_switchEthereumChain` handler. ([#18483](https://github.com/MetaMask/metamask-extension/pull/18483)) +- Fix to ensure all users see the NFT and transaction security notifications ([#18460](https://github.com/MetaMask/metamask-extension/pull/18460)) +- Fix issue blocking Hindi, Japanese and Turkish language users from installing from the Chrome store ([#18487](https://github.com/MetaMask/metamask-extension/pull/18487)) ## [10.28.1] ### Changed From 2cc41c9bb85559ea872b8eafd4d1774a2ff660de Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Tue, 11 Apr 2023 19:23:04 +0000 Subject: [PATCH 06/25] Version v10.28.3 --- CHANGELOG.md | 5 ++++- package.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cdec2e759..a7423ec0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.28.3] + ## [10.28.2] ### Fixed - Fix network switching prompted by dapps by fixing the `wallet_switchEthereumChain` handler. ([#18483](https://github.com/MetaMask/metamask-extension/pull/18483)) @@ -3649,7 +3651,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Uncategorized - Added the ability to restore accounts from seed words. -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.28.2...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.28.3...HEAD +[10.28.3]: https://github.com/MetaMask/metamask-extension/compare/v10.28.2...v10.28.3 [10.28.2]: https://github.com/MetaMask/metamask-extension/compare/v10.28.1...v10.28.2 [10.28.1]: https://github.com/MetaMask/metamask-extension/compare/v10.28.0...v10.28.1 [10.28.0]: https://github.com/MetaMask/metamask-extension/compare/v10.27.0...v10.28.0 diff --git a/package.json b/package.json index 787b6d747..df2bfa370 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "10.28.2", + "version": "10.28.3", "private": true, "repository": { "type": "git", From 6a14f12c760907e6329da66c7853a10c2295ccd8 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Tue, 11 Apr 2023 16:46:31 -0230 Subject: [PATCH 07/25] Ensure that all networkConfiguration object in networkController state have an id (#18513) * Ensure that all networkConfiguration object in networkController state have an id * Lint fix * Update app/scripts/migrations/084.ts Co-authored-by: Mark Stacey * Add unit tests for error cases * Simplify code * Remove unnecessary any typing * Fix network controller type checking * Lint fix * Improve typing --------- Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> Co-authored-by: Mark Stacey --- app/scripts/migrations/083.test.js | 254 +++++++++++++++++++++++++++++ app/scripts/migrations/083.ts | 58 +++++++ app/scripts/migrations/index.js | 2 + 3 files changed, 314 insertions(+) create mode 100644 app/scripts/migrations/083.test.js create mode 100644 app/scripts/migrations/083.ts diff --git a/app/scripts/migrations/083.test.js b/app/scripts/migrations/083.test.js new file mode 100644 index 000000000..c59951aef --- /dev/null +++ b/app/scripts/migrations/083.test.js @@ -0,0 +1,254 @@ +import { v4 } from 'uuid'; +import { migrate, version } from './083'; + +jest.mock('uuid', () => { + const actual = jest.requireActual('uuid'); + + return { + ...actual, + v4: jest.fn(), + }; +}); + +describe('migration #83', () => { + beforeEach(() => { + v4.mockImplementationOnce(() => 'network-configuration-id-1') + .mockImplementationOnce(() => 'network-configuration-id-2') + .mockImplementationOnce(() => 'network-configuration-id-3') + .mockImplementationOnce(() => 'network-configuration-id-4'); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + it('should update the version metadata', async () => { + const oldStorage = { + meta: { + version: 82, + }, + data: {}, + }; + + const newStorage = await migrate(oldStorage); + expect(newStorage.meta).toStrictEqual({ + version, + }); + }); + + it('should use the key of the networkConfigurations object to set the id of each network configuration', async () => { + const oldStorage = { + meta: { + version, + }, + data: { + NetworkController: { + networkConfigurations: { + 'network-configuration-id-1': { + chainId: '0x539', + nickname: 'Localhost 8545', + rpcPrefs: {}, + rpcUrl: 'http://localhost:8545', + ticker: 'ETH', + }, + 'network-configuration-id-2': { + chainId: '0xa4b1', + nickname: 'Arbitrum One', + rpcPrefs: { + blockExplorerUrl: 'https://explorer.arbitrum.io', + }, + rpcUrl: + 'https://arbitrum-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', + ticker: 'ETH', + }, + 'network-configuration-id-3': { + chainId: '0x4e454152', + nickname: 'Aurora Mainnet', + rpcPrefs: { + blockExplorerUrl: 'https://aurorascan.dev/', + }, + rpcUrl: + 'https://aurora-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', + ticker: 'Aurora ETH', + }, + 'network-configuration-id-4': { + chainId: '0x38', + nickname: + 'BNB Smart Chain (previously Binance Smart Chain Mainnet)', + rpcPrefs: { + blockExplorerUrl: 'https://bscscan.com/', + }, + rpcUrl: 'https://bsc-dataseed.binance.org/', + ticker: 'BNB', + }, + }, + }, + }, + }; + + const newStorage = await migrate(oldStorage); + + const expectedNewStorage = { + meta: { + version, + }, + data: { + NetworkController: { + networkConfigurations: { + 'network-configuration-id-1': { + chainId: '0x539', + nickname: 'Localhost 8545', + rpcPrefs: {}, + rpcUrl: 'http://localhost:8545', + ticker: 'ETH', + id: 'network-configuration-id-1', + }, + 'network-configuration-id-2': { + chainId: '0xa4b1', + nickname: 'Arbitrum One', + rpcPrefs: { + blockExplorerUrl: 'https://explorer.arbitrum.io', + }, + rpcUrl: + 'https://arbitrum-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', + ticker: 'ETH', + id: 'network-configuration-id-2', + }, + 'network-configuration-id-3': { + chainId: '0x4e454152', + nickname: 'Aurora Mainnet', + rpcPrefs: { + blockExplorerUrl: 'https://aurorascan.dev/', + }, + rpcUrl: + 'https://aurora-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', + ticker: 'Aurora ETH', + id: 'network-configuration-id-3', + }, + 'network-configuration-id-4': { + chainId: '0x38', + nickname: + 'BNB Smart Chain (previously Binance Smart Chain Mainnet)', + rpcPrefs: { + blockExplorerUrl: 'https://bscscan.com/', + }, + rpcUrl: 'https://bsc-dataseed.binance.org/', + ticker: 'BNB', + id: 'network-configuration-id-4', + }, + }, + }, + }, + }; + expect(newStorage).toStrictEqual(expectedNewStorage); + }); + + it('should not modify state if state.NetworkController is undefined', async () => { + const oldStorage = { + meta: { + version, + }, + data: { + testProperty: 'testValue', + }, + }; + + const newStorage = await migrate(oldStorage); + + const expectedNewStorage = { + meta: { + version, + }, + data: { + testProperty: 'testValue', + }, + }; + expect(newStorage).toStrictEqual(expectedNewStorage); + }); + + it('should not modify state if state.NetworkController is not an object', async () => { + const oldStorage = { + meta: { + version, + }, + data: { + NetworkController: false, + testProperty: 'testValue', + }, + }; + + const newStorage = await migrate(oldStorage); + + const expectedNewStorage = { + meta: { + version, + }, + data: { + NetworkController: false, + testProperty: 'testValue', + }, + }; + expect(newStorage).toStrictEqual(expectedNewStorage); + }); + + it('should not modify state if state.NetworkController.networkConfigurations is undefined', async () => { + const oldStorage = { + meta: { + version, + }, + data: { + NetworkController: { + testNetworkControllerProperty: 'testNetworkControllerValue', + networkConfigurations: undefined, + }, + testProperty: 'testValue', + }, + }; + + const newStorage = await migrate(oldStorage); + + const expectedNewStorage = { + meta: { + version, + }, + data: { + NetworkController: { + testNetworkControllerProperty: 'testNetworkControllerValue', + networkConfigurations: undefined, + }, + testProperty: 'testValue', + }, + }; + expect(newStorage).toStrictEqual(expectedNewStorage); + }); + + it('should not modify state if state.NetworkController.networkConfigurations is an empty object', async () => { + const oldStorage = { + meta: { + version, + }, + data: { + NetworkController: { + testNetworkControllerProperty: 'testNetworkControllerValue', + networkConfigurations: {}, + }, + testProperty: 'testValue', + }, + }; + + const newStorage = await migrate(oldStorage); + + const expectedNewStorage = { + meta: { + version, + }, + data: { + NetworkController: { + testNetworkControllerProperty: 'testNetworkControllerValue', + networkConfigurations: {}, + }, + testProperty: 'testValue', + }, + }; + expect(newStorage).toStrictEqual(expectedNewStorage); + }); +}); diff --git a/app/scripts/migrations/083.ts b/app/scripts/migrations/083.ts new file mode 100644 index 000000000..cc3e3b16b --- /dev/null +++ b/app/scripts/migrations/083.ts @@ -0,0 +1,58 @@ +import { cloneDeep } from 'lodash'; +import { isObject } from '@metamask/utils'; + +export const version = 83; + +/** + * Ensure that each networkConfigurations object in state.NetworkController.networkConfigurations has an + * `id` property which matches the key pointing that object + * + * @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist. + * @param originalVersionedData.meta - State metadata. + * @param originalVersionedData.meta.version - The current state version. + * @param originalVersionedData.data - The persisted MetaMask state, keyed by controller. + * @returns Updated versioned MetaMask extension state. + */ +export async function migrate(originalVersionedData: { + meta: { version: number }; + data: Record; +}) { + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + versionedData.data = transformState(versionedData.data); + return versionedData; +} + +function transformState(state: Record) { + if (!isObject(state.NetworkController)) { + return state; + } + const { NetworkController } = state; + + if (!isObject(NetworkController.networkConfigurations)) { + return state; + } + + const { networkConfigurations } = NetworkController; + + const newNetworkConfigurations: Record> = {}; + + for (const networkConfigurationId of Object.keys(networkConfigurations)) { + const networkConfiguration = networkConfigurations[networkConfigurationId]; + if (!isObject(networkConfiguration)) { + return state; + } + newNetworkConfigurations[networkConfigurationId] = { + ...networkConfiguration, + id: networkConfigurationId, + }; + } + + return { + ...state, + NetworkController: { + ...NetworkController, + networkConfigurations: newNetworkConfigurations, + }, + }; +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index fdd29924c..c3f8e515f 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -86,6 +86,7 @@ import m079 from './079'; import m080 from './080'; import * as m081 from './081'; import * as m082 from './082'; +import * as m083 from './083'; const migrations = [ m002, @@ -169,6 +170,7 @@ const migrations = [ m080, m081, m082, + m083, ]; export default migrations; From 8220051390650845b934dcff98769102545042c0 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Tue, 11 Apr 2023 17:49:08 -0230 Subject: [PATCH 08/25] Fix changelog for v10.28.3 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7423ec0a..1be32abe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ## [10.28.3] +### Fixed +- Fix network switching prompted by dapps for users that added the network prior to v10.28.0. ([#18513](https://github.com/MetaMask/metamask-extension/pull/18513)) ## [10.28.2] ### Fixed From 0ef26802946de22456086a1902515399ff488f00 Mon Sep 17 00:00:00 2001 From: legobeat <109787230+legobeat@users.noreply.github.com> Date: Sun, 9 Apr 2023 10:42:45 +0900 Subject: [PATCH 09/25] deps/security: vm2@3.9.11->3.9.15 (#18512) Fixes CVE-2023-29017 / GHSA-7jxr-cg7f-gpgv --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c770a116f..82cfd53d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34506,14 +34506,14 @@ __metadata: linkType: hard "vm2@npm:^3.9.3": - version: 3.9.11 - resolution: "vm2@npm:3.9.11" + version: 3.9.15 + resolution: "vm2@npm:3.9.15" dependencies: acorn: ^8.7.0 acorn-walk: ^8.2.0 bin: vm2: bin/vm2 - checksum: aab39e6e4b59146d24abacd79f490e854a6e058a8b23d93d2be5aca7720778e2605d2cc028ccc4a5f50d3d91b0c38be9a6247a80d2da1a6de09425cc437770b4 + checksum: 1df70d5a88173651c0062901aba67e5edfeeb3f699fe6c305f5efb6a5a7391e5724cbf98a6516600b65016c6824dc07cc79947ea4222f8537ae1d9ce0b730ad7 languageName: node linkType: hard From 52e91058a0a91954eac07e893073b99d97041565 Mon Sep 17 00:00:00 2001 From: "sumit shinde ( Roni )" <110285294+sumitshinde-84@users.noreply.github.com> Date: Wed, 19 Apr 2023 14:33:29 +0530 Subject: [PATCH 10/25] knob to control (#18635) * knob to control * Update confirm-add-suggested-token.stories.js * fix eslint * Update ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.stories.js Co-authored-by: George Marshall * Update ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.stories.js Co-authored-by: George Marshall * Update ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.stories.js Co-authored-by: George Marshall * Update ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.stories.js Co-authored-by: George Marshall * Update confirm-add-suggested-token.stories.js * updaes * Updating to use redux provider * lint fix --------- Co-authored-by: George Marshall Co-authored-by: georgewrmarshall --- .../approval-screens/add-suggested-token.js | 88 +++++----- .storybook/test-data.js | 4 +- .../confirm-add-suggested-token.stories.js | 150 +++++++----------- 3 files changed, 100 insertions(+), 142 deletions(-) diff --git a/.storybook/initial-states/approval-screens/add-suggested-token.js b/.storybook/initial-states/approval-screens/add-suggested-token.js index 5cd10451c..d8218a2ce 100644 --- a/.storybook/initial-states/approval-screens/add-suggested-token.js +++ b/.storybook/initial-states/approval-screens/add-suggested-token.js @@ -2,82 +2,82 @@ export const suggestedAssets = [ { asset: { address: '0x6b175474e89094c44da98b954eedeac495271d0f', - symbol: 'META', + symbol: 'ETH', decimals: 18, - image: 'metamark.svg', - unlisted: false + image: './images/eth_logo.svg', + unlisted: false, }, }, { asset: { - 'address': '0xB8c77482e45F1F44dE1745F52C74426C631bDD52', - 'symbol': '0X', - 'decimals': 18, - 'image': '0x.svg', - 'unlisted': false + address: '0xB8c77482e45F1F44dE1745F52C74426C631bDD52', + symbol: '0X', + decimals: 18, + image: '0x.svg', + unlisted: false, }, }, { asset: { - 'address': '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', - 'symbol': 'AST', - 'decimals': 18, - 'image': 'ast.png', - 'unlisted': false + address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', + symbol: 'AST', + decimals: 18, + image: 'ast.png', + unlisted: false, }, }, { asset: { - 'address': '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', - 'symbol': 'BAT', - 'decimals': 18, - 'image': 'BAT_icon.svg', - 'unlisted': false + address: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', + symbol: 'BAT', + decimals: 18, + image: 'BAT_icon.svg', + unlisted: false, }, }, { asset: { - 'address': '0xe83cccfabd4ed148903bf36d4283ee7c8b3494d1', - 'symbol': 'CVL', - 'decimals': 18, - 'image': 'CVL_token.svg', - 'unlisted': false + address: '0xe83cccfabd4ed148903bf36d4283ee7c8b3494d1', + symbol: 'CVL', + decimals: 18, + image: 'CVL_token.svg', + unlisted: false, }, }, { asset: { - 'address': '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e', - 'symbol': 'GLA', - 'decimals': 18, - 'image': 'gladius.svg', - 'unlisted': false + address: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e', + symbol: 'GLA', + decimals: 18, + image: 'gladius.svg', + unlisted: false, }, }, { asset: { - 'address': '0x467Bccd9d29f223BcE8043b84E8C8B282827790F', - 'symbol': 'GNO', - 'decimals': 18, - 'image': 'gnosis.svg', - 'unlisted': false + address: '0x467Bccd9d29f223BcE8043b84E8C8B282827790F', + symbol: 'GNO', + decimals: 18, + image: 'gnosis.svg', + unlisted: false, }, }, { asset: { - 'address': '0xff20817765cb7f73d4bde2e66e067e58d11095c2', - 'symbol': 'OMG', - 'decimals': 18, - 'image': 'omg.jpg', - 'unlisted': false + address: '0xff20817765cb7f73d4bde2e66e067e58d11095c2', + symbol: 'OMG', + decimals: 18, + image: 'omg.jpg', + unlisted: false, }, }, { asset: { - 'address': '0x8e870d67f660d95d5be530380d0ec0bd388289e1', - 'symbol': 'WED', - 'decimals': 18, - 'image': 'wed.png', - 'unlisted': false + address: '0x8e870d67f660d95d5be530380d0ec0bd388289e1', + symbol: 'WED', + decimals: 18, + image: 'wed.png', + unlisted: false, }, }, -] +]; diff --git a/.storybook/test-data.js b/.storybook/test-data.js index 23c88c485..22ec45e2a 100644 --- a/.storybook/test-data.js +++ b/.storybook/test-data.js @@ -172,9 +172,9 @@ const state = { }, '0x6b175474e89094c44da98b954eedeac495271d0f': { address: '0x6b175474e89094c44da98b954eedeac495271d0f', - symbol: 'META', + symbol: 'ETH', decimals: 18, - image: 'metamark.svg', + image: './images/eth_logo.svg', unlisted: false, }, '0xB8c77482e45F1F44dE1745F52C74426C631bDD52': { diff --git a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.stories.js b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.stories.js index c1f7d9558..ea1947804 100644 --- a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.stories.js +++ b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.stories.js @@ -1,107 +1,65 @@ /* eslint-disable react/prop-types */ -import React, { useEffect } from 'react'; -import { text } from '@storybook/addon-knobs'; -import { store, getNewState } from '../../../.storybook/preview'; +import React from 'react'; +import { Provider } from 'react-redux'; import { suggestedAssets as mockSuggestedAssets } from '../../../.storybook/initial-states/approval-screens/add-suggested-token'; -import { updateMetamaskState } from '../../store/actions'; + +import configureStore from '../../store/store'; + +import mockState from '../../../.storybook/test-data'; + import ConfirmAddSuggestedToken from '.'; +const store = configureStore({ + metamask: { + ...mockState.metamask, + suggestedAssets: [...mockSuggestedAssets], + tokens: [], + }, +}); + export default { title: 'Pages/ConfirmAddSuggestedToken', - - argTypes: { - tokens: { - control: 'array', - table: { category: 'Data' }, - }, - suggestedAssets: { - control: 'array', - table: { category: 'Data' }, - }, - }, + decorators: [(story) => {story()}], }; -const { metamask: state } = store.getState(); - -const PageSet = ({ children, suggestedAssets, tokens }) => { - const symbol = text('symbol', 'META'); - const image = text('Icon URL', 'metamark.svg'); - - useEffect(() => { - if (!suggestedAssets?.length) { - return; - } - - suggestedAssets[0].asset.image = image; - suggestedAssets[0].asset.symbol = symbol; - - store.dispatch( - updateMetamaskState( - getNewState(state, { - suggestedAssets, - }), - ), - ); - }, [image, suggestedAssets, symbol]); - - useEffect(() => { - store.dispatch( - updateMetamaskState( - getNewState(state, { - tokens, - }), - ), - ); - }, [tokens]); - - return children; -}; - -export const DefaultStory = ({ suggestedAssets, tokens }) => { - return ( - - - - ); -}; +export const DefaultStory = () => ; DefaultStory.storyName = 'Default'; -DefaultStory.args = { - suggestedAssets: [...mockSuggestedAssets], - tokens: [], -}; -export const WithDuplicateAddress = ({ suggestedAssets, tokens }) => { - return ( - - - - ); -}; -WithDuplicateAddress.args = { - suggestedAssets: [...mockSuggestedAssets], - tokens: [ - { - ...mockSuggestedAssets[0].asset, - }, - ], -}; +export const WithDuplicateAddress = () => ; +const WithDuplicateAddressStore = configureStore({ + metamask: { + ...mockState.metamask, + suggestedAssets: [...mockSuggestedAssets], + tokens: [ + { + ...mockSuggestedAssets[0].asset, + }, + ], + }, +}); +WithDuplicateAddress.decorators = [ + (story) => {story()}, +]; -export const WithDuplicateSymbolAndDifferentAddress = ({ - suggestedAssets, - tokens, -}) => { - return ( - - - - ); -}; -WithDuplicateSymbolAndDifferentAddress.args = { - suggestedAssets: [...mockSuggestedAssets], - tokens: [ - { - ...mockSuggestedAssets[0].asset, - address: '0xNonSuggestedAddress', - }, - ], -}; +export const WithDuplicateSymbolAndDifferentAddress = () => ( + +); +const WithDuplicateSymbolAndDifferentAddressStore = configureStore({ + metamask: { + ...mockState.metamask, + suggestedAssets: [...mockSuggestedAssets], + tokens: [ + { + ...mockSuggestedAssets[0].asset, + address: '0xNonSuggestedAddress', + }, + ], + }, +}); +WithDuplicateSymbolAndDifferentAddress.decorators = [ + (story) => ( + + {story()} + + ), +]; From 1cc709af41268c12a256e0c0d6eb553b8e5ec65c Mon Sep 17 00:00:00 2001 From: Peter <53189696+PeterYinusa@users.noreply.github.com> Date: Wed, 19 Apr 2023 13:36:24 +0100 Subject: [PATCH 11/25] wait for gas estimate to update (#18658) --- test/e2e/tests/send-eth.spec.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/e2e/tests/send-eth.spec.js b/test/e2e/tests/send-eth.spec.js index d287184c3..fbc84854b 100644 --- a/test/e2e/tests/send-eth.spec.js +++ b/test/e2e/tests/send-eth.spec.js @@ -1,6 +1,6 @@ const { strict: assert } = require('assert'); const { SMART_CONTRACTS } = require('../seeder/smart-contracts'); -const { convertToHexValue, withFixtures, tinyDelayMs } = require('../helpers'); +const { convertToHexValue, withFixtures } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); describe('Send ETH from inside MetaMask using default gas', function () { @@ -334,7 +334,15 @@ describe('Send ETH from dapp using advanced gas controls', function () { await priorityFeeInput.fill('1'); await driver.clickElement({ text: 'Save', tag: 'button' }); - await driver.delay(tinyDelayMs); + await driver.waitForSelector({ + css: '.transaction-detail-item:nth-of-type(1) h6:nth-of-type(2)', + text: '0.02367237 ETH', + }); + await driver.waitForSelector({ + css: '.transaction-detail-item:nth-of-type(2) h6:nth-of-type(2)', + text: '0.02367237 ETH', + }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); await driver.waitUntilXWindowHandles(2); await driver.switchToWindow(extension); From 7bc13e90f8bbf81456ba0e1068968340595010ee Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Wed, 19 Apr 2023 11:38:16 -0230 Subject: [PATCH 12/25] Rename migration 83 to 84 and rename migration 84 to 83 (#18655) Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- app/scripts/migrations/083.test.js | 349 +++++++++++++++++++++-------- app/scripts/migrations/083.ts | 45 ++-- app/scripts/migrations/084.test.js | 285 ++++++----------------- app/scripts/migrations/084.ts | 45 ++-- 4 files changed, 362 insertions(+), 362 deletions(-) diff --git a/app/scripts/migrations/083.test.js b/app/scripts/migrations/083.test.js index 6e0f58998..c59951aef 100644 --- a/app/scripts/migrations/083.test.js +++ b/app/scripts/migrations/083.test.js @@ -1,103 +1,254 @@ -import { migrate } from './083'; +import { v4 } from 'uuid'; +import { migrate, version } from './083'; -describe('migration #83', () => { - it('updates the version metadata', async () => { - const originalVersionedData = buildOriginalVersionedData({ - meta: { - version: 9999999, - }, - }); +jest.mock('uuid', () => { + const actual = jest.requireActual('uuid'); - const newVersionedData = await migrate(originalVersionedData); - - expect(newVersionedData.meta).toStrictEqual({ - version: 83, - }); - }); - - it('does not change the state if the network controller state does not exist', async () => { - const originalVersionedData = buildOriginalVersionedData({ - data: { - test: '123', - }, - }); - - const newVersionedData = await migrate(originalVersionedData); - - expect(newVersionedData.data).toStrictEqual(originalVersionedData.data); - }); - - const nonObjects = [undefined, null, 'test', 1, ['test']]; - for (const invalidState of nonObjects) { - it(`does not change the state if the network controller state is ${invalidState}`, async () => { - const originalVersionedData = buildOriginalVersionedData({ - data: { - NetworkController: invalidState, - }, - }); - - const newVersionedData = await migrate(originalVersionedData); - - expect(newVersionedData.data).toStrictEqual(originalVersionedData.data); - }); - } - - it('does not change the state if the network controller state does not include "network"', async () => { - const originalVersionedData = buildOriginalVersionedData({ - data: { - NetworkController: { - test: '123', - }, - }, - }); - - const newVersionedData = await migrate(originalVersionedData); - - expect(newVersionedData.data).toStrictEqual(originalVersionedData.data); - }); - - it('replaces "network" in the network controller state with "networkId": null, "networkStatus": "unknown" if it is "loading"', async () => { - const originalVersionedData = buildOriginalVersionedData({ - data: { - NetworkController: { - network: 'loading', - }, - }, - }); - - const newVersionedData = await migrate(originalVersionedData); - - expect(newVersionedData.data).toStrictEqual({ - NetworkController: { - networkId: null, - networkStatus: 'unknown', - }, - }); - }); - - it('replaces "network" in the network controller state with "networkId": network, "networkStatus": "available" if it is not "loading"', async () => { - const originalVersionedData = buildOriginalVersionedData({ - data: { - NetworkController: { - network: '12345', - }, - }, - }); - - const newVersionedData = await migrate(originalVersionedData); - - expect(newVersionedData.data).toStrictEqual({ - NetworkController: { - networkId: '12345', - networkStatus: 'available', - }, - }); - }); + return { + ...actual, + v4: jest.fn(), + }; }); -function buildOriginalVersionedData({ meta = {}, data = {} } = {}) { - return { - meta: { version: 999999, ...meta }, - data: { ...data }, - }; -} +describe('migration #83', () => { + beforeEach(() => { + v4.mockImplementationOnce(() => 'network-configuration-id-1') + .mockImplementationOnce(() => 'network-configuration-id-2') + .mockImplementationOnce(() => 'network-configuration-id-3') + .mockImplementationOnce(() => 'network-configuration-id-4'); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + it('should update the version metadata', async () => { + const oldStorage = { + meta: { + version: 82, + }, + data: {}, + }; + + const newStorage = await migrate(oldStorage); + expect(newStorage.meta).toStrictEqual({ + version, + }); + }); + + it('should use the key of the networkConfigurations object to set the id of each network configuration', async () => { + const oldStorage = { + meta: { + version, + }, + data: { + NetworkController: { + networkConfigurations: { + 'network-configuration-id-1': { + chainId: '0x539', + nickname: 'Localhost 8545', + rpcPrefs: {}, + rpcUrl: 'http://localhost:8545', + ticker: 'ETH', + }, + 'network-configuration-id-2': { + chainId: '0xa4b1', + nickname: 'Arbitrum One', + rpcPrefs: { + blockExplorerUrl: 'https://explorer.arbitrum.io', + }, + rpcUrl: + 'https://arbitrum-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', + ticker: 'ETH', + }, + 'network-configuration-id-3': { + chainId: '0x4e454152', + nickname: 'Aurora Mainnet', + rpcPrefs: { + blockExplorerUrl: 'https://aurorascan.dev/', + }, + rpcUrl: + 'https://aurora-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', + ticker: 'Aurora ETH', + }, + 'network-configuration-id-4': { + chainId: '0x38', + nickname: + 'BNB Smart Chain (previously Binance Smart Chain Mainnet)', + rpcPrefs: { + blockExplorerUrl: 'https://bscscan.com/', + }, + rpcUrl: 'https://bsc-dataseed.binance.org/', + ticker: 'BNB', + }, + }, + }, + }, + }; + + const newStorage = await migrate(oldStorage); + + const expectedNewStorage = { + meta: { + version, + }, + data: { + NetworkController: { + networkConfigurations: { + 'network-configuration-id-1': { + chainId: '0x539', + nickname: 'Localhost 8545', + rpcPrefs: {}, + rpcUrl: 'http://localhost:8545', + ticker: 'ETH', + id: 'network-configuration-id-1', + }, + 'network-configuration-id-2': { + chainId: '0xa4b1', + nickname: 'Arbitrum One', + rpcPrefs: { + blockExplorerUrl: 'https://explorer.arbitrum.io', + }, + rpcUrl: + 'https://arbitrum-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', + ticker: 'ETH', + id: 'network-configuration-id-2', + }, + 'network-configuration-id-3': { + chainId: '0x4e454152', + nickname: 'Aurora Mainnet', + rpcPrefs: { + blockExplorerUrl: 'https://aurorascan.dev/', + }, + rpcUrl: + 'https://aurora-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', + ticker: 'Aurora ETH', + id: 'network-configuration-id-3', + }, + 'network-configuration-id-4': { + chainId: '0x38', + nickname: + 'BNB Smart Chain (previously Binance Smart Chain Mainnet)', + rpcPrefs: { + blockExplorerUrl: 'https://bscscan.com/', + }, + rpcUrl: 'https://bsc-dataseed.binance.org/', + ticker: 'BNB', + id: 'network-configuration-id-4', + }, + }, + }, + }, + }; + expect(newStorage).toStrictEqual(expectedNewStorage); + }); + + it('should not modify state if state.NetworkController is undefined', async () => { + const oldStorage = { + meta: { + version, + }, + data: { + testProperty: 'testValue', + }, + }; + + const newStorage = await migrate(oldStorage); + + const expectedNewStorage = { + meta: { + version, + }, + data: { + testProperty: 'testValue', + }, + }; + expect(newStorage).toStrictEqual(expectedNewStorage); + }); + + it('should not modify state if state.NetworkController is not an object', async () => { + const oldStorage = { + meta: { + version, + }, + data: { + NetworkController: false, + testProperty: 'testValue', + }, + }; + + const newStorage = await migrate(oldStorage); + + const expectedNewStorage = { + meta: { + version, + }, + data: { + NetworkController: false, + testProperty: 'testValue', + }, + }; + expect(newStorage).toStrictEqual(expectedNewStorage); + }); + + it('should not modify state if state.NetworkController.networkConfigurations is undefined', async () => { + const oldStorage = { + meta: { + version, + }, + data: { + NetworkController: { + testNetworkControllerProperty: 'testNetworkControllerValue', + networkConfigurations: undefined, + }, + testProperty: 'testValue', + }, + }; + + const newStorage = await migrate(oldStorage); + + const expectedNewStorage = { + meta: { + version, + }, + data: { + NetworkController: { + testNetworkControllerProperty: 'testNetworkControllerValue', + networkConfigurations: undefined, + }, + testProperty: 'testValue', + }, + }; + expect(newStorage).toStrictEqual(expectedNewStorage); + }); + + it('should not modify state if state.NetworkController.networkConfigurations is an empty object', async () => { + const oldStorage = { + meta: { + version, + }, + data: { + NetworkController: { + testNetworkControllerProperty: 'testNetworkControllerValue', + networkConfigurations: {}, + }, + testProperty: 'testValue', + }, + }; + + const newStorage = await migrate(oldStorage); + + const expectedNewStorage = { + meta: { + version, + }, + data: { + NetworkController: { + testNetworkControllerProperty: 'testNetworkControllerValue', + networkConfigurations: {}, + }, + testProperty: 'testValue', + }, + }; + expect(newStorage).toStrictEqual(expectedNewStorage); + }); +}); diff --git a/app/scripts/migrations/083.ts b/app/scripts/migrations/083.ts index e55c1960c..cc3e3b16b 100644 --- a/app/scripts/migrations/083.ts +++ b/app/scripts/migrations/083.ts @@ -1,10 +1,11 @@ import { cloneDeep } from 'lodash'; -import { hasProperty, isObject } from '@metamask/utils'; +import { isObject } from '@metamask/utils'; export const version = 83; /** - * The `network` property in state was replaced with `networkId` and `networkStatus`. + * Ensure that each networkConfigurations object in state.NetworkController.networkConfigurations has an + * `id` property which matches the key pointing that object * * @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist. * @param originalVersionedData.meta - State metadata. @@ -23,25 +24,35 @@ export async function migrate(originalVersionedData: { } function transformState(state: Record) { - if ( - !hasProperty(state, 'NetworkController') || - !isObject(state.NetworkController) || - !hasProperty(state.NetworkController, 'network') - ) { + if (!isObject(state.NetworkController)) { + return state; + } + const { NetworkController } = state; + + if (!isObject(NetworkController.networkConfigurations)) { return state; } - const NetworkController = { ...state.NetworkController }; + const { networkConfigurations } = NetworkController; - if (NetworkController.network === 'loading') { - NetworkController.networkId = null; - NetworkController.networkStatus = 'unknown'; - } else { - NetworkController.networkId = NetworkController.network; - NetworkController.networkStatus = 'available'; + const newNetworkConfigurations: Record> = {}; + + for (const networkConfigurationId of Object.keys(networkConfigurations)) { + const networkConfiguration = networkConfigurations[networkConfigurationId]; + if (!isObject(networkConfiguration)) { + return state; + } + newNetworkConfigurations[networkConfigurationId] = { + ...networkConfiguration, + id: networkConfigurationId, + }; } - delete NetworkController.network; - - return { ...state, NetworkController }; + return { + ...state, + NetworkController: { + ...NetworkController, + networkConfigurations: newNetworkConfigurations, + }, + }; } diff --git a/app/scripts/migrations/084.test.js b/app/scripts/migrations/084.test.js index e93b561e5..138bfacb6 100644 --- a/app/scripts/migrations/084.test.js +++ b/app/scripts/migrations/084.test.js @@ -1,254 +1,103 @@ -import { v4 } from 'uuid'; -import { migrate, version } from './084'; - -jest.mock('uuid', () => { - const actual = jest.requireActual('uuid'); - - return { - ...actual, - v4: jest.fn(), - }; -}); +import { migrate } from './084'; describe('migration #84', () => { - beforeEach(() => { - v4.mockImplementationOnce(() => 'network-configuration-id-1') - .mockImplementationOnce(() => 'network-configuration-id-2') - .mockImplementationOnce(() => 'network-configuration-id-3') - .mockImplementationOnce(() => 'network-configuration-id-4'); - }); - - afterEach(() => { - jest.resetAllMocks(); - }); - it('should update the version metadata', async () => { - const oldStorage = { + it('updates the version metadata', async () => { + const originalVersionedData = buildOriginalVersionedData({ meta: { - version: 83, + version: 9999999, }, - data: {}, - }; + }); - const newStorage = await migrate(oldStorage); - expect(newStorage.meta).toStrictEqual({ - version, + const newVersionedData = await migrate(originalVersionedData); + + expect(newVersionedData.meta).toStrictEqual({ + version: 84, }); }); - it('should use the key of the networkConfigurations object to set the id of each network configuration', async () => { - const oldStorage = { - meta: { - version, - }, + it('does not change the state if the network controller state does not exist', async () => { + const originalVersionedData = buildOriginalVersionedData({ data: { - NetworkController: { - networkConfigurations: { - 'network-configuration-id-1': { - chainId: '0x539', - nickname: 'Localhost 8545', - rpcPrefs: {}, - rpcUrl: 'http://localhost:8545', - ticker: 'ETH', - }, - 'network-configuration-id-2': { - chainId: '0xa4b1', - nickname: 'Arbitrum One', - rpcPrefs: { - blockExplorerUrl: 'https://explorer.arbitrum.io', - }, - rpcUrl: - 'https://arbitrum-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', - ticker: 'ETH', - }, - 'network-configuration-id-3': { - chainId: '0x4e454152', - nickname: 'Aurora Mainnet', - rpcPrefs: { - blockExplorerUrl: 'https://aurorascan.dev/', - }, - rpcUrl: - 'https://aurora-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', - ticker: 'Aurora ETH', - }, - 'network-configuration-id-4': { - chainId: '0x38', - nickname: - 'BNB Smart Chain (previously Binance Smart Chain Mainnet)', - rpcPrefs: { - blockExplorerUrl: 'https://bscscan.com/', - }, - rpcUrl: 'https://bsc-dataseed.binance.org/', - ticker: 'BNB', - }, - }, - }, + test: '123', }, - }; + }); - const newStorage = await migrate(oldStorage); + const newVersionedData = await migrate(originalVersionedData); - const expectedNewStorage = { - meta: { - version, - }, - data: { - NetworkController: { - networkConfigurations: { - 'network-configuration-id-1': { - chainId: '0x539', - nickname: 'Localhost 8545', - rpcPrefs: {}, - rpcUrl: 'http://localhost:8545', - ticker: 'ETH', - id: 'network-configuration-id-1', - }, - 'network-configuration-id-2': { - chainId: '0xa4b1', - nickname: 'Arbitrum One', - rpcPrefs: { - blockExplorerUrl: 'https://explorer.arbitrum.io', - }, - rpcUrl: - 'https://arbitrum-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', - ticker: 'ETH', - id: 'network-configuration-id-2', - }, - 'network-configuration-id-3': { - chainId: '0x4e454152', - nickname: 'Aurora Mainnet', - rpcPrefs: { - blockExplorerUrl: 'https://aurorascan.dev/', - }, - rpcUrl: - 'https://aurora-mainnet.infura.io/v3/373266a93aab4acda48f89d4fe77c748', - ticker: 'Aurora ETH', - id: 'network-configuration-id-3', - }, - 'network-configuration-id-4': { - chainId: '0x38', - nickname: - 'BNB Smart Chain (previously Binance Smart Chain Mainnet)', - rpcPrefs: { - blockExplorerUrl: 'https://bscscan.com/', - }, - rpcUrl: 'https://bsc-dataseed.binance.org/', - ticker: 'BNB', - id: 'network-configuration-id-4', - }, - }, - }, - }, - }; - expect(newStorage).toStrictEqual(expectedNewStorage); + expect(newVersionedData.data).toStrictEqual(originalVersionedData.data); }); - it('should not modify state if state.NetworkController is undefined', async () => { - const oldStorage = { - meta: { - version, - }, - data: { - testProperty: 'testValue', - }, - }; + const nonObjects = [undefined, null, 'test', 1, ['test']]; + for (const invalidState of nonObjects) { + it(`does not change the state if the network controller state is ${invalidState}`, async () => { + const originalVersionedData = buildOriginalVersionedData({ + data: { + NetworkController: invalidState, + }, + }); - const newStorage = await migrate(oldStorage); + const newVersionedData = await migrate(originalVersionedData); - const expectedNewStorage = { - meta: { - version, - }, + expect(newVersionedData.data).toStrictEqual(originalVersionedData.data); + }); + } + + it('does not change the state if the network controller state does not include "network"', async () => { + const originalVersionedData = buildOriginalVersionedData({ data: { - testProperty: 'testValue', + NetworkController: { + test: '123', + }, }, - }; - expect(newStorage).toStrictEqual(expectedNewStorage); + }); + + const newVersionedData = await migrate(originalVersionedData); + + expect(newVersionedData.data).toStrictEqual(originalVersionedData.data); }); - it('should not modify state if state.NetworkController is not an object', async () => { - const oldStorage = { - meta: { - version, - }, + it('replaces "network" in the network controller state with "networkId": null, "networkStatus": "unknown" if it is "loading"', async () => { + const originalVersionedData = buildOriginalVersionedData({ data: { - NetworkController: false, - testProperty: 'testValue', + NetworkController: { + network: 'loading', + }, }, - }; + }); - const newStorage = await migrate(oldStorage); + const newVersionedData = await migrate(originalVersionedData); - const expectedNewStorage = { - meta: { - version, + expect(newVersionedData.data).toStrictEqual({ + NetworkController: { + networkId: null, + networkStatus: 'unknown', }, - data: { - NetworkController: false, - testProperty: 'testValue', - }, - }; - expect(newStorage).toStrictEqual(expectedNewStorage); + }); }); - it('should not modify state if state.NetworkController.networkConfigurations is undefined', async () => { - const oldStorage = { - meta: { - version, - }, + it('replaces "network" in the network controller state with "networkId": network, "networkStatus": "available" if it is not "loading"', async () => { + const originalVersionedData = buildOriginalVersionedData({ data: { NetworkController: { - testNetworkControllerProperty: 'testNetworkControllerValue', - networkConfigurations: undefined, + network: '12345', }, - testProperty: 'testValue', }, - }; + }); - const newStorage = await migrate(oldStorage); + const newVersionedData = await migrate(originalVersionedData); - const expectedNewStorage = { - meta: { - version, + expect(newVersionedData.data).toStrictEqual({ + NetworkController: { + networkId: '12345', + networkStatus: 'available', }, - data: { - NetworkController: { - testNetworkControllerProperty: 'testNetworkControllerValue', - networkConfigurations: undefined, - }, - testProperty: 'testValue', - }, - }; - expect(newStorage).toStrictEqual(expectedNewStorage); - }); - - it('should not modify state if state.NetworkController.networkConfigurations is an empty object', async () => { - const oldStorage = { - meta: { - version, - }, - data: { - NetworkController: { - testNetworkControllerProperty: 'testNetworkControllerValue', - networkConfigurations: {}, - }, - testProperty: 'testValue', - }, - }; - - const newStorage = await migrate(oldStorage); - - const expectedNewStorage = { - meta: { - version, - }, - data: { - NetworkController: { - testNetworkControllerProperty: 'testNetworkControllerValue', - networkConfigurations: {}, - }, - testProperty: 'testValue', - }, - }; - expect(newStorage).toStrictEqual(expectedNewStorage); + }); }); }); + +function buildOriginalVersionedData({ meta = {}, data = {} } = {}) { + return { + meta: { version: 999999, ...meta }, + data: { ...data }, + }; +} diff --git a/app/scripts/migrations/084.ts b/app/scripts/migrations/084.ts index 4ae81cdc8..66a2f45ae 100644 --- a/app/scripts/migrations/084.ts +++ b/app/scripts/migrations/084.ts @@ -1,11 +1,10 @@ import { cloneDeep } from 'lodash'; -import { isObject } from '@metamask/utils'; +import { hasProperty, isObject } from '@metamask/utils'; export const version = 84; /** - * Ensure that each networkConfigurations object in state.NetworkController.networkConfigurations has an - * `id` property which matches the key pointing that object + * The `network` property in state was replaced with `networkId` and `networkStatus`. * * @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist. * @param originalVersionedData.meta - State metadata. @@ -24,35 +23,25 @@ export async function migrate(originalVersionedData: { } function transformState(state: Record) { - if (!isObject(state.NetworkController)) { - return state; - } - const { NetworkController } = state; - - if (!isObject(NetworkController.networkConfigurations)) { + if ( + !hasProperty(state, 'NetworkController') || + !isObject(state.NetworkController) || + !hasProperty(state.NetworkController, 'network') + ) { return state; } - const { networkConfigurations } = NetworkController; + const NetworkController = { ...state.NetworkController }; - const newNetworkConfigurations: Record> = {}; - - for (const networkConfigurationId of Object.keys(networkConfigurations)) { - const networkConfiguration = networkConfigurations[networkConfigurationId]; - if (!isObject(networkConfiguration)) { - return state; - } - newNetworkConfigurations[networkConfigurationId] = { - ...networkConfiguration, - id: networkConfigurationId, - }; + if (NetworkController.network === 'loading') { + NetworkController.networkId = null; + NetworkController.networkStatus = 'unknown'; + } else { + NetworkController.networkId = NetworkController.network; + NetworkController.networkStatus = 'available'; } - return { - ...state, - NetworkController: { - ...NetworkController, - networkConfigurations: newNetworkConfigurations, - }, - }; + delete NetworkController.network; + + return { ...state, NetworkController }; } From 02e8e9c67940d213b46ffbd0da721f0b959d7bc6 Mon Sep 17 00:00:00 2001 From: Peter <53189696+PeterYinusa@users.noreply.github.com> Date: Wed, 19 Apr 2023 15:36:23 +0100 Subject: [PATCH 13/25] Avoid resetting the mock server (#18661) --- test/e2e/helpers.js | 4 ++-- test/e2e/mock-e2e.js | 11 +++++++---- test/e2e/tests/ens.spec.js | 4 +--- test/e2e/tests/errors.spec.js | 8 +++----- test/e2e/tests/metrics.spec.js | 11 ++++------- test/e2e/tests/network-error.spec.js | 1 + 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index 132003451..1dfccf73f 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -105,7 +105,7 @@ async function withFixtures(options, testSuite) { }); } } - await setupMocking(mockServer, testSpecificMock); + const mockedEndpoint = await setupMocking(mockServer, testSpecificMock); await mockServer.start(8000); if ( process.env.SELENIUM_BROWSER === 'chrome' && @@ -143,10 +143,10 @@ async function withFixtures(options, testSuite) { await testSuite({ driver: driverProxy ?? driver, - mockServer, contractRegistry, ganacheServer, secondaryGanacheServer, + mockedEndpoint, }); } catch (error) { failed = true; diff --git a/test/e2e/mock-e2e.js b/test/e2e/mock-e2e.js index cda544ded..b7e4e6e0c 100644 --- a/test/e2e/mock-e2e.js +++ b/test/e2e/mock-e2e.js @@ -32,6 +32,11 @@ async function setupMocking(server, testSpecificMock) { return {}; }, }); + + const mockedEndpoint = await testSpecificMock(server); + + // Mocks below this line can be overridden by test-specific mocks + await server .forPost( 'https://arbitrum-mainnet.infura.io/v3/00000000000000000000000000000000', @@ -369,10 +374,6 @@ async function setupMocking(server, testSpecificMock) { }; }); - testSpecificMock(server); - - // Mocks below this line can be overridden by test-specific mocks - await server.forGet(STALELIST_URL).thenCallback(() => { return { statusCode: 200, @@ -399,6 +400,8 @@ async function setupMocking(server, testSpecificMock) { }, }; }); + + return mockedEndpoint; } module.exports = { setupMocking }; diff --git a/test/e2e/tests/ens.spec.js b/test/e2e/tests/ens.spec.js index 3a0dffee1..136f06df1 100644 --- a/test/e2e/tests/ens.spec.js +++ b/test/e2e/tests/ens.spec.js @@ -9,8 +9,6 @@ describe('ENS', function () { 'https://mainnet.infura.io/v3/00000000000000000000000000000000'; async function mockInfura(mockServer) { - await mockServer.reset(); - await mockServer.forAnyRequest().thenPassThrough(); await mockServer .forPost(infuraUrl) .withJsonBodyIncluding({ method: 'eth_blockNumber' }) @@ -103,7 +101,7 @@ describe('ENS', function () { await driver.clickElement('[data-testid="eth-overview-send"]'); - await driver.fill( + await driver.pasteIntoField( 'input[placeholder="Search, public address (0x), or ENS"]', sampleEnsDomain, ); diff --git a/test/e2e/tests/errors.spec.js b/test/e2e/tests/errors.spec.js index 74f3ec502..f70317916 100644 --- a/test/e2e/tests/errors.spec.js +++ b/test/e2e/tests/errors.spec.js @@ -3,9 +3,7 @@ const { convertToHexValue, withFixtures } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); describe('Sentry errors', function () { - async function mockSegment(mockServer) { - mockServer.reset(); - await mockServer.forAnyRequest().thenPassThrough(); + async function mockSentry(mockServer) { return await mockServer .forPost('https://sentry.io/api/0000000/store/') .thenCallback(() => { @@ -36,9 +34,9 @@ describe('Sentry errors', function () { ganacheOptions, title: this.test.title, failOnConsoleError: false, + testSpecificMock: mockSentry, }, - async ({ driver, mockServer }) => { - const mockedEndpoint = await mockSegment(mockServer); + async ({ driver, mockedEndpoint }) => { await driver.navigate(); await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); diff --git a/test/e2e/tests/metrics.spec.js b/test/e2e/tests/metrics.spec.js index 21ee6c0fd..ac99d3fe3 100644 --- a/test/e2e/tests/metrics.spec.js +++ b/test/e2e/tests/metrics.spec.js @@ -4,8 +4,6 @@ const FixtureBuilder = require('../fixture-builder'); describe('Segment metrics', function () { async function mockSegment(mockServer) { - mockServer.reset(); - await mockServer.forAnyRequest().thenPassThrough(); return await mockServer .forPost('https://api.segment.io/v1/batch') .withJsonBodyIncluding({ batch: [{ type: 'page' }] }) @@ -36,18 +34,17 @@ describe('Segment metrics', function () { .build(), ganacheOptions, title: this.test.title, - failOnConsoleError: false, + testSpecificMock: mockSegment, }, - async ({ driver, mockServer }) => { - const mockedEndpoints = await mockSegment(mockServer); + async ({ driver, mockedEndpoint }) => { await driver.navigate(); await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); await driver.wait(async () => { - const isPending = await mockedEndpoints.isPending(); + const isPending = await mockedEndpoint.isPending(); return isPending === false; }, 10000); - const mockedRequests = await mockedEndpoints.getSeenRequests(); + const mockedRequests = await mockedEndpoint.getSeenRequests(); assert.equal(mockedRequests.length, 3); const [firstMock, secondMock, thirdMock] = mockedRequests; let [mockJson] = firstMock.body.json.batch; diff --git a/test/e2e/tests/network-error.spec.js b/test/e2e/tests/network-error.spec.js index fdb51df9e..778d32b35 100644 --- a/test/e2e/tests/network-error.spec.js +++ b/test/e2e/tests/network-error.spec.js @@ -8,6 +8,7 @@ describe('Gas API fallback', function () { .forGet( 'https://gas-api.metaswap.codefi.network/networks/1/suggestedGasFees', ) + .always() .thenCallback(() => { return { statusCode: 200, From d362dbfacbd3edf9550cee38711965d6d6e08205 Mon Sep 17 00:00:00 2001 From: Nidhi Kumari Date: Wed, 19 Apr 2023 20:55:19 +0530 Subject: [PATCH 14/25] UX Multichain: updated ethereum logo icon (#18528) * updated ethereum logo icon * Updating eth logo (#18631) * Updating eth logo * Removing border from eth logo identicon * Removing old eth logo * updated snapshot and lint errors * updated eth logo from svg to png --------- Co-authored-by: George Marshall --- .../approval-screens/add-suggested-token.js | 2 +- .storybook/test-data.js | 2 +- app/images/eth_logo.png | Bin 0 -> 3757 bytes app/images/eth_logo.svg | 18 ------------------ shared/constants/network.ts | 2 +- .../app/asset-list-item/asset-list-item.js | 3 --- .../asset-list-item.stories.js | 5 +---- .../app/wallet-overview/eth-overview.js | 2 +- .../component-library/avatar-base/README.mdx | 2 +- .../avatar-base/avatar-base.stories.js | 2 +- .../avatar-favicon/avatar-favicon.test.js | 2 +- .../avatar-network/avatar-network.test.js | 2 +- .../component-library/avatar-token/README.mdx | 4 ++-- .../avatar-token/avatar-token.stories.js | 14 +++++++------- .../badge-wrapper/README.mdx | 2 +- .../badge-wrapper/badge-wrapper.stories.tsx | 2 +- .../text-field/text-field.stories.js | 2 +- .../multichain-token-list-item.test.js.snap | 2 +- .../multichain-token-list-item.stories.js | 2 +- .../ui/identicon/identicon.stories.js | 2 +- .../ui/site-icon/site-icon.stories.js | 2 +- ui/components/ui/site-icon/site-icon.test.js | 2 +- 22 files changed, 26 insertions(+), 50 deletions(-) create mode 100644 app/images/eth_logo.png delete mode 100644 app/images/eth_logo.svg diff --git a/.storybook/initial-states/approval-screens/add-suggested-token.js b/.storybook/initial-states/approval-screens/add-suggested-token.js index d8218a2ce..ee62778cc 100644 --- a/.storybook/initial-states/approval-screens/add-suggested-token.js +++ b/.storybook/initial-states/approval-screens/add-suggested-token.js @@ -4,7 +4,7 @@ export const suggestedAssets = [ address: '0x6b175474e89094c44da98b954eedeac495271d0f', symbol: 'ETH', decimals: 18, - image: './images/eth_logo.svg', + image: './images/eth_logo.png', unlisted: false, }, }, diff --git a/.storybook/test-data.js b/.storybook/test-data.js index 22ec45e2a..496094a91 100644 --- a/.storybook/test-data.js +++ b/.storybook/test-data.js @@ -174,7 +174,7 @@ const state = { address: '0x6b175474e89094c44da98b954eedeac495271d0f', symbol: 'ETH', decimals: 18, - image: './images/eth_logo.svg', + image: './images/eth_logo.png', unlisted: false, }, '0xB8c77482e45F1F44dE1745F52C74426C631bDD52': { diff --git a/app/images/eth_logo.png b/app/images/eth_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3ac03d57bbd9392b7af9d3753096076be8a6d5a3 GIT binary patch literal 3757 zcmaJ^c{r4N`|p%e;@BliI){o3LSvVhtfO!!Gs%*%gvc`4nrOAmj3F@-8ZnlVr85}J zBwlG|Vl>Riz7!6|zOPw+&z$$)-}OG%HP>_9_x-s)%lA9~JjssNtVM+6gbo}yAYyBC z<*x$=ep}`LjvfL!J4dzZfY&`odlyUZxap?0js5-o$FJrWmv=)FXFoF6$&G8X3%hro z&cvqAMdD`Di|C1?j__b5K5LJu(KnRzla}} zBXM(mKerj2&8)H|ZvQsBXNy>|jLlmdpWaC%F2v^d=m3_sY_FKRMEB1Qy5agSizRR( zMe?r2rZ-i#ShhCL#%DUsKaR#`CEB>Wse0~U)3xo(&+$K=eR_^XR71TMa-z<7vplMp z7}?CUaAow0G!Ix<7jMcu)I=7>rCzEVH_~CI@)95BOKQYfDdC=9GucPa<7XIB@g%dD zvZ(y7Mv`di^WU*c#x%DINewnhbU|pU3&U$pvBxfjmivmN3MB4_}W9RYEduTc@f$(Mhz9DVo3>gBl*02Ak%UccD z3|zBY9m!8?lR6IUlu)+4kh+C(MmOm}+1u5aGc-5Nw`vuZ`t?4Y(>IZ|x9kvuryho~ zhA1+n0PD#v5sru!RRIA3md?*rp8aF5lIUuNIX-)xf1O{L5K+pc>-BiFJsX>#E>(vfP3W?roWuKfY77=i| zcuKBnI$frxLr5*mW@^c=jmWnBoKV zUmAU_n#HA-{W>RQ0~9$oS_@aiQ#`#@UjPVjimdHqA50&l;%Zd&`hi6jQbr5cXTyKR zB@dtg1$IE8qY>srZMFAlqNmo!(MwW%%FL91Um2>;`OLnqXNhpOb~!c;pgf~3W#^Ay zfhse&F?uq&szuza@j;0S)lb_o)(2oLgDH^5j(DwdQC0MkwKAeG0={9Ru3V_g+ERhp zOe)K{-u0;l)Y(Zo$;jLkOFy$~fHBBTZ9cWMHjEzuebWk1h_KFB0>q7#UqL5(SiEX) zWg;D;0E(snT$S_5nX)#370XxdMi_$mWhsrffEN?-!7Q%?nk(wE zfYJ5XK|wLVn&zXws!@EcLrz|Rw}nH2mS+4o7V0+Kt)vO(M`*k#a4A1KkKzG)#N6k3 z0Ee-l7uq*EnONpR{`_hZ*pXW*{h35cHn%srCPu%2{xKl5r_EZLilxUO*m6XHxv^hfyn zYcXbX&u8wn)(V2@Ai>1@oXQXCmPP00%wYBZ5r0~;JZWcW=Q`*9ZS*kq=B&ZH;SH|j zP(tdRw4|DXo!3ZT%0wj&A}0Si!u|RiXwS&rzMzSG&T(%vw4mOV7Px<1m-U<2)A9Y- zMr2VbyuR%kqN3iD_Ip&^r`Mw2e}fsCyk8ccG8)Vp4>z|93&@zXbI38q5I|mN{M@xn zf{jBnk{e(2b*14jM z8f}oro^~fX?p=n(6dm~kUJsM3O(+=jpjF2HRL(a1Yw*OwDFec4H8lcWTkuVGe8tvb zK^6FCq1EOWU9ML_9fF0cULVUbFHnHc8VY=tbRKdfR$~NkNX7Y`*ci}9R)GR^yL6q9 z4G(!QRcl&*UN9p!0f_DG%~KkG$6YHqj3HQL4-;@-x%caIS(#$LtPE+ZtGIMJhJ$W^ zwkq-u&>yh^+eisl0w7hw`BVC=!|Kd-PS$(%jE4?&UMc1iR`l7GG03(ir&3<7QkIYkr~f;X}72p=cy+4b=`4dB%p$M*J=>d1B(6b(?}oERk|A${2lA6 z9(&8)ZR5ftfMgR#F?Yq{y*K?@6Bc0n?(QGHKYa`jg4c#87*y|i{}Tz?KU!tS-1Ja zY4e+i-q`h%4#F*C-g3gkrk}-MPXyVZDi`8^TGp%%;=v7034y}76QfmOlK)`9DvF(p zd6kz#Sa;`CPC_rD%#$9GgF-2j1KXrbm}jUs zX;60>${qr@I$zu3_5ijDj+#VQVvlNtB>a&NgGd;=7J?l#-3YajcBPDGP1jW_saM~_ zAZko;Q=6bH)ghB_3BGe*Z~;}T>Zi%L%r{G4%y35`?QK83d8KqUj6_rgtWn47A3e^d zl|+|phVOC*)gb#hU?nL)l@&TNsnTxvqOCR;m^01!+v}%gv zih=j5IU%3+;2m!fjS9x;a&p=S&LRf<1ru<)Ra(rQDb&7s9|b;=z=m9^Es_bUGj`4J zHCT+u$)iLdxUu4MRb0&OfsH>yIFbwTU{=Wh&ni62jMxrSXE`7c5i z5PGegIzm+EW*@X;=JypcFJ|~wFuTdU6zH4HXZh;hp(ZGD!p8_pctRp71o1`R130^h zZDhz37frI*yU-`nD>Is_cFwO^6wD+ucuXv zT6Gel7k$`M z`g*gB;*4t*@-D{-PlkSz2DY1p?K$K)u&{3J(CKpc#Pf4T-5-ie;Cznk_ajMwdQRi) zkYUK!Whnti$TsBMktVMv+6j+Q`%w1i^~x*v6U*WjgbtIOlnyUO^IRD^#U}}J>3@eiuv-aLf8N#D()(0c)-pLv&2;ZK)4bxaZ;U z3eGofw1VdVYov>7H9Ghfo!V#fJ92)3M~Ak+_RZL0tS@&ko-fA^*GC3xv`=~P7&jHQzRnmPP;2aADGl-DOcaD3s8*H68J$ zX=AO1HPsYk1cYa%^mTbt11TEYu%-j7pa`GJvA#zZk>WIR+tK0`AeB`pKeYVkB@i&z z26;kyx{r|Kjt#;5#2U@stS#rIdhZDXm29UqkYy}7P828<7AAXj@F%}6%g}1{(mR8I ziE@l76JMj3u@w&#h?t!dG{J`#W=0$tI#0I-_;+*BArV+%yD)T`x5$A(V@pK-2j&0w p>;#DZevCg5*o~hPlK(H{!ZA@?fMQ{=RxZD`wY+wv!ousx{{aI#l#T!Z literal 0 HcmV?d00001 diff --git a/app/images/eth_logo.svg b/app/images/eth_logo.svg deleted file mode 100644 index 42be3a2e0..000000000 --- a/app/images/eth_logo.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - diff --git a/shared/constants/network.ts b/shared/constants/network.ts index ab5115bee..5227efe2e 100644 --- a/shared/constants/network.ts +++ b/shared/constants/network.ts @@ -221,7 +221,7 @@ export const CURRENCY_SYMBOLS = { OPTIMISM: 'OP', } as const; -export const ETH_TOKEN_IMAGE_URL = './images/eth_logo.svg'; +export const ETH_TOKEN_IMAGE_URL = './images/eth_logo.png'; export const TEST_ETH_TOKEN_IMAGE_URL = './images/black-eth-logo.svg'; export const BNB_TOKEN_IMAGE_URL = './images/bnb.png'; export const MATIC_TOKEN_IMAGE_URL = './images/matic-token.png'; 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 3070308b3..2be1b78b6 100644 --- a/ui/components/app/asset-list-item/asset-list-item.js +++ b/ui/components/app/asset-list-item/asset-list-item.js @@ -35,7 +35,6 @@ const AssetListItem = ({ warning, primary, secondary, - identiconBorder, isERC721, }) => { const t = useI18nContext(); @@ -137,7 +136,6 @@ const AssetListItem = ({ address={tokenAddress} image={tokenImage} alt={`${primary} ${tokenSymbol}`} - imageBorder={identiconBorder} /> } midContent={midContent} @@ -170,7 +168,6 @@ AssetListItem.propTypes = { warning: PropTypes.node, primary: PropTypes.string, secondary: PropTypes.string, - identiconBorder: PropTypes.bool, isERC721: PropTypes.bool, }; diff --git a/ui/components/app/asset-list-item/asset-list-item.stories.js b/ui/components/app/asset-list-item/asset-list-item.stories.js index 0fd34e53a..d339c546b 100644 --- a/ui/components/app/asset-list-item/asset-list-item.stories.js +++ b/ui/components/app/asset-list-item/asset-list-item.stories.js @@ -34,9 +34,6 @@ export default { secondary: { control: 'text', }, - identiconBorder: { - control: 'boolean', - }, isERC721: { control: 'boolean', }, @@ -44,7 +41,7 @@ export default { args: { tokenAddress: '0x2170ed0880ac9a755fd29b2688956bd959f933f8', tokenSymbol: 'ETH', - tokenImage: './images/eth_logo.svg', + tokenImage: './images/eth_logo.png', identiconBorder: true, }, }; diff --git a/ui/components/app/wallet-overview/eth-overview.js b/ui/components/app/wallet-overview/eth-overview.js index 0352039c4..070076227 100644 --- a/ui/components/app/wallet-overview/eth-overview.js +++ b/ui/components/app/wallet-overview/eth-overview.js @@ -273,7 +273,7 @@ const EthOverview = ({ className }) => { } className={className} - icon={} + icon={} /> ); }; diff --git a/ui/components/component-library/avatar-base/README.mdx b/ui/components/component-library/avatar-base/README.mdx index ff0e396f6..d232dfc10 100644 --- a/ui/components/component-library/avatar-base/README.mdx +++ b/ui/components/component-library/avatar-base/README.mdx @@ -59,7 +59,7 @@ The `AvatarBase` component can contain images, icons or text ```jsx import { AvatarBase } from '../../component-library'; - + diff --git a/ui/components/component-library/avatar-base/avatar-base.stories.js b/ui/components/component-library/avatar-base/avatar-base.stories.js index 49cc6b8d3..cd86e81d1 100644 --- a/ui/components/component-library/avatar-base/avatar-base.stories.js +++ b/ui/components/component-library/avatar-base/avatar-base.stories.js @@ -110,7 +110,7 @@ export const Size = (args) => ( export const Children = (args) => ( - + diff --git a/ui/components/component-library/avatar-favicon/avatar-favicon.test.js b/ui/components/component-library/avatar-favicon/avatar-favicon.test.js index 6c44e7123..4c882f0c1 100644 --- a/ui/components/component-library/avatar-favicon/avatar-favicon.test.js +++ b/ui/components/component-library/avatar-favicon/avatar-favicon.test.js @@ -6,7 +6,7 @@ import { AvatarFavicon, AVATAR_FAVICON_SIZES } from '.'; describe('AvatarFavicon', () => { const args = { - src: './images/eth_logo.svg', + src: './images/eth_logo.png', name: 'test', }; diff --git a/ui/components/component-library/avatar-network/avatar-network.test.js b/ui/components/component-library/avatar-network/avatar-network.test.js index cded1d76a..8817dc53e 100644 --- a/ui/components/component-library/avatar-network/avatar-network.test.js +++ b/ui/components/component-library/avatar-network/avatar-network.test.js @@ -13,7 +13,7 @@ import { AvatarNetwork } from './avatar-network'; describe('AvatarNetwork', () => { const args = { name: 'ethereum', - src: './images/eth_logo.svg', + src: './images/eth_logo.png', showHalo: false, }; diff --git a/ui/components/component-library/avatar-token/README.mdx b/ui/components/component-library/avatar-token/README.mdx index efe5375e9..fb39789bf 100644 --- a/ui/components/component-library/avatar-token/README.mdx +++ b/ui/components/component-library/avatar-token/README.mdx @@ -72,7 +72,7 @@ Use the `src` prop to set the image to be rendered of the `AvatarToken`. ```jsx import { AvatarToken } from '../../component-library'; - + @@ -92,7 +92,7 @@ Use the `showHalo` prop to display the component with halo effect. Only works if ```jsx import { AvatarToken } from '../../component-library'; -; +; ``` ### Color, Background Color And Border Color diff --git a/ui/components/component-library/avatar-token/avatar-token.stories.js b/ui/components/component-library/avatar-token/avatar-token.stories.js index e89756fdd..4262f30d1 100644 --- a/ui/components/component-library/avatar-token/avatar-token.stories.js +++ b/ui/components/component-library/avatar-token/avatar-token.stories.js @@ -61,7 +61,7 @@ export default { }, args: { name: 'eth', - src: './images/eth_logo.svg', + src: './images/eth_logo.png', size: Size.MD, showHalo: false, }, @@ -126,7 +126,7 @@ export const SizeStory = (args) => ( ( ( ( ( ( - + diff --git a/ui/components/component-library/badge-wrapper/badge-wrapper.stories.tsx b/ui/components/component-library/badge-wrapper/badge-wrapper.stories.tsx index 9c91fe7e0..29c754737 100644 --- a/ui/components/component-library/badge-wrapper/badge-wrapper.stories.tsx +++ b/ui/components/component-library/badge-wrapper/badge-wrapper.stories.tsx @@ -114,7 +114,7 @@ export const Children: ComponentStory = () => ( > diff --git a/ui/components/component-library/text-field/text-field.stories.js b/ui/components/component-library/text-field/text-field.stories.js index b266ebb94..92cc7ec38 100644 --- a/ui/components/component-library/text-field/text-field.stories.js +++ b/ui/components/component-library/text-field/text-field.stories.js @@ -277,7 +277,7 @@ export const StartAccessoryEndAccessory = (args) => { > ETH diff --git a/ui/components/multichain/multichain-token-list-item/__snapshots__/multichain-token-list-item.test.js.snap b/ui/components/multichain/multichain-token-list-item/__snapshots__/multichain-token-list-item.test.js.snap index 7ed3f32aa..fba0eabf9 100644 --- a/ui/components/multichain/multichain-token-list-item/__snapshots__/multichain-token-list-item.test.js.snap +++ b/ui/components/multichain/multichain-token-list-item/__snapshots__/multichain-token-list-item.test.js.snap @@ -28,7 +28,7 @@ exports[`MultichainTokenListItem should render correctly 1`] = ` undefined logo diff --git a/ui/components/multichain/multichain-token-list-item/multichain-token-list-item.stories.js b/ui/components/multichain/multichain-token-list-item/multichain-token-list-item.stories.js index 168e6ed1a..161ac7fec 100644 --- a/ui/components/multichain/multichain-token-list-item/multichain-token-list-item.stories.js +++ b/ui/components/multichain/multichain-token-list-item/multichain-token-list-item.stories.js @@ -30,7 +30,7 @@ export default { args: { secondary: '$9.80 USD', primary: '88.00687889', - tokenImage: './images/eth_logo.svg', + tokenImage: './images/eth_logo.png', tokenSymbol: 'ETH', title: 'Ethereum', }, diff --git a/ui/components/ui/identicon/identicon.stories.js b/ui/components/ui/identicon/identicon.stories.js index eff3050a4..0469ff50d 100644 --- a/ui/components/ui/identicon/identicon.stories.js +++ b/ui/components/ui/identicon/identicon.stories.js @@ -40,7 +40,7 @@ WithImage.args = { addBorder: false, diameter: 32, useBlockie: false, - image: './images/eth_logo.svg', + image: './images/eth_logo.png', alt: 'Ethereum', imageBorder: true, }; diff --git a/ui/components/ui/site-icon/site-icon.stories.js b/ui/components/ui/site-icon/site-icon.stories.js index bb1c7998e..893800cfa 100644 --- a/ui/components/ui/site-icon/site-icon.stories.js +++ b/ui/components/ui/site-icon/site-icon.stories.js @@ -31,7 +31,7 @@ DefaultStory.storyName = 'Default'; DefaultStory.args = { name: 'eth', - icon: './images/eth_logo.svg', + icon: './images/eth_logo.png', size: 24, }; diff --git a/ui/components/ui/site-icon/site-icon.test.js b/ui/components/ui/site-icon/site-icon.test.js index f1e793c3b..a78f2b8d0 100644 --- a/ui/components/ui/site-icon/site-icon.test.js +++ b/ui/components/ui/site-icon/site-icon.test.js @@ -6,7 +6,7 @@ describe('SiteIcon', () => { const args = { size: 32, name: 'Snap name', - icon: './images/eth_logo.svg', + icon: './images/eth_logo.png', className: 'classname-test', fallbackClassName: 'fallback-classname-test', }; From a876eaba23fa6aa0ff4db05de80f9d06592ff4bc Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Wed, 19 Apr 2023 09:47:33 -0600 Subject: [PATCH 15/25] removeNetworkConfiguration validates given ID (#18650) In the `core` version of NetworkController, `removeNetworkConfiguration` throws an error if the given network configuration ID doesn't match an existing network configuration. This commits adds the same check for consistency. It also makes some minor changes to the implementation and tests for `removeNetworkConfiguration` for consistency as well. --- .../network/network-controller.test.ts | 49 +++++++++++++------ .../controllers/network/network-controller.ts | 9 ++-- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/app/scripts/controllers/network/network-controller.test.ts b/app/scripts/controllers/network/network-controller.test.ts index 508d57fe7..8368decd0 100644 --- a/app/scripts/controllers/network/network-controller.test.ts +++ b/app/scripts/controllers/network/network-controller.test.ts @@ -7308,14 +7308,14 @@ describe('NetworkController', () => { }); describe('removeNetworkConfigurations', () => { - it('should remove a network configuration', async () => { - const networkConfigurationId = 'networkConfigurationId'; + it('removes a network configuration', async () => { + const networkConfigurationId = 'testNetworkConfigurationId'; await withController( { state: { networkConfigurations: { [networkConfigurationId]: { - id: 'aaaaaa', + id: networkConfigurationId, rpcUrl: 'https://test-rpc-url', ticker: 'old_rpc_ticker', nickname: 'old_rpc_chainName', @@ -7326,25 +7326,44 @@ describe('NetworkController', () => { }, }, async ({ controller }) => { - expect( - Object.values(controller.store.getState().networkConfigurations), - ).toStrictEqual([ - { - id: 'aaaaaa', - rpcUrl: 'https://test-rpc-url', - ticker: 'old_rpc_ticker', - nickname: 'old_rpc_chainName', - rpcPrefs: { blockExplorerUrl: 'testchainscan.io' }, - chainId: '0x1', - }, - ]); controller.removeNetworkConfiguration(networkConfigurationId); + expect( controller.store.getState().networkConfigurations, ).toStrictEqual({}); }, ); }); + + it('throws if the networkConfigurationId it is passed does not correspond to a network configuration in state', async () => { + const testNetworkConfigurationId = 'testNetworkConfigurationId'; + const invalidNetworkConfigurationId = 'invalidNetworkConfigurationId'; + await withController( + { + state: { + networkConfigurations: { + [testNetworkConfigurationId]: { + rpcUrl: 'https://rpc-url.com', + ticker: 'old_rpc_ticker', + nickname: 'old_rpc_nickname', + rpcPrefs: { blockExplorerUrl: 'testchainscan.io' }, + chainId: '0x1', + id: testNetworkConfigurationId, + }, + }, + }, + }, + async ({ controller }) => { + expect(() => + controller.removeNetworkConfiguration( + invalidNetworkConfigurationId, + ), + ).toThrow( + `networkConfigurationId ${invalidNetworkConfigurationId} does not match a configured networkConfiguration`, + ); + }, + ); + }); }); }); diff --git a/app/scripts/controllers/network/network-controller.ts b/app/scripts/controllers/network/network-controller.ts index 62d89b69f..9b95a8c7c 100644 --- a/app/scripts/controllers/network/network-controller.ts +++ b/app/scripts/controllers/network/network-controller.ts @@ -1141,9 +1141,12 @@ export class NetworkController extends EventEmitter { * @param networkConfigurationId - The unique id for the network configuration * to remove. */ - removeNetworkConfiguration( - networkConfigurationId: NetworkConfigurationId, - ): void { + removeNetworkConfiguration(networkConfigurationId: NetworkConfigurationId) { + if (!this.store.getState().networkConfigurations[networkConfigurationId]) { + throw new Error( + `networkConfigurationId ${networkConfigurationId} does not match a configured networkConfiguration`, + ); + } const networkConfigurations = { ...this.store.getState().networkConfigurations, }; From cb6223b75fbbb6a7df6bcc08632b6bed45c3281e Mon Sep 17 00:00:00 2001 From: Nidhi Kumari Date: Wed, 19 Apr 2023 22:22:53 +0530 Subject: [PATCH 16/25] removed portfolio icon from eth overview (#18662) --- .../app/wallet-overview/eth-overview.js | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/ui/components/app/wallet-overview/eth-overview.js b/ui/components/app/wallet-overview/eth-overview.js index 070076227..315ce61af 100644 --- a/ui/components/app/wallet-overview/eth-overview.js +++ b/ui/components/app/wallet-overview/eth-overview.js @@ -96,34 +96,36 @@ const EthOverview = ({ className }) => { {balanceIsCached ? ( * ) : null} - { - const portfolioUrl = process.env.PORTFOLIO_URL; - global.platform.openTab({ - url: `${portfolioUrl}?metamaskEntry=ext`, - }); - trackEvent( - { - category: MetaMetricsEventCategory.Home, - event: MetaMetricsEventName.PortfolioLinkClicked, - properties: { - url: portfolioUrl, + {process.env.MULTICHAIN ? null : ( + { + const portfolioUrl = process.env.PORTFOLIO_URL; + global.platform.openTab({ + url: `${portfolioUrl}?metamaskEntry=ext`, + }); + trackEvent( + { + category: MetaMetricsEventCategory.Home, + event: MetaMetricsEventName.PortfolioLinkClicked, + properties: { + url: portfolioUrl, + }, }, - }, - { - contextPropsIntoEventProperties: [ - MetaMetricsContextProp.PageTitle, - ], - }, - ); - }} - /> + { + contextPropsIntoEventProperties: [ + MetaMetricsContextProp.PageTitle, + ], + }, + ); + }} + /> + )} {showFiat && balance && ( Date: Wed, 19 Apr 2023 14:27:02 -0230 Subject: [PATCH 17/25] Fix Sentry console logs (#18539) Sentry console logs were failing with the error "Error: TypeError: Cannot read properties of undefined (reading 'log')". This error has been fixed; now Sentry can log errors to the console. Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- development/build/scripts.js | 1 + 1 file changed, 1 insertion(+) diff --git a/development/build/scripts.js b/development/build/scripts.js index 55323a454..393e43b35 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -72,6 +72,7 @@ const scuttlingConfigBase = { Date: '', JSON: '', encodeURIComponent: '', + console: '', crypto: '', // {clear/set}Timeout are "this sensitive" clearTimeout: 'window', From 1e5f481a51a2852125ae13537e44671e07b477ff Mon Sep 17 00:00:00 2001 From: Danica Shen Date: Wed, 19 Apr 2023 19:20:18 +0200 Subject: [PATCH 18/25] fix(18574): fix new BigNumber() not a number: undefined for setApprovalForAll method (#18660) --- ui/helpers/utils/token-util.js | 14 ++++----- ui/hooks/useAssetDetails.test.js | 50 ++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/ui/helpers/utils/token-util.js b/ui/helpers/utils/token-util.js index 882966472..e34bd9888 100644 --- a/ui/helpers/utils/token-util.js +++ b/ui/helpers/utils/token-util.js @@ -261,17 +261,15 @@ export async function getAssetDetails( // if we can't determine any token standard or details return the data we can extract purely from the parsed transaction data return { toAddress, tokenId }; } - + const tokenValue = getTokenValueParam(tokenData); + const tokenDecimals = tokenDetails?.decimals; const tokenAmount = tokenData && - tokenDetails?.decimals && - calcTokenAmount( - getTokenValueParam(tokenData), - tokenDetails?.decimals, - ).toString(10); + tokenValue && + tokenDecimals && + calcTokenAmount(tokenValue, tokenDecimals).toString(10); - const decimals = - tokenDetails?.decimals && Number(tokenDetails.decimals?.toString(10)); + const decimals = tokenDecimals && Number(tokenDecimals?.toString(10)); if (tokenDetails?.standard === TokenStandard.ERC20) { tokenId = undefined; diff --git a/ui/hooks/useAssetDetails.test.js b/ui/hooks/useAssetDetails.test.js index 6060c2dc2..f057a3f3e 100644 --- a/ui/hooks/useAssetDetails.test.js +++ b/ui/hooks/useAssetDetails.test.js @@ -37,12 +37,16 @@ describe('useAssetDetails', () => { let getTokenStandardAndDetailsStub; beforeEach(() => { - getTokenStandardAndDetailsStub = jest - .spyOn(Actions, 'getTokenStandardAndDetails') - .mockImplementation(() => Promise.resolve({})); + getTokenStandardAndDetailsStub = jest.spyOn( + Actions, + 'getTokenStandardAndDetails', + ); }); it('should return object with tokenSymbol set to an empty string, when getAssetDetails returns and empty object', async () => { + getTokenStandardAndDetailsStub.mockImplementation(() => + Promise.resolve({}), + ); const toAddress = '000000000000000000000000000000000000dead'; const tokenAddress = '0x1'; @@ -106,6 +110,46 @@ describe('useAssetDetails', () => { }); }); + it('should return object with correct tokenValues for an ERC20 token with no decimals', async () => { + const userAddress = '0xf04a5cc80b1e94c69b48f5ee68a08cd2f09a7c3e'; + const tokenAddress = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; + const toAddress = '000000000000000000000000000000000000dead'; + const transactionData = `0xa9059cbb000000000000000000000000${toAddress}00000000000000000000000000000000000000000000000000000000000001f4`; + + const standard = TokenStandard.ERC20; + const symbol = 'WETH'; + const balance = '1'; + + getTokenStandardAndDetailsStub.mockImplementation(() => + Promise.resolve({ + standard, + balance, + symbol, + }), + ); + + const { result, waitForNextUpdate } = renderUseAssetDetails({ + tokenAddress, + userAddress, + transactionData, + }); + + await waitForNextUpdate(); + + expect(result.current).toStrictEqual({ + assetAddress: tokenAddress, + assetName: undefined, + assetStandard: standard, + toAddress: `0x${toAddress}`, + tokenAmount: undefined, + tokenId: undefined, + tokenImage: undefined, + tokenSymbol: symbol, + userBalance: balance, + decimals: undefined, + }); + }); + it('should return object with correct tokenValues for an ERC721 token', async () => { const tokenAddress = '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D'; const toAddress = '000000000000000000000000000000000000dead'; From 4e1a96b4ef0ceda8c486655e16a8d4b8a72e55ad Mon Sep 17 00:00:00 2001 From: Garrett Bear Date: Wed, 19 Apr 2023 10:36:01 -0700 Subject: [PATCH 19/25] Feat/18308/ds popover header component (#18489) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add popover component popperjs init popperjs hook init popper arrow styles fix popover story add popover positions constant story testing popover structure popper placement make forwardref fix popover with TS updates modifiers createPortal add useClickAway hook newer popover component build simplifed popperjs with toggle to show/hide toggle popover modal version popover progress 65% add hover functionality hide folder storybook demo add close button props working popover with arrow title prop breaking popover TS conversion TS updates update test add test add arrow test add stories remove unused hook fix docs add popoverheader types fix Fix typo: detetcted-tokens-link -> detected-tokens-link (#18408) Typography to text (#18382) * Typography to text * Update README.md * Update README.md * minor changes in custom file * minor change * Resolved Conflict issues --------- Co-authored-by: Nidhi Kumari fix: Pass correct optimism chain id to gas estimation (#18478) removes unnecessary images (#18484) Fix firsttimeloaded logic (#18344) * use session storage, instead of chrome.runtime.onStartup and globalThis, for firstTimeLoaded architecture * Ensure account tracker accounts remain defined upon service worker restart * lint fix * Simplify code * Only call browser.storage.session in mv3 * Only call browser.storage.session.set after resetStates in mv3 * fix metamask controller reset states unit tests * fix test * fix test * Actually fix tests * lint fix [FLASK] More Snaps E2E Optimization and Delay Reductions (#18245) * bip32 delay reduction * asserts changed to waitFors in 32/44 * scrollTo change * replaced delay for firefox flake * more reduced delays * more delay reductions and changes * raise paralellism to 4 for snaps tests * additional delay changes * fixed update code * removed comment * removed another comment Fix switch-ethereum-chain handler by passing configuration id to setA… (#18483) * Fix switch-ethereum-chain handler by passing configuration id to setActiveNetwork * fix e2e test * Fix e2e tests * Update test/e2e/tests/switch-custom-network.spec.js Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> * Revert "Update test/e2e/tests/switch-custom-network.spec.js" This reverts commit be533ff7f25e1fd42e951d9b817b8438035ae256. --------- Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> Bumping notification id's to 18 & 19 (#18460) * Popover header update with TS ButtonIcon * update PopoverHeader types * update using new Text enums * readme fix * direct file import * remove forwardRef and add action argtypes * remove console.logs * add arg types and fix TS on HeaderBase * george nits * popover header snapshot update --------- Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- .../header-base/header-base.stories.tsx | 22 ++--- ui/components/component-library/index.js | 1 + .../popover-header/README.mdx | 98 +++++++++++++++++++ .../popover-header.test.tsx.snap | 20 ++++ .../component-library/popover-header/index.ts | 2 + .../popover-header/popover-header.stories.tsx | 65 ++++++++++++ .../popover-header/popover-header.test.tsx | 61 ++++++++++++ .../popover-header/popover-header.tsx | 61 ++++++++++++ .../popover-header/popover-header.types.ts | 42 ++++++++ 9 files changed, 361 insertions(+), 11 deletions(-) create mode 100644 ui/components/component-library/popover-header/README.mdx create mode 100644 ui/components/component-library/popover-header/__snapshots__/popover-header.test.tsx.snap create mode 100644 ui/components/component-library/popover-header/index.ts create mode 100644 ui/components/component-library/popover-header/popover-header.stories.tsx create mode 100644 ui/components/component-library/popover-header/popover-header.test.tsx create mode 100644 ui/components/component-library/popover-header/popover-header.tsx create mode 100644 ui/components/component-library/popover-header/popover-header.types.ts diff --git a/ui/components/component-library/header-base/header-base.stories.tsx b/ui/components/component-library/header-base/header-base.stories.tsx index c02ade945..6079b9f69 100644 --- a/ui/components/component-library/header-base/header-base.stories.tsx +++ b/ui/components/component-library/header-base/header-base.stories.tsx @@ -14,7 +14,7 @@ import { AlignItems, BackgroundColor, TextVariant, - TEXT_ALIGN, + TextAlign, } from '../../../helpers/constants/design-system'; import { HeaderBase } from './header-base'; import README from './README.mdx'; @@ -37,7 +37,7 @@ export const DefaultStory = Template.bind({}); DefaultStory.args = { children: ( - + Title is sentence case no period ), @@ -62,7 +62,7 @@ DefaultStory.storyName = 'Default'; export const Children = (args) => { return ( - + Title is sentence case no period @@ -82,7 +82,7 @@ export const StartAccessory = (args) => { } {...args} > - + Title is sentence case no period @@ -102,7 +102,7 @@ export const EndAccessory = (args) => { } {...args} > - + Title is sentence case no period @@ -116,7 +116,7 @@ export const UseCaseDemos = (args) => ( Title is sentence case no period @@ -139,7 +139,7 @@ export const UseCaseDemos = (args) => ( > Title is sentence case no period @@ -162,7 +162,7 @@ export const UseCaseDemos = (args) => ( > Title is sentence case no period @@ -193,7 +193,7 @@ export const UseCaseDemos = (args) => ( > Title is sentence case no period @@ -225,7 +225,7 @@ export const UseCaseDemos = (args) => ( > Title is sentence case no period @@ -260,7 +260,7 @@ export const UseCaseDemos = (args) => ( > Title is sentence case no period diff --git a/ui/components/component-library/index.js b/ui/components/component-library/index.js index 329c9e25c..c9eccf654 100644 --- a/ui/components/component-library/index.js +++ b/ui/components/component-library/index.js @@ -39,3 +39,4 @@ export { ModalOverlay } from './modal-overlay'; export { BannerBase } from './banner-base'; export { BannerAlert, BANNER_ALERT_SEVERITIES } from './banner-alert'; export { BannerTip, BannerTipLogoType } from './banner-tip'; +export { PopoverHeader } from './popover-header'; diff --git a/ui/components/component-library/popover-header/README.mdx b/ui/components/component-library/popover-header/README.mdx new file mode 100644 index 000000000..6910ec10c --- /dev/null +++ b/ui/components/component-library/popover-header/README.mdx @@ -0,0 +1,98 @@ +import { Story, Canvas, ArgsTable } from '@storybook/addon-docs'; +import { PopoverHeader } from './popover-header'; + +# PopoverHeader + +PopoverHeader is built on top of [HeaderBase](/docs/components-componentlibrary-headerbase--default-story) component with the most common use case of a back button in the startAccessory position, title, and close button in the endAccessory position. + + + + + +## Props + +The `PopoverHeader` accepts all props below as well as all [Box](/docs/ui-components-ui-box-box-stories-js--default-story#props) component props + + + +### Children + +Wrapping string content in the `PopoverHeader` component will be rendered in the center of the header with the default title `Text` component. + + + + + +```jsx +import { PopoverHeader } from '../../component-library'; + +Title is sentence case no period; +``` + +### onBack + +Use the onClick handler `onBack` prop to render the `ButtonIcon` back button in the startAccessory position. + +Use the `backButtonProps` prop to pass additional props to the `ButtonIcon` back button. + + + + + +```jsx +import { PopoverHeader } from '../../component-library'; + + console.log('Back button click')}> + OnBack Demo +; +``` + +### onClose + +Use the onClick handler `onClose` prop to render the `ButtonIcon` back button in the endAccessory position. + +Use the `backButtonProps` prop to pass additional props to the `ButtonIcon` back button. + + + + + +```jsx +import { PopoverHeader } from '../../component-library'; + + console.log('Back button click')}> + OnClose Demo +; +``` + +### startAccessory + +Use the `startAccessory` prop to render a component in the startAccessory position. This will override the default back `ButtonIcon`. + + + + + +```jsx +import { PopoverHeader, Button, BUTTON_SIZES } from '../../component-library'; + +Demo}> + StartAccessory +; +``` + +### endAccessory + +Use the `endAccessory` prop to render a component in the endAccessory position. This will override the default close `ButtonIcon`. + + + + + +```jsx +import { PopoverHeader, Button, BUTTON_SIZES } from '../../component-library'; + +Demo}> + EndAccessory +; +``` diff --git a/ui/components/component-library/popover-header/__snapshots__/popover-header.test.tsx.snap b/ui/components/component-library/popover-header/__snapshots__/popover-header.test.tsx.snap new file mode 100644 index 000000000..ff2a28597 --- /dev/null +++ b/ui/components/component-library/popover-header/__snapshots__/popover-header.test.tsx.snap @@ -0,0 +1,20 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PopoverHeader should render PopoverHeader correctly 1`] = ` +
+
+
+

+ Popover Header +

+
+
+
+`; diff --git a/ui/components/component-library/popover-header/index.ts b/ui/components/component-library/popover-header/index.ts new file mode 100644 index 000000000..158a08ff6 --- /dev/null +++ b/ui/components/component-library/popover-header/index.ts @@ -0,0 +1,2 @@ +export { PopoverHeader } from './popover-header'; +export type { PopoverHeaderProps } from './popover-header.types'; diff --git a/ui/components/component-library/popover-header/popover-header.stories.tsx b/ui/components/component-library/popover-header/popover-header.stories.tsx new file mode 100644 index 000000000..a5f5d175d --- /dev/null +++ b/ui/components/component-library/popover-header/popover-header.stories.tsx @@ -0,0 +1,65 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; +import { BUTTON_SIZES, Button } from '..'; +import { PopoverHeader } from './popover-header'; +import README from './README.mdx'; + +export default { + title: 'Components/ComponentLibrary/PopoverHeader', + component: PopoverHeader, + parameters: { + docs: { + page: README, + }, + }, + argTypes: { + children: { control: 'text' }, + className: { control: 'text' }, + onBack: { action: 'onBack' }, + onClose: { action: 'onClose' }, + }, + args: { + children: 'PopoverHeader', + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => { + return PopoverHeader; +}; + +export const DefaultStory = Template.bind({}); +DefaultStory.storyName = 'Default'; + +export const Children: ComponentStory = (args) => ( + +); + +Children.args = { + children: 'PopoverHeader Title', +}; + +export const OnBack: ComponentStory = (args) => ( + OnBack Demo +); + +export const OnClose: ComponentStory = (args) => ( + OnClose Demo +); + +export const StartAccessory: ComponentStory = (args) => ( + Demo} + {...args} + > + StartAccessory + +); + +export const EndAccessory: ComponentStory = (args) => ( + Demo} + {...args} + > + EndAccessory + +); diff --git a/ui/components/component-library/popover-header/popover-header.test.tsx b/ui/components/component-library/popover-header/popover-header.test.tsx new file mode 100644 index 000000000..ec5e4e203 --- /dev/null +++ b/ui/components/component-library/popover-header/popover-header.test.tsx @@ -0,0 +1,61 @@ +/* eslint-disable jest/require-top-level-describe */ +import { render, fireEvent } from '@testing-library/react'; +import React from 'react'; +import { PopoverHeader } from './popover-header'; + +describe('PopoverHeader', () => { + it('should render PopoverHeader correctly', () => { + const { getByTestId, container } = render( + + Popover Header + , + ); + expect(getByTestId('popover-header')).toHaveClass('mm-popover-header'); + expect(container).toMatchSnapshot(); + }); + + it('should render popover header title', () => { + const { getByText } = render( + + Popover Header Test + , + ); + expect(getByText('Popover Header Test')).toBeDefined(); + }); + + it('should render popover header back button', () => { + const onBackTest = jest.fn(); + const { getByTestId } = render( + + Popover + , + ); + + const backButton = getByTestId('back'); + fireEvent.click(backButton); + + expect(onBackTest).toHaveBeenCalled(); + }); + + it('should render popover header close button', () => { + const onCloseTest = jest.fn(); + const { getByTestId } = render( + + Popover + , + ); + + const closeButton = getByTestId('close'); + fireEvent.click(closeButton); + + expect(onCloseTest).toHaveBeenCalled(); + }); +}); diff --git a/ui/components/component-library/popover-header/popover-header.tsx b/ui/components/component-library/popover-header/popover-header.tsx new file mode 100644 index 000000000..1d6039e34 --- /dev/null +++ b/ui/components/component-library/popover-header/popover-header.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import classnames from 'classnames'; +import { HeaderBase, Text, ButtonIcon, ButtonIconSize, IconName } from '..'; +import { + TextVariant, + TextAlign, +} from '../../../helpers/constants/design-system'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { PopoverHeaderProps } from '.'; + +export const PopoverHeader: React.FC = ({ + children, + className = '', + startAccessory, + endAccessory, + onClose, + closeButtonProps, + onBack, + backButtonProps, + ...props +}) => { + const t = useI18nContext(); + return ( + + )) + } + endAccessory={ + endAccessory || + (onClose && ( + + )) + } + {...props} + > + {typeof children === 'string' ? ( + + {children} + + ) : ( + children + )} + + ); +}; diff --git a/ui/components/component-library/popover-header/popover-header.types.ts b/ui/components/component-library/popover-header/popover-header.types.ts new file mode 100644 index 000000000..66f8c7379 --- /dev/null +++ b/ui/components/component-library/popover-header/popover-header.types.ts @@ -0,0 +1,42 @@ +import React from 'react'; +import type { ButtonIconProps } from '../button-icon/button-icon.types'; +import type { HeaderBaseProps } from '../header-base'; + +export interface PopoverHeaderProps extends HeaderBaseProps { + /** + * The contents within the PopoverHeader positioned middle (popular for title use case) + */ + children?: React.ReactNode; + /** + * Additional classNames to be added to the Popover component + */ + className?: string; + /** + * The onClick handler for the back `ButtonIcon` + * When passed this will allow for the back `ButtonIcon` to show + */ + onBack?: () => void; + /** + * The props to pass to the back `ButtonIcon` + */ + backButtonProps?: ButtonIconProps; + /** + * The start (left) content area of PopoverHeader + * Default to have the back `ButtonIcon` when `onBack` is passed, but passing a `startAccessory` will override this + */ + startAccessory?: React.ReactNode; + /** + * The onClick handler for the close `ButtonIcon` + * When passed this will allow for the close `ButtonIcon` to show + */ + onClose?: () => void; + /** + * The props to pass to the close `ButtonIcon` + */ + closeButtonProps?: ButtonIconProps; + /** + * The end (right) content area of PopoverHeader + * Default to have the close `ButtonIcon` when `onClose` is passed, but passing a `endAccessory` will override this + */ + endAccessory?: React.ReactNode; +} From 21e07ae6ba561a1e237fd99dfe8fc7cf4ac2ce27 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Wed, 19 Apr 2023 20:38:27 +0200 Subject: [PATCH 20/25] use `history.replace()` instead of `history.push()` (#18663) --- .../permissions-connect.component.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/pages/permissions-connect/permissions-connect.component.js b/ui/pages/permissions-connect/permissions-connect.component.js index 9f3ef7592..4eaf97c6c 100644 --- a/ui/pages/permissions-connect/permissions-connect.component.js +++ b/ui/pages/permissions-connect/permissions-connect.component.js @@ -116,7 +116,7 @@ export default class PermissionConnect extends Component { getRequestAccountTabIds(); if (!permissionsRequest) { - history.push(DEFAULT_ROUTE); + history.replace(DEFAULT_ROUTE); return; } @@ -130,17 +130,17 @@ export default class PermissionConnect extends Component { switch (requestType) { case 'wallet_installSnap': - history.push(snapInstallPath); + history.replace(snapInstallPath); break; case 'wallet_updateSnap': - history.push(snapUpdatePath); + history.replace(snapUpdatePath); break; case 'wallet_installSnapResult': - history.push(snapResultPath); + history.replace(snapResultPath); break; default: ///: END:ONLY_INCLUDE_IN - history.push(confirmPermissionPath); + history.replace(confirmPermissionPath); ///: BEGIN:ONLY_INCLUDE_IN(flask) } ///: END:ONLY_INCLUDE_IN From 7ca93837851bc4927ef17d6acb5d66dd85fa9345 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Wed, 19 Apr 2023 18:15:26 -0230 Subject: [PATCH 21/25] Fix swaps controller: update provider after networkIdStore state update (#18670) * Fix swaps controller: update provider after networkIdStore state update * Listen for changes on networkController.store, instead of networkController.networkIdStore, in the swaps controller * Fix unit tests --- app/scripts/controllers/swaps.js | 4 ++-- app/scripts/controllers/swaps.test.js | 20 ++++++++++---------- app/scripts/metamask-controller.js | 6 ++---- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/app/scripts/controllers/swaps.js b/app/scripts/controllers/swaps.js index 5030f1cd3..b44e66a21 100644 --- a/app/scripts/controllers/swaps.js +++ b/app/scripts/controllers/swaps.js @@ -113,7 +113,7 @@ export default class SwapsController { fetchTradesInfo = defaultFetchTradesInfo, getCurrentChainId, getEIP1559GasFeeEstimates, - onNetworkDidChange, + onNetworkStateChange, }) { this.store = new ObservableStore({ swapsState: { ...initialState.swapsState }, @@ -137,7 +137,7 @@ export default class SwapsController { this.ethersProvider = new Web3Provider(provider); this._currentNetworkId = networkController.store.getState().networkId; - onNetworkDidChange(() => { + onNetworkStateChange(() => { const { networkId, networkStatus } = networkController.store.getState(); if ( networkStatus === NetworkStatus.Available && diff --git a/app/scripts/controllers/swaps.test.js b/app/scripts/controllers/swaps.test.js index f5a43e0dc..e3dbaafda 100644 --- a/app/scripts/controllers/swaps.test.js +++ b/app/scripts/controllers/swaps.test.js @@ -160,7 +160,7 @@ describe('SwapsController', function () { return new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController: getMockNetworkController(), - onNetworkDidChange: sinon.stub(), + onNetworkStateChange: sinon.stub(), provider: _provider, getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getTokenRatesState: MOCK_TOKEN_RATES_STORE, @@ -208,11 +208,11 @@ describe('SwapsController', function () { it('should replace ethers instance when network changes', function () { const networkController = getMockNetworkController(); - const onNetworkDidChange = sinon.stub(); + const onNetworkStateChange = sinon.stub(); const swapsController = new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController, - onNetworkDidChange, + onNetworkStateChange, provider, getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getTokenRatesState: MOCK_TOKEN_RATES_STORE, @@ -220,7 +220,7 @@ describe('SwapsController', function () { getCurrentChainId: getCurrentChainIdStub, }); const currentEthersInstance = swapsController.ethersProvider; - const changeNetwork = onNetworkDidChange.getCall(0).args[0]; + const changeNetwork = onNetworkStateChange.getCall(0).args[0]; networkController.store.getState.returns({ networkId: NETWORK_IDS.MAINNET, @@ -238,11 +238,11 @@ describe('SwapsController', function () { it('should not replace ethers instance when network changes to loading', function () { const networkController = getMockNetworkController(); - const onNetworkDidChange = sinon.stub(); + const onNetworkStateChange = sinon.stub(); const swapsController = new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController, - onNetworkDidChange, + onNetworkStateChange, provider, getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getTokenRatesState: MOCK_TOKEN_RATES_STORE, @@ -250,7 +250,7 @@ describe('SwapsController', function () { getCurrentChainId: getCurrentChainIdStub, }); const currentEthersInstance = swapsController.ethersProvider; - const changeNetwork = onNetworkDidChange.getCall(0).args[0]; + const changeNetwork = onNetworkStateChange.getCall(0).args[0]; networkController.store.getState.returns({ networkId: null, @@ -268,11 +268,11 @@ describe('SwapsController', function () { it('should not replace ethers instance when network changes to the same network', function () { const networkController = getMockNetworkController(); - const onNetworkDidChange = sinon.stub(); + const onNetworkStateChange = sinon.stub(); const swapsController = new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController, - onNetworkDidChange, + onNetworkStateChange, provider, getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getTokenRatesState: MOCK_TOKEN_RATES_STORE, @@ -280,7 +280,7 @@ describe('SwapsController', function () { getCurrentChainId: getCurrentChainIdStub, }); const currentEthersInstance = swapsController.ethersProvider; - const changeNetwork = onNetworkDidChange.getCall(0).args[0]; + const changeNetwork = onNetworkStateChange.getCall(0).args[0]; networkController.store.getState.returns({ networkId: NETWORK_IDS.GOERLI, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index fa619c62f..f24e1777a 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1195,10 +1195,8 @@ export default class MetamaskController extends EventEmitter { this.txController.txGasUtil, ), networkController: this.networkController, - onNetworkDidChange: networkControllerMessenger.subscribe.bind( - networkControllerMessenger, - NetworkControllerEventType.NetworkDidChange, - ), + onNetworkStateChange: (listener) => + this.networkController.store.subscribe(listener), provider: this.provider, getProviderConfig: () => this.networkController.store.getState().provider, getTokenRatesState: () => this.tokenRatesController.state, From 34c1e5a2a1e4c7d32f4d0e7b0e64236897f81536 Mon Sep 17 00:00:00 2001 From: Garrett Bear Date: Wed, 19 Apr 2023 14:16:49 -0700 Subject: [PATCH 22/25] Fix/18492/update icon ts app folder (#18645) --- .../account-menu/account-menu.component.js | 30 ++++++------------- ui/components/app/add-network/add-network.js | 11 ++----- .../approve-content-card.stories.js | 4 +-- .../app/asset-list-item/asset-list-item.js | 10 ++----- ui/components/app/beta-header/index.js | 10 ++----- ...confirm-page-container-header.component.js | 4 +-- .../confirmation-warning-modal.js | 11 ++----- ...nnected-accounts-list-options.component.js | 5 ++-- .../connected-accounts-list.component.js | 4 +-- .../custom-spending-cap.test.js.snap | 2 +- .../custom-spending-cap-tooltip.js | 14 ++++----- .../custom-spending-cap.js | 5 ++-- .../app/dropdowns/network-dropdown.js | 16 ++++------ .../edit-gas-fee-button.js | 10 ++----- ui/components/app/flask/copyable/copyable.js | 14 ++++----- .../flask/snap-authorship/snap-authorship.js | 11 ++----- .../app/flask/snap-avatar/snap-avatar.js | 12 ++++---- .../snap-content-footer.js | 4 +-- .../flask/snap-delineator/snap-delineator.js | 15 +++++----- .../snap-install-warning.js | 5 ++-- .../app/menu-bar/account-options-menu.js | 12 ++++---- ui/components/app/menu-bar/menu-bar.js | 5 ++-- .../contract-details-modal.js | 13 ++++---- .../customize-nonce.component.js | 12 ++++---- .../edit-approval-permission.component.js | 12 ++++---- .../hold-to-reveal-modal.js | 12 +++++--- .../new-account-modal.component.js | 5 ++-- .../transaction-confirmed.component.js | 10 ++----- .../app/network-display/network-display.js | 10 ++----- ui/components/app/nft-details/nft-details.js | 5 ++-- ui/components/app/nft-options/nft-options.js | 9 +++--- ui/components/app/nfts-items/nfts-items.js | 6 ++-- .../app/permission-cell/permission-cell.js | 27 +++++++++-------- .../selected-account.component.js | 12 ++------ .../set-approval-for-all-warning.js | 4 +-- .../signature-request-original-warning.js | 4 +-- .../signature-request-siwe-icon/index.js | 4 +-- ui/components/app/tab-bar/tab-bar.js | 10 ++----- ui/components/app/tab-bar/tab-bar.stories.js | 8 ++--- ...transaction-activity-log-icon.component.js | 24 +++++++-------- .../copy-raw-data/copy-raw-data.component.js | 7 ++--- .../app/wallet-overview/eth-overview.js | 21 +++++++------ .../app/wallet-overview/token-overview.js | 15 ++++------ .../avatar-base/avatar-base.js | 6 +++- .../avatar-icon/avatar-icon.js | 5 +++- 45 files changed, 186 insertions(+), 269 deletions(-) diff --git a/ui/components/app/account-menu/account-menu.component.js b/ui/components/app/account-menu/account-menu.component.js index e11980489..7c0b98bc3 100644 --- a/ui/components/app/account-menu/account-menu.component.js +++ b/ui/components/app/account-menu/account-menu.component.js @@ -37,11 +37,7 @@ import Button from '../../ui/button'; import SearchIcon from '../../ui/icon/search-icon'; import { SUPPORT_LINK } from '../../../../shared/lib/ui-utils'; import { IconColor } from '../../../helpers/constants/design-system'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; import KeyRingLabel from './keyring-label'; export function AccountMenuItem(props) { @@ -229,8 +225,8 @@ export default class AccountMenu extends Component { {isSelected ? ( ) : null} @@ -374,9 +370,7 @@ export default class AccountMenu extends Component { }); history.push(NEW_ACCOUNT_ROUTE); }} - icon={ - - } + icon={} text={t('createAccount')} /> + } text={t('importAccount')} /> @@ -415,10 +409,7 @@ export default class AccountMenu extends Component { } }} icon={ - + } text={t('connectHardwareWallet')} /> @@ -433,7 +424,7 @@ export default class AccountMenu extends Component { }} icon={
- + {unreadNotificationsCount > 0 && (
{unreadNotificationsCount} @@ -466,10 +457,7 @@ export default class AccountMenu extends Component { global.platform.openTab({ url: supportLink }); }} icon={ - + } text={supportText} /> @@ -488,7 +476,7 @@ export default class AccountMenu extends Component { }} icon={ diff --git a/ui/components/app/add-network/add-network.js b/ui/components/app/add-network/add-network.js index 83ec791b9..d8eae27ee 100644 --- a/ui/components/app/add-network/add-network.js +++ b/ui/components/app/add-network/add-network.js @@ -36,12 +36,7 @@ import { FEATURED_RPCS } from '../../../../shared/constants/network'; import { ADD_NETWORK_ROUTE } from '../../../helpers/constants/routes'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; -import { Text } from '../../component-library'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Text, Icon, IconName, IconSize } from '../../component-library'; import { MetaMetricsNetworkEventSource } from '../../../../shared/constants/metametrics'; const AddNetwork = () => { @@ -249,9 +244,9 @@ const AddNetwork = () => { > ) diff --git a/ui/components/app/approve-content-card/approve-content-card.stories.js b/ui/components/app/approve-content-card/approve-content-card.stories.js index 6ae43c22c..17216ba18 100644 --- a/ui/components/app/approve-content-card/approve-content-card.stories.js +++ b/ui/components/app/approve-content-card/approve-content-card.stories.js @@ -1,5 +1,5 @@ import React from 'react'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../component-library'; import ApproveContentCard from './approve-content-card'; export default { @@ -72,7 +72,7 @@ export default { }, args: { showHeader: true, - symbol: , + symbol: , title: 'Transaction fee', showEdit: true, showAdvanceGasFeeOptions: true, 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 2be1b78b6..d5b2b3f63 100644 --- a/ui/components/app/asset-list-item/asset-list-item.js +++ b/ui/components/app/asset-list-item/asset-list-item.js @@ -16,11 +16,7 @@ import { INVALID_ASSET_TYPE } from '../../../helpers/constants/error-keys'; 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/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; import Box from '../../ui/box/box'; const AssetListItem = ({ @@ -143,9 +139,9 @@ const AssetListItem = ({ !isERC721 && ( {sendTokenButton} diff --git a/ui/components/app/beta-header/index.js b/ui/components/app/beta-header/index.js index f030d53f6..1eb7bfbe0 100644 --- a/ui/components/app/beta-header/index.js +++ b/ui/components/app/beta-header/index.js @@ -14,11 +14,7 @@ import { import { BETA_BUGS_URL } from '../../../helpers/constants/beta'; import { hideBetaHeader } from '../../../store/actions'; -import { ButtonIcon } from '../../component-library/button-icon/deprecated'; -import { - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { ButtonIcon, ButtonIconSize, IconName } from '../../component-library'; const BetaHeader = () => { const t = useI18nContext(); @@ -51,8 +47,8 @@ const BetaHeader = () => { ])} - + { const t = useI18nContext(); @@ -60,10 +55,10 @@ const ConfirmationWarningModal = ({ onSubmit, onCancel }) => { className="confirmation-warning-modal__content__header" > - + {t('disconnectThisAccount')} diff --git a/ui/components/app/custom-spending-cap/__snapshots__/custom-spending-cap.test.js.snap b/ui/components/app/custom-spending-cap/__snapshots__/custom-spending-cap.test.js.snap index ba7f51b89..d72f4736d 100644 --- a/ui/components/app/custom-spending-cap/__snapshots__/custom-spending-cap.test.js.snap +++ b/ui/components/app/custom-spending-cap/__snapshots__/custom-spending-cap.test.js.snap @@ -42,7 +42,7 @@ exports[`CustomSpendingCap should match snapshot 1`] = ` tabindex="0" >
diff --git a/ui/components/app/custom-spending-cap/custom-spending-cap-tooltip.js b/ui/components/app/custom-spending-cap/custom-spending-cap-tooltip.js index b9113b2c1..49aebd8e4 100644 --- a/ui/components/app/custom-spending-cap/custom-spending-cap-tooltip.js +++ b/ui/components/app/custom-spending-cap/custom-spending-cap-tooltip.js @@ -8,11 +8,7 @@ import { DISPLAY, TypographyVariant, } from '../../../helpers/constants/design-system'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; export const CustomSpendingCapTooltip = ({ tooltipContentText, @@ -35,13 +31,15 @@ export const CustomSpendingCapTooltip = ({ > {tooltipIcon ? ( ) : ( - tooltipIcon !== '' && + tooltipIcon !== '' && ( + + ) )} diff --git a/ui/components/app/custom-spending-cap/custom-spending-cap.js b/ui/components/app/custom-spending-cap/custom-spending-cap.js index 23e8d16ee..0614b0f36 100644 --- a/ui/components/app/custom-spending-cap/custom-spending-cap.js +++ b/ui/components/app/custom-spending-cap/custom-spending-cap.js @@ -8,8 +8,7 @@ import { addHexPrefix } from 'ethereumjs-util'; import { I18nContext } from '../../../contexts/i18n'; import Box from '../../ui/box'; import FormField from '../../ui/form-field'; -import { Text, ButtonLink } from '../../component-library'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Text, ButtonLink, Icon, IconName } from '../../component-library'; import { AlignItems, DISPLAY, @@ -196,7 +195,7 @@ export default function CustomSpendingCap({ as="h6" color={TextColor.errorDefault} > - {t('beCareful')} + {t('beCareful')} , ]) : t('inputLogicEmptyState'); diff --git a/ui/components/app/dropdowns/network-dropdown.js b/ui/components/app/dropdowns/network-dropdown.js index 131b700f6..8b44fed0e 100644 --- a/ui/components/app/dropdowns/network-dropdown.js +++ b/ui/components/app/dropdowns/network-dropdown.js @@ -33,11 +33,7 @@ import { ADVANCED_ROUTE, } from '../../../helpers/constants/routes'; import { ButtonIcon } from '../../component-library/button-icon/deprecated'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; import { Dropdown, DropdownMenuItem } from './dropdown'; @@ -191,7 +187,7 @@ class NetworkDropdown extends Component { }} > {isCurrentRpcTarget ? ( - + ) : (
)} @@ -214,8 +210,8 @@ class NetworkDropdown extends Component { {isCurrentRpcTarget ? null : ( { e.stopPropagation(); @@ -265,7 +261,7 @@ class NetworkDropdown extends Component { style={DROP_DOWN_MENU_ITEM_STYLE} > {providerType === network ? ( - + ) : (
)} @@ -334,7 +330,7 @@ class NetworkDropdown extends Component { style={DROP_DOWN_MENU_ITEM_STYLE} > {isCurrentRpcTarget ? ( - + ) : (
)} diff --git a/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js b/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js index 378be5480..e3ee7fa00 100644 --- a/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js +++ b/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js @@ -14,11 +14,7 @@ import { useTransactionEventFragment } from '../../../hooks/useTransactionEventF import { useTransactionModalContext } from '../../../contexts/transaction-modal'; import InfoTooltip from '../../ui/info-tooltip/info-tooltip'; import Typography from '../../ui/typography/typography'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; export default function EditGasFeeButton({ userAcknowledgedGasMissing }) { const t = useI18nContext(); @@ -78,9 +74,9 @@ export default function EditGasFeeButton({ userAcknowledgedGasMissing }) { )} {t(title)} {estimateUsed === 'custom' && ( diff --git a/ui/components/app/flask/copyable/copyable.js b/ui/components/app/flask/copyable/copyable.js index 2741fd6c4..59cb51e6b 100644 --- a/ui/components/app/flask/copyable/copyable.js +++ b/ui/components/app/flask/copyable/copyable.js @@ -14,11 +14,7 @@ import { Color, } from '../../../../helpers/constants/design-system'; import { useCopyToClipboard } from '../../../../hooks/useCopyToClipboard'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../../component-library'; export const Copyable = ({ text }) => { const [copied, handleCopy] = useCopyToClipboard(); @@ -51,14 +47,14 @@ export const Copyable = ({ text }) => { > {copied ? ( ) : ( handleCopy(text)} /> diff --git a/ui/components/app/flask/snap-authorship/snap-authorship.js b/ui/components/app/flask/snap-authorship/snap-authorship.js index 4c44d20eb..66f3fa59b 100644 --- a/ui/components/app/flask/snap-authorship/snap-authorship.js +++ b/ui/components/app/flask/snap-authorship/snap-authorship.js @@ -20,12 +20,8 @@ import { getSnapName, removeSnapIdPrefix, } from '../../../../helpers/utils/util'; -import { ButtonIcon } from '../../../component-library/button-icon/deprecated'; -import { Text } from '../../../component-library'; -import { - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; +import { ButtonIcon, IconName, Text } from '../../../component-library'; + import { getTargetSubjectMetadata } from '../../../../selectors'; import SnapAvatar from '../snap-avatar'; @@ -85,9 +81,8 @@ const SnapAuthorship = ({ snapId, className }) => { rel="noopener noreferrer" target="_blank" href={url} - iconName={ICON_NAMES.EXPORT} + iconName={IconName.Export} color={IconColor.infoDefault} - size={ICON_SIZES.MD} style={{ marginLeft: 'auto' }} /> diff --git a/ui/components/app/flask/snap-avatar/snap-avatar.js b/ui/components/app/flask/snap-avatar/snap-avatar.js index 81e101b81..4e16b8a2a 100644 --- a/ui/components/app/flask/snap-avatar/snap-avatar.js +++ b/ui/components/app/flask/snap-avatar/snap-avatar.js @@ -17,11 +17,9 @@ import { BadgeWrapperPosition, AvatarIcon, AvatarBase, + IconName, + IconSize, } from '../../../component-library'; -import { - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; import { getTargetSubjectMetadata } from '../../../../selectors'; const SnapAvatar = ({ snapId, className }) => { @@ -40,11 +38,11 @@ const SnapAvatar = ({ snapId, className }) => { className={classnames('snap-avatar', className)} badge={ diff --git a/ui/components/app/flask/snap-content-footer/snap-content-footer.js b/ui/components/app/flask/snap-content-footer/snap-content-footer.js index aa5f385d1..f8b31826a 100644 --- a/ui/components/app/flask/snap-content-footer/snap-content-footer.js +++ b/ui/components/app/flask/snap-content-footer/snap-content-footer.js @@ -16,7 +16,7 @@ import { } from '../../../../helpers/constants/design-system'; import Button from '../../../ui/button'; import Box from '../../../ui/box/box'; -import { Icon, ICON_NAMES } from '../../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../../component-library'; export default function SnapContentFooter({ snapName, snapId }) { const t = useI18nContext(); @@ -36,7 +36,7 @@ export default function SnapContentFooter({ snapName, snapId }) { className="snap-content-footer" > diff --git a/ui/components/app/flask/snap-install-warning/snap-install-warning.js b/ui/components/app/flask/snap-install-warning/snap-install-warning.js index 31365909f..94e8c091c 100644 --- a/ui/components/app/flask/snap-install-warning/snap-install-warning.js +++ b/ui/components/app/flask/snap-install-warning/snap-install-warning.js @@ -15,8 +15,7 @@ import { } from '../../../../helpers/constants/design-system'; import Popover from '../../../ui/popover'; import Button from '../../../ui/button'; -import { AvatarIcon, Text } from '../../../component-library'; -import { ICON_NAMES } from '../../../component-library/icon/deprecated'; +import { AvatarIcon, Text, IconName } from '../../../component-library'; import Box from '../../../ui/box/box'; /** @@ -79,7 +78,7 @@ export default function SnapInstallWarning({ onCancel, onSubmit, warnings }) { > ) : null } - iconName={ICON_NAMES.EXPORT} + iconName={IconName.Export} > {t( blockExplorerLinkText.firstPart, @@ -109,7 +109,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { global.platform.openExtensionInBrowser(); onClose(); }} - iconName={ICON_NAMES.EXPAND} + iconName={IconName.Expand} > {t('expandView')} @@ -127,7 +127,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { }); onClose(); }} - iconName={ICON_NAMES.SCAN_BARCODE} + iconName={IconName.ScanBarcode} > {t('accountDetails')} @@ -144,7 +144,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { history.push(CONNECTED_ROUTE); onClose(); }} - iconName={ICON_NAMES.CONNECT} + iconName={IconName.Connect} > {t('connectedSites')} @@ -160,7 +160,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { ); onClose(); }} - iconName={ICON_NAMES.TRASH} + iconName={IconName.Trash} > {t('removeAccount')} diff --git a/ui/components/app/menu-bar/menu-bar.js b/ui/components/app/menu-bar/menu-bar.js index 08da8208f..7732a3c58 100644 --- a/ui/components/app/menu-bar/menu-bar.js +++ b/ui/components/app/menu-bar/menu-bar.js @@ -14,8 +14,7 @@ import { CONNECTED_ACCOUNTS_ROUTE } from '../../../helpers/constants/routes'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { getOriginOfCurrentTab } from '../../../selectors'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { ButtonIcon } from '../../component-library/button-icon/deprecated'; -import { ICON_NAMES } from '../../component-library/icon/deprecated'; +import { ButtonIcon, IconName } from '../../component-library'; import AccountOptionsMenu from './account-options-menu'; export default function MenuBar() { @@ -41,7 +40,7 @@ export default function MenuBar() { handleCopyTokenAddress(tokenAddress)} color={Color.iconMuted} @@ -163,7 +160,7 @@ export default function ContractDetailsModal({ { const blockExplorerTokenLink = getAccountLink( @@ -244,7 +241,7 @@ export default function ContractDetailsModal({ handleCopyToAddress(toAddress)} color={Color.iconMuted} @@ -258,7 +255,7 @@ export default function ContractDetailsModal({ { const blockExplorerTokenLink = getAccountLink( diff --git a/ui/components/app/modals/customize-nonce/customize-nonce.component.js b/ui/components/app/modals/customize-nonce/customize-nonce.component.js index e1e0a944b..58d3ab79a 100644 --- a/ui/components/app/modals/customize-nonce/customize-nonce.component.js +++ b/ui/components/app/modals/customize-nonce/customize-nonce.component.js @@ -15,11 +15,11 @@ import Box from '../../../ui/box'; import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import ZENDESK_URLS from '../../../../helpers/constants/zendesk-url'; -import { ButtonIcon } from '../../../component-library/button-icon/deprecated'; import { - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; + ButtonIcon, + ButtonIconSize, + IconName, +} from '../../../component-library'; const CustomizeNonce = ({ hideModal, @@ -58,9 +58,9 @@ const CustomizeNonce = ({ {t('editNonceField')} diff --git a/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js b/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js index 3c3b85cf0..caccc2ad6 100644 --- a/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js +++ b/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js @@ -10,11 +10,11 @@ import { calcTokenAmount, toPrecisionWithoutTrailingZeros, } from '../../../../../shared/lib/transactions-controller-utils'; -import { ButtonIcon } from '../../../component-library/button-icon/deprecated'; import { - ICON_SIZES, - ICON_NAMES, -} from '../../../component-library/icon/deprecated'; + ButtonIcon, + ButtonIconSize, + IconName, +} from '../../../component-library'; const MAX_UNSIGNED_256_INT = new BigNumber(2).pow(256).minus(1).toString(10); @@ -63,8 +63,8 @@ export default class EditApprovalPermission extends PureComponent { {t('editPermission')}
diff --git a/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.js b/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.js index de5a6a962..bf4b42ccf 100644 --- a/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.js +++ b/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.js @@ -2,9 +2,13 @@ import PropTypes from 'prop-types'; import React from 'react'; import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; import Box from '../../../ui/box'; -import { Text, Button, BUTTON_TYPES } from '../../../component-library'; -import { ButtonIcon } from '../../../component-library/button-icon/deprecated'; -import { ICON_NAMES } from '../../../component-library/icon/deprecated'; +import { + Text, + Button, + BUTTON_TYPES, + ButtonIcon, + IconName, +} from '../../../component-library'; import { AlignItems, DISPLAY, @@ -47,7 +51,7 @@ const HoldToRevealModal = ({ onLongPressed, hideModal }) => { {t('holdToRevealTitle')}
diff --git a/ui/components/app/modals/transaction-confirmed/transaction-confirmed.component.js b/ui/components/app/modals/transaction-confirmed/transaction-confirmed.component.js index 5899562d4..c5f112eef 100644 --- a/ui/components/app/modals/transaction-confirmed/transaction-confirmed.component.js +++ b/ui/components/app/modals/transaction-confirmed/transaction-confirmed.component.js @@ -1,11 +1,7 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import Modal from '../../modal'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../../component-library'; import { IconColor } from '../../../../helpers/constants/design-system'; export default class TransactionConfirmed extends PureComponent { @@ -35,9 +31,9 @@ export default class TransactionConfirmed extends PureComponent {
{`${t('confirmed')}!`} diff --git a/ui/components/app/network-display/network-display.js b/ui/components/app/network-display/network-display.js index 24519801b..57670908a 100644 --- a/ui/components/app/network-display/network-display.js +++ b/ui/components/app/network-display/network-display.js @@ -18,11 +18,7 @@ import { import Chip from '../../ui/chip/chip'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { isNetworkLoading } from '../../../selectors'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; export default function NetworkDisplay({ indicatorSize, @@ -70,9 +66,7 @@ export default function NetworkDisplay({ } rightIcon={ - onClick ? ( - - ) : null + onClick ? : null } label={ networkType === NETWORK_TYPES.RPC diff --git a/ui/components/app/nft-details/nft-details.js b/ui/components/app/nft-details/nft-details.js index 1888f32f1..336d5a96c 100644 --- a/ui/components/app/nft-details/nft-details.js +++ b/ui/components/app/nft-details/nft-details.js @@ -53,8 +53,7 @@ import { TokenStandard, } from '../../../../shared/constants/transaction'; import NftDefaultImage from '../nft-default-image'; -import { ButtonIcon } from '../../component-library/button-icon/deprecated'; -import { ICON_NAMES } from '../../component-library/icon/deprecated'; +import { ButtonIcon, IconName } from '../../component-library'; import Tooltip from '../../ui/tooltip'; import { decWEIToDecETH } from '../../../../shared/modules/conversion.utils'; @@ -427,7 +426,7 @@ export default function NftDetails({ nft }) { handleAddressCopy(address); }} iconName={ - addressCopied ? ICON_NAMES.COPY_SUCCESS : ICON_NAMES.COPY + addressCopied ? IconName.CopySuccess : IconName.Copy } /> diff --git a/ui/components/app/nft-options/nft-options.js b/ui/components/app/nft-options/nft-options.js index e67525f7c..1ff1c55f1 100644 --- a/ui/components/app/nft-options/nft-options.js +++ b/ui/components/app/nft-options/nft-options.js @@ -3,8 +3,7 @@ import PropTypes from 'prop-types'; import { I18nContext } from '../../../contexts/i18n'; import { Menu, MenuItem } from '../../ui/menu'; -import { ButtonIcon } from '../../component-library/button-icon/deprecated'; -import { ICON_NAMES } from '../../component-library/icon/deprecated'; +import { ButtonIcon, IconName } from '../../component-library'; import { Color } from '../../../helpers/constants/design-system'; const NftOptions = ({ onRemove, onViewOnOpensea }) => { @@ -15,7 +14,7 @@ const NftOptions = ({ onRemove, onViewOnOpensea }) => { return (
setNftOptionsOpen(true)} @@ -31,7 +30,7 @@ const NftOptions = ({ onRemove, onViewOnOpensea }) => { > {onViewOnOpensea ? ( { setNftOptionsOpen(false); @@ -42,7 +41,7 @@ const NftOptions = ({ onRemove, onViewOnOpensea }) => { ) : null} { setNftOptionsOpen(false); diff --git a/ui/components/app/nfts-items/nfts-items.js b/ui/components/app/nfts-items/nfts-items.js index 0e865b1b8..03d4d8f7d 100644 --- a/ui/components/app/nfts-items/nfts-items.js +++ b/ui/components/app/nfts-items/nfts-items.js @@ -30,7 +30,7 @@ import { updateNftDropDownState } from '../../../store/actions'; import { usePrevious } from '../../../hooks/usePrevious'; import { getNftsDropdownState } from '../../../ducks/metamask/metamask'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../component-library'; import NftDefaultImage from '../nft-default-image'; const width = @@ -158,9 +158,7 @@ export default function NftsItems({ diff --git a/ui/components/app/permission-cell/permission-cell.js b/ui/components/app/permission-cell/permission-cell.js index fbbafea43..cb9a10d8d 100644 --- a/ui/components/app/permission-cell/permission-cell.js +++ b/ui/components/app/permission-cell/permission-cell.js @@ -11,12 +11,13 @@ import { TextColor, TextVariant, } from '../../../helpers/constants/design-system'; -import { AvatarIcon, Text } from '../../component-library'; import { + AvatarIcon, + Text, Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; + IconName, + IconSize, +} from '../../component-library'; import { formatDate } from '../../../helpers/utils/util'; import { useI18nContext } from '../../../hooks/useI18nContext'; import Tooltip from '../../ui/tooltip'; @@ -32,24 +33,24 @@ const PermissionCell = ({ const t = useI18nContext(); let infoIconColor = IconColor.iconMuted; - let infoIcon = ICON_NAMES.INFO; - let iconColor = Color.primaryDefault; + let infoIcon = IconName.Info; + let iconColor = IconColor.primaryDefault; let iconBackgroundColor = Color.primaryMuted; if (!revoked && weight === 1) { - iconColor = Color.warningDefault; + iconColor = IconColor.warningDefault; iconBackgroundColor = Color.warningMuted; infoIconColor = IconColor.warningDefault; - infoIcon = ICON_NAMES.DANGER; + infoIcon = IconName.Danger; } if (dateApproved) { - iconColor = Color.iconMuted; + iconColor = IconColor.iconMuted; iconBackgroundColor = Color.backgroundAlternative; } if (revoked) { - iconColor = Color.iconMuted; + iconColor = IconColor.iconMuted; iconBackgroundColor = Color.backgroundAlternative; } @@ -72,9 +73,9 @@ const PermissionCell = ({ {typeof permissionIcon === 'string' ? ( {description}
} position="bottom"> - + diff --git a/ui/components/app/selected-account/selected-account.component.js b/ui/components/app/selected-account/selected-account.component.js index 08746392e..3dab4e12a 100644 --- a/ui/components/app/selected-account/selected-account.component.js +++ b/ui/components/app/selected-account/selected-account.component.js @@ -6,11 +6,7 @@ import { shortenAddress } from '../../../helpers/utils/util'; import Tooltip from '../../ui/tooltip'; import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils'; import { SECOND } from '../../../../shared/constants/time'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; import { IconColor } from '../../../helpers/constants/design-system'; class SelectedAccount extends Component { @@ -71,11 +67,9 @@ class SelectedAccount extends Component {
diff --git a/ui/components/app/set-approval-for-all-warning/set-approval-for-all-warning.js b/ui/components/app/set-approval-for-all-warning/set-approval-for-all-warning.js index f6f0794f6..f5dfe26ee 100644 --- a/ui/components/app/set-approval-for-all-warning/set-approval-for-all-warning.js +++ b/ui/components/app/set-approval-for-all-warning/set-approval-for-all-warning.js @@ -16,7 +16,7 @@ import { } from '../../../helpers/constants/design-system'; import Identicon from '../../ui/identicon'; import { shortenAddress } from '../../../helpers/utils/util'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../component-library'; const SetApproveForAllWarning = ({ collectionName, @@ -62,7 +62,7 @@ const SetApproveForAllWarning = ({ className="set-approval-for-all-warning__content__header" > diff --git a/ui/components/app/signature-request-siwe/signature-request-siwe-icon/index.js b/ui/components/app/signature-request-siwe/signature-request-siwe-icon/index.js index 7ef015ab5..ef85b2e6b 100644 --- a/ui/components/app/signature-request-siwe/signature-request-siwe-icon/index.js +++ b/ui/components/app/signature-request-siwe/signature-request-siwe-icon/index.js @@ -6,7 +6,7 @@ import { JustifyContent, } from '../../../../helpers/constants/design-system'; import Box from '../../../ui/box'; -import { Icon, ICON_NAMES } from '../../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../../component-library'; const SignatureRequestSIWEIcon = () => { return ( @@ -17,7 +17,7 @@ const SignatureRequestSIWEIcon = () => { backgroundColor={Color.errorDefault} justifyContent={JustifyContent.center} > - + ); }; diff --git a/ui/components/app/tab-bar/tab-bar.js b/ui/components/app/tab-bar/tab-bar.js index bcb97b80b..9c3c42a90 100644 --- a/ui/components/app/tab-bar/tab-bar.js +++ b/ui/components/app/tab-bar/tab-bar.js @@ -2,11 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; const TabBar = (props) => { const { tabs = [], onSelect, isActive } = props; @@ -26,8 +22,8 @@ const TabBar = (props) => {
{content}
diff --git a/ui/components/app/tab-bar/tab-bar.stories.js b/ui/components/app/tab-bar/tab-bar.stories.js index d7e08ed7c..a9677eb19 100644 --- a/ui/components/app/tab-bar/tab-bar.stories.js +++ b/ui/components/app/tab-bar/tab-bar.stories.js @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../component-library'; import TabBar from '.'; export default { @@ -19,12 +19,12 @@ export default { args: { tabs: [ { - icon: , + icon: , content: 'General', key: 'general', }, { - icon: , + icon: , content: 'Contacts', key: 'contacts', }, @@ -39,7 +39,7 @@ export default { key: 'securityAndPrivacy', }, { - icon: , + icon: , content: 'Alerts', key: 'alerts', }, diff --git a/ui/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js b/ui/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js index 3e253e621..7e119ebe6 100644 --- a/ui/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js +++ b/ui/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js @@ -12,22 +12,18 @@ import { TRANSACTION_CANCEL_ATTEMPTED_EVENT, TRANSACTION_CANCEL_SUCCESS_EVENT, } from '../transaction-activity-log.constants'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../../component-library'; import { Color } from '../../../../helpers/constants/design-system'; export const ACTIVITY_ICONS = { - [TRANSACTION_CREATED_EVENT]: ICON_NAMES.ADD, - [TRANSACTION_SUBMITTED_EVENT]: ICON_NAMES.ARROW_UP, - [TRANSACTION_RESUBMITTED_EVENT]: ICON_NAMES.PROGRAMMING_ARROWS, - [TRANSACTION_CONFIRMED_EVENT]: ICON_NAMES.CHECK, - [TRANSACTION_DROPPED_EVENT]: ICON_NAMES.CLOSE, - [TRANSACTION_ERRORED_EVENT]: ICON_NAMES.DANGER, - [TRANSACTION_CANCEL_ATTEMPTED_EVENT]: ICON_NAMES.CLOSE, - [TRANSACTION_CANCEL_SUCCESS_EVENT]: ICON_NAMES.CLOSE, + [TRANSACTION_CREATED_EVENT]: IconName.Add, + [TRANSACTION_SUBMITTED_EVENT]: IconName.ArrowUp, + [TRANSACTION_RESUBMITTED_EVENT]: IconName.ProgrammingArrows, + [TRANSACTION_CONFIRMED_EVENT]: IconName.Check, + [TRANSACTION_DROPPED_EVENT]: IconName.Close, + [TRANSACTION_ERRORED_EVENT]: IconName.Danger, + [TRANSACTION_CANCEL_ATTEMPTED_EVENT]: IconName.Close, + [TRANSACTION_CANCEL_SUCCESS_EVENT]: IconName.Close, }; export default class TransactionActivityLogIcon extends PureComponent { @@ -47,7 +43,7 @@ export default class TransactionActivityLogIcon extends PureComponent { return (
{icon ? ( - + ) : null}
); diff --git a/ui/components/app/transaction-decoding/components/ui/copy-raw-data/copy-raw-data.component.js b/ui/components/app/transaction-decoding/components/ui/copy-raw-data/copy-raw-data.component.js index 8e1f62d93..57e43e669 100644 --- a/ui/components/app/transaction-decoding/components/ui/copy-raw-data/copy-raw-data.component.js +++ b/ui/components/app/transaction-decoding/components/ui/copy-raw-data/copy-raw-data.component.js @@ -4,10 +4,7 @@ import Tooltip from '../../../../../ui/tooltip/tooltip'; import { I18nContext } from '../../../../../../contexts/i18n'; import { useCopyToClipboard } from '../../../../../../hooks/useCopyToClipboard'; -import { - Icon, - ICON_NAMES, -} from '../../../../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../../../../component-library'; import { IconColor } from '../../../../../../helpers/constants/design-system'; const CopyRawData = ({ data }) => { @@ -25,7 +22,7 @@ const CopyRawData = ({ data }) => { >
diff --git a/ui/components/app/wallet-overview/eth-overview.js b/ui/components/app/wallet-overview/eth-overview.js index 315ce61af..6d0dbdeaf 100644 --- a/ui/components/app/wallet-overview/eth-overview.js +++ b/ui/components/app/wallet-overview/eth-overview.js @@ -39,9 +39,10 @@ import { startNewDraftTransaction } from '../../../ducks/send'; import { AssetType } from '../../../../shared/constants/transaction'; import { ButtonIcon, - BUTTON_ICON_SIZES, -} from '../../component-library/button-icon/deprecated'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; + ButtonIconSize, + Icon, + IconName, +} from '../../component-library'; import { IconColor } from '../../../helpers/constants/design-system'; import useRamps from '../../../hooks/experiences/useRamps'; import WalletOverview from './wallet-overview'; @@ -101,9 +102,9 @@ const EthOverview = ({ className }) => { className="eth-overview__portfolio-button" data-testid="home__portfolio-site" color={IconColor.primaryDefault} - iconName={ICON_NAMES.DIAGRAM} + iconName={IconName.Diagram} ariaLabel={t('portfolio')} - size={BUTTON_ICON_SIZES.LG} + size={ButtonIconSize.Lg} onClick={() => { const portfolioUrl = process.env.PORTFOLIO_URL; global.platform.openTab({ @@ -147,9 +148,7 @@ const EthOverview = ({ className }) => { <> - } + Icon={} disabled={!isBuyableChain} data-testid="eth-overview-buy" label={t('buy')} @@ -170,7 +169,7 @@ const EthOverview = ({ className }) => { data-testid="eth-overview-send" Icon={ } @@ -197,7 +196,7 @@ const EthOverview = ({ className }) => { disabled={!isSwapsChain} Icon={ } @@ -239,7 +238,7 @@ const EthOverview = ({ className }) => { disabled={!isBridgeChain} data-testid="eth-overview-bridge" Icon={ - + } label={t('bridge')} onClick={() => { diff --git a/ui/components/app/wallet-overview/token-overview.js b/ui/components/app/wallet-overview/token-overview.js index a2d7728b1..7f9ade4b6 100644 --- a/ui/components/app/wallet-overview/token-overview.js +++ b/ui/components/app/wallet-overview/token-overview.js @@ -35,7 +35,7 @@ import { import { AssetType } from '../../../../shared/constants/transaction'; import useRamps from '../../../hooks/experiences/useRamps'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../component-library'; import { IconColor } from '../../../helpers/constants/design-system'; import WalletOverview from './wallet-overview'; @@ -93,9 +93,7 @@ const TokenOverview = ({ className, token }) => { <> - } + Icon={} label={t('buy')} data-testid="token-overview-buy" onClick={() => { @@ -139,7 +137,7 @@ const TokenOverview = ({ className, token }) => { }} Icon={ } @@ -152,7 +150,7 @@ const TokenOverview = ({ className, token }) => { disabled={!isSwapsChain} Icon={ } @@ -201,10 +199,7 @@ const TokenOverview = ({ className, token }) => { + } label={t('portfolio')} data-testid="home__portfolio-site" diff --git a/ui/components/component-library/avatar-base/avatar-base.js b/ui/components/component-library/avatar-base/avatar-base.js index 22a1e9553..7b981e04a 100644 --- a/ui/components/component-library/avatar-base/avatar-base.js +++ b/ui/components/component-library/avatar-base/avatar-base.js @@ -6,6 +6,7 @@ import { BackgroundColor, BorderColor, TextColor, + IconColor, DISPLAY, JustifyContent, AlignItems, @@ -81,7 +82,10 @@ AvatarBase.propTypes = { * The color of the text inside the AvatarBase * Defaults to TextColor.textDefault */ - color: PropTypes.oneOf(Object.values(TextColor)), + color: PropTypes.oneOf([ + ...Object.values(TextColor), + ...Object.values(IconColor), + ]), /** * Additional classNames to be added to the AvatarToken */ diff --git a/ui/components/component-library/avatar-icon/avatar-icon.js b/ui/components/component-library/avatar-icon/avatar-icon.js index a8f36e063..53271ef5b 100644 --- a/ui/components/component-library/avatar-icon/avatar-icon.js +++ b/ui/components/component-library/avatar-icon/avatar-icon.js @@ -73,7 +73,10 @@ AvatarIcon.propTypes = { * The color of the text inside the AvatarIcon * Defaults to TextColor.primaryDefault */ - color: PropTypes.oneOf(Object.values(TextColor)), + color: PropTypes.oneOf([ + ...Object.values(TextColor), + ...Object.values(IconColor), + ]), /** * Additional classNames to be added to the AvatarIcon */ From fa6e26744d076167a9f7c5af6930bc8a3c666ce3 Mon Sep 17 00:00:00 2001 From: Monte Lai Date: Thu, 20 Apr 2023 05:53:07 +0800 Subject: [PATCH 23/25] 18566 firefox ledger u2f message (#18570) * check for user agent * fix regex * fix lint * update link * add test * update message * update coverage * fix test names * update text * add whats new notification for firefox and ledger users * update action button link * update notification text * update viewed notification * update coverage * update coverage --- app/_locales/en/messages.json | 29 ++++ coverage-targets.js | 8 +- shared/notifications/index.js | 15 ++ .../app/whats-new-popup/whats-new-popup.js | 6 + ui/helpers/constants/zendesk-url.js | 2 + .../__snapshots__/index.test.tsx.snap | 110 +++++++++++++ .../create-account/connect-hardware/index.js | 71 ++++++-- .../connect-hardware/index.test.tsx | 151 ++++++++++++++++++ ui/selectors/selectors.js | 2 + 9 files changed, 381 insertions(+), 13 deletions(-) create mode 100644 ui/pages/create-account/connect-hardware/__snapshots__/index.test.tsx.snap create mode 100644 ui/pages/create-account/connect-hardware/index.test.tsx diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 03f2c2de2..10fd6d792 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -2537,6 +2537,19 @@ "message": "Swapping on mobile is here!", "description": "Title for a notification in the 'See What's New' popup. Tells users that they can now use MetaMask Swaps on Mobile." }, + "notifications20ActionText": { + "message": "Learn more", + "description": "The 'call to action' on the button, or link, of the 'Stay secure' notification. Upon clicking, users will be taken to a ledger page to resolve the U2F connection issue." + }, + + "notifications20Description": { + "message": "If you're on the latest version of Firefox, you might be experiencing an issue related to Firefox dropping U2F support.", + "description": "Description of a notification in the 'See What's New' popup. Describes the U2F support being dropped by firefox and that it affects ledger users." + }, + "notifications20Title": { + "message": "Ledger and Firefox Users Experiencing Connection Issues", + "description": "Title for a notification in the 'See What's New' popup. Tells users that latest firefox users using U2F may experience connection issues." + }, "notifications3ActionText": { "message": "Read more", "description": "The 'call to action' on the button, or link, of the 'Stay secure' notification. Upon clicking, users will be taken to a page about security on the metamask support website." @@ -4541,6 +4554,22 @@ "transferFrom": { "message": "Transfer from" }, + "troubleConnectingToLedgerU2FOnFirefox": { + "message": "We're having trouble connecting your Ledger. $1", + "description": "$1 is a link to the wallet connection guide;" + }, + "troubleConnectingToLedgerU2FOnFirefox2": { + "message": "Review our hardware wallet connection guide and try again.", + "description": "$1 of the ledger wallet connection guide" + }, + "troubleConnectingToLedgerU2FOnFirefoxLedgerSolution": { + "message": "If you're on the latest version of Firefox, you might be experiencing an issue related to Firefox dropping U2F support. Learn how to fix this issue $1.", + "description": "It is a link to the ledger website for the workaround." + }, + "troubleConnectingToLedgerU2FOnFirefoxLedgerSolution2": { + "message": "here", + "description": "Second part of the error message; It is a link to the ledger website for the workaround." + }, "troubleConnectingToWallet": { "message": "We had trouble connecting to your $1, try reviewing $2 and try again.", "description": "$1 is the wallet device name; $2 is a link to wallet connection guide" diff --git a/coverage-targets.js b/coverage-targets.js index 1ed939c2f..f9c2577b0 100644 --- a/coverage-targets.js +++ b/coverage-targets.js @@ -6,10 +6,10 @@ // subset of files to check against these targets. module.exports = { global: { - lines: 67.8, - branches: 55.84, - statements: 67.13, - functions: 59.66, + lines: 68.5, + branches: 56.34, + statements: 67.86, + functions: 60.69, }, transforms: { branches: 100, diff --git a/shared/notifications/index.js b/shared/notifications/index.js index 10c24bbfe..9bf285957 100644 --- a/shared/notifications/index.js +++ b/shared/notifications/index.js @@ -102,6 +102,10 @@ export const UI_NOTIFICATIONS = { width: '100%', }, }, + 20: { + id: 20, + date: null, + }, }; export const getTranslatedUINotifications = (t, locale) => { @@ -279,5 +283,16 @@ export const getTranslatedUINotifications = (t, locale) => { ) : '', }, + 20: { + ...UI_NOTIFICATIONS[20], + title: t('notifications20Title'), + description: [t('notifications20Description')], + actionText: t('notifications20ActionText'), + date: UI_NOTIFICATIONS[20].date + ? new Intl.DateTimeFormat(formattedLocale).format( + new Date(UI_NOTIFICATIONS[20].date), + ) + : '', + }, }; }; diff --git a/ui/components/app/whats-new-popup/whats-new-popup.js b/ui/components/app/whats-new-popup/whats-new-popup.js index 98c636e50..fd0bf14a7 100644 --- a/ui/components/app/whats-new-popup/whats-new-popup.js +++ b/ui/components/app/whats-new-popup/whats-new-popup.js @@ -73,6 +73,12 @@ function getActionFunctionById(id, history) { updateViewedNotifications({ 19: true }); history.push(`${EXPERIMENTAL_ROUTE}#autodetect-nfts`); }, + 20: () => { + updateViewedNotifications({ 20: true }); + global.platform.openTab({ + url: ZENDESK_URLS.LEDGER_FIREFOX_U2F_GUIDE, + }); + }, }; return actionFunctions[id]; diff --git a/ui/helpers/constants/zendesk-url.js b/ui/helpers/constants/zendesk-url.js index 1e3f4aec9..79ea52ffb 100644 --- a/ui/helpers/constants/zendesk-url.js +++ b/ui/helpers/constants/zendesk-url.js @@ -15,6 +15,8 @@ const ZENDESK_URLS = { 'https://metamask.zendesk.com/hc/en-us/articles/360015289932', INFURA_BLOCKAGE: 'https://metamask.zendesk.com/hc/en-us/articles/360059386712', + LEDGER_FIREFOX_U2F_GUIDE: + 'https://support.ledger.com/hc/en-us/articles/10371387758493-MetaMask-Firefox-Ledger-Integration-Issue?support=true', LEGACY_WEB3: 'https://metamask.zendesk.com/hc/en-us/articles/360053147012', NFT_TOKENS: 'https://metamask.zendesk.com/hc/en-us/articles/360058238591-NFT-tokens-in-MetaMask-wallet', diff --git a/ui/pages/create-account/connect-hardware/__snapshots__/index.test.tsx.snap b/ui/pages/create-account/connect-hardware/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000..5284b9760 --- /dev/null +++ b/ui/pages/create-account/connect-hardware/__snapshots__/index.test.tsx.snap @@ -0,0 +1,110 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ConnectHardwareForm should match snapshot 1`] = ` +
+ +
+`; diff --git a/ui/pages/create-account/connect-hardware/index.js b/ui/pages/create-account/connect-hardware/index.js index c46800f85..3105ceb29 100644 --- a/ui/pages/create-account/connect-hardware/index.js +++ b/ui/pages/create-account/connect-hardware/index.js @@ -20,7 +20,14 @@ import { HardwareDeviceNames, LedgerTransportTypes, } from '../../../../shared/constants/hardware-wallets'; +import { + BUTTON_TYPES, + BUTTON_SIZES, + Button, + Text, +} from '../../../components/component-library'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; +import { TextColor } from '../../../helpers/constants/design-system'; import SelectHardware from './select-hardware'; import AccountList from './account-list'; @@ -74,6 +81,7 @@ class ConnectHardwareForm extends Component { browserSupported: true, unlocked: false, device: null, + isFirefox: false, }; UNSAFE_componentWillReceiveProps(nextProps) { @@ -89,6 +97,10 @@ class ConnectHardwareForm extends Component { componentDidMount() { this.checkIfUnlocked(); + const useAgent = window.navigator.userAgent; + if (/Firefox/u.test(useAgent)) { + this.setState({ isFirefox: true }); + } } async checkIfUnlocked() { @@ -287,23 +299,64 @@ class ConnectHardwareForm extends Component { renderError() { if (this.state.error === U2F_ERROR) { + if (this.state.device === 'ledger' && this.state.isFirefox) { + return ( + <> + + {this.context.t('troubleConnectingToLedgerU2FOnFirefox', [ + // eslint-disable-next-line react/jsx-key + , + ])} + + + {this.context.t( + 'troubleConnectingToLedgerU2FOnFirefoxLedgerSolution', + [ + // eslint-disable-next-line react/jsx-key + , + ], + )} + + + ); + } return ( -

+ {this.context.t('troubleConnectingToWallet', [ this.state.device, // eslint-disable-next-line react/jsx-key - {this.context.t('walletConnectionGuide')} - , + , ])} -

+ ); } return this.state.error ? ( diff --git a/ui/pages/create-account/connect-hardware/index.test.tsx b/ui/pages/create-account/connect-hardware/index.test.tsx new file mode 100644 index 000000000..770782462 --- /dev/null +++ b/ui/pages/create-account/connect-hardware/index.test.tsx @@ -0,0 +1,151 @@ +import configureMockStore from 'redux-mock-store'; +import { fireEvent, waitFor } from '@testing-library/react'; +import thunk from 'redux-thunk'; +import React from 'react'; +import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { + LedgerTransportTypes, + HardwareDeviceNames, +} from '../../../../shared/constants/hardware-wallets'; +import ConnectHardwareForm from '.'; + +const mockConnectHardware = jest.fn(); +const mockCheckHardwareStatus = jest.fn().mockResolvedValue(false); + +jest.mock('../../../store/actions', () => ({ + connectHardware: () => mockConnectHardware, + checkHardwareStatus: () => mockCheckHardwareStatus, +})); + +jest.mock('../../../selectors', () => ({ + getCurrentChainId: () => jest.fn().mockResolvedValue('0x1'), + getRpcPrefsForCurrentProvider: () => jest.fn().mockResolvedValue({}), + getMetaMaskAccountsConnected: () => jest.fn().mockResolvedValue([]), + getMetaMaskAccounts: () => jest.fn().mockResolvedValue([]), +})); + +jest.mock('../../../ducks/history/history', () => ({ + getMostRecentOverviewPage: () => jest.fn().mockResolvedValue('/'), +})); + +const mockProps = { + forgetDevice: jest.fn(), + showAlert: jest.fn(), + hideAlert: jest.fn(), + unlockHardwareWalletAccount: jest.fn(), + setHardwareWalletDefaultHdPath: jest.fn(), + history: {}, + defaultHdPath: "m/44'/60'/0'/0", + mostRecentOverviewPage: '', +}; + +const mockState = { + metamask: { + provider: { + chainId: '0x1', + }, + }, + appState: { + networkDropdownOpen: false, + gasIsLoading: false, + isLoading: false, + modal: { + open: false, + modalState: { + name: null, + props: {}, + }, + previousModalState: { + name: null, + }, + }, + warning: null, + chainId: '0x1', + rpcPrefs: null, + accounts: [], + connectedAccounts: [], + defaultHdPaths: { + [HardwareDeviceNames.lattice]: "m/44'/60'/0'/0", + [HardwareDeviceNames.ledger]: "m/44'/60'/0'/0", + [HardwareDeviceNames.trezor]: "m/44'/60'/0'/0", + }, + mostRecentOverviewPage: '', + ledgerTransportType: LedgerTransportTypes.webhid, + }, +}; + +describe('ConnectHardwareForm', () => { + const mockStore = configureMockStore([thunk])(mockState); + it('should match snapshot', () => { + const { container } = renderWithProvider( + , + mockStore, + ); + + expect(container).toMatchSnapshot(); + }); + + describe('U2F Error', () => { + it('should render a U2F error', async () => { + mockConnectHardware.mockRejectedValue(new Error('U2F Error')); + const mockStateWithU2F = Object.assign(mockState, {}); + mockStateWithU2F.appState.ledgerTransportType = LedgerTransportTypes.u2f; + const mockStoreWithU2F = configureMockStore([thunk])(mockStateWithU2F); + const { getByText, getByLabelText, queryByText } = renderWithProvider( + , + mockStoreWithU2F, + ); + + const ledgerButton = getByLabelText('Ledger'); + const continueButton = getByText('Continue'); + + fireEvent.click(ledgerButton); + fireEvent.click(continueButton); + + await waitFor(() => { + expect( + getByText('We had trouble connecting to your ledger, try reviewing', { + exact: false, + }), + ).toBeInTheDocument(); + const firefoxError = queryByText( + "If you're on the latest version of Firefox, you might be experiencing an issue related to Firefox dropping U2F support. Learn how to fix this issue", + { exact: false }, + ); + expect(firefoxError).not.toBeInTheDocument(); + }); + }); + + it('should render a different U2F error for firefox', async () => { + jest + .spyOn(window.navigator, 'userAgent', 'get') + .mockReturnValue( + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0', + ); + + mockConnectHardware.mockRejectedValue(new Error('U2F Error')); + const mockStateWithU2F = Object.assign(mockState, {}); + mockStateWithU2F.appState.ledgerTransportType = LedgerTransportTypes.u2f; + const mockStoreWithU2F = configureMockStore([thunk])(mockStateWithU2F); + const { getByText, getByLabelText } = renderWithProvider( + , + mockStoreWithU2F, + ); + + const ledgerButton = getByLabelText('Ledger'); + const continueButton = getByText('Continue'); + + fireEvent.click(ledgerButton); + fireEvent.click(continueButton); + + await waitFor(() => { + expect( + getByText( + "If you're on the latest version of Firefox, you might be experiencing an issue related to Firefox dropping U2F support. Learn how to fix this issue", + { exact: false }, + ), + ).toBeInTheDocument(); + }); + }); + }); +}); diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 4b4c3aba8..ec606c02e 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -935,6 +935,7 @@ function getAllowedAnnouncementIds(state) { const supportsWebHid = window.navigator.hid !== undefined; const currentlyUsingLedgerLive = getLedgerTransportType(state) === LedgerTransportTypes.live; + const isFirefox = window.navigator.userAgent.includes('Firefox'); return { 1: false, @@ -956,6 +957,7 @@ function getAllowedAnnouncementIds(state) { 17: false, 18: true, 19: true, + 20: currentKeyringIsLedger && isFirefox, }; } From 8e52ed3fac704a3f031a57c9c84980b51379ebd2 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 19 Apr 2023 20:24:50 -0230 Subject: [PATCH 24/25] Make `upsertNetworkConfiguration` async (#18606) The network controller method `upsertNetworkConfiguration` has been made async. It makes one async call internally, which is the optional step of setting the given network as the active network. If the `setActive` option is set to `true`, this function will not resolve until after the network switch has completed. If the `setActive` option is `false`, this change will not have any functional impact. Relates to https://github.com/MetaMask/metamask-extension/issues/18587 --- .../network/network-controller.test.ts | 46 +++++++++---------- .../controllers/network/network-controller.ts | 6 +-- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/scripts/controllers/network/network-controller.test.ts b/app/scripts/controllers/network/network-controller.test.ts index 8368decd0..2e2c1b0b9 100644 --- a/app/scripts/controllers/network/network-controller.test.ts +++ b/app/scripts/controllers/network/network-controller.test.ts @@ -6740,7 +6740,7 @@ describe('NetworkController', () => { it('throws if the given chain ID is not a 0x-prefixed hex number', async () => { const invalidChainId = '1'; await withController(async ({ controller }) => { - expect(() => + await expect(() => controller.upsertNetworkConfiguration( { /* @ts-expect-error We are intentionally passing bad input. */ @@ -6755,7 +6755,7 @@ describe('NetworkController', () => { source: MetaMetricsNetworkEventSource.Dapp, }, ), - ).toThrow( + ).rejects.toThrow( new Error( `Invalid chain ID "${invalidChainId}": invalid hex string.`, ), @@ -6765,7 +6765,7 @@ describe('NetworkController', () => { it('throws if the given chain ID is greater than the maximum allowed ID', async () => { await withController(async ({ controller }) => { - expect(() => + await expect(() => controller.upsertNetworkConfiguration( { chainId: '0xFFFFFFFFFFFFFFFF', @@ -6779,7 +6779,7 @@ describe('NetworkController', () => { source: MetaMetricsNetworkEventSource.Dapp, }, ), - ).toThrow( + ).rejects.toThrow( new Error( 'Invalid chain ID "0xFFFFFFFFFFFFFFFF": numerical value greater than max safe value.', ), @@ -6789,7 +6789,7 @@ describe('NetworkController', () => { it('throws if the no (or a falsy) rpcUrl is passed', async () => { await withController(async ({ controller }) => { - expect(() => + await expect(() => controller.upsertNetworkConfiguration( /* @ts-expect-error We are intentionally passing bad input. */ { @@ -6803,7 +6803,7 @@ describe('NetworkController', () => { source: MetaMetricsNetworkEventSource.Dapp, }, ), - ).toThrow( + ).rejects.toThrow( new Error( 'An rpcUrl is required to add or update network configuration', ), @@ -6813,7 +6813,7 @@ describe('NetworkController', () => { it('throws if rpcUrl passed is not a valid Url', async () => { await withController(async ({ controller }) => { - expect(() => + await expect(() => controller.upsertNetworkConfiguration( { chainId: '0x9999', @@ -6827,13 +6827,13 @@ describe('NetworkController', () => { source: MetaMetricsNetworkEventSource.Dapp, }, ), - ).toThrow(new Error('rpcUrl must be a valid URL')); + ).rejects.toThrow(new Error('rpcUrl must be a valid URL')); }); }); it('throws if the no (or a falsy) ticker is passed', async () => { await withController(async ({ controller }) => { - expect(() => + await expect(() => controller.upsertNetworkConfiguration( /* @ts-expect-error We are intentionally passing bad input. */ { @@ -6847,7 +6847,7 @@ describe('NetworkController', () => { source: MetaMetricsNetworkEventSource.Dapp, }, ), - ).toThrow( + ).rejects.toThrow( new Error( 'A ticker is required to add or update networkConfiguration', ), @@ -6857,7 +6857,7 @@ describe('NetworkController', () => { it('throws if an options object is not passed as a second argument', async () => { await withController(async ({ controller }) => { - expect(() => + await expect(() => /* @ts-expect-error We are intentionally passing bad input. */ controller.upsertNetworkConfiguration({ chainId: '0x5', @@ -6865,7 +6865,7 @@ describe('NetworkController', () => { rpcPrefs: { blockExplorerUrl: 'test-block-explorer.com' }, rpcUrl: 'https://mock-rpc-url', }), - ).toThrow( + ).rejects.toThrow( new Error( "Cannot read properties of undefined (reading 'setActive')", ), @@ -6888,7 +6888,7 @@ describe('NetworkController', () => { ticker: 'test_ticker', }; - controller.upsertNetworkConfiguration(rpcUrlNetwork, { + await controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -6926,7 +6926,7 @@ describe('NetworkController', () => { invalidKey2: {}, }; - controller.upsertNetworkConfiguration(rpcUrlNetwork, { + await controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -6975,7 +6975,7 @@ describe('NetworkController', () => { ticker: 'RPC', }; - controller.upsertNetworkConfiguration(rpcUrlNetwork, { + await controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -7024,7 +7024,7 @@ describe('NetworkController', () => { rpcPrefs: { blockExplorerUrl: 'alternativetestchainscan.io' }, chainId: '0x1' as const, }; - controller.upsertNetworkConfiguration(updatedConfiguration, { + await controller.upsertNetworkConfiguration(updatedConfiguration, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -7069,7 +7069,7 @@ describe('NetworkController', () => { }, }, async ({ controller }) => { - controller.upsertNetworkConfiguration( + await controller.upsertNetworkConfiguration( { rpcUrl: 'https://test-rpc-url', ticker: 'new-ticker', @@ -7136,7 +7136,7 @@ describe('NetworkController', () => { ticker: 'test_ticker', }; - controller.upsertNetworkConfiguration(rpcUrlNetwork, { + await controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -7180,7 +7180,7 @@ describe('NetworkController', () => { ticker: 'test_ticker', }; - controller.upsertNetworkConfiguration(rpcUrlNetwork, { + await controller.upsertNetworkConfiguration(rpcUrlNetwork, { setActive: true, referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, @@ -7229,7 +7229,7 @@ describe('NetworkController', () => { rpcPrefs: { blockExplorerUrl: 'https://block-explorer' }, }; - controller.upsertNetworkConfiguration(newNetworkConfiguration, { + await controller.upsertNetworkConfiguration(newNetworkConfiguration, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -7296,10 +7296,10 @@ describe('NetworkController', () => { rpcPrefs: { blockExplorerUrl: 'https://block-explorer' }, }; - expect(() => { + await expect(() => /* @ts-expect-error We are intentionally passing bad input. */ - controller.upsertNetworkConfiguration(newNetworkConfiguration, {}); - }).toThrow( + controller.upsertNetworkConfiguration(newNetworkConfiguration, {}), + ).rejects.toThrow( 'referrer and source are required arguments for adding or updating a network configuration', ); }, diff --git a/app/scripts/controllers/network/network-controller.ts b/app/scripts/controllers/network/network-controller.ts index 9b95a8c7c..eaf3f6931 100644 --- a/app/scripts/controllers/network/network-controller.ts +++ b/app/scripts/controllers/network/network-controller.ts @@ -1034,7 +1034,7 @@ export class NetworkController extends EventEmitter { * @throws if `rpcUrl` is not a valid URL. * @returns The ID for the added or updated network configuration. */ - upsertNetworkConfiguration( + async upsertNetworkConfiguration( { rpcUrl, chainId, @@ -1051,7 +1051,7 @@ export class NetworkController extends EventEmitter { referrer: string; source: string; }, - ): NetworkConfigurationId { + ): Promise { assert.ok( isPrefixedFormattedHexString(chainId), `Invalid chain ID "${chainId}": invalid hex string.`, @@ -1129,7 +1129,7 @@ export class NetworkController extends EventEmitter { } if (setActive) { - this.setActiveNetwork(newNetworkConfigurationId); + await this.setActiveNetwork(newNetworkConfigurationId); } return newNetworkConfigurationId; From e96c0b696357af70471a91b6291d630e3bb85207 Mon Sep 17 00:00:00 2001 From: George Marshall Date: Wed, 19 Apr 2023 19:30:29 -0700 Subject: [PATCH 25/25] Update to component-library readme (#18501) * Update to component-library readme * Update ui/components/component-library/README.md Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --------- Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- ui/components/component-library/README.md | 34 +++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/ui/components/component-library/README.md b/ui/components/component-library/README.md index b108e9256..8c3c27f74 100644 --- a/ui/components/component-library/README.md +++ b/ui/components/component-library/README.md @@ -1,8 +1,38 @@ # Component Library -**⚠️ THESE COMPONENTS HAVE BREAKING CHANGES ⚠️** +This folder contains design system components that are built 1:1 with the Figma [DS Components](https://www.figma.com/file/HKpPKij9V3TpsyMV1TpV7C/DS-Components?node-id=16-6) UI kit and should be used where possible in all UI feature work. -This folder contains new design system(`DS 2.0`) components that will be used for the IA/Nav redesign work. They are currently a WIP and should not be used for feature work. That should change in the near future but for the time being please use existing UI components in `ui/components/ui` +## Architecture + +All components are built on top of the `Box` component and accept all `Box` [component props](https://metamask.github.io/metamask-storybook/?path=/docs/components-ui-box--default-story#props) + +#### Layout + +`component-library` components accept all utility props for layout + +``` +import { Text } from '../../component-library' + +This text has a margin-bottom of 16px +``` + +#### Polymorphic `as` prop + +`component-library` components accept a polymorphic as prop to change the root html element of a component + +``` +import { Text } from '../../component-library' + +
    +This renders as list item html element +
+``` + +## TypeScript + +We are currently in the process of migrating all component-library components to TypeScript. Feel free to contribute by creating a PR against one of [these issues](https://github.com/MetaMask/metamask-extension/issues?q=is%3Aissue+is%3Aopen+DS%2FExtension%2F2023%2FQ2%2FO1%2FKR3) + +## Support If internal folks have any questions please reach out the design system team via the internal slack channel [#metamask-design-system](https://consensys.slack.com/archives/C0354T27M5M) 💁