From 0306422bbfce4f6182418bbd07c1af94deb901b3 Mon Sep 17 00:00:00 2001 From: Monte Lai Date: Sun, 7 May 2023 05:04:20 +0800 Subject: [PATCH 001/120] Add reveal to export private key (#18170) Co-authored-by: George Marshall Co-authored-by: Brad Decker Co-authored-by: David Walsh Co-authored-by: Howard Braham * change js to tsx * update to typescript * add labels to circle animation * add willHide prop to hold to reveal modal * add test * convert to design system * fix lint * fix type * bump coverage * rename * remove comments * remove ts comment and add fix exhuastive dep check * update coverage * add hide modal test * use banneralert * update label * remove unused * fix text * update aria label messages * change exportAccountAndGetPrivateKey to be async * fix lint * update coverage target * update coverage * update input component * update coverage * update coverage * fix blank line * use && * move plainKey to under !privateKeyInput * update hold modal to display srp and private key message * fix styling * fix lint and test * fix unused locales * remove redundent check * update storybook * fix text alignment * fix lint * update snapshot * fix test * update coverage * fix merge conflict * refactor * fix variant * update snapshot * fix test after merge * fix test after merge conflict * fix label text * update to use label component --- app/_locales/de/messages.json | 6 - app/_locales/el/messages.json | 6 - app/_locales/en/messages.json | 24 +- 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 - .../hold-to-reveal-button.js | 4 +- .../hold-to-reveal-button.test.js | 39 +- .../export-private-key-modal.test.js.snap | 65 ++-- .../export-private-key-modal.component.js | 340 +++++++++--------- ...export-private-key-modal.component.test.js | 130 +++++++ .../export-private-key-modal.stories.js | 26 +- .../export-private-key-modal.test.js | 3 +- .../export-private-key-modal/index.scss | 82 ----- .../password-input.js | 50 +++ .../export-private-key-modal/private-key.js | 81 +++++ .../hold-to-reveal-modal.js | 134 +++++-- .../hold-to-reveal-modal.test.js | 19 +- ui/pages/keychains/reveal-seed.js | 1 + ui/pages/keychains/reveal-seed.test.js | 4 +- 29 files changed, 668 insertions(+), 418 deletions(-) create mode 100644 ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.test.js create mode 100644 ui/components/app/modals/export-private-key-modal/password-input.js create mode 100644 ui/components/app/modals/export-private-key-modal/private-key.js diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index b8b8c19df..fceaa5ed5 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "Verlauf" }, - "holdToReveal": { - "message": "Halten, um GWP anzuzeigen" - }, "holdToRevealContent1": { "message": "Ihre geheime Wiederherstellungsphrase bietet $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "Betrüger aber schon.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "Bewahren Sie Ihre GWP sicher auf" - }, "ignoreAll": { "message": "Alle ignorieren" }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 06ebced86..d17783925 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "Ιστορικό" }, - "holdToReveal": { - "message": "Κρατήστε πατημένο για αποκάλυψη της ΜΦΑ" - }, "holdToRevealContent1": { "message": "Η Μυστική σας Φράση Ανάκτησης παρέχει $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "αλλά οι απατεώνες μπορεί να το κάνουν.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "Κρατήστε τη ΜΦΑ σας ασφαλή" - }, "ignoreAll": { "message": "Αγνόηση όλων" }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 088fe8444..7572190c1 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1754,9 +1754,6 @@ "history": { "message": "History" }, - "holdToReveal": { - "message": "Hold to reveal SRP" - }, "holdToRevealContent1": { "message": "Your Secret Recovery Phrase provides $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1777,9 +1774,28 @@ "message": "but phishers might.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { + "holdToRevealContentPrivateKey1": { + "message": "Your Private Key provides $1", + "description": "$1 is a bolded text with the message from 'holdToRevealContentPrivateKey2'" + }, + "holdToRevealContentPrivateKey2": { + "message": "full access to your wallet and funds.", + "description": "Is the bolded text in 'holdToRevealContentPrivateKey2'" + }, + "holdToRevealLockedLabel": { "message": "hold to reveal circle locked" }, + "holdToRevealPrivateKey": { + "message": "Hold to reveal Private Key" + }, + "holdToRevealPrivateKeyTitle": { + "message": "Keep your private key safe" + }, + "holdToRevealSRP": { + "message": "Hold to reveal SRP" + }, + "holdToRevealSRPTitle": { "message": "Keep your SRP safe" }, + "holdToRevealUnlockedLabel": { "message": "hold to reveal circle unlocked" }, "id": { "message": "Id" }, diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 67a3b012a..0661e837a 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "Historial" }, - "holdToReveal": { - "message": "Mantenga presionado para mostrar la SRP" - }, "holdToRevealContent1": { "message": "Su frase secreta de recuperación proporciona $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "pero los defraudadores sí.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "Mantenga segura su SRP" - }, "ignoreAll": { "message": "Ignorar todo" }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index b543b2114..920ff11a7 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "Historique" }, - "holdToReveal": { - "message": "Appuyez longuement pour révéler la PSR" - }, "holdToRevealContent1": { "message": "Votre phrase secrète de récupération donne $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "mais les hameçonneurs pourraient le faire.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "Conservez votre PSR en lieu sûr" - }, "ignoreAll": { "message": "Ignorer tout" }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index e9781a768..7861fd19e 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "इतिहास" }, - "holdToReveal": { - "message": "SRP देखने के लिए होल्ड करें" - }, "holdToRevealContent1": { "message": "आपका सीक्रेट रिकवरी फ्रेज $1 प्रदान करता है", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "लेकिन फिशर कर सकते हैं।", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "अपने SRP को सुरक्षित रखें" - }, "ignoreAll": { "message": "सभी को अनदेखा करें" }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 97df69b6f..dd49e11ed 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "Riwayat" }, - "holdToReveal": { - "message": "Tahan untuk mengungkap FPR" - }, "holdToRevealContent1": { "message": "Frasa Pemulihan Rahasia memberikan $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "tetapi penipu akan mencoba memintanya.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "Jaga keamanan FPR Anda" - }, "ignoreAll": { "message": "Abaikan semua" }, diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index a3c0dd28e..6121b09dd 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "履歴" }, - "holdToReveal": { - "message": "長押しして SRP を表示" - }, "holdToRevealContent1": { "message": "秘密のリカバリーフレーズは$1を提供します。", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "もし尋ねられた場合はフィッシング詐欺の可能性があります。", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "SRP は安全に保管してください" - }, "ignoreAll": { "message": "すべて無視" }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index c4de64fc4..61a439b52 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "기록" }, - "holdToReveal": { - "message": "눌러서 SRP 확인" - }, "holdToRevealContent1": { "message": "비밀 복구 구문이 있으면 $1 기능을 사용할 수 있습니다", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "오히려 피싱 사기꾼들이 요구할 수 있으니 주의가 필요합니다.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "SRP를 안전하게 보관하세요" - }, "ignoreAll": { "message": "모두 무시" }, diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index d52ed995d..93adcfea8 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "Histórico" }, - "holdToReveal": { - "message": "Segure para revelar a FRS" - }, "holdToRevealContent1": { "message": "Sua Frase de Recuperação Secreta concede $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "mas os phishers talvez solicitem.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "Mantenha sua FRS em segurança" - }, "ignoreAll": { "message": "Ignorar tudo" }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 1b9a1a6e8..03d546df9 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "История" }, - "holdToReveal": { - "message": "Удерживайте для отображения СВФ" - }, "holdToRevealContent1": { "message": "Ваша секретная фраза для восстановления дает $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "но злоумышленники-фишеры могут.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "Обеспечьте безопасность своей СВФ" - }, "ignoreAll": { "message": "Игнорировать все" }, diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index 479683256..bb47c161f 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "History" }, - "holdToReveal": { - "message": "I-hold para ipakita ang SRP" - }, "holdToRevealContent1": { "message": "Ang iyong Secret Recovery Phrase ay nagbibigay ng $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "ngunit maaring hingin ng mga phisher.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "Ingatan ang iyong SRP" - }, "ignoreAll": { "message": "Huwag pansinin ang lahat" }, diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index 1479da53f..ebabab1c7 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "Geçmiş" }, - "holdToReveal": { - "message": "GKİ'yi göstermek için basılı tut" - }, "holdToRevealContent1": { "message": "Gizli Kurtarma İfadeniz: $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "ancak dolandırıcılar talep edilebilir.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "GKİ'nizi güvende tutun" - }, "ignoreAll": { "message": "Tümünü yoksay" }, diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index 4bb67b89e..120efa397 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "Lịch sử" }, - "holdToReveal": { - "message": "Giữ để hiển thị Cụm từ khôi phục bí mật" - }, "holdToRevealContent1": { "message": "Cụm từ khôi phục bí mật của bạn cung cấp $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "nhưng những kẻ lừa đảo qua mạng thì có.", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "Đảm bảo an toàn cho Cụm từ khôi phục bí mật của bạn" - }, "ignoreAll": { "message": "Bỏ qua tất cả" }, diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index 3bbbf0165..ffe567145 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -1570,9 +1570,6 @@ "history": { "message": "历史记录" }, - "holdToReveal": { - "message": "按住以显示 SRP" - }, "holdToRevealContent1": { "message": "您的助记词提供 $1", "description": "$1 is a bolded text with the message from 'holdToRevealContent2'" @@ -1593,9 +1590,6 @@ "message": "但网络钓鱼者可能会。", "description": "The text link in 'holdToRevealContent3'" }, - "holdToRevealTitle": { - "message": "确保 SRP 的安全" - }, "ignoreAll": { "message": "忽略所有" }, diff --git a/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.js b/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.js index fe2b422d4..b12443ccd 100644 --- a/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.js +++ b/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.js @@ -121,7 +121,7 @@ export default function HoldToRevealButton({ buttonText, onLongPressed }) {
diff --git a/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.test.js b/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.test.js index 16c6c0917..2fd23e8ef 100644 --- a/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.test.js +++ b/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.test.js @@ -1,20 +1,21 @@ import React from 'react'; import { render, fireEvent, waitFor } from '@testing-library/react'; +import configureMockState from 'redux-mock-store'; +import thunk from 'redux-thunk'; +import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import mockState from '../../../../test/data/mock-state.json'; import { MetaMetricsEventCategory, MetaMetricsEventKeyType, MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; +import { MetaMetricsContext } from '../../../contexts/metametrics'; import HoldToRevealButton from './hold-to-reveal-button'; const mockTrackEvent = jest.fn(); -jest.mock('react', () => ({ - ...jest.requireActual('react'), - useContext: () => mockTrackEvent, -})); - describe('HoldToRevealButton', () => { + const mockStore = configureMockState([thunk])(mockState); let props = {}; beforeEach(() => { @@ -51,21 +52,24 @@ describe('HoldToRevealButton', () => { }); it('should show the locked padlock when a button is long pressed and then should show it after it was lifted off before the animation concludes', async () => { - const { getByText, queryByLabelText } = render( - , + const { getByText, queryByLabelText } = renderWithProvider( + + + , + mockStore, ); const button = getByText('Hold to reveal SRP'); fireEvent.mouseDown(button); - const circleLocked = queryByLabelText('circle-locked'); + const circleLocked = queryByLabelText('hold to reveal circle locked'); await waitFor(() => { expect(circleLocked).toBeInTheDocument(); }); fireEvent.mouseUp(button); - const circleUnlocked = queryByLabelText('circle-unlocked'); + const circleUnlocked = queryByLabelText('hold to reveal circle unlocked'); await waitFor(() => { expect(circleUnlocked).not.toBeInTheDocument(); @@ -73,37 +77,40 @@ describe('HoldToRevealButton', () => { }); it('should show the unlocked padlock when a button is long pressed for the duration of the animation', async () => { - const { getByText, queryByLabelText } = render( - , + const { getByText, queryByLabelText, getByLabelText } = renderWithProvider( + + + , + mockStore, ); const button = getByText('Hold to reveal SRP'); fireEvent.mouseDown(button); - const circleLocked = queryByLabelText('circle-locked'); + const circleLocked = getByLabelText('hold to reveal circle locked'); fireEvent.transitionEnd(circleLocked); - const circleUnlocked = queryByLabelText('circle-unlocked'); + const circleUnlocked = queryByLabelText('hold to reveal circle unlocked'); fireEvent.animationEnd(circleUnlocked); await waitFor(() => { expect(circleUnlocked).toBeInTheDocument(); - expect(mockTrackEvent).toHaveBeenNthCalledWith(2, { + expect(mockTrackEvent).toHaveBeenNthCalledWith(1, { category: MetaMetricsEventCategory.Keys, event: MetaMetricsEventName.SrpHoldToRevealClickStarted, properties: { key_type: MetaMetricsEventKeyType.Srp, }, }); - expect(mockTrackEvent).toHaveBeenNthCalledWith(5, { + expect(mockTrackEvent).toHaveBeenNthCalledWith(2, { category: MetaMetricsEventCategory.Keys, event: MetaMetricsEventName.SrpHoldToRevealCompleted, properties: { key_type: MetaMetricsEventKeyType.Srp, }, }); - expect(mockTrackEvent).toHaveBeenNthCalledWith(6, { + expect(mockTrackEvent).toHaveBeenNthCalledWith(3, { category: MetaMetricsEventCategory.Keys, event: MetaMetricsEventName.SrpRevealViewed, properties: { diff --git a/ui/components/app/modals/export-private-key-modal/__snapshots__/export-private-key-modal.test.js.snap b/ui/components/app/modals/export-private-key-modal/__snapshots__/export-private-key-modal.test.js.snap index f275c351e..be40a2b06 100644 --- a/ui/components/app/modals/export-private-key-modal/__snapshots__/export-private-key-modal.test.js.snap +++ b/ui/components/app/modals/export-private-key-modal/__snapshots__/export-private-key-modal.test.js.snap @@ -59,57 +59,76 @@ exports[`Export PrivateKey Modal should match snapshot 1`] = ` class="account-modal__close" />
0x0DCD5D886577d5081B0c52e242Ef29E70Be3E7bc
- Show Private Keys - +

- Type your MetaMask password - - +
+ > + +
+

- Warning: Never disclose this key. Anyone with your private keys can steal any assets held in your account. + +
+

+ Warning: Never disclose this key. Anyone with your private keys can steal any assets held in your account. +

+
diff --git a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js index b50c3de85..49c4f7be2 100644 --- a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js +++ b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js @@ -1,139 +1,188 @@ import log from 'loglevel'; +import React, { useContext, useEffect, useState } from 'react'; import PropTypes from 'prop-types'; -import React, { Component } from 'react'; - -import copyToClipboard from 'copy-to-clipboard'; -import Button from '../../../ui/button'; -import AccountModalContainer from '../account-modal-container'; +import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; +import Box from '../../../ui/box'; import { - toChecksumHexAddress, - stripHexPrefix, -} from '../../../../../shared/modules/hexstring-utils'; + BUTTON_SIZES, + BUTTON_VARIANT, + BannerAlert, + Button, + Text, +} from '../../../component-library'; +import AccountModalContainer from '../account-modal-container'; +import { toChecksumHexAddress } from '../../../../../shared/modules/hexstring-utils'; import { MetaMetricsEventCategory, MetaMetricsEventKeyType, MetaMetricsEventName, } from '../../../../../shared/constants/metametrics'; +import HoldToRevealModal from '../hold-to-reveal-modal/hold-to-reveal-modal'; +import { MetaMetricsContext } from '../../../../contexts/metametrics'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { + BLOCK_SIZES, + BorderColor, + BorderStyle, + Color, + DISPLAY, + FLEX_DIRECTION, + FONT_WEIGHT, + JustifyContent, + TextVariant, +} from '../../../../helpers/constants/design-system'; +import PrivateKeyDisplay from './private-key'; +import PasswordInput from './password-input'; -export default class ExportPrivateKeyModal extends Component { - static contextTypes = { - t: PropTypes.func, - trackEvent: PropTypes.func, - }; +const ExportPrivateKeyModal = ({ + clearAccountDetails, + hideWarning, + exportAccount, + selectedIdentity, + showAccountDetailModal, + hideModal, + warning = null, + previousModalState, +}) => { + const [password, setPassword] = useState(''); + const [privateKey, setPrivateKey] = useState(null); + const [showWarning, setShowWarning] = useState(true); + const [showHoldToReveal, setShowHoldToReveal] = useState(false); + const trackEvent = useContext(MetaMetricsContext); + const t = useI18nContext(); - static defaultProps = { - warning: null, - previousModalState: null, - }; + useEffect(() => { + return () => { + clearAccountDetails(); + hideWarning(); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); - static propTypes = { - exportAccount: PropTypes.func.isRequired, - selectedIdentity: PropTypes.object.isRequired, - warning: PropTypes.node, - showAccountDetailModal: PropTypes.func.isRequired, - hideModal: PropTypes.func.isRequired, - hideWarning: PropTypes.func.isRequired, - clearAccountDetails: PropTypes.func.isRequired, - previousModalState: PropTypes.string, - }; - - state = { - password: '', - privateKey: null, - showWarning: true, - }; - - componentWillUnmount() { - this.props.clearAccountDetails(); - this.props.hideWarning(); - } - - exportAccountAndGetPrivateKey = (password, address) => { - const { exportAccount } = this.props; - - exportAccount(password, address) - .then((privateKey) => { - this.context.trackEvent({ + const exportAccountAndGetPrivateKey = async (passwordInput, address) => { + try { + const privateKeyRetrieved = await exportAccount(passwordInput, address); + trackEvent( + { category: MetaMetricsEventCategory.Keys, event: MetaMetricsEventName.KeyExportRevealed, properties: { key_type: MetaMetricsEventKeyType.Pkey, }, - }); - - this.setState({ - privateKey, - showWarning: false, - }); - }) - .catch((e) => { - this.context.trackEvent({ + }, + {}, + ); + setPrivateKey(privateKeyRetrieved); + setShowWarning(false); + setShowHoldToReveal(true); + } catch (e) { + trackEvent( + { category: MetaMetricsEventCategory.Keys, event: MetaMetricsEventName.KeyExportFailed, properties: { key_type: MetaMetricsEventKeyType.Pkey, reason: 'incorrect_password', }, - }); + }, + {}, + ); - log.error(e); - }); + log.error(e); + } }; - renderPasswordLabel(privateKey) { + const { name, address } = selectedIdentity; + + if (showHoldToReveal) { return ( - - {privateKey - ? this.context.t('copyPrivateKey') - : this.context.t('typePassword')} - - ); - } - - renderPasswordInput(privateKey) { - const plainKey = privateKey && stripHexPrefix(privateKey); - - if (!privateKey) { - return ( - this.setState({ password: event.target.value })} - /> - ); - } - - return ( -
{ - copyToClipboard(plainKey); - this.context.trackEvent({ - category: MetaMetricsEventCategory.Keys, - event: MetaMetricsEventName.KeyExportCopied, - properties: { - key_type: MetaMetricsEventKeyType.Pkey, - copy_method: 'clipboard', - }, - }); - }} + showAccountDetailModal()} > - {plainKey} -
+ setShowHoldToReveal(false)} + willHide={false} + holdToRevealType="PrivateKey" + /> + ); } - renderButtons(privateKey, address, hideModal) { - return ( -
+ return ( + showAccountDetailModal()} + > + + {name} + + + {toChecksumHexAddress(address)} + + + + {t('showPrivateKeys')} + + {privateKey ? ( + + ) : ( + + )} + {showWarning && ( + + {warning} + + )} + + {t('privateKeyWarning')} + + {!privateKey && ( )} {privateKey ? ( ) : ( )} -
- ); - } + + + ); +}; - render() { - const { - selectedIdentity, - warning, - showAccountDetailModal, - hideModal, - previousModalState, - } = this.props; - const { name, address } = selectedIdentity; +ExportPrivateKeyModal.propTypes = { + exportAccount: PropTypes.func.isRequired, + selectedIdentity: PropTypes.object.isRequired, + warning: PropTypes.node, + showAccountDetailModal: PropTypes.func.isRequired, + hideModal: PropTypes.func.isRequired, + hideWarning: PropTypes.func.isRequired, + clearAccountDetails: PropTypes.func.isRequired, + previousModalState: PropTypes.string, +}; - const { privateKey, showWarning } = this.state; - - return ( - showAccountDetailModal()} - > - {name} -
- {toChecksumHexAddress(address)} -
-
- - {this.context.t('showPrivateKeys')} - -
- {this.renderPasswordLabel(privateKey)} - {this.renderPasswordInput(privateKey)} - {showWarning && warning ? ( - - {warning} - - ) : null} -
-
- {this.context.t('privateKeyWarning')} -
- {this.renderButtons(privateKey, address, hideModal)} - - ); - } -} +export default withModalProps(ExportPrivateKeyModal); diff --git a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.test.js b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.test.js new file mode 100644 index 000000000..f4a913280 --- /dev/null +++ b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.test.js @@ -0,0 +1,130 @@ +import { fireEvent, waitFor } from '@testing-library/react'; +import configureMockStore from 'redux-mock-store'; +import React from 'react'; +import thunk from 'redux-thunk'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import ExportPrivateKeyModal from '.'; + +const mockAddress = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'; +const mockPrivateKey = 'mock private key'; +const mockExportAccount = jest.fn().mockResolvedValue(mockPrivateKey); +const mockClearAccountDetail = jest.fn(); +const mockHideWarning = jest.fn(); + +jest.mock('../../../../store/actions', () => ({ + exportAccount: () => mockExportAccount, + clearAccountDetails: () => mockClearAccountDetail, + hideWarning: () => mockHideWarning, +})); + +describe('Export Private Key Modal', () => { + const state = { + metamask: { + selectedAddress: mockAddress, + identities: { + '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': { + address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', + name: 'Test Account', + }, + }, + providerConfig: { + type: 'rpc', + chainId: '0x5', + ticker: 'ETH', + id: 'testNetworkConfigurationId', + }, + }, + appState: { + warning: null, + previousModalState: { + name: null, + }, + isLoading: false, + accountDetail: { + privateKey: null, + }, + modal: { + modalState: {}, + previousModalState: { + name: null, + }, + }, + }, + }; + const mockStore = configureMockStore([thunk])(state); + + it('renders export private key modal', () => { + const { queryByText } = renderWithProvider( + , + mockStore, + ); + + const title = queryByText('Show Private Keys'); + expect(title).toBeInTheDocument(); + + const warning = queryByText( + 'Warning: Never disclose this key. Anyone with your private keys can steal any assets held in your account.', + ); + expect(warning).toBeInTheDocument(); + expect(queryByText(mockPrivateKey)).not.toBeInTheDocument(); + }); + + it('renders hold to reveal after entering password', async () => { + const { queryByText, getByPlaceholderText } = renderWithProvider( + , + mockStore, + ); + + const nextButton = queryByText('Confirm'); + expect(nextButton).toBeInTheDocument(); + + const input = getByPlaceholderText('Enter password'); + + fireEvent.change(input, { + target: { value: 'password' }, + }); + + fireEvent.click(nextButton); + + await waitFor(() => { + expect(mockExportAccount).toHaveBeenCalled(); + expect(queryByText('Keep your private key safe')).toBeInTheDocument(); + }); + }); + + it('provides password after passing hold to reveal', async () => { + const { queryByText, getByLabelText, getByText, getByPlaceholderText } = + renderWithProvider(, mockStore); + + const nextButton = queryByText('Confirm'); + expect(nextButton).toBeInTheDocument(); + + const input = getByPlaceholderText('Enter password'); + fireEvent.change(input, { + target: { value: 'password' }, + }); + + fireEvent.click(nextButton); + + await waitFor(() => { + expect(mockExportAccount).toHaveBeenCalled(); + expect(queryByText('Keep your private key safe')).toBeInTheDocument(); + }); + + const holdButton = getByText('Hold to reveal Private Key'); + expect(holdButton).toBeInTheDocument(); + + fireEvent.mouseDown(holdButton); + + const circle = getByLabelText('hold to reveal circle locked'); + fireEvent.transitionEnd(circle); + const circleUnlocked = getByLabelText('hold to reveal circle unlocked'); + fireEvent.animationEnd(circleUnlocked); + + await waitFor(() => { + expect(queryByText('Show Private Keys')).toBeInTheDocument(); + expect(queryByText('Done')).toBeInTheDocument(); + expect(queryByText(mockPrivateKey)).toBeInTheDocument(); + }); + }); +}); diff --git a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.stories.js b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.stories.js index 39af8761f..36ba01b89 100644 --- a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.stories.js +++ b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.stories.js @@ -1,10 +1,32 @@ import React from 'react'; -import ExportPrivateKeyModal from '.'; +import { Provider } from 'react-redux'; +import testData from '../../../../../.storybook/test-data'; +import configureStore from '../../../../store/store'; +import ExportPrivateKeyModal from './export-private-key-modal.component'; + +// Using Test Data For Redux +const store = configureStore(testData); export default { title: 'Components/App/Modals/ExportPrivateKeyModal', + decorators: [(story) => {story()}], + argsTypes: { + exportAccount: { action: 'exportAccount' }, + }, }; -export const DefaultStory = () => ; +export const DefaultStory = () => { + return ( + { + return 'mockPrivateKey'; + }} + selectedIdentity={ + testData.metamask.identities[testData.metamask.selectedAddress] + } + /> + ); +}; DefaultStory.storyName = 'Default'; diff --git a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.test.js b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.test.js index bc5e38df2..873be62b6 100644 --- a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.test.js +++ b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.test.js @@ -59,7 +59,8 @@ describe('Export PrivateKey Modal', () => { mockStore, ); - const passwordInput = queryByTestId('password-input'); + const passwordInput = + queryByTestId('password-input').querySelector('input'); const passwordInputEvent = { target: { diff --git a/ui/components/app/modals/export-private-key-modal/index.scss b/ui/components/app/modals/export-private-key-modal/index.scss index 46e12a102..8edde5e39 100644 --- a/ui/components/app/modals/export-private-key-modal/index.scss +++ b/ui/components/app/modals/export-private-key-modal/index.scss @@ -1,11 +1,4 @@ .export-private-key-modal { - &__body-title { - @include H4; - - margin-top: 16px; - margin-bottom: 16px; - } - &__divider { width: 100%; height: 1px; @@ -13,93 +6,18 @@ background-color: var(--color-border-default); } - &__account-name { - @include H4; - - margin-top: 9px; - } - - &__password { - display: flex; - flex-direction: column; - } - - &__password-label, - &__password--error { - @include H6; - - color: var(--color-text-default); - margin-bottom: 10px; - } - - &__password--error { - color: var(--color-error-default); - margin-bottom: 0; - } - - &__password-input { - @include Paragraph; - - padding: 10px 0 13px 17px; - width: 291px; - height: 44px; - background: var(--color-background-default); - color: var(--color-text-default); - border: 1px solid var(--color-border-default); - } - &__password::-webkit-input-placeholder { color: var(--color-text-muted); } - &__password--warning { - @include H7; - - border-radius: 8px; - background-color: var(--color-error-muted); - font-weight: 500; - color: var(--color-text-default); - border: 1px solid var(--color-error-default); - width: 292px; - padding: 9px 15px; - margin-top: 18px; - } - &__private-key-display { - @include Paragraph; - height: 80px; width: 291px; - border: 1px solid var(--color-border-default); - border-radius: 2px; - color: var(--color-error-default); - padding: 9px 13px 8px; overflow: hidden; overflow-wrap: break-word; } - &__buttons { - display: flex; - flex-direction: row; - justify-content: center; - width: 100%; - padding: 0 25px; - } - - &__button { - margin-top: 17px; - width: 141px; - min-width: initial; - } - - &__button--cancel { - margin-right: 15px; - } - .ellip-address-wrapper { - border: 1px solid var(--color-border-default); - padding: 5px 10px; - margin-top: 7px; max-width: 286px; direction: ltr; overflow: hidden; diff --git a/ui/components/app/modals/export-private-key-modal/password-input.js b/ui/components/app/modals/export-private-key-modal/password-input.js new file mode 100644 index 000000000..4892055bd --- /dev/null +++ b/ui/components/app/modals/export-private-key-modal/password-input.js @@ -0,0 +1,50 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { + BLOCK_SIZES, + FLEX_DIRECTION, + DISPLAY, + AlignItems, + Color, + TextVariant, +} from '../../../../helpers/constants/design-system'; +import Box from '../../../ui/box'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { Label, TEXT_FIELD_TYPES, TextField } from '../../../component-library'; + +const PasswordInput = ({ setPassword }) => { + const t = useI18nContext(); + + return ( + + + setPassword(event.target.value)} + data-testid="password-input" + /> + + ); +}; + +PasswordInput.propTypes = { + setPassword: PropTypes.func.isRequired, +}; + +export default PasswordInput; diff --git a/ui/components/app/modals/export-private-key-modal/private-key.js b/ui/components/app/modals/export-private-key-modal/private-key.js new file mode 100644 index 000000000..c2200ed47 --- /dev/null +++ b/ui/components/app/modals/export-private-key-modal/private-key.js @@ -0,0 +1,81 @@ +import copyToClipboard from 'copy-to-clipboard'; +import { stripHexPrefix } from 'ethereumjs-util'; +import React, { useContext } from 'react'; +import PropTypes from 'prop-types'; +import Box from '../../../ui/box'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsEventKeyType, +} from '../../../../../shared/constants/metametrics'; +import { MetaMetricsContext } from '../../../../contexts/metametrics'; +import { + BLOCK_SIZES, + BorderStyle, + BorderColor, + BorderRadius, + AlignItems, + DISPLAY, + Color, + FLEX_DIRECTION, + TextVariant, +} from '../../../../helpers/constants/design-system'; +import { Label } from '../../../component-library'; + +const PrivateKeyDisplay = ({ privateKey }) => { + const trackEvent = useContext(MetaMetricsContext); + const t = useI18nContext(); + const plainKey = stripHexPrefix(privateKey); + + return ( + + + { + copyToClipboard(plainKey); + trackEvent( + { + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportCopied, + properties: { + key_type: MetaMetricsEventKeyType.Pkey, + copy_method: 'clipboard', + }, + }, + {}, + ); + }} + > + {plainKey} + + + ); +}; + +PrivateKeyDisplay.propTypes = { + privateKey: PropTypes.string.isRequired, +}; + +export default PrivateKeyDisplay; 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 4a4f79581..3377127c7 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 @@ -5,6 +5,7 @@ import Box from '../../../ui/box'; import { Text, Button, + BUTTON_SIZES, BUTTON_VARIANT, ButtonIcon, IconName, @@ -27,52 +28,80 @@ import { MetaMetricsEventName, } from '../../../../../shared/constants/metametrics'; -const HoldToRevealModal = ({ onLongPressed, hideModal }) => { +const HoldToRevealModal = ({ + onLongPressed, + hideModal, + willHide = true, + holdToRevealType = 'SRP', +}) => { const t = useI18nContext(); + const holdToRevealTitle = + holdToRevealType === 'SRP' + ? 'holdToRevealSRPTitle' + : 'holdToRevealPrivateKeyTitle'; + + const holdToRevealButton = + holdToRevealType === 'SRP' ? 'holdToRevealSRP' : 'holdToRevealPrivateKey'; const trackEvent = useContext(MetaMetricsContext); const unlock = () => { onLongPressed(); - hideModal(); + if (willHide) { + hideModal(); + } }; const handleCancel = () => { hideModal(); }; - return ( - + const renderHoldToRevealPrivateKeyContent = () => { + return ( - {t('holdToRevealTitle')} - { - trackEvent({ - category: MetaMetricsEventCategory.Keys, - event: MetaMetricsEventName.SrpHoldToRevealCloseClicked, - properties: { - key_type: MetaMetricsEventKeyType.Srp, - }, - }); - handleCancel(); - }} - ariaLabel={t('close')} - /> + + {t('holdToRevealContentPrivateKey1', [ + + {t('holdToRevealContentPrivateKey2')} + , + ])} + + + {t('holdToRevealContent3', [ + + {t('holdToRevealContent4')} + , + , + ])} + + ); + }; + + const renderHoldToRevealSRPContent = () => { + return ( { ])} + ); + }; + + return ( + + + {t(holdToRevealTitle)} + {willHide && ( + { + trackEvent({ + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.SrpHoldToRevealCloseClicked, + properties: { + key_type: MetaMetricsEventKeyType.Srp, + }, + }); + handleCancel(); + }} + ariaLabel={t('close')} + /> + )} + + {holdToRevealType === 'SRP' + ? renderHoldToRevealSRPContent() + : renderHoldToRevealPrivateKeyContent()} { const onLongPressStub = jest.fn(); const hideModalStub = jest.fn(); - global.platform = { openTab: jest.fn() }; - afterEach(() => { jest.resetAllMocks(); }); @@ -36,6 +34,7 @@ describe('Hold to Reveal Modal', () => { , mockStore, ); @@ -43,7 +42,7 @@ describe('Hold to Reveal Modal', () => { const holdButton = getByText('Hold to reveal SRP'); expect(holdButton).toBeInTheDocument(); - const warningTitle = getByText(holdToRevealTitle.message); + const warningTitle = getByText(holdToRevealSRPTitle.message); expect(warningTitle).toBeInTheDocument(); const warningText1 = getByText( holdToRevealContent1.message.replace(' $1', ''), @@ -83,12 +82,12 @@ describe('Hold to Reveal Modal', () => { ); const holdButton = getByText('Hold to reveal SRP'); - const circleLocked = queryByLabelText('circle-locked'); + const circleLocked = queryByLabelText('hold to reveal circle locked'); fireEvent.mouseDown(holdButton); fireEvent.transitionEnd(circleLocked); - const circleUnlocked = queryByLabelText('circle-unlocked'); + const circleUnlocked = queryByLabelText('hold to reveal circle unlocked'); fireEvent.animationEnd(circleUnlocked); await waitFor(() => { @@ -112,8 +111,8 @@ describe('Hold to Reveal Modal', () => { fireEvent.click(holdButton); - const circleLocked = queryByLabelText('circle-locked'); - const circleUnlocked = queryByLabelText('circle-unlocked'); + const circleLocked = queryByLabelText('hold to reveal circle locked'); + const circleUnlocked = queryByLabelText('hold to reveal circle unlocked'); await waitFor(() => { expect(circleLocked).toBeInTheDocument(); @@ -163,12 +162,12 @@ describe('Hold to Reveal Modal', () => { ); const holdButton = getByText('Hold to reveal SRP'); - const circleLocked = queryByLabelText('circle-locked'); + const circleLocked = queryByLabelText('hold to reveal circle locked'); fireEvent.mouseDown(holdButton); fireEvent.transitionEnd(circleLocked); - const circleUnlocked = queryByLabelText('circle-unlocked'); + const circleUnlocked = queryByLabelText('hold to reveal circle unlocked'); fireEvent.animationEnd(circleUnlocked); await waitFor(() => { diff --git a/ui/pages/keychains/reveal-seed.js b/ui/pages/keychains/reveal-seed.js index 81c264abc..0fa7aa948 100644 --- a/ui/pages/keychains/reveal-seed.js +++ b/ui/pages/keychains/reveal-seed.js @@ -91,6 +91,7 @@ const RevealSeedPage = () => { setCompletedLongPress(true); setScreen(REVEAL_SEED_SCREEN); }, + holdToRevealType: 'SRP', }), ); }) diff --git a/ui/pages/keychains/reveal-seed.test.js b/ui/pages/keychains/reveal-seed.test.js index aec802384..58baa7503 100644 --- a/ui/pages/keychains/reveal-seed.test.js +++ b/ui/pages/keychains/reveal-seed.test.js @@ -214,12 +214,12 @@ describe('Reveal Seed Page', () => { }); const holdButton = getByText('Hold to reveal SRP'); - const circleLocked = queryByLabelText('circle-locked'); + const circleLocked = queryByLabelText('hold to reveal circle locked'); fireEvent.mouseDown(holdButton); fireEvent.transitionEnd(circleLocked); - const circleUnlocked = queryByLabelText('circle-unlocked'); + const circleUnlocked = queryByLabelText('hold to reveal circle unlocked'); fireEvent.animationEnd(circleUnlocked); await waitFor(() => { From 8df3bc9c1b0001b3ebc2773cb9913b13c117b534 Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Mon, 8 May 2023 12:51:02 +0400 Subject: [PATCH 002/120] Label PRs based on the labels of the associated issue (#17603) * Implement CI to copy issue labels over to PRs * wip * wip * wip * wip * wip * wip * wip * wip * wip * clean up * clean up --- .github/scripts/label-prs.ts | 173 +++++++++++++++++++++++++ .github/workflows/label-prs.yml | 32 +++++ .husky/pre-push | 4 + .validate-branch-namerc.js | 11 ++ package.json | 8 +- yarn.lock | 221 ++++++++++++++++++++++++++++++++ 6 files changed, 448 insertions(+), 1 deletion(-) create mode 100644 .github/scripts/label-prs.ts create mode 100644 .github/workflows/label-prs.yml create mode 100755 .husky/pre-push create mode 100644 .validate-branch-namerc.js diff --git a/.github/scripts/label-prs.ts b/.github/scripts/label-prs.ts new file mode 100644 index 000000000..ef4e790db --- /dev/null +++ b/.github/scripts/label-prs.ts @@ -0,0 +1,173 @@ +import * as core from '@actions/core'; +import { context, getOctokit } from '@actions/github'; +import { GitHub } from '@actions/github/lib/utils'; + +main().catch((error: Error): void => { + console.error(error); + process.exit(1); +}); + +async function main(): Promise { + const token = process.env.GITHUB_TOKEN; + + if (!token) { + core.setFailed('GITHUB_TOKEN not found'); + process.exit(1); + } + + const octokit = getOctokit(token); + + const headRef = context.payload.pull_request?.head.ref || ''; + + let issueNumber = await getIssueNumberFromPullRequestBody(); + if (issueNumber === "") { + bailIfIsBranchNameInvalid(headRef); + bailIfIsNotFeatureBranch(headRef); + issueNumber = getIssueNumberFromBranchName(headRef); + } + + await updateLabels(octokit, issueNumber); +} + +async function getIssueNumberFromPullRequestBody(): Promise { + console.log("Checking if the PR's body references an issue..."); + + let ISSUE_LINK_IN_PR_DESCRIPTION_REGEX = + /(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\s#\d+/gi; + + const prBody = await getPullRequestBody(); + + let matches = prBody.match(ISSUE_LINK_IN_PR_DESCRIPTION_REGEX); + if (!matches || matches?.length === 0) { + console.log( + 'No direct link can be drawn between the PR and an issue from the PR body because no issue number was referenced.', + ); + return ""; + } + + if (matches?.length > 1) { + console.log( + 'No direct link can be drawn between the PR and an issue from the PR body because more than one issue number was referenced.', + ); + return ""; + } + + const ISSUE_NUMBER_REGEX = /\d+/; + const issueNumber = matches[0].match(ISSUE_NUMBER_REGEX)?.[0] || ''; + + console.log(`Found issue number ${issueNumber} in PR body.`); + + return issueNumber; +} + +async function getPullRequestBody(): Promise { + if (context.eventName !== 'pull_request') { + console.log('This action should only run on pull_request events.'); + process.exit(1); + } + + const prBody = context.payload.pull_request?.body || ''; + return prBody; +} + +function bailIfIsBranchNameInvalid(branchName: string): void { + const BRANCH_REGEX = + /^(main|develop|(ci|chore|docs|feat|feature|fix|perf|refactor|revert|style)\/\d*(?:[-](?![-])\w*)*|Version-v\d+\.\d+\.\d+)$/; + const isValidBranchName = new RegExp(BRANCH_REGEX).test(branchName); + + if (!isValidBranchName) { + console.log('This branch name does not follow the convention.'); + console.log( + 'Here are some example branch names that are accepted: "fix/123-description", "feat/123-longer-description", "feature/123", "main", "develop", "Version-v10.24.2".', + ); + console.log( + 'No issue could be linked to this PR, so no labels were copied', + ); + + process.exit(0); + } +} + +function bailIfIsNotFeatureBranch(branchName: string): void { + if ( + branchName === 'main' || + branchName === 'develop' || + branchName.startsWith('Version-v') + ) { + console.log(`${branchName} is not a feature branch.`); + console.log( + 'No issue could be linked to this PR, so no labels were copied', + ); + process.exit(0); + } +} + +async function updateLabels(octokit: InstanceType, issueNumber: string): Promise { + interface ILabel { + name: string; + }; + + const owner = context.repo.owner; + const repo = context.repo.repo; + + const issue = await octokit.rest.issues.get({ + owner: owner, + repo: repo, + issue_number: Number(issueNumber), + }); + + const getNameFromLabel = (label: ILabel): string => label.name + + const issueLabels = issue.data.labels.map(label => getNameFromLabel(label as ILabel)); + + const prNumber = context.payload.number; + + const pr = await octokit.rest.issues.get({ + owner: owner, + repo: repo, + issue_number: prNumber, + }); + + const startingPRLabels = pr.data.labels.map(label => getNameFromLabel(label as ILabel)); + + const dedupedFinalPRLabels = [ + ...new Set([...startingPRLabels, ...issueLabels]), + ]; + + const hasIssueAdditionalLabels = !sortedArrayEqual( + startingPRLabels, + dedupedFinalPRLabels, + ); + if (hasIssueAdditionalLabels) { + await octokit.rest.issues.update({ + owner, + repo, + issue_number: prNumber, + labels: dedupedFinalPRLabels, + }); + } +} + +function getIssueNumberFromBranchName(branchName: string): string { + console.log('Checking if the branch name references an issue...'); + + let issueNumber: string; + if (branchName.split('/').length > 1) { + issueNumber = branchName.split('/')[1].split('-')[0]; + } else { + issueNumber = branchName.split('-')[0]; + } + + console.log(`Found issue number ${issueNumber} in branch name.`); + + return issueNumber; +} + +function sortedArrayEqual(array1: string[], array2: string[]): boolean { + const lengthsAreEqual = array1.length === array2.length; + const everyElementMatchesByIndex = array1.every( + (value: string, index: number): boolean => value === array2[index], + ); + + return lengthsAreEqual && everyElementMatchesByIndex; +} diff --git a/.github/workflows/label-prs.yml b/.github/workflows/label-prs.yml new file mode 100644 index 000000000..f915a881a --- /dev/null +++ b/.github/workflows/label-prs.yml @@ -0,0 +1,32 @@ +name: Label PR + +on: + pull_request: + types: [assigned, opened, edited, synchronize, reopened] + +jobs: + label-pr: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: '16' + + - name: Install Yarn + run: npm install -g yarn + + - name: Install dependencies + run: yarn + + - name: Run PR labelling script + run: npm run label-prs + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100755 index 000000000..bbf5399ef --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +yarn validate-branch-name \ No newline at end of file diff --git a/.validate-branch-namerc.js b/.validate-branch-namerc.js new file mode 100644 index 000000000..8685701d1 --- /dev/null +++ b/.validate-branch-namerc.js @@ -0,0 +1,11 @@ +const BRANCH_REGEX = + /^(main|develop|(ci|chore|docs|feat|feature|fix|perf|refactor|revert|style)\/\d*(?:[-](?![-])\w*)*|Version-v\d+\.\d+\.\d+)$/; + +const ERROR_MSG = + 'This branch name does not follow our conventions.' + + '\n' + + 'Rename it with "git branch -m "' + + '\n' + + 'Here are some example branch names that are accepted: "fix/123-description", "feat/123-longer-description", "feature/123", "main", "develop", "Version-v10.24.2".'; + +module.exports = { pattern: BRANCH_REGEX, errorMsg: ERROR_MSG }; diff --git a/package.json b/package.json index afaf7c54a..c33842858 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,9 @@ "test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"yarn storybook:build && npx http-server storybook-build --port 6006 \" \"wait-on tcp:6006 && yarn test-storybook --maxWorkers=2\"", "githooks:install": "husky install", "fitness-functions": "ts-node development/fitness-functions/index.ts", - "generate-beta-commit": "node ./development/generate-beta-commit.js" + "generate-beta-commit": "node ./development/generate-beta-commit.js", + "validate-branch-name": "validate-branch-name", + "label-prs": "ts-node ./.github/scripts/label-prs.ts" }, "resolutions": { "analytics-node/axios": "^0.21.2", @@ -211,6 +213,8 @@ "request@^2.85.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch" }, "dependencies": { + "@actions/core": "^1.10.0", + "@actions/github": "^5.1.1", "@babel/runtime": "^7.5.5", "@download/blockies": "^1.0.3", "@ensdomains/content-hash": "^2.5.6", @@ -317,6 +321,7 @@ "fuse.js": "^3.2.0", "globalthis": "^1.0.1", "human-standard-token-abi": "^2.0.0", + "husky": "^8.0.3", "immer": "^9.0.6", "is-retry-allowed": "^2.2.0", "jest-junit": "^14.0.1", @@ -360,6 +365,7 @@ "unicode-confusables": "^0.1.1", "uuid": "^8.3.2", "valid-url": "^1.0.9", + "validate-branch-name": "^1.3.0", "web3-stream-provider": "^4.0.0", "zxcvbn": "^4.4.2" }, diff --git a/yarn.lock b/yarn.lock index 39656d679..69484f285 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,37 @@ __metadata: version: 6 cacheKey: 8 +"@actions/core@npm:^1.10.0": + version: 1.10.0 + resolution: "@actions/core@npm:1.10.0" + dependencies: + "@actions/http-client": ^2.0.1 + uuid: ^8.3.2 + checksum: 0a75621e007ab20d887434cdd165f0b9036f14c22252a2faed33543d8b9d04ec95d823e69ca636a25245574e4585d73e1e9e47a845339553c664f9f2c9614669 + languageName: node + linkType: hard + +"@actions/github@npm:^5.1.1": + version: 5.1.1 + resolution: "@actions/github@npm:5.1.1" + dependencies: + "@actions/http-client": ^2.0.1 + "@octokit/core": ^3.6.0 + "@octokit/plugin-paginate-rest": ^2.17.0 + "@octokit/plugin-rest-endpoint-methods": ^5.13.0 + checksum: 2210bd7f8e1e8b407b7df74a259523dc4c63f4ad3a6bfcc0d7867b6e9c3499bd3e25d7de7a9a1bbd0de3be441a8832d5c0b5c0cff3036cd477378c0ec5502434 + languageName: node + linkType: hard + +"@actions/http-client@npm:^2.0.1": + version: 2.1.0 + resolution: "@actions/http-client@npm:2.1.0" + dependencies: + tunnel: ^0.0.6 + checksum: 25a72a952cc95fb4b3ab086da73a5754dd0957c206637cace69be2e16f018cc1b3d3c40d3bcf89ffd8a5929d5e8445594b498b50db306a50ad7536023f8e3800 + languageName: node + linkType: hard + "@ampproject/remapping@npm:^2.1.0": version: 2.2.0 resolution: "@ampproject/remapping@npm:2.2.0" @@ -4692,6 +4723,116 @@ __metadata: languageName: node linkType: hard +"@octokit/auth-token@npm:^2.4.4": + version: 2.5.0 + resolution: "@octokit/auth-token@npm:2.5.0" + dependencies: + "@octokit/types": ^6.0.3 + checksum: 45949296c09abcd6beb4c3f69d45b0c1f265f9581d2a9683cf4d1800c4cf8259c2f58d58e44c16c20bffb85a0282a176c0d51f4af300e428b863f27b910e6297 + languageName: node + linkType: hard + +"@octokit/core@npm:^3.6.0": + version: 3.6.0 + resolution: "@octokit/core@npm:3.6.0" + dependencies: + "@octokit/auth-token": ^2.4.4 + "@octokit/graphql": ^4.5.8 + "@octokit/request": ^5.6.3 + "@octokit/request-error": ^2.0.5 + "@octokit/types": ^6.0.3 + before-after-hook: ^2.2.0 + universal-user-agent: ^6.0.0 + checksum: f81160129037bd8555d47db60cd5381637b7e3602ad70735a7bdf8f3d250c7b7114a666bb12ef7a8746a326a5d72ed30a1b8f8a5a170007f7285c8e217bef1f0 + languageName: node + linkType: hard + +"@octokit/endpoint@npm:^6.0.1": + version: 6.0.12 + resolution: "@octokit/endpoint@npm:6.0.12" + dependencies: + "@octokit/types": ^6.0.3 + is-plain-object: ^5.0.0 + universal-user-agent: ^6.0.0 + checksum: b48b29940af11c4b9bca41cf56809754bb8385d4e3a6122671799d27f0238ba575b3fde86d2d30a84f4dbbc14430940de821e56ecc6a9a92d47fc2b29a31479d + languageName: node + linkType: hard + +"@octokit/graphql@npm:^4.5.8": + version: 4.8.0 + resolution: "@octokit/graphql@npm:4.8.0" + dependencies: + "@octokit/request": ^5.6.0 + "@octokit/types": ^6.0.3 + universal-user-agent: ^6.0.0 + checksum: f68afe53f63900d4a16a0a733f2f500df2695b731f8ed32edb728d50edead7f5011437f71d069c2d2f6d656227703d0c832a3c8af58ecf82bd5dcc051f2d2d74 + languageName: node + linkType: hard + +"@octokit/openapi-types@npm:^12.11.0": + version: 12.11.0 + resolution: "@octokit/openapi-types@npm:12.11.0" + checksum: 8a7d4bd6288cc4085cabe0ca9af2b87c875c303af932cb138aa1b2290eb69d32407759ac23707bb02776466e671244a902e9857896903443a69aff4b6b2b0e3b + languageName: node + linkType: hard + +"@octokit/plugin-paginate-rest@npm:^2.17.0": + version: 2.21.3 + resolution: "@octokit/plugin-paginate-rest@npm:2.21.3" + dependencies: + "@octokit/types": ^6.40.0 + peerDependencies: + "@octokit/core": ">=2" + checksum: acf31de2ba4021bceec7ff49c5b0e25309fc3c009d407f153f928ddf436ab66cd4217344138378d5523f5fb233896e1db58c9c7b3ffd9612a66d760bc5d319ed + languageName: node + linkType: hard + +"@octokit/plugin-rest-endpoint-methods@npm:^5.13.0": + version: 5.16.2 + resolution: "@octokit/plugin-rest-endpoint-methods@npm:5.16.2" + dependencies: + "@octokit/types": ^6.39.0 + deprecation: ^2.3.1 + peerDependencies: + "@octokit/core": ">=3" + checksum: 30fcc50c335d1093f03573d9fa3a4b7d027fc98b215c43e07e82ee8dabfa0af0cf1b963feb542312ae32d897a2f68dc671577206f30850215517bebedc5a2c73 + languageName: node + linkType: hard + +"@octokit/request-error@npm:^2.0.5, @octokit/request-error@npm:^2.1.0": + version: 2.1.0 + resolution: "@octokit/request-error@npm:2.1.0" + dependencies: + "@octokit/types": ^6.0.3 + deprecation: ^2.0.0 + once: ^1.4.0 + checksum: baec2b5700498be01b4d958f9472cb776b3f3b0ea52924323a07e7a88572e24cac2cdf7eb04a0614031ba346043558b47bea2d346e98f0e8385b4261f138ef18 + languageName: node + linkType: hard + +"@octokit/request@npm:^5.6.0, @octokit/request@npm:^5.6.3": + version: 5.6.3 + resolution: "@octokit/request@npm:5.6.3" + dependencies: + "@octokit/endpoint": ^6.0.1 + "@octokit/request-error": ^2.1.0 + "@octokit/types": ^6.16.1 + is-plain-object: ^5.0.0 + node-fetch: ^2.6.7 + universal-user-agent: ^6.0.0 + checksum: c0b4542eb4baaf880d673c758d3e0b5c4a625a4ae30abf40df5548b35f1ff540edaac74625192b1aff42a79ac661e774da4ab7d5505f1cb4ef81239b1e8510c5 + languageName: node + linkType: hard + +"@octokit/types@npm:^6.0.3, @octokit/types@npm:^6.16.1, @octokit/types@npm:^6.39.0, @octokit/types@npm:^6.40.0": + version: 6.41.0 + resolution: "@octokit/types@npm:6.41.0" + dependencies: + "@octokit/openapi-types": ^12.11.0 + checksum: fd6f75e0b19b90d1a3d244d2b0c323ed8f2f05e474a281f60a321986683548ef2e0ec2b3a946aa9405d6092e055344455f69f58957c60f58368c8bdda5b7d2ab + languageName: node + linkType: hard + "@oozcitak/dom@npm:1.15.10": version: 1.15.10 resolution: "@oozcitak/dom@npm:1.15.10" @@ -9913,6 +10054,13 @@ __metadata: languageName: node linkType: hard +"babel-plugin-add-module-exports@npm:^0.2.1": + version: 0.2.1 + resolution: "babel-plugin-add-module-exports@npm:0.2.1" + checksum: 0d40e7b970161a10960fbbd0492565ae2f3f4872b4da089f8f5bb874cfac4e38e088e4d96bc33cef22a8963774abe84622feeebbbe049ad95c4ee33c907b277d + languageName: node + linkType: hard + "babel-plugin-add-react-displayname@npm:^0.0.5": version: 0.0.5 resolution: "babel-plugin-add-react-displayname@npm:0.0.5" @@ -10351,6 +10499,13 @@ __metadata: languageName: node linkType: hard +"before-after-hook@npm:^2.2.0": + version: 2.2.3 + resolution: "before-after-hook@npm:2.2.3" + checksum: a1a2430976d9bdab4cd89cb50d27fa86b19e2b41812bf1315923b0cba03371ebca99449809226425dd3bcef20e010db61abdaff549278e111d6480034bebae87 + languageName: node + linkType: hard + "better-opn@npm:^2.1.1": version: 2.1.1 resolution: "better-opn@npm:2.1.1" @@ -13247,6 +13402,17 @@ __metadata: languageName: node linkType: hard +"current-git-branch@npm:^1.1.0": + version: 1.1.0 + resolution: "current-git-branch@npm:1.1.0" + dependencies: + babel-plugin-add-module-exports: ^0.2.1 + execa: ^0.6.1 + is-git-repository: ^1.0.0 + checksum: 57042d5c9fc608a951e81310da1caa3bdf917d0fede06996bfd7eaab5bdee7d29ced3440c3c73e5d90e503e689e2084e1906b1a17723e35684b1579d1bb5a54f + languageName: node + linkType: hard + "cwd@npm:^0.10.0": version: 0.10.0 resolution: "cwd@npm:0.10.0" @@ -13774,6 +13940,13 @@ __metadata: languageName: node linkType: hard +"deprecation@npm:^2.0.0, deprecation@npm:^2.3.1": + version: 2.3.1 + resolution: "deprecation@npm:2.3.1" + checksum: f56a05e182c2c195071385455956b0c4106fe14e36245b00c689ceef8e8ab639235176a96977ba7c74afb173317fac2e0ec6ec7a1c6d1e6eaa401c586c714132 + languageName: node + linkType: hard + "deps-regex@npm:^0.1.4": version: 0.1.4 resolution: "deps-regex@npm:0.1.4" @@ -16173,6 +16346,21 @@ __metadata: languageName: node linkType: hard +"execa@npm:^0.6.1": + version: 0.6.3 + resolution: "execa@npm:0.6.3" + dependencies: + cross-spawn: ^5.0.1 + get-stream: ^3.0.0 + is-stream: ^1.1.0 + npm-run-path: ^2.0.0 + p-finally: ^1.0.0 + signal-exit: ^3.0.0 + strip-eof: ^1.0.0 + checksum: 2c66177731273a7c0a4c031af81b486b67ec1eeeb8f353ebc68e0cfe7f63aca9ebc1e6fe03ba10f130f2bd179c0ac69b35668fe2bfc1ceb68fbf5291d0783457 + languageName: node + linkType: hard + "execa@npm:^0.7.0": version: 0.7.0 resolution: "execa@npm:0.7.0" @@ -20036,6 +20224,16 @@ __metadata: languageName: node linkType: hard +"is-git-repository@npm:^1.0.0": + version: 1.1.1 + resolution: "is-git-repository@npm:1.1.1" + dependencies: + execa: ^0.6.1 + path-is-absolute: ^1.0.1 + checksum: 2873d41da9ae5771a9118bdd743f32fa868301c57e8e4d8e255d4e14c04267112294a29f2824531fa554696042d8d87185811cff2de2a06381cff7d61d9ac22d + languageName: node + linkType: hard + "is-glob@npm:^2.0.0, is-glob@npm:^2.0.1": version: 2.0.1 resolution: "is-glob@npm:2.0.1" @@ -23951,6 +24149,8 @@ __metadata: version: 0.0.0-use.local resolution: "metamask-crx@workspace:." dependencies: + "@actions/core": ^1.10.0 + "@actions/github": ^5.1.1 "@babel/code-frame": ^7.12.13 "@babel/core": ^7.12.1 "@babel/eslint-parser": ^7.13.14 @@ -24280,6 +24480,7 @@ __metadata: unicode-confusables: ^0.1.1 uuid: ^8.3.2 valid-url: ^1.0.9 + validate-branch-name: ^1.3.0 vinyl: ^2.2.1 vinyl-buffer: ^1.0.1 vinyl-source-stream: ^2.0.0 @@ -33597,6 +33798,13 @@ __metadata: languageName: node linkType: hard +"universal-user-agent@npm:^6.0.0": + version: 6.0.0 + resolution: "universal-user-agent@npm:6.0.0" + checksum: 5092bbc80dd0d583cef0b62c17df0043193b74f425112ea6c1f69bc5eda21eeec7a08d8c4f793a277eb2202ffe9b44bec852fa3faff971234cd209874d1b79ef + languageName: node + linkType: hard + "universalify@npm:^0.1.0, universalify@npm:^0.1.2": version: 0.1.2 resolution: "universalify@npm:0.1.2" @@ -33956,6 +34164,19 @@ __metadata: languageName: node linkType: hard +"validate-branch-name@npm:^1.3.0": + version: 1.3.0 + resolution: "validate-branch-name@npm:1.3.0" + dependencies: + commander: ^8.3.0 + cosmiconfig: ^7.0.1 + current-git-branch: ^1.1.0 + bin: + validate-branch-name: cli.js + checksum: be82c1e39bfe0519fa02f01670b5ef928903a19289249559c9148c0fd20df356f373f2490fbfd54d018868a6348cc2ceb82fb67d5f5c48c15ecb48735b9b87fb + languageName: node + linkType: hard + "validate-npm-package-license@npm:^3.0.1": version: 3.0.4 resolution: "validate-npm-package-license@npm:3.0.4" From da8cb0bbc0f1b71daff536fc1de8f55b5efca3b7 Mon Sep 17 00:00:00 2001 From: Vinicius Stevam <45455812+vinistevam@users.noreply.github.com> Date: Mon, 8 May 2023 11:09:46 +0100 Subject: [PATCH 003/120] Fix fail to reject multiple approval requests (#19050) --- app/scripts/metamask-controller.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 48e18e5a3..60dae3130 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -63,6 +63,7 @@ import { ///: END:ONLY_INCLUDE_IN import { SignatureController } from '@metamask/signature-controller'; +import { ApprovalType } from '@metamask/controller-utils'; import { AssetType, TransactionStatus, @@ -94,7 +95,6 @@ import { UI_NOTIFICATIONS } from '../../shared/notifications'; import { MILLISECOND, SECOND } from '../../shared/constants/time'; import { ORIGIN_METAMASK, - MESSAGE_TYPE, ///: BEGIN:ONLY_INCLUDE_IN(snaps) SNAP_DIALOG_TYPES, ///: END:ONLY_INCLUDE_IN @@ -256,9 +256,13 @@ export default class MetamaskController extends EventEmitter { }), showApprovalRequest: opts.showUserConfirmation, typesExcludedFromRateLimiting: [ - MESSAGE_TYPE.ETH_SIGN, - MESSAGE_TYPE.PERSONAL_SIGN, - MESSAGE_TYPE.ETH_SIGN_TYPED_DATA, + ApprovalType.EthSign, + ApprovalType.PersonalSign, + ApprovalType.EthSignTypedData, + ApprovalType.Transaction, + ApprovalType.WatchAsset, + ApprovalType.EthGetEncryptionPublicKey, + ApprovalType.EthDecrypt, ], }); From 46f717feef0b17fa073a60323229ac4d6354e10c Mon Sep 17 00:00:00 2001 From: Harsh Shukla <125105825+PrgrmrHarshShukla@users.noreply.github.com> Date: Mon, 8 May 2023 19:04:24 +0530 Subject: [PATCH 004/120] Update slider.component.js (#19035) --- ui/components/ui/slider/slider.component.js | 36 +++++++-------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/ui/components/ui/slider/slider.component.js b/ui/components/ui/slider/slider.component.js index 2dc67e08b..581665062 100644 --- a/ui/components/ui/slider/slider.component.js +++ b/ui/components/ui/slider/slider.component.js @@ -4,13 +4,12 @@ import MaterialSlider from '@material-ui/core/Slider'; import { withStyles } from '@material-ui/core/styles'; import { - Color, - FONT_WEIGHT, - TypographyVariant, + TextColor, + TextVariant, } from '../../../helpers/constants/design-system'; import InfoTooltip from '../info-tooltip/info-tooltip'; -import Typography from '../typography/typography'; +import { Text } from '../../component-library'; const styles = { root: { @@ -68,34 +67,24 @@ const Slider = ({
{titleText && ( - + {titleText} - + )} {tooltipText && ( )} {valueText && ( - + {valueText} - + )}
{titleDetail && (
- + {titleDetail} - +
)}
@@ -103,12 +92,9 @@ const Slider = ({
{infoText && ( - + {infoText} - + )}
From 50f2d06223a65dd6cfb5fb03aa3393f56c2e4d18 Mon Sep 17 00:00:00 2001 From: Dhruv <79097544+dhruvv173@users.noreply.github.com> Date: Mon, 8 May 2023 19:06:40 +0530 Subject: [PATCH 005/120] Changes to confirm-data and confirm-hexdata (#19041) --- ui/components/app/confirm-data/confirm-data.js | 6 +++--- .../app/confirm-hexdata/confirm-hexdata.js | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ui/components/app/confirm-data/confirm-data.js b/ui/components/app/confirm-data/confirm-data.js index a82e71510..b5030e0e1 100644 --- a/ui/components/app/confirm-data/confirm-data.js +++ b/ui/components/app/confirm-data/confirm-data.js @@ -5,7 +5,7 @@ import { useSelector } from 'react-redux'; import { Color, TextVariant, - TEXT_TRANSFORM, + TextTransform, } from '../../../helpers/constants/design-system'; import { getKnownMethodData } from '../../../selectors'; import { useI18nContext } from '../../../hooks/useI18nContext'; @@ -42,7 +42,7 @@ const ConfirmData = ({ txData, dataComponent }) => { {`${t('functionType')}:`} @@ -51,7 +51,7 @@ const ConfirmData = ({ txData, dataComponent }) => { as="span" color={Color.textDefault} paddingLeft={1} - textTransform={TEXT_TRANSFORM.CAPITALIZE} + textTransform={TextTransform.Capitalize} variant={TextVariant.bodySmBold} > {`${functionType} ${functionParams}`} diff --git a/ui/components/app/confirm-hexdata/confirm-hexdata.js b/ui/components/app/confirm-hexdata/confirm-hexdata.js index de76017ed..e85e46a5b 100644 --- a/ui/components/app/confirm-hexdata/confirm-hexdata.js +++ b/ui/components/app/confirm-hexdata/confirm-hexdata.js @@ -8,9 +8,9 @@ import { useI18nContext } from '../../../hooks/useI18nContext'; import { useTransactionFunctionType } from '../../../hooks/useTransactionFunctionType'; import { Color, - OVERFLOW_WRAP, + OverflowWrap, TextVariant, - TEXT_TRANSFORM, + TextTransform, } from '../../../helpers/constants/design-system'; import Box from '../../ui/box'; import { Text } from '../../component-library'; @@ -42,7 +42,7 @@ const ConfirmHexData = ({ txData, dataHexComponent }) => { {`${t('functionType')}:`} @@ -51,7 +51,7 @@ const ConfirmHexData = ({ txData, dataHexComponent }) => { as="span" color={Color.textDefault} paddingLeft={1} - textTransform={TEXT_TRANSFORM.CAPITALIZE} + textTransform={TextTransform.Capitalize} variant={TextVariant.bodySmBold} > {`${functionType} ${functionParams}`} @@ -63,13 +63,13 @@ const ConfirmHexData = ({ txData, dataHexComponent }) => { as="h3" paddingBottom={3} paddingTop={2} - textTransform={TEXT_TRANSFORM.UPPERCASE} + textTransform={TextTransform.Uppercase} variant={TextVariant.bodySm} > {`${t('parameters')}:`}
{JSON.stringify(params, null, 2)}
@@ -80,14 +80,14 @@ const ConfirmHexData = ({ txData, dataHexComponent }) => { as="h3" paddingBottom={3} paddingTop={2} - textTransform={TEXT_TRANSFORM.UPPERCASE} + textTransform={TextTransform.Uppercase} variant={TextVariant.bodySm} > {`${t('hexData')}: ${toBuffer(txParams?.data).length} bytes`}
From e8dd6a6ff1413c7f87ad4900b57aadff4d4b0826 Mon Sep 17 00:00:00 2001 From: Nidhi Kumari Date: Mon, 8 May 2023 19:17:45 +0530 Subject: [PATCH 006/120] UX Multichain: Added extra margin for native token (#18988) * added extra margin for native token * fixed lint errors * added marginTop via css * updated test * added boxprops and margin bottom for tab component * updated snapshot * update asset list component --- ui/pages/home/home.component.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index 0bfe5d8ce..e32d6ebee 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -701,11 +701,13 @@ export default class Home extends PureComponent { name={this.context.t('assets')} tabKey="assets" > - - history.push(`${ASSET_ROUTE}/${asset}`) - } - /> + + + history.push(`${ASSET_ROUTE}/${asset}`) + } + /> + Date: Mon, 8 May 2023 13:48:29 +0000 Subject: [PATCH 007/120] devDeps: storybook-dark-mode@1.1.2->2.1.1 (#18866) * devDeps: @storybook/*->6.5.16 * devDeps: storybook-dark-mode@1.1.2->2.1.1 * add lavamoat build policy override --- lavamoat/build-system/policy-override.json | 8 +- lavamoat/build-system/policy.json | 19 +- package.json | 35 ++-- yarn.lock | 221 +++++++++++---------- 4 files changed, 143 insertions(+), 140 deletions(-) diff --git a/lavamoat/build-system/policy-override.json b/lavamoat/build-system/policy-override.json index 895e28eae..15dc64c54 100644 --- a/lavamoat/build-system/policy-override.json +++ b/lavamoat/build-system/policy-override.json @@ -81,22 +81,26 @@ }, "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils": { "packages": { - "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils>eslint-visitor-keys": true + "eslint>@eslint-community/eslint-utils": true, + "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils>eslint-visitor-keys": true, + "semver": true } }, "eslint-plugin-jest>@typescript-eslint/utils": { "builtin": { + "assert": true, "path": true }, "packages": { "eslint-plugin-jest>@typescript-eslint/experimental-utils>@typescript-eslint/types": true, - "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils": true, + "eslint>@eslint-community/eslint-utils": true, "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/types": true, "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/scope-manager": true, "eslint-plugin-jest>@typescript-eslint/utils>webpack>eslint-scope": true, "eslint-plugin-mocha>eslint-utils": true, "@typescript-eslint/parser>@typescript-eslint/types": true, "eslint": true, + "semver": true, "@typescript-eslint/parser>@typescript-eslint/scope-manager": true, "eslint>eslint-scope": true, "eslint>eslint-utils": true, diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json index d5b552bdc..b60f9dcae 100644 --- a/lavamoat/build-system/policy.json +++ b/lavamoat/build-system/policy.json @@ -55,19 +55,10 @@ "define": true }, "packages": { - "@babel/core>@ampproject/remapping>@jridgewell/gen-mapping": true, + "terser>@jridgewell/source-map>@jridgewell/gen-mapping": true, "terser>@jridgewell/source-map>@jridgewell/trace-mapping": true } }, - "@babel/core>@ampproject/remapping>@jridgewell/gen-mapping": { - "globals": { - "define": true - }, - "packages": { - "terser>@jridgewell/source-map>@jridgewell/gen-mapping>@jridgewell/set-array": true, - "terser>@jridgewell/source-map>@jridgewell/gen-mapping>@jridgewell/sourcemap-codec": true - } - }, "@babel/core>@babel/generator": { "globals": { "console.error": true @@ -2702,6 +2693,7 @@ }, "eslint-plugin-jest>@typescript-eslint/utils": { "builtin": { + "assert": true, "path": true }, "packages": { @@ -2711,11 +2703,12 @@ "eslint-plugin-jest>@typescript-eslint/experimental-utils>@typescript-eslint/types": true, "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/scope-manager": true, "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/types": true, - "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils": true, "eslint-plugin-jest>@typescript-eslint/utils>webpack>eslint-scope": true, "eslint-plugin-mocha>eslint-utils": true, + "eslint>@eslint-community/eslint-utils": true, "eslint>eslint-scope": true, "eslint>eslint-utils": true, + "semver": true, "webpack>eslint-scope": true } }, @@ -2738,7 +2731,9 @@ }, "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils": { "packages": { - "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils>eslint-visitor-keys": true + "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils>eslint-visitor-keys": true, + "eslint>@eslint-community/eslint-utils": true, + "semver": true } }, "eslint-plugin-jsdoc": { diff --git a/package.json b/package.json index c33842858..a66a79c11 100644 --- a/package.json +++ b/package.json @@ -392,22 +392,22 @@ "@metamask/phishing-warning": "^2.1.0", "@metamask/test-dapp": "^6.0.0", "@sentry/cli": "^1.58.0", - "@storybook/addon-a11y": "^6.5.13", - "@storybook/addon-actions": "^6.5.13", - "@storybook/addon-essentials": "^6.5.13", + "@storybook/addon-a11y": "^6.5.16", + "@storybook/addon-actions": "^6.5.16", + "@storybook/addon-essentials": "^6.5.16", "@storybook/addon-knobs": "^6.4.0", - "@storybook/addons": "^6.5.13", - "@storybook/api": "^6.5.13", - "@storybook/builder-webpack5": "^6.5.13", - "@storybook/client-api": "^6.5.13", - "@storybook/components": "^6.5.13", - "@storybook/core": "^6.5.13", - "@storybook/core-events": "^6.5.13", - "@storybook/manager-webpack5": "^6.5.13", - "@storybook/react": "^6.5.13", + "@storybook/addons": "^6.5.16", + "@storybook/api": "^6.5.16", + "@storybook/builder-webpack5": "^6.5.16", + "@storybook/client-api": "^6.5.16", + "@storybook/components": "^6.5.16", + "@storybook/core": "^6.5.16", + "@storybook/core-events": "^6.5.16", + "@storybook/manager-webpack5": "^6.5.16", + "@storybook/react": "^6.5.16", "@storybook/storybook-deployer": "^2.8.16", - "@storybook/test-runner": "^0.9.2", - "@storybook/theming": "^6.5.13", + "@storybook/test-runner": "^0.9.4", + "@storybook/theming": "^6.5.16", "@testing-library/jest-dom": "^5.11.10", "@testing-library/react": "^10.4.8", "@testing-library/react-hooks": "^8.0.1", @@ -439,7 +439,7 @@ "@types/yargs": "^17.0.8", "@typescript-eslint/eslint-plugin": "^5.30.7", "@typescript-eslint/parser": "^5.30.7", - "@whitespace/storybook-addon-html": "^5.1.1", + "@whitespace/storybook-addon-html": "^5.1.4", "addons-linter": "^5.2.0", "babel-plugin-module-resolver": "^5.0.0", "babelify": "^10.0.0", @@ -472,7 +472,7 @@ "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.23.1", "eslint-plugin-react-hooks": "^4.2.0", - "eslint-plugin-storybook": "^0.6.4", + "eslint-plugin-storybook": "^0.6.10", "fancy-log": "^1.3.3", "fast-glob": "^3.2.2", "fs-extra": "^8.1.0", @@ -540,7 +540,7 @@ "source-map": "^0.7.2", "source-map-explorer": "^2.4.2", "squirrelly": "^8.0.8", - "storybook-dark-mode": "^1.1.0", + "storybook-dark-mode": "^2.1.1", "stream-browserify": "^3.0.0", "string.prototype.matchall": "^4.0.2", "style-loader": "^0.21.0", @@ -582,6 +582,7 @@ "@metamask/eth-ledger-bridge-keyring>hdkey>secp256k1": false, "@storybook/api>core-js": false, "@storybook/core>@storybook/core-client>@storybook/ui>core-js-pure": false, + "@storybook/test-runner>@storybook/core-common>esbuild": false, "eth-json-rpc-filters>eth-json-rpc-middleware>ethereumjs-util>keccak": false, "eth-json-rpc-filters>eth-json-rpc-middleware>ethereumjs-util>secp256k1": false, "eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>keccak": false, diff --git a/yarn.lock b/yarn.lock index 69484f285..8b87ccdc8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -37,12 +37,12 @@ __metadata: linkType: hard "@ampproject/remapping@npm:^2.1.0": - version: 2.2.0 - resolution: "@ampproject/remapping@npm:2.2.0" + version: 2.2.1 + resolution: "@ampproject/remapping@npm:2.2.1" dependencies: - "@jridgewell/gen-mapping": ^0.1.0 + "@jridgewell/gen-mapping": ^0.3.0 "@jridgewell/trace-mapping": ^0.3.9 - checksum: d74d170d06468913921d72430259424b7e4c826b5a7d39ff839a29d547efb97dc577caa8ba3fb5cf023624e9af9d09651afc3d4112a45e2050328abc9b3a2292 + checksum: 03c04fd526acc64a1f4df22651186f3e5ef0a9d6d6530ce4482ec9841269cf7a11dbb8af79237c282d721c5312024ff17529cd72cc4768c11e999b58e2302079 languageName: node linkType: hard @@ -3252,16 +3252,6 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.1.0": - version: 0.1.1 - resolution: "@jridgewell/gen-mapping@npm:0.1.1" - dependencies: - "@jridgewell/set-array": ^1.0.0 - "@jridgewell/sourcemap-codec": ^1.4.10 - checksum: 3bcc21fe786de6ffbf35c399a174faab05eb23ce6a03e8769569de28abbf4facc2db36a9ddb0150545ae23a8d35a7cf7237b2aa9e9356a7c626fb4698287d5cc - languageName: node - linkType: hard - "@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.2": version: 0.3.2 resolution: "@jridgewell/gen-mapping@npm:0.3.2" @@ -3280,7 +3270,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/set-array@npm:^1.0.0, @jridgewell/set-array@npm:^1.0.1": +"@jridgewell/set-array@npm:^1.0.1": version: 1.1.2 resolution: "@jridgewell/set-array@npm:1.1.2" checksum: 69a84d5980385f396ff60a175f7177af0b8da4ddb81824cb7016a9ef914eee9806c72b6b65942003c63f7983d4f39a5c6c27185bbca88eb4690b62075602e28e @@ -5274,7 +5264,7 @@ __metadata: languageName: node linkType: hard -"@storybook/addon-a11y@npm:^6.5.13": +"@storybook/addon-a11y@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/addon-a11y@npm:6.5.16" dependencies: @@ -5306,7 +5296,7 @@ __metadata: languageName: node linkType: hard -"@storybook/addon-actions@npm:6.5.16, @storybook/addon-actions@npm:^6.5.13": +"@storybook/addon-actions@npm:6.5.16, @storybook/addon-actions@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/addon-actions@npm:6.5.16" dependencies: @@ -5445,7 +5435,7 @@ __metadata: languageName: node linkType: hard -"@storybook/addon-essentials@npm:^6.5.13": +"@storybook/addon-essentials@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/addon-essentials@npm:6.5.16" dependencies: @@ -5637,7 +5627,7 @@ __metadata: languageName: node linkType: hard -"@storybook/addons@npm:6.5.16, @storybook/addons@npm:^6.5.13": +"@storybook/addons@npm:6.5.16, @storybook/addons@npm:^6.5.14, @storybook/addons@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/addons@npm:6.5.16" dependencies: @@ -5659,7 +5649,7 @@ __metadata: languageName: node linkType: hard -"@storybook/api@npm:6.5.16, @storybook/api@npm:^6.5.13": +"@storybook/api@npm:6.5.16, @storybook/api@npm:^6.5.14, @storybook/api@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/api@npm:6.5.16" dependencies: @@ -5748,7 +5738,7 @@ __metadata: languageName: node linkType: hard -"@storybook/builder-webpack5@npm:^6.5.13": +"@storybook/builder-webpack5@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/builder-webpack5@npm:6.5.16" dependencies: @@ -5839,7 +5829,7 @@ __metadata: languageName: node linkType: hard -"@storybook/client-api@npm:6.5.16, @storybook/client-api@npm:^6.5.13": +"@storybook/client-api@npm:6.5.16, @storybook/client-api@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/client-api@npm:6.5.16" dependencies: @@ -5880,7 +5870,7 @@ __metadata: languageName: node linkType: hard -"@storybook/components@npm:6.5.16, @storybook/components@npm:^6.5.13": +"@storybook/components@npm:6.5.16, @storybook/components@npm:^6.5.14, @storybook/components@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/components@npm:6.5.16" dependencies: @@ -5998,7 +5988,7 @@ __metadata: languageName: node linkType: hard -"@storybook/core-events@npm:6.5.16, @storybook/core-events@npm:^6.5.13": +"@storybook/core-events@npm:6.5.16, @storybook/core-events@npm:^6.5.14, @storybook/core-events@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/core-events@npm:6.5.16" dependencies: @@ -6070,7 +6060,7 @@ __metadata: languageName: node linkType: hard -"@storybook/core@npm:6.5.16, @storybook/core@npm:^6.5.13": +"@storybook/core@npm:6.5.16, @storybook/core@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/core@npm:6.5.16" dependencies: @@ -6151,6 +6141,13 @@ __metadata: languageName: node linkType: hard +"@storybook/global@npm:^5.0.0": + version: 5.0.0 + resolution: "@storybook/global@npm:5.0.0" + checksum: ede0ad35ec411fe31c61150dbd118fef344d1d0e72bf5d3502368e35cf68126f6b7ae4a0ab5e2ffe2f0baa3b4286f03ad069ba3e098e1725449ef08b7e154ba8 + languageName: node + linkType: hard + "@storybook/manager-webpack4@npm:6.5.16": version: 6.5.16 resolution: "@storybook/manager-webpack4@npm:6.5.16" @@ -6200,7 +6197,7 @@ __metadata: languageName: node linkType: hard -"@storybook/manager-webpack5@npm:^6.5.13": +"@storybook/manager-webpack5@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/manager-webpack5@npm:6.5.16" dependencies: @@ -6332,7 +6329,7 @@ __metadata: languageName: node linkType: hard -"@storybook/react@npm:^6.5.13": +"@storybook/react@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/react@npm:6.5.16" dependencies: @@ -6508,7 +6505,7 @@ __metadata: languageName: node linkType: hard -"@storybook/test-runner@npm:^0.9.2": +"@storybook/test-runner@npm:^0.9.4": version: 0.9.4 resolution: "@storybook/test-runner@npm:0.9.4" dependencies: @@ -6548,7 +6545,7 @@ __metadata: languageName: node linkType: hard -"@storybook/theming@npm:6.5.16, @storybook/theming@npm:^6.5.13": +"@storybook/theming@npm:6.5.16, @storybook/theming@npm:^6.5.14, @storybook/theming@npm:^6.5.16": version: 6.5.16 resolution: "@storybook/theming@npm:6.5.16" dependencies: @@ -7604,9 +7601,9 @@ __metadata: linkType: hard "@types/node@npm:^14.0.10 || ^16.0.0, @types/node@npm:^14.14.20 || ^16.0.0, @types/node@npm:^16.7.10": - version: 16.11.56 - resolution: "@types/node@npm:16.11.56" - checksum: b4efade16eb08a39810921c54a1637e69c8f3184a20d87e8fe74d557d9bda73f0829ac318e2a30a32b1903e4b099812defd1dfe438be70b98dbfbea5b0d99a53 + version: 16.18.25 + resolution: "@types/node@npm:16.18.25" + checksum: 181760ad6b54fcc498dfeb249e98bbf0be51d7c35e92e760e1a82004fa42b86e8c33a8f8dd7743b5ef872bda0753d9e6a5b8e3f0aed63e9eb79b4e65760c1fbe languageName: node linkType: hard @@ -7781,6 +7778,13 @@ __metadata: languageName: node linkType: hard +"@types/semver@npm:^7.3.12": + version: 7.3.13 + resolution: "@types/semver@npm:7.3.13" + checksum: 00c0724d54757c2f4bc60b5032fe91cda6410e48689633d5f35ece8a0a66445e3e57fa1d6e07eb780f792e82ac542948ec4d0b76eb3484297b79bd18b8cf1cb0 + languageName: node + linkType: hard + "@types/sinon@npm:^10.0.13": version: 10.0.13 resolution: "@types/sinon@npm:10.0.13" @@ -8042,17 +8046,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/experimental-utils@npm:^5.3.0": - version: 5.34.0 - resolution: "@typescript-eslint/experimental-utils@npm:5.34.0" - dependencies: - "@typescript-eslint/utils": 5.34.0 - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: adbb3c64846a2a75f655f7985798e7d4a54c8ae1510ffddfeefc693908e605440dad27d83dce2d8425b7d304257ac68aa30cb31a99947e484205a126be804d97 - languageName: node - linkType: hard - "@typescript-eslint/parser@npm:^5.30.7": version: 5.30.7 resolution: "@typescript-eslint/parser@npm:5.30.7" @@ -8080,13 +8073,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.34.0": - version: 5.34.0 - resolution: "@typescript-eslint/scope-manager@npm:5.34.0" +"@typescript-eslint/scope-manager@npm:5.59.1": + version: 5.59.1 + resolution: "@typescript-eslint/scope-manager@npm:5.59.1" dependencies: - "@typescript-eslint/types": 5.34.0 - "@typescript-eslint/visitor-keys": 5.34.0 - checksum: 039893fa1b8d349427c642a24932dba7932be823f860ce191691d999cd77ac99c3cc743ecd9dd68ad58ba987626e77c1ec458dad9534623e136766b9f9c5c9bf + "@typescript-eslint/types": 5.59.1 + "@typescript-eslint/visitor-keys": 5.59.1 + checksum: ae7758181d0f18d1ad20abf95164553fa98c20410968d538ac7abd430ec59f69e30d4da16ad968d029feced1ed49abc65daf6685c996eb4529d798e8320204ff languageName: node linkType: hard @@ -8120,10 +8113,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:5.34.0": - version: 5.34.0 - resolution: "@typescript-eslint/types@npm:5.34.0" - checksum: 74ad0302ebac160d1b8178ff07183868018a9b558137c638140b24589ba71dbeccfcedf57156f4d6b7443b139e186ede24a01cba66132f0bda6f891d515878fb +"@typescript-eslint/types@npm:5.59.1": + version: 5.59.1 + resolution: "@typescript-eslint/types@npm:5.59.1" + checksum: 40ea7ccf59c4951797d3761e53c866a5979e07fbdabef9dc07d3a3f625a99d4318d5329ae8e628cdfdc0bb9bb6e6d8dfb740f33c7bf318e63fa0a863b9ae85c7 languageName: node linkType: hard @@ -8145,12 +8138,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.34.0": - version: 5.34.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.34.0" +"@typescript-eslint/typescript-estree@npm:5.59.1": + version: 5.59.1 + resolution: "@typescript-eslint/typescript-estree@npm:5.59.1" dependencies: - "@typescript-eslint/types": 5.34.0 - "@typescript-eslint/visitor-keys": 5.34.0 + "@typescript-eslint/types": 5.59.1 + "@typescript-eslint/visitor-keys": 5.59.1 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -8159,7 +8152,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 2b9dac41d6dc544a2f61384ef8ed6559a15bdc19d9e49257829441dd166dd0ca395f4f6b42c97fbb2f006b1a6e7c8907c149add7644267b638ec7f1c0d01de30 + checksum: e33081937225f38e717ac2f9e90c4a8c6b71b701923eea3e03be76d8c466f0d3c6a4ec1d65c9fc1da4f1989416d386305353c5b53aa736d3af9503061001e3eb languageName: node linkType: hard @@ -8197,19 +8190,21 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.34.0, @typescript-eslint/utils@npm:^5.10.0": - version: 5.34.0 - resolution: "@typescript-eslint/utils@npm:5.34.0" +"@typescript-eslint/utils@npm:^5.10.0, @typescript-eslint/utils@npm:^5.45.0": + version: 5.59.1 + resolution: "@typescript-eslint/utils@npm:5.59.1" dependencies: + "@eslint-community/eslint-utils": ^4.2.0 "@types/json-schema": ^7.0.9 - "@typescript-eslint/scope-manager": 5.34.0 - "@typescript-eslint/types": 5.34.0 - "@typescript-eslint/typescript-estree": 5.34.0 + "@types/semver": ^7.3.12 + "@typescript-eslint/scope-manager": 5.59.1 + "@typescript-eslint/types": 5.59.1 + "@typescript-eslint/typescript-estree": 5.59.1 eslint-scope: ^5.1.1 - eslint-utils: ^3.0.0 + semver: ^7.3.7 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 6b05bb2bf5c492dec19ae8ee29550ede1c76cc46c5aa03c4b83aff4b1205611e3e03e7fbf3839d60acce8c596ee7cbf715117b474fdcfd47c6879d504a4c3401 + checksum: ca32c90efa57e937ebf812221e070c0604ca99f900fbca60578b42d40c923d5a94fd9503cf5918ecd75b687b68a1be562f7c6593a329bc40b880c95036a021c0 languageName: node linkType: hard @@ -8233,13 +8228,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.34.0": - version: 5.34.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.34.0" +"@typescript-eslint/visitor-keys@npm:5.59.1": + version: 5.59.1 + resolution: "@typescript-eslint/visitor-keys@npm:5.59.1" dependencies: - "@typescript-eslint/types": 5.34.0 + "@typescript-eslint/types": 5.59.1 eslint-visitor-keys: ^3.3.0 - checksum: b5574ce8363f905f0a11e14126ec606130bbcc151c326c004d0f510c8e4e884175a70e0299adb0a82ed817db469558d2d385137c09837249118e15cbfa47bff2 + checksum: f98e399147310cad67de718a8a6336f053d46753bade380c89ddac3dd49512555c3f613636b255ce0b5e2b004654d1c167eb5e53fc8085148b637a5afc20cdd8 languageName: node linkType: hard @@ -8649,9 +8644,9 @@ __metadata: languageName: node linkType: hard -"@whitespace/storybook-addon-html@npm:^5.1.1": - version: 5.1.1 - resolution: "@whitespace/storybook-addon-html@npm:5.1.1" +"@whitespace/storybook-addon-html@npm:^5.1.4": + version: 5.1.4 + resolution: "@whitespace/storybook-addon-html@npm:5.1.4" peerDependencies: "@storybook/addons": ^6.5.8 "@storybook/api": ^6.5.8 @@ -8667,7 +8662,7 @@ __metadata: optional: true react-dom: optional: true - checksum: 34bdd5e2ffeffeb7c6fb57e4c913dce4cbf87e118cfd6d26556fce0313e7233f1eaa17eb61da3eef3c8b8c345cf341f774a26e927c4d3a6aa791b8685ed66c92 + checksum: cd2b3da31774bf44f6cda1f91e77d627f601caee4050a01afe2f3c61d0d7e87e27bb6d7a32dd36208b4a0992b77f537c48cc55c683d50b7334212e8131a3ee93 languageName: node linkType: hard @@ -15292,17 +15287,17 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-storybook@npm:^0.6.4": - version: 0.6.4 - resolution: "eslint-plugin-storybook@npm:0.6.4" +"eslint-plugin-storybook@npm:^0.6.10": + version: 0.6.11 + resolution: "eslint-plugin-storybook@npm:0.6.11" dependencies: "@storybook/csf": ^0.0.1 - "@typescript-eslint/experimental-utils": ^5.3.0 + "@typescript-eslint/utils": ^5.45.0 requireindex: ^1.1.0 ts-dedent: ^2.2.0 peerDependencies: eslint: ">=6" - checksum: 9bc1befb50ed741ee27f0492ba5c8c6c3d8d54a8ac53bd6c2054046a2918829d80b0f0ff916abe10c7e01fb45d29ec284ff9d19d0ef35d7812367b4f708756a3 + checksum: efb85688041d4fd02be0cc51f07803acffaa54fdf61c21e9ae9eb18f26e6b8aec50911cfa71855ff4322b377b62cd53e7bf549faf60df4f20b8840171eab0029 languageName: node linkType: hard @@ -16737,7 +16732,7 @@ __metadata: languageName: node linkType: hard -"fast-deep-equal@npm:^3.0.0, fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": +"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" checksum: e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d @@ -24242,22 +24237,22 @@ __metadata: "@sentry/integrations": ^6.0.0 "@sentry/types": ^6.0.1 "@sentry/utils": ^6.0.1 - "@storybook/addon-a11y": ^6.5.13 - "@storybook/addon-actions": ^6.5.13 - "@storybook/addon-essentials": ^6.5.13 + "@storybook/addon-a11y": ^6.5.16 + "@storybook/addon-actions": ^6.5.16 + "@storybook/addon-essentials": ^6.5.16 "@storybook/addon-knobs": ^6.4.0 - "@storybook/addons": ^6.5.13 - "@storybook/api": ^6.5.13 - "@storybook/builder-webpack5": ^6.5.13 - "@storybook/client-api": ^6.5.13 - "@storybook/components": ^6.5.13 - "@storybook/core": ^6.5.13 - "@storybook/core-events": ^6.5.13 - "@storybook/manager-webpack5": ^6.5.13 - "@storybook/react": ^6.5.13 + "@storybook/addons": ^6.5.16 + "@storybook/api": ^6.5.16 + "@storybook/builder-webpack5": ^6.5.16 + "@storybook/client-api": ^6.5.16 + "@storybook/components": ^6.5.16 + "@storybook/core": ^6.5.16 + "@storybook/core-events": ^6.5.16 + "@storybook/manager-webpack5": ^6.5.16 + "@storybook/react": ^6.5.16 "@storybook/storybook-deployer": ^2.8.16 - "@storybook/test-runner": ^0.9.2 - "@storybook/theming": ^6.5.13 + "@storybook/test-runner": ^0.9.4 + "@storybook/theming": ^6.5.16 "@testing-library/jest-dom": ^5.11.10 "@testing-library/react": ^10.4.8 "@testing-library/react-hooks": ^8.0.1 @@ -24291,7 +24286,7 @@ __metadata: "@types/yargs": ^17.0.8 "@typescript-eslint/eslint-plugin": ^5.30.7 "@typescript-eslint/parser": ^5.30.7 - "@whitespace/storybook-addon-html": ^5.1.1 + "@whitespace/storybook-addon-html": ^5.1.4 "@zxing/browser": ^0.0.10 "@zxing/library": 0.8.0 addons-linter: ^5.2.0 @@ -24338,7 +24333,7 @@ __metadata: eslint-plugin-prettier: ^4.2.1 eslint-plugin-react: ^7.23.1 eslint-plugin-react-hooks: ^4.2.0 - eslint-plugin-storybook: ^0.6.4 + eslint-plugin-storybook: ^0.6.10 eth-block-tracker: ^7.0.0 eth-ens-namehash: ^2.0.8 eth-json-rpc-filters: ^6.0.0 @@ -24466,7 +24461,7 @@ __metadata: source-map: ^0.7.2 source-map-explorer: ^2.4.2 squirrelly: ^8.0.8 - storybook-dark-mode: ^1.1.0 + storybook-dark-mode: ^2.1.1 stream-browserify: ^3.0.0 string.prototype.matchall: ^4.0.2 style-loader: ^0.21.0 @@ -31638,19 +31633,27 @@ __metadata: languageName: node linkType: hard -"storybook-dark-mode@npm:^1.1.0": - version: 1.1.0 - resolution: "storybook-dark-mode@npm:1.1.0" +"storybook-dark-mode@npm:^2.1.1": + version: 2.1.1 + resolution: "storybook-dark-mode@npm:2.1.1" dependencies: - fast-deep-equal: ^3.0.0 + "@storybook/addons": ^6.5.14 + "@storybook/api": ^6.5.14 + "@storybook/components": ^6.5.14 + "@storybook/core-events": ^6.5.14 + "@storybook/global": ^5.0.0 + "@storybook/theming": ^6.5.14 + fast-deep-equal: ^3.1.3 memoizerific: ^1.11.3 peerDependencies: - "@storybook/addons": ^6.0.0 - "@storybook/api": ^6.0.0 - "@storybook/components": ^6.0.0 - "@storybook/core-events": ^6.0.0 - "@storybook/theming": ^6.0.0 - checksum: e1d7abbb96d1cdbe9cdba1e20aabffa6878f170e348958cc328de4183027c2052f44f6d78f82a45039f803349c7a4ec19988d42898030b2720dc591192f520e6 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + checksum: 44d6313013a1d63f47c95e2e8e0d11c24d467b3540259e152ceb3236636dbadf7a46c6f7f183946b105ee53173cb13815f1f88ca6da41fc74673c3c11f619863 languageName: node linkType: hard From dd04913e7e26da6ccdad769ba8619beadeb1e9e1 Mon Sep 17 00:00:00 2001 From: Harsh Shukla <125105825+PrgrmrHarshShukla@users.noreply.github.com> Date: Mon, 8 May 2023 19:25:25 +0530 Subject: [PATCH 008/120] Working on some lint issues in 2 files. (#18633) * Addressed some lint issues. * Worked on the mentioned lint issue. * Worked on the CRLF lint issues. --------- Co-authored-by: Brad Decker Co-authored-by: George Marshall --- .../advanced-gas-fee-defaults.js | 12 ++++++------ .../advanced-gas-fee-gas-limit.js | 13 +++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.js b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.js index 0890f679b..c4a57667d 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.js +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.js @@ -4,20 +4,19 @@ import { useSelector, useDispatch } from 'react-redux'; import { useTransactionEventFragment } from '../../../../hooks/useTransactionEventFragment'; import { EditGasModes } from '../../../../../shared/constants/gas'; import Box from '../../../ui/box'; -import Typography from '../../../ui/typography'; import CheckBox from '../../../ui/check-box'; import { DISPLAY, FLEX_DIRECTION, TextColor, - TypographyVariant, + TextVariant, } from '../../../../helpers/constants/design-system'; import { getAdvancedGasFeeValues } from '../../../../selectors'; import { setAdvancedGasFee } from '../../../../store/actions'; import { useGasFeeContext } from '../../../../contexts/gasFee'; - import { useAdvancedGasFeePopoverContext } from '../context'; import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { Text } from '../../../component-library'; const AdvancedGasFeeDefaults = () => { const t = useI18nContext(); @@ -87,8 +86,9 @@ const AdvancedGasFeeDefaults = () => { onClick={handleUpdateDefaultSettings} disabled={gasErrors.maxFeePerGas || gasErrors.maxPriorityFeePerGas} /> - @@ -97,7 +97,7 @@ const AdvancedGasFeeDefaults = () => { : t('advancedGasFeeDefaultOptIn', [ {t('newValues')}, ])} - +
); diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.js b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.js index e26720b01..9c8af1bb7 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.js +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.js @@ -2,14 +2,14 @@ import React, { useEffect, useState } from 'react'; import { useGasFeeContext } from '../../../../contexts/gasFee'; import { bnGreaterThan, bnLessThan } from '../../../../helpers/utils/util'; -import { TypographyVariant } from '../../../../helpers/constants/design-system'; +import { TextVariant } from '../../../../helpers/constants/design-system'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import { MAX_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'; import Button from '../../../ui/button'; import FormField from '../../../ui/form-field'; -import Typography from '../../../ui/typography'; import { useAdvancedGasFeePopoverContext } from '../context'; +import { Text } from '../../../component-library'; const validateGasLimit = (gasLimit, minimumGasLimitDec) => { return bnLessThan(gasLimit, minimumGasLimitDec) || @@ -58,9 +58,10 @@ const AdvancedGasFeeGasLimit = () => { } return ( - { > {t('edit')} - +
); }; From a5494fc637c711ce0272e1d49a3b2cde095d7c14 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 8 May 2023 09:03:34 -0500 Subject: [PATCH 009/120] UX: Multichain: Account Details Fixes (#18999) * Fix account details editable label * Fix font-weight of the password label * Remove duplicate error * Hide password warning on first screen after bad password, autofocus password field * Fix jest failure * Restore className --- .../account-details-modal.test.js | 4 +- .../account-details-authenticate.js | 17 ++----- .../account-details/account-details.js | 5 +- .../account-details/account-details.test.js | 2 +- .../ui/editable-label/editable-label.js | 49 ++++++++++++------- ui/components/ui/editable-label/index.scss | 46 ----------------- ui/components/ui/ui-components.scss | 1 - ui/helpers/utils/accounts.js | 6 ++- 8 files changed, 46 insertions(+), 84 deletions(-) delete mode 100644 ui/components/ui/editable-label/index.scss diff --git a/ui/components/app/modals/account-details-modal/account-details-modal.test.js b/ui/components/app/modals/account-details-modal/account-details-modal.test.js index 72bf233c2..7b85c27bb 100644 --- a/ui/components/app/modals/account-details-modal/account-details-modal.test.js +++ b/ui/components/app/modals/account-details-modal/account-details-modal.test.js @@ -24,7 +24,7 @@ describe('Account Details Modal', () => { global.platform = { openTab: jest.fn() }; it('should set account label when changing default account label', () => { - const { queryByTestId } = renderWithProvider( + const { queryByTestId, getByPlaceholderText } = renderWithProvider( , mockStore, ); @@ -35,7 +35,7 @@ describe('Account Details Modal', () => { fireEvent.click(editButton); expect(queryByTestId('editable-input')).toBeInTheDocument(); - const editableInput = queryByTestId('editable-input'); + const editableInput = getByPlaceholderText('Account name'); const newAccountLabel = 'New Label'; fireEvent.change(editableInput, { diff --git a/ui/components/multichain/account-details/account-details-authenticate.js b/ui/components/multichain/account-details/account-details-authenticate.js index 240b618a4..c76bde71b 100644 --- a/ui/components/multichain/account-details/account-details-authenticate.js +++ b/ui/components/multichain/account-details/account-details-authenticate.js @@ -3,8 +3,8 @@ import { useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import { DISPLAY, + FontWeight, SEVERITIES, - TextColor, TextVariant, } from '../../../helpers/constants/design-system'; import { @@ -56,19 +56,10 @@ export const AccountDetailsAuthenticate = ({ address, onCancel }) => { value={password} variant={TextVariant.bodySm} type="password" - inputProps={{ - onKeyPress: handleKeyPress, - }} + inputProps={{ onKeyPress: handleKeyPress }} + labelProps={{ fontWeight: FontWeight.Medium }} + autoFocus /> - {warning ? ( - - {warning} - - ) : null} {t('privateKeyWarning')} diff --git a/ui/components/multichain/account-details/account-details.js b/ui/components/multichain/account-details/account-details.js index 70fa9e862..67244de38 100644 --- a/ui/components/multichain/account-details/account-details.js +++ b/ui/components/multichain/account-details/account-details.js @@ -79,7 +79,10 @@ export const AccountDetails = ({ address }) => { setAttemptingExport(false)} + onClick={() => { + dispatch(hideWarning()); + setAttemptingExport(false); + }} iconName={IconName.ArrowLeft} size={Size.SM} /> diff --git a/ui/components/multichain/account-details/account-details.test.js b/ui/components/multichain/account-details/account-details.test.js index baec78f20..4caed5b0f 100644 --- a/ui/components/multichain/account-details/account-details.test.js +++ b/ui/components/multichain/account-details/account-details.test.js @@ -45,7 +45,7 @@ describe('AccountDetails', () => { const editButton = screen.getByTestId('editable-label-button'); fireEvent.click(editButton); - const editableInput = screen.getByTestId('editable-input'); + const editableInput = screen.getByPlaceholderText('Account name'); const newAccountLabel = 'New Label'; fireEvent.change(editableInput, { target: { value: newAccountLabel } }); diff --git a/ui/components/ui/editable-label/editable-label.js b/ui/components/ui/editable-label/editable-label.js index 7a0558cd8..8e944efec 100644 --- a/ui/components/ui/editable-label/editable-label.js +++ b/ui/components/ui/editable-label/editable-label.js @@ -1,9 +1,20 @@ +import React, { Component } from 'react'; import classnames from 'classnames'; import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { Color } from '../../../helpers/constants/design-system'; +import { + AlignItems, + Color, + DISPLAY, + TextVariant, +} from '../../../helpers/constants/design-system'; import { getAccountNameErrorMessage } from '../../../helpers/utils/accounts'; -import { ButtonIcon, IconName } from '../../component-library'; +import { + ButtonIcon, + FormTextField, + IconName, + Text, +} from '../../component-library'; +import Box from '../box/box'; export default class EditableLabel extends Component { static propTypes = { @@ -40,40 +51,40 @@ export default class EditableLabel extends Component { ); return ( -
- + { if (event.key === 'Enter') { this.handleSubmit(isValidAccountName); } }} - onChange={(event) => this.setState({ value: event.target.value })} + onChange={(event) => { + this.setState({ value: event.target.value }); + }} data-testid="editable-input" - className={classnames('large-input', 'editable-label__input', { - 'editable-label__input--error': !isValidAccountName, - })} + error={!isValidAccountName} + helpText={errorMessage} autoFocus + placeholder={this.context.t('accountName')} /> this.handleSubmit(isValidAccountName)} /> -
- {errorMessage} -
-
+
); } renderReadonly() { return ( -
-
{this.state.value}
+ + {this.state.value} this.setState({ isEditing: true })} color={Color.iconDefault} /> -
+ ); } diff --git a/ui/components/ui/editable-label/index.scss b/ui/components/ui/editable-label/index.scss deleted file mode 100644 index d4b0b7983..000000000 --- a/ui/components/ui/editable-label/index.scss +++ /dev/null @@ -1,46 +0,0 @@ -.editable-label { - display: flex; - align-items: center; - justify-content: center; - position: relative; - flex-flow: wrap; - - &__value { - max-width: 250px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - - &__input { - @include H6; - - color: var(--color-text-default); - background-color: var(--color-background-default); - width: 250px; - text-align: center; - border: 1px solid var(--color-border-default); - - &--error { - border: 1px solid var(--color-error-default); - } - } - - &__icon-button { - margin-left: 10px; - left: 100%; - } - - &__error { - @include H7; - - left: 8px; - color: var(--color-error-default); - width: 100%; - text-align: center; - } - - &__error-amount { - margin-top: 5px; - } -} diff --git a/ui/components/ui/ui-components.scss b/ui/components/ui/ui-components.scss index 9558e3ea4..6f012fb2a 100644 --- a/ui/components/ui/ui-components.scss +++ b/ui/components/ui/ui-components.scss @@ -16,7 +16,6 @@ @import 'definition-list/definition-list'; @import 'dialog/dialog'; @import 'dropdown/dropdown'; -@import 'editable-label/index'; @import 'error-message/index'; @import 'icon-border/icon-border'; @import 'icon-button/icon-button'; diff --git a/ui/helpers/utils/accounts.js b/ui/helpers/utils/accounts.js index 6bfa68d86..4f953bf66 100644 --- a/ui/helpers/utils/accounts.js +++ b/ui/helpers/utils/accounts.js @@ -10,6 +10,8 @@ export function getAccountNameErrorMessage( (item) => item.name === newAccountName, ); + const isEmptyAccountName = newAccountName === ''; + const localizedWordForAccount = context .t('newAccountNumberName') .replace(' $1', ''); @@ -24,7 +26,7 @@ export function getAccountNameErrorMessage( const isValidAccountName = newAccountName === defaultAccountName || // What is written in the text field is the same as the placeholder - (!isDuplicateAccountName && !isReservedAccountName); + (!isDuplicateAccountName && !isReservedAccountName && !isEmptyAccountName); let errorMessage; if (isValidAccountName) { @@ -33,6 +35,8 @@ export function getAccountNameErrorMessage( errorMessage = context.t('accountNameDuplicate'); } else if (isReservedAccountName) { errorMessage = context.t('accountNameReserved'); + } else if (isEmptyAccountName) { + errorMessage = context.t('required'); } return { isValidAccountName, errorMessage }; From 7ebd561ff9cf84fc8c04dfbf8e69f6589c038e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Regadas?= Date: Mon, 8 May 2023 15:09:00 +0100 Subject: [PATCH 010/120] [MMI] adds mmi logic in home view (#18960) * adds mmi logic to home container * adds code fences to home component * adds code fences to home component * lint fix * lint fix * updates fences and runs prettier * version bump * clean up code fence --- package.json | 1 + ui/pages/home/home.component.js | 156 ++++++++++++++++++++++++++++---- ui/pages/home/home.container.js | 110 ++++++++++++++-------- yarn.lock | 8 ++ 4 files changed, 216 insertions(+), 59 deletions(-) diff --git a/package.json b/package.json index a66a79c11..e878e91a8 100644 --- a/package.json +++ b/package.json @@ -231,6 +231,7 @@ "@keystonehq/metamask-airgapped-keyring": "^0.9.2", "@lavamoat/snow": "^1.5.0", "@material-ui/core": "^4.11.0", + "@metamask-institutional/portfolio-dashboard": "1.1.2", "@metamask/address-book-controller": "^2.0.0", "@metamask/announcement-controller": "^3.0.0", "@metamask/approval-controller": "^2.1.0", diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index e32d6ebee..6bcb8532e 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -55,9 +55,14 @@ import { CONFIRMATION_V_NEXT_ROUTE, ADD_NFT_ROUTE, ONBOARDING_SECURE_YOUR_WALLET_ROUTE, + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + CONFIRM_INSTITUTIONAL_FEATURE_CONNECT, + CONFIRM_ADD_CUSTODIAN_TOKEN, + INTERACTIVE_REPLACEMENT_TOKEN_PAGE, + ///: END:ONLY_INCLUDE_IN } from '../../helpers/constants/routes'; import ZENDESK_URLS from '../../helpers/constants/zendesk-url'; -///: BEGIN:ONLY_INCLUDE_IN(build-main) +///: BEGIN:ONLY_INCLUDE_IN(build-main,build-mmi) import { SUPPORT_LINK } from '../../../shared/lib/ui-utils'; ///: END:ONLY_INCLUDE_IN ///: BEGIN:ONLY_INCLUDE_IN(build-beta) @@ -71,12 +76,25 @@ function shouldCloseNotificationPopup({ isNotification, totalUnapprovedCount, isSigningQRHardwareTransaction, + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + waitForConfirmDeepLinkDialog, + institutionalConnectRequests, + ///: END:ONLY_INCLUDE_IN }) { - return ( + let shouldCLose = isNotification && totalUnapprovedCount === 0 && - !isSigningQRHardwareTransaction - ); + !isSigningQRHardwareTransaction; + + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + shouldCLose &&= + // MMI User must be shown a deeplink + !waitForConfirmDeepLinkDialog && + // MMI User is connecting to custodian or compliance + institutionalConnectRequests.length === 0; + ///: END:ONLY_INCLUDE_IN + + return shouldCLose; } export default class Home extends PureComponent { @@ -152,6 +170,14 @@ export default class Home extends PureComponent { clearNewNetworkAdded: PropTypes.func, setActiveNetwork: PropTypes.func, onboardedInThisUISession: PropTypes.bool, + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + institutionalConnectRequests: PropTypes.arrayOf(PropTypes.object), + mmiPortfolioEnabled: PropTypes.bool, + mmiPortfolioUrl: PropTypes.string, + modalOpen: PropTypes.bool, + setWaitForConfirmDeepLinkDialog: PropTypes.func, + waitForConfirmDeepLinkDialog: PropTypes.bool, + ///: END:ONLY_INCLUDE_IN }; state = { @@ -188,6 +214,55 @@ export default class Home extends PureComponent { } } + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + checkInstitutionalConnectRequest() { + const { history, institutionalConnectRequests } = this.props; + if ( + institutionalConnectRequests && + institutionalConnectRequests.length > 0 && + institutionalConnectRequests[0].feature === 'custodian' + ) { + if ( + institutionalConnectRequests[0].method === + 'metamaskinstitutional_reauthenticate' + ) { + history.push(INTERACTIVE_REPLACEMENT_TOKEN_PAGE); + } else if ( + institutionalConnectRequests[0].method === + 'metamaskinstitutional_authenticate' + ) { + history.push(CONFIRM_ADD_CUSTODIAN_TOKEN); + } + } else if ( + institutionalConnectRequests && + institutionalConnectRequests.length > 0 && + institutionalConnectRequests[0].feature !== 'custodian' + ) { + history.push(CONFIRM_INSTITUTIONAL_FEATURE_CONNECT); + } + } + + shouldCloseCurrentWindow() { + const { + isNotification, + modalOpen, + totalUnapprovedCount, + institutionalConnectRequests, + waitForConfirmDeepLinkDialog, + } = this.props; + + if ( + isNotification && + totalUnapprovedCount === 0 && + institutionalConnectRequests.length === 0 && + !waitForConfirmDeepLinkDialog && + !modalOpen + ) { + global.platform.closeCurrentWindow(); + } + } + ///: END:ONLY_INCLUDE_IN + checkStatusAndNavigate() { const { firstPermissionsRequestId, @@ -200,6 +275,11 @@ export default class Home extends PureComponent { swapsFetchParams, pendingConfirmations, } = this.props; + + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + this.shouldCloseCurrentWindow(); + ///: END:ONLY_INCLUDE_IN + if (!isNotification && showAwaitingSwapScreen) { history.push(AWAITING_SWAP_ROUTE); } else if (!isNotification && haveSwapsQuotes) { @@ -215,10 +295,22 @@ export default class Home extends PureComponent { } else if (pendingConfirmations.length > 0) { history.push(CONFIRMATION_V_NEXT_ROUTE); } + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + this.checkInstitutionalConnectRequest(); + ///: END:ONLY_INCLUDE_IN } componentDidMount() { this.checkStatusAndNavigate(); + + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + const { setWaitForConfirmDeepLinkDialog } = this.props; + + window.addEventListener('beforeunload', () => { + // If user closes notification window manually, change waitForConfirmDeepLinkDialog to false + setWaitForConfirmDeepLinkDialog(false); + }); + ///: END:ONLY_INCLUDE_IN } static getDerivedStateFromProps(props) { @@ -625,6 +717,10 @@ export default class Home extends PureComponent { completedOnboarding, onboardedInThisUISession, newNetworkAddedConfigurationId, + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + mmiPortfolioEnabled, + mmiPortfolioUrl, + ///: END:ONLY_INCLUDE_IN } = this.props; if (forgottenPassword) { @@ -653,6 +749,9 @@ export default class Home extends PureComponent { exact />
+ { + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) + } {showWhatsNew ? : null} {!showWhatsNew && showRecoveryPhraseReminder ? ( {process.env.MULTICHAIN ? null : }
- + { + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) + + ///: END:ONLY_INCLUDE_IN + } + { + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + + ///: END:ONLY_INCLUDE_IN + }
- - { - history.push(ADD_NFT_ROUTE); - }} - /> - + { + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) + + { + history.push(ADD_NFT_ROUTE); + }} + /> + + ///: END:ONLY_INCLUDE_IN + }
{ - ///: BEGIN:ONLY_INCLUDE_IN(build-main) + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-mmi) t('needHelp', [ { const totalUnapprovedCount = getTotalUnapprovedCount(state); const swapsEnabled = getSwapsFeatureIsLive(state); const pendingConfirmations = getUnapprovedTemplatedConfirmations(state); + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + const institutionalConnectRequests = getInstitutionalConnectRequests(state); + ///: END:ONLY_INCLUDE_IN const envType = getEnvironmentType(); const isPopup = envType === ENVIRONMENT_TYPE_POPUP; @@ -155,50 +167,68 @@ const mapStateToProps = (state) => { newTokensImported: getNewTokensImported(state), newNetworkAddedConfigurationId: appState.newNetworkAddedConfigurationId, onboardedInThisUISession: appState.onboardedInThisUISession, + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + waitForConfirmDeepLinkDialog: getWaitForConfirmDeepLinkDialog(state), + institutionalConnectRequests, + modalOpen: state.appState.modal.open, + mmiPortfolioUrl: getMmiPortfolioUrl(state), + mmiPortfolioEnabled: getMmiPortfolioEnabled(state), + notificationsToShow: getSortedAnnouncementsToShow(state).length > 0, + ///: END:ONLY_INCLUDE_IN }; }; -const mapDispatchToProps = (dispatch) => ({ - closeNotificationPopup: () => closeNotificationPopup(), - ///: BEGIN:ONLY_INCLUDE_IN(snaps) - removeSnapError: async (id) => await removeSnapError(id), +const mapDispatchToProps = (dispatch) => { + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + const mmiActions = mmiActionsFactory(); ///: END:ONLY_INCLUDE_IN - setConnectedStatusPopoverHasBeenShown: () => - dispatch(setConnectedStatusPopoverHasBeenShown()), - onTabClick: (name) => dispatch(setDefaultHomeActiveTabName(name)), - setWeb3ShimUsageAlertDismissed: (origin) => - setWeb3ShimUsageAlertDismissed(origin), - disableWeb3ShimUsageAlert: () => - setAlertEnabledness(AlertTypes.web3ShimUsage, false), - hideWhatsNewPopup: () => dispatch(hideWhatsNewPopup()), - setRecoveryPhraseReminderHasBeenShown: () => - dispatch(setRecoveryPhraseReminderHasBeenShown()), - setRecoveryPhraseReminderLastShown: (lastShown) => - dispatch(setRecoveryPhraseReminderLastShown(lastShown)), - setTermsOfUseLastAgreed: (lastAgreed) => { - dispatch(setTermsOfUseLastAgreed(lastAgreed)); - }, - setOutdatedBrowserWarningLastShown: (lastShown) => { - dispatch(setOutdatedBrowserWarningLastShown(lastShown)); - }, - setNewNftAddedMessage: (message) => { - dispatch(setRemoveNftMessage('')); - dispatch(setNewNftAddedMessage(message)); - }, - setRemoveNftMessage: (message) => { - dispatch(setNewNftAddedMessage('')); - dispatch(setRemoveNftMessage(message)); - }, - setNewTokensImported: (newTokens) => { - dispatch(setNewTokensImported(newTokens)); - }, - clearNewNetworkAdded: () => { - dispatch(setNewNetworkAdded({})); - }, - setActiveNetwork: (networkConfigurationId) => { - dispatch(setActiveNetwork(networkConfigurationId)); - }, -}); + + return { + closeNotificationPopup: () => closeNotificationPopup(), + ///: BEGIN:ONLY_INCLUDE_IN(snaps) + removeSnapError: async (id) => await removeSnapError(id), + ///: END:ONLY_INCLUDE_IN + setConnectedStatusPopoverHasBeenShown: () => + dispatch(setConnectedStatusPopoverHasBeenShown()), + onTabClick: (name) => dispatch(setDefaultHomeActiveTabName(name)), + setWeb3ShimUsageAlertDismissed: (origin) => + setWeb3ShimUsageAlertDismissed(origin), + disableWeb3ShimUsageAlert: () => + setAlertEnabledness(AlertTypes.web3ShimUsage, false), + hideWhatsNewPopup: () => dispatch(hideWhatsNewPopup()), + setRecoveryPhraseReminderHasBeenShown: () => + dispatch(setRecoveryPhraseReminderHasBeenShown()), + setRecoveryPhraseReminderLastShown: (lastShown) => + dispatch(setRecoveryPhraseReminderLastShown(lastShown)), + setTermsOfUseLastAgreed: (lastAgreed) => { + dispatch(setTermsOfUseLastAgreed(lastAgreed)); + }, + setOutdatedBrowserWarningLastShown: (lastShown) => { + dispatch(setOutdatedBrowserWarningLastShown(lastShown)); + }, + setNewNftAddedMessage: (message) => { + dispatch(setRemoveNftMessage('')); + dispatch(setNewNftAddedMessage(message)); + }, + setRemoveNftMessage: (message) => { + dispatch(setNewNftAddedMessage('')); + dispatch(setRemoveNftMessage(message)); + }, + setNewTokensImported: (newTokens) => { + dispatch(setNewTokensImported(newTokens)); + }, + clearNewNetworkAdded: () => { + dispatch(setNewNetworkAdded({})); + }, + setActiveNetwork: (networkConfigurationId) => { + dispatch(setActiveNetwork(networkConfigurationId)); + }, + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + setWaitForConfirmDeepLinkDialog: (wait) => + dispatch(mmiActions.setWaitForConfirmDeepLinkDialog(wait)), + ///: END:ONLY_INCLUDE_IN + }; +}; export default compose( withRouter, diff --git a/yarn.lock b/yarn.lock index 8b87ccdc8..aab21f545 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3614,6 +3614,13 @@ __metadata: languageName: node linkType: hard +"@metamask-institutional/portfolio-dashboard@npm:1.1.2": + version: 1.1.2 + resolution: "@metamask-institutional/portfolio-dashboard@npm:1.1.2" + checksum: f2e1ec83fe0411f4d2e67dfdf2183f89667f34ae862425ece7b5cd0f4099eb7ae091910d67a3f15b7b5982e87bc80e9f668c25072c3bc5a977377fce14357cd3 + languageName: node + linkType: hard + "@metamask/abi-utils@npm:^1.1.0": version: 1.1.1 resolution: "@metamask/abi-utils@npm:1.1.1" @@ -24173,6 +24180,7 @@ __metadata: "@lavamoat/lavapack": ^5.0.0 "@lavamoat/snow": ^1.5.0 "@material-ui/core": ^4.11.0 + "@metamask-institutional/portfolio-dashboard": 1.1.2 "@metamask/address-book-controller": ^2.0.0 "@metamask/announcement-controller": ^3.0.0 "@metamask/approval-controller": ^2.1.0 From 4ad281c8063c469857ea5293e83a8d37918ac86a Mon Sep 17 00:00:00 2001 From: Harsh Shukla <125105825+PrgrmrHarshShukla@users.noreply.github.com> Date: Mon, 8 May 2023 19:52:33 +0530 Subject: [PATCH 011/120] Part of #17670 & #18714: Replace Typography with Text component: nft-details.js (#18771) * Update nft-details.js * Update nft-details.test.js.snap * Update nft-details.js * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update ui/components/app/nft-details/nft-details.js Co-authored-by: George Marshall * Update nft-details.test.js.snap --------- Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> Co-authored-by: Brad Decker Co-authored-by: George Marshall Co-authored-by: George Marshall --- .../__snapshots__/nft-details.test.js.snap | 22 +- ui/components/app/nft-details/nft-details.js | 191 ++++++++---------- 2 files changed, 100 insertions(+), 113 deletions(-) diff --git a/ui/components/app/nft-details/__snapshots__/nft-details.test.js.snap b/ui/components/app/nft-details/__snapshots__/nft-details.test.js.snap index b66a360ac..6dc2d4854 100644 --- a/ui/components/app/nft-details/__snapshots__/nft-details.test.js.snap +++ b/ui/components/app/nft-details/__snapshots__/nft-details.test.js.snap @@ -56,12 +56,12 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = ` >

MUNK #1

# 1 @@ -88,7 +88,7 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = ` class="box box--display-flex box--flex-direction-row" >
@@ -96,7 +96,7 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = ` class="box nft-details__contract-wrapper box--display-flex box--flex-direction-row" >
1/18/2023
@@ -106,7 +106,7 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = ` class="box box--display-flex box--flex-direction-row" > @@ -114,7 +114,7 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = ` class="box nft-details__contract-wrapper box--display-flex box--flex-direction-row" >
0.0049 ETH
@@ -124,12 +124,12 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = ` class="box box--display-flex box--flex-direction-row" >
@@ -153,7 +153,7 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = ` class="box nft-details__contract-wrapper box--display-flex box--flex-direction-row" >
0xDc7...6414
@@ -183,7 +183,7 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = `
Disclaimer: MetaMask pulls the media file from the source url. This url sometimes is changed by the marketplace the NFT was minted on.
diff --git a/ui/components/app/nft-details/nft-details.js b/ui/components/app/nft-details/nft-details.js index 336d5a96c..bbdd1df12 100644 --- a/ui/components/app/nft-details/nft-details.js +++ b/ui/components/app/nft-details/nft-details.js @@ -5,15 +5,14 @@ import { useHistory } from 'react-router-dom'; import { isEqual } from 'lodash'; import Box from '../../ui/box'; import Card from '../../ui/card'; -import Typography from '../../ui/typography/typography'; import { TextColor, IconColor, - TypographyVariant, - FONT_WEIGHT, + TextVariant, + FontWeight, JustifyContent, FLEX_DIRECTION, - OVERFLOW_WRAP, + OverflowWrap, DISPLAY, BLOCK_SIZES, } from '../../../helpers/constants/design-system'; @@ -53,7 +52,7 @@ import { TokenStandard, } from '../../../../shared/constants/transaction'; import NftDefaultImage from '../nft-default-image'; -import { ButtonIcon, IconName } from '../../component-library'; +import { ButtonIcon, IconName, Text } from '../../component-library'; import Tooltip from '../../ui/tooltip'; import { decWEIToDecETH } from '../../../../shared/modules/conversion.utils'; @@ -201,42 +200,45 @@ export default function NftDetails({ nft }) { justifyContent={JustifyContent.spaceBetween} >
- {name} - - + #{tokenId} - +
{description ? (
- {t('description')} - - + {description} - +
) : null} {inPopUp ? null : renderSendButton()} @@ -246,87 +248,78 @@ export default function NftDetails({ nft }) { {lastSale ? ( <> - {t('lastSold')} - + - {formattedTimestamp} - + - {t('lastPriceSold')} - + - {`${Number(decWEIToDecETH(lastSale.total_price))} ${ lastSale.payment_token.symbol }`} - + ) : null} - {t('source')} - - + )} - + {imageThumbnail ? ( - {t('link')} - - + {imageThumbnail}
- + ) : null} - {t('contractAddress')} - + - {shortenAddress(address)} - + {inPopUp ? renderSendButton() : null} - {t('nftDisclaimer')} - + From 90630edef7037e9e92cac9ab87377e0e0d79c050 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 8 May 2023 09:50:04 -0500 Subject: [PATCH 012/120] Fix #18916 - UX: Multichain: Network picker design updates (#18962) * Remove border radius from network menu list * Provide background color for test network avatars * Make button size large * Update ui/components/multichain/network-list-item/network-list-item.js Co-authored-by: Nidhi Kumari * Fix lint --------- Co-authored-by: Nidhi Kumari --- .../network-list-item/network-list-item.js | 25 ++++++++++++++++++- .../multichain/network-list-menu/index.scss | 5 ++++ .../network-list-menu/network-list-menu.js | 19 ++++++++++---- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/ui/components/multichain/network-list-item/network-list-item.js b/ui/components/multichain/network-list-item/network-list-item.js index a66bbc0be..6430fca6d 100644 --- a/ui/components/multichain/network-list-item/network-list-item.js +++ b/ui/components/multichain/network-list-item/network-list-item.js @@ -11,6 +11,7 @@ import { JustifyContent, TextColor, BLOCK_SIZES, + BackgroundColor, } from '../../../helpers/constants/design-system'; import { AvatarNetwork, @@ -20,9 +21,27 @@ import { } from '../../component-library'; import { useI18nContext } from '../../../hooks/useI18nContext'; import Tooltip from '../../ui/tooltip/tooltip'; +import { + GOERLI_DISPLAY_NAME, + LINEA_TESTNET_DISPLAY_NAME, + SEPOLIA_DISPLAY_NAME, +} from '../../../../shared/constants/network'; const MAXIMUM_CHARACTERS_WITHOUT_TOOLTIP = 17; +function getAvatarNetworkColor(name) { + switch (name) { + case GOERLI_DISPLAY_NAME: + return BackgroundColor.goerli; + case LINEA_TESTNET_DISPLAY_NAME: + return BackgroundColor.lineaTestnet; + case SEPOLIA_DISPLAY_NAME: + return BackgroundColor.sepolia; + default: + return undefined; + } +} + export const NetworkListItem = ({ name, iconSrc, @@ -60,7 +79,11 @@ export const NetworkListItem = ({ backgroundColor={Color.primaryDefault} /> )} - + { diff --git a/ui/components/multichain/network-list-menu/index.scss b/ui/components/multichain/network-list-menu/index.scss index fbd2ed7ba..19f83c1aa 100644 --- a/ui/components/multichain/network-list-menu/index.scss +++ b/ui/components/multichain/network-list-menu/index.scss @@ -1,4 +1,9 @@ .multichain-network-list-menu { max-height: 200px; overflow: auto; + + /* Overrides the popover's default behavior */ + &-content-wrapper { + border-radius: 0; + } } diff --git a/ui/components/multichain/network-list-menu/network-list-menu.js b/ui/components/multichain/network-list-menu/network-list-menu.js index 460f7ce1d..fffe5647b 100644 --- a/ui/components/multichain/network-list-menu/network-list-menu.js +++ b/ui/components/multichain/network-list-menu/network-list-menu.js @@ -26,7 +26,11 @@ import { DISPLAY, JustifyContent, } from '../../../helpers/constants/design-system'; -import { Button, BUTTON_VARIANT, Text } from '../../component-library'; +import { + BUTTON_SECONDARY_SIZES, + ButtonSecondary, + Text, +} from '../../component-library'; import { ADD_POPULAR_CUSTOM_NETWORK } from '../../../helpers/constants/routes'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../shared/constants/app'; @@ -64,7 +68,12 @@ export const NetworkListMenu = ({ onClose }) => { }, [showTestNetworks, showTestNetworksRef]); return ( - + <> {networks.map((network) => { @@ -158,8 +167,8 @@ export const NetworkListMenu = ({ onClose }) => { /> - + From 995887aa927d9622dfdead0ddc1a2e6ade7fccc0 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 8 May 2023 09:50:13 -0500 Subject: [PATCH 013/120] UX: Multichain: Ensure network picker renders properly for long and short names (#18974) * UX: Multichain: Ensure network picker renders properly for long and short network names * Updatte ui/components/multichain/app-header/app-header.js Co-authored-by: George Marshall * Update ui/components/multichain/app-header/app-header.js Co-authored-by: George Marshall * Update ui/components/multichain/app-header/app-header.js Co-authored-by: George Marshall * Update ui/components/multichain/app-header/app-header.js Co-authored-by: George Marshall * Update ui/components/multichain/app-header/app-header.js Co-authored-by: George Marshall * Update ui/components/multichain/app-header/app-header.scss Co-authored-by: George Marshall * Update ui/components/multichain/app-header/app-header.scss Co-authored-by: George Marshall * Fix jest issue --------- Co-authored-by: George Marshall --- .../__snapshots__/app-header.test.js.snap | 36 ++++++++++--------- .../multichain/app-header/app-header.js | 35 +++++++++++------- .../multichain/app-header/app-header.scss | 2 +- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap b/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap index 81e4fd326..d4cb98b3c 100644 --- a/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap +++ b/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap @@ -8,24 +8,26 @@ exports[`App Header should match snapshot 1`] = `
-
-

- Goerli -

- - +
+ G +
+

+ Goerli +

+ + +
{ onClick={networkOpenCallback} display={[DISPLAY.FLEX, DISPLAY.NONE]} // show on popover hide on desktop /> - + {popupStatus ? null : ( +
+ +
+ )} {showProductTour && popupStatus && multichainProductTourStep === 1 ? ( @@ -316,12 +321,16 @@ export const AppHeader = ({ onClick }) => { padding={2} gap={2} > - dispatch(toggleNetworkMenu())} - className="multichain-app-header__contents__network-picker" - /> + {popupStatus ? null : ( +
+ dispatch(toggleNetworkMenu())} + className="multichain-app-header__contents__network-picker" + /> +
+ )} { diff --git a/ui/components/multichain/app-header/app-header.scss b/ui/components/multichain/app-header/app-header.scss index 1bf3cbd82..e7a341711 100644 --- a/ui/components/multichain/app-header/app-header.scss +++ b/ui/components/multichain/app-header/app-header.scss @@ -30,7 +30,7 @@ } &__network-picker { - max-width: 200px; + max-width: 250px; } &--avatar-network { From 37b481f3056344de6d9c763ebeeaccc18146642e Mon Sep 17 00:00:00 2001 From: legobeat <109787230+legobeat@users.noreply.github.com> Date: Mon, 8 May 2023 15:11:36 +0000 Subject: [PATCH 014/120] devDeps: react-devtools@4.16.0->4.27.6 (#18869) --- yarn.lock | 359 +++++++++++++++--------------------------------------- 1 file changed, 98 insertions(+), 261 deletions(-) diff --git a/yarn.lock b/yarn.lock index aab21f545..a60d76397 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1777,26 +1777,22 @@ __metadata: languageName: node linkType: hard -"@electron/get@npm:^1.0.1": - version: 1.12.3 - resolution: "@electron/get@npm:1.12.3" +"@electron/get@npm:^2.0.0": + version: 2.0.2 + resolution: "@electron/get@npm:2.0.2" dependencies: debug: ^4.1.1 env-paths: ^2.2.0 - filenamify: ^4.1.0 fs-extra: ^8.1.0 - global-agent: ^2.0.2 - global-tunnel-ng: ^2.7.1 - got: ^9.6.0 + global-agent: ^3.0.0 + got: ^11.8.5 progress: ^2.0.3 semver: ^6.2.0 sumchecker: ^3.0.1 dependenciesMeta: global-agent: optional: true - global-tunnel-ng: - optional: true - checksum: 4aff199a7c38f1824eb8ae215f4c85dc7af61f8599b99d525a7fade850be1deaa5dfbe25fbea47bed23fca60f9291ca01c8c9ad5090b2fc60283a3999b60026e + checksum: 900845cc0b31b54761fc9b0ada2dea1e999e59aacc48999d53903bcb7c9a0a7356b5fe736cf610b2a56c5a21f5a3c0e083b2ed2b7e52c36a4d0f420d4b5ec268 languageName: node linkType: hard @@ -5192,13 +5188,6 @@ __metadata: languageName: node linkType: hard -"@sindresorhus/is@npm:^0.14.0": - version: 0.14.0 - resolution: "@sindresorhus/is@npm:0.14.0" - checksum: 971e0441dd44ba3909b467219a5e242da0fc584048db5324cfb8048148fa8dcc9d44d71e3948972c4f6121d24e5da402ef191420d1266a95f713bb6d6e59c98a - languageName: node - linkType: hard - "@sindresorhus/is@npm:^4.0.0": version: 4.6.0 resolution: "@sindresorhus/is@npm:4.6.0" @@ -6617,15 +6606,6 @@ __metadata: languageName: node linkType: hard -"@szmarczak/http-timer@npm:^1.1.2": - version: 1.1.2 - resolution: "@szmarczak/http-timer@npm:1.1.2" - dependencies: - defer-to-connect: ^1.0.1 - checksum: 4d9158061c5f397c57b4988cde33a163244e4f02df16364f103971957a32886beb104d6180902cbe8b38cb940e234d9f98a4e486200deca621923f62f50a06fe - languageName: node - linkType: hard - "@szmarczak/http-timer@npm:^4.0.5": version: 4.0.6 resolution: "@szmarczak/http-timer@npm:4.0.6" @@ -7600,24 +7580,17 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^12.0.12": - version: 12.19.15 - resolution: "@types/node@npm:12.19.15" - checksum: 9672f6f33d2461105902e15cd21f9de34bb2c331a95d7baab499b5822e1547e0716051374647bb4e430e3f57b1dae820aca624fe9ef6dc4cc74acbaab8ec1eab - languageName: node - linkType: hard - -"@types/node@npm:^14.0.10 || ^16.0.0, @types/node@npm:^14.14.20 || ^16.0.0, @types/node@npm:^16.7.10": - version: 16.18.25 - resolution: "@types/node@npm:16.18.25" - checksum: 181760ad6b54fcc498dfeb249e98bbf0be51d7c35e92e760e1a82004fa42b86e8c33a8f8dd7743b5ef872bda0753d9e6a5b8e3f0aed63e9eb79b4e65760c1fbe +"@types/node@npm:^14.0.10 || ^16.0.0, @types/node@npm:^14.14.20 || ^16.0.0, @types/node@npm:^16.11.26, @types/node@npm:^16.7.10": + version: 16.18.26 + resolution: "@types/node@npm:16.18.26" + checksum: 2a746b3f9e97e00aa5d1d8cce36c5b75d5504df15e82647ad1fadbc3435ea4491203d044bbaa595edc2ab25a9ab820793f9d38dba753ad150929335fa21e24d4 languageName: node linkType: hard "@types/node@npm:^17.0.21": - version: 17.0.29 - resolution: "@types/node@npm:17.0.29" - checksum: bb9d7bce9d6d3882efd9d63b773b548dce98df4bd57eff8ceaa316aa2f3346e36d3618764cc93da84bbff92005174a35eec3465cde91ee973ef1c351ffa40074 + version: 17.0.45 + resolution: "@types/node@npm:17.0.45" + checksum: aa04366b9103b7d6cfd6b2ef64182e0eaa7d4462c3f817618486ea0422984c51fc69fd0d436eae6c9e696ddfdbec9ccaa27a917f7c2e8c75c5d57827fe3d95e8 languageName: node linkType: hard @@ -11179,16 +11152,16 @@ __metadata: linkType: hard "browserslist@npm:^4.12.0, browserslist@npm:^4.14.5, browserslist@npm:^4.21.3, browserslist@npm:^4.21.4": - version: 4.21.4 - resolution: "browserslist@npm:4.21.4" + version: 4.21.5 + resolution: "browserslist@npm:4.21.5" dependencies: - caniuse-lite: ^1.0.30001400 - electron-to-chromium: ^1.4.251 - node-releases: ^2.0.6 - update-browserslist-db: ^1.0.9 + caniuse-lite: ^1.0.30001449 + electron-to-chromium: ^1.4.284 + node-releases: ^2.0.8 + update-browserslist-db: ^1.0.10 bin: browserslist: cli.js - checksum: 4af3793704dbb4615bcd29059ab472344dc7961c8680aa6c4bb84f05340e14038d06a5aead58724eae69455b8fade8b8c69f1638016e87e5578969d74c078b79 + checksum: 9755986b22e73a6a1497fd8797aedd88e04270be33ce66ed5d85a1c8a798292a65e222b0f251bafa1c2522261e237d73b08b58689d4920a607e5a53d56dc4706 languageName: node linkType: hard @@ -11520,21 +11493,6 @@ __metadata: languageName: node linkType: hard -"cacheable-request@npm:^6.0.0": - version: 6.1.0 - resolution: "cacheable-request@npm:6.1.0" - dependencies: - clone-response: ^1.0.2 - get-stream: ^5.1.0 - http-cache-semantics: ^4.0.0 - keyv: ^3.0.0 - lowercase-keys: ^2.0.0 - normalize-url: ^4.1.0 - responselike: ^1.0.2 - checksum: b510b237b18d17e89942e9ee2d2a077cb38db03f12167fd100932dfa8fc963424bfae0bfa1598df4ae16c944a5484e43e03df8f32105b04395ee9495e9e4e9f1 - languageName: node - linkType: hard - "cacheable-request@npm:^7.0.2": version: 7.0.2 resolution: "cacheable-request@npm:7.0.2" @@ -11668,10 +11626,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001400, caniuse-lite@npm:^1.0.30001426": - version: 1.0.30001431 - resolution: "caniuse-lite@npm:1.0.30001431" - checksum: bc8ab55cd194e240152946b54bfaff7456180cc018674fc7ed134f4f502192405f6643f422feaa0a5e7cc02b5bac564cfac7771ac6d29f5d129482fcfe335ba1 +"caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001426, caniuse-lite@npm:^1.0.30001449": + version: 1.0.30001481 + resolution: "caniuse-lite@npm:1.0.30001481" + checksum: 8200a043c191b4fd4fe0beda37a58fd61869c895ab93f87bdd0420e5927453f48434d716ce9da8552ff6c3ecc4dcd1366354cda3a134f3cc844af741574a7cab languageName: node linkType: hard @@ -12626,7 +12584,7 @@ __metadata: languageName: node linkType: hard -"concat-stream@npm:^1.5.0, concat-stream@npm:^1.6.0, concat-stream@npm:^1.6.1, concat-stream@npm:^1.6.2, concat-stream@npm:~1.6.0": +"concat-stream@npm:^1.5.0, concat-stream@npm:^1.6.0, concat-stream@npm:^1.6.1, concat-stream@npm:~1.6.0": version: 1.6.2 resolution: "concat-stream@npm:1.6.2" dependencies: @@ -12668,16 +12626,6 @@ __metadata: languageName: node linkType: hard -"config-chain@npm:^1.1.11": - version: 1.1.12 - resolution: "config-chain@npm:1.1.12" - dependencies: - ini: ^1.3.4 - proto-list: ~1.2.1 - checksum: a16332f87212b4015afcdfc95fe42b40b162e7f10b4f4370ab3239979b6e69a41b4e6fb34d7891aa028a557f2340da236f810df433b18dfa5c408b2eb8489bf7 - languageName: node - linkType: hard - "configstore@npm:^3.0.0": version: 3.1.2 resolution: "configstore@npm:3.1.2" @@ -13623,15 +13571,6 @@ __metadata: languageName: node linkType: hard -"decompress-response@npm:^3.3.0": - version: 3.3.0 - resolution: "decompress-response@npm:3.3.0" - dependencies: - mimic-response: ^1.0.0 - checksum: 952552ac3bd7de2fc18015086b09468645c9638d98a551305e485230ada278c039c91116e946d07894b39ee53c0f0d5b6473f25a224029344354513b412d7380 - languageName: node - linkType: hard - "decompress-response@npm:^6.0.0": version: 6.0.0 resolution: "decompress-response@npm:6.0.0" @@ -13742,13 +13681,6 @@ __metadata: languageName: node linkType: hard -"defer-to-connect@npm:^1.0.1": - version: 1.1.3 - resolution: "defer-to-connect@npm:1.1.3" - checksum: 9491b301dcfa04956f989481ba7a43c2231044206269eb4ab64a52d6639ee15b1252262a789eb4239fb46ab63e44d4e408641bae8e0793d640aee55398cb3930 - languageName: node - linkType: hard - "defer-to-connect@npm:^2.0.0": version: 2.0.1 resolution: "defer-to-connect@npm:2.0.1" @@ -14606,23 +14538,23 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.251": - version: 1.4.284 - resolution: "electron-to-chromium@npm:1.4.284" - checksum: be496e9dca6509dbdbb54dc32146fc99f8eb716d28a7ee8ccd3eba0066561df36fc51418d8bd7cf5a5891810bf56c0def3418e74248f51ea4a843d423603d10a +"electron-to-chromium@npm:^1.4.284": + version: 1.4.376 + resolution: "electron-to-chromium@npm:1.4.376" + checksum: 881351d25e0e983432c10844540bb664ee4c54f781b81b7247c36d6e617dc85305fd87ffb5de6d9630c6a54f4432afd8e97565a11c62bb77b63051e43cb8a942 languageName: node linkType: hard -"electron@npm:^11.1.0": - version: 11.5.0 - resolution: "electron@npm:11.5.0" +"electron@npm:^23.1.2": + version: 23.3.0 + resolution: "electron@npm:23.3.0" dependencies: - "@electron/get": ^1.0.1 - "@types/node": ^12.0.12 - extract-zip: ^1.0.3 + "@electron/get": ^2.0.0 + "@types/node": ^16.11.26 + extract-zip: ^2.0.1 bin: electron: cli.js - checksum: 9c7cc76bf2d10d3299ed60ca1461573e62f30a0e38520e6447f8544d369a1aa743c4b0c59fed9666b3c9c5ba4638d9d797edea1ea4379adbf21b79eb3949b7a0 + checksum: 3d2959d736f3d448f768d12d5d225b9569837695aa07706a6d5b8d6705f5fabaa643ed4b3319a35cec00234bdf7a15a86cabbe04439baff8c9ad7b9e2425c45d languageName: node linkType: hard @@ -14778,9 +14710,9 @@ __metadata: linkType: hard "env-paths@npm:^2.2.0": - version: 2.2.0 - resolution: "env-paths@npm:2.2.0" - checksum: ba2aea38301aafd69086be1f8cb453b92946e4840cb0de9d1c88a67e6f43a6174dcddb60b218ec36db8720b12de46b0d93c2f97ad9bbec6a267b479ab37debb6 + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e languageName: node linkType: hard @@ -16646,20 +16578,6 @@ __metadata: languageName: node linkType: hard -"extract-zip@npm:^1.0.3": - version: 1.7.0 - resolution: "extract-zip@npm:1.7.0" - dependencies: - concat-stream: ^1.6.2 - debug: ^2.6.9 - mkdirp: ^0.5.4 - yauzl: ^2.10.0 - bin: - extract-zip: cli.js - checksum: 011bab660d738614555773d381a6ba4815d98c1cfcdcdf027e154ebcc9fc8c9ef637b3ea5c9b2144013100071ee41722ed041fc9aacc60f6198ef747cac0c073 - languageName: node - linkType: hard - "extract-zip@npm:^2.0.1": version: 2.0.1 resolution: "extract-zip@npm:2.0.1" @@ -16984,7 +16902,7 @@ __metadata: languageName: node linkType: hard -"filenamify@npm:^4.1.0, filenamify@npm:^4.3.0": +"filenamify@npm:^4.3.0": version: 4.3.0 resolution: "filenamify@npm:4.3.0" dependencies: @@ -17912,7 +17830,7 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^4.0.0, get-stream@npm:^4.1.0": +"get-stream@npm:^4.0.0": version: 4.1.0 resolution: "get-stream@npm:4.1.0" dependencies: @@ -18150,18 +18068,17 @@ __metadata: languageName: node linkType: hard -"global-agent@npm:^2.0.2": - version: 2.1.12 - resolution: "global-agent@npm:2.1.12" +"global-agent@npm:^3.0.0": + version: 3.0.0 + resolution: "global-agent@npm:3.0.0" dependencies: boolean: ^3.0.1 - core-js: ^3.6.5 es6-error: ^4.1.1 matcher: ^3.0.0 roarr: ^2.15.3 semver: ^7.3.2 serialize-error: ^7.0.1 - checksum: 220c30f0ee19bf0a32a286d94b5d23c11b4f1c0a029b68a6ba22c25e0e9409dbe5e9e19e724cb4dd68e7be64f5fc5fd04cb0a897361f8e2fdda571438ecc37ad + checksum: 75074d80733b4bd5386c47f5df028e798018025beac0ab310e9908c72bf5639e408203e7bca0130d5ee01b5f4abc6d34385d96a9f950ea5fe1979bb431c808f7 languageName: node linkType: hard @@ -18240,18 +18157,6 @@ __metadata: languageName: node linkType: hard -"global-tunnel-ng@npm:^2.7.1": - version: 2.7.1 - resolution: "global-tunnel-ng@npm:2.7.1" - dependencies: - encodeurl: ^1.0.2 - lodash: ^4.17.10 - npm-conf: ^1.1.3 - tunnel: ^0.0.6 - checksum: b7e016093eab6058b5fdd8caea31c22dc1a607f0f0b41c001ade5e0227c5d74efe9ce9bae56316d794bc1cedd461a187b8b7e8f0a3eb4d194972cdfb9d860af2 - languageName: node - linkType: hard - "global@npm:^4.4.0": version: 4.4.0 resolution: "global@npm:4.4.0" @@ -18386,6 +18291,25 @@ __metadata: languageName: node linkType: hard +"got@npm:^11.8.5": + version: 11.8.6 + resolution: "got@npm:11.8.6" + dependencies: + "@sindresorhus/is": ^4.0.0 + "@szmarczak/http-timer": ^4.0.5 + "@types/cacheable-request": ^6.0.1 + "@types/responselike": ^1.0.0 + cacheable-lookup: ^5.0.3 + cacheable-request: ^7.0.2 + decompress-response: ^6.0.0 + http2-wrapper: ^1.0.0-beta.5.2 + lowercase-keys: ^2.0.0 + p-cancelable: ^2.0.0 + responselike: ^2.0.0 + checksum: bbc783578a8d5030c8164ef7f57ce41b5ad7db2ed13371e1944bef157eeca5a7475530e07c0aaa71610d7085474d0d96222c9f4268d41db333a17e39b463f45d + languageName: node + linkType: hard + "got@npm:^6.7.1": version: 6.7.1 resolution: "got@npm:6.7.1" @@ -18405,25 +18329,6 @@ __metadata: languageName: node linkType: hard -"got@npm:^9.6.0": - version: 9.6.0 - resolution: "got@npm:9.6.0" - dependencies: - "@sindresorhus/is": ^0.14.0 - "@szmarczak/http-timer": ^1.1.2 - cacheable-request: ^6.0.0 - decompress-response: ^3.3.0 - duplexer3: ^0.1.4 - get-stream: ^4.1.0 - lowercase-keys: ^1.0.1 - mimic-response: ^1.0.1 - p-cancelable: ^1.0.0 - to-readable-stream: ^1.0.0 - url-parse-lax: ^3.0.0 - checksum: 941807bd9704bacf5eb401f0cc1212ffa1f67c6642f2d028fd75900471c221b1da2b8527f4553d2558f3faeda62ea1cf31665f8b002c6137f5de8732f07370b0 - languageName: node - linkType: hard - "graceful-fs@npm:^4.0.0, graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.1.9, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.3, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.10 resolution: "graceful-fs@npm:4.2.10" @@ -22258,13 +22163,6 @@ __metadata: languageName: node linkType: hard -"json-buffer@npm:3.0.0": - version: 3.0.0 - resolution: "json-buffer@npm:3.0.0" - checksum: 0cecacb8025370686a916069a2ff81f7d55167421b6aa7270ee74e244012650dd6bce22b0852202ea7ff8624fce50ff0ec1bdf95914ccb4553426e290d5a63fa - languageName: node - linkType: hard - "json-buffer@npm:3.0.1": version: 3.0.1 resolution: "json-buffer@npm:3.0.1" @@ -22691,15 +22589,6 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^3.0.0": - version: 3.1.0 - resolution: "keyv@npm:3.1.0" - dependencies: - json-buffer: 3.0.0 - checksum: bb7e8f3acffdbafbc2dd5b63f377fe6ec4c0e2c44fc82720449ef8ab54f4a7ce3802671ed94c0f475ae0a8549703353a2124561fcf3317010c141b32ca1ce903 - languageName: node - linkType: hard - "kind-of@npm:^2.0.1": version: 2.0.1 resolution: "kind-of@npm:2.0.1" @@ -23424,7 +23313,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.13.1, lodash@npm:^4.16.4, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4": +"lodash@npm:^4.13.1, lodash@npm:^4.16.4, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -23514,7 +23403,7 @@ __metadata: languageName: node linkType: hard -"lowercase-keys@npm:^1.0.0, lowercase-keys@npm:^1.0.1": +"lowercase-keys@npm:^1.0.0": version: 1.0.1 resolution: "lowercase-keys@npm:1.0.1" checksum: 4d045026595936e09953e3867722e309415ff2c80d7701d067546d75ef698dac218a4f53c6d1d0e7368b47e45fd7529df47e6cb56fbb90523ba599f898b3d147 @@ -24650,7 +24539,7 @@ __metadata: languageName: node linkType: hard -"mimic-response@npm:^1.0.0, mimic-response@npm:^1.0.1": +"mimic-response@npm:^1.0.0": version: 1.0.1 resolution: "mimic-response@npm:1.0.1" checksum: 034c78753b0e622bc03c983663b1cdf66d03861050e0c8606563d149bc2b02d63f62ce4d32be4ab50d0553ae0ffe647fc34d1f5281184c6e1e8cf4d85e8d9823 @@ -24910,7 +24799,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.3, mkdirp@npm:^0.5.4, mkdirp@npm:^0.5.5, mkdirp@npm:^0.5.6": +"mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.3, mkdirp@npm:^0.5.5, mkdirp@npm:^0.5.6": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" dependencies: @@ -25647,10 +25536,10 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.6": - version: 2.0.6 - resolution: "node-releases@npm:2.0.6" - checksum: e86a926dc9fbb3b41b4c4a89d998afdf140e20a4e8dbe6c0a807f7b2948b42ea97d7fd3ad4868041487b6e9ee98409829c6e4d84a734a4215dff060a7fbeb4bf +"node-releases@npm:^2.0.8": + version: 2.0.10 + resolution: "node-releases@npm:2.0.10" + checksum: d784ecde25696a15d449c4433077f5cce620ed30a1656c4abf31282bfc691a70d9618bae6868d247a67914d1be5cc4fde22f65a05f4398cdfb92e0fc83cadfbc languageName: node linkType: hard @@ -25757,13 +25646,6 @@ __metadata: languageName: node linkType: hard -"normalize-url@npm:^4.1.0": - version: 4.5.1 - resolution: "normalize-url@npm:4.5.1" - checksum: 9a9dee01df02ad23e171171893e56e22d752f7cff86fb96aafeae074819b572ea655b60f8302e2d85dbb834dc885c972cc1c573892fea24df46b2765065dd05a - languageName: node - linkType: hard - "normalize-url@npm:^6.0.1": version: 6.1.0 resolution: "normalize-url@npm:6.1.0" @@ -25787,16 +25669,6 @@ __metadata: languageName: node linkType: hard -"npm-conf@npm:^1.1.3": - version: 1.1.3 - resolution: "npm-conf@npm:1.1.3" - dependencies: - config-chain: ^1.1.11 - pify: ^3.0.0 - checksum: 2d4e933b657623d98183ec408d17318547296b1cd17c4d3587e2920c554675f24f829d8f5f7f84db3a020516678fdcd01952ebaaf0e7fa8a17f6c39be4154bef - languageName: node - linkType: hard - "npm-normalize-package-bin@npm:^1.0.0, npm-normalize-package-bin@npm:^1.0.1": version: 1.0.1 resolution: "npm-normalize-package-bin@npm:1.0.1" @@ -26382,13 +26254,6 @@ __metadata: languageName: node linkType: hard -"p-cancelable@npm:^1.0.0": - version: 1.1.0 - resolution: "p-cancelable@npm:1.1.0" - checksum: 2db3814fef6d9025787f30afaee4496a8857a28be3c5706432cbad76c688a6db1874308f48e364a42f5317f5e41e8e7b4f2ff5c8ff2256dbb6264bc361704ece - languageName: node - linkType: hard - "p-cancelable@npm:^2.0.0": version: 2.1.1 resolution: "p-cancelable@npm:2.1.1" @@ -27744,13 +27609,6 @@ __metadata: languageName: node linkType: hard -"prepend-http@npm:^2.0.0": - version: 2.0.0 - resolution: "prepend-http@npm:2.0.0" - checksum: 7694a9525405447662c1ffd352fcb41b6410c705b739b6f4e3a3e21cf5fdede8377890088e8934436b8b17ba55365a615f153960f30877bf0d0392f9e93503ea - languageName: node - linkType: hard - "preserve@npm:^0.2.0": version: 0.2.0 resolution: "preserve@npm:0.2.0" @@ -28027,13 +27885,6 @@ __metadata: languageName: node linkType: hard -"proto-list@npm:~1.2.1": - version: 1.2.4 - resolution: "proto-list@npm:1.2.4" - checksum: 4d4826e1713cbfa0f15124ab0ae494c91b597a3c458670c9714c36e8baddf5a6aad22842776f2f5b137f259c8533e741771445eb8df82e861eea37a6eaba03f7 - languageName: node - linkType: hard - "protobufjs@npm:^6.11.3": version: 6.11.3 resolution: "protobufjs@npm:6.11.3" @@ -28501,29 +28352,29 @@ __metadata: languageName: node linkType: hard -"react-devtools-core@npm:4.16.0": - version: 4.16.0 - resolution: "react-devtools-core@npm:4.16.0" +"react-devtools-core@npm:4.27.6": + version: 4.27.6 + resolution: "react-devtools-core@npm:4.27.6" dependencies: shell-quote: ^1.6.1 ws: ^7 - checksum: 93b9d49b3b9ffc0148dcf24ecf6bbf805eb8f28f0e8c35dc50e93c6566f6130cb74cd472ac770debb48ea863e5182af5d307c6b50554077b245b405010bd34b0 + checksum: c0ec5d798c1bbf8c8861677a5940ad552efbe7aa99f2a4aa04e2841605266bc93b2b5956890b5d6c5136f88c6a0c8d080b929dde89227ac56d4a7fb0e85fe55f languageName: node linkType: hard "react-devtools@npm:^4.11.0": - version: 4.16.0 - resolution: "react-devtools@npm:4.16.0" + version: 4.27.6 + resolution: "react-devtools@npm:4.27.6" dependencies: cross-spawn: ^5.0.1 - electron: ^11.1.0 + electron: ^23.1.2 ip: ^1.1.4 minimist: ^1.2.3 - react-devtools-core: 4.16.0 + react-devtools-core: 4.27.6 update-notifier: ^2.1.0 bin: react-devtools: bin.js - checksum: 65ba2e3a93bfa58b4c2c624de383adf87a91b7a1ebb5c74500ebf0edf30c7d752a78f36909a88ad5abedcd10411fb6dba414fdaea9173dddef56ccc230928449 + checksum: 95db5d2e2907c5b349a3fab70915c95ffc3196c4679b43b77ed78263d56919d5c6ec7ec05e3a2d31f975e5e1f51c7a0903b268207787b095b0cbb318e5070d67 languageName: node linkType: hard @@ -29993,15 +29844,6 @@ __metadata: languageName: node linkType: hard -"responselike@npm:^1.0.2": - version: 1.0.2 - resolution: "responselike@npm:1.0.2" - dependencies: - lowercase-keys: ^1.0.0 - checksum: 2e9e70f1dcca3da621a80ce71f2f9a9cad12c047145c6ece20df22f0743f051cf7c73505e109814915f23f9e34fb0d358e22827723ee3d56b623533cab8eafcd - languageName: node - linkType: hard - "responselike@npm:^2.0.0": version: 2.0.1 resolution: "responselike@npm:2.0.1" @@ -30672,7 +30514,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.3.8, semver@npm:^7.0.0, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8": +"semver@npm:7.3.8": version: 7.3.8 resolution: "semver@npm:7.3.8" dependencies: @@ -30692,6 +30534,17 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.0.0, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8": + version: 7.5.0 + resolution: "semver@npm:7.5.0" + dependencies: + lru-cache: ^6.0.0 + bin: + semver: bin/semver.js + checksum: 2d266937756689a76f124ffb4c1ea3e1bbb2b263219f90ada8a11aebebe1280b13bb76cca2ca96bdee3dbc554cbc0b24752eb895b2a51577aa644427e9229f2b + languageName: node + linkType: hard + "semver@npm:~5.4.1": version: 5.4.1 resolution: "semver@npm:5.4.1" @@ -32960,13 +32813,6 @@ __metadata: languageName: node linkType: hard -"to-readable-stream@npm:^1.0.0": - version: 1.0.0 - resolution: "to-readable-stream@npm:1.0.0" - checksum: 2bd7778490b6214a2c40276065dd88949f4cf7037ce3964c76838b8cb212893aeb9cceaaf4352a4c486e3336214c350270f3263e1ce7a0c38863a715a4d9aeb5 - languageName: node - linkType: hard - "to-regex-range@npm:^2.1.0": version: 2.1.1 resolution: "to-regex-range@npm:2.1.1" @@ -33877,17 +33723,17 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.9": - version: 1.0.10 - resolution: "update-browserslist-db@npm:1.0.10" +"update-browserslist-db@npm:^1.0.10": + version: 1.0.11 + resolution: "update-browserslist-db@npm:1.0.11" dependencies: escalade: ^3.1.1 picocolors: ^1.0.0 peerDependencies: browserslist: ">= 4.21.0" bin: - browserslist-lint: cli.js - checksum: 12db73b4f63029ac407b153732e7cd69a1ea8206c9100b482b7d12859cd3cd0bc59c602d7ae31e652706189f1acb90d42c53ab24a5ba563ed13aebdddc5561a0 + update-browserslist-db: cli.js + checksum: b98327518f9a345c7cad5437afae4d2ae7d865f9779554baf2a200fdf4bac4969076b679b1115434bd6557376bdd37ca7583d0f9b8f8e302d7d4cc1e91b5f231 languageName: node linkType: hard @@ -33967,15 +33813,6 @@ __metadata: languageName: node linkType: hard -"url-parse-lax@npm:^3.0.0": - version: 3.0.0 - resolution: "url-parse-lax@npm:3.0.0" - dependencies: - prepend-http: ^2.0.0 - checksum: 1040e357750451173132228036aff1fd04abbd43eac1fb3e4fca7495a078bcb8d33cb765fe71ad7e473d9c94d98fd67adca63bd2716c815a2da066198dd37217 - languageName: node - linkType: hard - "url@npm:^0.11.0, url@npm:~0.11.0": version: 0.11.0 resolution: "url@npm:0.11.0" From c4e7b5532dc05bc722c057900a9d5533552238a6 Mon Sep 17 00:00:00 2001 From: Dhruv <79097544+dhruvv173@users.noreply.github.com> Date: Mon, 8 May 2023 22:58:46 +0530 Subject: [PATCH 015/120] Changes to custody-labels.js (#19038) --- .../institutional/custody-labels/custody-labels.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/components/institutional/custody-labels/custody-labels.js b/ui/components/institutional/custody-labels/custody-labels.js index 4cbd4acd0..3f9d8700e 100644 --- a/ui/components/institutional/custody-labels/custody-labels.js +++ b/ui/components/institutional/custody-labels/custody-labels.js @@ -2,10 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Text, Label } from '../../component-library'; import { - TEXT_TRANSFORM, + TextTransform, BackgroundColor, TextColor, - FONT_WEIGHT, + FontWeight, BorderRadius, TypographyVariant, } from '../../../helpers/constants/design-system'; @@ -25,7 +25,7 @@ const CustodyLabels = (props) => { {filteredLabels.map((item) => ( { paddingRight={2} backgroundColor={BackgroundColor.backgroundAlternative} color={TextColor.textMuted} - fontWeight={FONT_WEIGHT.NORMAL} + fontWeight={FontWeight.Normal} borderRadius={BorderRadius.SM} variant={TypographyVariant.H9} > From b9813773044353fe31ffdf95f0fe4ecd9de2aed2 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 8 May 2023 12:32:39 -0500 Subject: [PATCH 016/120] UX: Multichain: Disable network and account picker when necessary (#18909) --- .../account-picker/account-picker.js | 7 ++- .../multichain/app-header/app-header.js | 52 ++++++++++++++----- .../app-header/app-header.stories.js | 7 ++- .../multichain/app-header/app-header.test.js | 9 +++- ui/pages/routes/routes.component.js | 3 +- 5 files changed, 60 insertions(+), 18 deletions(-) diff --git a/ui/components/multichain/account-picker/account-picker.js b/ui/components/multichain/account-picker/account-picker.js index c0a6ba190..56c704d2e 100644 --- a/ui/components/multichain/account-picker/account-picker.js +++ b/ui/components/multichain/account-picker/account-picker.js @@ -19,7 +19,7 @@ import { Size, } from '../../../helpers/constants/design-system'; -export const AccountPicker = ({ address, name, onClick }) => { +export const AccountPicker = ({ address, name, onClick, disabled }) => { const useBlockie = useSelector((state) => state.metamask.useBlockie); return ( @@ -34,6 +34,7 @@ export const AccountPicker = ({ address, name, onClick }) => { gap: 2, alignItems: AlignItems.center, }} + disabled={disabled} > { +export const AppHeader = ({ location }) => { const trackEvent = useContext(MetaMetricsContext); const [accountOptionsMenuOpen, setAccountOptionsMenuOpen] = useState(false); const [multichainProductTourStep, setMultichainProductTourStep] = useState(1); @@ -87,6 +91,33 @@ export const AppHeader = ({ onClick }) => { .querySelector('[dir]') ?.getAttribute('dir'); + // Disable the network and account pickers if the user is in + // a critical flow + const sendStage = useSelector(getSendStage); + const isConfirmationPage = Boolean( + matchPath(location.pathname, { + path: CONFIRM_TRANSACTION_ROUTE, + exact: false, + }), + ); + const isTransactionEditPage = [ + SEND_STAGES.EDIT, + SEND_STAGES.DRAFT, + SEND_STAGES.ADD_RECIPIENT, + ].includes(sendStage); + const isSwapsPage = Boolean( + matchPath(location.pathname, { path: SWAPS_ROUTE, exact: false }), + ); + const isSwapsBuildQuotePage = Boolean( + matchPath(location.pathname, { path: BUILD_QUOTE_ROUTE, exact: false }), + ); + + const disablePickers = + isConfirmationPage || + isTransactionEditPage || + (isSwapsPage && !isSwapsBuildQuotePage); + const disableNetworkPicker = isSwapsPage || disablePickers; + // Callback for network dropdown const networkOpenCallback = useCallback(() => { dispatch(toggleNetworkMenu()); @@ -113,12 +144,7 @@ export const AppHeader = ({ onClick }) => { > { - if (onClick) { - await onClick(); - } - history.push(DEFAULT_ROUTE); - }} + onClick={async () => history.push(DEFAULT_ROUTE)} /> ) : null} @@ -160,6 +186,7 @@ export const AppHeader = ({ onClick }) => { size={Size.SM} onClick={networkOpenCallback} display={[DISPLAY.FLEX, DISPLAY.NONE]} // show on popover hide on desktop + disabled={disableNetworkPicker} /> {popupStatus ? null : (
@@ -170,6 +197,7 @@ export const AppHeader = ({ onClick }) => { onClick={networkOpenCallback} display={[DISPLAY.NONE, DISPLAY.FLEX]} // show on desktop hide on popover className="multichain-app-header__contents__network-picker" + disabled={disableNetworkPicker} />
)} @@ -205,6 +233,7 @@ export const AppHeader = ({ onClick }) => { }, }); }} + disabled={disablePickers} /> { { - if (onClick) { - await onClick(); - } history.push(DEFAULT_ROUTE); }} /> @@ -350,7 +376,7 @@ export const AppHeader = ({ onClick }) => { AppHeader.propTypes = { /** - * The onClick handler to be passed to the MetaMask Logo in the App Header + * The location object for the application */ - onClick: PropTypes.func, + location: PropTypes.object, }; diff --git a/ui/components/multichain/app-header/app-header.stories.js b/ui/components/multichain/app-header/app-header.stories.js index c8ae6a810..ea2da2019 100644 --- a/ui/components/multichain/app-header/app-header.stories.js +++ b/ui/components/multichain/app-header/app-header.stories.js @@ -11,10 +11,13 @@ export default { decorators: [(story) => {story()}], component: AppHeader, argTypes: { - onClick: { - action: 'onClick', + location: { + control: 'object', }, }, + args: { + location: { pathname: '' }, + }, }; const customNetworkUnlockedData = { ...testData, diff --git a/ui/components/multichain/app-header/app-header.test.js b/ui/components/multichain/app-header/app-header.test.js index d2885587e..cca6bfe2d 100644 --- a/ui/components/multichain/app-header/app-header.test.js +++ b/ui/components/multichain/app-header/app-header.test.js @@ -2,6 +2,7 @@ import React from 'react'; import configureStore from 'redux-mock-store'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { SEND_STAGES } from '../../../ducks/send'; import { AppHeader } from '.'; describe('App Header', () => { @@ -100,11 +101,17 @@ describe('App Header', () => { appState: { onboardedInThisUISession: false, }, + send: { + stage: SEND_STAGES.INACTIVE, + }, }; const mockStore = configureStore(); const store = mockStore(mockState); - const { container } = renderWithProvider(, store); + const { container } = renderWithProvider( + , + store, + ); expect(container).toMatchSnapshot(); }); }); diff --git a/ui/pages/routes/routes.component.js b/ui/pages/routes/routes.component.js index 0b5620949..7ae47b961 100644 --- a/ui/pages/routes/routes.component.js +++ b/ui/pages/routes/routes.component.js @@ -498,6 +498,7 @@ export default class Routes extends Component { isNetworkMenuOpen, toggleNetworkMenu, accountDetailsAddress, + location, } = this.props; const loadMessage = loadingMessage || isNetworkLoading @@ -542,7 +543,7 @@ export default class Routes extends Component { {!this.hideAppHeader() && (process.env.MULTICHAIN ? ( - + ) : ( Date: Tue, 9 May 2023 03:05:47 -0500 Subject: [PATCH 017/120] UX: Multichain: Update deprecated variables (#19058) --- .../multichain/account-list-item/account-list-item.js | 6 +++--- .../multichain/account-picker/account-picker.js | 4 ++-- .../multichain-token-list-item.js | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ui/components/multichain/account-list-item/account-list-item.js b/ui/components/multichain/account-list-item/account-list-item.js index a10268017..731016718 100644 --- a/ui/components/multichain/account-list-item/account-list-item.js +++ b/ui/components/multichain/account-list-item/account-list-item.js @@ -22,7 +22,7 @@ import { } from '../../component-library'; import { Color, - TEXT_ALIGN, + TextAlign, AlignItems, DISPLAY, TextVariant, @@ -170,7 +170,7 @@ export const AccountListItem = ({ marginInlineEnd={2} /> ) : null} - + { size={Size.XS} borderColor={BackgroundColor.backgroundDefault} // we currently don't have white color for border hence using backgroundDefault as the border /> - + {name} @@ -130,10 +130,10 @@ export const MultichainTokenListItem = ({ {secondary} From 124678e70151342e8e7f3e636852ffcb46c0c46e Mon Sep 17 00:00:00 2001 From: David Walsh Date: Tue, 9 May 2023 03:06:54 -0500 Subject: [PATCH 018/120] Fix #19059 - Show network picker when locked (#19063) --- .../multichain/app-header/app-header.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/ui/components/multichain/app-header/app-header.js b/ui/components/multichain/app-header/app-header.js index cc6a66ada..c070de771 100644 --- a/ui/components/multichain/app-header/app-header.js +++ b/ui/components/multichain/app-header/app-header.js @@ -350,16 +350,14 @@ export const AppHeader = ({ location }) => { padding={2} gap={2} > - {popupStatus ? null : ( -
- dispatch(toggleNetworkMenu())} - className="multichain-app-header__contents__network-picker" - /> -
- )} +
+ dispatch(toggleNetworkMenu())} + className="multichain-app-header__contents__network-picker" + /> +
{ From 09b113e0df897830b093ebe5f5fb9fff7a25b21b Mon Sep 17 00:00:00 2001 From: David Walsh Date: Tue, 9 May 2023 07:38:36 -0500 Subject: [PATCH 019/120] Fix #19060 - Ensure there's multiple accounts before focusing search (#19062) --- ui/components/multichain/account-list-menu/account-list-menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/components/multichain/account-list-menu/account-list-menu.js b/ui/components/multichain/account-list-menu/account-list-menu.js index 9903b8a96..12721f482 100644 --- a/ui/components/multichain/account-list-menu/account-list-menu.js +++ b/ui/components/multichain/account-list-menu/account-list-menu.js @@ -66,7 +66,7 @@ export const AccountListMenu = ({ onClose }) => { // Focus on the search box when the popover is opened useEffect(() => { if (inputRef.current) { - inputRef.current.rootNode.querySelector('input[type=search]').focus(); + inputRef.current.rootNode.querySelector('input[type=search]')?.focus(); } }, [inputRef]); From 4cb3284136a5585019ced40aeb40bf13e66eb8b4 Mon Sep 17 00:00:00 2001 From: Dominik Rudzki Date: Tue, 9 May 2023 18:32:29 +0200 Subject: [PATCH 020/120] Fix popover scroll button WhatsNewPopup hiding (#19017) Co-authored-by: David Walsh --- .../app/whats-new-popup/whats-new-popup.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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 12f81a60c..707a2d286 100644 --- a/ui/components/app/whats-new-popup/whats-new-popup.js +++ b/ui/components/app/whats-new-popup/whats-new-popup.js @@ -3,6 +3,7 @@ import { useHistory } from 'react-router-dom'; import { useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import classnames from 'classnames'; +import { debounce } from 'lodash'; import { getCurrentLocale } from '../../../ducks/locale/locale'; import { I18nContext } from '../../../contexts/i18n'; import { useEqualityCheck } from '../../../hooks/useEqualityCheck'; @@ -238,6 +239,16 @@ export default function WhatsNewPopup({ onClose }) { const trackEvent = useContext(MetaMetricsContext); + const handleDebouncedScroll = debounce((target) => { + setShouldShowScrollButton( + target.scrollHeight - target.scrollTop !== target.clientHeight, + ); + }, 100); + + const handleScroll = (e) => { + handleDebouncedScroll(e.target); + }; + const handleScrollDownClick = (e) => { e.stopPropagation(); idRefMap[notifications[notifications.length - 1].id].current.scrollIntoView( @@ -245,7 +256,6 @@ export default function WhatsNewPopup({ onClose }) { behavior: 'smooth', }, ); - setShouldShowScrollButton(false); }; useEffect(() => { const observer = new window.IntersectionObserver( @@ -300,6 +310,7 @@ export default function WhatsNewPopup({ onClose }) { popoverRef={popoverRef} showScrollDown={shouldShowScrollButton && notifications.length > 1} onScrollDownButtonClick={handleScrollDownClick} + onScroll={handleScroll} >
{notifications.map(({ id }, index) => { From cde449925b878e6231446d6c014bdc8f79810577 Mon Sep 17 00:00:00 2001 From: Nidhi Kumari Date: Tue, 9 May 2023 22:02:56 +0530 Subject: [PATCH 021/120] UX Multichain: updated margin top for assets tab (#19071) * updated margin top for assets tab * remove changes from yml file * remove changes from yml file --- ui/pages/home/home.component.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index 6bcb8532e..01499fa6c 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -815,13 +815,21 @@ export default class Home extends PureComponent { name={this.context.t('assets')} tabKey="assets" > - + {process.env.MULTICHAIN ? ( + + + history.push(`${ASSET_ROUTE}/${asset}`) + } + /> + + ) : ( history.push(`${ASSET_ROUTE}/${asset}`) } /> - + )} { ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) From 6535e349431970697d9580125ff890c1dce7a8d1 Mon Sep 17 00:00:00 2001 From: Nidhi Kumari Date: Tue, 9 May 2023 23:04:58 +0530 Subject: [PATCH 022/120] Replaced all fa-icon-circle with INFO icon (#17539) * replace all fa-icon-circle with INFO icon * updated classnames * updated classnames * updated snapshots * updated colors * resolved errors * fixed relative import * fixed lint errors * added story for alerts tab * update snapshot * updated info-circle * updated enum for iconName * removed classnames * updated iconName in settings * fixed lint errors and snapshots --- .../advanced-gas-inputs.component.js | 8 +++++++- .../app/advanced-gas-inputs/index.scss | 5 ++--- .../unconnected-account-alert.js | 3 ++- .../confirm-legacy-gas-display.js | 5 +++-- ...onfirm-page-container-warning.component.js | 8 +++++++- .../home-notification.component.js | 4 +++- .../app/home-notification/index.scss | 4 ---- .../nfts-detection-notice.js | 12 +++++------ ui/components/app/tab-bar/tab-bar.stories.js | 2 +- .../accrediation.component.stories.js | 20 +++++++++++++++++++ .../accreditation/accreditation.component.js | 3 ++- .../transaction-detail-item.stories.js | 3 ++- .../transaction-detail.stories.js | 3 ++- ui/components/ui/account-list/account-list.js | 16 +++++++++++++-- ui/components/ui/account-list/index.scss | 7 ++----- .../ui/definition-list/definition-list.js | 9 ++++++++- .../ui/definition-list/definition-list.scss | 6 ------ .../deprecated-test-networks.js | 4 ++-- .../ui/deprecated-test-networks/index.scss | 4 ---- ui/components/ui/tooltip/tooltip.stories.js | 13 ++++-------- ui/helpers/constants/settings.js | 19 +++++++++--------- .../__snapshots__/send-gas-row.test.js.snap | 10 ++++++---- ui/pages/settings/alerts-tab/alerts-tab.js | 6 +++++- .../settings/alerts-tab/alerts-tab.stories.js | 14 +++++++++++++ ui/pages/settings/settings.component.js | 2 +- .../view-quote-price-difference.test.js.snap | 20 +++++++++++-------- .../view-quote/view-quote-price-difference.js | 3 ++- 27 files changed, 137 insertions(+), 76 deletions(-) create mode 100644 ui/components/app/transaction-decoding/components/ui/accreditation/accrediation.component.stories.js create mode 100644 ui/pages/settings/alerts-tab/alerts-tab.stories.js diff --git a/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.component.js b/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.component.js index cda7f4d73..1cfd8b7e5 100644 --- a/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.component.js +++ b/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.component.js @@ -3,6 +3,8 @@ import PropTypes from 'prop-types'; import classnames from 'classnames'; import { debounce } from 'lodash'; import Tooltip from '../../ui/tooltip'; +import { Icon, IconName } from '../../component-library'; +import { IconColor } from '../../../helpers/constants/design-system'; export default class AdvancedGasInputs extends Component { static contextTypes = { @@ -138,7 +140,11 @@ export default class AdvancedGasInputs extends Component {
{label} - +
diff --git a/ui/components/app/advanced-gas-inputs/index.scss b/ui/components/app/advanced-gas-inputs/index.scss index 1f1630485..cc472897f 100644 --- a/ui/components/app/advanced-gas-inputs/index.scss +++ b/ui/components/app/advanced-gas-inputs/index.scss @@ -22,12 +22,11 @@ @include H8; } - .fa-info-circle { - color: var(--color-icon-alternative); + .info-circle { cursor: pointer; } - .fa-info-circle:hover { + .info-circle:hover { color: var(--color-icon-muted); } } diff --git a/ui/components/app/alerts/unconnected-account-alert/unconnected-account-alert.js b/ui/components/app/alerts/unconnected-account-alert/unconnected-account-alert.js index cbcac50eb..1a64b0aa0 100644 --- a/ui/components/app/alerts/unconnected-account-alert/unconnected-account-alert.js +++ b/ui/components/app/alerts/unconnected-account-alert/unconnected-account-alert.js @@ -22,6 +22,7 @@ import Checkbox from '../../../ui/check-box'; import Tooltip from '../../../ui/tooltip'; import ConnectedAccountsList from '../../connected-accounts-list'; import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { Icon, IconName } from '../../../component-library'; const { ERROR, LOADING } = ALERT_STATE; @@ -68,7 +69,7 @@ const UnconnectedAccountAlert = () => { title={t('alertDisableTooltip')} wrapperClassName="unconnected-account-alert__checkbox-label-tooltip" > - +
diff --git a/ui/components/app/confirm-gas-display/confirm-legacy-gas-display/confirm-legacy-gas-display.js b/ui/components/app/confirm-gas-display/confirm-legacy-gas-display/confirm-legacy-gas-display.js index b5dcc0abe..c09ad91ac 100644 --- a/ui/components/app/confirm-gas-display/confirm-legacy-gas-display/confirm-legacy-gas-display.js +++ b/ui/components/app/confirm-gas-display/confirm-legacy-gas-display/confirm-legacy-gas-display.js @@ -26,6 +26,7 @@ import { import { useDraftTransactionGasValues } from '../../../../hooks/useDraftTransactionGasValues'; import { getNativeCurrency } from '../../../../ducks/metamask/metamask'; import MultilayerFeeMessage from '../../multilayer-fee-message/multi-layer-fee-message'; +import { Icon, IconName } from '../../../component-library'; const renderHeartBeatIfNotInTest = () => process.env.IN_TEST ? null : ; @@ -95,7 +96,7 @@ const ConfirmLegacyGasDisplay = () => { contentText={t('transactionDetailDappGasTooltip')} position="top" > - + ) : ( @@ -123,7 +124,7 @@ const ConfirmLegacyGasDisplay = () => { } position="top" > - + ) diff --git a/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js b/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js index 5c4f5d632..e8d4402e8 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js +++ b/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js @@ -1,10 +1,16 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { Icon, IconName } from '../../../../component-library'; +import { IconColor } from '../../../../../helpers/constants/design-system'; const ConfirmPageContainerWarning = (props) => { return (
- +
{props.warning}
diff --git a/ui/components/app/home-notification/home-notification.component.js b/ui/components/app/home-notification/home-notification.component.js index 1344c74ea..cb56dc0fa 100644 --- a/ui/components/app/home-notification/home-notification.component.js +++ b/ui/components/app/home-notification/home-notification.component.js @@ -4,6 +4,8 @@ import PropTypes from 'prop-types'; import Button from '../../ui/button'; import Checkbox from '../../ui/check-box'; import Tooltip from '../../ui/tooltip'; +import { Icon, IconName } from '../../component-library'; +import { IconColor } from '../../../helpers/constants/design-system'; const HomeNotification = ({ acceptText, @@ -39,7 +41,7 @@ const HomeNotification = ({ title={infoText} wrapperClassName="home-notification__tooltip-wrapper" > - + ) : null}
diff --git a/ui/components/app/home-notification/index.scss b/ui/components/app/home-notification/index.scss index 64672e85d..ad3b3ddfd 100644 --- a/ui/components/app/home-notification/index.scss +++ b/ui/components/app/home-notification/index.scss @@ -36,10 +36,6 @@ cursor: pointer; } - .fa-info-circle { - color: var(--color-icon-default); - } - &__checkbox-wrapper { display: flex; flex-direction: row; diff --git a/ui/components/app/nfts-detection-notice/nfts-detection-notice.js b/ui/components/app/nfts-detection-notice/nfts-detection-notice.js index ab7b6365a..84d90c5d7 100644 --- a/ui/components/app/nfts-detection-notice/nfts-detection-notice.js +++ b/ui/components/app/nfts-detection-notice/nfts-detection-notice.js @@ -9,10 +9,12 @@ import { FONT_WEIGHT, DISPLAY, TextColor, + IconColor, } from '../../../helpers/constants/design-system'; import { useI18nContext } from '../../../hooks/useI18nContext'; import Button from '../../ui/button'; import { EXPERIMENTAL_ROUTE } from '../../../helpers/constants/routes'; +import { Icon, IconName } from '../../component-library'; export default function NftsDetectionNotice() { const t = useI18nContext(); @@ -23,12 +25,10 @@ export default function NftsDetectionNotice() { - diff --git a/ui/components/app/tab-bar/tab-bar.stories.js b/ui/components/app/tab-bar/tab-bar.stories.js index 2861437a3..c4f18c48a 100644 --- a/ui/components/app/tab-bar/tab-bar.stories.js +++ b/ui/components/app/tab-bar/tab-bar.stories.js @@ -54,7 +54,7 @@ export default { key: 'experimental', }, { - icon: , + icon: , content: 'About', key: 'about', }, diff --git a/ui/components/app/transaction-decoding/components/ui/accreditation/accrediation.component.stories.js b/ui/components/app/transaction-decoding/components/ui/accreditation/accrediation.component.stories.js new file mode 100644 index 000000000..5eb2e730d --- /dev/null +++ b/ui/components/app/transaction-decoding/components/ui/accreditation/accrediation.component.stories.js @@ -0,0 +1,20 @@ +import React from 'react'; +import Accreditation from './accreditation.component'; + +export default { + title: 'Components/App/Accrediation', // title should follow the folder structure location of the component. Don't use spaces. + + argTypes: { + fetchVia: { + control: 'string', + }, + address: { control: 'string' }, + }, + args: { + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + }, +}; + +export const DefaultStory = (args) => ; + +DefaultStory.storyName = 'Default'; diff --git a/ui/components/app/transaction-decoding/components/ui/accreditation/accreditation.component.js b/ui/components/app/transaction-decoding/components/ui/accreditation/accreditation.component.js index e79f227b9..cf0f40073 100644 --- a/ui/components/app/transaction-decoding/components/ui/accreditation/accreditation.component.js +++ b/ui/components/app/transaction-decoding/components/ui/accreditation/accreditation.component.js @@ -12,6 +12,7 @@ import { TypographyVariant } from '../../../../../../helpers/constants/design-sy import Button from '../../../../../ui/button'; import Typography from '../../../../../ui/typography'; +import { Icon, IconName } from '../../../../../component-library'; const Accreditation = ({ fetchVia, address }) => { const t = useContext(I18nContext); @@ -55,7 +56,7 @@ const Accreditation = ({ fetchVia, address }) => { return (
- +
diff --git a/ui/components/app/transaction-detail-item/transaction-detail-item.stories.js b/ui/components/app/transaction-detail-item/transaction-detail-item.stories.js index cfd8a39d1..dcb8f1c07 100644 --- a/ui/components/app/transaction-detail-item/transaction-detail-item.stories.js +++ b/ui/components/app/transaction-detail-item/transaction-detail-item.stories.js @@ -3,6 +3,7 @@ import InfoTooltip from '../../ui/info-tooltip/info-tooltip'; import { TextColor } from '../../../helpers/constants/design-system'; +import { Icon, IconName } from '../../component-library'; import README from './README.mdx'; import TransactionDetailItem from '.'; @@ -45,7 +46,7 @@ DefaultStory.args = { <> Estimated gas fee - + ), diff --git a/ui/components/app/transaction-detail/transaction-detail.stories.js b/ui/components/app/transaction-detail/transaction-detail.stories.js index 0a44d22fb..4e34ff627 100644 --- a/ui/components/app/transaction-detail/transaction-detail.stories.js +++ b/ui/components/app/transaction-detail/transaction-detail.stories.js @@ -2,6 +2,7 @@ import React from 'react'; import InfoTooltip from '../../ui/info-tooltip/info-tooltip'; import TransactionDetailItem from '../transaction-detail-item/transaction-detail-item.component'; import GasTiming from '../gas-timing/gas-timing.component'; +import { Icon, IconName } from '../../component-library'; import README from './README.mdx'; import TransactionDetail from '.'; @@ -27,7 +28,7 @@ const rows = [ <> Estimated gas fee - + } diff --git a/ui/components/ui/account-list/account-list.js b/ui/components/ui/account-list/account-list.js index 2cfdf70d2..1bcd5f99b 100644 --- a/ui/components/ui/account-list/account-list.js +++ b/ui/components/ui/account-list/account-list.js @@ -8,6 +8,8 @@ import Identicon from '../identicon'; import UserPreferencedCurrencyDisplay from '../../app/user-preferenced-currency-display'; import { PRIMARY } from '../../../helpers/constants/common'; import Tooltip from '../tooltip'; +import { Icon, IconName } from '../../component-library'; +import { IconColor } from '../../../helpers/constants/design-system'; const AccountList = ({ selectNewAccountViaModal, @@ -61,7 +63,12 @@ const AccountList = ({
} > - +
) : null} @@ -114,7 +121,12 @@ const AccountList = ({ addressLastConnectedMap[address] }`} > - + ) : null}
diff --git a/ui/components/ui/account-list/index.scss b/ui/components/ui/account-list/index.scss index c00b08e0e..c5e97f183 100644 --- a/ui/components/ui/account-list/index.scss +++ b/ui/components/ui/account-list/index.scss @@ -113,14 +113,11 @@ } } - .fa-info-circle { - color: var(--color-icon-muted); + .info-circle { cursor: pointer; - margin-inline-start: 8px; - font-size: 0.9rem; } - .fa-info-circle:hover { + .info-circle:hover { color: var(--color-icon-default); } diff --git a/ui/components/ui/definition-list/definition-list.js b/ui/components/ui/definition-list/definition-list.js index bfe3b4b1a..60aa5cf5c 100644 --- a/ui/components/ui/definition-list/definition-list.js +++ b/ui/components/ui/definition-list/definition-list.js @@ -8,8 +8,10 @@ import { FONT_WEIGHT, OVERFLOW_WRAP, TextColor, + IconColor, } from '../../../helpers/constants/design-system'; import Tooltip from '../tooltip'; +import { Icon, IconName, IconSize } from '../../component-library'; const MARGIN_MAP = { [Size.XS]: 0, @@ -48,7 +50,12 @@ export default function DefinitionList({ position="top" containerClassName="definition-list__tooltip-wrapper" > - + )} diff --git a/ui/components/ui/definition-list/definition-list.scss b/ui/components/ui/definition-list/definition-list.scss index 1517d46b7..2a99ab126 100644 --- a/ui/components/ui/definition-list/definition-list.scss +++ b/ui/components/ui/definition-list/definition-list.scss @@ -5,12 +5,6 @@ display: flex; align-items: center; - & i { - color: var(--color-icon-default); - margin-left: 6px; - font-size: $font-size-h8; - } - & #{$self}__tooltip-wrapper { display: flex !important; align-items: center; diff --git a/ui/components/ui/deprecated-test-networks/deprecated-test-networks.js b/ui/components/ui/deprecated-test-networks/deprecated-test-networks.js index 310d19bc3..1c8aaa180 100644 --- a/ui/components/ui/deprecated-test-networks/deprecated-test-networks.js +++ b/ui/components/ui/deprecated-test-networks/deprecated-test-networks.js @@ -12,7 +12,7 @@ import Box from '../box/box'; import ActionableMessage from '../actionable-message/actionable-message'; import { getCurrentChainId } from '../../../selectors'; import { getCompletedOnboarding } from '../../../ducks/metamask/metamask'; -import { Text } from '../../component-library'; +import { Text, Icon, IconName, IconSize } from '../../component-library'; export default function DeprecatedTestNetworks() { const currentChainID = useSelector(getCurrentChainId); @@ -45,7 +45,7 @@ export default function DeprecatedTestNetworks() { className="deprecated-test-networks__content" > - + ( Hover over the info icon to see the tooltip - + ); @@ -74,10 +72,7 @@ export const HTML = (args) => ( This tooltips content is html - + ); diff --git a/ui/helpers/constants/settings.js b/ui/helpers/constants/settings.js index 2fbc8e713..f7297238f 100644 --- a/ui/helpers/constants/settings.js +++ b/ui/helpers/constants/settings.js @@ -1,3 +1,4 @@ +import { IconName } from '../../components/component-library'; import { ICON_NAMES } from '../../components/component-library/icon/deprecated'; import { ALERTS_ROUTE, @@ -259,28 +260,28 @@ export const SETTINGS_CONSTANTS = [ sectionMessage: (t) => t('metamaskVersion'), descriptionMessage: (t) => t('builtAroundTheWorld'), route: `${ABOUT_US_ROUTE}#version`, - icon: 'fa fa-info-circle', + iconName: IconName.Info, }, { tabMessage: (t) => t('about'), sectionMessage: (t) => t('links'), descriptionMessage: (t) => t('links'), route: `${ABOUT_US_ROUTE}#links`, - icon: 'fa fa-info-circle', + iconName: IconName.Info, }, { tabMessage: (t) => t('about'), sectionMessage: (t) => t('privacyMsg'), descriptionMessage: (t) => t('privacyMsg'), route: `${ABOUT_US_ROUTE}#privacy-policy`, - icon: 'fa fa-info-circle', + iconName: IconName.Info, }, { tabMessage: (t) => t('about'), sectionMessage: (t) => t('terms'), descriptionMessage: (t) => t('terms'), route: `${ABOUT_US_ROUTE}#terms`, - icon: 'fa fa-info-circle', + iconName: IconName.Info, }, { @@ -288,7 +289,7 @@ export const SETTINGS_CONSTANTS = [ sectionMessage: (t) => t('attributions'), descriptionMessage: (t) => t('attributions'), route: `${ABOUT_US_ROUTE}#attributions`, - icon: 'fa fa-info-circle', + iconName: IconName.Info, }, { @@ -296,7 +297,7 @@ export const SETTINGS_CONSTANTS = [ sectionMessage: (t) => t('supportCenter'), descriptionMessage: (t) => t('supportCenter'), route: `${ABOUT_US_ROUTE}#supportcenter`, - icon: 'fa fa-info-circle', + iconName: IconName.Info, }, { @@ -304,7 +305,7 @@ export const SETTINGS_CONSTANTS = [ sectionMessage: (t) => t('visitWebSite'), descriptionMessage: (t) => t('visitWebSite'), route: `${ABOUT_US_ROUTE}#visitwebsite`, - icon: 'fa fa-info-circle', + iconName: IconName.Info, }, { @@ -312,14 +313,14 @@ export const SETTINGS_CONSTANTS = [ sectionMessage: (t) => t('contactUs'), descriptionMessage: (t) => t('contactUs'), route: `${ABOUT_US_ROUTE}#contactus`, - icon: 'fa fa-info-circle', + iconName: IconName.Info, }, { tabMessage: (t) => t('about'), sectionMessage: (t) => t('betaTerms'), descriptionMessage: (t) => t('betaTerms'), route: `${ABOUT_US_ROUTE}#beta-terms`, - icon: 'fa fa-info-circle', + iconName: IconName.Info, }, { tabMessage: (t) => t('experimental'), diff --git a/ui/pages/send/send-content/send-gas-row/__snapshots__/send-gas-row.test.js.snap b/ui/pages/send/send-content/send-gas-row/__snapshots__/send-gas-row.test.js.snap index cee7edf62..f97cefbc4 100644 --- a/ui/pages/send/send-content/send-gas-row/__snapshots__/send-gas-row.test.js.snap +++ b/ui/pages/send/send-content/send-gas-row/__snapshots__/send-gas-row.test.js.snap @@ -30,8 +30,9 @@ exports[`SendGasRow Component render should match snapshot 1`] = ` style="display: inline;" tabindex="0" > -
@@ -82,8 +83,9 @@ exports[`SendGasRow Component render should match snapshot 1`] = ` style="display: inline;" tabindex="0" > -
diff --git a/ui/pages/settings/alerts-tab/alerts-tab.js b/ui/pages/settings/alerts-tab/alerts-tab.js index 83dd76e14..7523c68f6 100644 --- a/ui/pages/settings/alerts-tab/alerts-tab.js +++ b/ui/pages/settings/alerts-tab/alerts-tab.js @@ -9,6 +9,7 @@ import { setAlertEnabledness } from '../../../store/actions'; import { getAlertEnabledness } from '../../../ducks/metamask/metamask'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { handleSettingsRefs } from '../../../helpers/utils/settings-search'; +import { Icon, IconName } from '../../../components/component-library'; const AlertSettingsEntry = ({ alertId, description, title }) => { const t = useI18nContext(); @@ -30,7 +31,10 @@ const AlertSettingsEntry = ({ alertId, description, title }) => { title={description} wrapperClassName="alerts-tab__description" > - + { + return ; +}; + +DefaultAlertsTab.storyName = 'Default'; diff --git a/ui/pages/settings/settings.component.js b/ui/pages/settings/settings.component.js index deab2d573..788110616 100644 --- a/ui/pages/settings/settings.component.js +++ b/ui/pages/settings/settings.component.js @@ -303,7 +303,7 @@ class SettingsPage extends PureComponent { }, { content: t('about'), - icon: , + icon: , key: ABOUT_US_ROUTE, }, ]; diff --git a/ui/pages/swaps/view-quote/__snapshots__/view-quote-price-difference.test.js.snap b/ui/pages/swaps/view-quote/__snapshots__/view-quote-price-difference.test.js.snap index 41cf8a7fa..ce2ad6d17 100644 --- a/ui/pages/swaps/view-quote/__snapshots__/view-quote-price-difference.test.js.snap +++ b/ui/pages/swaps/view-quote/__snapshots__/view-quote-price-difference.test.js.snap @@ -35,8 +35,9 @@ exports[`View Price Quote Difference displays a fiat error when calculationError style="display: inline;" tabindex="0" > -
@@ -92,8 +93,9 @@ exports[`View Price Quote Difference displays an error when in high bucket 1`] = style="display: inline;" tabindex="0" > -
@@ -149,8 +151,9 @@ exports[`View Price Quote Difference displays an error when in medium bucket 1`] style="display: inline;" tabindex="0" > - @@ -206,8 +209,9 @@ exports[`View Price Quote Difference should match snapshot 1`] = ` style="display: inline;" tabindex="0" > - diff --git a/ui/pages/swaps/view-quote/view-quote-price-difference.js b/ui/pages/swaps/view-quote/view-quote-price-difference.js index 602db1393..260724349 100644 --- a/ui/pages/swaps/view-quote/view-quote-price-difference.js +++ b/ui/pages/swaps/view-quote/view-quote-price-difference.js @@ -12,6 +12,7 @@ import { DISPLAY, } from '../../../helpers/constants/design-system'; import { GasRecommendations } from '../../../../shared/constants/gas'; +import { Icon, IconName } from '../../../components/component-library'; export default function ViewQuotePriceDifference(props) { const { @@ -74,7 +75,7 @@ export default function ViewQuotePriceDifference(props) { {priceDifferenceTitle} - +
{priceDifferenceMessage} From 9847179f54c972e1060cf6557353895e90683f68 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Tue, 9 May 2023 15:44:14 -0230 Subject: [PATCH 023/120] Set network status to "unknown" when ID is invalid (#19068) We now set the network status to "unknown" rather than "unavailable" when the network ID is invalid. This better reflects what we know when this happens, and it makes the network controller better aligned with the core network controller. This was accomplished by using a regular error for the network ID assertion rather than using `assert` directly. `assert` would throw an error with a `code` property, which resutled in us treating it like an RPC error. This isn't tested, but it was found in the course of porting unit tests from core to extension. It will be covered by these tests, which will be added in the next PR. This change should have no functional impact because we treat these two network statuses as equivalent. The distinction between unknown and unavailable is useful only for debugging. --- app/scripts/controllers/network/network-controller.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/scripts/controllers/network/network-controller.ts b/app/scripts/controllers/network/network-controller.ts index 463565a54..b6fd4a503 100644 --- a/app/scripts/controllers/network/network-controller.ts +++ b/app/scripts/controllers/network/network-controller.ts @@ -307,10 +307,9 @@ function isErrorWithCode(error: unknown): error is { code: string | number } { * @param value - The value to check. */ function assertNetworkId(value: any): asserts value is NetworkId { - assert( - /^\d+$/u.test(value) && !Number.isNaN(Number(value)), - 'value is not a number', - ); + if (!/^\d+$/u.test(value) || Number.isNaN(Number(value))) { + throw new Error('value is not a number'); + } } /** From 6e180af3137b21635588e0993710e603e4cbdb8f Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Tue, 9 May 2023 20:39:38 +0100 Subject: [PATCH 024/120] remove pre commit hook for branch names (#19077) * remove pre commit hook for branch names * bail with ticket number 0 detected --- .github/scripts/label-prs.ts | 4 +++ .husky/pre-push | 4 --- .validate-branch-namerc.js | 11 ------- package.json | 1 - yarn.lock | 57 ------------------------------------ 5 files changed, 4 insertions(+), 73 deletions(-) delete mode 100755 .husky/pre-push delete mode 100644 .validate-branch-namerc.js diff --git a/.github/scripts/label-prs.ts b/.github/scripts/label-prs.ts index ef4e790db..8d05779d7 100644 --- a/.github/scripts/label-prs.ts +++ b/.github/scripts/label-prs.ts @@ -26,6 +26,10 @@ async function main(): Promise { issueNumber = getIssueNumberFromBranchName(headRef); } + if (Number(issueNumber) === 0) { + process.exit(0); + } + await updateLabels(octokit, issueNumber); } diff --git a/.husky/pre-push b/.husky/pre-push deleted file mode 100755 index bbf5399ef..000000000 --- a/.husky/pre-push +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - -yarn validate-branch-name \ No newline at end of file diff --git a/.validate-branch-namerc.js b/.validate-branch-namerc.js deleted file mode 100644 index 8685701d1..000000000 --- a/.validate-branch-namerc.js +++ /dev/null @@ -1,11 +0,0 @@ -const BRANCH_REGEX = - /^(main|develop|(ci|chore|docs|feat|feature|fix|perf|refactor|revert|style)\/\d*(?:[-](?![-])\w*)*|Version-v\d+\.\d+\.\d+)$/; - -const ERROR_MSG = - 'This branch name does not follow our conventions.' + - '\n' + - 'Rename it with "git branch -m "' + - '\n' + - 'Here are some example branch names that are accepted: "fix/123-description", "feat/123-longer-description", "feature/123", "main", "develop", "Version-v10.24.2".'; - -module.exports = { pattern: BRANCH_REGEX, errorMsg: ERROR_MSG }; diff --git a/package.json b/package.json index e878e91a8..be2d0959c 100644 --- a/package.json +++ b/package.json @@ -366,7 +366,6 @@ "unicode-confusables": "^0.1.1", "uuid": "^8.3.2", "valid-url": "^1.0.9", - "validate-branch-name": "^1.3.0", "web3-stream-provider": "^4.0.0", "zxcvbn": "^4.4.2" }, diff --git a/yarn.lock b/yarn.lock index a60d76397..34e31bee6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10029,13 +10029,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-add-module-exports@npm:^0.2.1": - version: 0.2.1 - resolution: "babel-plugin-add-module-exports@npm:0.2.1" - checksum: 0d40e7b970161a10960fbbd0492565ae2f3f4872b4da089f8f5bb874cfac4e38e088e4d96bc33cef22a8963774abe84622feeebbbe049ad95c4ee33c907b277d - languageName: node - linkType: hard - "babel-plugin-add-react-displayname@npm:^0.0.5": version: 0.0.5 resolution: "babel-plugin-add-react-displayname@npm:0.0.5" @@ -13352,17 +13345,6 @@ __metadata: languageName: node linkType: hard -"current-git-branch@npm:^1.1.0": - version: 1.1.0 - resolution: "current-git-branch@npm:1.1.0" - dependencies: - babel-plugin-add-module-exports: ^0.2.1 - execa: ^0.6.1 - is-git-repository: ^1.0.0 - checksum: 57042d5c9fc608a951e81310da1caa3bdf917d0fede06996bfd7eaab5bdee7d29ced3440c3c73e5d90e503e689e2084e1906b1a17723e35684b1579d1bb5a54f - languageName: node - linkType: hard - "cwd@npm:^0.10.0": version: 0.10.0 resolution: "cwd@npm:0.10.0" @@ -16280,21 +16262,6 @@ __metadata: languageName: node linkType: hard -"execa@npm:^0.6.1": - version: 0.6.3 - resolution: "execa@npm:0.6.3" - dependencies: - cross-spawn: ^5.0.1 - get-stream: ^3.0.0 - is-stream: ^1.1.0 - npm-run-path: ^2.0.0 - p-finally: ^1.0.0 - signal-exit: ^3.0.0 - strip-eof: ^1.0.0 - checksum: 2c66177731273a7c0a4c031af81b486b67ec1eeeb8f353ebc68e0cfe7f63aca9ebc1e6fe03ba10f130f2bd179c0ac69b35668fe2bfc1ceb68fbf5291d0783457 - languageName: node - linkType: hard - "execa@npm:^0.7.0": version: 0.7.0 resolution: "execa@npm:0.7.0" @@ -20131,16 +20098,6 @@ __metadata: languageName: node linkType: hard -"is-git-repository@npm:^1.0.0": - version: 1.1.1 - resolution: "is-git-repository@npm:1.1.1" - dependencies: - execa: ^0.6.1 - path-is-absolute: ^1.0.1 - checksum: 2873d41da9ae5771a9118bdd743f32fa868301c57e8e4d8e255d4e14c04267112294a29f2824531fa554696042d8d87185811cff2de2a06381cff7d61d9ac22d - languageName: node - linkType: hard - "is-glob@npm:^2.0.0, is-glob@npm:^2.0.1": version: 2.0.1 resolution: "is-glob@npm:2.0.1" @@ -24372,7 +24329,6 @@ __metadata: unicode-confusables: ^0.1.1 uuid: ^8.3.2 valid-url: ^1.0.9 - validate-branch-name: ^1.3.0 vinyl: ^2.2.1 vinyl-buffer: ^1.0.1 vinyl-source-stream: ^2.0.0 @@ -34012,19 +33968,6 @@ __metadata: languageName: node linkType: hard -"validate-branch-name@npm:^1.3.0": - version: 1.3.0 - resolution: "validate-branch-name@npm:1.3.0" - dependencies: - commander: ^8.3.0 - cosmiconfig: ^7.0.1 - current-git-branch: ^1.1.0 - bin: - validate-branch-name: cli.js - checksum: be82c1e39bfe0519fa02f01670b5ef928903a19289249559c9148c0fd20df356f373f2490fbfd54d018868a6348cc2ceb82fb67d5f5c48c15ecb48735b9b87fb - languageName: node - linkType: hard - "validate-npm-package-license@npm:^3.0.1": version: 3.0.4 resolution: "validate-npm-package-license@npm:3.0.4" From a1ff530430fc09b55223ef76befd5aa17fb1bb12 Mon Sep 17 00:00:00 2001 From: Olaf Tomalka Date: Tue, 9 May 2023 21:47:42 +0200 Subject: [PATCH 025/120] Made builds.yml variable errors more helpful (#19066) --- development/lib/variables.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/development/lib/variables.js b/development/lib/variables.js index b2fb61212..a3b393759 100644 --- a/development/lib/variables.js +++ b/development/lib/variables.js @@ -29,7 +29,11 @@ class Variables { assert( value !== DeclaredOnly, new TypeError( - `Tried to access a declared, but not defined environmental variable "${key}"`, + `Tried to access a declared, but not defined environmental variable "${key}" +\tWhy am I seeing this: "${key}" is declared in builds.yml, but had no actual value when we tried loading it. +\tHow do I fix this: You could provide a default value for the variable in builds.yml under "env" property and commit to git. For example: +\t\tenv: +\t\t - ${key}: ''`, ), ); return value; @@ -46,7 +50,9 @@ class Variables { assert( this.isDeclared(key), new TypeError( - `Tried to access an environmental variable "${key}" that wasn't declared in builds.yml`, + `Tried to access an environmental variable "${key}" that wasn't declared in builds.yml +\tWhy am I seeing this: We've made use of new variables be explicit to keep track of all of them in one place +\tHow do I fix this: Adding your variable in builds.yml under "env" property and committing to git will fix this`, ), ); return this.#definitions.get(key); From 62ffd8022ab0aa4e983d98dc7b70e145185f836b Mon Sep 17 00:00:00 2001 From: George Marshall Date: Tue, 9 May 2023 14:09:10 -0700 Subject: [PATCH 026/120] Some style, accessibility and sematic html updates to modal sub components (#19034) --- .../__snapshots__/modal-header.test.tsx.snap | 4 ++-- .../modal-header/modal-header.tsx | 15 +++++++++++++-- .../__snapshots__/modal-overlay.test.tsx.snap | 1 + .../modal-overlay/modal-overlay.scss | 3 ++- .../modal-overlay/modal-overlay.tsx | 1 + .../component-library/text/text.types.ts | 1 + ui/components/ui/popover/index.scss | 2 +- ui/css/design-system/z-index.scss | 1 + 8 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ui/components/component-library/modal-header/__snapshots__/modal-header.test.tsx.snap b/ui/components/component-library/modal-header/__snapshots__/modal-header.test.tsx.snap index d5c717bcf..e6ff624af 100644 --- a/ui/components/component-library/modal-header/__snapshots__/modal-header.test.tsx.snap +++ b/ui/components/component-library/modal-header/__snapshots__/modal-header.test.tsx.snap @@ -9,11 +9,11 @@ exports[`ModalHeader should render ModalHeader correctly 1`] = `
-

Modal header -

+
diff --git a/ui/components/component-library/modal-header/modal-header.tsx b/ui/components/component-library/modal-header/modal-header.tsx index 9cd4ca5d3..864bb6539 100644 --- a/ui/components/component-library/modal-header/modal-header.tsx +++ b/ui/components/component-library/modal-header/modal-header.tsx @@ -1,6 +1,13 @@ import React from 'react'; import classnames from 'classnames'; -import { HeaderBase, Text, ButtonIcon, ButtonIconSize, IconName } from '..'; +import { + HeaderBase, + Text, + ButtonIcon, + ButtonIconSize, + IconName, + ValidTag, +} from '..'; import { TextVariant, TextAlign, @@ -50,7 +57,11 @@ export const ModalHeader: React.FC = ({ {...props} > {typeof children === 'string' ? ( - + {children} ) : ( diff --git a/ui/components/component-library/modal-overlay/__snapshots__/modal-overlay.test.tsx.snap b/ui/components/component-library/modal-overlay/__snapshots__/modal-overlay.test.tsx.snap index 10f22ae8d..7041d8a3b 100644 --- a/ui/components/component-library/modal-overlay/__snapshots__/modal-overlay.test.tsx.snap +++ b/ui/components/component-library/modal-overlay/__snapshots__/modal-overlay.test.tsx.snap @@ -3,6 +3,7 @@ exports[`ModalOverlay should match snapshot 1`] = `
diff --git a/ui/components/component-library/modal-overlay/modal-overlay.scss b/ui/components/component-library/modal-overlay/modal-overlay.scss index afa528a18..5ef170df0 100644 --- a/ui/components/component-library/modal-overlay/modal-overlay.scss +++ b/ui/components/component-library/modal-overlay/modal-overlay.scss @@ -1,7 +1,8 @@ .mm-modal-overlay { - position: absolute; + position: fixed; top: 0; left: 0; right: 0; bottom: 0; + z-index: $modal-z-index; } diff --git a/ui/components/component-library/modal-overlay/modal-overlay.tsx b/ui/components/component-library/modal-overlay/modal-overlay.tsx index 76b9586cb..c8da17592 100644 --- a/ui/components/component-library/modal-overlay/modal-overlay.tsx +++ b/ui/components/component-library/modal-overlay/modal-overlay.tsx @@ -21,6 +21,7 @@ export const ModalOverlay: React.FC = ({ width={BLOCK_SIZES.FULL} height={BLOCK_SIZES.FULL} onClick={onClick} + aria-hidden="true" {...props} /> ); diff --git a/ui/components/component-library/text/text.types.ts b/ui/components/component-library/text/text.types.ts index 68fe42128..1f2e96bfe 100644 --- a/ui/components/component-library/text/text.types.ts +++ b/ui/components/component-library/text/text.types.ts @@ -41,6 +41,7 @@ export enum ValidTag { Ul = 'ul', Label = 'label', Input = 'input', + Header = 'header', } export interface TextProps extends BoxProps { diff --git a/ui/components/ui/popover/index.scss b/ui/components/ui/popover/index.scss index 760c73212..2b53cf892 100644 --- a/ui/components/ui/popover/index.scss +++ b/ui/components/ui/popover/index.scss @@ -51,7 +51,7 @@ display: flex; justify-content: center; align-items: center; - z-index: 1050; + z-index: $modal-z-index; } &-footer { diff --git a/ui/css/design-system/z-index.scss b/ui/css/design-system/z-index.scss index 38086904a..0fd57acc1 100644 --- a/ui/css/design-system/z-index.scss +++ b/ui/css/design-system/z-index.scss @@ -10,3 +10,4 @@ $main-container-z-index: 18; $send-card-z-index: 20; $sidebar-z-index: 26; $sidebar-overlay-z-index: 25; +$modal-z-index: 1050; From 32688c2e3c527ea6105d99543dbbf1e5fc2ba918 Mon Sep 17 00:00:00 2001 From: George Marshall Date: Tue, 9 May 2023 14:33:29 -0700 Subject: [PATCH 027/120] Adding ModalFocus component (#18979) --- lavamoat/browserify/beta/policy.json | 58 ++++ lavamoat/browserify/desktop/policy.json | 58 ++++ lavamoat/browserify/flask/policy.json | 58 ++++ lavamoat/browserify/main/policy.json | 58 ++++ lavamoat/build-system/policy.json | 2 +- package.json | 1 + ui/components/component-library/index.js | 1 + .../component-library/modal-focus/README.mdx | 248 ++++++++++++++++++ .../component-library/modal-focus/index.ts | 2 + .../modal-focus/modal-focus.stories.tsx | 158 +++++++++++ .../modal-focus/modal-focus.test.tsx | 61 +++++ .../modal-focus/modal-focus.tsx | 46 ++++ .../modal-focus/modal-focus.types.ts | 35 +++ yarn.lock | 90 ++++++- 14 files changed, 874 insertions(+), 2 deletions(-) create mode 100644 ui/components/component-library/modal-focus/README.mdx create mode 100644 ui/components/component-library/modal-focus/index.ts create mode 100644 ui/components/component-library/modal-focus/modal-focus.stories.tsx create mode 100644 ui/components/component-library/modal-focus/modal-focus.test.tsx create mode 100644 ui/components/component-library/modal-focus/modal-focus.tsx create mode 100644 ui/components/component-library/modal-focus/modal-focus.types.ts diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 2581ffd89..7504336d4 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -3910,6 +3910,64 @@ "setTimeout": true } }, + "react-focus-lock": { + "globals": { + "addEventListener": true, + "console.error": true, + "console.warn": true, + "document": true, + "removeEventListener": true, + "setTimeout": true + }, + "packages": { + "@babel/runtime": true, + "prop-types": true, + "react": true, + "react-focus-lock>focus-lock": true, + "react-focus-lock>react-clientside-effect": true, + "react-focus-lock>use-callback-ref": true, + "react-focus-lock>use-sidecar": true + } + }, + "react-focus-lock>focus-lock": { + "globals": { + "HTMLIFrameElement": true, + "Node.DOCUMENT_FRAGMENT_NODE": true, + "Node.DOCUMENT_NODE": true, + "Node.DOCUMENT_POSITION_CONTAINED_BY": true, + "Node.DOCUMENT_POSITION_CONTAINS": true, + "Node.ELEMENT_NODE": true, + "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "setTimeout": true + }, + "packages": { + "wait-on>rxjs>tslib": true + } + }, + "react-focus-lock>react-clientside-effect": { + "packages": { + "react": true, + "react-focus-lock>react-clientside-effect>@babel/runtime": true + } + }, + "react-focus-lock>use-callback-ref": { + "packages": { + "react": true + } + }, + "react-focus-lock>use-sidecar": { + "globals": { + "console.error": true + }, + "packages": { + "react": true, + "react-focus-lock>use-sidecar>detect-node-es": true, + "wait-on>rxjs>tslib": true + } + }, "react-idle-timer": { "globals": { "clearTimeout": true, diff --git a/lavamoat/browserify/desktop/policy.json b/lavamoat/browserify/desktop/policy.json index f0fa38c5f..e3184f749 100644 --- a/lavamoat/browserify/desktop/policy.json +++ b/lavamoat/browserify/desktop/policy.json @@ -4362,6 +4362,64 @@ "setTimeout": true } }, + "react-focus-lock": { + "globals": { + "addEventListener": true, + "console.error": true, + "console.warn": true, + "document": true, + "removeEventListener": true, + "setTimeout": true + }, + "packages": { + "@babel/runtime": true, + "prop-types": true, + "react": true, + "react-focus-lock>focus-lock": true, + "react-focus-lock>react-clientside-effect": true, + "react-focus-lock>use-callback-ref": true, + "react-focus-lock>use-sidecar": true + } + }, + "react-focus-lock>focus-lock": { + "globals": { + "HTMLIFrameElement": true, + "Node.DOCUMENT_FRAGMENT_NODE": true, + "Node.DOCUMENT_NODE": true, + "Node.DOCUMENT_POSITION_CONTAINED_BY": true, + "Node.DOCUMENT_POSITION_CONTAINS": true, + "Node.ELEMENT_NODE": true, + "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "setTimeout": true + }, + "packages": { + "wait-on>rxjs>tslib": true + } + }, + "react-focus-lock>react-clientside-effect": { + "packages": { + "react": true, + "react-focus-lock>react-clientside-effect>@babel/runtime": true + } + }, + "react-focus-lock>use-callback-ref": { + "packages": { + "react": true + } + }, + "react-focus-lock>use-sidecar": { + "globals": { + "console.error": true + }, + "packages": { + "react": true, + "react-focus-lock>use-sidecar>detect-node-es": true, + "wait-on>rxjs>tslib": true + } + }, "react-idle-timer": { "globals": { "clearTimeout": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index f0fa38c5f..e3184f749 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -4362,6 +4362,64 @@ "setTimeout": true } }, + "react-focus-lock": { + "globals": { + "addEventListener": true, + "console.error": true, + "console.warn": true, + "document": true, + "removeEventListener": true, + "setTimeout": true + }, + "packages": { + "@babel/runtime": true, + "prop-types": true, + "react": true, + "react-focus-lock>focus-lock": true, + "react-focus-lock>react-clientside-effect": true, + "react-focus-lock>use-callback-ref": true, + "react-focus-lock>use-sidecar": true + } + }, + "react-focus-lock>focus-lock": { + "globals": { + "HTMLIFrameElement": true, + "Node.DOCUMENT_FRAGMENT_NODE": true, + "Node.DOCUMENT_NODE": true, + "Node.DOCUMENT_POSITION_CONTAINED_BY": true, + "Node.DOCUMENT_POSITION_CONTAINS": true, + "Node.ELEMENT_NODE": true, + "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "setTimeout": true + }, + "packages": { + "wait-on>rxjs>tslib": true + } + }, + "react-focus-lock>react-clientside-effect": { + "packages": { + "react": true, + "react-focus-lock>react-clientside-effect>@babel/runtime": true + } + }, + "react-focus-lock>use-callback-ref": { + "packages": { + "react": true + } + }, + "react-focus-lock>use-sidecar": { + "globals": { + "console.error": true + }, + "packages": { + "react": true, + "react-focus-lock>use-sidecar>detect-node-es": true, + "wait-on>rxjs>tslib": true + } + }, "react-idle-timer": { "globals": { "clearTimeout": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 2581ffd89..7504336d4 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -3910,6 +3910,64 @@ "setTimeout": true } }, + "react-focus-lock": { + "globals": { + "addEventListener": true, + "console.error": true, + "console.warn": true, + "document": true, + "removeEventListener": true, + "setTimeout": true + }, + "packages": { + "@babel/runtime": true, + "prop-types": true, + "react": true, + "react-focus-lock>focus-lock": true, + "react-focus-lock>react-clientside-effect": true, + "react-focus-lock>use-callback-ref": true, + "react-focus-lock>use-sidecar": true + } + }, + "react-focus-lock>focus-lock": { + "globals": { + "HTMLIFrameElement": true, + "Node.DOCUMENT_FRAGMENT_NODE": true, + "Node.DOCUMENT_NODE": true, + "Node.DOCUMENT_POSITION_CONTAINED_BY": true, + "Node.DOCUMENT_POSITION_CONTAINS": true, + "Node.ELEMENT_NODE": true, + "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "setTimeout": true + }, + "packages": { + "wait-on>rxjs>tslib": true + } + }, + "react-focus-lock>react-clientside-effect": { + "packages": { + "react": true, + "react-focus-lock>react-clientside-effect>@babel/runtime": true + } + }, + "react-focus-lock>use-callback-ref": { + "packages": { + "react": true + } + }, + "react-focus-lock>use-sidecar": { + "globals": { + "console.error": true + }, + "packages": { + "react": true, + "react-focus-lock>use-sidecar>detect-node-es": true, + "wait-on>rxjs>tslib": true + } + }, "react-idle-timer": { "globals": { "clearTimeout": true, diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json index b60f9dcae..49711a209 100644 --- a/lavamoat/build-system/policy.json +++ b/lavamoat/build-system/policy.json @@ -7362,7 +7362,7 @@ }, "stylelint>postcss-html>htmlparser2>domutils>dom-serializer": { "packages": { - "stylelint>postcss-html>htmlparser2>domutils>dom-serializer>domelementtype": true, + "stylelint>postcss-html>htmlparser2>domelementtype": true, "stylelint>postcss-html>htmlparser2>entities": true } }, diff --git a/package.json b/package.json index be2d0959c..8ea8817b3 100644 --- a/package.json +++ b/package.json @@ -345,6 +345,7 @@ "qrcode.react": "^1.0.1", "react": "^16.12.0", "react-dom": "^16.12.0", + "react-focus-lock": "^2.9.4", "react-idle-timer": "^4.2.5", "react-inspector": "^2.3.0", "react-markdown": "^6.0.3", diff --git a/ui/components/component-library/index.js b/ui/components/component-library/index.js index 5c38ef3b1..99d4870bc 100644 --- a/ui/components/component-library/index.js +++ b/ui/components/component-library/index.js @@ -34,6 +34,7 @@ export { TextField, TEXT_FIELD_TYPES, TEXT_FIELD_SIZES } from './text-field'; export { TextFieldSearch } from './text-field-search'; export { ModalContent, ModalContentSize } from './modal-content'; export { ModalOverlay } from './modal-overlay'; +export { ModalFocus } from './modal-focus'; // Molecules export { BannerBase } from './banner-base'; diff --git a/ui/components/component-library/modal-focus/README.mdx b/ui/components/component-library/modal-focus/README.mdx new file mode 100644 index 000000000..3ec22f551 --- /dev/null +++ b/ui/components/component-library/modal-focus/README.mdx @@ -0,0 +1,248 @@ +import { Story, Canvas, ArgsTable } from '@storybook/addon-docs'; + +import { ModalFocus } from './modal-focus'; + +# ModalFocus + +`ModalFocus` traps the focus within the modal. This greatly improves the experience for screen readers and keyboard only users. + + + + + +## Props + +The `ModalFocus` is built with [react-focus-lock](https://github.com/theKashey/react-focus-lock) and accepts all of the props from that library. + + + +### Children + +Use the `children` prop to render the component to lock focus to + + + + + +```jsx +import React from 'react'; +import { + BorderColor, + DISPLAY, + FLEX_DIRECTION, +} from '../../../helpers/constants/design-system'; + +import Box from '../../ui/box'; + +import { ModalFocus } from '../../component-library'; + +const [open, setOpen] = React.useState(false); + +; + +{ + open && ( + + +

Modal focus children

+ +

+ Use the keyboard to try tabbing around you will notice that the focus + is locked to the content within modal focus +

+ +
+
+ ); +} +``` + +### Initial Focus Ref + +Use the `initialFocusRef` to pass the `ref` of the element to receive focus initially + + + + + +```jsx +import React from 'react'; +import { + BorderColor, + DISPLAY, + FLEX_DIRECTION, +} from '../../../helpers/constants/design-system'; + +import Box from '../../ui/box'; + +import { ModalFocus } from '../../component-library'; + +const [open, setOpen] = React.useState(false); +const ref = React.useRef < HTMLButtonElement > null; + +; + +{ + open && ( + + + +

Initial focus is on the close button

+ +
+
+ ); +} +``` + +### Final Focus Ref + +Use the `finalFocusRef` to pass the `ref` of the element to return focus to when `ModalFocus` unmounts + + + + + +```jsx +import React from 'react'; +import { + BorderColor, + DISPLAY, + FLEX_DIRECTION, +} from '../../../helpers/constants/design-system'; + +import Box from '../../ui/box'; + +import { ModalFocus } from '../../component-library'; + +const [open, setOpen] = React.useState(false); +const ref = React.useRef < HTMLInputElement > null; + +; +; + +{ + open && ( + + +

Focus will be returned to the input once closed

+ +
+
+ ); +} +``` + +### Restore Focus + +Use the `restoreFocus` to restore focus to the element that triggered the `ModalFocus` once it unmounts + + + + + +```jsx +import React from 'react'; +import { + BorderColor, + DISPLAY, + FLEX_DIRECTION, +} from '../../../helpers/constants/design-system'; + +import Box from '../../ui/box'; + +import { ModalFocus } from '../../component-library'; + +const [open, setOpen] = React.useState(false); + +; +{ + open && ( + + +

Focus will be restored to the open button once closed

+ +
+
+ ); +} +``` + +### Auto Focus + +Use the `autoFocus` to auto focus to the first focusable element within the `ModalFocus` once it mounts + +Defaults to `true` + + + + + +```jsx +import React from 'react'; +import { + BorderColor, + DISPLAY, + FLEX_DIRECTION, +} from '../../../helpers/constants/design-system'; + +import Box from '../../ui/box'; + +import { ModalFocus } from '../../component-library'; + +const [open, setOpen] = React.useState(false); + +; +{ + open && ( + + +

auto focus set to false

+ +
+
+ ); +} +``` diff --git a/ui/components/component-library/modal-focus/index.ts b/ui/components/component-library/modal-focus/index.ts new file mode 100644 index 000000000..32d54eed1 --- /dev/null +++ b/ui/components/component-library/modal-focus/index.ts @@ -0,0 +1,2 @@ +export { ModalFocus } from './modal-focus'; +export type { ModalFocusProps } from './modal-focus.types'; diff --git a/ui/components/component-library/modal-focus/modal-focus.stories.tsx b/ui/components/component-library/modal-focus/modal-focus.stories.tsx new file mode 100644 index 000000000..5ae6e2c3d --- /dev/null +++ b/ui/components/component-library/modal-focus/modal-focus.stories.tsx @@ -0,0 +1,158 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import Box from '../../ui/box'; + +import { + BorderColor, + DISPLAY, + FLEX_DIRECTION, +} from '../../../helpers/constants/design-system'; + +import { ModalFocus } from './modal-focus'; +import README from './README.mdx'; + +export default { + title: 'Components/ComponentLibrary/ModalFocus', + component: ModalFocus, + parameters: { + docs: { + page: README, + }, + }, + args: { + children: ( + <> +

Modal focus children

+ +

+ Use the keyboard to try tabbing around you will notice that the focus + is locked to the content within modal focus +

+ + ), + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => { + const [open, setOpen] = React.useState(false); + return ( + <> + + {open && ( + + + {args.children} + + + + )} + + ); +}; + +export const DefaultStory = Template.bind({}); +DefaultStory.storyName = 'Default'; + +export const Children = Template.bind({}); +Children.args = { + children: ( + <> +

Modal focus children

+ + ), +}; +export const InitialFocusRef = (args) => { + const ref = React.useRef(null); + const [open, setOpen] = React.useState(false); + return ( + <> + + {open && ( + + + + {args.children} + + + + )} + + ); +}; +InitialFocusRef.args = { + children:

Initial focus is on the close button

, +}; + +export const FinalFocusRef = (args) => { + const ref = React.useRef(null); + const [open, setOpen] = React.useState(false); + return ( + <> + + + + + {open && ( + + +

Focus will be returned to the input once closed

+ +
+
+ )} + + ); +}; + +export const RestoreFocus = (args) => { + const ref = React.useRef(null); + const [open, setOpen] = React.useState(false); + return ( + <> + + {open && ( + + +

Focus will be restored to the open button once closed

+ +
+
+ )} + + ); +}; + +export const AutoFocus = Template.bind({}); +AutoFocus.args = { + autoFocus: false, + children:

auto focus set to false

, +}; diff --git a/ui/components/component-library/modal-focus/modal-focus.test.tsx b/ui/components/component-library/modal-focus/modal-focus.test.tsx new file mode 100644 index 000000000..efdf4439d --- /dev/null +++ b/ui/components/component-library/modal-focus/modal-focus.test.tsx @@ -0,0 +1,61 @@ +/* eslint-disable jest/require-top-level-describe */ +import { render } from '@testing-library/react'; +import React from 'react'; + +import { ModalFocus } from './modal-focus'; + +describe('ModalFocus', () => { + it('should render with children inside the ModalFocus', () => { + const { getByText } = render( + +
modal focus
+
, + ); + expect(getByText('modal focus')).toBeDefined(); + }); + + it('should render with the initial element focused', () => { + const { getByTestId } = render( + + + , + ); + expect(getByTestId('input')).toHaveFocus(); + }); + + it('should render with focused with autoFocus is set to false', () => { + const { getByTestId } = render( + + + , + ); + expect(getByTestId('input')).not.toHaveFocus(); + }); + + it('should focus initialFocusRef on render', () => { + const ref: React.RefObject = React.createRef(); + const { getByTestId } = render( + + + + + , + ); + expect(getByTestId('input')).toHaveFocus(); + }); + + it('should focus final focus ref when closed', () => { + const finalRef: React.RefObject = React.createRef(); + const { rerender, getByRole } = render( + <> + + +
modal focus
+
+ , + ); + expect(finalRef.current).not.toHaveFocus(); + rerender(); + expect(getByRole('button')).toHaveFocus(); + }); +}); diff --git a/ui/components/component-library/modal-focus/modal-focus.tsx b/ui/components/component-library/modal-focus/modal-focus.tsx new file mode 100644 index 000000000..f8152d527 --- /dev/null +++ b/ui/components/component-library/modal-focus/modal-focus.tsx @@ -0,0 +1,46 @@ +import React, { useCallback } from 'react'; +import ReactFocusLock from 'react-focus-lock'; +import type { ModalFocusProps } from './modal-focus.types'; + +/** + * Based on the ModalFocusScope component from chakra-ui + * https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/modal/src/modal-focus.tsx + */ + +const FocusTrap: typeof ReactFocusLock = + (ReactFocusLock as any).default ?? ReactFocusLock; + +export const ModalFocus: React.FC = ({ + initialFocusRef, + finalFocusRef, + restoreFocus, + children, + autoFocus, + ...props +}) => { + const onActivation = useCallback(() => { + if (initialFocusRef?.current) { + initialFocusRef.current.focus(); + } + }, [initialFocusRef]); + + const onDeactivation = useCallback(() => { + finalFocusRef?.current?.focus(); + }, [finalFocusRef]); + + const returnFocus = restoreFocus && !finalFocusRef; + + return ( + + {children} + + ); +}; + +ModalFocus.displayName = 'ModalFocus'; diff --git a/ui/components/component-library/modal-focus/modal-focus.types.ts b/ui/components/component-library/modal-focus/modal-focus.types.ts new file mode 100644 index 000000000..c36da41fa --- /dev/null +++ b/ui/components/component-library/modal-focus/modal-focus.types.ts @@ -0,0 +1,35 @@ +import React from 'react'; + +export interface FocusableElement { + focus(options?: FocusOptions): void; +} + +export interface ModalFocusProps { + /** + * The `ref` of the element to receive focus initially + */ + initialFocusRef?: React.RefObject; + /** + * The `ref` of the element to return focus to when `ModalFocus` + * unmounts + */ + finalFocusRef?: React.RefObject; + /** + * If `true`, focus will be restored to the element that + * triggered the `ModalFocus` once it unmounts + * + * @default false + */ + restoreFocus?: boolean; + /** + * The node to lock focus to + */ + children: React.ReactNode; + /** + * If `true`, the first focusable element within the `children` + * will auto-focused once `ModalFocus` mounts + * + * @default false + */ + autoFocus?: boolean; +} diff --git a/yarn.lock b/yarn.lock index 34e31bee6..6c4da2694 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1627,6 +1627,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.12.13": + version: 7.21.0 + resolution: "@babel/runtime@npm:7.21.0" + dependencies: + regenerator-runtime: ^0.13.11 + checksum: 7b33e25bfa9e0e1b9e8828bb61b2d32bdd46b41b07ba7cb43319ad08efc6fda8eb89445193e67d6541814627df0ca59122c0ea795e412b99c5183a0540d338ab + languageName: node + linkType: hard + "@babel/runtime@patch:@babel/runtime@npm%3A7.18.9#./.yarn/patches/@babel-runtime-npm-7.18.9-28ca6b5f61.patch::locator=metamask-crx%40workspace%3A.": version: 7.18.9 resolution: "@babel/runtime@patch:@babel/runtime@npm%3A7.18.9#./.yarn/patches/@babel-runtime-npm-7.18.9-28ca6b5f61.patch::version=7.18.9&hash=918bda&locator=metamask-crx%40workspace%3A." @@ -13947,6 +13956,13 @@ __metadata: languageName: node linkType: hard +"detect-node-es@npm:^1.1.0": + version: 1.1.0 + resolution: "detect-node-es@npm:1.1.0" + checksum: e46307d7264644975b71c104b9f028ed1d3d34b83a15b8a22373640ce5ea630e5640b1078b8ea15f202b54641da71e4aa7597093bd4b91f113db520a26a37449 + languageName: node + linkType: hard + "detect-node@npm:^2.0.4": version: 2.0.4 resolution: "detect-node@npm:2.0.4" @@ -17201,6 +17217,15 @@ __metadata: languageName: node linkType: hard +"focus-lock@npm:^0.11.6": + version: 0.11.6 + resolution: "focus-lock@npm:0.11.6" + dependencies: + tslib: ^2.0.3 + checksum: 6a407c4c45f05f8258f92565541fc5f8043f576643a7603eb999e1a790173e08712056766ed034ccd31c6d6deed259dea558002712fa5ef2432fc6930b9c7a05 + languageName: node + linkType: hard + "follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.14.9, follow-redirects@npm:^1.15.0": version: 1.15.2 resolution: "follow-redirects@npm:1.15.2" @@ -24282,6 +24307,7 @@ __metadata: react: ^16.12.0 react-devtools: ^4.11.0 react-dom: ^16.12.0 + react-focus-lock: ^2.9.4 react-idle-timer: ^4.2.5 react-inspector: ^2.3.0 react-markdown: ^6.0.3 @@ -28298,6 +28324,17 @@ __metadata: languageName: node linkType: hard +"react-clientside-effect@npm:^1.2.6": + version: 1.2.6 + resolution: "react-clientside-effect@npm:1.2.6" + dependencies: + "@babel/runtime": ^7.12.13 + peerDependencies: + react: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 7db6110027a51458b1a46109d2b63dd822825f483c71afef7c0c0a671f3b1aa155049dbd8651c9d536ffac83601f8823b7c3f8916b4f4ee5c3cb7647a85cce4e + languageName: node + linkType: hard + "react-colorful@npm:^5.1.2": version: 5.3.0 resolution: "react-colorful@npm:5.3.0" @@ -28416,6 +28453,26 @@ __metadata: languageName: node linkType: hard +"react-focus-lock@npm:^2.9.4": + version: 2.9.4 + resolution: "react-focus-lock@npm:2.9.4" + dependencies: + "@babel/runtime": ^7.0.0 + focus-lock: ^0.11.6 + prop-types: ^15.6.2 + react-clientside-effect: ^1.2.6 + use-callback-ref: ^1.3.0 + use-sidecar: ^1.1.2 + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: f4c696bdbde5008560388622b994c00502d1faeeabff32b02964770c8c020208872f5f6b914b249a8bf3e97cc12e58bb0d227cd33460093654156b7b7f4c8d76 + languageName: node + linkType: hard + "react-idle-timer@npm:^4.2.5": version: 4.2.5 resolution: "react-idle-timer@npm:4.2.5" @@ -29058,7 +29115,7 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.13.9": +"regenerator-runtime@npm:^0.13.11, regenerator-runtime@npm:^0.13.9": version: 0.13.11 resolution: "regenerator-runtime@npm:0.13.11" checksum: 27481628d22a1c4e3ff551096a683b424242a216fee44685467307f14d58020af1e19660bf2e26064de946bad7eff28950eae9f8209d55723e2d9351e632bbb4 @@ -33779,6 +33836,37 @@ __metadata: languageName: node linkType: hard +"use-callback-ref@npm:^1.3.0": + version: 1.3.0 + resolution: "use-callback-ref@npm:1.3.0" + dependencies: + tslib: ^2.0.0 + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 7913df383a5a6fcb399212eedefaac2e0c6f843555202d4e3010bac3848afe38ecaa3d0d6500ad1d936fbeffd637e6c517e68edb024af5e6beca7f27f3ce7b21 + languageName: node + linkType: hard + +"use-sidecar@npm:^1.1.2": + version: 1.1.2 + resolution: "use-sidecar@npm:1.1.2" + dependencies: + detect-node-es: ^1.1.0 + tslib: ^2.0.0 + peerDependencies: + "@types/react": ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 925d1922f9853e516eaad526b6fed1be38008073067274f0ecc3f56b17bb8ab63480140dd7c271f94150027c996cea4efe83d3e3525e8f3eda22055f6a39220b + languageName: node + linkType: hard + "use@npm:^3.1.0": version: 3.1.0 resolution: "use@npm:3.1.0" From 490e0770c76c6024747c3782082cae5cf6a39e1b Mon Sep 17 00:00:00 2001 From: Dhruv <79097544+dhruvv173@users.noreply.github.com> Date: Wed, 10 May 2023 06:22:16 +0530 Subject: [PATCH 028/120] Changes to edit-gas-display.component.js (#19037) Co-authored-by: Brad Decker --- .../app/edit-gas-display/edit-gas-display.component.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/components/app/edit-gas-display/edit-gas-display.component.js b/ui/components/app/edit-gas-display/edit-gas-display.component.js index b33bd65c2..6bd1ed4cc 100644 --- a/ui/components/app/edit-gas-display/edit-gas-display.component.js +++ b/ui/components/app/edit-gas-display/edit-gas-display.component.js @@ -7,8 +7,8 @@ import { EditGasModes } from '../../../../shared/constants/gas'; import Button from '../../ui/button'; import { - TEXT_ALIGN, - FONT_WEIGHT, + TextAlign, + FontWeight, TextColor, TextVariant, } from '../../../helpers/constants/design-system'; @@ -101,7 +101,7 @@ export default function EditGasDisplay({ color={TextColor.textDefault} variant={TextVariant.bodySm} as="h6" - fontWeight={FONT_WEIGHT.BOLD} + fontWeight={FontWeight.Bold} > {t('speedUpTooltipText')}{' '} {estimatedMinimumNative} From e991439718f0ddbc2b9ad280eec86ebdeedbf39b Mon Sep 17 00:00:00 2001 From: Harsh Shukla <125105825+PrgrmrHarshShukla@users.noreply.github.com> Date: Wed, 10 May 2023 06:25:30 +0530 Subject: [PATCH 029/120] Part of #17670 & #18714: Replace Typography with Text component in token-details-page.js (#18741) * Worked on issue #17670 & #18714 in file token-details-page.js in file * Worked on issue #17670 & #18714 in file token-details-page.js in file * Update token-details-page.js --- ui/pages/token-details/token-details-page.js | 110 ++++++++++--------- 1 file changed, 61 insertions(+), 49 deletions(-) diff --git a/ui/pages/token-details/token-details-page.js b/ui/pages/token-details/token-details-page.js index 4b75b71a8..17f058187 100644 --- a/ui/pages/token-details/token-details-page.js +++ b/ui/pages/token-details/token-details-page.js @@ -14,13 +14,12 @@ import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../helpers/constants/routes'; import Tooltip from '../../components/ui/tooltip'; import Button from '../../components/ui/button'; import Box from '../../components/ui/box'; -import Typography from '../../components/ui/typography'; import { - TypographyVariant, - FONT_WEIGHT, + TextVariant, + FontWeight, DISPLAY, - TEXT_ALIGN, - OVERFLOW_WRAP, + TextAlign, + OverflowWrap, TextColor, IconColor, } from '../../helpers/constants/design-system'; @@ -29,6 +28,7 @@ import { ButtonIcon, ButtonIconSize, IconName, + Text, } from '../../components/component-library'; export default function TokenDetailsPage() { @@ -64,11 +64,12 @@ export default function TokenDetailsPage() { return ( - @@ -78,19 +79,20 @@ export default function TokenDetailsPage() { onClick={() => history.push(`${ASSET_ROUTE}/${token.address}`)} className="token-details__closeButton" /> - + - {tokenBalance || ''} - + - {tokenCurrencyBalance || ''} - - + {t('tokenContractAddress')} - + - {token.address} - + - {t('tokenDecimalTitle')} - - + {token.decimals} - - + {t('network')} - - + + {aggregators && ( <> - {t('tokenList')} - - + {`${aggregators}.`} - + )} From df3db6e5596b4b5e59923d9263a6f4f5da432a6d Mon Sep 17 00:00:00 2001 From: Vinicius Stevam <45455812+vinistevam@users.noreply.github.com> Date: Wed, 10 May 2023 06:36:01 +0100 Subject: [PATCH 030/120] Adopt ApprovalType from core (#18567) --- app/scripts/background.js | 12 ++++++------ app/scripts/controllers/app-state.js | 5 ++--- app/scripts/controllers/transactions/index.js | 8 +++----- app/scripts/controllers/transactions/index.test.js | 10 ++++------ .../handlers/add-ethereum-chain.js | 7 ++++--- .../handlers/switch-ethereum-chain.js | 3 ++- ui/components/app/add-network/add-network.js | 6 +++--- .../signature-request-original.component.js | 1 - ui/pages/confirmation/confirmation.js | 12 ++++++------ ui/pages/confirmation/templates/index.js | 14 +++++++------- ui/selectors/selectors.js | 4 ++-- 11 files changed, 39 insertions(+), 43 deletions(-) diff --git a/app/scripts/background.js b/app/scripts/background.js index 082a13b67..059b1bdd0 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -9,6 +9,9 @@ import debounce from 'debounce-stream'; import log from 'loglevel'; import browser from 'webextension-polyfill'; import { storeAsStream } from '@metamask/obs-store'; +///: BEGIN:ONLY_INCLUDE_IN(snaps) +import { ApprovalType } from '@metamask/controller-utils'; +///: END:ONLY_INCLUDE_IN import PortStream from 'extension-port-stream'; import { ethErrors } from 'eth-rpc-errors'; @@ -18,9 +21,6 @@ import { ENVIRONMENT_TYPE_FULLSCREEN, EXTENSION_MESSAGES, PLATFORM_FIREFOX, - ///: BEGIN:ONLY_INCLUDE_IN(snaps) - MESSAGE_TYPE, - ///: END:ONLY_INCLUDE_IN } from '../../shared/constants/app'; import { REJECT_NOTIFICATION_CLOSE, @@ -800,11 +800,11 @@ export function setupController( ({ id, type }) => { switch (type) { ///: BEGIN:ONLY_INCLUDE_IN(snaps) - case MESSAGE_TYPE.SNAP_DIALOG_ALERT: - case MESSAGE_TYPE.SNAP_DIALOG_PROMPT: + case ApprovalType.SnapDialogAlert: + case ApprovalType.SnapDialogPrompt: controller.approvalController.accept(id, null); break; - case MESSAGE_TYPE.SNAP_DIALOG_CONFIRMATION: + case ApprovalType.SnapDialogConfirmation: controller.approvalController.accept(id, false); break; ///: END:ONLY_INCLUDE_IN diff --git a/app/scripts/controllers/app-state.js b/app/scripts/controllers/app-state.js index 63eaf085d..92166eac2 100644 --- a/app/scripts/controllers/app-state.js +++ b/app/scripts/controllers/app-state.js @@ -2,6 +2,7 @@ import EventEmitter from 'events'; import { ObservableStore } from '@metamask/obs-store'; import { v4 as uuid } from 'uuid'; import log from 'loglevel'; +import { ApprovalType } from '@metamask/controller-utils'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; import { MINUTE } from '../../../shared/constants/time'; import { AUTO_LOCK_TIMEOUT_ALARM } from '../../../shared/constants/alarms'; @@ -13,8 +14,6 @@ import { ORIGIN_METAMASK, } from '../../../shared/constants/app'; -const APPROVAL_REQUEST_TYPE = 'unlock'; - export default class AppStateController extends EventEmitter { /** * @param {object} opts @@ -408,7 +407,7 @@ export default class AppStateController extends EventEmitter { { id: this._approvalRequestId, origin: ORIGIN_METAMASK, - type: APPROVAL_REQUEST_TYPE, + type: ApprovalType.Unlock, }, true, ) diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index e31215171..a3bad2f62 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -5,6 +5,7 @@ import EthQuery from 'ethjs-query'; import { ethErrors } from 'eth-rpc-errors'; import { Common, Hardfork } from '@ethereumjs/common'; import { TransactionFactory } from '@ethereumjs/tx'; +import { ApprovalType } from '@metamask/controller-utils'; import NonceTracker from 'nonce-tracker'; import log from 'loglevel'; import BigNumber from 'bignumber.js'; @@ -51,10 +52,7 @@ import { determineTransactionType, isEIP1559Transaction, } from '../../../../shared/modules/transaction.utils'; -import { - ORIGIN_METAMASK, - MESSAGE_TYPE, -} from '../../../../shared/constants/app'; +import { ORIGIN_METAMASK } from '../../../../shared/constants/app'; import { calcGasTotal, getSwapsTokensReceivedFromTxMeta, @@ -2651,7 +2649,7 @@ export default class TransactionController extends EventEmitter { _requestApproval(txMeta) { const id = this._getApprovalId(txMeta); const { origin } = txMeta; - const type = MESSAGE_TYPE.TRANSACTION; + const type = ApprovalType.Transaction; const requestData = { txId: txMeta.id }; this.messagingSystem diff --git a/app/scripts/controllers/transactions/index.test.js b/app/scripts/controllers/transactions/index.test.js index 12e39d5ac..1203c6c58 100644 --- a/app/scripts/controllers/transactions/index.test.js +++ b/app/scripts/controllers/transactions/index.test.js @@ -3,6 +3,7 @@ import EventEmitter from 'events'; import { toBuffer } from 'ethereumjs-util'; import { TransactionFactory } from '@ethereumjs/tx'; import { ObservableStore } from '@metamask/obs-store'; +import { ApprovalType } from '@metamask/controller-utils'; import sinon from 'sinon'; import { @@ -29,10 +30,7 @@ import { GasRecommendations, } from '../../../../shared/constants/gas'; import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller'; -import { - MESSAGE_TYPE, - ORIGIN_METAMASK, -} from '../../../../shared/constants/app'; +import { ORIGIN_METAMASK } from '../../../../shared/constants/app'; import { NetworkStatus } from '../../../../shared/constants/network'; import { TRANSACTION_ENVELOPE_TYPE_NAMES } from '../../../../shared/lib/transactions-controller-utils'; import TransactionController from '.'; @@ -513,7 +511,7 @@ describe('Transaction Controller', function () { id: String(txMeta.id), origin: ORIGIN_METAMASK, requestData: { txId: txMeta.id }, - type: MESSAGE_TYPE.TRANSACTION, + type: ApprovalType.Transaction, }, true, // Show popup ]); @@ -551,7 +549,7 @@ describe('Transaction Controller', function () { id: String(secondTxMeta.id), origin: ORIGIN_METAMASK, requestData: { txId: secondTxMeta.id }, - type: MESSAGE_TYPE.TRANSACTION, + type: ApprovalType.Transaction, }, true, // Show popup ]); diff --git a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js index f63412b61..03b3f5714 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js @@ -1,6 +1,7 @@ import { ethErrors, errorCodes } from 'eth-rpc-errors'; import validUrl from 'valid-url'; import { omit } from 'lodash'; +import { ApprovalType } from '@metamask/controller-utils'; import { MESSAGE_TYPE, UNKNOWN_TICKER_SYMBOL, @@ -158,7 +159,7 @@ async function addEthereumChainHandler( try { await requestUserApproval({ origin, - type: MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN, + type: ApprovalType.SwitchEthereumChain, requestData: { rpcUrl: existingNetwork.rpcUrl, chainId: existingNetwork.chainId, @@ -244,7 +245,7 @@ async function addEthereumChainHandler( try { await requestUserApproval({ origin, - type: MESSAGE_TYPE.ADD_ETHEREUM_CHAIN, + type: ApprovalType.AddEthereumChain, requestData: { chainId: _chainId, rpcPrefs: { blockExplorerUrl: firstValidBlockExplorerUrl }, @@ -275,7 +276,7 @@ async function addEthereumChainHandler( try { await requestUserApproval({ origin, - type: MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN, + type: ApprovalType.SwitchEthereumChain, requestData: { rpcUrl: firstValidRPCUrl, chainId: _chainId, 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 4755a2c3d..6d71ba602 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 @@ -1,5 +1,6 @@ import { ethErrors } from 'eth-rpc-errors'; import { omit } from 'lodash'; +import { ApprovalType } from '@metamask/controller-utils'; import { MESSAGE_TYPE } from '../../../../../shared/constants/app'; import { CHAIN_ID_TO_TYPE_MAP, @@ -109,7 +110,7 @@ async function switchEthereumChainHandler( try { const approvedRequestData = await requestUserApproval({ origin, - type: MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN, + type: ApprovalType.SwitchEthereumChain, requestData, }); if ( diff --git a/ui/components/app/add-network/add-network.js b/ui/components/app/add-network/add-network.js index d8eae27ee..d0eca654b 100644 --- a/ui/components/app/add-network/add-network.js +++ b/ui/components/app/add-network/add-network.js @@ -1,6 +1,7 @@ import React, { useContext, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; +import { ApprovalType } from '@metamask/controller-utils'; import { I18nContext } from '../../../contexts/i18n'; import Box from '../../ui/box'; import { @@ -26,7 +27,6 @@ import { import { ENVIRONMENT_TYPE_FULLSCREEN, ENVIRONMENT_TYPE_POPUP, - MESSAGE_TYPE, ORIGIN_METAMASK, } from '../../../../shared/constants/app'; import { requestUserApproval } from '../../../store/actions'; @@ -66,7 +66,7 @@ const AddNetwork = () => { unapprovedConfirmations?.find((confirmation) => { return ( confirmation.origin === 'metamask' && - confirmation.type === MESSAGE_TYPE.ADD_ETHEREUM_CHAIN + confirmation.type === ApprovalType.AddEthereumChain ); }); if (!showPopover && anAddNetworkConfirmationFromMetaMaskExists) { @@ -258,7 +258,7 @@ const AddNetwork = () => { await dispatch( requestUserApproval({ origin: ORIGIN_METAMASK, - type: MESSAGE_TYPE.ADD_ETHEREUM_CHAIN, + type: ApprovalType.AddEthereumChain, requestData: { chainId: item.chainId, rpcUrl: item.rpcUrl, diff --git a/ui/components/app/signature-request-original/signature-request-original.component.js b/ui/components/app/signature-request-original/signature-request-original.component.js index cfabd20bb..0cc27dd42 100644 --- a/ui/components/app/signature-request-original/signature-request-original.component.js +++ b/ui/components/app/signature-request-original/signature-request-original.component.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import classnames from 'classnames'; import { ObjectInspector } from 'react-inspector'; import LedgerInstructionField from '../ledger-instruction-field'; - import { MESSAGE_TYPE } from '../../../../shared/constants/app'; import { getURLHostName, diff --git a/ui/pages/confirmation/confirmation.js b/ui/pages/confirmation/confirmation.js index 83a5b1cba..4666a4cbf 100644 --- a/ui/pages/confirmation/confirmation.js +++ b/ui/pages/confirmation/confirmation.js @@ -11,7 +11,7 @@ import { useHistory } from 'react-router-dom'; import { isEqual } from 'lodash'; import { produce } from 'immer'; -import { MESSAGE_TYPE } from '../../../shared/constants/app'; +import { ApprovalType } from '@metamask/controller-utils'; import Box from '../../components/ui/box'; import MetaMaskTemplateRenderer from '../../components/app/metamask-template-renderer'; import ConfirmationWarningModal from '../../components/app/confirmation-warning-modal'; @@ -198,9 +198,9 @@ export default function ConfirmationPage({ getSnapName(pendingConfirmation?.origin, targetSubjectMetadata); const SNAP_DIALOG_TYPE = [ - MESSAGE_TYPE.SNAP_DIALOG_ALERT, - MESSAGE_TYPE.SNAP_DIALOG_CONFIRMATION, - MESSAGE_TYPE.SNAP_DIALOG_PROMPT, + ApprovalType.SnapDialogAlert, + ApprovalType.SnapDialogConfirmation, + ApprovalType.SnapDialogPrompt, ]; const isSnapDialog = SNAP_DIALOG_TYPE.includes(pendingConfirmation?.type); @@ -208,7 +208,7 @@ export default function ConfirmationPage({ const INPUT_STATE_CONFIRMATIONS = [ ///: BEGIN:ONLY_INCLUDE_IN(snaps) - MESSAGE_TYPE.SNAP_DIALOG_PROMPT, + ApprovalType.SnapDialogPrompt, ///: END:ONLY_INCLUDE_IN ]; @@ -284,7 +284,7 @@ export default function ConfirmationPage({ setShowWarningModal(true); } else { const inputState = hasInputState(pendingConfirmation.type) - ? inputStates[MESSAGE_TYPE.SNAP_DIALOG_PROMPT] + ? inputStates[ApprovalType.SnapDialogPrompt] : null; // submit result is an array of errors or empty on success const submitResult = await templatedValues.onSubmit(inputState); diff --git a/ui/pages/confirmation/templates/index.js b/ui/pages/confirmation/templates/index.js index 2dc7a50c5..bd2b733a6 100644 --- a/ui/pages/confirmation/templates/index.js +++ b/ui/pages/confirmation/templates/index.js @@ -1,5 +1,5 @@ import { omit, pick } from 'lodash'; -import { MESSAGE_TYPE } from '../../../../shared/constants/app'; +import { ApprovalType } from '@metamask/controller-utils'; import { rejectPendingApproval, resolvePendingApproval, @@ -15,16 +15,16 @@ import snapPrompt from './snaps/snap-prompt/snap-prompt'; ///: END:ONLY_INCLUDE_IN const APPROVAL_TEMPLATES = { - [MESSAGE_TYPE.ADD_ETHEREUM_CHAIN]: addEthereumChain, - [MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN]: switchEthereumChain, + [ApprovalType.AddEthereumChain]: addEthereumChain, + [ApprovalType.SwitchEthereumChain]: switchEthereumChain, ///: BEGIN:ONLY_INCLUDE_IN(snaps) - [MESSAGE_TYPE.SNAP_DIALOG_ALERT]: snapAlert, - [MESSAGE_TYPE.SNAP_DIALOG_CONFIRMATION]: snapConfirmation, - [MESSAGE_TYPE.SNAP_DIALOG_PROMPT]: snapPrompt, + [ApprovalType.SnapDialogAlert]: snapAlert, + [ApprovalType.SnapDialogConfirmation]: snapConfirmation, + [ApprovalType.SnapDialogPrompt]: snapPrompt, ///: END:ONLY_INCLUDE_IN }; -export const TEMPLATED_CONFIRMATION_MESSAGE_TYPES = +export const TEMPLATED_CONFIRMATION_APPROVAL_TYPES = Object.keys(APPROVAL_TEMPLATES); const ALLOWED_TEMPLATE_KEYS = [ diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index de7a4b8dc..85cb57be3 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -63,7 +63,7 @@ import { ///: END:ONLY_INCLUDE_IN } from '../helpers/utils/util'; -import { TEMPLATED_CONFIRMATION_MESSAGE_TYPES } from '../pages/confirmation/templates'; +import { TEMPLATED_CONFIRMATION_APPROVAL_TYPES } from '../pages/confirmation/templates'; import { STATIC_MAINNET_TOKEN_LIST } from '../../shared/constants/tokens'; import { DAY } from '../../shared/constants/time'; import { TERMS_OF_USE_LAST_UPDATED } from '../../shared/constants/terms'; @@ -551,7 +551,7 @@ export function getUnapprovedConfirmations(state) { export function getUnapprovedTemplatedConfirmations(state) { const unapprovedConfirmations = getUnapprovedConfirmations(state); return unapprovedConfirmations.filter((approval) => - TEMPLATED_CONFIRMATION_MESSAGE_TYPES.includes(approval.type), + TEMPLATED_CONFIRMATION_APPROVAL_TYPES.includes(approval.type), ); } From 23b8b15e5c94232d4e24fb22d2a0a4ea8042c2de Mon Sep 17 00:00:00 2001 From: legobeat <109787230+legobeat@users.noreply.github.com> Date: Wed, 10 May 2023 10:33:57 +0000 Subject: [PATCH 031/120] builds.yml: add env var EDITOR_URL (#19074) --- builds.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builds.yml b/builds.yml index 6adcb0d98..414641af0 100644 --- a/builds.yml +++ b/builds.yml @@ -213,6 +213,8 @@ env: # if it's not inside process.env # Also see DEBUG and METAMASK_DEBUG - NODE_DEBUG: '' + # Used by react-devtools-core + - EDITOR_URL: '' ### # Meta variables From 05fb01802d6c65e6ac71b1af62c1167518692374 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Wed, 10 May 2023 06:04:10 -0600 Subject: [PATCH 032/120] Re-enable tests for subscription-based RPC methods (#18994) NetworkController doesn't handle `eth_subscribe` or `eth_unsubscribe` specially, but as it's supported by Infura, we want to make sure we exercise these RPC methods in the network client tests, even if it is just to ensure that they get passed through to the network. We had tests for these RPC methods, but they were commented out in c095b1accd00c8123f954633bf396ddea7b95eff when the network client code was extracted to a separate file. At the time we were considering adding subscription- and filter-based middleware to NetworkController, and so we commented out the tests for `eth_subscribe` and `eth_unsubscribe` temporarily until we could rewrite them in a way that would exercise the new middleware. We reverted that change in bd23a490133693a464c2f4ab1976181378a9f7bf, which meant that we could restore the existing tests, but it appears that this task was not caught during review. This commit takes care of restoring them. Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- .../controllers/network/provider-api-tests/shared-tests.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/scripts/controllers/network/provider-api-tests/shared-tests.ts b/app/scripts/controllers/network/provider-api-tests/shared-tests.ts index 6337bb56a..cf34302ce 100644 --- a/app/scripts/controllers/network/provider-api-tests/shared-tests.ts +++ b/app/scripts/controllers/network/provider-api-tests/shared-tests.ts @@ -295,9 +295,8 @@ export function testsForProviderType(providerType: ProviderType) { // tests on the core side. { name: 'net_listening', numberOfParameters: 0 }, - // TODO: Methods to add back when we add testing for subscribe middleware - // { name: 'eth_subscribe', numberOfParameters: 1 }, - // { name: 'eth_unsubscribe', numberOfParameters: 1 }, + { name: 'eth_subscribe', numberOfParameters: 1 }, + { name: 'eth_unsubscribe', numberOfParameters: 1 }, { name: 'custom_rpc_method', numberOfParameters: 1 }, { name: 'net_peerCount', numberOfParameters: 0 }, { name: 'parity_nextNonce', numberOfParameters: 1 }, From 46c2f1cc56138e4b256d96e70833b9a7b01e70a6 Mon Sep 17 00:00:00 2001 From: Nidhi Kumari Date: Wed, 10 May 2023 19:11:03 +0530 Subject: [PATCH 033/120] removed mmi fencing from copy icon in header (#19087) * removed mmi fencing from copy icon * updated snapshot --- .../selected-account-component.test.js.snap | 8 -------- .../selected-account/selected-account.component.js | 13 ++----------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/ui/components/app/selected-account/__snapshots__/selected-account-component.test.js.snap b/ui/components/app/selected-account/__snapshots__/selected-account-component.test.js.snap index 43e1f1a76..6031f8d0b 100644 --- a/ui/components/app/selected-account/__snapshots__/selected-account-component.test.js.snap +++ b/ui/components/app/selected-account/__snapshots__/selected-account-component.test.js.snap @@ -29,14 +29,6 @@ exports[`SelectedAccount Component should match snapshot 1`] = ` class="selected-account__address" > 0x0DC...E7bc - From cf7c7905053058d55f16fb47de65c3b4e5442cb7 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 10 May 2023 12:11:57 -0230 Subject: [PATCH 034/120] Only recognize "blocked" status for built-in networks (#19069) The detection of the Infura "blocked" status has been updated to apply only to built-in networks. The message we show to users in this state is meant only for Infura; we don't want to show it for third-party RPC APIs that happen to use the same error response. This brings the network controller further in alignment with the core network controller. This isn't tested, but it was found in the course of porting unit tests from core to extension. It will be covered by these tests, which will be added in the next PR. --- .../controllers/network/network-controller.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/scripts/controllers/network/network-controller.ts b/app/scripts/controllers/network/network-controller.ts index b6fd4a503..4a79eaf1a 100644 --- a/app/scripts/controllers/network/network-controller.ts +++ b/app/scripts/controllers/network/network-controller.ts @@ -623,12 +623,14 @@ export class NetworkController extends EventEmitter { supportsEIP1559 = results[1]; networkStatus = NetworkStatus.Available; } catch (error) { - if (isErrorWithCode(error) && isErrorWithMessage(error)) { + if (isErrorWithCode(error)) { let responseBody; - try { - responseBody = JSON.parse(error.message); - } catch { - // error.message must not be JSON + if (isInfura && isErrorWithMessage(error)) { + try { + responseBody = JSON.parse(error.message); + } catch { + // error.message must not be JSON + } } if ( From 033b529c17aa06736cdf4dc43fd201b2957249ac Mon Sep 17 00:00:00 2001 From: Nicholas Ellul Date: Wed, 10 May 2023 14:45:19 -0400 Subject: [PATCH 035/120] Fix script to build migrations by having it use the `.ts` template (#18878) * Fix script to build migrations * Validate version is a number --- development/generate-migration.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/development/generate-migration.sh b/development/generate-migration.sh index 0e08b9421..791563e3e 100755 --- a/development/generate-migration.sh +++ b/development/generate-migration.sh @@ -1,12 +1,24 @@ #! /bin/bash + +validate-number(){ + re='^[0-9]+$' + if [[ ! $1 =~ $re ]]; then + echo "Error: The value must be a number." >&2 + exit 1 + fi +} + g-migration() { [[ -z "$1" ]] && { echo "Migration version is required!" ; exit 1; } local vnum=$1 + + validate-number "$vnum" + if (($1 < 100)); then vnum=0$1 fi - touch app/scripts/migrations/"$vnum".js - cp app/scripts/migrations/template.js app/scripts/migrations/"$vnum".js + touch app/scripts/migrations/"$vnum".ts + cp app/scripts/migrations/template.ts app/scripts/migrations/"$vnum".ts touch app/scripts/migrations/"$vnum".test.js cp app/scripts/migrations/template.test.js app/scripts/migrations/"$vnum".test.js From d37d5bf0eebf5a28fbfe7f672842e5ce3bf9137a Mon Sep 17 00:00:00 2001 From: OGPoyraz Date: Thu, 11 May 2023 07:56:17 +0200 Subject: [PATCH 036/120] feat: Refactor Transaction Confirmation selector (#18796) --- app/scripts/background.js | 4 +- app/scripts/controllers/transactions/index.js | 25 +++++- .../controllers/transactions/index.test.js | 54 +++++++++++++ ui/helpers/utils/confirm-tx.util.ts | 17 ----- ui/pages/home/home.component.js | 10 +-- ui/pages/home/home.container.js | 8 +- ui/selectors/approvals.test.ts | 22 +++--- ui/selectors/approvals.ts | 20 ++++- ui/selectors/confirm-transaction.js | 44 ----------- ui/selectors/confirm-transaction.test.js | 28 ------- ui/selectors/transactions.js | 33 ++++++++ ui/selectors/transactions.test.js | 76 +++++++++++++++++++ ui/store/actions.ts | 4 +- 13 files changed, 229 insertions(+), 116 deletions(-) diff --git a/app/scripts/background.js b/app/scripts/background.js index 059b1bdd0..2b04d2cd8 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -713,7 +713,9 @@ export function setupController( // User Interface setup // - updateBadge(); + controller.txController.initApprovals().then(() => { + updateBadge(); + }); controller.txController.on( METAMASK_CONTROLLER_EVENTS.UPDATE_BADGE, updateBadge, diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index a3bad2f62..cd962e566 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -394,6 +394,22 @@ export default class TransactionController extends EventEmitter { }); } + /** + * Creates approvals for all unapproved transactions in the txStateManager. + * + * @returns {Promise} + */ + async initApprovals() { + const unapprovedTxs = this.txStateManager.getUnapprovedTxList(); + return Promise.all( + Object.values(unapprovedTxs).map((txMeta) => + this._requestApproval(txMeta, { + shouldShowRequest: false, + }), + ), + ); + } + // ==================================================================================================================================================== /** @@ -2646,13 +2662,16 @@ export default class TransactionController extends EventEmitter { ); } - _requestApproval(txMeta) { + async _requestApproval( + txMeta, + { shouldShowRequest } = { shouldShowRequest: true }, + ) { const id = this._getApprovalId(txMeta); const { origin } = txMeta; const type = ApprovalType.Transaction; const requestData = { txId: txMeta.id }; - this.messagingSystem + return this.messagingSystem .call( 'ApprovalController:addRequest', { @@ -2661,7 +2680,7 @@ export default class TransactionController extends EventEmitter { type, requestData, }, - true, + shouldShowRequest, ) .catch(() => { // Intentionally ignored as promise not currently used diff --git a/app/scripts/controllers/transactions/index.test.js b/app/scripts/controllers/transactions/index.test.js index 1203c6c58..02eb957da 100644 --- a/app/scripts/controllers/transactions/index.test.js +++ b/app/scripts/controllers/transactions/index.test.js @@ -2992,4 +2992,58 @@ describe('Transaction Controller', function () { assert.equal(result.type, TransactionType.simpleSend); }); }); + + describe('initApprovals', function () { + it('adds unapprovedTxs as approvals', async function () { + const firstTxId = '1'; + txController.addTransaction( + { + id: firstTxId, + origin: ORIGIN_METAMASK, + status: TransactionStatus.unapproved, + metamaskNetworkId: currentNetworkId, + txParams: { + to: VALID_ADDRESS, + from: VALID_ADDRESS_TWO, + }, + }, + noop, + ); + const secondTxId = '2'; + txController.addTransaction( + { + id: secondTxId, + origin: ORIGIN_METAMASK, + status: TransactionStatus.unapproved, + metamaskNetworkId: currentNetworkId, + txParams: { + to: VALID_ADDRESS, + from: VALID_ADDRESS_TWO, + }, + }, + noop, + ); + await txController.initApprovals(); + assert.deepEqual(messengerMock.call.getCall(0).args, [ + 'ApprovalController:addRequest', + { + id: firstTxId, + origin: ORIGIN_METAMASK, + requestData: { txId: firstTxId }, + type: ApprovalType.Transaction, + }, + false, + ]); + assert.deepEqual(messengerMock.call.getCall(1).args, [ + 'ApprovalController:addRequest', + { + id: secondTxId, + origin: ORIGIN_METAMASK, + requestData: { txId: secondTxId }, + type: ApprovalType.Transaction, + }, + false, + ]); + }); + }); }); diff --git a/ui/helpers/utils/confirm-tx.util.ts b/ui/helpers/utils/confirm-tx.util.ts index 4c4e0c4e0..a67a89dfb 100644 --- a/ui/helpers/utils/confirm-tx.util.ts +++ b/ui/helpers/utils/confirm-tx.util.ts @@ -2,7 +2,6 @@ import currencyFormatter from 'currency-formatter'; import currencies from 'currency-formatter/currencies'; import { BigNumber } from 'bignumber.js'; -import { unconfirmedTransactionsCountSelector } from '../../selectors'; import { Numeric } from '../../../shared/modules/Numeric'; import { EtherDenomination } from '../../../shared/constants/common'; import { TransactionMeta } from '../../../shared/constants/transaction'; @@ -86,22 +85,6 @@ export function convertTokenToFiat({ return tokenInFiat.round(2).toString(); } -/** - * This is a selector and probably doesn't belong here but its staying for now - * Note: I did not go so far as to type the entirety of the MetaMask state tree - * which definitely needs to be done for the full conversion of TypeScript to - * be successful and as useful as possible. - * TODO: Type the MetaMask state tree and use that type here. - * - * @param state - MetaMask state - * @returns true if there are unconfirmed transactions in state - */ -export function hasUnconfirmedTransactions( - state: Record, -): boolean { - return unconfirmedTransactionsCountSelector(state) > 0; -} - /** * Rounds the given decimal string to 4 significant digits. * diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index 01499fa6c..8b8206020 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -107,7 +107,7 @@ export default class Home extends PureComponent { history: PropTypes.object, forgottenPassword: PropTypes.bool, hasWatchAssetPendingApprovals: PropTypes.bool, - unconfirmedTransactionsCount: PropTypes.number, + hasTransactionPendingApprovals: PropTypes.bool.isRequired, shouldShowSeedPhraseReminder: PropTypes.bool.isRequired, isPopup: PropTypes.bool, isNotification: PropTypes.bool.isRequired, @@ -197,7 +197,7 @@ export default class Home extends PureComponent { showAwaitingSwapScreen, hasWatchAssetPendingApprovals, swapsFetchParams, - unconfirmedTransactionsCount, + hasTransactionPendingApprovals, } = this.props; if (shouldCloseNotificationPopup(props)) { @@ -205,7 +205,7 @@ export default class Home extends PureComponent { closeNotificationPopup(); } else if ( firstPermissionsRequestId || - unconfirmedTransactionsCount > 0 || + hasTransactionPendingApprovals || hasWatchAssetPendingApprovals || (!isNotification && (showAwaitingSwapScreen || haveSwapsQuotes || swapsFetchParams)) @@ -269,7 +269,7 @@ export default class Home extends PureComponent { history, isNotification, hasWatchAssetPendingApprovals, - unconfirmedTransactionsCount, + hasTransactionPendingApprovals, haveSwapsQuotes, showAwaitingSwapScreen, swapsFetchParams, @@ -288,7 +288,7 @@ export default class Home extends PureComponent { history.push(BUILD_QUOTE_ROUTE); } else if (firstPermissionsRequestId) { history.push(`${CONNECT_ROUTE}/${firstPermissionsRequestId}`); - } else if (unconfirmedTransactionsCount > 0) { + } else if (hasTransactionPendingApprovals) { history.push(CONFIRM_TRANSACTION_ROUTE); } else if (hasWatchAssetPendingApprovals) { history.push(CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE); diff --git a/ui/pages/home/home.container.js b/ui/pages/home/home.container.js index 8d4db31e5..ce1931476 100644 --- a/ui/pages/home/home.container.js +++ b/ui/pages/home/home.container.js @@ -22,7 +22,6 @@ import { getTotalUnapprovedCount, getUnapprovedTemplatedConfirmations, getWeb3ShimUsageStateForOrigin, - unconfirmedTransactionsCountSelector, getInfuraBlocked, getShowWhatsNewPopup, getSortedAnnouncementsToShow, @@ -36,7 +35,7 @@ import { getNewTokensImported, getShouldShowSeedPhraseReminder, getRemoveNftMessage, - hasPendingApprovalsSelector, + hasPendingApprovals, } from '../../selectors'; import { @@ -71,6 +70,7 @@ import { AlertTypes, Web3ShimUsageAlertStates, } from '../../../shared/constants/alerts'; +import { hasTransactionPendingApprovals } from '../../selectors/transactions'; import Home from './home.component'; const mapStateToProps = (state) => { @@ -121,7 +121,7 @@ const mapStateToProps = (state) => { hasUnsignedQRHardwareTransaction(state) || hasUnsignedQRHardwareMessage(state); - const hasWatchAssetPendingApprovals = hasPendingApprovalsSelector( + const hasWatchAssetPendingApprovals = hasPendingApprovals( state, ApprovalType.WatchAsset, ); @@ -130,7 +130,7 @@ const mapStateToProps = (state) => { forgottenPassword, hasWatchAssetPendingApprovals, swapsEnabled, - unconfirmedTransactionsCount: unconfirmedTransactionsCountSelector(state), + hasTransactionPendingApprovals: hasTransactionPendingApprovals(state), shouldShowSeedPhraseReminder: getShouldShowSeedPhraseReminder(state), isPopup, isNotification, diff --git a/ui/selectors/approvals.test.ts b/ui/selectors/approvals.test.ts index 384d4d1be..44923b416 100644 --- a/ui/selectors/approvals.test.ts +++ b/ui/selectors/approvals.test.ts @@ -1,10 +1,10 @@ import { ApprovalType } from '@metamask/controller-utils'; -import { hasPendingApprovalsSelector } from './approvals'; +import { hasPendingApprovals } from './approvals'; describe('approval selectors', () => { const mockedState = { metamask: { - pendingApprovalCount: 2, + pendingApprovalCount: 3, pendingApprovals: { '1': { id: '1', @@ -18,28 +18,30 @@ describe('approval selectors', () => { id: '2', origin: 'origin', time: Date.now(), - type: ApprovalType.EthSignTypedData, + type: ApprovalType.Transaction, requestData: {}, requestState: null, }, }, + unapprovedTxs: { + '2': { + id: '2', + }, + }, }, }; - describe('hasPendingApprovalsSelector', () => { + describe('hasPendingApprovals', () => { it('should return true if there is a pending approval request', () => { - const result = hasPendingApprovalsSelector( - mockedState, - ApprovalType.WatchAsset, - ); + const result = hasPendingApprovals(mockedState, ApprovalType.WatchAsset); expect(result).toBe(true); }); it('should return false if there is no pending approval request', () => { - const result = hasPendingApprovalsSelector( + const result = hasPendingApprovals( mockedState, - ApprovalType.Transaction, + ApprovalType.SnapDialogPrompt, ); expect(result).toBe(false); diff --git a/ui/selectors/approvals.ts b/ui/selectors/approvals.ts index f777185df..408ed8918 100644 --- a/ui/selectors/approvals.ts +++ b/ui/selectors/approvals.ts @@ -1,19 +1,35 @@ import { ApprovalControllerState } from '@metamask/approval-controller'; import { ApprovalType } from '@metamask/controller-utils'; +import { TransactionMeta } from '../../shared/constants/transaction'; type ApprovalsMetaMaskState = { metamask: { pendingApprovals: ApprovalControllerState['pendingApprovals']; + unapprovedTxs: { + [transactionId: string]: TransactionMeta; + }; }; }; -export function hasPendingApprovalsSelector( +export const getApprovalRequestsByType = ( state: ApprovalsMetaMaskState, approvalType: ApprovalType, -) { +) => { const pendingApprovalRequests = Object.values( state.metamask.pendingApprovals, ).filter(({ type }) => type === approvalType); + return pendingApprovalRequests; +}; + +export function hasPendingApprovals( + state: ApprovalsMetaMaskState, + approvalType: ApprovalType, +) { + const pendingApprovalRequests = getApprovalRequestsByType( + state, + approvalType, + ); + return pendingApprovalRequests.length > 0; } diff --git a/ui/selectors/confirm-transaction.js b/ui/selectors/confirm-transaction.js index 3b3e7b137..349750192 100644 --- a/ui/selectors/confirm-transaction.js +++ b/ui/selectors/confirm-transaction.js @@ -142,50 +142,6 @@ export const unconfirmedMessagesHashSelector = createSelector( }, ); -const unapprovedMsgCountSelector = (state) => state.metamask.unapprovedMsgCount; -const unapprovedPersonalMsgCountSelector = (state) => - state.metamask.unapprovedPersonalMsgCount; -const unapprovedDecryptMsgCountSelector = (state) => - state.metamask.unapprovedDecryptMsgCount; -const unapprovedEncryptionPublicKeyMsgCountSelector = (state) => - state.metamask.unapprovedEncryptionPublicKeyMsgCount; -const unapprovedTypedMessagesCountSelector = (state) => - state.metamask.unapprovedTypedMessagesCount; - -export const unconfirmedTransactionsCountSelector = createSelector( - unapprovedTxsSelector, - unapprovedMsgCountSelector, - unapprovedPersonalMsgCountSelector, - unapprovedDecryptMsgCountSelector, - unapprovedEncryptionPublicKeyMsgCountSelector, - unapprovedTypedMessagesCountSelector, - deprecatedGetCurrentNetworkId, - getCurrentChainId, - ( - unapprovedTxs = {}, - unapprovedMsgCount = 0, - unapprovedPersonalMsgCount = 0, - unapprovedDecryptMsgCount = 0, - unapprovedEncryptionPublicKeyMsgCount = 0, - unapprovedTypedMessagesCount = 0, - network, - chainId, - ) => { - const filteredUnapprovedTxIds = Object.keys(unapprovedTxs).filter((txId) => - transactionMatchesNetwork(unapprovedTxs[txId], chainId, network), - ); - - return ( - filteredUnapprovedTxIds.length + - unapprovedTypedMessagesCount + - unapprovedMsgCount + - unapprovedPersonalMsgCount + - unapprovedDecryptMsgCount + - unapprovedEncryptionPublicKeyMsgCount - ); - }, -); - export const currentCurrencySelector = (state) => state.metamask.currentCurrency; export const conversionRateSelector = (state) => state.metamask.conversionRate; diff --git a/ui/selectors/confirm-transaction.test.js b/ui/selectors/confirm-transaction.test.js index e0f7c9c6f..653301265 100644 --- a/ui/selectors/confirm-transaction.test.js +++ b/ui/selectors/confirm-transaction.test.js @@ -1,7 +1,5 @@ -import { CHAIN_IDS } from '../../shared/constants/network'; import { TransactionType } from '../../shared/constants/transaction'; import { - unconfirmedTransactionsCountSelector, sendTokenTokenAmountAndToAddressSelector, contractExchangeRateSelector, conversionRateSelector, @@ -17,32 +15,6 @@ const getEthersArrayLikeFromObj = (obj) => { }; describe('Confirm Transaction Selector', () => { - describe('unconfirmedTransactionsCountSelector', () => { - const state = { - metamask: { - unapprovedTxs: { - 1: { - metamaskNetworkId: '5', - }, - 2: { - chainId: CHAIN_IDS.MAINNET, - }, - }, - unapprovedMsgCount: 1, - unapprovedPersonalMsgCount: 1, - unapprovedTypedMessagesCount: 1, - networkId: '5', - providerConfig: { - chainId: '0x5', - }, - }, - }; - - it('returns number of txs in unapprovedTxs state with the same network plus unapproved signing method counts', () => { - expect(unconfirmedTransactionsCountSelector(state)).toStrictEqual(4); - }); - }); - describe('sendTokenTokenAmountAndToAddressSelector', () => { const state = { confirmTransaction: { diff --git a/ui/selectors/transactions.js b/ui/selectors/transactions.js index 63e72d8c2..1b2a07dc7 100644 --- a/ui/selectors/transactions.js +++ b/ui/selectors/transactions.js @@ -1,4 +1,5 @@ import { createSelector } from 'reselect'; +import { ApprovalType } from '@metamask/controller-utils'; import { PRIORITY_STATUS_HASH, PENDING_STATUS_HASH, @@ -17,6 +18,7 @@ import { deprecatedGetCurrentNetworkId, getSelectedAddress, } from './selectors'; +import { hasPendingApprovals, getApprovalRequestsByType } from './approvals'; const INVALID_INITIAL_TRANSACTION_TYPES = [ TransactionType.cancel, @@ -534,3 +536,34 @@ export const submittedPendingTransactionsSelector = createSelector( (transaction) => transaction.status === TransactionStatus.submitted, ), ); + +const hasUnapprovedTransactionsInCurrentNetwork = (state) => { + const { unapprovedTxs } = state.metamask; + const unapprovedTxRequests = getApprovalRequestsByType( + state, + ApprovalType.Transaction, + ); + + const chainId = getCurrentChainId(state); + + const filteredUnapprovedTxInCurrentNetwork = unapprovedTxRequests.filter( + ({ id }) => transactionMatchesNetwork(unapprovedTxs[id], chainId), + ); + + return filteredUnapprovedTxInCurrentNetwork.length > 0; +}; + +const TRANSACTION_APPROVAL_TYPES = [ + ApprovalType.EthDecrypt, + ApprovalType.EthGetEncryptionPublicKey, + ApprovalType.EthSign, + ApprovalType.EthSignTypedData, + ApprovalType.PersonalSign, +]; + +export function hasTransactionPendingApprovals(state) { + return ( + hasUnapprovedTransactionsInCurrentNetwork(state) || + TRANSACTION_APPROVAL_TYPES.some((type) => hasPendingApprovals(state, type)) + ); +} diff --git a/ui/selectors/transactions.test.js b/ui/selectors/transactions.test.js index 02227c410..30d48efcc 100644 --- a/ui/selectors/transactions.test.js +++ b/ui/selectors/transactions.test.js @@ -1,3 +1,4 @@ +import { ApprovalType } from '@metamask/controller-utils'; import { CHAIN_IDS } from '../../shared/constants/network'; import { TransactionStatus } from '../../shared/constants/transaction'; import { @@ -7,6 +8,7 @@ import { nonceSortedPendingTransactionsSelector, nonceSortedCompletedTransactionsSelector, submittedPendingTransactionsSelector, + hasTransactionPendingApprovals, } from './transactions'; describe('Transaction Selectors', () => { @@ -329,4 +331,78 @@ describe('Transaction Selectors', () => { ); }); }); + + describe('hasTransactionPendingApprovals', () => { + const mockNetworkId = 'mockNetworkId'; + const mockedState = { + metamask: { + providerConfig: { + chainId: mockNetworkId, + }, + pendingApprovalCount: 2, + pendingApprovals: { + 1: { + id: '1', + origin: 'origin', + time: Date.now(), + type: ApprovalType.WatchAsset, + requestData: {}, + requestState: null, + }, + 2: { + id: '2', + origin: 'origin', + time: Date.now(), + type: ApprovalType.Transaction, + requestData: {}, + requestState: null, + }, + }, + unapprovedTxs: { + 2: { + id: '2', + chainId: mockNetworkId, + }, + }, + }, + }; + + it('should return true if there is a pending transaction on same network', () => { + const result = hasTransactionPendingApprovals(mockedState); + expect(result).toBe(true); + }); + it('should return false if there is a pending transaction on different network', () => { + mockedState.metamask.unapprovedTxs['2'].chainId = 'differentNetworkId'; + const result = hasTransactionPendingApprovals(mockedState); + expect(result).toBe(false); + }); + it.each([ + [ApprovalType.EthDecrypt], + [ApprovalType.EthGetEncryptionPublicKey], + [ApprovalType.EthSign], + [ApprovalType.EthSignTypedData], + [ApprovalType.PersonalSign], + ])( + 'should return true if there is a pending transaction of %s type', + (type) => { + const result = hasTransactionPendingApprovals({ + ...mockedState, + metamask: { + ...mockedState.metamask, + pendingApprovals: { + 2: { + id: '2', + origin: 'origin', + time: Date.now(), + type, + requestData: {}, + requestState: null, + }, + }, + }, + }); + expect(result).toBe(true); + }, + ); + }); }); diff --git a/ui/store/actions.ts b/ui/store/actions.ts index a923bca0f..845540969 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -23,12 +23,12 @@ import { POLLING_TOKEN_ENVIRONMENT_TYPES, MESSAGE_TYPE, } from '../../shared/constants/app'; -import { hasUnconfirmedTransactions } from '../helpers/utils/confirm-tx.util'; import { getEnvironmentType, addHexPrefix } from '../../app/scripts/lib/util'; import { getMetaMaskAccounts, getPermittedAccountsForCurrentTab, getSelectedAddress, + hasTransactionPendingApprovals, ///: BEGIN:ONLY_INCLUDE_IN(snaps) getNotifications, ///: END:ONLY_INCLUDE_IN @@ -2698,7 +2698,7 @@ export function closeCurrentNotificationWindow(): ThunkAction< return (_, getState) => { if ( getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION && - !hasUnconfirmedTransactions(getState()) + !hasTransactionPendingApprovals(getState()) ) { closeNotificationPopup(); } From 37a2be0fbb796606067b38846bf540869f2c116f Mon Sep 17 00:00:00 2001 From: OGPoyraz Date: Thu, 11 May 2023 10:22:42 +0200 Subject: [PATCH 037/120] Add `getCurrentChainId` argument to `SignatureController` (#19078) --- app/scripts/metamask-controller.js | 2 ++ lavamoat/browserify/beta/policy.json | 1 + lavamoat/browserify/desktop/policy.json | 1 + lavamoat/browserify/flask/policy.json | 1 + lavamoat/browserify/main/policy.json | 1 + lavamoat/build-system/policy.json | 12 ++++-------- package.json | 4 ++-- yarn.lock | 22 +++++++++++----------- 8 files changed, 23 insertions(+), 21 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 60dae3130..8378cb02a 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1210,6 +1210,8 @@ export default class MetamaskController extends EventEmitter { ?.disabledRpcMethodPreferences?.eth_sign, getAllState: this.getState.bind(this), securityProviderRequest: this.securityProviderRequest.bind(this), + getCurrentChainId: () => + this.networkController.store.getState().providerConfig.chainId, }); this.signatureController.hub.on('cancelWithReason', (message, reason) => { diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 7504336d4..bff7adb06 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -4293,6 +4293,7 @@ }, "packages": { "browserify>process": true, + "browserify>util": true, "semver>lru-cache": true } }, diff --git a/lavamoat/browserify/desktop/policy.json b/lavamoat/browserify/desktop/policy.json index e3184f749..c5eee11b6 100644 --- a/lavamoat/browserify/desktop/policy.json +++ b/lavamoat/browserify/desktop/policy.json @@ -4859,6 +4859,7 @@ }, "packages": { "browserify>process": true, + "browserify>util": true, "semver>lru-cache": true } }, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index e3184f749..c5eee11b6 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -4859,6 +4859,7 @@ }, "packages": { "browserify>process": true, + "browserify>util": true, "semver>lru-cache": true } }, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 7504336d4..bff7adb06 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -4293,6 +4293,7 @@ }, "packages": { "browserify>process": true, + "browserify>util": true, "semver>lru-cache": true } }, diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json index 49711a209..fd2759c0b 100644 --- a/lavamoat/build-system/policy.json +++ b/lavamoat/build-system/policy.json @@ -6799,6 +6799,9 @@ } }, "semver": { + "builtin": { + "util.inspect": true + }, "globals": { "console.error": true, "process": true @@ -7990,14 +7993,7 @@ }, "globals": { "console.warn": true, - "process.env.BROWSERSLIST": true, - "process.env.BROWSERSLIST_CONFIG": true, - "process.env.BROWSERSLIST_DANGEROUS_EXTEND": true, - "process.env.BROWSERSLIST_DISABLE_CACHE": true, - "process.env.BROWSERSLIST_ENV": true, - "process.env.BROWSERSLIST_IGNORE_OLD_DATA": true, - "process.env.BROWSERSLIST_STATS": true, - "process.env.NODE_ENV": true, + "process.env": true, "process.versions.node": true }, "packages": { diff --git a/package.json b/package.json index 8ea8817b3..5c2920ed6 100644 --- a/package.json +++ b/package.json @@ -253,7 +253,7 @@ "@metamask/jazzicon": "^2.0.0", "@metamask/key-tree": "^7.0.0", "@metamask/logo": "^3.1.1", - "@metamask/message-manager": "^4.0.0", + "@metamask/message-manager": "^5.0.0", "@metamask/metamask-eth-abis": "^3.0.0", "@metamask/notification-controller": "^2.0.0", "@metamask/obs-store": "^8.1.0", @@ -266,7 +266,7 @@ "@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.32.2", "@metamask/safe-event-emitter": "^2.0.0", "@metamask/scure-bip39": "^2.0.3", - "@metamask/signature-controller": "^1.0.0", + "@metamask/signature-controller": "^2.0.0", "@metamask/slip44": "^3.0.0", "@metamask/smart-transactions-controller": "^3.1.0", "@metamask/snaps-controllers": "^0.32.2", diff --git a/yarn.lock b/yarn.lock index 6c4da2694..773754267 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4078,9 +4078,9 @@ __metadata: languageName: node linkType: hard -"@metamask/message-manager@npm:^4.0.0": - version: 4.0.0 - resolution: "@metamask/message-manager@npm:4.0.0" +"@metamask/message-manager@npm:^5.0.0": + version: 5.0.0 + resolution: "@metamask/message-manager@npm:5.0.0" dependencies: "@metamask/base-controller": ^2.0.0 "@metamask/controller-utils": ^3.4.0 @@ -4089,7 +4089,7 @@ __metadata: ethereumjs-util: ^7.0.10 jsonschema: ^1.2.4 uuid: ^8.3.2 - checksum: 9c3295a726eb59c2cc3f764b96010833edf2463e2dd3ee0a4d23ea6bf662615b3bd71110a5c6b60f253eac1de6c8b38af1edc0188ec766770a9d02c0f7401caa + checksum: 078c7eeca03975c3a899dcaa7485ce7aaff6d97b53c2a8e8563ec4e17791b836914fbc0f57a64cbf263be231609e0ffc77eabbe9a98fdcc1240af09a733ba574 languageName: node linkType: hard @@ -4345,18 +4345,18 @@ __metadata: languageName: node linkType: hard -"@metamask/signature-controller@npm:^1.0.0": - version: 1.0.0 - resolution: "@metamask/signature-controller@npm:1.0.0" +"@metamask/signature-controller@npm:^2.0.0": + version: 2.0.0 + resolution: "@metamask/signature-controller@npm:2.0.0" dependencies: "@metamask/approval-controller": ^2.1.1 "@metamask/base-controller": ^2.0.0 "@metamask/controller-utils": ^3.4.0 - "@metamask/message-manager": ^4.0.0 + "@metamask/message-manager": ^5.0.0 eth-rpc-errors: ^4.0.2 ethereumjs-util: ^7.0.10 immer: ^9.0.6 - checksum: 7efb738646a179db15c45d6e1654e17ce6c7a3e42b03fd27d365e50bb2e4287a1757f26efc0b3e99b3e5d320816f3f9e0c7038491289cf6071b7f886eaa0f27b + checksum: aa7a37079cb108bd9dcb23292f82690b6796b3cde5a2b841db7f636fa9f19a5eaaa8eea7461d757dcfd664d1a6a5da3af8ea25a402c6fe575c3204390ff3964f languageName: node linkType: hard @@ -24080,7 +24080,7 @@ __metadata: "@metamask/jazzicon": ^2.0.0 "@metamask/key-tree": ^7.0.0 "@metamask/logo": ^3.1.1 - "@metamask/message-manager": ^4.0.0 + "@metamask/message-manager": ^5.0.0 "@metamask/metamask-eth-abis": ^3.0.0 "@metamask/notification-controller": ^2.0.0 "@metamask/obs-store": ^8.1.0 @@ -24094,7 +24094,7 @@ __metadata: "@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.32.2" "@metamask/safe-event-emitter": ^2.0.0 "@metamask/scure-bip39": ^2.0.3 - "@metamask/signature-controller": ^1.0.0 + "@metamask/signature-controller": ^2.0.0 "@metamask/slip44": ^3.0.0 "@metamask/smart-transactions-controller": ^3.1.0 "@metamask/snaps-controllers": ^0.32.2 From d859181029fa1782ff813a73fec71aac65009d27 Mon Sep 17 00:00:00 2001 From: OGPoyraz Date: Thu, 11 May 2023 16:40:51 +0200 Subject: [PATCH 038/120] fix: use approvals selector fn in permission selectors (#19095) --- ui/selectors/permissions.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ui/selectors/permissions.js b/ui/selectors/permissions.js index dfc2a83e7..fd7ac5767 100644 --- a/ui/selectors/permissions.js +++ b/ui/selectors/permissions.js @@ -1,7 +1,9 @@ +import { ApprovalType } from '@metamask/controller-utils'; ///: BEGIN:ONLY_INCLUDE_IN(snaps) import { WALLET_SNAP_PERMISSION_KEY } from '@metamask/rpc-methods'; ///: END:ONLY_INCLUDE_IN import { CaveatTypes } from '../../shared/constants/permissions'; +import { getApprovalRequestsByType } from './approvals'; import { getMetaMaskAccountsOrdered, getOriginOfCurrentTab, @@ -341,9 +343,10 @@ export function getFirstSnapInstallOrUpdateRequest(state) { ///: END:ONLY_INCLUDE_IN export function getPermissionsRequests(state) { - return Object.values(state.metamask.pendingApprovals) - .filter(({ type }) => type === 'wallet_requestPermissions') - .map(({ requestData }) => requestData); + return getApprovalRequestsByType( + state, + ApprovalType.WalletRequestPermissions, + ).map(({ requestData }) => requestData); } export function getFirstPermissionRequest(state) { From be8d8324261858d71b7a1aaffdaa4f8e216830d8 Mon Sep 17 00:00:00 2001 From: Bowen Sanders Date: Thu, 11 May 2023 12:43:08 -0700 Subject: [PATCH 039/120] [FLASK] Create E2E test for snap_GetEntropy (#18998) --- test/e2e/snaps/enums.js | 2 +- test/e2e/snaps/test-snap-getentropy.spec.js | 108 ++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 test/e2e/snaps/test-snap-getentropy.spec.js diff --git a/test/e2e/snaps/enums.js b/test/e2e/snaps/enums.js index 0835e9241..8a0079ed0 100644 --- a/test/e2e/snaps/enums.js +++ b/test/e2e/snaps/enums.js @@ -1,3 +1,3 @@ module.exports = { - TEST_SNAPS_WEBSITE_URL: 'https://metamask.github.io/test-snaps/5.2.0/', + TEST_SNAPS_WEBSITE_URL: 'https://metamask.github.io/test-snaps/5.3.0/', }; diff --git a/test/e2e/snaps/test-snap-getentropy.spec.js b/test/e2e/snaps/test-snap-getentropy.spec.js new file mode 100644 index 000000000..c29da48d1 --- /dev/null +++ b/test/e2e/snaps/test-snap-getentropy.spec.js @@ -0,0 +1,108 @@ +const { withFixtures } = require('../helpers'); +const FixtureBuilder = require('../fixture-builder'); +const { TEST_SNAPS_WEBSITE_URL } = require('./enums'); + +describe('Test Snap getEntropy', function () { + it('can use snap_getEntropy inside a snap', async function () { + const ganacheOptions = { + accounts: [ + { + secretKey: + '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: 25000000000000000000, + }, + ], + }; + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions, + failOnConsoleError: false, + title: this.test.title, + }, + async ({ driver }) => { + await driver.navigate(); + + // enter pw into extension + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + // navigate to test snaps page and connect + await driver.driver.get(TEST_SNAPS_WEBSITE_URL); + await driver.delay(1000); + const snapButton = await driver.findElement('#connectGetEntropySnap'); + await driver.scrollToElement(snapButton); + await driver.delay(1000); + await driver.clickElement('#connectGetEntropySnap'); + await driver.delay(1000); + + // switch to metamask extension and click connect + let windowHandles = await driver.waitUntilXWindowHandles( + 2, + 1000, + 10000, + ); + await driver.switchToWindowWithTitle( + 'MetaMask Notification', + windowHandles, + ); + await driver.clickElement({ + text: 'Connect', + tag: 'button', + }); + + await driver.waitForSelector({ text: 'Approve & install' }); + + await driver.clickElement({ + text: 'Approve & install', + tag: 'button', + }); + + await driver.waitForSelector({ text: 'Ok' }); + + await driver.clickElement({ + text: 'Ok', + tag: 'button', + }); + + // click send inputs on test snap page + await driver.switchToWindowWithTitle('Test Snaps', windowHandles); + + // wait for npm installation success + await driver.waitForSelector({ + css: '#connectGetEntropySnap', + text: 'Reconnect to getEntropy Snap', + }); + + // find and click on send test + await driver.pasteIntoField('#entropyMessage', '1234'); + await driver.delay(500); + const snapButton2 = await driver.findElement('#signEntropyMessage'); + await driver.scrollToElement(snapButton2); + await driver.delay(500); + await driver.clickElement('#signEntropyMessage'); + + // Switch to approve signature message window and approve + windowHandles = await driver.waitUntilXWindowHandles(2, 1000, 10000); + await driver.switchToWindowWithTitle( + 'MetaMask Notification', + windowHandles, + ); + await driver.clickElement({ + text: 'Approve', + tag: 'button', + }); + + // switch back to test-snaps page + windowHandles = await driver.waitUntilXWindowHandles(1, 1000, 10000); + await driver.switchToWindowWithTitle('Test Snaps', windowHandles); + + // check the results of the message signature using waitForSelector + await driver.waitForSelector({ + css: '#entropySignResult', + text: '"0xb9c20d675976e12c8bb53c3fd8fdff2dee11ad2b132eb453b5a8f35b0553c52d3bcac0fd3324d22ff0c53b3445ef48c119ba6435bc9bfb03234806719599aa6f6245593238c734bcf9d94d2873cacdd65a3176be3ae7e5b84f95fdd4487a395f"', + }); + }, + ); + }); +}); From 578f73b2eacdee89c25763bf9fbd973864d32e83 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Fri, 12 May 2023 12:31:15 -0230 Subject: [PATCH 040/120] Ensure the GasDetailsItem component can handle a tx with a maxPriorityFee of 0 (#19102) * Ensure the GasDetailsItem component can handle a tx with a maxPriorityFee of 0 * Clean up code * Update ui/components/app/gas-details-item/gas-details-item.js Co-authored-by: Mark Stacey --------- Co-authored-by: Mark Stacey --- .../app/gas-details-item/gas-details-item.js | 20 ++++++---- .../gas-details-item/gas-details-item.test.js | 39 +++++++++++++++++++ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/ui/components/app/gas-details-item/gas-details-item.js b/ui/components/app/gas-details-item/gas-details-item.js index 08a021451..a7acc35af 100644 --- a/ui/components/app/gas-details-item/gas-details-item.js +++ b/ui/components/app/gas-details-item/gas-details-item.js @@ -50,6 +50,16 @@ const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => { return null; } + const maxPriorityFeePerGasToRender = ( + maxPriorityFeePerGas ?? + hexWEIToDecGWEI(transactionData.txParams?.maxPriorityFeePerGas ?? '0x0') + ).toString(); + + const maxFeePerGasToRender = ( + maxFeePerGas ?? + hexWEIToDecGWEI(transactionData.txParams?.maxFeePerGas ?? '0x0') + ).toString(); + return ( { } subTitle={ } /> diff --git a/ui/components/app/gas-details-item/gas-details-item.test.js b/ui/components/app/gas-details-item/gas-details-item.test.js index 4885f9068..9b61c28ce 100644 --- a/ui/components/app/gas-details-item/gas-details-item.test.js +++ b/ui/components/app/gas-details-item/gas-details-item.test.js @@ -110,4 +110,43 @@ describe('GasDetailsItem', () => { expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0); }); }); + + it('should render gas fee details if maxPriorityFeePerGas is 0', async () => { + render({ + contextProps: { + transaction: { + txParams: { + gas: '0x5208', + maxFeePerGas: '0x59682f10', + maxPriorityFeePerGas: '0', + }, + simulationFails: false, + userFeeLevel: 'low', + }, + }, + }); + await waitFor(() => { + expect(screen.queryAllByTitle('0.0000315 ETH').length).toBeGreaterThan(0); + expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0); + }); + }); + + it('should render gas fee details if maxPriorityFeePerGas is undefined', async () => { + render({ + contextProps: { + transaction: { + txParams: { + gas: '0x5208', + maxFeePerGas: '0x59682f10', + }, + simulationFails: false, + userFeeLevel: 'low', + }, + }, + }); + await waitFor(() => { + expect(screen.queryAllByTitle('0.0000315 ETH').length).toBeGreaterThan(0); + expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0); + }); + }); }); From aa9ee8af6cb0a44f9510f5c2879f6e97ae6ce925 Mon Sep 17 00:00:00 2001 From: Ariella Vu <20778143+digiwand@users.noreply.github.com> Date: Fri, 12 May 2023 13:27:25 -0500 Subject: [PATCH 041/120] Update useDraftTransactionGasValues (#19105) * useDraftTransactionGasValues: update return value * rn useDraftTransactionGasValues -> useDraftTransactionWithTxParams --- .../confirm-legacy-gas-display.js | 4 ++-- ui/components/app/gas-details-item/gas-details-item.js | 4 ++-- ...tionGasValues.js => useDraftTransactionWithTxParams.js} | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) rename ui/hooks/{useDraftTransactionGasValues.js => useDraftTransactionWithTxParams.js} (92%) diff --git a/ui/components/app/confirm-gas-display/confirm-legacy-gas-display/confirm-legacy-gas-display.js b/ui/components/app/confirm-gas-display/confirm-legacy-gas-display/confirm-legacy-gas-display.js index c09ad91ac..124fbb0d9 100644 --- a/ui/components/app/confirm-gas-display/confirm-legacy-gas-display/confirm-legacy-gas-display.js +++ b/ui/components/app/confirm-gas-display/confirm-legacy-gas-display/confirm-legacy-gas-display.js @@ -23,7 +23,7 @@ import { TextVariant, TextColor, } from '../../../../helpers/constants/design-system'; -import { useDraftTransactionGasValues } from '../../../../hooks/useDraftTransactionGasValues'; +import { useDraftTransactionWithTxParams } from '../../../../hooks/useDraftTransactionWithTxParams'; import { getNativeCurrency } from '../../../../ducks/metamask/metamask'; import MultilayerFeeMessage from '../../multilayer-fee-message/multi-layer-fee-message'; import { Icon, IconName } from '../../../component-library'; @@ -41,7 +41,7 @@ const ConfirmLegacyGasDisplay = () => { const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences); const nativeCurrency = useSelector(getNativeCurrency); const unapprovedTxs = useSelector(getUnapprovedTransactions); - const { transactionData } = useDraftTransactionGasValues(); + const transactionData = useDraftTransactionWithTxParams(); const txData = useSelector((state) => txDataSelector(state)); const { id: transactionId, dappSuggestedGasFees } = txData; const transaction = Object.keys(transactionData).length diff --git a/ui/components/app/gas-details-item/gas-details-item.js b/ui/components/app/gas-details-item/gas-details-item.js index a7acc35af..cc716900d 100644 --- a/ui/components/app/gas-details-item/gas-details-item.js +++ b/ui/components/app/gas-details-item/gas-details-item.js @@ -20,13 +20,13 @@ import GasTiming from '../gas-timing/gas-timing.component'; import TransactionDetailItem from '../transaction-detail-item/transaction-detail-item.component'; import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'; import { hexWEIToDecGWEI } from '../../../../shared/modules/conversion.utils'; -import { useDraftTransactionGasValues } from '../../../hooks/useDraftTransactionGasValues'; +import { useDraftTransactionWithTxParams } from '../../../hooks/useDraftTransactionWithTxParams'; import GasDetailsItemTitle from './gas-details-item-title'; const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => { const t = useI18nContext(); const draftTransaction = useSelector(getCurrentDraftTransaction); - const { transactionData } = useDraftTransactionGasValues(); + const transactionData = useDraftTransactionWithTxParams(); const { hexMinimumTransactionFee: draftHexMinimumTransactionFee, diff --git a/ui/hooks/useDraftTransactionGasValues.js b/ui/hooks/useDraftTransactionWithTxParams.js similarity index 92% rename from ui/hooks/useDraftTransactionGasValues.js rename to ui/hooks/useDraftTransactionWithTxParams.js index b94a8b816..7e822f18e 100644 --- a/ui/hooks/useDraftTransactionGasValues.js +++ b/ui/hooks/useDraftTransactionWithTxParams.js @@ -8,13 +8,14 @@ import { getUnapprovedTransactions } from '../selectors'; * the gas data from draftTransaction and unapprovedTx has to be reorganized * to mimic the txdata.txParam from a confirmTransaction * - * @returns {Object txData.txParams} + * @returns {object} The transaction data */ -export const useDraftTransactionGasValues = () => { +export const useDraftTransactionWithTxParams = () => { const draftTransaction = useSelector(getCurrentDraftTransaction); const unapprovedTxs = useSelector(getUnapprovedTransactions); let transactionData = {}; + if (Object.keys(draftTransaction).length !== 0) { const editingTransaction = unapprovedTxs[draftTransaction.id]; transactionData = { @@ -36,5 +37,5 @@ export const useDraftTransactionGasValues = () => { }; } - return { transactionData }; + return transactionData; }; From 5b5e5d222fba8ac66d6ef9f3e65df269546adb75 Mon Sep 17 00:00:00 2001 From: Dan Finlay <542863+danfinlay@users.noreply.github.com> Date: Mon, 15 May 2023 02:39:48 -0700 Subject: [PATCH 042/120] Skip injection on snaps iframe (#19096) * skip injection on snaps iframe * escape periods from regex block list These values are used as regex inputs, so plain periods are wild characters, and mean these can be interpreted as more domains than intended. * remove period escaping It's already escaped below. Whoops! Bad AI advice! --- shared/modules/provider-injection.js | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/modules/provider-injection.js b/shared/modules/provider-injection.js index c4d741823..1fff08854 100644 --- a/shared/modules/provider-injection.js +++ b/shared/modules/provider-injection.js @@ -65,6 +65,7 @@ function documentElementCheck() { */ function blockedDomainCheck() { const blockedDomains = [ + 'execution.metamask.io', 'uscourts.gov', 'dropbox.com', 'webbyawards.com', From f95320d03ea2eedd1c250a1c934a0ecce66112fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Oliv=C3=A9?= Date: Mon, 15 May 2023 13:38:54 +0200 Subject: [PATCH 043/120] [MMI] Started adding styles imports with code fences (#17943) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Started adding styles imports with code fences * FIxed prettier issues * removed fences since they dont do anything * Update ui/components/ui/ui-components.scss Co-authored-by: Frederik Bolding --------- Co-authored-by: Antonio Regadas Co-authored-by: António Regadas Co-authored-by: Frederik Bolding --- ui/components/app/app-components.scss | 4 ++-- ui/components/app/app-header/index.scss | 2 -- .../custody-labels/{custody-labels.scss => index.scss} | 0 ...ractive-replacement-token-notification.scss => index.scss} | 0 ui/components/ui/ui-components.scss | 3 ++- ui/css/index.scss | 2 -- ui/pages/pages.scss | 4 ++-- 7 files changed, 6 insertions(+), 9 deletions(-) rename ui/components/institutional/custody-labels/{custody-labels.scss => index.scss} (100%) rename ui/components/institutional/interactive-replacement-token-notification/{interactive-replacement-token-notification.scss => index.scss} (100%) diff --git a/ui/components/app/app-components.scss b/ui/components/app/app-components.scss index 1a4b9eac3..0ec09c41f 100644 --- a/ui/components/app/app-components.scss +++ b/ui/components/app/app-components.scss @@ -105,8 +105,8 @@ @import 'network-account-balance-header/index'; @import 'approve-content-card/index'; @import 'transaction-alerts/transaction-alerts'; -///: BEGIN:ONLY_INCLUDE_IN(build-mmi) +@import '../institutional/compliance-details/index'; +@import '../institutional/interactive-replacement-token-notification/index'; @import '../institutional/confirm-remove-jwt-modal/index'; @import '../institutional/custody-confirm-link-modal/index'; @import '../institutional/transaction-failed-modal/index'; -///: END:ONLY_INCLUDE_IN diff --git a/ui/components/app/app-header/index.scss b/ui/components/app/app-header/index.scss index 4bcb08f63..a6838e33f 100644 --- a/ui/components/app/app-header/index.scss +++ b/ui/components/app/app-header/index.scss @@ -34,7 +34,6 @@ } } - ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) &__custody-logo { &--icon { height: 16px; @@ -46,7 +45,6 @@ } } } - ///: END:ONLY_INCLUDE_IN &__contents { display: flex; diff --git a/ui/components/institutional/custody-labels/custody-labels.scss b/ui/components/institutional/custody-labels/index.scss similarity index 100% rename from ui/components/institutional/custody-labels/custody-labels.scss rename to ui/components/institutional/custody-labels/index.scss diff --git a/ui/components/institutional/interactive-replacement-token-notification/interactive-replacement-token-notification.scss b/ui/components/institutional/interactive-replacement-token-notification/index.scss similarity index 100% rename from ui/components/institutional/interactive-replacement-token-notification/interactive-replacement-token-notification.scss rename to ui/components/institutional/interactive-replacement-token-notification/index.scss diff --git a/ui/components/ui/ui-components.scss b/ui/components/ui/ui-components.scss index 6f012fb2a..7ac0d578b 100644 --- a/ui/components/ui/ui-components.scss +++ b/ui/components/ui/ui-components.scss @@ -60,4 +60,5 @@ @import 'deprecated-test-networks/index.scss'; @import 'nft-info/index.scss'; @import 'nft-collection-image/index'; - +@import '../institutional/custody-labels/index'; +@import '../institutional/note-to-trader/index'; diff --git a/ui/css/index.scss b/ui/css/index.scss index 1033eec1e..2e5aa982c 100644 --- a/ui/css/index.scss +++ b/ui/css/index.scss @@ -11,9 +11,7 @@ @import '../components/component-library/component-library-components.scss'; @import '../components/app/app-components'; @import '../components/ui/ui-components'; -///: BEGIN:ONLY_INCLUDE_IN(build-mmi) @import '../components/institutional/institutional-components'; -///: END:ONLY_INCLUDE_IN @import '../components/multichain/multichain-components.scss'; @import '../pages/pages'; @import './errors.scss'; diff --git a/ui/pages/pages.scss b/ui/pages/pages.scss index 26b50cbfb..41be4f458 100644 --- a/ui/pages/pages.scss +++ b/ui/pages/pages.scss @@ -12,14 +12,14 @@ @import 'connected-accounts/index'; @import 'connected-sites/index'; @import 'create-account/index'; -///: BEGIN:ONLY_INCLUDE_IN(build-mmi) @import "institutional/connect-custody/index"; @import "institutional/custody/index"; @import "institutional/institutional-entity-done-page/index"; @import "institutional/compliance-feature-page/index"; @import "institutional/confirm-add-custodian-token/index"; @import "institutional/interactive-replacement-token-page/index"; -///: END:ONLY_INCLUDE_IN +@import 'institutional/interactive-replacement-token-page/index'; +@import 'institutional/confirm-add-custodian-token/index'; @import 'error/index'; @import 'send/gas-display/index'; @import 'home/index'; From e5fdb72acc03ce1932b7ad51c788f141a884acd9 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 15 May 2023 10:15:39 -0500 Subject: [PATCH 044/120] UX: Multichain: Improve networks selector (#19083) * UX: Multichain: Improve networks selector * Update ui/selectors/selectors.js Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> * Update ui/selectors/selectors.js Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> * Update ui/selectors/selectors.js Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> * Improvements --------- Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- ui/selectors/selectors.js | 97 +++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 51 deletions(-) diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 85cb57be3..c3549d099 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -1170,61 +1170,56 @@ export function getAllEnabledNetworks(state) { export function getAllNetworks(state) { const networkConfigurations = getNetworkConfigurations(state) || {}; - const localhostFilter = (network) => network.chainId === CHAIN_IDS.LOCALHOST; - const networks = []; - // Mainnet always first - networks.push({ - chainId: CHAIN_IDS.MAINNET, - nickname: MAINNET_DISPLAY_NAME, - rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.MAINNET], - rpcPrefs: { - imageUrl: ETH_TOKEN_IMAGE_URL, + const networks = [ + // Mainnet always first + { + chainId: CHAIN_IDS.MAINNET, + nickname: MAINNET_DISPLAY_NAME, + rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.MAINNET], + rpcPrefs: { + imageUrl: ETH_TOKEN_IMAGE_URL, + }, + providerType: NETWORK_TYPES.MAINNET, + ticker: CURRENCY_SYMBOLS.ETH, }, - providerType: NETWORK_TYPES.MAINNET, - ticker: CURRENCY_SYMBOLS.ETH, - }); - // Custom networks added - networks.push( - ...Object.entries(networkConfigurations) - .filter( - ([, network]) => - !localhostFilter(network) && - network.chainId !== CHAIN_IDS.MAINNET && + // Custom networks added by the user + ...Object.values(networkConfigurations).filter( + ({ chainId }) => + ![ + CHAIN_IDS.LOCALHOST, + CHAIN_IDS.MAINNET, // Linea gets added as a custom network configuration so // we must ignore it here to display in test networks - network.chainId !== CHAIN_IDS.LINEA_TESTNET, - ) - .map(([, network]) => network), - ); - // Test networks - networks.push( - ...[ - { - chainId: CHAIN_IDS.GOERLI, - nickname: GOERLI_DISPLAY_NAME, - rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.GOERLI], - providerType: NETWORK_TYPES.GOERLI, - ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.GOERLI], - }, - { - chainId: CHAIN_IDS.SEPOLIA, - nickname: SEPOLIA_DISPLAY_NAME, - rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.SEPOLIA], - providerType: NETWORK_TYPES.SEPOLIA, - ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.SEPOLIA], - }, - { - chainId: CHAIN_IDS.LINEA_TESTNET, - nickname: LINEA_TESTNET_DISPLAY_NAME, - rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.LINEA_TESTNET], - ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_TESTNET], - }, - ], // Localhosts - ...Object.entries(networkConfigurations) - .filter(([, network]) => localhostFilter(network)) - .map(([, network]) => network), - ); + CHAIN_IDS.LINEA_TESTNET, + ].includes(chainId), + ), + // Test networks + { + chainId: CHAIN_IDS.GOERLI, + nickname: GOERLI_DISPLAY_NAME, + rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.GOERLI], + providerType: NETWORK_TYPES.GOERLI, + ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.GOERLI], + }, + { + chainId: CHAIN_IDS.SEPOLIA, + nickname: SEPOLIA_DISPLAY_NAME, + rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.SEPOLIA], + providerType: NETWORK_TYPES.SEPOLIA, + ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.SEPOLIA], + }, + { + chainId: CHAIN_IDS.LINEA_TESTNET, + nickname: LINEA_TESTNET_DISPLAY_NAME, + rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.LINEA_TESTNET], + ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_TESTNET], + }, + // Localhosts + ...Object.values(networkConfigurations).filter( + ({ chainId }) => chainId === CHAIN_IDS.LOCALHOST, + ), + ]; return networks; } From e29faca3a6a39d1c92577b36ae670989c658795f Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Mon, 15 May 2023 13:34:34 -0230 Subject: [PATCH 045/120] Refactor `lookupNetwork` unit tests (#19070) The `lookupNetwork` unit tests have been updated to expand test coverage and match the unit tests for the core network controller. A helper function `lookupNetworkTests` has been copied from core. It covers most of the behavior of the function. Vidation tests and functional tests not covered in core have been retained, but any tests that are now redundant have been deleted. Relates to #1197 --- .../network/network-controller.test.ts | 3058 +++++++---------- 1 file changed, 1271 insertions(+), 1787 deletions(-) diff --git a/app/scripts/controllers/network/network-controller.test.ts b/app/scripts/controllers/network/network-controller.test.ts index 2099e427e..7ceb32d2a 100644 --- a/app/scripts/controllers/network/network-controller.test.ts +++ b/app/scripts/controllers/network/network-controller.test.ts @@ -15,6 +15,7 @@ import { NetworkControllerEventType, NetworkControllerOptions, NetworkControllerState, + ProviderConfiguration, } from './network-controller'; import { createNetworkClient, @@ -86,19 +87,19 @@ const DEFAULT_INFURA_PROJECT_ID = 'fake-infura-project-id'; const INFURA_NETWORKS = [ { networkType: NETWORK_TYPES.MAINNET, - chainId: '0x1', + chainId: '0x1' as const, ticker: 'ETH', blockExplorerUrl: 'https://etherscan.io', }, { networkType: NETWORK_TYPES.GOERLI, - chainId: '0x5', + chainId: '0x5' as const, ticker: 'GoerliETH', blockExplorerUrl: 'https://goerli.etherscan.io', }, { networkType: NETWORK_TYPES.SEPOLIA, - chainId: '0xaa36a7', + chainId: '0xaa36a7' as const, ticker: 'SepoliaETH', blockExplorerUrl: 'https://sepolia.etherscan.io', }, @@ -1252,852 +1253,6 @@ describe('NetworkController', () => { INFURA_NETWORKS.forEach(({ networkType }) => { describe(`when the type in the provider configuration is "${networkType}"`, () => { - describe('if the request for eth_getBlockByNumber responds successfully', () => { - it('stores the fact that the network is available', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkStatus).toBe( - 'unknown', - ); - - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkStatus).toBe( - 'available', - ); - }, - ); - }); - - it('stores the ID of the network', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: { - result: '1', - }, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkId).toBeNull(); - - await waitForStateChanges({ - controller, - propertyPath: ['networkId'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkId).toBe('1'); - }, - ); - }); - - it('stores the fact that the network supports EIP-1559 when baseFeePerGas is in the block header', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - networkDetails: { - EIPS: {}, - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - response: { - result: POST_1559_BLOCK, - }, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - await waitForStateChanges({ - controller, - propertyPath: ['networkDetails'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect( - controller.store.getState().networkDetails.EIPS[1559], - ).toBeTruthy(); - }, - ); - }); - - it('stores the fact that the network does not support EIP-1559 when baseFeePerGas is not in the block header', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - networkDetails: { - EIPS: {}, - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - response: { - result: PRE_1559_BLOCK, - }, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - await waitForStateChanges({ - controller, - propertyPath: ['networkDetails'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect( - controller.store.getState().networkDetails.EIPS[1559], - ).toBe(false); - }, - ); - }); - - it('emits infuraIsUnblocked', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID - // of the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller, messenger }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - response: { - result: POST_1559_BLOCK, - }, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - const infuraIsUnblocked = await waitForPublishedEvents({ - messenger, - eventType: NetworkControllerEventType.InfuraIsUnblocked, - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(infuraIsUnblocked).toBeTruthy(); - }, - ); - }); - }); - - describe('if the request for eth_blockNumber responds with a "countryBlocked" error', () => { - it('stores the fact that the network is blocked', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID - // of the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - error: BLOCKED_INFURA_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkStatus).toBe( - 'blocked', - ); - }, - ); - }); - - it('clears the ID of the network from state', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: { - result: '1', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - { - request: { - method: 'net_version', - }, - response: { - result: '2', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - error: BLOCKED_INFURA_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await waitForStateChanges({ - controller, - propertyPath: ['networkId'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkId).toBe('1'); - - await waitForStateChanges({ - controller, - propertyPath: ['networkId'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - expect(controller.store.getState().networkId).toBeNull(); - }, - ); - }); - - it('clears whether the network supports EIP-1559 from state along with any other network details', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - networkDetails: { - EIPS: { - 1559: true, - }, - other: 'details', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - error: BLOCKED_INFURA_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - await waitForStateChanges({ - controller, - propertyPath: ['networkDetails'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - expect( - controller.store.getState().networkDetails, - ).toStrictEqual({ - EIPS: { - 1559: undefined, - }, - }); - }, - ); - }); - - it('emits infuraIsBlocked', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID - // of the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller, messenger }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - error: BLOCKED_INFURA_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - const infuraIsBlocked = await waitForPublishedEvents({ - messenger, - eventType: NetworkControllerEventType.InfuraIsBlocked, - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(infuraIsBlocked).toBeTruthy(); - }, - ); - }); - - it('does not emit infuraIsUnblocked', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID - // of the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller, messenger }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - error: BLOCKED_INFURA_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - const promiseForNoInfuraIsUnblockedEvents = - waitForPublishedEvents({ - messenger, - eventType: NetworkControllerEventType.InfuraIsUnblocked, - count: 0, - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(await promiseForNoInfuraIsUnblockedEvents).toBeTruthy(); - }, - ); - }); - }); - - describe('if the request for eth_getBlockByNumber responds with a generic error', () => { - it('stores the network status as unavailable if the error does not translate to an internal RPC error', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: { - result: '1', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - { - request: { - method: 'net_version', - }, - response: { - result: '2', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - error: ethErrors.rpc.methodNotFound(), - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkStatus).toBe( - 'available', - ); - - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - expect(controller.store.getState().networkStatus).toBe( - 'unavailable', - ); - }, - ); - }); - - it('stores the network status as unknown if the error translates to an internal RPC error', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: { - result: '1', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - { - request: { - method: 'net_version', - }, - response: { - result: '2', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkStatus).toBe( - 'available', - ); - - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - expect(controller.store.getState().networkStatus).toBe( - 'unknown', - ); - }, - ); - }); - - it('clears the ID of the network from state', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: { - result: '1', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - { - request: { - method: 'net_version', - }, - response: { - result: '2', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await waitForStateChanges({ - controller, - propertyPath: ['networkId'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkId).toBe('1'); - - await waitForStateChanges({ - controller, - propertyPath: ['networkId'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - expect(controller.store.getState().networkId).toBeNull(); - }, - ); - }); - - it('clears whether the network supports EIP-1559 from state along with any other network details', async () => { - const intentionalErrorMessage = - 'intentional error from eth_getBlockByNumber'; - - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - networkDetails: { - EIPS: { - 1559: true, - }, - other: 'details', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - await waitForStateChanges({ - controller, - propertyPath: ['networkDetails'], - operation: async () => { - try { - await controller.lookupNetwork(); - } catch (error) { - if (error !== intentionalErrorMessage) { - console.error(error); - } - } - }, - }); - expect( - controller.store.getState().networkDetails, - ).toStrictEqual({ - EIPS: { - 1559: undefined, - }, - }); - }, - ); - }); - - it('does not emit infuraIsBlocked', async () => { - await withController(async ({ controller, messenger }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - const promiseForNoInfuraIsBlockedEvents = waitForPublishedEvents({ - messenger, - eventType: NetworkControllerEventType.InfuraIsBlocked, - count: 0, - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(await promiseForNoInfuraIsBlockedEvents).toBeTruthy(); - }); - }); - - it('does not emit infuraIsUnblocked', async () => { - await withController( - { - state: { - providerConfig: { - type: networkType, - // NOTE: This doesn't need to match the logical chain ID of - // the network selected, it just needs to exist - chainId: '0x9999999', - }, - }, - }, - async ({ controller, messenger }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'eth_getBlockByNumber', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - const promiseForNoInfuraIsUnblockedEvents = - waitForPublishedEvents({ - messenger, - eventType: NetworkControllerEventType.InfuraIsUnblocked, - count: 0, - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(await promiseForNoInfuraIsUnblockedEvents).toBeTruthy(); - }, - ); - }); - }); - describe('if the network was switched after the eth_getBlockByNumber request started but before it completed', () => { it('stores the network status of the second network, not the first', async () => { await withController( @@ -2482,948 +1637,20 @@ describe('NetworkController', () => { ); }); }); + + lookupNetworkTests({ + expectedProviderConfig: buildProviderConfig({ type: networkType }), + initialState: { + providerConfig: buildProviderConfig({ type: networkType }), + }, + operation: async (controller) => { + await controller.lookupNetwork(); + }, + }); }); }); describe('when the type in the provider configuration is "rpc"', () => { - describe('if both net_version and eth_getBlockByNumber respond successfully', () => { - it('stores the fact the network is available', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkStatus).toBe('unknown'); - - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkStatus).toBe( - 'available', - ); - }, - ); - }); - - it('stores the ID of the network', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: { - result: '42', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: { - result: POST_1559_BLOCK, - }, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkId).toBe(null); - - await waitForStateChanges({ - controller, - propertyPath: ['networkId'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkId).toBe('42'); - }, - ); - }); - - it('stores the fact that the network supports EIP-1559 when baseFeePerGas is in the block header', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: { - result: POST_1559_BLOCK, - }, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - await waitForStateChanges({ - controller, - propertyPath: ['networkDetails'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect( - controller.store.getState().networkDetails.EIPS[1559], - ).toBeTruthy(); - }, - ); - }); - - it('stores the fact that the network does not support EIP-1559 when baseFeePerGas is not in the block header', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: { - result: PRE_1559_BLOCK, - }, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - await waitForStateChanges({ - controller, - propertyPath: ['networkDetails'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect( - controller.store.getState().networkDetails.EIPS[1559], - ).toBe(false); - }, - ); - }); - - it('emits infuraIsUnblocked', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller, messenger }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: { - result: PRE_1559_BLOCK, - }, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - const infuraIsUnblocked = await waitForPublishedEvents({ - messenger, - eventType: NetworkControllerEventType.InfuraIsUnblocked, - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(infuraIsUnblocked).toBeTruthy(); - }, - ); - }); - }); - - describe('if the request for eth_getBlockByNumber responds successfully, but the request for net_version responds with a generic error', () => { - it('stores the network status as available if the error does not translate to an internal RPC error', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - { - request: { - method: 'net_version', - }, - error: ethErrors.rpc.methodNotFound(), - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkStatus).toBe( - 'available', - ); - - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkStatus).toBe( - 'unavailable', - ); - }, - ); - }); - - it('stores the network status as unknown if the error translates to an internal RPC error', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - { - request: { - method: 'net_version', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkStatus).toBe( - 'available', - ); - - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkStatus).toBe('unknown'); - }, - ); - }); - - it('clears the ID of the network from state', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: { - result: '42', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - { - request: { - method: 'net_version', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkId).toBe('42'); - - await waitForStateChanges({ - controller, - propertyPath: ['networkId'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkId).toBeNull(); - }, - ); - }); - - it('clears whether the network supports EIP-1559 from state along with any other network details', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - networkDetails: { - EIPS: { - 1559: true, - }, - other: 'details', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: { - result: PRE_1559_BLOCK, - }, - }, - { - request: { - method: 'net_version', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: { - result: POST_1559_BLOCK, - }, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkDetails).toStrictEqual({ - EIPS: { - 1559: false, - }, - other: 'details', - }); - - await waitForStateChanges({ - controller, - propertyPath: ['networkDetails'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkDetails).toStrictEqual({ - EIPS: { - 1559: undefined, - }, - }); - }, - ); - }); - - it('does not emit infuraIsBlocked', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller, messenger }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - const promiseForNoInfuraIsBlockedEvents = waitForPublishedEvents({ - messenger, - eventType: NetworkControllerEventType.InfuraIsBlocked, - count: 0, - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(await promiseForNoInfuraIsBlockedEvents).toBeTruthy(); - }, - ); - }); - - it('emits infuraIsUnblocked', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller, messenger }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - const infuraIsUnblocked = await waitForPublishedEvents({ - messenger, - eventType: NetworkControllerEventType.InfuraIsUnblocked, - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(infuraIsUnblocked).toBeTruthy(); - }, - ); - }); - }); - - describe('if the request for net_version responds successfully, but the request for eth_getBlockByNumber responds with a generic error', () => { - it('stores the fact that the network is unavailable', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkStatus).toBe( - 'available', - ); - - await waitForStateChanges({ - controller, - propertyPath: ['networkStatus'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkStatus).toBe('unknown'); - }, - ); - }); - - it('clears the ID of the network from state', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: { - result: '42', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - { - request: { - method: 'net_version', - }, - response: { - result: '42', - }, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await waitForStateChanges({ - controller, - propertyPath: ['networkId'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkId).toBe('42'); - - await waitForStateChanges({ - controller, - propertyPath: ['networkId'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkId).toBeNull(); - }, - ); - }); - - it('clears whether the network supports EIP-1559 from state along with any other network details', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - networkDetails: { - EIPS: {}, - other: 'details', - }, - }, - }, - async ({ controller }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE, - }, - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await waitForStateChanges({ - controller, - propertyPath: ['networkDetails'], - operation: async () => { - await controller.initializeProvider(); - }, - }); - expect(controller.store.getState().networkDetails).toStrictEqual({ - EIPS: { - 1559: true, - }, - other: 'details', - }); - - await waitForStateChanges({ - controller, - propertyPath: ['networkDetails'], - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(controller.store.getState().networkDetails).toStrictEqual({ - EIPS: { - 1559: undefined, - }, - }); - }, - ); - }); - - it('does not emit infuraIsBlocked', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller, messenger }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - const promiseForNoInfuraIsBlockedEvents = waitForPublishedEvents({ - messenger, - eventType: NetworkControllerEventType.InfuraIsBlocked, - count: 0, - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(await promiseForNoInfuraIsBlockedEvents).toBeTruthy(); - }, - ); - }); - - it('emits infuraIsUnblocked', async () => { - await withController( - { - state: { - providerConfig: { - type: 'rpc', - rpcUrl: 'https://mock-rpc-url', - chainId: '0x1337', - }, - }, - }, - async ({ controller, messenger }) => { - const fakeProvider = buildFakeProvider([ - { - request: { - method: 'net_version', - }, - response: SUCCESSFUL_NET_VERSION_RESPONSE, - }, - { - request: { - method: 'eth_getBlockByNumber', - }, - error: GENERIC_JSON_RPC_ERROR, - }, - ]); - const fakeNetworkClient = buildFakeClient(fakeProvider); - mockCreateNetworkClient().mockReturnValue(fakeNetworkClient); - await withoutCallingLookupNetwork({ - controller, - operation: async () => { - await controller.initializeProvider(); - }, - }); - - const infuraIsUnblocked = await waitForPublishedEvents({ - messenger, - eventType: NetworkControllerEventType.InfuraIsUnblocked, - operation: async () => { - await controller.lookupNetwork(); - }, - }); - - expect(infuraIsUnblocked).toBeTruthy(); - }, - ); - }); - }); - describe('if the network was switched after the net_version request started but before it completed', () => { it('stores the network status of the second network, not the first', async () => { await withController( @@ -4240,6 +2467,18 @@ describe('NetworkController', () => { ); }); }); + + lookupNetworkTests({ + expectedProviderConfig: buildProviderConfig({ + type: NETWORK_TYPES.RPC, + }), + initialState: { + providerConfig: buildProviderConfig({ type: NETWORK_TYPES.RPC }), + }, + operation: async (controller) => { + await controller.lookupNetwork(); + }, + }); }); }); @@ -8060,6 +6299,1169 @@ function mockCreateNetworkClient() { }); } +/** + * Test an operation that performs a `lookupNetwork` call with the given + * provider configuration. All effects of the `lookupNetwork` call should be + * covered by these tests. + * + * @param args - Arguments. + * @param args.expectedProviderConfig - The provider configuration that the + * operation is expected to set. + * @param args.initialState - The initial state of the network controller. + * @param args.operation - The operation to test. + */ +function lookupNetworkTests({ + expectedProviderConfig, + initialState, + operation, +}: { + expectedProviderConfig: ProviderConfiguration; + initialState?: Partial; + operation: (controller: NetworkController) => Promise; +}) { + describe('if the network ID and network details requests resolve successfully', () => { + describe('if the current network is different from the network in state', () => { + it('updates the network in state to match', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + response: { result: '12345' }, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkId).toBe('12345'); + }, + ); + }); + }); + + describe('if the version of the current network is the same as that in state', () => { + it('does not change network ID in state', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + response: { result: '12345' }, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + await expect(controller.store.getState().networkId).toBe('12345'); + }, + ); + }); + }); + + describe('if the network details of the current network are different from the network details in state', () => { + it('updates the network in state to match', async () => { + await withController( + { + state: { + ...initialState, + networkDetails: { + EIPS: { + 1559: false, + }, + }, + }, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + response: { + result: { + baseFeePerGas: '0x1', + }, + }, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkDetails).toStrictEqual({ + EIPS: { + 1559: true, + }, + }); + }, + ); + }); + }); + + describe('if the network details of the current network are the same as the network details in state', () => { + it('does not change network details in state', async () => { + await withController( + { + state: { + ...initialState, + networkDetails: { + EIPS: { + 1559: true, + }, + }, + }, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + response: { + result: { + baseFeePerGas: '0x1', + }, + }, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkDetails).toStrictEqual({ + EIPS: { + 1559: true, + }, + }); + }, + ); + }); + }); + + it('emits infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + + it('does not emit infuraIsBlocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsBlocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + }); + + describe('if an RPC error is encountered while retrieving the version of the current network', () => { + it('updates the network in state to "unavailable"', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: ethErrors.rpc.limitExceeded('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkStatus).toBe('unavailable'); + }, + ); + }); + + if (expectedProviderConfig.type === NETWORK_TYPES.RPC) { + it('emits infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: ethErrors.rpc.limitExceeded('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } else { + it('does not emit infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: ethErrors.rpc.limitExceeded('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } + + it('does not emit infuraIsBlocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: ethErrors.rpc.limitExceeded('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsBlocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + }); + + describe('if a country blocked error is encountered while retrieving the version of the current network', () => { + if (expectedProviderConfig.type === NETWORK_TYPES.RPC) { + it('updates the network in state to "unknown"', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkStatus).toBe('unknown'); + }, + ); + }); + + it('emits infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + + it('does not emit infuraIsBlocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsBlocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } else { + it('updates the network in state to "blocked"', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkStatus).toBe('blocked'); + }, + ); + }); + + it('does not emit infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + + it('emits infuraIsBlocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsBlocked, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } + }); + + describe('if an internal error is encountered while retrieving the version of the current network', () => { + it('updates the network in state to "unknown"', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: ethErrors.rpc.internal('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkStatus).toBe('unknown'); + }, + ); + }); + + if (expectedProviderConfig.type === NETWORK_TYPES.RPC) { + it('emits infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: ethErrors.rpc.internal('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } else { + it('does not emit infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: ethErrors.rpc.internal('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } + + it('does not emit infuraIsBlocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + error: ethErrors.rpc.internal('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsBlocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + }); + + describe('if an invalid network ID is returned', () => { + it('updates the network in state to "unknown"', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + response: { result: 'invalid' }, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkStatus).toBe('unknown'); + }, + ); + }); + + if (expectedProviderConfig.type === NETWORK_TYPES.RPC) { + it('emits infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + response: { result: 'invalid' }, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } else { + it('does not emit infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + response: { result: 'invalid' }, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } + + it('does not emit infuraIsBlocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { method: 'net_version' }, + response: { result: 'invalid' }, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsBlocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + }); + + describe('if an RPC error is encountered while retrieving the network details of the current network', () => { + it('updates the network in state to "unavailable"', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: ethErrors.rpc.limitExceeded('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkStatus).toBe('unavailable'); + }, + ); + }); + + if (expectedProviderConfig.type === NETWORK_TYPES.RPC) { + it('emits infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: ethErrors.rpc.limitExceeded('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } else { + it('does not emit infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: ethErrors.rpc.limitExceeded('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } + + it('does not emit infuraIsBlocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: ethErrors.rpc.limitExceeded('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsBlocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + }); + + describe('if a country blocked error is encountered while retrieving the network details of the current network', () => { + if (expectedProviderConfig.type === NETWORK_TYPES.RPC) { + it('updates the network in state to "unknown"', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkStatus).toBe('unknown'); + }, + ); + }); + + it('emits infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + + it('does not emit infuraIsBlocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsBlocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } else { + it('updates the network in state to "blocked"', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + await operation(controller); + + expect(controller.store.getState().networkStatus).toBe('blocked'); + }, + ); + }); + + it('does not emit infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + + it('emits infuraIsBlocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: BLOCKED_INFURA_JSON_RPC_ERROR, + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsBlocked, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } + }); + + describe('if an internal error is encountered while retrieving the network details of the current network', () => { + it('updates the network in state to "unknown"', async () => { + await withController( + { + state: initialState, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: ethErrors.rpc.internal('some error'), + }, + ], + }); + + await operation(controller); + + expect(controller.store.getState().networkStatus).toBe('unknown'); + }, + ); + }); + + if (expectedProviderConfig.type === NETWORK_TYPES.RPC) { + it('emits infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: ethErrors.rpc.internal('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } else { + it('does not emit infuraIsUnblocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: ethErrors.rpc.internal('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsUnblocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + } + + it('does not emit infuraIsBlocked', async () => { + await withController( + { + state: initialState, + }, + async ({ controller, messenger }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: ethErrors.rpc.internal('some error'), + }, + ], + stubLookupNetworkWhileSetting: true, + }); + + const payloads = await waitForPublishedEvents({ + messenger, + eventType: NetworkControllerEventType.InfuraIsBlocked, + count: 0, + operation: async () => { + await operation(controller); + }, + }); + + expect(payloads).toBeTruthy(); + }, + ); + }); + }); +} + /** * Builds a controller messenger. * @@ -8146,6 +7548,41 @@ async function withController( } } +/** + * Builds a complete ProviderConfig object, filling in values that are not + * provided with defaults. + * + * @param config - An incomplete ProviderConfig object. + * @returns The complete ProviderConfig object. + */ +function buildProviderConfig( + config: Partial = {}, +): ProviderConfiguration { + if (config.type && config.type !== NETWORK_TYPES.RPC) { + const networkConfig = INFURA_NETWORKS.find( + ({ networkType }) => networkType === config.type, + ); + if (!networkConfig) { + throw new Error(`Invalid type: ${config.type}`); + } + return { + ...networkConfig, + // This is redundant with the spread operation below, but this was + // required for TypeScript to understand that this property was set to an + // Infura type. + type: config.type, + ...config, + }; + } + return { + type: NETWORK_TYPES.RPC, + chainId: '0x42', + nickname: undefined, + rpcUrl: 'http://doesntmatter.com', + ...config, + }; +} + /** * Builds an object that `createInfuraProvider` or `createJsonRpcClient` returns. * @@ -8191,6 +7628,53 @@ function buildFakeProvider(stubs: FakeProviderStub[] = []) { return new FakeProvider({ stubs: completeStubs }); } +/** + * Asks the controller to set the provider in the simplest way, stubbing the + * provider appropriately so as not to cause any errors to be thrown. This is + * useful in tests where it doesn't matter how the provider gets set, just that + * it does. Canned responses may be optionally provided for certain RPC methods + * on the provider. + * + * @param controller - The network controller. + * @param options - Additional options. + * @param options.stubs - The set of RPC methods you want to stub on the + * provider along with their responses. + * @param options.stubLookupNetworkWhileSetting - Whether to stub the call to + * `lookupNetwork` that happens when the provider is set. This option is useful + * in tests that need a provider to get set but also call `lookupNetwork` on + * their own. In this case, since the `providerConfig` setter already calls + * `lookupNetwork` once, and since `lookupNetwork` is called out of band, the + * test may run with unexpected results. By stubbing `lookupNetwork` before + * setting the provider, the test is free to explicitly call it. + * @returns The set provider. + */ +async function setFakeProvider( + controller: NetworkController, + { + stubs = [], + stubLookupNetworkWhileSetting = false, + }: { + stubs?: FakeProviderStub[]; + stubLookupNetworkWhileSetting?: boolean; + } = {}, +): Promise { + const fakeProvider = buildFakeProvider(stubs); + const fakeNetworkClient = buildFakeClient(fakeProvider); + createNetworkClientMock.mockReturnValue(fakeNetworkClient); + const lookupNetworkMock = jest.spyOn(controller, 'lookupNetwork'); + + if (stubLookupNetworkWhileSetting) { + lookupNetworkMock.mockResolvedValue(undefined); + } + + await controller.initializeProvider(); + assert(controller.getProviderAndBlockTracker().provider); + + if (stubLookupNetworkWhileSetting) { + lookupNetworkMock.mockRestore(); + } +} + /** * For each kind of way that the provider can be set, `lookupNetwork` is always * called. This can cause difficulty when testing the behavior of From 1c346674df00e40fe83d36538eba2198667357a9 Mon Sep 17 00:00:00 2001 From: Harsh Shukla <125105825+PrgrmrHarshShukla@users.noreply.github.com> Date: Mon, 15 May 2023 22:22:02 +0530 Subject: [PATCH 046/120] Part of #18714 Replace deprecated design system typography consts with enums in: 'srp-input' (#19040) * Part of #18714 Replace deprecated design system typography consts with enums in: 'srp-input' * Update ui/components/app/srp-input/srp-input.js Co-authored-by: George Marshall * Update srp-input.js --------- Co-authored-by: Brad Decker Co-authored-by: George Marshall --- ui/components/app/srp-input/srp-input.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/ui/components/app/srp-input/srp-input.js b/ui/components/app/srp-input/srp-input.js index 27b7abc1f..be990e3cf 100644 --- a/ui/components/app/srp-input/srp-input.js +++ b/ui/components/app/srp-input/srp-input.js @@ -6,13 +6,12 @@ import TextField from '../../ui/text-field'; import { clearClipboard } from '../../../helpers/utils/util'; import ActionableMessage from '../../ui/actionable-message'; import Dropdown from '../../ui/dropdown'; -import Typography from '../../ui/typography'; import ShowHideToggle from '../../ui/show-hide-toggle'; import { - FONT_WEIGHT, - TEXT_ALIGN, - TypographyVariant, + TextAlign, + TextVariant, } from '../../../helpers/constants/design-system'; +import { Text } from '../../component-library'; import { parseSecretRecoveryPhrase } from './parse-secret-recovery-phrase'; const defaultNumberOfWords = 12; @@ -129,13 +128,9 @@ export default function SrpInput({ onChange, srpText }) { return (
Date: Mon, 15 May 2023 19:36:24 +0200 Subject: [PATCH 047/120] [FLASK] `snaps-monorepo@0.33.1-flask.1` (#18913) * snaps-monorepo@0.33.0-flask.1 * Add browser-passworder * Patch babel/core * Fix PermissionController messenger allowlist * Update test-snaps * Use latest patch * Update LavaMoat policies * Re-enable RPC E2E * Make snaps iframe URL be a env variable and bump it * Add new env variable to test env * Add iframe URL to desktop build --- .../@babel-core-npm-7.21.5-c72c337956.patch | 12 + app/scripts/metamask-controller.js | 6 +- builds.yml | 3 + lavamoat/browserify/beta/policy.json | 30 +- lavamoat/browserify/desktop/policy.json | 168 +++---- lavamoat/browserify/flask/policy.json | 168 +++---- lavamoat/browserify/main/policy.json | 30 +- lavamoat/build-system/policy.json | 18 +- package.json | 24 +- test/e2e/snaps/test-snap-rpc.spec.js | 5 +- test/env.js | 2 + yarn.lock | 422 +++++++++++------- 12 files changed, 521 insertions(+), 367 deletions(-) create mode 100644 .yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch diff --git a/.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch b/.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch new file mode 100644 index 000000000..c6a1743a7 --- /dev/null +++ b/.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch @@ -0,0 +1,12 @@ +diff --git a/lib/index.js b/lib/index.js +index c991f62dc64553502e9911a7f21e77e008d7f438..e503c7494d21b13df85b10e1657b2af8ca4d964f 100644 +--- a/lib/index.js ++++ b/lib/index.js +@@ -222,7 +222,6 @@ var _transform = require("./transform"); + var _transformFile = require("./transform-file"); + var _transformAst = require("./transform-ast"); + var _parse = require("./parse"); +-var thisFile = require("./index"); + const version = "7.21.5"; + exports.version = version; + const DEFAULT_EXTENSIONS = Object.freeze([".js", ".jsx", ".es6", ".es", ".mjs", ".cjs"]); diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 8378cb02a..d1019ccb8 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -49,6 +49,7 @@ import { SubjectType, } from '@metamask/subject-metadata-controller'; ///: BEGIN:ONLY_INCLUDE_IN(snaps) +import { encrypt, decrypt } from '@metamask/browser-passworder'; import { RateLimitController } from '@metamask/rate-limit-controller'; import { NotificationController } from '@metamask/notification-controller'; ///: END:ONLY_INCLUDE_IN @@ -754,6 +755,7 @@ export default class MetamaskController extends EventEmitter { `${this.approvalController.name}:rejectRequest`, `SnapController:getPermitted`, `SnapController:install`, + `SubjectMetadataController:getSubjectMetadata`, ], }), state: initState.PermissionController, @@ -813,7 +815,7 @@ export default class MetamaskController extends EventEmitter { ///: BEGIN:ONLY_INCLUDE_IN(snaps) const snapExecutionServiceArgs = { - iframeUrl: new URL('https://execution.metamask.io/0.15.1/index.html'), + iframeUrl: new URL(process.env.IFRAME_EXECUTION_ENVIRONMENT_URL), messenger: this.controllerMessenger.getRestricted({ name: 'ExecutionService', }), @@ -1572,6 +1574,8 @@ export default class MetamaskController extends EventEmitter { return { ...buildSnapEndowmentSpecifications(), ...buildSnapRestrictedMethodSpecifications({ + encrypt, + decrypt, clearSnapState: this.controllerMessenger.call.bind( this.controllerMessenger, 'SnapController:clearSnapState', diff --git a/builds.yml b/builds.yml index 414641af0..83b331523 100644 --- a/builds.yml +++ b/builds.yml @@ -50,6 +50,7 @@ buildTypes: - SEGMENT_FLASK_WRITE_KEY - ALLOW_LOCAL_SNAPS: true - REQUIRE_SNAPS_ALLOWLIST: false + - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/0.16.0-flask.1/index.html - SUPPORT_LINK: https://metamask-flask.zendesk.com/hc - SUPPORT_REQUEST_LINK: https://metamask-flask.zendesk.com/hc/en-us/requests/new - INFURA_ENV_KEY_REF: INFURA_FLASK_PROJECT_ID @@ -67,6 +68,7 @@ buildTypes: - SEGMENT_FLASK_WRITE_KEY - ALLOW_LOCAL_SNAPS: true - REQUIRE_SNAPS_ALLOWLIST: false + - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/0.16.0-flask.1/index.html - SUPPORT_LINK: https://metamask-flask.zendesk.com/hc - SUPPORT_REQUEST_LINK: https://metamask-flask.zendesk.com/hc/en-us/requests/new - INFURA_ENV_KEY_REF: INFURA_FLASK_PROJECT_ID @@ -101,6 +103,7 @@ features: - ALLOW_LOCAL_SNAPS # Whether to verify that a snap can be installed using an allow list - REQUIRE_SNAPS_ALLOWLIST + - IFRAME_EXECUTION_ENVIRONMENT_URL assets: - ./{app,shared,ui}/**/snaps/** desktop: diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index bff7adb06..a049ea57c 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -868,6 +868,20 @@ "immer": true } }, + "@metamask/browser-passworder": { + "globals": { + "btoa": true, + "crypto.getRandomValues": true, + "crypto.subtle.decrypt": true, + "crypto.subtle.deriveKey": true, + "crypto.subtle.encrypt": true, + "crypto.subtle.exportKey": true, + "crypto.subtle.importKey": true + }, + "packages": { + "browserify>buffer": true + } + }, "@metamask/controller-utils": { "globals": { "URL": true, @@ -998,11 +1012,11 @@ }, "@metamask/eth-keyring-controller": { "packages": { + "@metamask/browser-passworder": true, "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, "@metamask/eth-keyring-controller>obs-store": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, - "@metamask/rpc-methods>@metamask/browser-passworder": true, "browserify>events": true } }, @@ -1610,20 +1624,6 @@ "crypto.getRandomValues": true } }, - "@metamask/rpc-methods>@metamask/browser-passworder": { - "globals": { - "btoa": true, - "crypto.getRandomValues": true, - "crypto.subtle.decrypt": true, - "crypto.subtle.deriveKey": true, - "crypto.subtle.encrypt": true, - "crypto.subtle.exportKey": true, - "crypto.subtle.importKey": true - }, - "packages": { - "browserify>buffer": true - } - }, "@metamask/rpc-methods>nanoid": { "globals": { "crypto.getRandomValues": true diff --git a/lavamoat/browserify/desktop/policy.json b/lavamoat/browserify/desktop/policy.json index c5eee11b6..54c984578 100644 --- a/lavamoat/browserify/desktop/policy.json +++ b/lavamoat/browserify/desktop/policy.json @@ -868,6 +868,20 @@ "immer": true } }, + "@metamask/browser-passworder": { + "globals": { + "btoa": true, + "crypto.getRandomValues": true, + "crypto.subtle.decrypt": true, + "crypto.subtle.deriveKey": true, + "crypto.subtle.encrypt": true, + "crypto.subtle.exportKey": true, + "crypto.subtle.importKey": true + }, + "packages": { + "browserify>buffer": true + } + }, "@metamask/controller-utils": { "globals": { "URL": true, @@ -1069,11 +1083,11 @@ }, "@metamask/eth-keyring-controller": { "packages": { + "@metamask/browser-passworder": true, "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, "@metamask/eth-keyring-controller>obs-store": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, - "@metamask/rpc-methods>@metamask/browser-passworder": true, "browserify>events": true } }, @@ -1683,25 +1697,12 @@ "browser": true, "chrome": true, "location.origin": true, - "onmessage": "write", "postMessage": true, "removeEventListener": true }, "packages": { - "@metamask/post-message-stream>@metamask/utils": true, - "@metamask/post-message-stream>readable-stream": true - } - }, - "@metamask/post-message-stream>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true + "@metamask/post-message-stream>readable-stream": true, + "@metamask/utils": true } }, "@metamask/post-message-stream>readable-stream": { @@ -1753,53 +1754,52 @@ "eth-rpc-errors": true } }, - "@metamask/rpc-methods": { - "packages": { - "@metamask/key-tree": true, - "@metamask/key-tree>@noble/hashes": true, - "@metamask/permission-controller": true, - "@metamask/rpc-methods>@metamask/browser-passworder": true, - "@metamask/rpc-methods>nanoid": true, - "@metamask/snaps-ui": true, - "@metamask/snaps-utils": true, - "@metamask/utils": true, - "eth-rpc-errors": true, - "superstruct": true - } - }, "@metamask/rpc-methods-flask": { "packages": { "@metamask/key-tree": true, "@metamask/key-tree>@noble/hashes": true, "@metamask/permission-controller": true, + "@metamask/rpc-methods-flask>@metamask/snaps-ui": true, + "@metamask/rpc-methods-flask>@metamask/snaps-utils": true, "@metamask/rpc-methods-flask>nanoid": true, - "@metamask/rpc-methods>@metamask/browser-passworder": true, - "@metamask/snaps-ui": true, - "@metamask/snaps-utils": true, "@metamask/utils": true, "eth-rpc-errors": true, "superstruct": true } }, + "@metamask/rpc-methods-flask>@metamask/snaps-ui": { + "packages": { + "@metamask/utils": true, + "superstruct": true + } + }, + "@metamask/rpc-methods-flask>@metamask/snaps-utils": { + "globals": { + "TextDecoder": true, + "URL": true, + "console.error": true, + "console.log": true, + "console.warn": true, + "document.body.appendChild": true, + "document.createElement": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "@metamask/key-tree>@scure/base": true, + "@metamask/snaps-utils>cron-parser": true, + "@metamask/snaps-utils>fast-json-stable-stringify": true, + "@metamask/snaps-utils>rfdc": true, + "@metamask/snaps-utils>validate-npm-package-name": true, + "@metamask/utils": true, + "semver": true, + "superstruct": true + } + }, "@metamask/rpc-methods-flask>nanoid": { "globals": { "crypto.getRandomValues": true } }, - "@metamask/rpc-methods>@metamask/browser-passworder": { - "globals": { - "btoa": true, - "crypto.getRandomValues": true, - "crypto.subtle.decrypt": true, - "crypto.subtle.deriveKey": true, - "crypto.subtle.encrypt": true, - "crypto.subtle.exportKey": true, - "crypto.subtle.importKey": true - }, - "packages": { - "browserify>buffer": true - } - }, "@metamask/rpc-methods>nanoid": { "globals": { "crypto.getRandomValues": true @@ -1922,16 +1922,15 @@ "@metamask/permission-controller": true, "@metamask/post-message-stream": true, "@metamask/providers>@metamask/object-multiplex": true, - "@metamask/rpc-methods": true, + "@metamask/snaps-controllers-flask>@metamask/rpc-methods": true, + "@metamask/snaps-controllers-flask>@metamask/snaps-utils": true, "@metamask/snaps-controllers-flask>concat-stream": true, "@metamask/snaps-controllers-flask>nanoid": true, "@metamask/snaps-controllers>@xstate/fsm": true, "@metamask/snaps-controllers>gunzip-maybe": true, "@metamask/snaps-controllers>readable-web-to-node-stream": true, "@metamask/snaps-controllers>tar-stream": true, - "@metamask/snaps-utils": true, "@metamask/snaps-utils>@metamask/snaps-registry": true, - "@metamask/subject-metadata-controller": true, "@metamask/utils": true, "eth-rpc-errors": true, "json-rpc-engine": true, @@ -1939,6 +1938,47 @@ "pump": true } }, + "@metamask/snaps-controllers-flask>@metamask/rpc-methods": { + "packages": { + "@metamask/key-tree": true, + "@metamask/key-tree>@noble/hashes": true, + "@metamask/permission-controller": true, + "@metamask/snaps-controllers-flask>@metamask/snaps-utils": true, + "@metamask/snaps-controllers-flask>@metamask/snaps-utils>@metamask/snaps-ui": true, + "@metamask/snaps-controllers-flask>nanoid": true, + "@metamask/utils": true, + "eth-rpc-errors": true, + "superstruct": true + } + }, + "@metamask/snaps-controllers-flask>@metamask/snaps-utils": { + "globals": { + "TextDecoder": true, + "URL": true, + "console.error": true, + "console.log": true, + "console.warn": true, + "document.body.appendChild": true, + "document.createElement": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "@metamask/key-tree>@scure/base": true, + "@metamask/snaps-utils>cron-parser": true, + "@metamask/snaps-utils>fast-json-stable-stringify": true, + "@metamask/snaps-utils>rfdc": true, + "@metamask/snaps-utils>validate-npm-package-name": true, + "@metamask/utils": true, + "semver": true, + "superstruct": true + } + }, + "@metamask/snaps-controllers-flask>@metamask/snaps-utils>@metamask/snaps-ui": { + "packages": { + "@metamask/utils": true, + "superstruct": true + } + }, "@metamask/snaps-controllers-flask>concat-stream": { "packages": { "@metamask/snaps-controllers-flask>concat-stream>readable-stream": true, @@ -2090,40 +2130,12 @@ "pumpify>inherits": true } }, - "@metamask/snaps-ui": { - "packages": { - "@metamask/utils": true, - "superstruct": true - } - }, "@metamask/snaps-ui-flask": { "packages": { "@metamask/utils": true, "superstruct": true } }, - "@metamask/snaps-utils": { - "globals": { - "TextDecoder": true, - "URL": true, - "console.error": true, - "console.log": true, - "console.warn": true, - "document.body.appendChild": true, - "document.createElement": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "@metamask/key-tree>@scure/base": true, - "@metamask/snaps-utils>cron-parser": true, - "@metamask/snaps-utils>fast-json-stable-stringify": true, - "@metamask/snaps-utils>rfdc": true, - "@metamask/snaps-utils>validate-npm-package-name": true, - "@metamask/utils": true, - "semver": true, - "superstruct": true - } - }, "@metamask/snaps-utils-flask": { "globals": { "TextDecoder": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index c5eee11b6..54c984578 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -868,6 +868,20 @@ "immer": true } }, + "@metamask/browser-passworder": { + "globals": { + "btoa": true, + "crypto.getRandomValues": true, + "crypto.subtle.decrypt": true, + "crypto.subtle.deriveKey": true, + "crypto.subtle.encrypt": true, + "crypto.subtle.exportKey": true, + "crypto.subtle.importKey": true + }, + "packages": { + "browserify>buffer": true + } + }, "@metamask/controller-utils": { "globals": { "URL": true, @@ -1069,11 +1083,11 @@ }, "@metamask/eth-keyring-controller": { "packages": { + "@metamask/browser-passworder": true, "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, "@metamask/eth-keyring-controller>obs-store": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, - "@metamask/rpc-methods>@metamask/browser-passworder": true, "browserify>events": true } }, @@ -1683,25 +1697,12 @@ "browser": true, "chrome": true, "location.origin": true, - "onmessage": "write", "postMessage": true, "removeEventListener": true }, "packages": { - "@metamask/post-message-stream>@metamask/utils": true, - "@metamask/post-message-stream>readable-stream": true - } - }, - "@metamask/post-message-stream>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true + "@metamask/post-message-stream>readable-stream": true, + "@metamask/utils": true } }, "@metamask/post-message-stream>readable-stream": { @@ -1753,53 +1754,52 @@ "eth-rpc-errors": true } }, - "@metamask/rpc-methods": { - "packages": { - "@metamask/key-tree": true, - "@metamask/key-tree>@noble/hashes": true, - "@metamask/permission-controller": true, - "@metamask/rpc-methods>@metamask/browser-passworder": true, - "@metamask/rpc-methods>nanoid": true, - "@metamask/snaps-ui": true, - "@metamask/snaps-utils": true, - "@metamask/utils": true, - "eth-rpc-errors": true, - "superstruct": true - } - }, "@metamask/rpc-methods-flask": { "packages": { "@metamask/key-tree": true, "@metamask/key-tree>@noble/hashes": true, "@metamask/permission-controller": true, + "@metamask/rpc-methods-flask>@metamask/snaps-ui": true, + "@metamask/rpc-methods-flask>@metamask/snaps-utils": true, "@metamask/rpc-methods-flask>nanoid": true, - "@metamask/rpc-methods>@metamask/browser-passworder": true, - "@metamask/snaps-ui": true, - "@metamask/snaps-utils": true, "@metamask/utils": true, "eth-rpc-errors": true, "superstruct": true } }, + "@metamask/rpc-methods-flask>@metamask/snaps-ui": { + "packages": { + "@metamask/utils": true, + "superstruct": true + } + }, + "@metamask/rpc-methods-flask>@metamask/snaps-utils": { + "globals": { + "TextDecoder": true, + "URL": true, + "console.error": true, + "console.log": true, + "console.warn": true, + "document.body.appendChild": true, + "document.createElement": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "@metamask/key-tree>@scure/base": true, + "@metamask/snaps-utils>cron-parser": true, + "@metamask/snaps-utils>fast-json-stable-stringify": true, + "@metamask/snaps-utils>rfdc": true, + "@metamask/snaps-utils>validate-npm-package-name": true, + "@metamask/utils": true, + "semver": true, + "superstruct": true + } + }, "@metamask/rpc-methods-flask>nanoid": { "globals": { "crypto.getRandomValues": true } }, - "@metamask/rpc-methods>@metamask/browser-passworder": { - "globals": { - "btoa": true, - "crypto.getRandomValues": true, - "crypto.subtle.decrypt": true, - "crypto.subtle.deriveKey": true, - "crypto.subtle.encrypt": true, - "crypto.subtle.exportKey": true, - "crypto.subtle.importKey": true - }, - "packages": { - "browserify>buffer": true - } - }, "@metamask/rpc-methods>nanoid": { "globals": { "crypto.getRandomValues": true @@ -1922,16 +1922,15 @@ "@metamask/permission-controller": true, "@metamask/post-message-stream": true, "@metamask/providers>@metamask/object-multiplex": true, - "@metamask/rpc-methods": true, + "@metamask/snaps-controllers-flask>@metamask/rpc-methods": true, + "@metamask/snaps-controllers-flask>@metamask/snaps-utils": true, "@metamask/snaps-controllers-flask>concat-stream": true, "@metamask/snaps-controllers-flask>nanoid": true, "@metamask/snaps-controllers>@xstate/fsm": true, "@metamask/snaps-controllers>gunzip-maybe": true, "@metamask/snaps-controllers>readable-web-to-node-stream": true, "@metamask/snaps-controllers>tar-stream": true, - "@metamask/snaps-utils": true, "@metamask/snaps-utils>@metamask/snaps-registry": true, - "@metamask/subject-metadata-controller": true, "@metamask/utils": true, "eth-rpc-errors": true, "json-rpc-engine": true, @@ -1939,6 +1938,47 @@ "pump": true } }, + "@metamask/snaps-controllers-flask>@metamask/rpc-methods": { + "packages": { + "@metamask/key-tree": true, + "@metamask/key-tree>@noble/hashes": true, + "@metamask/permission-controller": true, + "@metamask/snaps-controllers-flask>@metamask/snaps-utils": true, + "@metamask/snaps-controllers-flask>@metamask/snaps-utils>@metamask/snaps-ui": true, + "@metamask/snaps-controllers-flask>nanoid": true, + "@metamask/utils": true, + "eth-rpc-errors": true, + "superstruct": true + } + }, + "@metamask/snaps-controllers-flask>@metamask/snaps-utils": { + "globals": { + "TextDecoder": true, + "URL": true, + "console.error": true, + "console.log": true, + "console.warn": true, + "document.body.appendChild": true, + "document.createElement": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "@metamask/key-tree>@scure/base": true, + "@metamask/snaps-utils>cron-parser": true, + "@metamask/snaps-utils>fast-json-stable-stringify": true, + "@metamask/snaps-utils>rfdc": true, + "@metamask/snaps-utils>validate-npm-package-name": true, + "@metamask/utils": true, + "semver": true, + "superstruct": true + } + }, + "@metamask/snaps-controllers-flask>@metamask/snaps-utils>@metamask/snaps-ui": { + "packages": { + "@metamask/utils": true, + "superstruct": true + } + }, "@metamask/snaps-controllers-flask>concat-stream": { "packages": { "@metamask/snaps-controllers-flask>concat-stream>readable-stream": true, @@ -2090,40 +2130,12 @@ "pumpify>inherits": true } }, - "@metamask/snaps-ui": { - "packages": { - "@metamask/utils": true, - "superstruct": true - } - }, "@metamask/snaps-ui-flask": { "packages": { "@metamask/utils": true, "superstruct": true } }, - "@metamask/snaps-utils": { - "globals": { - "TextDecoder": true, - "URL": true, - "console.error": true, - "console.log": true, - "console.warn": true, - "document.body.appendChild": true, - "document.createElement": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "@metamask/key-tree>@scure/base": true, - "@metamask/snaps-utils>cron-parser": true, - "@metamask/snaps-utils>fast-json-stable-stringify": true, - "@metamask/snaps-utils>rfdc": true, - "@metamask/snaps-utils>validate-npm-package-name": true, - "@metamask/utils": true, - "semver": true, - "superstruct": true - } - }, "@metamask/snaps-utils-flask": { "globals": { "TextDecoder": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index bff7adb06..a049ea57c 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -868,6 +868,20 @@ "immer": true } }, + "@metamask/browser-passworder": { + "globals": { + "btoa": true, + "crypto.getRandomValues": true, + "crypto.subtle.decrypt": true, + "crypto.subtle.deriveKey": true, + "crypto.subtle.encrypt": true, + "crypto.subtle.exportKey": true, + "crypto.subtle.importKey": true + }, + "packages": { + "browserify>buffer": true + } + }, "@metamask/controller-utils": { "globals": { "URL": true, @@ -998,11 +1012,11 @@ }, "@metamask/eth-keyring-controller": { "packages": { + "@metamask/browser-passworder": true, "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, "@metamask/eth-keyring-controller>obs-store": true, "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, - "@metamask/rpc-methods>@metamask/browser-passworder": true, "browserify>events": true } }, @@ -1610,20 +1624,6 @@ "crypto.getRandomValues": true } }, - "@metamask/rpc-methods>@metamask/browser-passworder": { - "globals": { - "btoa": true, - "crypto.getRandomValues": true, - "crypto.subtle.decrypt": true, - "crypto.subtle.deriveKey": true, - "crypto.subtle.encrypt": true, - "crypto.subtle.exportKey": true, - "crypto.subtle.importKey": true - }, - "packages": { - "browserify>buffer": true - } - }, "@metamask/rpc-methods>nanoid": { "globals": { "crypto.getRandomValues": true diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json index fd2759c0b..29f62566a 100644 --- a/lavamoat/build-system/policy.json +++ b/lavamoat/build-system/policy.json @@ -15,13 +15,19 @@ "fs": true, "module": true, "path": true, + "process": true, "url": true, - "util": true + "util": true, + "v8": true }, "globals": { "console.error": true, "console.log": true, - "process": true + "process.env.BABEL_ENV": true, + "process.env.BABEL_SHOW_CONFIG_FOR": true, + "process.env.NODE_ENV": true, + "process.versions.node": true, + "process.versions.pnp": true }, "packages": { "$root$": true, @@ -66,7 +72,8 @@ "packages": { "@babel/core>@babel/generator>jsesc": true, "@babel/core>@babel/types": true, - "terser>@jridgewell/source-map>@jridgewell/gen-mapping": true + "terser>@jridgewell/source-map>@jridgewell/gen-mapping": true, + "terser>@jridgewell/source-map>@jridgewell/trace-mapping": true } }, "@babel/core>@babel/generator>jsesc": { @@ -139,7 +146,7 @@ }, "@babel/core>@babel/types": { "globals": { - "console.trace": true, + "console.warn": true, "process.env.BABEL_TYPES_8_BREAKING": true }, "packages": { @@ -2225,8 +2232,7 @@ }, "depcheck>@babel/traverse": { "globals": { - "console.log": true, - "console.trace": true + "console.log": true }, "packages": { "@babel/code-frame": true, diff --git a/package.json b/package.json index 5c2920ed6..2d0c117ac 100644 --- a/package.json +++ b/package.json @@ -210,7 +210,18 @@ "fast-json-patch@^3.1.1": "patch:fast-json-patch@npm%3A3.1.1#./.yarn/patches/fast-json-patch-npm-3.1.1-7e8bb70a45.patch", "request@^2.83.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch", "request@^2.88.2": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch", - "request@^2.85.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch" + "request@^2.85.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch", + "@babel/core@^7.12.1": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch", + "@babel/core@^7.20.12": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch", + "@babel/core@^7.18.6": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch", + "@babel/core@^7.18.13": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch", + "@babel/core@^7.12.10": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch", + "@babel/core@^7.7.5": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch", + "@babel/core@^7.11.6": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch", + "@babel/core@>=7.9.0": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch", + "@babel/core@^7.1.0": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch", + "@babel/core@^7.12.3": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch", + "@babel/core@7.12.9": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch" }, "dependencies": { "@actions/core": "^1.10.0", @@ -237,6 +248,7 @@ "@metamask/approval-controller": "^2.1.0", "@metamask/assets-controllers": "^6.0.0", "@metamask/base-controller": "^2.0.0", + "@metamask/browser-passworder": "^4.1.0", "@metamask/contract-metadata": "^2.3.1", "@metamask/controller-utils": "^3.3.0", "@metamask/design-tokens": "^1.9.0", @@ -257,24 +269,24 @@ "@metamask/metamask-eth-abis": "^3.0.0", "@metamask/notification-controller": "^2.0.0", "@metamask/obs-store": "^8.1.0", - "@metamask/permission-controller": "^3.1.0", + "@metamask/permission-controller": "^3.2.0", "@metamask/phishing-controller": "^3.0.0", "@metamask/post-message-stream": "^6.0.0", "@metamask/providers": "^10.2.1", "@metamask/rate-limit-controller": "^2.0.0", "@metamask/rpc-methods": "^0.32.2", - "@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.32.2", + "@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.33.1-flask.1", "@metamask/safe-event-emitter": "^2.0.0", "@metamask/scure-bip39": "^2.0.3", "@metamask/signature-controller": "^2.0.0", "@metamask/slip44": "^3.0.0", "@metamask/smart-transactions-controller": "^3.1.0", "@metamask/snaps-controllers": "^0.32.2", - "@metamask/snaps-controllers-flask": "npm:@metamask/snaps-controllers@0.32.2", + "@metamask/snaps-controllers-flask": "npm:@metamask/snaps-controllers@0.33.1-flask.1", "@metamask/snaps-ui": "^0.32.2", - "@metamask/snaps-ui-flask": "npm:@metamask/snaps-ui@0.32.2", + "@metamask/snaps-ui-flask": "npm:@metamask/snaps-ui@0.33.1-flask.1", "@metamask/snaps-utils": "^0.32.2", - "@metamask/snaps-utils-flask": "npm:@metamask/snaps-utils@0.32.2", + "@metamask/snaps-utils-flask": "npm:@metamask/snaps-utils@0.33.1-flask.1", "@metamask/subject-metadata-controller": "^2.0.0", "@metamask/swappable-obj-proxy": "^2.1.0", "@metamask/utils": "^5.0.0", diff --git a/test/e2e/snaps/test-snap-rpc.spec.js b/test/e2e/snaps/test-snap-rpc.spec.js index 9135801c3..3505a6c85 100644 --- a/test/e2e/snaps/test-snap-rpc.spec.js +++ b/test/e2e/snaps/test-snap-rpc.spec.js @@ -3,10 +3,7 @@ const FixtureBuilder = require('../fixture-builder'); const { TEST_SNAPS_WEBSITE_URL } = require('./enums'); describe('Test Snap RPC', function () { - // Disabled for now due to a bug. - // TODO: Re-enable when fixed. - // eslint-disable-next-line mocha/no-skipped-tests - it.skip('can use the cross-snap RPC endowment and produce a public key', async function () { + it('can use the cross-snap RPC endowment and produce a public key', async function () { const ganacheOptions = { accounts: [ { diff --git a/test/env.js b/test/env.js index fd055ee8a..cb66e3d3b 100644 --- a/test/env.js +++ b/test/env.js @@ -1,2 +1,4 @@ process.env.METAMASK_ENVIRONMENT = 'test'; process.env.SUPPORT_LINK = 'https://support.metamask.io'; +process.env.IFRAME_EXECUTION_ENVIRONMENT_URL = + 'https://execution.metamask.io/0.16.0-flask.1/index.html'; diff --git a/yarn.lock b/yarn.lock index 773754267..669dbbd2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -36,7 +36,7 @@ __metadata: languageName: node linkType: hard -"@ampproject/remapping@npm:^2.1.0": +"@ampproject/remapping@npm:^2.2.0": version: 2.2.1 resolution: "@ampproject/remapping@npm:2.2.1" dependencies: @@ -62,66 +62,65 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.18.6, @babel/code-frame@npm:^7.5.5, @babel/code-frame@npm:^7.8.3": - version: 7.18.6 - resolution: "@babel/code-frame@npm:7.18.6" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.18.6, @babel/code-frame@npm:^7.21.4, @babel/code-frame@npm:^7.5.5, @babel/code-frame@npm:^7.8.3": + version: 7.21.4 + resolution: "@babel/code-frame@npm:7.21.4" dependencies: "@babel/highlight": ^7.18.6 - checksum: 195e2be3172d7684bf95cff69ae3b7a15a9841ea9d27d3c843662d50cdd7d6470fd9c8e64be84d031117e4a4083486effba39f9aef6bbb2c89f7f21bcfba33ba + checksum: e5390e6ec1ac58dcef01d4f18eaf1fd2f1325528661ff6d4a5de8979588b9f5a8e852a54a91b923846f7a5c681b217f0a45c2524eb9560553160cd963b7d592c languageName: node linkType: hard -"@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.20.1, @babel/compat-data@npm:^7.20.5": - version: 7.20.10 - resolution: "@babel/compat-data@npm:7.20.10" - checksum: 6ed6c1bb6fc03c225d63b8611788cd976107d1692402b560ebffbf1fa53e63705f8625bb12e12d17ce7f7af34e61e1ca96c77858aac6f57010045271466200c0 +"@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.20.1, @babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.21.5": + version: 7.21.7 + resolution: "@babel/compat-data@npm:7.21.7" + checksum: 28747eb3fc084d088ba2db0336f52118cfa730a57bdbac81630cae1f38ad0336605b95b3390325937802f344e0b7fa25e2f1b67e3ee2d7383b877f88dee0e51c languageName: node linkType: hard -"@babel/core@npm:7.12.9": - version: 7.12.9 - resolution: "@babel/core@npm:7.12.9" +"@babel/core@npm:7.21.5": + version: 7.21.5 + resolution: "@babel/core@npm:7.21.5" dependencies: - "@babel/code-frame": ^7.10.4 - "@babel/generator": ^7.12.5 - "@babel/helper-module-transforms": ^7.12.1 - "@babel/helpers": ^7.12.5 - "@babel/parser": ^7.12.7 - "@babel/template": ^7.12.7 - "@babel/traverse": ^7.12.9 - "@babel/types": ^7.12.7 - convert-source-map: ^1.7.0 - debug: ^4.1.0 - gensync: ^1.0.0-beta.1 - json5: ^2.1.2 - lodash: ^4.17.19 - resolve: ^1.3.2 - semver: ^5.4.1 - source-map: ^0.5.0 - checksum: 4d34eca4688214a4eb6bd5dde906b69a7824f17b931f52cd03628a8ac94d8fbe15565aebffdde106e974c8738cd64ac62c6a6060baa7139a06db1f18c4ff872d - languageName: node - linkType: hard - -"@babel/core@npm:>=7.9.0, @babel/core@npm:^7.1.0, @babel/core@npm:^7.11.6, @babel/core@npm:^7.12.1, @babel/core@npm:^7.12.10, @babel/core@npm:^7.12.3, @babel/core@npm:^7.18.13, @babel/core@npm:^7.18.6, @babel/core@npm:^7.7.5": - version: 7.20.12 - resolution: "@babel/core@npm:7.20.12" - dependencies: - "@ampproject/remapping": ^2.1.0 - "@babel/code-frame": ^7.18.6 - "@babel/generator": ^7.20.7 - "@babel/helper-compilation-targets": ^7.20.7 - "@babel/helper-module-transforms": ^7.20.11 - "@babel/helpers": ^7.20.7 - "@babel/parser": ^7.20.7 + "@ampproject/remapping": ^2.2.0 + "@babel/code-frame": ^7.21.4 + "@babel/generator": ^7.21.5 + "@babel/helper-compilation-targets": ^7.21.5 + "@babel/helper-module-transforms": ^7.21.5 + "@babel/helpers": ^7.21.5 + "@babel/parser": ^7.21.5 "@babel/template": ^7.20.7 - "@babel/traverse": ^7.20.12 - "@babel/types": ^7.20.7 + "@babel/traverse": ^7.21.5 + "@babel/types": ^7.21.5 convert-source-map: ^1.7.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.2 semver: ^6.3.0 - checksum: 62e6c3e2149a70b5c9729ef5f0d3e2e97e9dcde89fc039c8d8e3463d5d7ba9b29ee84d10faf79b61532ac1645aa62f2bd42338320617e6e3a8a4d8e2a27076e7 + checksum: 77ca0e6493860fb6f91cf441313c0bb464d21f8c6842cf3f1dbb083a910370e37a4c0ada35cf11ef0ebe7d0ee2d6bde2f4ee9b4caa3328e807988aa282787677 + languageName: node + linkType: hard + +"@babel/core@patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch::locator=metamask-crx%40workspace%3A.": + version: 7.21.5 + resolution: "@babel/core@patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch::version=7.21.5&hash=c84981&locator=metamask-crx%40workspace%3A." + dependencies: + "@ampproject/remapping": ^2.2.0 + "@babel/code-frame": ^7.21.4 + "@babel/generator": ^7.21.5 + "@babel/helper-compilation-targets": ^7.21.5 + "@babel/helper-module-transforms": ^7.21.5 + "@babel/helpers": ^7.21.5 + "@babel/parser": ^7.21.5 + "@babel/template": ^7.20.7 + "@babel/traverse": ^7.21.5 + "@babel/types": ^7.21.5 + convert-source-map: ^1.7.0 + debug: ^4.1.0 + gensync: ^1.0.0-beta.2 + json5: ^2.2.2 + semver: ^6.3.0 + checksum: 1b067f9452f1f9218418742e3ff28d5967bce51b251daf007cf8bc6a8e78ffee34f156d7b7f80b44017f48e3661ef88a44d4c2e9f01ad5bc43c247722c5cd9ed languageName: node linkType: hard @@ -151,14 +150,15 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.12.11, @babel/generator@npm:^7.12.5, @babel/generator@npm:^7.18.13, @babel/generator@npm:^7.20.7, @babel/generator@npm:^7.7.2": - version: 7.20.7 - resolution: "@babel/generator@npm:7.20.7" +"@babel/generator@npm:^7.12.11, @babel/generator@npm:^7.18.13, @babel/generator@npm:^7.21.5, @babel/generator@npm:^7.7.2": + version: 7.21.5 + resolution: "@babel/generator@npm:7.21.5" dependencies: - "@babel/types": ^7.20.7 + "@babel/types": ^7.21.5 "@jridgewell/gen-mapping": ^0.3.2 + "@jridgewell/trace-mapping": ^0.3.17 jsesc: ^2.5.1 - checksum: 84b6983ffdb50c80c1c2e3f3c32617a7133d8effd1065f3e0f9bba188a7d54ab42a4dd5e42b61b843c65f9dd1aa870036ff0f848ebd42707aaa8a2b6d31d04f5 + checksum: 78af737b9dd701d4c657f9731880430fa1c177767b562f4e8a330a7fe72a4abe857e3d24de4e6d9dafc1f6a11f894162d27e523d7e5948ff9e3925a0ce9867c4 languageName: node linkType: hard @@ -181,18 +181,18 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.13.0, @babel/helper-compilation-targets@npm:^7.17.7, @babel/helper-compilation-targets@npm:^7.18.9, @babel/helper-compilation-targets@npm:^7.20.0, @babel/helper-compilation-targets@npm:^7.20.7": - version: 7.20.7 - resolution: "@babel/helper-compilation-targets@npm:7.20.7" +"@babel/helper-compilation-targets@npm:^7.13.0, @babel/helper-compilation-targets@npm:^7.17.7, @babel/helper-compilation-targets@npm:^7.18.9, @babel/helper-compilation-targets@npm:^7.20.0, @babel/helper-compilation-targets@npm:^7.20.7, @babel/helper-compilation-targets@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helper-compilation-targets@npm:7.21.5" dependencies: - "@babel/compat-data": ^7.20.5 - "@babel/helper-validator-option": ^7.18.6 + "@babel/compat-data": ^7.21.5 + "@babel/helper-validator-option": ^7.21.0 browserslist: ^4.21.3 lru-cache: ^5.1.1 semver: ^6.3.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 8c32c873ba86e2e1805b30e0807abd07188acbe00ebb97576f0b09061cc65007f1312b589eccb4349c5a8c7f8bb9f2ab199d41da7030bf103d9f347dcd3a3cf4 + checksum: 0edecb9c970ddc22ebda1163e77a7f314121bef9e483e0e0d9a5802540eed90d5855b6bf9bce03419b35b2e07c323e62d0353b153fa1ca34f17dbba897a83c25 languageName: node linkType: hard @@ -259,10 +259,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.18.9": - version: 7.18.9 - resolution: "@babel/helper-environment-visitor@npm:7.18.9" - checksum: b25101f6162ddca2d12da73942c08ad203d7668e06663df685634a8fde54a98bc015f6f62938e8554457a592a024108d45b8f3e651fd6dcdb877275b73cc4420 +"@babel/helper-environment-visitor@npm:^7.18.9, @babel/helper-environment-visitor@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helper-environment-visitor@npm:7.21.5" + checksum: e436af7b62956e919066448013a3f7e2cd0b51010c26c50f790124dcd350be81d5597b4e6ed0a4a42d098a27de1e38561cd7998a116a42e7899161192deac9a6 languageName: node linkType: hard @@ -275,13 +275,13 @@ __metadata: languageName: node linkType: hard -"@babel/helper-function-name@npm:^7.18.9, @babel/helper-function-name@npm:^7.19.0": - version: 7.19.0 - resolution: "@babel/helper-function-name@npm:7.19.0" +"@babel/helper-function-name@npm:^7.18.9, @babel/helper-function-name@npm:^7.19.0, @babel/helper-function-name@npm:^7.21.0": + version: 7.21.0 + resolution: "@babel/helper-function-name@npm:7.21.0" dependencies: - "@babel/template": ^7.18.10 - "@babel/types": ^7.19.0 - checksum: eac1f5db428ba546270c2b8d750c24eb528b8fcfe50c81de2e0bdebf0e20f24bec688d4331533b782e4a907fad435244621ca2193cfcf80a86731299840e0f6e + "@babel/template": ^7.20.7 + "@babel/types": ^7.21.0 + checksum: d63e63c3e0e3e8b3138fa47b0cd321148a300ef12b8ee951196994dcd2a492cc708aeda94c2c53759a5c9177fffaac0fd8778791286746f72a000976968daf4e languageName: node linkType: hard @@ -303,28 +303,28 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.12.13, @babel/helper-module-imports@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/helper-module-imports@npm:7.18.6" +"@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.12.13, @babel/helper-module-imports@npm:^7.18.6, @babel/helper-module-imports@npm:^7.21.4": + version: 7.21.4 + resolution: "@babel/helper-module-imports@npm:7.21.4" dependencies: - "@babel/types": ^7.18.6 - checksum: f393f8a3b3304b1b7a288a38c10989de754f01d29caf62ce7c4e5835daf0a27b81f3ac687d9d2780d39685aae7b55267324b512150e7b2be967b0c493b6a1def + "@babel/types": ^7.21.4 + checksum: bd330a2edaafeb281fbcd9357652f8d2666502567c0aad71db926e8499c773c9ea9c10dfaae30122452940326d90c8caff5c649ed8e1bf15b23f858758d3abc6 languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.12.1, @babel/helper-module-transforms@npm:^7.18.6, @babel/helper-module-transforms@npm:^7.20.11": - version: 7.20.11 - resolution: "@babel/helper-module-transforms@npm:7.20.11" +"@babel/helper-module-transforms@npm:^7.18.6, @babel/helper-module-transforms@npm:^7.20.11, @babel/helper-module-transforms@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helper-module-transforms@npm:7.21.5" dependencies: - "@babel/helper-environment-visitor": ^7.18.9 - "@babel/helper-module-imports": ^7.18.6 - "@babel/helper-simple-access": ^7.20.2 + "@babel/helper-environment-visitor": ^7.21.5 + "@babel/helper-module-imports": ^7.21.4 + "@babel/helper-simple-access": ^7.21.5 "@babel/helper-split-export-declaration": ^7.18.6 "@babel/helper-validator-identifier": ^7.19.1 "@babel/template": ^7.20.7 - "@babel/traverse": ^7.20.10 - "@babel/types": ^7.20.7 - checksum: 29319ebafa693d48756c6ba0d871677bb0037e0da084fbe221a17c38d57093fc8aa38543c07d76e788266a937976e37ab4901971ca7f237c5ab45f524b9ecca0 + "@babel/traverse": ^7.21.5 + "@babel/types": ^7.21.5 + checksum: 1ccfc88830675a5d485d198e918498f9683cdd46f973fdd4fe1c85b99648fb70f87fca07756c7a05dc201bd9b248c74ced06ea80c9991926ac889f53c3659675 languageName: node linkType: hard @@ -379,12 +379,12 @@ __metadata: languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.20.2": - version: 7.20.2 - resolution: "@babel/helper-simple-access@npm:7.20.2" +"@babel/helper-simple-access@npm:^7.20.2, @babel/helper-simple-access@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helper-simple-access@npm:7.21.5" dependencies: - "@babel/types": ^7.20.2 - checksum: ad1e96ee2e5f654ffee2369a586e5e8d2722bf2d8b028a121b4c33ebae47253f64d420157b9f0a8927aea3a9e0f18c0103e74fdd531815cf3650a0a4adca11a1 + "@babel/types": ^7.21.5 + checksum: ad212beaa24be3864c8c95bee02f840222457ccf5419991e2d3e3e39b0f75b77e7e857e0bf4ed428b1cd97acefc87f3831bdb0b9696d5ad0557421f398334fc3 languageName: node linkType: hard @@ -406,10 +406,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.19.4": - version: 7.19.4 - resolution: "@babel/helper-string-parser@npm:7.19.4" - checksum: b2f8a3920b30dfac81ec282ac4ad9598ea170648f8254b10f475abe6d944808fb006aab325d3eb5a8ad3bea8dfa888cfa6ef471050dae5748497c110ec060943 +"@babel/helper-string-parser@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helper-string-parser@npm:7.21.5" + checksum: 36c0ded452f3858e67634b81960d4bde1d1cd2a56b82f4ba2926e97864816021c885f111a7cf81de88a0ed025f49d84a393256700e9acbca2d99462d648705d8 languageName: node linkType: hard @@ -420,10 +420,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/helper-validator-option@npm:7.18.6" - checksum: f9cc6eb7cc5d759c5abf006402180f8d5e4251e9198197428a97e05d65eb2f8ae5a0ce73b1dfd2d35af41d0eb780627a64edf98a4e71f064eeeacef8de58f2cf +"@babel/helper-validator-option@npm:^7.18.6, @babel/helper-validator-option@npm:^7.21.0": + version: 7.21.0 + resolution: "@babel/helper-validator-option@npm:7.21.0" + checksum: 8ece4c78ffa5461fd8ab6b6e57cc51afad59df08192ed5d84b475af4a7193fc1cb794b59e3e7be64f3cdc4df7ac78bf3dbb20c129d7757ae078e6279ff8c2f07 languageName: node linkType: hard @@ -439,14 +439,14 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.12.5, @babel/helpers@npm:^7.20.7": - version: 7.20.7 - resolution: "@babel/helpers@npm:7.20.7" +"@babel/helpers@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/helpers@npm:7.21.5" dependencies: "@babel/template": ^7.20.7 - "@babel/traverse": ^7.20.7 - "@babel/types": ^7.20.7 - checksum: 3fb10df3510ba7116a180d5fd983d0f558f7a65c3d599385dba991bff66b74174c88881bc12c2b3cf7284294fcac5b301ded49a8b0098bdf2ef61d0cad8010db + "@babel/traverse": ^7.21.5 + "@babel/types": ^7.21.5 + checksum: a6f74b8579713988e7f5adf1a986d8b5255757632ba65b2552f0f609ead5476edb784044c7e4b18f3681ee4818ca9d08c41feb9bd4e828648c25a00deaa1f9e4 languageName: node linkType: hard @@ -470,12 +470,12 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.0.0, @babel/parser@npm:^7.1.0, @babel/parser@npm:^7.10.1, @babel/parser@npm:^7.12.0, @babel/parser@npm:^7.12.11, @babel/parser@npm:^7.12.7, @babel/parser@npm:^7.13.9, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7": - version: 7.20.7 - resolution: "@babel/parser@npm:7.20.7" +"@babel/parser@npm:^7.0.0, @babel/parser@npm:^7.1.0, @babel/parser@npm:^7.10.1, @babel/parser@npm:^7.12.0, @babel/parser@npm:^7.12.11, @babel/parser@npm:^7.13.9, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.5": + version: 7.21.5 + resolution: "@babel/parser@npm:7.21.5" bin: parser: ./bin/babel-parser.js - checksum: 25b5266e3bd4be837092685f6b7ef886f1308ff72659a24342eb646ae5014f61ed1771ce8fc20636c890fcae19304fc72c069564ca6075207b7fbf3f75367275 + checksum: c7ec0dae795f2a43885fdd5c1c53c7f11b3428628ae82ebe1e1537cb3d13e25e7993549e026662a3e05dcc743b595f82b25f0a49ef9155459a9a424eedb7e2b0 languageName: node linkType: hard @@ -1645,7 +1645,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.12.7, @babel/template@npm:^7.14.5, @babel/template@npm:^7.18.10, @babel/template@npm:^7.18.6, @babel/template@npm:^7.20.7, @babel/template@npm:^7.3.3": +"@babel/template@npm:^7.14.5, @babel/template@npm:^7.18.6, @babel/template@npm:^7.20.7, @babel/template@npm:^7.3.3": version: 7.20.7 resolution: "@babel/template@npm:7.20.7" dependencies: @@ -1656,32 +1656,32 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.10.1, @babel/traverse@npm:^7.12.11, @babel/traverse@npm:^7.12.5, @babel/traverse@npm:^7.12.9, @babel/traverse@npm:^7.13.0, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.20.10, @babel/traverse@npm:^7.20.12, @babel/traverse@npm:^7.20.7, @babel/traverse@npm:^7.7.2": - version: 7.20.12 - resolution: "@babel/traverse@npm:7.20.12" +"@babel/traverse@npm:^7.10.1, @babel/traverse@npm:^7.12.11, @babel/traverse@npm:^7.12.5, @babel/traverse@npm:^7.13.0, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.20.7, @babel/traverse@npm:^7.21.5, @babel/traverse@npm:^7.7.2": + version: 7.21.5 + resolution: "@babel/traverse@npm:7.21.5" dependencies: - "@babel/code-frame": ^7.18.6 - "@babel/generator": ^7.20.7 - "@babel/helper-environment-visitor": ^7.18.9 - "@babel/helper-function-name": ^7.19.0 + "@babel/code-frame": ^7.21.4 + "@babel/generator": ^7.21.5 + "@babel/helper-environment-visitor": ^7.21.5 + "@babel/helper-function-name": ^7.21.0 "@babel/helper-hoist-variables": ^7.18.6 "@babel/helper-split-export-declaration": ^7.18.6 - "@babel/parser": ^7.20.7 - "@babel/types": ^7.20.7 + "@babel/parser": ^7.21.5 + "@babel/types": ^7.21.5 debug: ^4.1.0 globals: ^11.1.0 - checksum: d758b355ab4f1e87984524b67785fa23d74e8a45d2ceb8bcf4d5b2b0cd15ee160db5e68c7078808542805774ca3802e2eafb1b9638afa4cd7f9ecabd0ca7fd56 + checksum: b403733fa7d858f0c8e224f0434a6ade641bc469a4f92975363391e796629d5bf53e544761dfe85039aab92d5389ebe7721edb309d7a5bb7df2bf74f37bf9f47 languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.0, @babel/types@npm:^7.12.11, @babel/types@npm:^7.12.7, @babel/types@npm:^7.13.0, @babel/types@npm:^7.14.8, @babel/types@npm:^7.18.6, @babel/types@npm:^7.18.7, @babel/types@npm:^7.18.9, @babel/types@npm:^7.19.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.2, @babel/types@npm:^7.20.7, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": - version: 7.20.7 - resolution: "@babel/types@npm:7.20.7" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.0, @babel/types@npm:^7.12.11, @babel/types@npm:^7.13.0, @babel/types@npm:^7.14.8, @babel/types@npm:^7.18.6, @babel/types@npm:^7.18.7, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.2, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.0, @babel/types@npm:^7.21.4, @babel/types@npm:^7.21.5, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": + version: 7.21.5 + resolution: "@babel/types@npm:7.21.5" dependencies: - "@babel/helper-string-parser": ^7.19.4 + "@babel/helper-string-parser": ^7.21.5 "@babel/helper-validator-identifier": ^7.19.1 to-fast-properties: ^2.0.0 - checksum: b39af241f0b72bba67fd6d0d23914f6faec8c0eba8015c181cbd5ea92e59fc91a52a1ab490d3520c7dbd19ddb9ebb76c476308f6388764f16d8201e37fae6811 + checksum: 43242a99c612d13285ee4af46cc0f1066bcb6ffd38307daef7a76e8c70f36cfc3255eb9e75c8e768b40e761176c313aec4d5c0b9d97a21e494d49d5fd123a9f7 languageName: node linkType: hard @@ -3736,10 +3736,10 @@ __metadata: languageName: node linkType: hard -"@metamask/browser-passworder@npm:^4.0.2": - version: 4.0.2 - resolution: "@metamask/browser-passworder@npm:4.0.2" - checksum: 997c330b1c72f7135d0fd2a7f4b0dce37b3c2e6b30e92f048fa8d4f8c949f5b669dcc3064790f41df30ee2e53a9e64a812df72e00527736be704cce2cf4f6e49 +"@metamask/browser-passworder@npm:^4.0.2, @metamask/browser-passworder@npm:^4.1.0": + version: 4.1.0 + resolution: "@metamask/browser-passworder@npm:4.1.0" + checksum: f1edb3b75594b8e8d075b3134c9ce6c73573160eb48184ef722b9d96a5763db1e2e9acb166fc5c66c7c82936e134a02a3fb4c0022ca9a948857a30181cb84d7e languageName: node linkType: hard @@ -4208,23 +4208,23 @@ __metadata: languageName: node linkType: hard -"@metamask/permission-controller@npm:^3.0.0, @metamask/permission-controller@npm:^3.1.0": - version: 3.1.0 - resolution: "@metamask/permission-controller@npm:3.1.0" +"@metamask/permission-controller@npm:^3.0.0, @metamask/permission-controller@npm:^3.1.0, @metamask/permission-controller@npm:^3.2.0": + version: 3.2.0 + resolution: "@metamask/permission-controller@npm:3.2.0" dependencies: - "@metamask/approval-controller": ^2.0.0 + "@metamask/approval-controller": ^2.1.1 "@metamask/base-controller": ^2.0.0 - "@metamask/controller-utils": ^3.1.0 + "@metamask/controller-utils": ^3.4.0 "@metamask/types": ^1.1.0 "@types/deep-freeze-strict": ^1.1.0 deep-freeze-strict: ^1.1.1 - eth-rpc-errors: ^4.0.0 + eth-rpc-errors: ^4.0.2 immer: ^9.0.6 json-rpc-engine: ^6.1.0 nanoid: ^3.1.31 peerDependencies: - "@metamask/approval-controller": ^2.0.0 - checksum: 91c615e2faf9c1ce16371602e99354178d79a0af0697f1c3c81c860c2e9972f23e8189290cd41423c3df3048906bbf55c01fef8326677f2ea5cbcfdfb6a58db6 + "@metamask/approval-controller": ^2.1.1 + checksum: 34650f2d9b51170fc9b2a56d2004a2cd2ca3f427e9dad2e3229bbd0b1dfad40a98f639752b1bfe17946c39677e4c8fe52581b5dbbf42e4a18e83b72e8e06d9b0 languageName: node linkType: hard @@ -4258,13 +4258,13 @@ __metadata: languageName: node linkType: hard -"@metamask/post-message-stream@npm:^6.0.0, @metamask/post-message-stream@npm:^6.1.1": - version: 6.1.1 - resolution: "@metamask/post-message-stream@npm:6.1.1" +"@metamask/post-message-stream@npm:^6.0.0, @metamask/post-message-stream@npm:^6.1.1, @metamask/post-message-stream@npm:^6.1.2": + version: 6.1.2 + resolution: "@metamask/post-message-stream@npm:6.1.2" dependencies: - "@metamask/utils": ^4.0.0 + "@metamask/utils": ^5.0.0 readable-stream: 2.3.3 - checksum: 588988d555ff20e0d60ed2de71e804d96963a9d4c07716901d5ae13100eb0f97c49eb6b2dbd93ac408098067c0e12cbfca90fed345fecdb69c92e852ab28c0b4 + checksum: 3591ec9b7fd602806b07cbc0fed5075fb7a347c279c43ef1f25fbdd8634dfcad9ce192ae59457fb76554ef0bc15cbf25cfaa5875aee2d72668a273b7a6852c32 languageName: node linkType: hard @@ -4309,7 +4309,25 @@ __metadata: languageName: node linkType: hard -"@metamask/rpc-methods-flask@npm:@metamask/rpc-methods@0.32.2, @metamask/rpc-methods@npm:^0.32.2": +"@metamask/rpc-methods-flask@npm:@metamask/rpc-methods@0.33.1-flask.1, @metamask/rpc-methods@npm:^0.33.1-flask.1": + version: 0.33.1-flask.1 + resolution: "@metamask/rpc-methods@npm:0.33.1-flask.1" + dependencies: + "@metamask/key-tree": ^7.0.0 + "@metamask/permission-controller": ^3.2.0 + "@metamask/snaps-ui": ^0.33.1-flask.1 + "@metamask/snaps-utils": ^0.33.1-flask.1 + "@metamask/types": ^1.1.0 + "@metamask/utils": ^5.0.0 + "@noble/hashes": ^1.1.3 + eth-rpc-errors: ^4.0.3 + nanoid: ^3.1.31 + superstruct: ^1.0.3 + checksum: 1a7fd246944b68c8b70ab64e5db544b175b68195cca4a2692bf34bca7f5c55eab248156e4702152f044c49c644ad82a92d1b328fcfa876291665d2a8c2ae7dce + languageName: node + linkType: hard + +"@metamask/rpc-methods@npm:^0.32.2": version: 0.32.2 resolution: "@metamask/rpc-methods@npm:0.32.2" dependencies: @@ -4386,7 +4404,37 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-controllers-flask@npm:@metamask/snaps-controllers@0.32.2, @metamask/snaps-controllers@npm:^0.32.2": +"@metamask/snaps-controllers-flask@npm:@metamask/snaps-controllers@0.33.1-flask.1": + version: 0.33.1-flask.1 + resolution: "@metamask/snaps-controllers@npm:0.33.1-flask.1" + dependencies: + "@metamask/approval-controller": ^2.0.0 + "@metamask/base-controller": ^2.0.0 + "@metamask/object-multiplex": ^1.2.0 + "@metamask/permission-controller": ^3.2.0 + "@metamask/post-message-stream": ^6.1.2 + "@metamask/rpc-methods": ^0.33.1-flask.1 + "@metamask/snaps-execution-environments": ^0.33.1-flask.1 + "@metamask/snaps-registry": ^1.2.0 + "@metamask/snaps-utils": ^0.33.1-flask.1 + "@metamask/utils": ^5.0.0 + "@xstate/fsm": ^2.0.0 + concat-stream: ^2.0.0 + cron-parser: ^4.5.0 + eth-rpc-errors: ^4.0.3 + gunzip-maybe: ^1.4.2 + immer: ^9.0.6 + json-rpc-engine: ^6.1.0 + json-rpc-middleware-stream: ^4.2.0 + nanoid: ^3.1.31 + pump: ^3.0.0 + readable-web-to-node-stream: ^3.0.2 + tar-stream: ^2.2.0 + checksum: 26fcba72c8bcb84783a970db4af2bfec65429a7206eadc05856873739b85aebd75b0d8d6062eadb9fffce30c436f79ff4bbca9d15e9e80016f1b27ac5e8693bc + languageName: node + linkType: hard + +"@metamask/snaps-controllers@npm:^0.32.2": version: 0.32.2 resolution: "@metamask/snaps-controllers@npm:0.32.2" dependencies: @@ -4437,6 +4485,27 @@ __metadata: languageName: node linkType: hard +"@metamask/snaps-execution-environments@npm:^0.33.1-flask.1": + version: 0.33.1-flask.1 + resolution: "@metamask/snaps-execution-environments@npm:0.33.1-flask.1" + dependencies: + "@metamask/object-multiplex": ^1.2.0 + "@metamask/post-message-stream": ^6.1.2 + "@metamask/providers": ^10.2.1 + "@metamask/rpc-methods": ^0.33.1-flask.1 + "@metamask/snaps-utils": ^0.33.1-flask.1 + "@metamask/utils": ^5.0.0 + eth-rpc-errors: ^4.0.3 + json-rpc-engine: ^6.1.0 + nanoid: ^3.1.31 + pump: ^3.0.0 + ses: ^0.18.1 + stream-browserify: ^3.0.0 + superstruct: ^1.0.3 + checksum: e86d70befbb6e3639368d7974f3e89ef343be1932a606a4b77ddfafdc0ed672a227481458e8935392bad9494c82deb75b6e1761606baea08ff165f4e6974f262 + languageName: node + linkType: hard + "@metamask/snaps-registry@npm:^1.2.0": version: 1.2.0 resolution: "@metamask/snaps-registry@npm:1.2.0" @@ -4448,7 +4517,17 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-ui-flask@npm:@metamask/snaps-ui@0.32.2, @metamask/snaps-ui@npm:^0.32.2": +"@metamask/snaps-ui-flask@npm:@metamask/snaps-ui@0.33.1-flask.1, @metamask/snaps-ui@npm:^0.33.1-flask.1": + version: 0.33.1-flask.1 + resolution: "@metamask/snaps-ui@npm:0.33.1-flask.1" + dependencies: + "@metamask/utils": ^5.0.0 + superstruct: ^1.0.3 + checksum: 52f00f1ac1e23da1fbb0307cd5bdc620cf9c235ee94a6cb6fb4fd38da0677a5d8df501952e3b7119bac918c3a56e8ffe453cbff0b2be35d3b882882deac65dc4 + languageName: node + linkType: hard + +"@metamask/snaps-ui@npm:^0.32.2": version: 0.32.2 resolution: "@metamask/snaps-ui@npm:0.32.2" dependencies: @@ -4458,7 +4537,34 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-utils-flask@npm:@metamask/snaps-utils@0.32.2, @metamask/snaps-utils@npm:^0.32.2": +"@metamask/snaps-utils-flask@npm:@metamask/snaps-utils@0.33.1-flask.1, @metamask/snaps-utils@npm:^0.33.1-flask.1": + version: 0.33.1-flask.1 + resolution: "@metamask/snaps-utils@npm:0.33.1-flask.1" + dependencies: + "@babel/core": ^7.20.12 + "@babel/types": ^7.18.7 + "@metamask/base-controller": ^2.0.0 + "@metamask/permission-controller": ^3.2.0 + "@metamask/providers": ^10.2.1 + "@metamask/snaps-registry": ^1.2.0 + "@metamask/snaps-ui": ^0.33.1-flask.1 + "@metamask/utils": ^5.0.0 + "@noble/hashes": ^1.1.3 + "@scure/base": ^1.1.1 + cron-parser: ^4.5.0 + eth-rpc-errors: ^4.0.3 + fast-deep-equal: ^3.1.3 + fast-json-stable-stringify: ^2.1.0 + rfdc: ^1.3.0 + semver: ^7.3.7 + ses: ^0.18.1 + superstruct: ^1.0.3 + validate-npm-package-name: ^5.0.0 + checksum: 15a87d290423a31f3113aa65cb7076e5220f5697e4614eb9f4b7bf1e4b55e83a6545f05311d34555e05e111e94309f75154ae889eb593beef71010e9dae18c12 + languageName: node + linkType: hard + +"@metamask/snaps-utils@npm:^0.32.2": version: 0.32.2 resolution: "@metamask/snaps-utils@npm:0.32.2" dependencies: @@ -4530,18 +4636,6 @@ __metadata: languageName: node linkType: hard -"@metamask/utils@npm:^4.0.0": - version: 4.0.0 - resolution: "@metamask/utils@npm:4.0.0" - dependencies: - "@types/debug": ^4.1.7 - debug: ^4.3.4 - semver: ^7.3.8 - superstruct: ^1.0.3 - checksum: 6d4edca78fe1f66504ed5e5ca021a67f4b4e0893e86484c746b87039c2161c39d3b8bd8e4b9235ddfd023b2d76dd54210af94ec5550e27bc4ad9c0d7d5f3f231 - languageName: node - linkType: hard - "@metamask/utils@npm:^5.0.0, @metamask/utils@npm:^5.0.1": version: 5.0.1 resolution: "@metamask/utils@npm:5.0.1" @@ -17738,7 +17832,7 @@ __metadata: languageName: node linkType: hard -"gensync@npm:^1.0.0-beta.1, gensync@npm:^1.0.0-beta.2": +"gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" checksum: a7437e58c6be12aa6c90f7730eac7fa9833dc78872b4ad2963d2031b00a3367a93f98aec75f9aaac7220848e4026d67a8655e870b24f20a543d103c0d65952ec @@ -24058,6 +24152,7 @@ __metadata: "@metamask/assets-controllers": ^6.0.0 "@metamask/auto-changelog": ^2.1.0 "@metamask/base-controller": ^2.0.0 + "@metamask/browser-passworder": ^4.1.0 "@metamask/contract-metadata": ^2.3.1 "@metamask/controller-utils": ^3.3.0 "@metamask/design-tokens": ^1.9.0 @@ -24084,25 +24179,25 @@ __metadata: "@metamask/metamask-eth-abis": ^3.0.0 "@metamask/notification-controller": ^2.0.0 "@metamask/obs-store": ^8.1.0 - "@metamask/permission-controller": ^3.1.0 + "@metamask/permission-controller": ^3.2.0 "@metamask/phishing-controller": ^3.0.0 "@metamask/phishing-warning": ^2.1.0 "@metamask/post-message-stream": ^6.0.0 "@metamask/providers": ^10.2.1 "@metamask/rate-limit-controller": ^2.0.0 "@metamask/rpc-methods": ^0.32.2 - "@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.32.2" + "@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.33.1-flask.1" "@metamask/safe-event-emitter": ^2.0.0 "@metamask/scure-bip39": ^2.0.3 "@metamask/signature-controller": ^2.0.0 "@metamask/slip44": ^3.0.0 "@metamask/smart-transactions-controller": ^3.1.0 "@metamask/snaps-controllers": ^0.32.2 - "@metamask/snaps-controllers-flask": "npm:@metamask/snaps-controllers@0.32.2" + "@metamask/snaps-controllers-flask": "npm:@metamask/snaps-controllers@0.33.1-flask.1" "@metamask/snaps-ui": ^0.32.2 - "@metamask/snaps-ui-flask": "npm:@metamask/snaps-ui@0.32.2" + "@metamask/snaps-ui-flask": "npm:@metamask/snaps-ui@0.33.1-flask.1" "@metamask/snaps-utils": ^0.32.2 - "@metamask/snaps-utils-flask": "npm:@metamask/snaps-utils@0.32.2" + "@metamask/snaps-utils-flask": "npm:@metamask/snaps-utils@0.33.1-flask.1" "@metamask/subject-metadata-controller": ^2.0.0 "@metamask/swappable-obj-proxy": ^2.1.0 "@metamask/test-dapp": ^6.0.0 @@ -29797,7 +29892,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.4, resolve@npm:^1.1.5, resolve@npm:^1.1.6, resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.10.1, resolve@npm:^1.11.1, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.15.1, resolve@npm:^1.17.0, resolve@npm:^1.18.1, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.21.0, resolve@npm:^1.22.0, resolve@npm:^1.22.1, resolve@npm:^1.3.2, resolve@npm:^1.4.0": +"resolve@npm:^1.1.4, resolve@npm:^1.1.5, resolve@npm:^1.1.6, resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.10.1, resolve@npm:^1.11.1, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.15.1, resolve@npm:^1.17.0, resolve@npm:^1.18.1, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.21.0, resolve@npm:^1.22.0, resolve@npm:^1.22.1, resolve@npm:^1.4.0": version: 1.22.3 resolution: "resolve@npm:1.22.3" dependencies: @@ -29830,8 +29925,7 @@ __metadata: languageName: node linkType: hard -? "resolve@patch:resolve@^1.1.4#~builtin, resolve@patch:resolve@^1.1.5#~builtin, resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.1.7#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.10.1#~builtin, resolve@patch:resolve@^1.11.1#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.15.1#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.18.1#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.21.0#~builtin, resolve@patch:resolve@^1.22.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.3.2#~builtin, resolve@patch:resolve@^1.4.0#~builtin" -: +"resolve@patch:resolve@^1.1.4#~builtin, resolve@patch:resolve@^1.1.5#~builtin, resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.1.7#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.10.1#~builtin, resolve@patch:resolve@^1.11.1#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.15.1#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.18.1#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.21.0#~builtin, resolve@patch:resolve@^1.22.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.4.0#~builtin": version: 1.22.3 resolution: "resolve@patch:resolve@npm%3A1.22.3#~builtin::version=1.22.3&hash=07638b" dependencies: @@ -30507,7 +30601,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.0.3, semver@npm:^5.1.0, semver@npm:^5.3.0, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.0.3, semver@npm:^5.1.0, semver@npm:^5.3.0, semver@npm:^5.5.0, semver@npm:^5.6.0": version: 5.7.1 resolution: "semver@npm:5.7.1" bin: @@ -31196,7 +31290,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.5.0, source-map@npm:^0.5.1, source-map@npm:^0.5.6, source-map@npm:^0.5.7, source-map@npm:~0.5.3": +"source-map@npm:^0.5.1, source-map@npm:^0.5.6, source-map@npm:^0.5.7, source-map@npm:~0.5.3": version: 0.5.7 resolution: "source-map@npm:0.5.7" checksum: 5dc2043b93d2f194142c7f38f74a24670cd7a0063acdaf4bf01d2964b402257ae843c2a8fa822ad5b71013b5fcafa55af7421383da919752f22ff488bc553f4d From 8a8c8fad1075c2ec40686a387b889d6374fe7f7c Mon Sep 17 00:00:00 2001 From: Harsh Shukla <125105825+PrgrmrHarshShukla@users.noreply.github.com> Date: Mon, 15 May 2023 23:20:49 +0530 Subject: [PATCH 048/120] Part of ##18714 Replace deprecated design system typography consts with enums in: confirm-page-container.component.js (#19065) --- .../confirm-page-container.component.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/components/app/confirm-page-container/confirm-page-container.component.js b/ui/components/app/confirm-page-container/confirm-page-container.component.js index 5ae5819ea..b4fb0e5d1 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container.component.js +++ b/ui/components/app/confirm-page-container/confirm-page-container.component.js @@ -25,7 +25,7 @@ import { INSUFFICIENT_FUNDS_ERROR_KEY } from '../../../helpers/constants/error-k import { Text } from '../../component-library'; import { TextVariant, - TEXT_ALIGN, + TextAlign, } from '../../../helpers/constants/design-system'; import NetworkAccountBalanceHeader from '../network-account-balance-header/network-account-balance-header'; @@ -247,7 +247,7 @@ const ConfirmPageContainer = (props) => { isBuyableChain ? ( {t('insufficientCurrencyBuyOrDeposit', [ @@ -278,7 +278,7 @@ const ConfirmPageContainer = (props) => { ) : ( {t('insufficientCurrencyDeposit', [ From c9f420234fe56158011fb9f4938db6ae765a18e3 Mon Sep 17 00:00:00 2001 From: Dhruv <79097544+dhruvv173@users.noreply.github.com> Date: Mon, 15 May 2023 23:26:20 +0530 Subject: [PATCH 049/120] Changes to gas-items-details (#19075) --- .../gas-details-item-title.js | 16 ++++++++-------- .../gas-details-item-title.stories.js | 10 ++++++++++ .../gas-details-item/gas-details-item.stories.js | 10 ++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 ui/components/app/gas-details-item/gas-details-item-title/gas-details-item-title.stories.js create mode 100644 ui/components/app/gas-details-item/gas-details-item.stories.js diff --git a/ui/components/app/gas-details-item/gas-details-item-title/gas-details-item-title.js b/ui/components/app/gas-details-item/gas-details-item-title/gas-details-item-title.js index 00a25e36e..9e7c267dd 100644 --- a/ui/components/app/gas-details-item/gas-details-item-title/gas-details-item-title.js +++ b/ui/components/app/gas-details-item/gas-details-item-title/gas-details-item-title.js @@ -1,12 +1,12 @@ import React from 'react'; import { useSelector } from 'react-redux'; -import { TypographyVariant } from '../../../../helpers/constants/design-system'; +import { TextVariant } from '../../../../helpers/constants/design-system'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import { getIsMainnet } from '../../../../selectors'; import Box from '../../../ui/box'; import InfoTooltip from '../../../ui/info-tooltip/info-tooltip'; -import Typography from '../../../ui/typography/typography'; +import { Text } from '../../../component-library'; const GasDetailsItemTitle = () => { const t = useI18nContext(); @@ -21,15 +21,15 @@ const GasDetailsItemTitle = () => { - + {t('transactionDetailGasTooltipIntro', [ isMainnet ? t('networkNameEthereum') : '', ])} - - + + {t('transactionDetailGasTooltipExplanation')} - - + + { > {t('transactionDetailGasTooltipConversion')} - + } position="bottom" diff --git a/ui/components/app/gas-details-item/gas-details-item-title/gas-details-item-title.stories.js b/ui/components/app/gas-details-item/gas-details-item-title/gas-details-item-title.stories.js new file mode 100644 index 000000000..33978b407 --- /dev/null +++ b/ui/components/app/gas-details-item/gas-details-item-title/gas-details-item-title.stories.js @@ -0,0 +1,10 @@ +import React from 'react'; +import GasDetailsItemTitle from '.'; + +export default { + title: 'Components/App/GasDetailsItemTitle', +}; + +export const DefaultStory = () => ; + +DefaultStory.storyName = 'Default'; diff --git a/ui/components/app/gas-details-item/gas-details-item.stories.js b/ui/components/app/gas-details-item/gas-details-item.stories.js new file mode 100644 index 000000000..f676c7786 --- /dev/null +++ b/ui/components/app/gas-details-item/gas-details-item.stories.js @@ -0,0 +1,10 @@ +import React from 'react'; +import GasDetailsItem from '.'; + +export default { + title: 'Components/App/GasDetailsItem', +}; + +export const DefaultStory = () => ; + +DefaultStory.storyName = 'Default'; From 5135b80de7fb274c86aae94430a86ac8c5391e6a Mon Sep 17 00:00:00 2001 From: Dhruv <79097544+dhruvv173@users.noreply.github.com> Date: Mon, 15 May 2023 23:38:48 +0530 Subject: [PATCH 050/120] Part of #18714 and #17670: Changes to nfts-detection-notice.js (#19051) * Changes to nfts-detection-notice.js * Adding story --------- Co-authored-by: georgewrmarshall --- .../nfts-detection-notice.js | 30 ++++++++++--------- .../nfts-detection-notice.stories.js | 10 +++++++ 2 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 ui/components/app/nfts-detection-notice/nfts-detection-notice.stories.js diff --git a/ui/components/app/nfts-detection-notice/nfts-detection-notice.js b/ui/components/app/nfts-detection-notice/nfts-detection-notice.js index 84d90c5d7..c724625db 100644 --- a/ui/components/app/nfts-detection-notice/nfts-detection-notice.js +++ b/ui/components/app/nfts-detection-notice/nfts-detection-notice.js @@ -2,11 +2,11 @@ import React from 'react'; import { useHistory } from 'react-router-dom'; import Box from '../../ui/box'; import Dialog from '../../ui/dialog'; -import Typography from '../../ui/typography/typography'; +import { Text } from '../../component-library'; import { - TypographyVariant, - TEXT_ALIGN, - FONT_WEIGHT, + TextVariant, + TextAlign, + FontWeight, DISPLAY, TextColor, IconColor, @@ -32,22 +32,24 @@ export default function NftsDetectionNotice() { /> - {t('newNFTsDetected')} - - + {t('newNFTDetectedMessage')} - + , + ///: END:ONLY_INCLUDE_IN ])} ) : ( diff --git a/ui/components/app/confirm-page-container/confirm-page-container.component.js b/ui/components/app/confirm-page-container/confirm-page-container.component.js index b4fb0e5d1..345ceb9e8 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container.component.js +++ b/ui/components/app/confirm-page-container/confirm-page-container.component.js @@ -99,6 +99,9 @@ const ConfirmPageContainer = (props) => { txData, assetStandard, isApprovalOrRejection, + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + noteComponent, + ///: END:ONLY_INCLUDE_IN } = props; const t = useI18nContext(); @@ -238,6 +241,9 @@ const ConfirmPageContainer = (props) => { transactionType={currentTransaction.type} isBuyableChain={isBuyableChain} txData={txData} + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + noteComponent={noteComponent} + ///: END:ONLY_INCLUDE_IN /> )} {shouldDisplayWarning && errorKey === INSUFFICIENT_FUNDS_ERROR_KEY && ( @@ -398,6 +404,9 @@ ConfirmPageContainer.propTypes = { supportsEIP1559: PropTypes.bool, nativeCurrency: PropTypes.string, isApprovalOrRejection: PropTypes.bool, + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) + noteComponent: PropTypes.node, + ///: END:ONLY_INCLUDE_IN }; export default ConfirmPageContainer; diff --git a/ui/components/institutional/note-to-trader/__snapshots__/note-to-trader.test.js.snap b/ui/components/institutional/note-to-trader/__snapshots__/note-to-trader.test.js.snap index 73e3cc2dd..86cb4de6e 100644 --- a/ui/components/institutional/note-to-trader/__snapshots__/note-to-trader.test.js.snap +++ b/ui/components/institutional/note-to-trader/__snapshots__/note-to-trader.test.js.snap @@ -3,33 +3,41 @@ exports[`NoteToTrader should render the Note to trader component 1`] = `
- -

- 9 - / - 280 -

-
-
- +
+ +

+ 9 + / + 280 +

+
+
+ +
+
`; diff --git a/ui/components/institutional/note-to-trader/note-to-trader.js b/ui/components/institutional/note-to-trader/note-to-trader.js index 5d8ba4c92..459ef49de 100644 --- a/ui/components/institutional/note-to-trader/note-to-trader.js +++ b/ui/components/institutional/note-to-trader/note-to-trader.js @@ -12,33 +12,35 @@ const NoteToTrader = (props) => { const { placeholder, maxLength, onChange, noteText, labelText } = props; return ( - <> - - - - {noteText.length}/{maxLength} - + + + + + + {noteText.length}/{maxLength} + + + +