From 9b4cd28f71bd2193b3fc0e1936438428fe36fa6b Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Thu, 30 Oct 2025 07:44:55 -0400 Subject: [PATCH 01/68] Set `react-hooks/rules-of-hooks` eslint ruleset to "error" --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 69d22b3376dd..6910b5b13d4b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -377,7 +377,7 @@ module.exports = { 'react/prop-types': 'off', 'react/no-children-prop': 'off', 'react/jsx-key': 'warn', // TODO - increase this into 'error' level - 'react-hooks/rules-of-hooks': 'warn', // TODO - increase this into 'error' level + 'react-hooks/rules-of-hooks': 'error', }, settings: { react: { From af51e2b08505577a81b809f46f5aeefc108c7464 Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Thu, 30 Oct 2025 08:33:13 -0400 Subject: [PATCH 02/68] Fix `rules-of-hooks` violations --- .../alert-system/alert-modal/alert-modal.tsx | 2 +- .../configure-snap-popup.stories.tsx | 4 +- .../snap-install-warning.stories.tsx | 34 ++-- .../modal-footer/modal-footer.stories.tsx | 2 +- .../useMultichainAccountTotalFiatBalance.ts | 12 +- .../batch-simulation-details.tsx | 16 +- .../confirm/info/typed-sign/typed-sign.tsx | 22 ++- .../confirm/ledger-info/ledger-info.tsx | 5 +- .../confusable-recipient-name.tsx | 24 ++- .../useSimulationMetrics.test.ts | 174 ++++++++++-------- .../confirmations/hooks/syncConfirmPath.ts | 4 +- .../notification-components/snap/snap.tsx | 3 +- .../smart-transaction-status-page.tsx | 11 +- 13 files changed, 179 insertions(+), 134 deletions(-) diff --git a/ui/components/app/alert-system/alert-modal/alert-modal.tsx b/ui/components/app/alert-system/alert-modal/alert-modal.tsx index f4b53fd126b2..0ab72a98096d 100644 --- a/ui/components/app/alert-system/alert-modal/alert-modal.tsx +++ b/ui/components/app/alert-system/alert-modal/alert-modal.tsx @@ -258,12 +258,12 @@ export function AcknowledgeCheckboxBase({ label?: string; }) { const t = useI18nContext(); + const severityStyle = getSeverityStyle(selectedAlert.severity); if (!requiresAcknowledgement(selectedAlert)) { return null; } - const severityStyle = getSeverityStyle(selectedAlert.severity); return ( { + render: function Render(args) { const [{ isOpen }, updateArgs] = useArgs(); const handleClose = () => { updateArgs({ isOpen: false }); @@ -67,7 +67,7 @@ export const Install: Story = { args: { type: ConfigureSnapPopupType.INSTALL, }, - render: (args) => { + render: function Render(args) { const [{ isOpen }, updateArgs] = useArgs(); const handleClose = () => { updateArgs({ isOpen: false }); diff --git a/ui/components/app/snaps/snap-install-warning/snap-install-warning.stories.tsx b/ui/components/app/snaps/snap-install-warning/snap-install-warning.stories.tsx index 5b8c7b43e683..b3b8b42fbf57 100644 --- a/ui/components/app/snaps/snap-install-warning/snap-install-warning.stories.tsx +++ b/ui/components/app/snaps/snap-install-warning/snap-install-warning.stories.tsx @@ -42,24 +42,24 @@ export default meta; type Story = StoryObj; export const Default: Story = { - render:(args) => { - const [showWarning, setShowWarning] = useState(false); + render: function Render(args) { + const [showWarning, setShowWarning] = useState(false); - const handleOpen = () => { - setShowWarning(true); - }; + const handleOpen = () => { + setShowWarning(true); + }; - return ( -
- - {showWarning && ( - setShowWarning(false)} - onSubmit={() => setShowWarning(false)} - /> - )} -
- ); + return ( +
+ + {showWarning && ( + setShowWarning(false)} + onSubmit={() => setShowWarning(false)} + /> + )} +
+ ); }, }; diff --git a/ui/components/component-library/modal-footer/modal-footer.stories.tsx b/ui/components/component-library/modal-footer/modal-footer.stories.tsx index b2aefc730b6f..53dc15f15828 100644 --- a/ui/components/component-library/modal-footer/modal-footer.stories.tsx +++ b/ui/components/component-library/modal-footer/modal-footer.stories.tsx @@ -146,7 +146,7 @@ export const Children: Story = { args: { children: 'Lorem ipsum dolor sit ', }, - render: (args) => { + render: function Render(args) { const [checked, setChecked] = React.useState(false); const handleCheckboxChange = () => setChecked(!checked); return ( diff --git a/ui/hooks/useMultichainAccountTotalFiatBalance.ts b/ui/hooks/useMultichainAccountTotalFiatBalance.ts index 47be7ce8e91e..72619c26a77c 100644 --- a/ui/hooks/useMultichainAccountTotalFiatBalance.ts +++ b/ui/hooks/useMultichainAccountTotalFiatBalance.ts @@ -41,10 +41,10 @@ export const useMultichainAccountTotalFiatBalance = ( loading: boolean; orderedTokenList: { iconUrl: string; symbol: string; fiatBalance: string }[]; } => { - if (isEvmAccountType(account.type)) { - return useAccountTotalFiatBalance(account, shouldHideZeroBalanceTokens); - } - + const accountTotalFiatBalance = useAccountTotalFiatBalance( + account, + shouldHideZeroBalanceTokens, + ); const currentCurrency = useMultichainSelector( getMultichainCurrentCurrency, account, @@ -67,6 +67,10 @@ export const useMultichainAccountTotalFiatBalance = ( ticker as keyof typeof MULTICHAIN_NATIVE_CURRENCY_TO_CAIP19 ]; + if (isEvmAccountType(account.type)) { + return accountTotalFiatBalance; + } + if (!balances?.[account.id]?.[asset]) { // FIXME: We might try to get the balance for a created account, but the // MultichainBalancesController might not have updated it yet! diff --git a/ui/pages/confirmations/components/confirm/info/batch/batch-simulation-details/batch-simulation-details.tsx b/ui/pages/confirmations/components/confirm/info/batch/batch-simulation-details/batch-simulation-details.tsx index 67341bec5e58..f5e8ab073b91 100644 --- a/ui/pages/confirmations/components/confirm/info/batch/batch-simulation-details/batch-simulation-details.tsx +++ b/ui/pages/confirmations/components/confirm/info/batch/batch-simulation-details/batch-simulation-details.tsx @@ -58,13 +58,6 @@ export function BatchSimulationDetails() { [id, nestedTransactionIndexToEdit], ); - if ( - transactionMeta?.type === TransactionType.revokeDelegation || - isUpgradeOnly - ) { - return null; - } - const approveRows: StaticRow[] = useMemo(() => { const finalBalanceChanges = approveBalanceChanges?.map((change) => ({ ...change, @@ -80,7 +73,14 @@ export function BatchSimulationDetails() { balanceChanges: finalBalanceChanges ?? [], }, ]; - }, [approveBalanceChanges, handleEdit]); + }, [approveBalanceChanges, handleEdit, t]); + + if ( + transactionMeta?.type === TransactionType.revokeDelegation || + isUpgradeOnly + ) { + return null; + } const nestedTransactionToEdit = nestedTransactionIndexToEdit === undefined diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx index 83c2ed48f8a8..0c2b0eb1b308 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx @@ -27,14 +27,11 @@ import { NetworkRow } from '../shared/network-row/network-row'; import { SigningInWithRow } from '../shared/sign-in-with-row/sign-in-with-row'; import { TypedSignV4Simulation } from './typed-sign-v4-simulation'; -const TypedSignInfo: React.FC = () => { - const t = useI18nContext(); +const useTokenContract = () => { const { currentConfirmation } = useConfirmContext(); - const isSimulationSupported = useTypesSignSimulationEnabledInfo(); - const isBIP44 = useIsBIP44(); if (!currentConfirmation?.msgParams) { - return null; + return {}; } const { @@ -45,8 +42,23 @@ const TypedSignInfo: React.FC = () => { const isPermit = isPermitSignatureRequest(currentConfirmation); const isOrder = isOrderSignatureRequest(currentConfirmation); const tokenContract = isPermit || isOrder ? verifyingContract : undefined; + + return { tokenContract, verifyingContract, spender, isPermit }; +}; + +const TypedSignInfo: React.FC = () => { + const t = useI18nContext(); + const isSimulationSupported = useTypesSignSimulationEnabledInfo(); + const isBIP44 = useIsBIP44(); + const { tokenContract, verifyingContract, spender, isPermit } = + useTokenContract(); const { decimalsNumber } = useGetTokenStandardAndDetails(tokenContract); + const { currentConfirmation } = useConfirmContext(); + if (!currentConfirmation?.msgParams) { + return null; + } + const chainId = currentConfirmation.chainId as string; const toolTipMessage = isSnapId(currentConfirmation.msgParams.origin) diff --git a/ui/pages/confirmations/components/confirm/ledger-info/ledger-info.tsx b/ui/pages/confirmations/components/confirm/ledger-info/ledger-info.tsx index e6fd75669d38..b11b718febd3 100644 --- a/ui/pages/confirmations/components/confirm/ledger-info/ledger-info.tsx +++ b/ui/pages/confirmations/components/confirm/ledger-info/ledger-info.tsx @@ -38,9 +38,12 @@ const LedgerInfo: React.FC = () => { const inE2eTest = process.env.IN_TEST && process.env.JEST_WORKER_ID === 'undefined'; + const ledgerWebHidConnectedStatus = useSelector( + getLedgerWebHidConnectedStatus, + ); const webHidConnectedStatus = inE2eTest ? WebHIDConnectedStatuses.connected - : useSelector(getLedgerWebHidConnectedStatus); + : ledgerWebHidConnectedStatus; const ledgerTransportType = useSelector(getLedgerTransportType); const transportStatus = useSelector(getLedgerTransportStatus); const environmentType = getEnvironmentType(); diff --git a/ui/pages/confirmations/components/send/recipient-input/confusable-recipient-name.tsx b/ui/pages/confirmations/components/send/recipient-input/confusable-recipient-name.tsx index cddf805e3249..d760967eb171 100644 --- a/ui/pages/confirmations/components/send/recipient-input/confusable-recipient-name.tsx +++ b/ui/pages/confirmations/components/send/recipient-input/confusable-recipient-name.tsx @@ -33,11 +33,10 @@ export const ConfusableRecipientName = ({ const t = useI18nContext(); const { to } = useSendContext(); - if (!to) { - return null; - } - const nameSplits = useMemo(() => { + if (!to) { + return null; + } const confusableList = confusableCharacters.flatMap((confusable) => findAllIndexesOfConfusable(to, confusable), ); @@ -59,20 +58,21 @@ export const ConfusableRecipientName = ({ return splits; }, [to, confusableCharacters]); - return ( + return nameSplits ? ( - {nameSplits.map((split) => { + {nameSplits.map((split, index) => { if (split.confusable) { return ( {t('confusableCharacterTooltip', [ - + {` ‘${split.confusable.point}’ `} , - + {` ‘${split.confusable.similarTo}’`}. , ])} @@ -89,8 +89,12 @@ export const ConfusableRecipientName = ({ ); } - return {split.str}; + return ( + + {split.str} + + ); })} - ); + ) : null; }; diff --git a/ui/pages/confirmations/components/simulation-details/useSimulationMetrics.test.ts b/ui/pages/confirmations/components/simulation-details/useSimulationMetrics.test.ts index e0f8da30703c..8565969d55cc 100644 --- a/ui/pages/confirmations/components/simulation-details/useSimulationMetrics.test.ts +++ b/ui/pages/confirmations/components/simulation-details/useSimulationMetrics.test.ts @@ -96,7 +96,7 @@ describe('useSimulationMetrics', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any let trackEventMock: jest.MockedFunction; - function expectUpdateTransactionEventFragmentCalled( + function useExpectUpdateTransactionEventFragmentCalled( { balanceChanges, simulationData, @@ -200,17 +200,19 @@ describe('useSimulationMetrics', () => { useDisplayNamesMock.mockReset(); useDisplayNamesMock.mockReturnValue([]); - expectUpdateTransactionEventFragmentCalled( - { - simulationData: simulationData as SimulationData, - }, - expect.objectContaining({ - properties: expect.objectContaining({ - // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 - // eslint-disable-next-line @typescript-eslint/naming-convention - simulation_response: simulationResponse, + renderHook(() => + useExpectUpdateTransactionEventFragmentCalled( + { + simulationData: simulationData as SimulationData, + }, + expect.objectContaining({ + properties: expect.objectContaining({ + // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 + // eslint-disable-next-line @typescript-eslint/naming-convention + simulation_response: simulationResponse, + }), }), - }), + ), ); }, ); @@ -227,15 +229,17 @@ describe('useSimulationMetrics', () => { amount: new BigNumber(isNegative ? -1 : 1), }; - expectUpdateTransactionEventFragmentCalled( - { - balanceChanges: [balanceChange, balanceChange, balanceChange], - }, - expect.objectContaining({ - properties: expect.objectContaining({ - [property]: 3, + renderHook(() => + useExpectUpdateTransactionEventFragmentCalled( + { + balanceChanges: [balanceChange, balanceChange, balanceChange], + }, + expect.objectContaining({ + properties: expect.objectContaining({ + [property]: 3, + }), }), - }), + ), ); }, ); @@ -307,21 +311,23 @@ describe('useSimulationMetrics', () => { property: string, value: AssetType[], ) => { - expectUpdateTransactionEventFragmentCalled( - { - balanceChanges: [ - { - ...BALANCE_CHANGE_MOCK, - asset: { ...BALANCE_CHANGE_MOCK.asset, standard }, - amount: new BigNumber(isNegative ? -1 : 1), - } as BalanceChange, - ], - }, - expect.objectContaining({ - properties: expect.objectContaining({ - [property]: value, + renderHook(() => + useExpectUpdateTransactionEventFragmentCalled( + { + balanceChanges: [ + { + ...BALANCE_CHANGE_MOCK, + asset: { ...BALANCE_CHANGE_MOCK.asset, standard }, + amount: new BigNumber(isNegative ? -1 : 1), + } as BalanceChange, + ], + }, + expect.objectContaining({ + properties: expect.objectContaining({ + [property]: value, + }), }), - }), + ), ); }, ); @@ -371,15 +377,17 @@ describe('useSimulationMetrics', () => { fiatAmount, }; - expectUpdateTransactionEventFragmentCalled( - { - balanceChanges: [balanceChange], - }, - expect.objectContaining({ - properties: expect.objectContaining({ - [property]: [expected], + renderHook(() => + useExpectUpdateTransactionEventFragmentCalled( + { + balanceChanges: [balanceChange], + }, + expect.objectContaining({ + properties: expect.objectContaining({ + [property]: [expected], + }), }), - }), + ), ); }, ); @@ -470,15 +478,17 @@ describe('useSimulationMetrics', () => { asset: { ...BALANCE_CHANGE_MOCK.asset, standard }, }; - expectUpdateTransactionEventFragmentCalled( - { - balanceChanges: [balanceChange as BalanceChange], - }, - expect.objectContaining({ - properties: expect.objectContaining({ - [property]: [expected], + renderHook(() => + useExpectUpdateTransactionEventFragmentCalled( + { + balanceChanges: [balanceChange as BalanceChange], + }, + expect.objectContaining({ + properties: expect.objectContaining({ + [property]: [expected], + }), }), - }), + ), ); }, ); @@ -501,15 +511,17 @@ describe('useSimulationMetrics', () => { usdAmount: 1.23, }; - expectUpdateTransactionEventFragmentCalled( - { - balanceChanges: [balanceChange1, balanceChange2], - }, - expect.objectContaining({ - properties: expect.objectContaining({ - [property]: 2.46, + renderHook(() => + useExpectUpdateTransactionEventFragmentCalled( + { + balanceChanges: [balanceChange1, balanceChange2], + }, + expect.objectContaining({ + properties: expect.objectContaining({ + [property]: 2.46, + }), }), - }), + ), ); }, ); @@ -517,13 +529,15 @@ describe('useSimulationMetrics', () => { describe('creates incomplete asset event', () => { it('if petname is unknown', () => { - useSimulationMetrics({ - enableMetrics: true, - balanceChanges: [BALANCE_CHANGE_MOCK], - simulationData: undefined, - loading: false, - transactionId: TRANSACTION_ID_MOCK, - }); + renderHook(() => + useSimulationMetrics({ + enableMetrics: true, + balanceChanges: [BALANCE_CHANGE_MOCK], + simulationData: undefined, + loading: false, + transactionId: TRANSACTION_ID_MOCK, + }), + ); expect(trackEventMock).toHaveBeenCalledTimes(1); expect(trackEventMock).toHaveBeenCalledWith({ @@ -554,13 +568,15 @@ describe('useSimulationMetrics', () => { useDisplayNamesMock.mockReset(); useDisplayNamesMock.mockReturnValue([DISPLAY_NAME_SAVED_MOCK]); - useSimulationMetrics({ - enableMetrics: true, - balanceChanges: [{ ...BALANCE_CHANGE_MOCK, fiatAmount: null }], - simulationData: undefined, - loading: false, - transactionId: TRANSACTION_ID_MOCK, - }); + renderHook(() => + useSimulationMetrics({ + enableMetrics: true, + balanceChanges: [{ ...BALANCE_CHANGE_MOCK, fiatAmount: null }], + simulationData: undefined, + loading: false, + transactionId: TRANSACTION_ID_MOCK, + }), + ); expect(trackEventMock).toHaveBeenCalledTimes(1); expect(trackEventMock).toHaveBeenCalledWith({ @@ -608,13 +624,15 @@ describe('useSimulationMetrics', () => { enableMetrics: boolean, simulationData: { error: { code: SimulationErrorCode } } | undefined, ) => { - useSimulationMetrics({ - enableMetrics, - balanceChanges: [BALANCE_CHANGE_MOCK], - simulationData: simulationData as SimulationData, - loading: false, - transactionId: TRANSACTION_ID_MOCK, - }); + renderHook(() => + useSimulationMetrics({ + enableMetrics, + balanceChanges: [BALANCE_CHANGE_MOCK], + simulationData: simulationData as SimulationData, + loading: false, + transactionId: TRANSACTION_ID_MOCK, + }), + ); expect(updateTransactionEventFragmentMock).not.toHaveBeenCalled(); }, diff --git a/ui/pages/confirmations/hooks/syncConfirmPath.ts b/ui/pages/confirmations/hooks/syncConfirmPath.ts index dc66fc0b1451..dc1b408cfaf2 100644 --- a/ui/pages/confirmations/hooks/syncConfirmPath.ts +++ b/ui/pages/confirmations/hooks/syncConfirmPath.ts @@ -4,7 +4,7 @@ import { useParams } from 'react-router-dom'; import { Confirmation } from '../types/confirm'; import { useConfirmationNavigation } from './useConfirmationNavigation'; -const syncConfirmPath = (currentConfirmation?: Confirmation) => { +const useSyncConfirmPath = (currentConfirmation?: Confirmation) => { const { navigateToId } = useConfirmationNavigation(); const { id: paramId } = useParams<{ id: string }>(); const confirmationId = currentConfirmation?.id; @@ -20,4 +20,4 @@ const syncConfirmPath = (currentConfirmation?: Confirmation) => { }, [confirmationId, paramId, navigateToId]); }; -export default syncConfirmPath; +export default useSyncConfirmPath; diff --git a/ui/pages/notifications/notification-components/snap/snap.tsx b/ui/pages/notifications/notification-components/snap/snap.tsx index ea329f66064c..e54a9d547d8e 100644 --- a/ui/pages/notifications/notification-components/snap/snap.tsx +++ b/ui/pages/notifications/notification-components/snap/snap.tsx @@ -31,7 +31,8 @@ import { SnapFooterButton } from './snap-footer-button'; export const components: NotificationComponent = { guardFn: isOfTypeNodeGuard([TRIGGER_TYPES.SNAP]), - item: ({ notification, onClick }) => { + // eslint-disable-next-line func-name-matching, @typescript-eslint/naming-convention + item: function Item({ notification, onClick }) { const navigate = useNavigate(); const snapsMetadata = useSelector(getSnapsMetadata); const snapsNameGetter = getSnapName(snapsMetadata); diff --git a/ui/pages/smart-transactions/smart-transaction-status-page/smart-transaction-status-page.tsx b/ui/pages/smart-transactions/smart-transaction-status-page/smart-transaction-status-page.tsx index 224c50a14502..11125db0c9f1 100644 --- a/ui/pages/smart-transactions/smart-transaction-status-page/smart-transaction-status-page.tsx +++ b/ui/pages/smart-transactions/smart-transaction-status-page/smart-transaction-status-page.tsx @@ -131,10 +131,10 @@ const PortfolioSmartTransactionStatusUrl = ({ onCloseExtension: () => void; }) => { const t = useI18nContext(); - if (!portfolioSmartTransactionStatusUrl) { - return null; - } const handleViewTransactionLinkClick = useCallback(() => { + if (!portfolioSmartTransactionStatusUrl) { + return; + } const isWiderThanNotificationWidth = window.innerWidth > NOTIFICATION_WIDTH; if (!isSmartTransactionPending || isWiderThanNotificationWidth) { onCloseExtension(); @@ -147,6 +147,9 @@ const PortfolioSmartTransactionStatusUrl = ({ onCloseExtension, portfolioSmartTransactionStatusUrl, ]); + if (!portfolioSmartTransactionStatusUrl) { + return null; + } return ( { dispatch(hideLoadingIndication()); - }, []); + }, [dispatch]); const canShowSimulationDetails = fullTxData.simulationData?.tokenBalanceChanges?.length > 0 || From c53e435098fced1d12ffc0ab2d48eb760e3ba919 Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Thu, 30 Oct 2025 09:23:17 -0400 Subject: [PATCH 03/68] Rename: `{s,useS}etConfirmationAlerts` --- .../components/confirm/confirm-alerts/confirm-alerts.tsx | 4 ++-- ...ionAlerts.test.ts => useSetConfirmationAlerts.test.ts} | 8 ++++---- ...tConfirmationAlerts.ts => useSetConfirmationAlerts.ts} | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) rename ui/pages/confirmations/hooks/{setConfirmationAlerts.test.ts => useSetConfirmationAlerts.test.ts} (91%) rename ui/pages/confirmations/hooks/{setConfirmationAlerts.ts => useSetConfirmationAlerts.ts} (89%) diff --git a/ui/pages/confirmations/components/confirm/confirm-alerts/confirm-alerts.tsx b/ui/pages/confirmations/components/confirm/confirm-alerts/confirm-alerts.tsx index be63ea250dd8..96fc9a7ee806 100644 --- a/ui/pages/confirmations/components/confirm/confirm-alerts/confirm-alerts.tsx +++ b/ui/pages/confirmations/components/confirm/confirm-alerts/confirm-alerts.tsx @@ -1,7 +1,7 @@ import React, { ReactElement } from 'react'; import { AlertActionHandlerProvider } from '../../../../../components/app/alert-system/contexts/alertActionHandler'; import useConfirmationAlertActions from '../../../hooks/useConfirmationAlertActions'; -import setConfirmationAlerts from '../../../hooks/setConfirmationAlerts'; +import useSetConfirmationAlerts from '../../../hooks/useSetConfirmationAlerts'; import { AlertMetricsProvider } from '../../../../../components/app/alert-system/contexts/alertMetricsContext'; import { useConfirmationAlertMetrics } from '../../../hooks/useConfirmationAlertMetrics'; @@ -10,7 +10,7 @@ const ConfirmAlerts = ({ children }: { children: ReactElement }) => { useConfirmationAlertMetrics(); const processAction = useConfirmationAlertActions(); - setConfirmationAlerts(); + useSetConfirmationAlerts(); return ( ({ @@ -38,14 +38,14 @@ const mockState = getMockPersonalSignConfirmStateForRequest( }, ); -describe('setConfirmationAlerts', () => { +describe('useSetConfirmationAlerts', () => { it('updates confirmation alerts', () => { const mockDispatch = jest.fn(); (useDispatch as jest.Mock).mockReturnValue(mockDispatch); (useConfirmationAlerts as jest.Mock).mockReturnValue(alerts); renderHookWithConfirmContextProvider( - () => setConfirmationAlerts(), + () => useSetConfirmationAlerts(), mockState, ); @@ -60,7 +60,7 @@ describe('setConfirmationAlerts', () => { (useDispatch as jest.Mock).mockReturnValue(mockDispatch); const { unmount } = renderHookWithConfirmContextProvider( - () => setConfirmationAlerts(), + () => useSetConfirmationAlerts(), mockState, ); diff --git a/ui/pages/confirmations/hooks/setConfirmationAlerts.ts b/ui/pages/confirmations/hooks/useSetConfirmationAlerts.ts similarity index 89% rename from ui/pages/confirmations/hooks/setConfirmationAlerts.ts rename to ui/pages/confirmations/hooks/useSetConfirmationAlerts.ts index c1196f0ad4f2..7a005ae33fd6 100644 --- a/ui/pages/confirmations/hooks/setConfirmationAlerts.ts +++ b/ui/pages/confirmations/hooks/useSetConfirmationAlerts.ts @@ -8,7 +8,7 @@ import { import { useConfirmContext } from '../context/confirm'; import useConfirmationAlerts from './useConfirmationAlerts'; -const setConfirmationAlerts = () => { +const useSetConfirmationAlerts = () => { const dispatch = useDispatch(); const { currentConfirmation } = useConfirmContext(); const alerts = useConfirmationAlerts(); @@ -25,4 +25,4 @@ const setConfirmationAlerts = () => { }, []); }; -export default setConfirmationAlerts; +export default useSetConfirmationAlerts; From 0e10ad71f2f82dd3a238a3561e2cc6083302a2d8 Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Thu, 30 Oct 2025 09:30:13 -0400 Subject: [PATCH 04/68] Add `eslint-disable` directives for `rules-of-hooks` --- ui/hooks/snaps/useSnapNavigation.ts | 33 +++++++++++-------- .../info/hooks/useNestedTransactionLabels.ts | 1 + .../snap/snap-footer-button.tsx | 2 ++ 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/ui/hooks/snaps/useSnapNavigation.ts b/ui/hooks/snaps/useSnapNavigation.ts index 97bf2ad0b497..65b4e4733ef8 100644 --- a/ui/hooks/snaps/useSnapNavigation.ts +++ b/ui/hooks/snaps/useSnapNavigation.ts @@ -1,22 +1,29 @@ +import { useCallback, useMemo } from 'react'; import { useNavigate } from 'react-router-dom-v5-compat'; import { parseMetaMaskUrl } from '@metamask/snaps-utils'; import { getSnapRoute } from '../../helpers/utils/util'; const useSnapNavigation = () => { const navigate = useNavigate(); - const useSnapNavigate = (url: string) => { - let path; - const linkData = parseMetaMaskUrl(url); - if (linkData.snapId) { - path = getSnapRoute(linkData.snapId); - } else { - path = linkData.path; - } - navigate(path); - }; - return { - useSnapNavigate, - }; + const useSnapNavigate = useCallback( + (url: string) => { + let path; + const linkData = parseMetaMaskUrl(url); + if (linkData.snapId) { + path = getSnapRoute(linkData.snapId); + } else { + path = linkData.path; + } + navigate(path); + }, + [navigate], + ); + return useMemo( + () => ({ + useSnapNavigate, + }), + [useSnapNavigate], + ); }; export default useSnapNavigation; diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.ts b/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.ts index 1497dd231fe3..f04a5ca70b52 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.ts @@ -15,6 +15,7 @@ export function useNestedTransactionLabels({ const { data, to } = nestedTransaction; // It's safe to call useFourByte here because the length of nestedTransactions // remains stable throughout the component's lifecycle. + // eslint-disable-next-line react-hooks/rules-of-hooks const methodData = useFourByte({ data, to }); const functionName = methodData?.name; diff --git a/ui/pages/notifications/notification-components/snap/snap-footer-button.tsx b/ui/pages/notifications/notification-components/snap/snap-footer-button.tsx index 0b53a43f8ce4..f8239d29529a 100644 --- a/ui/pages/notifications/notification-components/snap/snap-footer-button.tsx +++ b/ui/pages/notifications/notification-components/snap/snap-footer-button.tsx @@ -44,6 +44,8 @@ export const SnapFooterButton = (props: { notification: SnapNotification }) => { if (isExternal) { setIsOpen(true); } else { + // This hook is safe to include in this event handler, because its only reactive component is `useNavigate` + // eslint-disable-next-line react-hooks/rules-of-hooks useSnapNavigate(href); } }, From d3c1f6e2560bbf4a1ebfd2877d3e1af56a397d6f Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Thu, 30 Oct 2025 09:39:03 -0400 Subject: [PATCH 05/68] Rename: `{s,useS}yncConfirmPath` --- ui/pages/confirmations/context/confirm/index.tsx | 4 ++-- .../{syncConfirmPath.test.ts => useSyncConfirmPath.test.ts} | 6 +++--- .../hooks/{syncConfirmPath.ts => useSyncConfirmPath.ts} | 0 3 files changed, 5 insertions(+), 5 deletions(-) rename ui/pages/confirmations/hooks/{syncConfirmPath.test.ts => useSyncConfirmPath.test.ts} (87%) rename ui/pages/confirmations/hooks/{syncConfirmPath.ts => useSyncConfirmPath.ts} (100%) diff --git a/ui/pages/confirmations/context/confirm/index.tsx b/ui/pages/confirmations/context/confirm/index.tsx index 09121983e321..5d032b75b96e 100644 --- a/ui/pages/confirmations/context/confirm/index.tsx +++ b/ui/pages/confirmations/context/confirm/index.tsx @@ -11,7 +11,7 @@ import { useDispatch } from 'react-redux'; import { setAccountDetailsAddress } from '../../../../store/actions'; import useCurrentConfirmation from '../../hooks/useCurrentConfirmation'; -import syncConfirmPath from '../../hooks/syncConfirmPath'; +import useSyncConfirmPath from '../../hooks/useSyncConfirmPath'; import { Confirmation } from '../../types/confirm'; export type ConfirmContextType = { @@ -30,7 +30,7 @@ export const ConfirmContextProvider: React.FC<{ const [isScrollToBottomCompleted, setIsScrollToBottomCompleted] = useState(true); const { currentConfirmation } = useCurrentConfirmation(); - syncConfirmPath(currentConfirmation); + useSyncConfirmPath(currentConfirmation); const dispatch = useDispatch(); const value = useMemo( diff --git a/ui/pages/confirmations/hooks/syncConfirmPath.test.ts b/ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts similarity index 87% rename from ui/pages/confirmations/hooks/syncConfirmPath.test.ts rename to ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts index eb01018a22c5..17db39e58439 100644 --- a/ui/pages/confirmations/hooks/syncConfirmPath.test.ts +++ b/ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts @@ -2,7 +2,7 @@ import { ApprovalType } from '@metamask/controller-utils'; import mockState from '../../../../test/data/mock-state.json'; import { unapprovedPersonalSignMsg } from '../../../../test/data/confirmations/personal_sign'; import { renderHookWithConfirmContextProvider } from '../../../../test/lib/confirmations/render-helpers'; -import syncConfirmPath from './syncConfirmPath'; +import useSyncConfirmPath from './useSyncConfirmPath'; const mockHistoryReplace = jest.fn(); @@ -27,7 +27,7 @@ const STATE_MOCK = { describe('syncConfirmPath', () => { it('should execute correctly', () => { const result = renderHookWithConfirmContextProvider( - () => syncConfirmPath(unapprovedPersonalSignMsg), + () => useSyncConfirmPath(unapprovedPersonalSignMsg), STATE_MOCK, ); expect(result).toBeDefined(); @@ -36,7 +36,7 @@ describe('syncConfirmPath', () => { it('should replace history route', () => { mockHistoryReplace.mockClear(); renderHookWithConfirmContextProvider( - () => syncConfirmPath(unapprovedPersonalSignMsg), + () => useSyncConfirmPath(unapprovedPersonalSignMsg), STATE_MOCK, ); expect(mockHistoryReplace).toHaveBeenCalled(); diff --git a/ui/pages/confirmations/hooks/syncConfirmPath.ts b/ui/pages/confirmations/hooks/useSyncConfirmPath.ts similarity index 100% rename from ui/pages/confirmations/hooks/syncConfirmPath.ts rename to ui/pages/confirmations/hooks/useSyncConfirmPath.ts From da42adc949bee58c0f4a019a08756d3e8077e75e Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Wed, 12 Nov 2025 13:00:14 -0500 Subject: [PATCH 06/68] Fix conditional hook calls introduced from main --- .../multichain-account-details-page.tsx | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.tsx b/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.tsx index 4f7e5fedda48..8322c66e513a 100644 --- a/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.tsx +++ b/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.tsx @@ -62,23 +62,11 @@ export const MultichainAccountDetailsPage = () => { const trackEvent = useContext(MetaMetricsContext); const { id } = useParams(); - // Validate URL parameter early - if (!id) { - history.push(DEFAULT_ROUTE); - return null; - } - - const accountGroupId = decodeURIComponent(id) as AccountGroupId; + const accountGroupId = decodeURIComponent(id ?? '') as AccountGroupId; const multichainAccount = useSelector((state) => getMultichainAccountGroupById(state, accountGroupId), ); - // Redirect if account doesn't exist - if (!multichainAccount) { - history.push(DEFAULT_ROUTE); - return null; - } - const walletId = extractWalletIdFromGroupId(accountGroupId); const wallet = useSelector((state) => getWallet(state, walletId)); const { keyringId, isSRPBackedUp } = useWalletInfo(walletId); @@ -158,7 +146,12 @@ export const MultichainAccountDetailsPage = () => { history.push(walletRoute); }; - return ( + // Redirect if account doesn't exist + if (!id || !multichainAccount) { + history.push(DEFAULT_ROUTE); + } + + return id && multichainAccount ? (
{ )} - ); + ) : null; }; From 8fd579431ac8d8a79ba839784f6df70105418793 Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Wed, 12 Nov 2025 13:07:50 -0500 Subject: [PATCH 07/68] Fix incorrectly resolved merge conflict --- .../batch-simulation-details.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/ui/pages/confirmations/components/confirm/info/batch/batch-simulation-details/batch-simulation-details.tsx b/ui/pages/confirmations/components/confirm/info/batch/batch-simulation-details/batch-simulation-details.tsx index 68a6ebec92f6..4c0c16b2bcfe 100644 --- a/ui/pages/confirmations/components/confirm/info/batch/batch-simulation-details/batch-simulation-details.tsx +++ b/ui/pages/confirmations/components/confirm/info/batch/batch-simulation-details/batch-simulation-details.tsx @@ -75,14 +75,7 @@ export function BatchSimulationDetails() { balanceChanges: finalBalanceChanges ?? [], }, ]; - }, [approveBalanceChanges, handleEdit, t]); - - if ( - transactionMeta?.type === TransactionType.revokeDelegation || - isUpgradeOnly - ) { - return null; - } + }, [approveBalanceChanges, handleEdit]); if ( transactionMeta?.type === TransactionType.revokeDelegation || From 8933eb69713f51bcc7bf9074ac4b98a38ebab7d9 Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Mon, 3 Nov 2025 14:43:11 -0500 Subject: [PATCH 08/68] Set up React Compiler --- .depcheckrc.yml | 3 + .eslintrc.js | 6 +- babel.config.js | 12 + development/webpack/constants.ts | 20 + development/webpack/webpack.config.ts | 23 +- lavamoat/browserify/beta/policy.json | 84 +- lavamoat/browserify/experimental/policy.json | 84 +- lavamoat/browserify/flask/policy.json | 84 +- lavamoat/browserify/main/policy.json | 84 +- lavamoat/build-system/policy-override.json | 19 +- lavamoat/build-system/policy.json | 422 +++++-- lavamoat/webpack/policy.json | 76 +- package.json | 8 +- yarn.lock | 1075 ++++++++++++++++-- 14 files changed, 1652 insertions(+), 348 deletions(-) create mode 100644 development/webpack/constants.ts diff --git a/.depcheckrc.yml b/.depcheckrc.yml index 1844be15171c..a6809efdc474 100644 --- a/.depcheckrc.yml +++ b/.depcheckrc.yml @@ -8,6 +8,7 @@ ignores: - '@lavamoat/webpack' - '@lavamoat/allow-scripts' - '@babel/runtime' + - 'react-compiler-runtime' - '@fortawesome/fontawesome-free' - 'punycode' # injected via build system @@ -80,8 +81,10 @@ ignores: - 'path-browserify' # polyfill - 'nyc' # coverage - 'core-js-pure' # polyfills + - 'react-compiler-webpack' # babel - '@babel/plugin-transform-logical-assignment-operators' + - 'babel-plugin-react-compiler' # used in image optimization script - 'sharp' # trezor diff --git a/.eslintrc.js b/.eslintrc.js index 6910b5b13d4b..901db79c4591 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -321,8 +321,9 @@ module.exports = { jsx: true, }, }, - plugins: ['react'], + plugins: ['react', 'react-compiler'], rules: { + 'react-compiler/react-compiler': 'error', 'react/no-unused-prop-types': 'error', 'react/no-unused-state': 'error', 'react/jsx-boolean-value': 'error', @@ -363,8 +364,9 @@ module.exports = { jsx: true, }, }, - plugins: ['react'], + plugins: ['react', 'react-compiler'], rules: { + 'react-compiler/react-compiler': 'error', 'react/no-unused-prop-types': 'warn', 'react/no-unused-state': 'warn', 'react/jsx-boolean-value': 'off', diff --git a/babel.config.js b/babel.config.js index 69ac5f5f70c9..c5b42958fe57 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,5 +1,16 @@ const path = require('path'); +const ReactCompilerConfig = { + target: '17', + sources: (filename) => { + return ( + filename.indexOf('ui/') !== -1 && + filename.indexOf('ui/pages/confirmations') === -1 && + filename.indexOf('ui/components/app/identity') === -1 + ); + }, +}; + module.exports = function (api) { api.cache(false); return { @@ -10,6 +21,7 @@ module.exports = function (api) { browsers: ['chrome >= 89', 'firefox >= 89'], }, plugins: [ + ['babel-plugin-react-compiler', ReactCompilerConfig], // `browserify` is old and busted, and doesn't support `??=` (and other // logical assignment operators). This plugin lets us target es2020-level // browsers (except we do still end up with transpiled logical assignment diff --git a/development/webpack/constants.ts b/development/webpack/constants.ts new file mode 100644 index 000000000000..b7b75fa83df8 --- /dev/null +++ b/development/webpack/constants.ts @@ -0,0 +1,20 @@ +import { defineReactCompilerLoaderOption } from 'react-compiler-webpack'; + +export const reactCompilerOptions = { + target: '17', + logger: null, + gating: null, + noEmit: true, + compilationMode: 'all', + eslintSuppressionRules: null, + flowSuppressions: false, + ignoreUseNoForget: false, + sources: (filename) => { + return ( + filename.indexOf('ui/') !== -1 && + filename.indexOf('ui/pages/confirmations') === -1 && + filename.indexOf('ui/components/app/identity') === -1 + ); + }, + enableReanimatedCheck: false, +} as const satisfies Parameters[0]; diff --git a/development/webpack/webpack.config.ts b/development/webpack/webpack.config.ts index f09dd2e99e4b..37bd9f62ed5d 100644 --- a/development/webpack/webpack.config.ts +++ b/development/webpack/webpack.config.ts @@ -18,6 +18,10 @@ import rtlCss from 'postcss-rtlcss'; import autoprefixer from 'autoprefixer'; import discardFonts from 'postcss-discard-font-face'; import type ReactRefreshPluginType from '@pmmmwh/react-refresh-webpack-plugin'; +import { + defineReactCompilerLoaderOption, + reactCompilerLoader, +} from 'react-compiler-webpack'; import tailwindcss from 'tailwindcss'; import { loadBuildTypesConfig } from '../lib/build-type'; import { @@ -36,6 +40,7 @@ import { getSwcLoader } from './utils/loaders/swcLoader'; import { getVariables } from './utils/config'; import { ManifestPlugin } from './utils/plugins/ManifestPlugin'; import { getLatestCommit } from './utils/git'; +import { reactCompilerOptions } from './constants'; const buildTypes = loadBuildTypesConfig(); const { args, cacheKey, features } = parseArgv(argv.slice(2), buildTypes); @@ -312,13 +317,27 @@ const config = { { test: /\.(?:ts|mts|tsx)$/u, exclude: NODE_MODULES_RE, - use: [tsxLoader, codeFenceLoader], + use: [ + { + loader: reactCompilerLoader, + options: defineReactCompilerLoaderOption(reactCompilerOptions), + }, + tsxLoader, + codeFenceLoader, + ], }, // own javascript, and own javascript with jsx { test: /\.(?:js|mjs|jsx)$/u, exclude: NODE_MODULES_RE, - use: [jsxLoader, codeFenceLoader], + use: [ + { + loader: reactCompilerLoader, + options: defineReactCompilerLoaderOption(reactCompilerOptions), + }, + jsxLoader, + codeFenceLoader, + ], }, // vendor javascript. We must transform all npm modules to ensure browser // compatibility. diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 5e6d165a6e96..51752392164c 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -3211,7 +3211,7 @@ }, "string.prototype.matchall>call-bind>call-bind-apply-helpers": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>has>function-bind": true } }, @@ -3496,14 +3496,14 @@ "string.prototype.matchall>define-properties>define-data-property": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "string.prototype.matchall>define-properties": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true, "@lavamoat/webpack>json-stable-stringify>object-keys": true } }, @@ -3541,10 +3541,10 @@ "define": true } }, - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": { + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": { "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "@toruslabs/eccrypto>elliptic": { @@ -3566,7 +3566,7 @@ "browserify>util>is-arguments": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-import>array-includes>is-string": true, "@lavamoat/webpack>json-stable-stringify>isarray": true, "process": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true @@ -3817,20 +3817,20 @@ "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, "browserify>has>function-bind": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "string.prototype.matchall>has-symbols": true, - "axios>form-data>hasown": true, - "string.prototype.matchall>get-intrinsic>math-intrinsics": true + "eslint-plugin-react>hasown": true, + "eslint-plugin-react>array-includes>math-intrinsics": true } }, "string.prototype.matchall>get-intrinsic>get-proto": { "packages": { - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": true, + "eslint-plugin-react>object.values>es-object-atoms": true } }, "eth-lattice-keyring>gridplus-sdk": { @@ -3870,7 +3870,7 @@ "eth-lattice-keyring>gridplus-sdk>uuid": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true } @@ -3907,7 +3907,7 @@ "@toruslabs/eccrypto>elliptic>minimalistic-assert": true } }, - "axios>form-data>hasown": { + "eslint-plugin-react>hasown": { "packages": { "browserify>has>function-bind": true } @@ -3991,10 +3991,10 @@ "browserify>punycode": true } }, - "string.prototype.matchall>internal-slot": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator>internal-slot": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, - "axios>form-data>hasown": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>hasown": true, "string.prototype.matchall>side-channel": true } }, @@ -4057,7 +4057,7 @@ "string.prototype.matchall>call-bind": true } }, - "eslint-plugin-react>array-includes>is-string": { + "eslint-plugin-import>array-includes>is-string": { "packages": { "koa>is-generator-function>has-tostringtag": true } @@ -4676,6 +4676,14 @@ "react": true } }, + "react-compiler-runtime": { + "globals": { + "console.error": true + }, + "packages": { + "react": true + } + }, "react-dom": { "globals": { "HTMLIFrameElement": true, @@ -5150,10 +5158,10 @@ "packages": { "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name": true } }, "react-markdown>remark-parse": { @@ -5275,18 +5283,18 @@ "string.prototype.matchall>call-bind>set-function-length": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "eslint-plugin-react>string.prototype.matchall>set-function-name": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name>functions-have-names": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, "eth-method-registry>@metamask/ethjs-query>promise-to-callback>set-immediate-shim": { @@ -5306,14 +5314,14 @@ }, "string.prototype.matchall>side-channel>side-channel-list": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true } }, "string.prototype.matchall>side-channel>side-channel-map": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true } @@ -5321,7 +5329,7 @@ "string.prototype.matchall>side-channel>side-channel-weakmap": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-map": true @@ -5329,7 +5337,7 @@ }, "string.prototype.matchall>side-channel": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-list": true, "string.prototype.matchall>side-channel>side-channel-map": true, @@ -5353,7 +5361,7 @@ "StopIteration": true }, "packages": { - "string.prototype.matchall>internal-slot": true + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator>internal-slot": true } }, "stream-browserify": { @@ -5470,7 +5478,7 @@ "string.prototype.matchall>es-abstract>typed-array-buffer": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>util>is-typed-array": true } }, @@ -5697,7 +5705,7 @@ "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, - "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-import>array-includes>is-string": true, "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true } }, @@ -5716,7 +5724,7 @@ "@lavamoat/webpack>json-stable-stringify>call-bound": true, "browserify>util>which-typed-array>for-each": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "koa>is-generator-function>has-tostringtag": true } } diff --git a/lavamoat/browserify/experimental/policy.json b/lavamoat/browserify/experimental/policy.json index 5e6d165a6e96..51752392164c 100644 --- a/lavamoat/browserify/experimental/policy.json +++ b/lavamoat/browserify/experimental/policy.json @@ -3211,7 +3211,7 @@ }, "string.prototype.matchall>call-bind>call-bind-apply-helpers": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>has>function-bind": true } }, @@ -3496,14 +3496,14 @@ "string.prototype.matchall>define-properties>define-data-property": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "string.prototype.matchall>define-properties": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true, "@lavamoat/webpack>json-stable-stringify>object-keys": true } }, @@ -3541,10 +3541,10 @@ "define": true } }, - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": { + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": { "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "@toruslabs/eccrypto>elliptic": { @@ -3566,7 +3566,7 @@ "browserify>util>is-arguments": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-import>array-includes>is-string": true, "@lavamoat/webpack>json-stable-stringify>isarray": true, "process": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true @@ -3817,20 +3817,20 @@ "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, "browserify>has>function-bind": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "string.prototype.matchall>has-symbols": true, - "axios>form-data>hasown": true, - "string.prototype.matchall>get-intrinsic>math-intrinsics": true + "eslint-plugin-react>hasown": true, + "eslint-plugin-react>array-includes>math-intrinsics": true } }, "string.prototype.matchall>get-intrinsic>get-proto": { "packages": { - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": true, + "eslint-plugin-react>object.values>es-object-atoms": true } }, "eth-lattice-keyring>gridplus-sdk": { @@ -3870,7 +3870,7 @@ "eth-lattice-keyring>gridplus-sdk>uuid": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true } @@ -3907,7 +3907,7 @@ "@toruslabs/eccrypto>elliptic>minimalistic-assert": true } }, - "axios>form-data>hasown": { + "eslint-plugin-react>hasown": { "packages": { "browserify>has>function-bind": true } @@ -3991,10 +3991,10 @@ "browserify>punycode": true } }, - "string.prototype.matchall>internal-slot": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator>internal-slot": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, - "axios>form-data>hasown": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>hasown": true, "string.prototype.matchall>side-channel": true } }, @@ -4057,7 +4057,7 @@ "string.prototype.matchall>call-bind": true } }, - "eslint-plugin-react>array-includes>is-string": { + "eslint-plugin-import>array-includes>is-string": { "packages": { "koa>is-generator-function>has-tostringtag": true } @@ -4676,6 +4676,14 @@ "react": true } }, + "react-compiler-runtime": { + "globals": { + "console.error": true + }, + "packages": { + "react": true + } + }, "react-dom": { "globals": { "HTMLIFrameElement": true, @@ -5150,10 +5158,10 @@ "packages": { "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name": true } }, "react-markdown>remark-parse": { @@ -5275,18 +5283,18 @@ "string.prototype.matchall>call-bind>set-function-length": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "eslint-plugin-react>string.prototype.matchall>set-function-name": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name>functions-have-names": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, "eth-method-registry>@metamask/ethjs-query>promise-to-callback>set-immediate-shim": { @@ -5306,14 +5314,14 @@ }, "string.prototype.matchall>side-channel>side-channel-list": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true } }, "string.prototype.matchall>side-channel>side-channel-map": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true } @@ -5321,7 +5329,7 @@ "string.prototype.matchall>side-channel>side-channel-weakmap": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-map": true @@ -5329,7 +5337,7 @@ }, "string.prototype.matchall>side-channel": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-list": true, "string.prototype.matchall>side-channel>side-channel-map": true, @@ -5353,7 +5361,7 @@ "StopIteration": true }, "packages": { - "string.prototype.matchall>internal-slot": true + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator>internal-slot": true } }, "stream-browserify": { @@ -5470,7 +5478,7 @@ "string.prototype.matchall>es-abstract>typed-array-buffer": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>util>is-typed-array": true } }, @@ -5697,7 +5705,7 @@ "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, - "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-import>array-includes>is-string": true, "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true } }, @@ -5716,7 +5724,7 @@ "@lavamoat/webpack>json-stable-stringify>call-bound": true, "browserify>util>which-typed-array>for-each": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "koa>is-generator-function>has-tostringtag": true } } diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 5e6d165a6e96..51752392164c 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -3211,7 +3211,7 @@ }, "string.prototype.matchall>call-bind>call-bind-apply-helpers": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>has>function-bind": true } }, @@ -3496,14 +3496,14 @@ "string.prototype.matchall>define-properties>define-data-property": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "string.prototype.matchall>define-properties": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true, "@lavamoat/webpack>json-stable-stringify>object-keys": true } }, @@ -3541,10 +3541,10 @@ "define": true } }, - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": { + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": { "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "@toruslabs/eccrypto>elliptic": { @@ -3566,7 +3566,7 @@ "browserify>util>is-arguments": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-import>array-includes>is-string": true, "@lavamoat/webpack>json-stable-stringify>isarray": true, "process": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true @@ -3817,20 +3817,20 @@ "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, "browserify>has>function-bind": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "string.prototype.matchall>has-symbols": true, - "axios>form-data>hasown": true, - "string.prototype.matchall>get-intrinsic>math-intrinsics": true + "eslint-plugin-react>hasown": true, + "eslint-plugin-react>array-includes>math-intrinsics": true } }, "string.prototype.matchall>get-intrinsic>get-proto": { "packages": { - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": true, + "eslint-plugin-react>object.values>es-object-atoms": true } }, "eth-lattice-keyring>gridplus-sdk": { @@ -3870,7 +3870,7 @@ "eth-lattice-keyring>gridplus-sdk>uuid": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true } @@ -3907,7 +3907,7 @@ "@toruslabs/eccrypto>elliptic>minimalistic-assert": true } }, - "axios>form-data>hasown": { + "eslint-plugin-react>hasown": { "packages": { "browserify>has>function-bind": true } @@ -3991,10 +3991,10 @@ "browserify>punycode": true } }, - "string.prototype.matchall>internal-slot": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator>internal-slot": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, - "axios>form-data>hasown": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>hasown": true, "string.prototype.matchall>side-channel": true } }, @@ -4057,7 +4057,7 @@ "string.prototype.matchall>call-bind": true } }, - "eslint-plugin-react>array-includes>is-string": { + "eslint-plugin-import>array-includes>is-string": { "packages": { "koa>is-generator-function>has-tostringtag": true } @@ -4676,6 +4676,14 @@ "react": true } }, + "react-compiler-runtime": { + "globals": { + "console.error": true + }, + "packages": { + "react": true + } + }, "react-dom": { "globals": { "HTMLIFrameElement": true, @@ -5150,10 +5158,10 @@ "packages": { "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name": true } }, "react-markdown>remark-parse": { @@ -5275,18 +5283,18 @@ "string.prototype.matchall>call-bind>set-function-length": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "eslint-plugin-react>string.prototype.matchall>set-function-name": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name>functions-have-names": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, "eth-method-registry>@metamask/ethjs-query>promise-to-callback>set-immediate-shim": { @@ -5306,14 +5314,14 @@ }, "string.prototype.matchall>side-channel>side-channel-list": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true } }, "string.prototype.matchall>side-channel>side-channel-map": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true } @@ -5321,7 +5329,7 @@ "string.prototype.matchall>side-channel>side-channel-weakmap": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-map": true @@ -5329,7 +5337,7 @@ }, "string.prototype.matchall>side-channel": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-list": true, "string.prototype.matchall>side-channel>side-channel-map": true, @@ -5353,7 +5361,7 @@ "StopIteration": true }, "packages": { - "string.prototype.matchall>internal-slot": true + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator>internal-slot": true } }, "stream-browserify": { @@ -5470,7 +5478,7 @@ "string.prototype.matchall>es-abstract>typed-array-buffer": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>util>is-typed-array": true } }, @@ -5697,7 +5705,7 @@ "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, - "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-import>array-includes>is-string": true, "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true } }, @@ -5716,7 +5724,7 @@ "@lavamoat/webpack>json-stable-stringify>call-bound": true, "browserify>util>which-typed-array>for-each": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "koa>is-generator-function>has-tostringtag": true } } diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 5e6d165a6e96..51752392164c 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -3211,7 +3211,7 @@ }, "string.prototype.matchall>call-bind>call-bind-apply-helpers": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>has>function-bind": true } }, @@ -3496,14 +3496,14 @@ "string.prototype.matchall>define-properties>define-data-property": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "string.prototype.matchall>define-properties": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true, "@lavamoat/webpack>json-stable-stringify>object-keys": true } }, @@ -3541,10 +3541,10 @@ "define": true } }, - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": { + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": { "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "@toruslabs/eccrypto>elliptic": { @@ -3566,7 +3566,7 @@ "browserify>util>is-arguments": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-import>array-includes>is-string": true, "@lavamoat/webpack>json-stable-stringify>isarray": true, "process": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true @@ -3817,20 +3817,20 @@ "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, "browserify>has>function-bind": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "string.prototype.matchall>has-symbols": true, - "axios>form-data>hasown": true, - "string.prototype.matchall>get-intrinsic>math-intrinsics": true + "eslint-plugin-react>hasown": true, + "eslint-plugin-react>array-includes>math-intrinsics": true } }, "string.prototype.matchall>get-intrinsic>get-proto": { "packages": { - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": true, + "eslint-plugin-react>object.values>es-object-atoms": true } }, "eth-lattice-keyring>gridplus-sdk": { @@ -3870,7 +3870,7 @@ "eth-lattice-keyring>gridplus-sdk>uuid": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true } @@ -3907,7 +3907,7 @@ "@toruslabs/eccrypto>elliptic>minimalistic-assert": true } }, - "axios>form-data>hasown": { + "eslint-plugin-react>hasown": { "packages": { "browserify>has>function-bind": true } @@ -3991,10 +3991,10 @@ "browserify>punycode": true } }, - "string.prototype.matchall>internal-slot": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator>internal-slot": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, - "axios>form-data>hasown": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>hasown": true, "string.prototype.matchall>side-channel": true } }, @@ -4057,7 +4057,7 @@ "string.prototype.matchall>call-bind": true } }, - "eslint-plugin-react>array-includes>is-string": { + "eslint-plugin-import>array-includes>is-string": { "packages": { "koa>is-generator-function>has-tostringtag": true } @@ -4676,6 +4676,14 @@ "react": true } }, + "react-compiler-runtime": { + "globals": { + "console.error": true + }, + "packages": { + "react": true + } + }, "react-dom": { "globals": { "HTMLIFrameElement": true, @@ -5150,10 +5158,10 @@ "packages": { "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name": true } }, "react-markdown>remark-parse": { @@ -5275,18 +5283,18 @@ "string.prototype.matchall>call-bind>set-function-length": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "eslint-plugin-react>string.prototype.matchall>set-function-name": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name>functions-have-names": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, "eth-method-registry>@metamask/ethjs-query>promise-to-callback>set-immediate-shim": { @@ -5306,14 +5314,14 @@ }, "string.prototype.matchall>side-channel>side-channel-list": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true } }, "string.prototype.matchall>side-channel>side-channel-map": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true } @@ -5321,7 +5329,7 @@ "string.prototype.matchall>side-channel>side-channel-weakmap": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-map": true @@ -5329,7 +5337,7 @@ }, "string.prototype.matchall>side-channel": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-list": true, "string.prototype.matchall>side-channel>side-channel-map": true, @@ -5353,7 +5361,7 @@ "StopIteration": true }, "packages": { - "string.prototype.matchall>internal-slot": true + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator>internal-slot": true } }, "stream-browserify": { @@ -5470,7 +5478,7 @@ "string.prototype.matchall>es-abstract>typed-array-buffer": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>util>is-typed-array": true } }, @@ -5697,7 +5705,7 @@ "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, - "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-import>array-includes>is-string": true, "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true } }, @@ -5716,7 +5724,7 @@ "@lavamoat/webpack>json-stable-stringify>call-bound": true, "browserify>util>which-typed-array>for-each": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "koa>is-generator-function>has-tostringtag": true } } diff --git a/lavamoat/build-system/policy-override.json b/lavamoat/build-system/policy-override.json index c5e8950556e7..caf84c46946a 100644 --- a/lavamoat/build-system/policy-override.json +++ b/lavamoat/build-system/policy-override.json @@ -11,7 +11,8 @@ "@babel/plugin-proposal-nullish-coalescing-operator": true, "@babel/plugin-proposal-object-rest-spread": true, "@babel/plugin-proposal-optional-chaining": true, - "@babel/preset-typescript": true + "@babel/preset-typescript": true, + "babel-plugin-react-compiler": true } }, "@babel/eslint-parser": { @@ -577,6 +578,22 @@ "process.stderr": true, "process.stdout": true } + }, + "babel-plugin-react-compiler": { + "builtin": { + "crypto": true, + "path": true, + "tty": true, + "util": true + }, + "globals": { + "process.env": true, + "process.stderr.fd": true, + "console": true + }, + "packages": { + "@babel/core>@babel/types": true + } } } } diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json index f3df2d66d4a2..424f25f73dc7 100644 --- a/lavamoat/build-system/policy.json +++ b/lavamoat/build-system/policy.json @@ -62,6 +62,7 @@ "@babel/core>@babel/template": true, "depcheck>@babel/traverse": true, "@babel/core>@babel/types": true, + "babel-plugin-react-compiler": true, "@babel/core>convert-source-map": true, "nock>debug": true, "@babel/core>gensync": true, @@ -290,7 +291,7 @@ "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/preset-typescript>@babel/plugin-syntax-jsx": { + "react-compiler-webpack>@babel/plugin-syntax-jsx": { "packages": { "@babel/preset-env>@babel/helper-plugin-utils": true } @@ -583,7 +584,7 @@ "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, "@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports": true, "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-typescript>@babel/plugin-syntax-jsx": true + "react-compiler-webpack>@babel/plugin-syntax-jsx": true } }, "@babel/preset-react>@babel/plugin-transform-react-pure-annotations": { @@ -767,7 +768,7 @@ "packages": { "@babel/preset-env>@babel/helper-plugin-utils": true, "@babel/preset-env>@babel/helper-validator-option": true, - "@babel/preset-typescript>@babel/plugin-syntax-jsx": true, + "react-compiler-webpack>@babel/plugin-syntax-jsx": true, "@babel/preset-env>@babel/plugin-transform-modules-commonjs": true, "@babel/preset-typescript>@babel/plugin-transform-typescript": true } @@ -1405,13 +1406,25 @@ "gulp>undertaker>arr-map>make-iterator": true } }, + "eslint-plugin-import>array-includes": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "eslint-plugin-import>array-includes>es-abstract": true, + "string.prototype.matchall>get-intrinsic": true, + "eslint-plugin-import>array-includes>is-string": true + } + }, "eslint-plugin-react>array-includes": { "packages": { "string.prototype.matchall>call-bind": true, + "@lavamoat/webpack>json-stable-stringify>call-bound": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true, + "eslint-plugin-react>array-includes>es-abstract": true, + "eslint-plugin-react>object.values>es-object-atoms": true, "string.prototype.matchall>get-intrinsic": true, - "eslint-plugin-react>array-includes>is-string": true + "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-react>array-includes>math-intrinsics": true } }, "gulp>undertaker>bach>array-initial": { @@ -1425,19 +1438,38 @@ "gulp>undertaker>bach>array-last>is-number": true } }, - "eslint-plugin-import>array.prototype.flat": { + "eslint-plugin-react>array.prototype.findlast": { "packages": { "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true, + "eslint-plugin-react>array-includes>es-abstract": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": true } }, + "eslint-plugin-import>array.prototype.flat": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "eslint-plugin-import>array.prototype.flat>es-abstract": true, + "eslint-plugin-import>array.prototype.flat>es-shim-unscopables": true + } + }, "eslint-plugin-react>array.prototype.flatmap": { "packages": { "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true, + "eslint-plugin-react>array-includes>es-abstract": true, + "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": true + } + }, + "eslint-plugin-react>array.prototype.tosorted": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "eslint-plugin-react>array-includes>es-abstract": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": true } }, @@ -1514,6 +1546,38 @@ "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider": true } }, + "babel-plugin-react-compiler": { + "builtin": { + "buffer": true, + "crypto": true, + "fs": true, + "os.homedir": true, + "os.release": true, + "path": true, + "tty": true, + "util": true + }, + "globals": { + "Buffer": true, + "TextDecoder": true, + "URL": true, + "__DEV__": true, + "atob": true, + "compile": true, + "console": true, + "define": true, + "document": true, + "findDirectiveEnablingMemoization": true, + "localStorage": true, + "navigator": true, + "performance.mark": true, + "performance.measure": true, + "process": true + }, + "packages": { + "@babel/core>@babel/types": true + } + }, "babelify": { "builtin": { "path.extname": true, @@ -1765,7 +1829,7 @@ }, "string.prototype.matchall>call-bind>call-bind-apply-helpers": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>has>function-bind": true } }, @@ -2302,14 +2366,14 @@ "string.prototype.matchall>define-properties>define-data-property": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "string.prototype.matchall>define-properties": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true, "@lavamoat/webpack>json-stable-stringify>object-keys": true } }, @@ -2463,10 +2527,11 @@ "stylelint>postcss-html>htmlparser2>domelementtype": true } }, - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": { + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": { "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "unzipper>duplexer2": { @@ -2540,47 +2605,118 @@ "watchify>xtend": true } }, - "string.prototype.matchall>es-abstract": { + "eslint-plugin-import>array-includes>es-abstract": { "packages": { "string.prototype.matchall>call-bind": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, + "string.prototype.matchall>es-abstract>es-to-primitive": true, + "string.prototype.matchall>get-intrinsic": true, + "eslint-plugin-import>array-includes>es-abstract>safe-regex-test": true, + "string.prototype.matchall>es-abstract>string.prototype.trim": true + } + }, + "eslint-plugin-react>array-includes>es-abstract": { + "packages": { + "string.prototype.matchall>call-bind": true, + "@lavamoat/webpack>json-stable-stringify>call-bound": true, "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, "axios>form-data>es-set-tostringtag": true, + "eslint-plugin-react>array-includes>es-abstract>es-to-primitive": true, + "eslint-plugin-react>array-includes>es-abstract>function.prototype.name": true, + "string.prototype.matchall>get-intrinsic": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true, + "eslint-plugin-react>array-includes>es-abstract>has-proto": true, + "string.prototype.matchall>has-symbols": true, + "eslint-plugin-react>hasown": true, + "eslint-plugin-react>es-iterator-helpers>internal-slot": true, + "string.prototype.matchall>es-abstract>is-callable": true, + "eslint-plugin-react>array-includes>es-abstract>is-regex": true, + "eslint-plugin-react>array-includes>es-abstract>is-string": true, + "eslint-plugin-react>array-includes>math-intrinsics": true, + "eslint-plugin-react>array-includes>es-abstract>object-inspect": true, + "eslint-plugin-react>array-includes>es-abstract>safe-regex-test": true, + "eslint-plugin-react>array-includes>es-abstract>set-proto": true, + "eslint-plugin-react>array-includes>es-abstract>string.prototype.trim": true + } + }, + "eslint-plugin-import>array.prototype.flat>es-abstract": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>call-bind>es-define-property": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, "string.prototype.matchall>es-abstract>es-to-primitive": true, "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true, "string.prototype.matchall>es-abstract>has-proto": true, - "string.prototype.matchall>has-symbols": true, - "axios>form-data>hasown": true, - "string.prototype.matchall>internal-slot": true, + "eslint-plugin-react>hasown": true, "string.prototype.matchall>es-abstract>is-callable": true, - "string.prototype.matchall>es-abstract>is-regex": true, - "eslint-plugin-react>array-includes>is-string": true, "string.prototype.matchall>es-abstract>object-inspect": true, - "string.prototype.matchall>es-abstract>safe-regex-test": true, + "eslint-plugin-import>array.prototype.flat>es-abstract>safe-regex-test": true, "string.prototype.matchall>es-abstract>string.prototype.trim": true } }, - "string.prototype.matchall>es-abstract>es-object-atoms": { + "string.prototype.matchall>es-abstract>string.prototype.trim>es-abstract": { + "packages": { + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "string.prototype.matchall>get-intrinsic": true + } + }, + "eslint-plugin-react>es-iterator-helpers": { + "globals": { + "Iterator": true + }, + "packages": { + "string.prototype.matchall>call-bind": true, + "@lavamoat/webpack>json-stable-stringify>call-bound": true, + "string.prototype.matchall>define-properties": true, + "eslint-plugin-react>array-includes>es-abstract": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "axios>form-data>es-set-tostringtag": true, + "string.prototype.matchall>get-intrinsic": true, + "eslint-plugin-react>es-iterator-helpers>globalthis": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true, + "eslint-plugin-react>es-iterator-helpers>has-proto": true, + "eslint-plugin-react>es-iterator-helpers>internal-slot": true, + "eslint-plugin-react>es-iterator-helpers>iterator.prototype": true, + "eslint-plugin-react>es-iterator-helpers>safe-array-concat": true + } + }, + "eslint-plugin-react>object.values>es-object-atoms": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true } }, "axios>form-data>es-set-tostringtag": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "koa>is-generator-function>has-tostringtag": true, - "axios>form-data>hasown": true + "eslint-plugin-react>hasown": true } }, - "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": { + "eslint-plugin-import>array.prototype.flat>es-shim-unscopables": { "packages": { "browserify>has": true } }, + "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": { + "packages": { + "eslint-plugin-react>hasown": true + } + }, + "eslint-plugin-react>array-includes>es-abstract>es-to-primitive": { + "packages": { + "string.prototype.matchall>es-abstract>is-callable": true, + "@metamask/eth-token-tracker>deep-equal>is-date-object": true, + "eslint-plugin-react>array-includes>es-abstract>es-to-primitive>is-symbol": true + } + }, "string.prototype.matchall>es-abstract>es-to-primitive": { "packages": { "string.prototype.matchall>es-abstract>is-callable": true, @@ -2764,7 +2900,7 @@ "process.env": true }, "packages": { - "eslint-plugin-react>array-includes": true, + "eslint-plugin-import>array-includes": true, "eslint-plugin-import>array.prototype.flat": true, "eslint-plugin-import>debug": true, "eslint-plugin-import>doctrine": true, @@ -2774,7 +2910,7 @@ "depcheck>is-core-module": true, "del>is-glob": true, "eslint>minimatch": true, - "eslint-plugin-react>object.values": true, + "eslint-plugin-import>object.values": true, "eslint-plugin-import>tsconfig-paths": true, "typescript": true } @@ -2847,25 +2983,30 @@ "globals": { "console.error": true, "console.log": true, + "console.warn": true, "process.argv.join": true, "process.cwd": true }, "packages": { "eslint-plugin-react>array-includes": true, + "eslint-plugin-react>array.prototype.findlast": true, "eslint-plugin-react>array.prototype.flatmap": true, + "eslint-plugin-react>array.prototype.tosorted": true, "eslint-plugin-react>doctrine": true, + "eslint-plugin-react>es-iterator-helpers": true, "eslint": true, "eslint-plugin-react>estraverse": true, + "eslint-plugin-react>hasown": true, "eslint-plugin-react>jsx-ast-utils": true, "eslint>minimatch": true, "eslint-plugin-react>object.entries": true, "eslint-plugin-react>object.fromentries": true, - "eslint-plugin-react>object.hasown": true, "eslint-plugin-react>object.values": true, "prop-types": true, "eslint-plugin-react>resolve": true, "eslint-plugin-react>semver": true, - "string.prototype.matchall": true + "eslint-plugin-react>string.prototype.matchall": true, + "eslint-plugin-react>string.prototype.repeat": true } }, "eslint-plugin-react-hooks": { @@ -3411,6 +3552,19 @@ "gulp-watch>chokidar>fsevents>node-pre-gyp": true } }, + "eslint-plugin-react>array-includes>es-abstract>function.prototype.name": { + "globals": { + "document": true + }, + "packages": { + "string.prototype.matchall>call-bind": true, + "@lavamoat/webpack>json-stable-stringify>call-bound": true, + "string.prototype.matchall>define-properties": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name>functions-have-names": true, + "eslint-plugin-react>hasown": true, + "string.prototype.matchall>es-abstract>is-callable": true + } + }, "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge": { "builtin": { "util.format": true @@ -3447,20 +3601,20 @@ "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, "browserify>has>function-bind": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "string.prototype.matchall>has-symbols": true, - "axios>form-data>hasown": true, - "string.prototype.matchall>get-intrinsic>math-intrinsics": true + "eslint-plugin-react>hasown": true, + "eslint-plugin-react>array-includes>math-intrinsics": true } }, "string.prototype.matchall>get-intrinsic>get-proto": { "packages": { - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": true, + "eslint-plugin-react>object.values>es-object-atoms": true } }, "gulp-zip>get-stream": { @@ -3582,6 +3736,12 @@ "stylelint>global-modules>global-prefix>which": true } }, + "eslint-plugin-react>es-iterator-helpers>globalthis": { + "packages": { + "string.prototype.matchall>define-properties": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true + } + }, "globby": { "builtin": { "fs.Stats": true, @@ -3815,7 +3975,7 @@ "process.argv": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true } @@ -3860,7 +4020,7 @@ "browserify>has>function-bind": true } }, - "axios>form-data>hasown": { + "eslint-plugin-react>hasown": { "packages": { "browserify>has>function-bind": true } @@ -3962,10 +4122,10 @@ "watchify>xtend": true } }, - "string.prototype.matchall>internal-slot": { + "eslint-plugin-react>es-iterator-helpers>internal-slot": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, - "axios>form-data>hasown": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>hasown": true, "string.prototype.matchall>side-channel": true } }, @@ -4014,7 +4174,7 @@ "process.versions": true }, "packages": { - "axios>form-data>hasown": true + "eslint-plugin-react>hasown": true } }, "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": { @@ -4134,22 +4294,57 @@ "gulp>gulp-cli>isobject": true } }, + "eslint-plugin-react>array-includes>es-abstract>is-regex": { + "packages": { + "@lavamoat/webpack>json-stable-stringify>call-bound": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "koa>is-generator-function>has-tostringtag": true, + "eslint-plugin-react>hasown": true + } + }, "string.prototype.matchall>es-abstract>is-regex": { "packages": { "string.prototype.matchall>call-bind": true, "koa>is-generator-function>has-tostringtag": true } }, + "eslint-plugin-react>array-includes>es-abstract>safe-regex-test>is-regex": { + "packages": { + "@lavamoat/webpack>json-stable-stringify>call-bound": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "koa>is-generator-function>has-tostringtag": true, + "eslint-plugin-react>hasown": true + } + }, "gulp>gulp-cli>replace-homedir>is-absolute>is-relative": { "packages": { "gulp>gulp-cli>replace-homedir>is-absolute>is-relative>is-unc-path": true } }, + "eslint-plugin-import>array-includes>is-string": { + "packages": { + "koa>is-generator-function>has-tostringtag": true + } + }, "eslint-plugin-react>array-includes>is-string": { "packages": { + "@lavamoat/webpack>json-stable-stringify>call-bound": true, + "koa>is-generator-function>has-tostringtag": true + } + }, + "eslint-plugin-react>array-includes>es-abstract>is-string": { + "packages": { + "@lavamoat/webpack>json-stable-stringify>call-bound": true, "koa>is-generator-function>has-tostringtag": true } }, + "eslint-plugin-react>array-includes>es-abstract>es-to-primitive>is-symbol": { + "packages": { + "@lavamoat/webpack>json-stable-stringify>call-bound": true, + "string.prototype.matchall>has-symbols": true, + "eslint-plugin-react>array-includes>es-abstract>safe-regex-test": true + } + }, "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { "packages": { "string.prototype.matchall>has-symbols": true @@ -4198,6 +4393,16 @@ "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value>isobject>isarray": true } }, + "eslint-plugin-react>es-iterator-helpers>iterator.prototype": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "eslint-plugin-react>object.values>es-object-atoms": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>get-intrinsic>get-proto": true, + "string.prototype.matchall>has-symbols": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name": true + } + }, "tailwindcss>jiti": { "builtin": { "assert": true, @@ -4887,6 +5092,15 @@ "Buffer": true } }, + "eslint-plugin-react>array-includes>es-abstract>object-inspect": { + "builtin": { + "util.inspect": true + }, + "globals": { + "HTMLElement": true, + "WeakRef": true + } + }, "string.prototype.matchall>es-abstract>object-inspect": { "builtin": { "util.inspect": true @@ -4920,20 +5134,17 @@ "eslint-plugin-react>object.entries": { "packages": { "string.prototype.matchall>call-bind": true, + "@lavamoat/webpack>json-stable-stringify>call-bound": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true + "eslint-plugin-react>object.values>es-object-atoms": true } }, "eslint-plugin-react>object.fromentries": { "packages": { "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true - } - }, - "eslint-plugin-react>object.hasown": { - "packages": { - "string.prototype.matchall>es-abstract": true + "eslint-plugin-react>array-includes>es-abstract": true, + "eslint-plugin-react>object.values>es-object-atoms": true } }, "gulp-watch>anymatch>micromatch>object.omit": { @@ -4953,6 +5164,14 @@ "gulp>undertaker>arr-map>make-iterator": true } }, + "eslint-plugin-react>object.values": { + "packages": { + "string.prototype.matchall>call-bind": true, + "@lavamoat/webpack>json-stable-stringify>call-bound": true, + "string.prototype.matchall>define-properties": true, + "eslint-plugin-react>object.values>es-object-atoms": true + } + }, "@metamask/object-multiplex>once": { "packages": { "@metamask/object-multiplex>once>wrappy": true @@ -6486,10 +6705,10 @@ "packages": { "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name": true } }, "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core": { @@ -6774,6 +6993,15 @@ "setTimeout.apply": true } }, + "eslint-plugin-react>es-iterator-helpers>safe-array-concat": { + "packages": { + "string.prototype.matchall>call-bind": true, + "@lavamoat/webpack>json-stable-stringify>call-bound": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>has-symbols": true, + "@lavamoat/webpack>json-stable-stringify>isarray": true + } + }, "koa>content-disposition>safe-buffer": { "builtin": { "buffer": true @@ -6929,10 +7157,24 @@ "buffer": true } }, - "string.prototype.matchall>es-abstract>safe-regex-test": { + "eslint-plugin-import>array-includes>es-abstract>safe-regex-test": { + "packages": { + "string.prototype.matchall>call-bind": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "string.prototype.matchall>es-abstract>is-regex": true + } + }, + "eslint-plugin-react>array-includes>es-abstract>safe-regex-test": { + "packages": { + "@lavamoat/webpack>json-stable-stringify>call-bound": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>array-includes>es-abstract>safe-regex-test>is-regex": true + } + }, + "eslint-plugin-import>array.prototype.flat>es-abstract>safe-regex-test": { "packages": { "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>is-regex": true } }, @@ -7072,18 +7314,25 @@ "string.prototype.matchall>call-bind>set-function-length": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "eslint-plugin-react>string.prototype.matchall>set-function-name": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name>functions-have-names": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true + } + }, + "eslint-plugin-react>array-includes>es-abstract>set-proto": { + "packages": { + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true } }, "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value": { @@ -7115,14 +7364,14 @@ }, "string.prototype.matchall>side-channel>side-channel-list": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true } }, "string.prototype.matchall>side-channel>side-channel-map": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true } @@ -7130,7 +7379,7 @@ "string.prototype.matchall>side-channel>side-channel-weakmap": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-map": true @@ -7138,7 +7387,7 @@ }, "string.prototype.matchall>side-channel": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-list": true, "string.prototype.matchall>side-channel>side-channel-map": true, @@ -7346,21 +7595,44 @@ "eslint>strip-ansi": true } }, - "string.prototype.matchall": { + "eslint-plugin-react>string.prototype.matchall": { "packages": { "string.prototype.matchall>call-bind": true, + "@lavamoat/webpack>json-stable-stringify>call-bound": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true, + "eslint-plugin-react>array-includes>es-abstract": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, + "string.prototype.matchall>get-intrinsic": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "string.prototype.matchall>has-symbols": true, - "string.prototype.matchall>regexp.prototype.flags": true + "string.prototype.matchall>regexp.prototype.flags": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name": true + } + }, + "eslint-plugin-react>string.prototype.repeat": { + "packages": { + "string.prototype.matchall>define-properties": true, + "eslint-plugin-react>array-includes>es-abstract": true + } + }, + "eslint-plugin-react>array-includes>es-abstract>string.prototype.trim": { + "packages": { + "string.prototype.matchall>call-bind": true, + "@lavamoat/webpack>json-stable-stringify>call-bound": true, + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>define-properties": true, + "eslint-plugin-react>array-includes>es-abstract": true, + "eslint-plugin-react>object.values>es-object-atoms": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, "string.prototype.matchall>es-abstract>string.prototype.trim": { "packages": { "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true + "string.prototype.matchall>es-abstract>string.prototype.trim>es-abstract": true, + "eslint-plugin-react>object.values>es-object-atoms": true } }, "browserify>string_decoder": { diff --git a/lavamoat/webpack/policy.json b/lavamoat/webpack/policy.json index 2bbc12183fde..32bda38e87be 100644 --- a/lavamoat/webpack/policy.json +++ b/lavamoat/webpack/policy.json @@ -3341,7 +3341,7 @@ }, "string.prototype.matchall>call-bind>call-bind-apply-helpers": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>has>function-bind": true } }, @@ -3657,14 +3657,14 @@ "string.prototype.matchall>define-properties>define-data-property": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "string.prototype.matchall>define-properties": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true, "@lavamoat/webpack>json-stable-stringify>object-keys": true } }, @@ -3690,10 +3690,10 @@ "console.warn": true } }, - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": { + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": { "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-react>es-iterator-helpers>gopd": true } }, "@toruslabs/eccrypto>elliptic": { @@ -3718,7 +3718,7 @@ "browserify>util>is-arguments": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-import>array-includes>is-string": true, "@lavamoat/webpack>json-stable-stringify>isarray": true, "process": true, "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true @@ -3984,14 +3984,14 @@ "packages": { "string.prototype.matchall>call-bind>call-bind-apply-helpers": true, "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>object.values>es-object-atoms": true, "browserify>has>function-bind": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "string.prototype.matchall>has-symbols": true, - "axios>form-data>hasown": true, - "string.prototype.matchall>get-intrinsic>math-intrinsics": true + "eslint-plugin-react>hasown": true, + "eslint-plugin-react>array-includes>math-intrinsics": true } }, "remote-redux-devtools>redux-devtools-core>get-params": { @@ -4001,8 +4001,8 @@ }, "string.prototype.matchall>get-intrinsic>get-proto": { "packages": { - "string.prototype.matchall>get-intrinsic>get-proto>dunder-proto": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true + "eslint-plugin-react>es-iterator-helpers>has-proto>dunder-proto": true, + "eslint-plugin-react>object.values>es-object-atoms": true } }, "eth-lattice-keyring>gridplus-sdk": { @@ -4045,7 +4045,7 @@ "eth-lattice-keyring>gridplus-sdk>uuid": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": { "packages": { "string.prototype.matchall>call-bind>es-define-property": true } @@ -4085,7 +4085,7 @@ "@toruslabs/eccrypto>elliptic>minimalistic-assert": true } }, - "axios>form-data>hasown": { + "eslint-plugin-react>hasown": { "packages": { "browserify>has>function-bind": true } @@ -4162,10 +4162,10 @@ "eth-ens-namehash>idna-uts46-hx>punycode": true } }, - "string.prototype.matchall>internal-slot": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator>internal-slot": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, - "axios>form-data>hasown": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>hasown": true, "string.prototype.matchall>side-channel": true } }, @@ -4234,7 +4234,7 @@ "string.prototype.matchall>call-bind": true } }, - "eslint-plugin-react>array-includes>is-string": { + "eslint-plugin-import>array-includes>is-string": { "packages": { "koa>is-generator-function>has-tostringtag": true } @@ -5416,10 +5416,10 @@ "packages": { "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name": true } }, "react-markdown>remark-parse": { @@ -5586,18 +5586,18 @@ "string.prototype.matchall>call-bind>set-function-length": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>gopd": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "eslint-plugin-react>string.prototype.matchall>set-function-name": { "packages": { "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>es-errors": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "eslint-plugin-react>es-iterator-helpers>es-errors": true, + "eslint-plugin-react>string.prototype.matchall>set-function-name>functions-have-names": true, + "eslint-plugin-react>es-iterator-helpers>has-property-descriptors": true } }, "eth-method-registry>@metamask/ethjs-query>promise-to-callback>set-immediate-shim": { @@ -5618,14 +5618,14 @@ }, "string.prototype.matchall>side-channel>side-channel-list": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true } }, "string.prototype.matchall>side-channel>side-channel-map": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true } @@ -5633,7 +5633,7 @@ "string.prototype.matchall>side-channel>side-channel-weakmap": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>get-intrinsic": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-map": true @@ -5641,7 +5641,7 @@ }, "string.prototype.matchall>side-channel": { "packages": { - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "string.prototype.matchall>es-abstract>object-inspect": true, "string.prototype.matchall>side-channel>side-channel-list": true, "string.prototype.matchall>side-channel>side-channel-map": true, @@ -5688,7 +5688,7 @@ "StopIteration": true }, "packages": { - "string.prototype.matchall>internal-slot": true + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator>internal-slot": true } }, "stream-browserify": { @@ -5792,7 +5792,7 @@ "string.prototype.matchall>es-abstract>typed-array-buffer": { "packages": { "@lavamoat/webpack>json-stable-stringify>call-bound": true, - "string.prototype.matchall>es-abstract>es-errors": true, + "eslint-plugin-react>es-iterator-helpers>es-errors": true, "browserify>util>is-typed-array": true } }, @@ -5998,7 +5998,7 @@ "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, - "eslint-plugin-react>array-includes>is-string": true, + "eslint-plugin-import>array-includes>is-string": true, "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true } }, @@ -6017,7 +6017,7 @@ "@lavamoat/webpack>json-stable-stringify>call-bound": true, "browserify>util>which-typed-array>for-each": true, "string.prototype.matchall>get-intrinsic>get-proto": true, - "string.prototype.matchall>es-abstract>gopd": true, + "eslint-plugin-react>es-iterator-helpers>gopd": true, "koa>is-generator-function>has-tostringtag": true } } diff --git a/package.json b/package.json index 25eb45e0c805..103d6811c3ff 100644 --- a/package.json +++ b/package.json @@ -430,6 +430,7 @@ "react": "^17.0.2", "react-beautiful-dnd": "^13.1.1", "react-chartjs-2": "^5.2.0", + "react-compiler-runtime": "^19.1.0-rc.2", "react-dom": "^17.0.2", "react-focus-lock": "^2.9.4", "react-idle-timer": "4.5.6", @@ -577,6 +578,7 @@ "addons-linter": "^6.28.0", "autoprefixer": "^10.4.19", "axios": "^1.12.0", + "babel-plugin-react-compiler": "^19.1.0-rc.2", "babelify": "^10.0.0", "bify-module-groups": "^2.0.0", "browserify": "^17.0.0", @@ -608,8 +610,9 @@ "eslint-plugin-mocha": "^10.1.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^5.5.1", - "eslint-plugin-react": "^7.23.1", - "eslint-plugin-react-hooks": "^4.2.0", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-compiler": "^19.1.0-rc.2", + "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-storybook": "^0.6.15", "eslint-plugin-tailwindcss": "^3.18.0", "eta": "^3.2.0", @@ -674,6 +677,7 @@ "process": "^0.11.10", "pumpify": "^2.0.1", "randomcolor": "^0.5.4", + "react-compiler-webpack": "^0.2.0", "react-devtools": "^6.1.5", "react-devtools-core": "^6.1.5", "react-syntax-highlighter": "^15.5.0", diff --git a/yarn.lock b/yarn.lock index ba6f4988621a..fbc93cf4b4e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -267,7 +267,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.22.5, @babel/helper-annotate-as-pure@npm:^7.25.9": +"@babel/helper-annotate-as-pure@npm:^7.22.5, @babel/helper-annotate-as-pure@npm:^7.25.9, @babel/helper-annotate-as-pure@npm:^7.27.3": version: 7.27.3 resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" dependencies: @@ -299,6 +299,23 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.18.6": + version: 7.28.3 + resolution: "@babel/helper-create-class-features-plugin@npm:7.28.3" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-member-expression-to-functions": "npm:^7.27.1" + "@babel/helper-optimise-call-expression": "npm:^7.27.1" + "@babel/helper-replace-supers": "npm:^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.3" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/32d01bdd601b4d129b1d510058a19644abc764badcc543adaec9e71443e874ef252783cceb2809645bdf0e92b07f206fd439c75a2a48cf702c627aba7f3ee34a + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-create-class-features-plugin@npm:7.25.9" @@ -389,6 +406,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-member-expression-to-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-member-expression-to-functions@npm:7.27.1" + dependencies: + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10/533a5a2cf1c9a8770d241b86d5f124c88e953c831a359faf1ac7ba1e632749c1748281b83295d227fe6035b202d81f3d3a1ea13891f150c6538e040668d6126a + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.22.5, @babel/helper-module-imports@npm:^7.25.9": version: 7.27.1 resolution: "@babel/helper-module-imports@npm:7.27.1" @@ -422,6 +449,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-optimise-call-expression@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" + dependencies: + "@babel/types": "npm:^7.27.1" + checksum: 10/0fb7ee824a384529d6b74f8a58279f9b56bfe3cce332168067dddeab2552d8eeb56dc8eaf86c04a3a09166a316cb92dfc79c4c623cd034ad4c563952c98b464f + languageName: node + linkType: hard + "@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0, @babel/helper-plugin-utils@npm:^7.25.9, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.8.0": version: 7.27.1 resolution: "@babel/helper-plugin-utils@npm:7.27.1" @@ -455,6 +491,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-replace-supers@npm:7.27.1" + dependencies: + "@babel/helper-member-expression-to-functions": "npm:^7.27.1" + "@babel/helper-optimise-call-expression": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/72e3f8bef744c06874206bf0d80a0abbedbda269586966511c2491df4f6bf6d47a94700810c7a6737345a545dfb8295222e1e72f506bcd0b40edb3f594f739ea + languageName: node + linkType: hard + "@babel/helper-simple-access@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-simple-access@npm:7.25.9" @@ -475,6 +524,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" + dependencies: + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10/4f380c5d0e0769fa6942a468b0c2d7c8f0c438f941aaa88f785f8752c103631d0904c7b4e76207a3b0e6588b2dec376595370d92ca8f8f1b422c14a69aa146d4 + languageName: node + linkType: hard + "@babel/helper-split-export-declaration@npm:^7.24.6": version: 7.24.7 resolution: "@babel/helper-split-export-declaration@npm:7.24.7" @@ -578,7 +637,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.24.6, @babel/parser@npm:^7.25.3, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.27.3, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.24.6, @babel/parser@npm:^7.25.3, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.27.3, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": version: 7.28.4 resolution: "@babel/parser@npm:7.28.4" dependencies: @@ -659,6 +718,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-proposal-private-methods@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/plugin-proposal-private-methods@npm:7.18.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.18.6" + "@babel/helper-plugin-utils": "npm:^7.18.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/22d8502ee96bca99ad2c8393e8493e2b8d4507576dd054490fd8201a36824373440106f5b098b6d821b026c7e72b0424ff4aeca69ed5f42e48f029d3a156d5ad + languageName: node + linkType: hard + "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2": version: 7.21.0-placeholder-for-preset-env.2 resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2" @@ -756,7 +827,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.25.9, @babel/plugin-syntax-jsx@npm:^7.7.2": +"@babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.25.9, @babel/plugin-syntax-jsx@npm:^7.27.1, @babel/plugin-syntax-jsx@npm:^7.7.2": version: 7.27.1 resolution: "@babel/plugin-syntax-jsx@npm:7.27.1" dependencies: @@ -855,6 +926,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-typescript@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-typescript@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/87836f7e32af624c2914c73cd6b9803cf324e07d43f61dbb973c6a86f75df725e12540d91fac7141c14b697aa9268fd064220998daced156e96ac3062d7afb41 + languageName: node + linkType: hard + "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -1732,7 +1814,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.12.5, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.4.5": +"@babel/traverse@npm:^7.12.5, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.4.5": version: 7.28.4 resolution: "@babel/traverse@npm:7.28.4" dependencies: @@ -1783,7 +1865,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.6, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.6, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.28.4 resolution: "@babel/types@npm:7.28.4" dependencies: @@ -17704,6 +17786,16 @@ __metadata: languageName: node linkType: hard +"array-buffer-byte-length@npm:^1.0.2": + version: 1.0.2 + resolution: "array-buffer-byte-length@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.3" + is-array-buffer: "npm:^3.0.5" + checksum: 10/0ae3786195c3211b423e5be8dd93357870e6fb66357d81da968c2c39ef43583ef6eece1f9cb1caccdae4806739c65dea832b44b8593414313cd76a89795fca63 + languageName: node + linkType: hard + "array-differ@npm:^3.0.0": version: 3.0.0 resolution: "array-differ@npm:3.0.0" @@ -17738,6 +17830,22 @@ __metadata: languageName: node linkType: hard +"array-includes@npm:^3.1.8": + version: 3.1.9 + resolution: "array-includes@npm:3.1.9" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.24.0" + es-object-atoms: "npm:^1.1.1" + get-intrinsic: "npm:^1.3.0" + is-string: "npm:^1.1.1" + math-intrinsics: "npm:^1.1.0" + checksum: 10/8bfe9a58df74f326b4a76b04ee05c13d871759e888b4ee8f013145297cf5eb3c02cfa216067ebdaac5d74eb9763ac5cad77cdf2773b8ab475833701e032173aa + languageName: node + linkType: hard + "array-initial@npm:^1.0.0": version: 1.1.0 resolution: "array-initial@npm:1.1.0" @@ -17812,6 +17920,20 @@ __metadata: languageName: node linkType: hard +"array.prototype.findlast@npm:^1.2.5": + version: 1.2.5 + resolution: "array.prototype.findlast@npm:1.2.5" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/7dffcc665aa965718ad6de7e17ac50df0c5e38798c0a5bf9340cf24feb8594df6ec6f3fcbe714c1577728a1b18b5704b15669474b27bceeca91ef06ce2a23c31 + languageName: node + linkType: hard + "array.prototype.flat@npm:^1.2.5": version: 1.3.1 resolution: "array.prototype.flat@npm:1.3.1" @@ -17824,15 +17946,28 @@ __metadata: languageName: node linkType: hard -"array.prototype.flatmap@npm:^1.3.0": - version: 1.3.1 - resolution: "array.prototype.flatmap@npm:1.3.1" +"array.prototype.flatmap@npm:^1.3.3": + version: 1.3.3 + resolution: "array.prototype.flatmap@npm:1.3.3" dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.1.4" - es-abstract: "npm:^1.20.4" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10/f1f3d8e0610afce06a8622295b4843507dfc2fbbd2c2b2a8d541d9f42871747393c3099d630a3f8266ca086b97b089687db64cd86b6eb7e270ebc8f767eec9fc + call-bind: "npm:^1.0.8" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.5" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/473534573aa4b37b1d80705d0ce642f5933cccf5617c9f3e8a56686e9815ba93d469138e86a1f25d2fe8af999c3d24f54d703ec1fc2db2e6778d46d0f4ac951e + languageName: node + linkType: hard + +"array.prototype.tosorted@npm:^1.1.4": + version: 1.1.4 + resolution: "array.prototype.tosorted@npm:1.1.4" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.3" + es-errors: "npm:^1.3.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/874694e5d50e138894ff5b853e639c29b0aa42bbd355acda8e8e9cd337f1c80565f21edc15e8c727fa4c0877fd9d8783c575809e440cc4d2d19acaa048bf967d languageName: node linkType: hard @@ -17852,6 +17987,21 @@ __metadata: languageName: node linkType: hard +"arraybuffer.prototype.slice@npm:^1.0.4": + version: 1.0.4 + resolution: "arraybuffer.prototype.slice@npm:1.0.4" + dependencies: + array-buffer-byte-length: "npm:^1.0.1" + call-bind: "npm:^1.0.8" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.5" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.6" + is-array-buffer: "npm:^3.0.4" + checksum: 10/4821ebdfe7d699f910c7f09bc9fa996f09b96b80bccb4f5dd4b59deae582f6ad6e505ecef6376f8beac1eda06df2dbc89b70e82835d104d6fcabd33c1aed1ae9 + languageName: node + linkType: hard + "arrify@npm:^1.0.1": version: 1.0.1 resolution: "arrify@npm:1.0.1" @@ -17970,6 +18120,20 @@ __metadata: languageName: node linkType: hard +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 10/1a09379937d846f0ce7614e75071c12826945d4e417db634156bf0e4673c495989302f52186dfa9767a1d9181794554717badd193ca2bbab046ef1da741d8efd + languageName: node + linkType: hard + +"async-generator-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-generator-function@npm:1.0.0" + checksum: 10/3d49e7acbeee9e84537f4cb0e0f91893df8eba976759875ae8ee9e3d3c82f6ecdebdb347c2fad9926b92596d93cdfc78ecc988bcdf407e40433e8e8e6fe5d78e + languageName: node + linkType: hard + "async-limiter@npm:~1.0.0": version: 1.0.1 resolution: "async-limiter@npm:1.0.1" @@ -18279,6 +18443,15 @@ __metadata: languageName: node linkType: hard +"babel-plugin-react-compiler@npm:^19.1.0-rc.2": + version: 19.1.0-rc.3 + resolution: "babel-plugin-react-compiler@npm:19.1.0-rc.3" + dependencies: + "@babel/types": "npm:^7.26.0" + checksum: 10/69981f07a382cbd1e2f1dc41b25084ca1e5355331ad4a60d5c49ff33dba7db2e27180f7f5cf5017fc334d14500956322fd4a6a405b95aba9662cb2744cd39fae + languageName: node + linkType: hard + "babel-plugin-styled-components@npm:>= 1.12.0": version: 2.1.4 resolution: "babel-plugin-styled-components@npm:2.1.4" @@ -21383,6 +21556,17 @@ __metadata: languageName: node linkType: hard +"data-view-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "data-view-buffer@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.3" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.2" + checksum: 10/c10b155a4e93999d3a215d08c23eea95f865e1f510b2e7748fcae1882b776df1afe8c99f483ace7fc0e5a3193ab08da138abebc9829d12003746c5a338c4d644 + languageName: node + linkType: hard + "data-view-byte-length@npm:^1.0.1": version: 1.0.1 resolution: "data-view-byte-length@npm:1.0.1" @@ -21394,6 +21578,17 @@ __metadata: languageName: node linkType: hard +"data-view-byte-length@npm:^1.0.2": + version: 1.0.2 + resolution: "data-view-byte-length@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.3" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.2" + checksum: 10/2a47055fcf1ab3ec41b00b6f738c6461a841391a643c9ed9befec1117c1765b4d492661d97fb7cc899200c328949dca6ff189d2c6537d96d60e8a02dfe3c95f7 + languageName: node + linkType: hard + "data-view-byte-offset@npm:^1.0.0": version: 1.0.0 resolution: "data-view-byte-offset@npm:1.0.0" @@ -21405,6 +21600,17 @@ __metadata: languageName: node linkType: hard +"data-view-byte-offset@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-byte-offset@npm:1.0.1" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: 10/fa3bdfa0968bea6711ee50375094b39f561bce3f15f9e558df59de9c25f0bdd4cddc002d9c1d70ac7772ebd36854a7e22d1761e7302a934e6f1c2263bcf44aa2 + languageName: node + linkType: hard + "date-fns@npm:^2.30.0": version: 2.30.0 resolution: "date-fns@npm:2.30.0" @@ -22570,7 +22776,7 @@ __metadata: languageName: node linkType: hard -"dunder-proto@npm:^1.0.1": +"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" dependencies: @@ -22941,6 +23147,68 @@ __metadata: languageName: node linkType: hard +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0": + version: 1.24.0 + resolution: "es-abstract@npm:1.24.0" + dependencies: + array-buffer-byte-length: "npm:^1.0.2" + arraybuffer.prototype.slice: "npm:^1.0.4" + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" + data-view-buffer: "npm:^1.0.2" + data-view-byte-length: "npm:^1.0.2" + data-view-byte-offset: "npm:^1.0.1" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + es-set-tostringtag: "npm:^2.1.0" + es-to-primitive: "npm:^1.3.0" + function.prototype.name: "npm:^1.1.8" + get-intrinsic: "npm:^1.3.0" + get-proto: "npm:^1.0.1" + get-symbol-description: "npm:^1.1.0" + globalthis: "npm:^1.0.4" + gopd: "npm:^1.2.0" + has-property-descriptors: "npm:^1.0.2" + has-proto: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + internal-slot: "npm:^1.1.0" + is-array-buffer: "npm:^3.0.5" + is-callable: "npm:^1.2.7" + is-data-view: "npm:^1.0.2" + is-negative-zero: "npm:^2.0.3" + is-regex: "npm:^1.2.1" + is-set: "npm:^2.0.3" + is-shared-array-buffer: "npm:^1.0.4" + is-string: "npm:^1.1.1" + is-typed-array: "npm:^1.1.15" + is-weakref: "npm:^1.1.1" + math-intrinsics: "npm:^1.1.0" + object-inspect: "npm:^1.13.4" + object-keys: "npm:^1.1.1" + object.assign: "npm:^4.1.7" + own-keys: "npm:^1.0.1" + regexp.prototype.flags: "npm:^1.5.4" + safe-array-concat: "npm:^1.1.3" + safe-push-apply: "npm:^1.0.0" + safe-regex-test: "npm:^1.1.0" + set-proto: "npm:^1.0.0" + stop-iteration-iterator: "npm:^1.1.0" + string.prototype.trim: "npm:^1.2.10" + string.prototype.trimend: "npm:^1.0.9" + string.prototype.trimstart: "npm:^1.0.8" + typed-array-buffer: "npm:^1.0.3" + typed-array-byte-length: "npm:^1.0.3" + typed-array-byte-offset: "npm:^1.0.4" + typed-array-length: "npm:^1.0.7" + unbox-primitive: "npm:^1.1.0" + which-typed-array: "npm:^1.1.19" + checksum: 10/64e07a886f7439cf5ccfc100f9716e6173e10af6071a50a5031afbdde474a3dbc9619d5965da54e55f8908746a9134a46be02af8c732d574b7b81ed3124e2daf + languageName: node + linkType: hard + "es-abstract@npm:^1.19.1, es-abstract@npm:^1.20.4, es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0": version: 1.23.3 resolution: "es-abstract@npm:1.23.3" @@ -23026,6 +23294,30 @@ __metadata: languageName: node linkType: hard +"es-iterator-helpers@npm:^1.2.1": + version: 1.2.1 + resolution: "es-iterator-helpers@npm:1.2.1" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.6" + es-errors: "npm:^1.3.0" + es-set-tostringtag: "npm:^2.0.3" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.6" + globalthis: "npm:^1.0.4" + gopd: "npm:^1.2.0" + has-property-descriptors: "npm:^1.0.2" + has-proto: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + internal-slot: "npm:^1.1.0" + iterator.prototype: "npm:^1.1.4" + safe-array-concat: "npm:^1.1.3" + checksum: 10/802e0e8427a05ff4a5b0c70c7fdaaeff37cdb81a28694aeb7bfb831c6ab340d8f3deeb67b96732ff9e9699ea240524d5ea8a9a6a335fcd15aa3983b27b06113f + languageName: node + linkType: hard + "es-module-lexer@npm:^1.2.1, es-module-lexer@npm:^1.4.1": version: 1.5.3 resolution: "es-module-lexer@npm:1.5.3" @@ -23063,6 +23355,15 @@ __metadata: languageName: node linkType: hard +"es-shim-unscopables@npm:^1.0.2": + version: 1.1.0 + resolution: "es-shim-unscopables@npm:1.1.0" + dependencies: + hasown: "npm:^2.0.2" + checksum: 10/c351f586c30bbabc62355be49564b2435468b52c3532b8a1663672e3d10dc300197e69c247869dd173e56d86423ab95fc0c10b0939cdae597094e0fdca078cba + languageName: node + linkType: hard + "es-to-primitive@npm:^1.2.1": version: 1.2.1 resolution: "es-to-primitive@npm:1.2.1" @@ -23074,6 +23375,17 @@ __metadata: languageName: node linkType: hard +"es-to-primitive@npm:^1.3.0": + version: 1.3.0 + resolution: "es-to-primitive@npm:1.3.0" + dependencies: + is-callable: "npm:^1.2.7" + is-date-object: "npm:^1.0.5" + is-symbol: "npm:^1.0.4" + checksum: 10/17faf35c221aad59a16286cbf58ef6f080bf3c485dff202c490d074d8e74da07884e29b852c245d894eac84f73c58330ec956dfd6d02c0b449d75eb1012a3f9b + languageName: node + linkType: hard + "es-toolkit@npm:1.33.0": version: 1.33.0 resolution: "es-toolkit@npm:1.33.0" @@ -23625,36 +23937,56 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^4.2.0": - version: 4.6.0 - resolution: "eslint-plugin-react-hooks@npm:4.6.0" +"eslint-plugin-react-compiler@npm:^19.1.0-rc.2": + version: 19.1.0-rc.2 + resolution: "eslint-plugin-react-compiler@npm:19.1.0-rc.2" + dependencies: + "@babel/core": "npm:^7.24.4" + "@babel/parser": "npm:^7.24.4" + "@babel/plugin-proposal-private-methods": "npm:^7.18.6" + hermes-parser: "npm:^0.25.1" + zod: "npm:^3.22.4" + zod-validation-error: "npm:^3.0.3" peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 10/3c63134e056a6d98d66e2c475c81f904169db817e89316d14e36269919e31f4876a2588aa0e466ec8ef160465169c627fe823bfdaae7e213946584e4a165a3ac + eslint: ">=7" + checksum: 10/cabdcbe884722049c11e84a13d1b2747c0612c61b23505fdf7b69dd9ee26e0f4bb86452486708fb359205ab5770b279d8dabac3a2d0c4409a176773eed7a4471 languageName: node linkType: hard -"eslint-plugin-react@npm:^7.23.1": - version: 7.30.1 - resolution: "eslint-plugin-react@npm:7.30.1" +"eslint-plugin-react-hooks@npm:^5.2.0": + version: 5.2.0 + resolution: "eslint-plugin-react-hooks@npm:5.2.0" + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + checksum: 10/ebb79e9cf69ae06e3a7876536653c5e556b5fd8cd9dc49577f10a6e728360e7b6f5ce91f4339b33e93b26e3bb23805418f8b5e75db80baddd617b1dffe73bed1 + languageName: node + linkType: hard + +"eslint-plugin-react@npm:^7.37.5": + version: 7.37.5 + resolution: "eslint-plugin-react@npm:7.37.5" dependencies: - array-includes: "npm:^3.1.5" - array.prototype.flatmap: "npm:^1.3.0" + array-includes: "npm:^3.1.8" + array.prototype.findlast: "npm:^1.2.5" + array.prototype.flatmap: "npm:^1.3.3" + array.prototype.tosorted: "npm:^1.1.4" doctrine: "npm:^2.1.0" + es-iterator-helpers: "npm:^1.2.1" estraverse: "npm:^5.3.0" + hasown: "npm:^2.0.2" jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.5" - object.fromentries: "npm:^2.0.5" - object.hasown: "npm:^1.1.1" - object.values: "npm:^1.1.5" + object.entries: "npm:^1.1.9" + object.fromentries: "npm:^2.0.8" + object.values: "npm:^1.2.1" prop-types: "npm:^15.8.1" - resolve: "npm:^2.0.0-next.3" - semver: "npm:^6.3.0" - string.prototype.matchall: "npm:^4.0.7" + resolve: "npm:^2.0.0-next.5" + semver: "npm:^6.3.1" + string.prototype.matchall: "npm:^4.0.12" + string.prototype.repeat: "npm:^1.0.0" peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 10/28e519ebae9d89708bdf66ddc22f761da1328f2c1d6d11303bfb0774e084014590e95531418ab61f065d16f0980ef3444c40f0bd581303b9dac5f78a3508770d + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + checksum: 10/ee1bd4e0ec64f29109d5a625bb703d179c82e0159c86c3f1b52fc1209d2994625a137dae303c333fb308a2e38315e44066d5204998177e31974382f9fda25d5c languageName: node linkType: hard @@ -25735,6 +26067,20 @@ __metadata: languageName: node linkType: hard +"function.prototype.name@npm:^1.1.8": + version: 1.1.8 + resolution: "function.prototype.name@npm:1.1.8" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + define-properties: "npm:^1.2.1" + functions-have-names: "npm:^1.2.3" + hasown: "npm:^2.0.2" + is-callable: "npm:^1.2.7" + checksum: 10/25b9e5bea936732a6f0c0c08db58cc0d609ac1ed458c6a07ead46b32e7b9bf3fe5887796c3f83d35994efbc4fdde81c08ac64135b2c399b8f2113968d44082bc + languageName: node + linkType: hard + "functions-have-names@npm:^1.2.3": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" @@ -25809,6 +26155,13 @@ __metadata: languageName: node linkType: hard +"generator-function@npm:^2.0.0": + version: 2.0.1 + resolution: "generator-function@npm:2.0.1" + checksum: 10/eb7e7eb896c5433f3d40982b2ccacdb3dd990dd3499f14040e002b5d54572476513be8a2e6f9609f6e41ab29f2c4469307611ddbfc37ff4e46b765c326663805 + languageName: node + linkType: hard + "gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" @@ -25865,6 +26218,27 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.7": + version: 1.3.1 + resolution: "get-intrinsic@npm:1.3.1" + dependencies: + async-function: "npm:^1.0.0" + async-generator-function: "npm:^1.0.0" + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + function-bind: "npm:^1.1.2" + generator-function: "npm:^2.0.0" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + math-intrinsics: "npm:^1.1.0" + checksum: 10/bb579dda84caa4a3a41611bdd483dade7f00f246f2a7992eb143c5861155290df3fdb48a8406efa3dfb0b434e2c8fafa4eebd469e409d0439247f85fc3fa2cc1 + languageName: node + linkType: hard + "get-nonce@npm:^1.0.0": version: 1.0.1 resolution: "get-nonce@npm:1.0.1" @@ -25914,7 +26288,7 @@ __metadata: languageName: node linkType: hard -"get-proto@npm:^1.0.1": +"get-proto@npm:^1.0.0, get-proto@npm:^1.0.1": version: 1.0.1 resolution: "get-proto@npm:1.0.1" dependencies: @@ -25981,6 +26355,17 @@ __metadata: languageName: node linkType: hard +"get-symbol-description@npm:^1.1.0": + version: 1.1.0 + resolution: "get-symbol-description@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.3" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.6" + checksum: 10/a353e3a9595a74720b40fb5bae3ba4a4f826e186e83814d93375182384265676f59e49998b9cdfac4a2225ce95a3d32a68f502a2c5619303987f1c183ab80494 + languageName: node + linkType: hard + "get-tsconfig@npm:^4.7.0, get-tsconfig@npm:^4.7.5": version: 4.8.1 resolution: "get-tsconfig@npm:4.8.1" @@ -26331,6 +26716,16 @@ __metadata: languageName: node linkType: hard +"globalthis@npm:^1.0.4": + version: 1.0.4 + resolution: "globalthis@npm:1.0.4" + dependencies: + define-properties: "npm:^1.2.1" + gopd: "npm:^1.0.1" + checksum: 10/1f1fd078fb2f7296306ef9dd51019491044ccf17a59ed49d375b576ca108ff37e47f3d29aead7add40763574a992f16a5367dd1e2173b8634ef18556ab719ac4 + languageName: node + linkType: hard + "globby@npm:^11.0.1, globby@npm:^11.0.2, globby@npm:^11.0.4, globby@npm:^11.1.0": version: 11.1.0 resolution: "globby@npm:11.1.0" @@ -26869,6 +27264,15 @@ __metadata: languageName: node linkType: hard +"has-proto@npm:^1.2.0": + version: 1.2.0 + resolution: "has-proto@npm:1.2.0" + dependencies: + dunder-proto: "npm:^1.0.0" + checksum: 10/7eaed07728eaa28b77fadccabce53f30de467ff186a766872669a833ac2e87d8922b76a22cc58339d7e0277aefe98d6d00762113b27a97cdf65adcf958970935 + languageName: node + linkType: hard + "has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": version: 1.1.0 resolution: "has-symbols@npm:1.1.0" @@ -27040,6 +27444,22 @@ __metadata: languageName: node linkType: hard +"hermes-estree@npm:0.25.1": + version: 0.25.1 + resolution: "hermes-estree@npm:0.25.1" + checksum: 10/7b1eca98b264a25632064cffa5771360d30cf452e77db1e191f9913ee45cf78c292b2dbca707e92fb71b0870abb97e94b506a5ab80abd96ba237fee169b601fe + languageName: node + linkType: hard + +"hermes-parser@npm:^0.25.1": + version: 0.25.1 + resolution: "hermes-parser@npm:0.25.1" + dependencies: + hermes-estree: "npm:0.25.1" + checksum: 10/805efc05691420f236654349872c70731121791fa54de521c7ee51059eae34f84dd19f22ee846741dcb60372f8fb5335719b96b4ecb010d2aed7d872f2eff9cc + languageName: node + linkType: hard + "highlight.js@npm:^10.4.1, highlight.js@npm:~10.7.0": version: 10.7.3 resolution: "highlight.js@npm:10.7.3" @@ -27876,6 +28296,17 @@ __metadata: languageName: node linkType: hard +"internal-slot@npm:^1.1.0": + version: 1.1.0 + resolution: "internal-slot@npm:1.1.0" + dependencies: + es-errors: "npm:^1.3.0" + hasown: "npm:^2.0.2" + side-channel: "npm:^1.1.0" + checksum: 10/1d5219273a3dab61b165eddf358815eefc463207db33c20fcfca54717da02e3f492003757721f972fd0bf21e4b426cab389c5427b99ceea4b8b670dc88ee6d4a + languageName: node + linkType: hard + "interpret@npm:^1.0.0, interpret@npm:^1.4.0": version: 1.4.0 resolution: "interpret@npm:1.4.0" @@ -28037,6 +28468,17 @@ __metadata: languageName: node linkType: hard +"is-array-buffer@npm:^3.0.5": + version: 3.0.5 + resolution: "is-array-buffer@npm:3.0.5" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + get-intrinsic: "npm:^1.2.6" + checksum: 10/ef1095c55b963cd0dcf6f88a113e44a0aeca91e30d767c475e7d746d28d1195b10c5076b94491a7a0cd85020ca6a4923070021d74651d093dc909e9932cf689b + languageName: node + linkType: hard + "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -28051,6 +28493,19 @@ __metadata: languageName: node linkType: hard +"is-async-function@npm:^2.0.0": + version: 2.1.1 + resolution: "is-async-function@npm:2.1.1" + dependencies: + async-function: "npm:^1.0.0" + call-bound: "npm:^1.0.3" + get-proto: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.2" + safe-regex-test: "npm:^1.1.0" + checksum: 10/7c2ac7efdf671e03265e74a043bcb1c0a32e226bc2a42dfc5ec8644667df668bbe14b91c08e6c1414f392f8cf86cd1d489b3af97756e2c7a49dd1ba63fd40ca6 + languageName: node + linkType: hard + "is-bigint@npm:^1.0.1": version: 1.0.4 resolution: "is-bigint@npm:1.0.4" @@ -28060,6 +28515,15 @@ __metadata: languageName: node linkType: hard +"is-bigint@npm:^1.1.0": + version: 1.1.0 + resolution: "is-bigint@npm:1.1.0" + dependencies: + has-bigints: "npm:^1.0.2" + checksum: 10/10cf327310d712fe227cfaa32d8b11814c214392b6ac18c827f157e1e85363cf9c8e2a22df526689bd5d25e53b58cc110894787afb54e138e7c504174dba15fd + languageName: node + linkType: hard + "is-binary-path@npm:~2.1.0": version: 2.1.0 resolution: "is-binary-path@npm:2.1.0" @@ -28079,6 +28543,16 @@ __metadata: languageName: node linkType: hard +"is-boolean-object@npm:^1.2.1": + version: 1.2.2 + resolution: "is-boolean-object@npm:1.2.2" + dependencies: + call-bound: "npm:^1.0.3" + has-tostringtag: "npm:^1.0.2" + checksum: 10/051fa95fdb99d7fbf653165a7e6b2cba5d2eb62f7ffa81e793a790f3fb5366c91c1b7b6af6820aa2937dd86c73aa3ca9d9ca98f500988457b1c59692c52ba911 + languageName: node + linkType: hard + "is-buffer@npm:^1.0.2, is-buffer@npm:^1.1.0, is-buffer@npm:^1.1.5, is-buffer@npm:~1.1.6": version: 1.1.6 resolution: "is-buffer@npm:1.1.6" @@ -28131,7 +28605,7 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.12.1, is-core-module@npm:^2.16.0, is-core-module@npm:^2.4.0, is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": +"is-core-module@npm:^2.12.1, is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.0, is-core-module@npm:^2.4.0, is-core-module@npm:^2.8.1": version: 2.16.1 resolution: "is-core-module@npm:2.16.1" dependencies: @@ -28167,6 +28641,17 @@ __metadata: languageName: node linkType: hard +"is-data-view@npm:^1.0.2": + version: 1.0.2 + resolution: "is-data-view@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.2" + get-intrinsic: "npm:^1.2.6" + is-typed-array: "npm:^1.1.13" + checksum: 10/357e9a48fa38f369fd6c4c3b632a3ab2b8adca14997db2e4b3fe94c4cd0a709af48e0fb61b02c64a90c0dd542fd489d49c2d03157b05ae6c07f5e4dec9e730a8 + languageName: node + linkType: hard + "is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": version: 1.0.5 resolution: "is-date-object@npm:1.0.5" @@ -28176,6 +28661,16 @@ __metadata: languageName: node linkType: hard +"is-date-object@npm:^1.1.0": + version: 1.1.0 + resolution: "is-date-object@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.2" + checksum: 10/3a811b2c3176fb31abee1d23d3dc78b6c65fd9c07d591fcb67553cab9e7f272728c3dd077d2d738b53f9a2103255b0a6e8dfc9568a7805c56a78b2563e8d1dec + languageName: node + linkType: hard + "is-decimal@npm:^1.0.0, is-decimal@npm:^1.0.2": version: 1.0.4 resolution: "is-decimal@npm:1.0.4" @@ -28276,6 +28771,15 @@ __metadata: languageName: node linkType: hard +"is-finalizationregistry@npm:^1.1.0": + version: 1.1.1 + resolution: "is-finalizationregistry@npm:1.1.1" + dependencies: + call-bound: "npm:^1.0.3" + checksum: 10/0bfb145e9a1ba852ddde423b0926d2169ae5fe9e37882cde9e8f69031281a986308df4d982283e152396e88b86562ed2256cbaa5e6390fb840a4c25ab54b8a80 + languageName: node + linkType: hard + "is-fn@npm:^1.0.0": version: 1.0.0 resolution: "is-fn@npm:1.0.0" @@ -28313,6 +28817,19 @@ __metadata: languageName: node linkType: hard +"is-generator-function@npm:^1.0.10": + version: 1.1.2 + resolution: "is-generator-function@npm:1.1.2" + dependencies: + call-bound: "npm:^1.0.4" + generator-function: "npm:^2.0.0" + get-proto: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.2" + safe-regex-test: "npm:^1.1.0" + checksum: 10/cc50fa01034356bdfda26983c5457103240f201f4663c0de1257802714e40d36bcff7aee21091d37bbba4be962fa5c6475ce7ddbc0abfa86d6bef466e41e50a5 + languageName: node + linkType: hard + "is-generator-function@npm:^1.0.7": version: 1.0.10 resolution: "is-generator-function@npm:1.0.10" @@ -28438,6 +28955,13 @@ __metadata: languageName: node linkType: hard +"is-map@npm:^2.0.3": + version: 2.0.3 + resolution: "is-map@npm:2.0.3" + checksum: 10/8de7b41715b08bcb0e5edb0fb9384b80d2d5bcd10e142188f33247d19ff078abaf8e9b6f858e2302d8d05376a26a55cd23a3c9f8ab93292b02fcd2cc9e4e92bb + languageName: node + linkType: hard + "is-mergeable-object@npm:1.1.1": version: 1.1.1 resolution: "is-mergeable-object@npm:1.1.1" @@ -28499,6 +29023,16 @@ __metadata: languageName: node linkType: hard +"is-number-object@npm:^1.1.1": + version: 1.1.1 + resolution: "is-number-object@npm:1.1.1" + dependencies: + call-bound: "npm:^1.0.3" + has-tostringtag: "npm:^1.0.2" + checksum: 10/a5922fb8779ab1ea3b8a9c144522b3d0bea5d9f8f23f7a72470e61e1e4df47714e28e0154ac011998b709cce260c3c9447ad3cd24a96c2f2a0abfdb2cbdc76c8 + languageName: node + linkType: hard + "is-number@npm:^2.1.0": version: 2.1.0 resolution: "is-number@npm:2.1.0" @@ -28650,6 +29184,18 @@ __metadata: languageName: node linkType: hard +"is-regex@npm:^1.2.1": + version: 1.2.1 + resolution: "is-regex@npm:1.2.1" + dependencies: + call-bound: "npm:^1.0.2" + gopd: "npm:^1.2.0" + has-tostringtag: "npm:^1.0.2" + hasown: "npm:^2.0.2" + checksum: 10/c42b7efc5868a5c9a4d8e6d3e9816e8815c611b09535c00fead18a1138455c5cb5e1887f0023a467ad3f9c419d62ba4dc3d9ba8bafe55053914d6d6454a945d2 + languageName: node + linkType: hard + "is-regexp@npm:^1.0.0": version: 1.0.0 resolution: "is-regexp@npm:1.0.0" @@ -28701,6 +29247,13 @@ __metadata: languageName: node linkType: hard +"is-set@npm:^2.0.3": + version: 2.0.3 + resolution: "is-set@npm:2.0.3" + checksum: 10/5685df33f0a4a6098a98c72d94d67cad81b2bc72f1fb2091f3d9283c4a1c582123cd709145b02a9745f0ce6b41e3e43f1c944496d1d74d4ea43358be61308669 + languageName: node + linkType: hard + "is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": version: 1.0.3 resolution: "is-shared-array-buffer@npm:1.0.3" @@ -28710,6 +29263,15 @@ __metadata: languageName: node linkType: hard +"is-shared-array-buffer@npm:^1.0.4": + version: 1.0.4 + resolution: "is-shared-array-buffer@npm:1.0.4" + dependencies: + call-bound: "npm:^1.0.3" + checksum: 10/0380d7c60cc692856871526ffcd38a8133818a2ee42d47bb8008248a0cd2121d8c8b5f66b6da3cac24bc5784553cacb6faaf678f66bc88c6615b42af2825230e + languageName: node + linkType: hard + "is-ssh@npm:^1.4.0": version: 1.4.0 resolution: "is-ssh@npm:1.4.0" @@ -28756,6 +29318,16 @@ __metadata: languageName: node linkType: hard +"is-string@npm:^1.1.1": + version: 1.1.1 + resolution: "is-string@npm:1.1.1" + dependencies: + call-bound: "npm:^1.0.3" + has-tostringtag: "npm:^1.0.2" + checksum: 10/5277cb9e225a7cc8a368a72623b44a99f2cfa139659c6b203553540681ad4276bfc078420767aad0e73eef5f0bd07d4abf39a35d37ec216917879d11cebc1f8b + languageName: node + linkType: hard + "is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": version: 1.0.4 resolution: "is-symbol@npm:1.0.4" @@ -28765,7 +29337,18 @@ __metadata: languageName: node linkType: hard -"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.3": +"is-symbol@npm:^1.0.4, is-symbol@npm:^1.1.1": + version: 1.1.1 + resolution: "is-symbol@npm:1.1.1" + dependencies: + call-bound: "npm:^1.0.2" + has-symbols: "npm:^1.1.0" + safe-regex-test: "npm:^1.1.0" + checksum: 10/db495c0d8cd0a7a66b4f4ef7fccee3ab5bd954cb63396e8ac4d32efe0e9b12fdfceb851d6c501216a71f4f21e5ff20fc2ee845a3d52d455e021c466ac5eb2db2 + languageName: node + linkType: hard + +"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15, is-typed-array@npm:^1.1.3": version: 1.1.15 resolution: "is-typed-array@npm:1.1.15" dependencies: @@ -28832,6 +29415,13 @@ __metadata: languageName: node linkType: hard +"is-weakmap@npm:^2.0.2": + version: 2.0.2 + resolution: "is-weakmap@npm:2.0.2" + checksum: 10/a7b7e23206c542dcf2fa0abc483142731788771527e90e7e24f658c0833a0d91948a4f7b30d78f7a65255a48512e41a0288b778ba7fc396137515c12e201fd11 + languageName: node + linkType: hard + "is-weakref@npm:^1.0.2": version: 1.0.2 resolution: "is-weakref@npm:1.0.2" @@ -28841,6 +29431,15 @@ __metadata: languageName: node linkType: hard +"is-weakref@npm:^1.1.1": + version: 1.1.1 + resolution: "is-weakref@npm:1.1.1" + dependencies: + call-bound: "npm:^1.0.3" + checksum: 10/543506fd8259038b371bb083aac25b16cb4fd8b12fc58053aa3d45ac28dfd001cd5c6dffbba7aeea4213c74732d46b6cb2cfb5b412eed11f2db524f3f97d09a0 + languageName: node + linkType: hard + "is-weakset@npm:^2.0.1": version: 2.0.2 resolution: "is-weakset@npm:2.0.2" @@ -28851,6 +29450,16 @@ __metadata: languageName: node linkType: hard +"is-weakset@npm:^2.0.3": + version: 2.0.4 + resolution: "is-weakset@npm:2.0.4" + dependencies: + call-bound: "npm:^1.0.3" + get-intrinsic: "npm:^1.2.6" + checksum: 10/1d5e1d0179beeed3661125a6faa2e59bfb48afda06fc70db807f178aa0ebebc3758fb6358d76b3d528090d5ef85148c345dcfbf90839592fe293e3e5e82f2134 + languageName: node + linkType: hard + "is-whitespace-character@npm:^1.0.0": version: 1.0.3 resolution: "is-whitespace-character@npm:1.0.3" @@ -29105,6 +29714,20 @@ __metadata: languageName: node linkType: hard +"iterator.prototype@npm:^1.1.4": + version: 1.1.5 + resolution: "iterator.prototype@npm:1.1.5" + dependencies: + define-data-property: "npm:^1.1.4" + es-object-atoms: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.6" + get-proto: "npm:^1.0.0" + has-symbols: "npm:^1.1.0" + set-function-name: "npm:^2.0.2" + checksum: 10/352bcf333f42189e65cc8cb2dcb94a5c47cf0a9110ce12aba788d405a980b5f5f3a06c79bf915377e1d480647169babd842ded0d898bed181bf6686e8e6823f6 + languageName: node + linkType: hard + "jackspeak@npm:^3.1.2": version: 3.1.2 resolution: "jackspeak@npm:3.1.2" @@ -32239,6 +32862,7 @@ __metadata: autoprefixer: "npm:^10.4.19" await-semaphore: "npm:^0.1.3" axios: "npm:^1.12.0" + babel-plugin-react-compiler: "npm:^19.1.0-rc.2" babelify: "npm:^10.0.0" base32-encode: "npm:^1.2.0" base64-js: "npm:^1.5.1" @@ -32284,8 +32908,9 @@ __metadata: eslint-plugin-mocha: "npm:^10.1.0" eslint-plugin-node: "npm:^11.1.0" eslint-plugin-prettier: "npm:^5.5.1" - eslint-plugin-react: "npm:^7.23.1" - eslint-plugin-react-hooks: "npm:^4.2.0" + eslint-plugin-react: "npm:^7.37.5" + eslint-plugin-react-compiler: "npm:^19.1.0-rc.2" + eslint-plugin-react-hooks: "npm:^5.2.0" eslint-plugin-storybook: "npm:^0.6.15" eslint-plugin-tailwindcss: "npm:^3.18.0" eta: "npm:^3.2.0" @@ -32381,6 +33006,8 @@ __metadata: react: "npm:^17.0.2" react-beautiful-dnd: "npm:^13.1.1" react-chartjs-2: "npm:^5.2.0" + react-compiler-runtime: "npm:^19.1.0-rc.2" + react-compiler-webpack: "npm:^0.2.0" react-devtools: "npm:^6.1.5" react-devtools-core: "npm:^6.1.5" react-dom: "npm:^17.0.2" @@ -33842,6 +34469,13 @@ __metadata: languageName: node linkType: hard +"object-inspect@npm:^1.13.4": + version: 1.13.4 + resolution: "object-inspect@npm:1.13.4" + checksum: 10/aa13b1190ad3e366f6c83ad8a16ed37a19ed57d267385aa4bfdccda833d7b90465c057ff6c55d035a6b2e52c1a2295582b294217a0a3a1ae7abdd6877ef781fb + languageName: node + linkType: hard + "object-is@npm:^1.1.5": version: 1.1.5 resolution: "object-is@npm:1.1.5" @@ -33880,6 +34514,20 @@ __metadata: languageName: node linkType: hard +"object.assign@npm:^4.1.7": + version: 4.1.7 + resolution: "object.assign@npm:4.1.7" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + has-symbols: "npm:^1.1.0" + object-keys: "npm:^1.1.1" + checksum: 10/3fe28cdd779f2a728a9a66bd688679ba231a2b16646cd1e46b528fe7c947494387dda4bc189eff3417f3717ef4f0a8f2439347cf9a9aa3cef722fbfd9f615587 + languageName: node + linkType: hard + "object.defaults@npm:^1.0.0, object.defaults@npm:^1.1.0": version: 1.1.0 resolution: "object.defaults@npm:1.1.0" @@ -33892,35 +34540,27 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.5": - version: 1.1.6 - resolution: "object.entries@npm:1.1.6" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.1.4" - es-abstract: "npm:^1.20.4" - checksum: 10/08a09ff839fd541e8af90a47c67a3dd71721683cdc28e55470e191a8afd8b61188fb9a429fd1d1805808097d8d5950b47c0c2862157dad891226112d8321401b - languageName: node - linkType: hard - -"object.fromentries@npm:^2.0.5": - version: 2.0.6 - resolution: "object.fromentries@npm:2.0.6" +"object.entries@npm:^1.1.9": + version: 1.1.9 + resolution: "object.entries@npm:1.1.9" dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.1.4" - es-abstract: "npm:^1.20.4" - checksum: 10/e8b813647cbc6505750cdff8b3978bb341492707a5f1df4129e2d8a904b31692e225eff92481ae5916be3bde3c2eff1d0e8a6730921ca7f4eed60bc15a70cb35 + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.1.1" + checksum: 10/24163ab1e1e013796693fc5f5d349e8b3ac0b6a34a7edb6c17d3dd45c6a8854145780c57d302a82512c1582f63720f4b4779d6c1cfba12cbb1420b978802d8a3 languageName: node linkType: hard -"object.hasown@npm:^1.1.1": - version: 1.1.2 - resolution: "object.hasown@npm:1.1.2" +"object.fromentries@npm:^2.0.8": + version: 2.0.8 + resolution: "object.fromentries@npm:2.0.8" dependencies: - define-properties: "npm:^1.1.4" - es-abstract: "npm:^1.20.4" - checksum: 10/94031022a2ba6006c15c6f1e0c4f51a7fa5b36aee64800192335b979fcc8bd823b18c35cb1a728af68fdfdbbe6d765f77a3c5437306c031f63654b8a34b9e639 + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-object-atoms: "npm:^1.0.0" + checksum: 10/5b2e80f7af1778b885e3d06aeb335dcc86965e39464671adb7167ab06ac3b0f5dd2e637a90d8ebd7426d69c6f135a4753ba3dd7d0fe2a7030cf718dcb910fd92 languageName: node linkType: hard @@ -33974,6 +34614,18 @@ __metadata: languageName: node linkType: hard +"object.values@npm:^1.2.1": + version: 1.2.1 + resolution: "object.values@npm:1.2.1" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10/f5ec9eccdefeaaa834b089c525663436812a65ff13de7964a1c3a9110f32054f2d58aa476a645bb14f75a79f3fe1154fb3e7bfdae7ac1e80affe171b2ef74bce + languageName: node + linkType: hard + "object.values@patch:object.values@npm%3A1.1.5#./.yarn/patches/object.values-npm-1.1.5-f1de7f3742.patch::locator=metamask-crx%40workspace%3A.": version: 1.1.5 resolution: "object.values@patch:object.values@npm%3A1.1.5#./.yarn/patches/object.values-npm-1.1.5-f1de7f3742.patch::version=1.1.5&hash=b949cc&locator=metamask-crx%40workspace%3A." @@ -34255,6 +34907,17 @@ __metadata: languageName: node linkType: hard +"own-keys@npm:^1.0.1": + version: 1.0.1 + resolution: "own-keys@npm:1.0.1" + dependencies: + get-intrinsic: "npm:^1.2.6" + object-keys: "npm:^1.1.1" + safe-push-apply: "npm:^1.0.0" + checksum: 10/ab4bb3b8636908554fc19bf899e225444195092864cb61503a0d048fdaf662b04be2605b636a4ffeaf6e8811f6fcfa8cbb210ec964c0eb1a41eb853e1d5d2f41 + languageName: node + linkType: hard + "ox@npm:0.6.7": version: 0.6.7 resolution: "ox@npm:0.6.7" @@ -36460,6 +37123,28 @@ __metadata: languageName: node linkType: hard +"react-compiler-runtime@npm:^19.1.0-rc.2": + version: 19.1.0-rc.3 + resolution: "react-compiler-runtime@npm:19.1.0-rc.3" + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental + checksum: 10/ee9085e070eec4135bad982f47a82a4fc28c0c6d7111b3ec93354dab61bd56f9da0bde18af2ab0ee84f5ff9e71026cbfa58513ce8ac7c0290979a84199970ab6 + languageName: node + linkType: hard + +"react-compiler-webpack@npm:^0.2.0": + version: 0.2.1 + resolution: "react-compiler-webpack@npm:0.2.1" + dependencies: + "@babel/core": "npm:^7.28.4" + "@babel/plugin-syntax-jsx": "npm:^7.27.1" + "@babel/plugin-syntax-typescript": "npm:^7.27.1" + peerDependencies: + babel-plugin-react-compiler: "*" + checksum: 10/5571abebe68334969f3a40c6c21a4a6c3d8ba8a63c91348eac1209624e58e5b373609677244bbbd7480a094517c1b15f75d54400a91914728d74c9194d76775a + languageName: node + linkType: hard + "react-devtools-core@npm:6.1.5, react-devtools-core@npm:^6.1.5": version: 6.1.5 resolution: "react-devtools-core@npm:6.1.5" @@ -37349,6 +38034,22 @@ __metadata: languageName: node linkType: hard +"reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9": + version: 1.0.10 + resolution: "reflect.getprototypeof@npm:1.0.10" + dependencies: + call-bind: "npm:^1.0.8" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.9" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.7" + get-proto: "npm:^1.0.1" + which-builtin-type: "npm:^1.2.1" + checksum: 10/80a4e2be716f4fe46a89a08ccad0863b47e8ce0f49616cab2d65dab0fbd53c6fdba0f52935fd41d37a2e4e22355c272004f920d63070de849f66eea7aeb4a081 + languageName: node + linkType: hard + "refractor@npm:^3.6.0": version: 3.6.0 resolution: "refractor@npm:3.6.0" @@ -37418,7 +38119,7 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.4.1, regexp.prototype.flags@npm:^1.5.1, regexp.prototype.flags@npm:^1.5.2": +"regexp.prototype.flags@npm:^1.4.1, regexp.prototype.flags@npm:^1.5.1, regexp.prototype.flags@npm:^1.5.2, regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4": version: 1.5.4 resolution: "regexp.prototype.flags@npm:1.5.4" dependencies: @@ -37991,16 +38692,16 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^2.0.0-next.3": - version: 2.0.0-next.4 - resolution: "resolve@npm:2.0.0-next.4" +"resolve@npm:^2.0.0-next.5": + version: 2.0.0-next.5 + resolution: "resolve@npm:2.0.0-next.5" dependencies: - is-core-module: "npm:^2.9.0" + is-core-module: "npm:^2.13.0" path-parse: "npm:^1.0.7" supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10/20d5293f5015aa0b65c488ee365f9dfc30b954b04f9074425a6fb738d78fa63825a82ba8574b7ee200af7ebd5e98c41786831d1d4c1612da3cd063980dfa06a3 + checksum: 10/2d6fd28699f901744368e6f2032b4268b4c7b9185fd8beb64f68c93ac6b22e52ae13560ceefc96241a665b985edf9ffd393ae26d2946a7d3a07b7007b7d51e79 languageName: node linkType: hard @@ -38018,16 +38719,16 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^2.0.0-next.3#optional!builtin": - version: 2.0.0-next.4 - resolution: "resolve@patch:resolve@npm%3A2.0.0-next.4#optional!builtin::version=2.0.0-next.4&hash=c3c19d" +"resolve@patch:resolve@npm%3A^2.0.0-next.5#optional!builtin": + version: 2.0.0-next.5 + resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#optional!builtin::version=2.0.0-next.5&hash=c3c19d" dependencies: - is-core-module: "npm:^2.9.0" + is-core-module: "npm:^2.13.0" path-parse: "npm:^1.0.7" supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10/27bff19d8219385bb1e271066317e553cff18daa2a19db9598d94ae444417ef3f5aec19e86927872d6cb241d02649cfb35a4c0d9d10ef2afa6325bce8bc8d903 + checksum: 10/05fa778de9d0347c8b889eb7a18f1f06bf0f801b0eb4610b4871a4b2f22e220900cf0ad525e94f990bb8d8921c07754ab2122c0c225ab4cdcea98f36e64fa4c2 languageName: node linkType: hard @@ -38342,6 +39043,19 @@ __metadata: languageName: node linkType: hard +"safe-array-concat@npm:^1.1.3": + version: 1.1.3 + resolution: "safe-array-concat@npm:1.1.3" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.2" + get-intrinsic: "npm:^1.2.6" + has-symbols: "npm:^1.1.0" + isarray: "npm:^2.0.5" + checksum: 10/fac4f40f20a3f7da024b54792fcc61059e814566dcbb04586bfefef4d3b942b2408933f25b7b3dd024affd3f2a6bbc916bef04807855e4f192413941369db864 + languageName: node + linkType: hard + "safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" @@ -38363,6 +39077,16 @@ __metadata: languageName: node linkType: hard +"safe-push-apply@npm:^1.0.0": + version: 1.0.0 + resolution: "safe-push-apply@npm:1.0.0" + dependencies: + es-errors: "npm:^1.3.0" + isarray: "npm:^2.0.5" + checksum: 10/2bd4e53b6694f7134b9cf93631480e7fafc8637165f0ee91d5a4af5e7f33d37de9562d1af5021178dd4217d0230cde8d6530fa28cfa1ebff9a431bf8fff124b4 + languageName: node + linkType: hard + "safe-regex-test@npm:^1.0.3": version: 1.0.3 resolution: "safe-regex-test@npm:1.0.3" @@ -38374,6 +39098,17 @@ __metadata: languageName: node linkType: hard +"safe-regex-test@npm:^1.1.0": + version: 1.1.0 + resolution: "safe-regex-test@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + is-regex: "npm:^1.2.1" + checksum: 10/ebdb61f305bf4756a5b023ad86067df5a11b26898573afe9e52a548a63c3bd594825d9b0e2dde2eb3c94e57e0e04ac9929d4107c394f7b8e56a4613bed46c69a + languageName: node + linkType: hard + "safe-regex@npm:^1.1.0": version: 1.1.0 resolution: "safe-regex@npm:1.1.0" @@ -39044,6 +39779,17 @@ __metadata: languageName: node linkType: hard +"set-proto@npm:^1.0.0": + version: 1.0.0 + resolution: "set-proto@npm:1.0.0" + dependencies: + dunder-proto: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + checksum: 10/b87f8187bca595ddc3c0721ece4635015fd9d7cb294e6dd2e394ce5186a71bbfa4dc8a35010958c65e43ad83cde09642660e61a952883c24fd6b45ead15f045c + languageName: node + linkType: hard + "set-value@npm:^2.0.0, set-value@npm:^2.0.1": version: 2.0.1 resolution: "set-value@npm:2.0.1" @@ -39932,6 +40678,16 @@ __metadata: languageName: node linkType: hard +"stop-iteration-iterator@npm:^1.1.0": + version: 1.1.0 + resolution: "stop-iteration-iterator@npm:1.1.0" + dependencies: + es-errors: "npm:^1.3.0" + internal-slot: "npm:^1.1.0" + checksum: 10/ff36c4db171ee76c936ccfe9541946b77017f12703d4c446652017356816862d3aa029a64e7d4c4ceb484e00ed4a81789333896390d808458638f3a216aa1f41 + languageName: node + linkType: hard + "store2@npm:^2.14.2": version: 2.14.2 resolution: "store2@npm:2.14.2" @@ -40146,7 +40902,28 @@ __metadata: languageName: node linkType: hard -"string.prototype.matchall@npm:^4.0.2, string.prototype.matchall@npm:^4.0.7": +"string.prototype.matchall@npm:^4.0.12": + version: 4.0.12 + resolution: "string.prototype.matchall@npm:4.0.12" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.6" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.6" + gopd: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + internal-slot: "npm:^1.1.0" + regexp.prototype.flags: "npm:^1.5.3" + set-function-name: "npm:^2.0.2" + side-channel: "npm:^1.1.0" + checksum: 10/e4ab34b9e7639211e6c5e9759adb063028c5c5c4fc32ad967838b2bd1e5ce83a66ae8ec755d24a79302849f090b59194571b2c33471e86e7821b21c0f56df316 + languageName: node + linkType: hard + +"string.prototype.matchall@npm:^4.0.2": version: 4.0.7 resolution: "string.prototype.matchall@npm:4.0.7" dependencies: @@ -40162,6 +40939,31 @@ __metadata: languageName: node linkType: hard +"string.prototype.repeat@npm:^1.0.0": + version: 1.0.0 + resolution: "string.prototype.repeat@npm:1.0.0" + dependencies: + define-properties: "npm:^1.1.3" + es-abstract: "npm:^1.17.5" + checksum: 10/4b1bd91b75fa8fdf0541625184ebe80e445a465ce4253c19c3bccd633898005dadae0f74b85ae72662a53aafb8035bf48f8f5c0755aec09bc106a7f13959d05e + languageName: node + linkType: hard + +"string.prototype.trim@npm:^1.2.10": + version: 1.2.10 + resolution: "string.prototype.trim@npm:1.2.10" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.2" + define-data-property: "npm:^1.1.4" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.5" + es-object-atoms: "npm:^1.0.0" + has-property-descriptors: "npm:^1.0.2" + checksum: 10/47bb63cd2470a64bc5e2da1e570d369c016ccaa85c918c3a8bb4ab5965120f35e66d1f85ea544496fac84b9207a6b722adf007e6c548acd0813e5f8a82f9712a + languageName: node + linkType: hard + "string.prototype.trim@npm:^1.2.9": version: 1.2.9 resolution: "string.prototype.trim@npm:1.2.9" @@ -40185,6 +40987,18 @@ __metadata: languageName: node linkType: hard +"string.prototype.trimend@npm:^1.0.9": + version: 1.0.9 + resolution: "string.prototype.trimend@npm:1.0.9" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.2" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10/140c73899b6747de9e499c7c2e7a83d549c47a26fa06045b69492be9cfb9e2a95187499a373983a08a115ecff8bc3bd7b0fb09b8ff72fb2172abe766849272ef + languageName: node + linkType: hard + "string.prototype.trimstart@npm:^1.0.8": version: 1.0.8 resolution: "string.prototype.trimstart@npm:1.0.8" @@ -41812,6 +42626,19 @@ __metadata: languageName: node linkType: hard +"typed-array-byte-length@npm:^1.0.3": + version: 1.0.3 + resolution: "typed-array-byte-length@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.8" + for-each: "npm:^0.3.3" + gopd: "npm:^1.2.0" + has-proto: "npm:^1.2.0" + is-typed-array: "npm:^1.1.14" + checksum: 10/269dad101dda73e3110117a9b84db86f0b5c07dad3a9418116fd38d580cab7fc628a4fc167e29b6d7c39da2f53374b78e7cb578b3c5ec7a556689d985d193519 + languageName: node + linkType: hard + "typed-array-byte-offset@npm:^1.0.2": version: 1.0.2 resolution: "typed-array-byte-offset@npm:1.0.2" @@ -41826,6 +42653,21 @@ __metadata: languageName: node linkType: hard +"typed-array-byte-offset@npm:^1.0.4": + version: 1.0.4 + resolution: "typed-array-byte-offset@npm:1.0.4" + dependencies: + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + for-each: "npm:^0.3.3" + gopd: "npm:^1.2.0" + has-proto: "npm:^1.2.0" + is-typed-array: "npm:^1.1.15" + reflect.getprototypeof: "npm:^1.0.9" + checksum: 10/c2869aa584cdae24ecfd282f20a0f556b13a49a9d5bca1713370bb3c89dff0ccbc5ceb45cb5b784c98f4579e5e3e2a07e438c3a5b8294583e2bd4abbd5104fb5 + languageName: node + linkType: hard + "typed-array-length@npm:^1.0.6": version: 1.0.6 resolution: "typed-array-length@npm:1.0.6" @@ -41840,6 +42682,20 @@ __metadata: languageName: node linkType: hard +"typed-array-length@npm:^1.0.7": + version: 1.0.7 + resolution: "typed-array-length@npm:1.0.7" + dependencies: + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + is-typed-array: "npm:^1.1.13" + possible-typed-array-names: "npm:^1.0.0" + reflect.getprototypeof: "npm:^1.0.6" + checksum: 10/d6b2f0e81161682d2726eb92b1dc2b0890890f9930f33f9bcf6fc7272895ce66bc368066d273e6677776de167608adc53fcf81f1be39a146d64b630edbf2081c + languageName: node + linkType: hard + "typed-error@npm:^3.0.2": version: 3.2.1 resolution: "typed-error@npm:3.2.1" @@ -42012,6 +42868,18 @@ __metadata: languageName: node linkType: hard +"unbox-primitive@npm:^1.1.0": + version: 1.1.0 + resolution: "unbox-primitive@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.3" + has-bigints: "npm:^1.0.2" + has-symbols: "npm:^1.1.0" + which-boxed-primitive: "npm:^1.1.1" + checksum: 10/fadb347020f66b2c8aeacf8b9a79826fa34cc5e5457af4eb0bbc4e79bd87fed0fa795949825df534320f7c13f199259516ad30abc55a6e7b91d8d996ca069e50 + languageName: node + linkType: hard + "unc-path-regex@npm:^0.1.2": version: 0.1.2 resolution: "unc-path-regex@npm:0.1.2" @@ -43789,6 +44657,40 @@ __metadata: languageName: node linkType: hard +"which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1": + version: 1.1.1 + resolution: "which-boxed-primitive@npm:1.1.1" + dependencies: + is-bigint: "npm:^1.1.0" + is-boolean-object: "npm:^1.2.1" + is-number-object: "npm:^1.1.1" + is-string: "npm:^1.1.1" + is-symbol: "npm:^1.1.1" + checksum: 10/a877c0667bc089518c83ad4d845cf8296b03efe3565c1de1940c646e00a2a1ae9ed8a185bcfa27cbf352de7906f0616d83b9d2f19ca500ee02a551fb5cf40740 + languageName: node + linkType: hard + +"which-builtin-type@npm:^1.2.1": + version: 1.2.1 + resolution: "which-builtin-type@npm:1.2.1" + dependencies: + call-bound: "npm:^1.0.2" + function.prototype.name: "npm:^1.1.6" + has-tostringtag: "npm:^1.0.2" + is-async-function: "npm:^2.0.0" + is-date-object: "npm:^1.1.0" + is-finalizationregistry: "npm:^1.1.0" + is-generator-function: "npm:^1.0.10" + is-regex: "npm:^1.2.1" + is-weakref: "npm:^1.0.2" + isarray: "npm:^2.0.5" + which-boxed-primitive: "npm:^1.1.0" + which-collection: "npm:^1.0.2" + which-typed-array: "npm:^1.1.16" + checksum: 10/22c81c5cb7a896c5171742cd30c90d992ff13fb1ea7693e6cf80af077791613fb3f89aa9b4b7f890bd47b6ce09c6322c409932359580a2a2a54057f7b52d1cbe + languageName: node + linkType: hard + "which-collection@npm:^1.0.1": version: 1.0.1 resolution: "which-collection@npm:1.0.1" @@ -43801,6 +44703,18 @@ __metadata: languageName: node linkType: hard +"which-collection@npm:^1.0.2": + version: 1.0.2 + resolution: "which-collection@npm:1.0.2" + dependencies: + is-map: "npm:^2.0.3" + is-set: "npm:^2.0.3" + is-weakmap: "npm:^2.0.2" + is-weakset: "npm:^2.0.3" + checksum: 10/674bf659b9bcfe4055f08634b48a8588e879161b9fefed57e9ec4ff5601e4d50a05ccd76cf10f698ef5873784e5df3223336d56c7ce88e13bcf52ebe582fc8d7 + languageName: node + linkType: hard + "which-module@npm:^1.0.0": version: 1.0.0 resolution: "which-module@npm:1.0.0" @@ -43815,7 +44729,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.2": +"which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19, which-typed-array@npm:^1.1.2": version: 1.1.19 resolution: "which-typed-array@npm:1.1.19" dependencies: @@ -44413,6 +45327,15 @@ __metadata: languageName: node linkType: hard +"zod-validation-error@npm:^3.0.3": + version: 3.5.3 + resolution: "zod-validation-error@npm:3.5.3" + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + checksum: 10/f550565ffb2a0a1733616d856302184dbe2080ec649ff9361125467065c3dfa02aeb5bf399605cdb61fe640f79ff1fe8ad0805f6e0c8144fa34764cad58f4401 + languageName: node + linkType: hard + "zod@npm:3.22.4": version: 3.22.4 resolution: "zod@npm:3.22.4" @@ -44420,7 +45343,7 @@ __metadata: languageName: node linkType: hard -"zod@npm:3.25.76": +"zod@npm:3.25.76, zod@npm:^3.22.4": version: 3.25.76 resolution: "zod@npm:3.25.76" checksum: 10/f0c963ec40cd96858451d1690404d603d36507c1fc9682f2dae59ab38b578687d542708a7fdbf645f77926f78c9ed558f57c3d3aa226c285f798df0c4da16995 From 435d46f4e2ff3419f0e99537e5c28628f49ebe0d Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Mon, 3 Nov 2025 14:43:27 -0500 Subject: [PATCH 09/68] Fix formatting rule violations --- .../app/assets/token-cell/token-cell.test.tsx | 4 +- .../app/assets/token-list/token-list.tsx | 2 - .../app/currency-input/currency-input.js | 1 - .../modals/qr-scanner/qr-scanner.component.js | 1 - .../qr-hardware-popover/enhanced-reader.js | 1 - .../qr-hardware-popover.js | 1 - .../terms-of-use-popup/terms-of-use-popup.js | 1 - .../account-list-item-menu.js | 1 - .../account-picker/account-picker.js | 7 +- .../notification-detail-network-fee.tsx | 15 +- ui/components/multichain/pages/send/send.js | 1 - ui/ducks/swaps/swaps.js | 5 +- .../initialized/initialized.component.js | 2 +- .../with-router-hooks/with-router-hooks.tsx | 6 +- .../gator-permissions/useGatorPermissions.ts | 1 - ui/hooks/useCurrencyRatePolling.ts | 4 +- .../useIsOriginalNativeTokenSymbol.test.ts | 6 +- ui/hooks/useIsOriginalNativeTokenSymbol.ts | 4 +- ui/hooks/useIsOriginalTokenSymbol.js | 1 - ui/hooks/useName.test.ts | 99 ++++---- ui/hooks/useOriginTrustSignals.test.ts | 111 +++++---- ui/hooks/useTrustSignals.test.ts | 233 ++++++++++-------- .../awaiting-signatures.tsx | 1 - .../bridge/prepare/prepare-bridge-page.tsx | 18 +- .../confirm-add-suggested-token.js | 1 - .../info/hooks/useDecodedTransactionData.ts | 4 +- .../confirm/info/hooks/useFourByte.ts | 4 +- .../info/hooks/useNestedTransactionLabels.ts | 2 +- .../simulation-error-message.js | 1 - .../confirm-transaction.component.js | 6 +- .../confirmation/confirmation.js | 4 +- .../snap/snap-footer-button.tsx | 4 +- .../networks-form/use-safe-chains.ts | 4 +- .../awaiting-signatures.js | 1 - .../prepare-swap-page/prepare-swap-page.js | 2 - .../swaps/prepare-swap-page/review-quote.js | 4 +- ui/selectors/confirm-transaction.js | 2 +- ui/selectors/selectors.js | 2 +- ui/store/background-connection.ts | 2 +- 39 files changed, 308 insertions(+), 261 deletions(-) diff --git a/ui/components/app/assets/token-cell/token-cell.test.tsx b/ui/components/app/assets/token-cell/token-cell.test.tsx index f6fd5732cb04..5d23438bd6c7 100644 --- a/ui/components/app/assets/token-cell/token-cell.test.tsx +++ b/ui/components/app/assets/token-cell/token-cell.test.tsx @@ -12,7 +12,7 @@ import { getPreferences, getCurrencyRates, getUseCurrencyRateCheck, - useSafeChainsListValidationSelector, + getUseSafeChainsListValidation, getEnabledNetworksByNamespace, } from '../../../../selectors'; import { @@ -193,7 +193,7 @@ describe('Token Cell', () => { if (selector === getUseCurrencyRateCheck) { return true; } - if (selector === useSafeChainsListValidationSelector) { + if (selector === getUseSafeChainsListValidation) { return true; } if (selector === getEnabledNetworksByNamespace) { diff --git a/ui/components/app/assets/token-list/token-list.tsx b/ui/components/app/assets/token-list/token-list.tsx index c9eadc70b3d0..320b866de33c 100644 --- a/ui/components/app/assets/token-list/token-list.tsx +++ b/ui/components/app/assets/token-list/token-list.tsx @@ -139,8 +139,6 @@ function TokenList({ onTokenClick, safeChains }: TokenListProps) { return token; }); - - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ isEvm, evmBalances, diff --git a/ui/components/app/currency-input/currency-input.js b/ui/components/app/currency-input/currency-input.js index 35696921912c..c12ddce40140 100644 --- a/ui/components/app/currency-input/currency-input.js +++ b/ui/components/app/currency-input/currency-input.js @@ -164,7 +164,6 @@ export default function CurrencyInput({ ); // tokenDecimalValue does not need to be in here, since this side effect is only for upstream updates - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ hexValue, asset?.address, diff --git a/ui/components/app/modals/qr-scanner/qr-scanner.component.js b/ui/components/app/modals/qr-scanner/qr-scanner.component.js index 51ae5a89a6ef..32f04dd5b3fd 100644 --- a/ui/components/app/modals/qr-scanner/qr-scanner.component.js +++ b/ui/components/app/modals/qr-scanner/qr-scanner.component.js @@ -179,7 +179,6 @@ export default function QRCodeScanner({ hideModal, qrCodeDetected }) { await checkEnvironment(); })(); // only renders when component is mounted and unmounted - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { diff --git a/ui/components/app/qr-hardware-popover/enhanced-reader.js b/ui/components/app/qr-hardware-popover/enhanced-reader.js index 2c58a7263beb..340983a4e011 100644 --- a/ui/components/app/qr-hardware-popover/enhanced-reader.js +++ b/ui/components/app/qr-hardware-popover/enhanced-reader.js @@ -42,7 +42,6 @@ const EnhancedReader = ({ handleScan }) => { }) .catch(log.info); }; - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/ui/components/app/qr-hardware-popover/qr-hardware-popover.js b/ui/components/app/qr-hardware-popover/qr-hardware-popover.js index 5779a3740f72..21506313777f 100644 --- a/ui/components/app/qr-hardware-popover/qr-hardware-popover.js +++ b/ui/components/app/qr-hardware-popover/qr-hardware-popover.js @@ -27,7 +27,6 @@ const QRHardwarePopover = () => { // we want to block the changing by sign request id; const _txData = useMemo(() => { return txData; - // eslint-disable-next-line react-hooks/exhaustive-deps }, [activeScanRequest?.requestId]); const dispatch = useDispatch(); diff --git a/ui/components/app/terms-of-use-popup/terms-of-use-popup.js b/ui/components/app/terms-of-use-popup/terms-of-use-popup.js index 4b27cd507d4e..7adc9719e661 100644 --- a/ui/components/app/terms-of-use-popup/terms-of-use-popup.js +++ b/ui/components/app/terms-of-use-popup/terms-of-use-popup.js @@ -92,7 +92,6 @@ export default function TermsOfUsePopup({ onClose, onAccept }) { location: 'Terms Of Use Popover', }, }); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/ui/components/multichain/account-list-item-menu/account-list-item-menu.js b/ui/components/multichain/account-list-item-menu/account-list-item-menu.js index 01899176b97c..94d6db12ed47 100644 --- a/ui/components/multichain/account-list-item-menu/account-list-item-menu.js +++ b/ui/components/multichain/account-list-item-menu/account-list-item-menu.js @@ -83,7 +83,6 @@ export const AccountListItemMenu = ({ } else { lastItemRef.current = accountDetailsItemRef.current; } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ removeJWTItemRef.current, removeAccountItemRef.current, diff --git a/ui/components/multichain/account-picker/account-picker.js b/ui/components/multichain/account-picker/account-picker.js index 7cf8761b97e3..112826011905 100644 --- a/ui/components/multichain/account-picker/account-picker.js +++ b/ui/components/multichain/account-picker/account-picker.js @@ -43,9 +43,6 @@ export const AccountPicker = ({ showAvatarAccount = true, ...props }) => { - AccountPicker.propTypes = { - showAvatarAccount: PropTypes.bool, - }; const shortenedAddress = address ? shortenAddress(toChecksumHexAddress(address)) : ''; @@ -188,4 +185,8 @@ AccountPicker.propTypes = { * Additional className to be added to the AccountPicker */ className: PropTypes.string, + /** + * Represents if the avatar account should display + */ + showAvatarAccount: PropTypes.bool, }; diff --git a/ui/components/multichain/notification-detail-network-fee/notification-detail-network-fee.tsx b/ui/components/multichain/notification-detail-network-fee/notification-detail-network-fee.tsx index d4ba1250c3d9..21972172e92c 100644 --- a/ui/components/multichain/notification-detail-network-fee/notification-detail-network-fee.tsx +++ b/ui/components/multichain/notification-detail-network-fee/notification-detail-network-fee.tsx @@ -1,6 +1,6 @@ import React, { useContext, useState, useEffect } from 'react'; import type { FC } from 'react'; -import type { NotificationServicesController } from '@metamask/notification-services-controller'; +import type { OnChainRawNotificationsWithNetworkFields } from '@metamask/notification-services-controller/notification-services'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../../contexts/metametrics'; @@ -36,9 +36,6 @@ import { } from '../../../helpers/constants/design-system'; import Preloader from '../../ui/icon/preloader/preloader-icon.component'; -type OnChainRawNotificationsWithNetworkFields = - NotificationServicesController.Types.OnChainRawNotificationsWithNetworkFields; - type NetworkFees = { transactionFee: { transactionFeeInEther: string; @@ -86,8 +83,8 @@ const FeeDetail = ({ label, value }: { label: string; value: string }) => ( * @deprecated - we are planning to remove this component * @returns The NotificationDetailNetworkFee component. */ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -const _NotificationDetailNetworkFee: FC = ({ +// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/naming-convention +const NotificationDetailNetworkFee_: FC = ({ notification, }) => { const t = useI18nContext(); @@ -105,7 +102,9 @@ const _NotificationDetailNetworkFee: FC = ({ useEffect(() => { const fetchNetworkFees = async () => { try { - const networkFeesData = await getNetworkFees(notification); + const networkFeesData = await getNetworkFees( + notification as Parameters[0], + ); if (networkFeesData) { setNetworkFees({ transactionFee: { @@ -124,7 +123,7 @@ const _NotificationDetailNetworkFee: FC = ({ } }; fetchNetworkFees(); - }, []); + }, [notification]); const handleClick = () => { if (!isOpen) { diff --git a/ui/components/multichain/pages/send/send.js b/ui/components/multichain/pages/send/send.js index 6a10f881989a..85e0ba458928 100644 --- a/ui/components/multichain/pages/send/send.js +++ b/ui/components/multichain/pages/send/send.js @@ -276,7 +276,6 @@ export const SendPage = () => { ); } // sendAnalytics should not result in the event refiring - // eslint-disable-next-line react-hooks/exhaustive-deps }, [trackEvent, swapQuotesError]); const onSubmit = async (event) => { diff --git a/ui/ducks/swaps/swaps.js b/ui/ducks/swaps/swaps.js index 73f40fc1aa98..c62abd95b1c2 100644 --- a/ui/ducks/swaps/swaps.js +++ b/ui/ducks/swaps/swaps.js @@ -1505,13 +1505,11 @@ export function cancelSwapsSmartTransaction(uuid) { }; } -export const getIsEstimatedReturnLow = ({ usedQuote, rawNetworkFees }) => { +export const useGetIsEstimatedReturnLow = ({ usedQuote, rawNetworkFees }) => { const sourceTokenAmount = calcTokenAmount( usedQuote?.sourceAmount, usedQuote?.sourceTokenInfo?.decimals, ); - // Disabled because it's not a hook - // eslint-disable-next-line react-hooks/rules-of-hooks const sourceTokenFiatAmount = useTokenFiatAmount( usedQuote?.sourceTokenInfo?.address, sourceTokenAmount || 0, @@ -1528,7 +1526,6 @@ export const getIsEstimatedReturnLow = ({ usedQuote, rawNetworkFees }) => { usedQuote?.destinationTokenInfo?.decimals, ); // Disabled because it's not a hook - // eslint-disable-next-line react-hooks/rules-of-hooks const destinationTokenFiatAmount = useTokenFiatAmount( usedQuote?.destinationTokenInfo?.address, destinationTokenAmount || 0, diff --git a/ui/helpers/higher-order-components/initialized/initialized.component.js b/ui/helpers/higher-order-components/initialized/initialized.component.js index 6c2561da2893..7ab8ad60dc25 100644 --- a/ui/helpers/higher-order-components/initialized/initialized.component.js +++ b/ui/helpers/higher-order-components/initialized/initialized.component.js @@ -16,6 +16,6 @@ export default function Initialized(props) { Initialized.propTypes = { completedOnboarding: PropTypes.bool, path: PropTypes.string, - component: PropTypes.object, + component: PropTypes.func, exact: PropTypes.bool, }; diff --git a/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.tsx b/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.tsx index 48a23e49748a..ab37ff7c8bc6 100644 --- a/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.tsx +++ b/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.tsx @@ -15,7 +15,7 @@ export type RouterHooksProps = { function withRouterHooks( WrappedComponent: React.ComponentType, ): React.ComponentType { - const ComponentWithRouterHooks = (props: Props) => { + const useComponentWithRouterHooks = (props: Props) => { const navigate = useNavigate(); const location = useLocation(); const params = useParams(); @@ -31,11 +31,11 @@ function withRouterHooks( }; // Preserve component name for debugging - ComponentWithRouterHooks.displayName = `withRouterHooks(${ + useComponentWithRouterHooks.displayName = `withRouterHooks(${ WrappedComponent.displayName || WrappedComponent.name || 'Component' })`; - return ComponentWithRouterHooks; + return useComponentWithRouterHooks; } export default withRouterHooks; diff --git a/ui/hooks/gator-permissions/useGatorPermissions.ts b/ui/hooks/gator-permissions/useGatorPermissions.ts index 9714830c2648..1bd36df8c2a2 100644 --- a/ui/hooks/gator-permissions/useGatorPermissions.ts +++ b/ui/hooks/gator-permissions/useGatorPermissions.ts @@ -118,7 +118,6 @@ export function useGatorPermissions( }; // Note: cachedData is intentionally excluded from dependencies to prevent infinite loop // when fetchAndUpdateGatorPermissions updates the Redux store - // eslint-disable-next-line react-hooks/exhaustive-deps }, [dispatch, refreshInBackground]); return { diff --git a/ui/hooks/useCurrencyRatePolling.ts b/ui/hooks/useCurrencyRatePolling.ts index 124f68429d08..ed0aa6428124 100644 --- a/ui/hooks/useCurrencyRatePolling.ts +++ b/ui/hooks/useCurrencyRatePolling.ts @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux'; import { getChainIdsToPoll, getUseCurrencyRateCheck, - useSafeChainsListValidationSelector, + getUseSafeChainsListValidation, } from '../selectors'; import { getEnabledChainIds } from '../selectors/multichain/networks'; import { @@ -30,7 +30,7 @@ const usePollingEnabled = () => { const useNativeCurrencies = (isPollingEnabled: boolean) => { const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); const useSafeChainsListValidation = useSelector( - useSafeChainsListValidationSelector, + getUseSafeChainsListValidation, ); const [nativeCurrencies, setNativeCurrencies] = useState([]); const chainIds = useSelector(getChainIdsToPoll); diff --git a/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts b/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts index 0d5f0102bd02..5d12650cc08e 100644 --- a/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts +++ b/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts @@ -8,8 +8,8 @@ import { useIsOriginalNativeTokenSymbol } from './useIsOriginalNativeTokenSymbol const arrangeMocks = () => { // Mock Selectors - const mockUseSafeChainsListValidationSelector = jest - .spyOn(SelectorsModule, 'useSafeChainsListValidationSelector') + const mockGetUseSafeChainsListValidation = jest + .spyOn(SelectorsModule, 'getUseSafeChainsListValidation') .mockReturnValue(true); const createMockProviderConfig = () => @@ -26,7 +26,7 @@ const arrangeMocks = () => { .mockResolvedValue(true); return { - mockUseSafeChainsListValidationSelector, + mockGetUseSafeChainsListValidation, createMockProviderConfig, mockGetMultichainCurrentNetwork, mockIsOriginalNativeTokenSymbol, diff --git a/ui/hooks/useIsOriginalNativeTokenSymbol.ts b/ui/hooks/useIsOriginalNativeTokenSymbol.ts index 747b26757f6f..3a85c209f914 100644 --- a/ui/hooks/useIsOriginalNativeTokenSymbol.ts +++ b/ui/hooks/useIsOriginalNativeTokenSymbol.ts @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; import { CaipChainId, Hex } from '@metamask/utils'; -import { useSafeChainsListValidationSelector } from '../selectors'; +import { getUseSafeChainsListValidation } from '../selectors'; import { getMultichainCurrentNetwork } from '../selectors/multichain'; import { isEvmChainId } from '../../shared/lib/asset-utils'; @@ -18,7 +18,7 @@ export function useIsOriginalNativeTokenSymbol( ) { const [isOriginalNativeSymbol, setIsOriginalNativeSymbol] = useState(false); const useSafeChainsListValidation = useSelector( - useSafeChainsListValidationSelector, + getUseSafeChainsListValidation, ); const isEvm = isEvmChainId(chainId); diff --git a/ui/hooks/useIsOriginalTokenSymbol.js b/ui/hooks/useIsOriginalTokenSymbol.js index 8b12c118bf95..e88b70b4268b 100644 --- a/ui/hooks/useIsOriginalTokenSymbol.js +++ b/ui/hooks/useIsOriginalTokenSymbol.js @@ -38,7 +38,6 @@ export function useIsOriginalTokenSymbol(tokenAddress, tokenSymbol) { getTokenSymbolForToken(tokenAddress); // no need to wait for tokens to load, since we'd fetch without them if they aren't available - // eslint-disable-next-line react-hooks/exhaustive-deps }, [tokenAddress, tokenSymbol]); return isOriginalNativeSymbol; diff --git a/ui/hooks/useName.test.ts b/ui/hooks/useName.test.ts index 5d9f7aca716b..4a8e98e660e7 100644 --- a/ui/hooks/useName.test.ts +++ b/ui/hooks/useName.test.ts @@ -1,3 +1,4 @@ +import { renderHook } from '@testing-library/react-hooks'; import { FALLBACK_VARIATION, NameControllerState, @@ -47,13 +48,15 @@ describe('useName', () => { it('returns default values if no state', () => { getNamesMock.mockReturnValue({} as NameControllerState['names']); - const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_MOCK); + renderHook(() => { + const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_MOCK); - expect(nameEntry).toStrictEqual({ - name: null, - sourceId: null, - origin: null, - proposedNames: {}, + expect(nameEntry).toStrictEqual({ + name: null, + sourceId: null, + origin: null, + proposedNames: {}, + }); }); }); @@ -71,13 +74,15 @@ describe('useName', () => { }, }); - const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_MOCK); + renderHook(() => { + const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_MOCK); - expect(nameEntry).toStrictEqual({ - name: null, - sourceId: null, - origin: null, - proposedNames: {}, + expect(nameEntry).toStrictEqual({ + name: null, + sourceId: null, + origin: null, + proposedNames: {}, + }); }); }); @@ -95,13 +100,15 @@ describe('useName', () => { }, }); - const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_MOCK); + renderHook(() => { + const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_MOCK); - expect(nameEntry).toStrictEqual({ - name: NAME_MOCK, - sourceId: SOURCE_ID_MOCK, - proposedNames: PROPOSED_NAMES_MOCK, - origin: ORIGIN_MOCK, + expect(nameEntry).toStrictEqual({ + name: NAME_MOCK, + sourceId: SOURCE_ID_MOCK, + proposedNames: PROPOSED_NAMES_MOCK, + origin: ORIGIN_MOCK, + }); }); }); @@ -119,13 +126,15 @@ describe('useName', () => { }, }); - const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_2_MOCK); + renderHook(() => { + const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_2_MOCK); - expect(nameEntry).toStrictEqual({ - name: NAME_MOCK, - sourceId: SOURCE_ID_MOCK, - proposedNames: PROPOSED_NAMES_MOCK, - origin: ORIGIN_MOCK, + expect(nameEntry).toStrictEqual({ + name: NAME_MOCK, + sourceId: SOURCE_ID_MOCK, + proposedNames: PROPOSED_NAMES_MOCK, + origin: ORIGIN_MOCK, + }); }); }); @@ -144,13 +153,15 @@ describe('useName', () => { }, }); - const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_2_MOCK); + renderHook(() => { + const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_2_MOCK); - expect(nameEntry).toStrictEqual({ - name: NAME_MOCK, - sourceId: SOURCE_ID_MOCK, - proposedNames: PROPOSED_NAMES_MOCK, - origin: ORIGIN_MOCK, + expect(nameEntry).toStrictEqual({ + name: NAME_MOCK, + sourceId: SOURCE_ID_MOCK, + proposedNames: PROPOSED_NAMES_MOCK, + origin: ORIGIN_MOCK, + }); }); }); @@ -174,13 +185,15 @@ describe('useName', () => { }, }); - const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_2_MOCK); + renderHook(() => { + const nameEntry = useName(VALUE_MOCK, TYPE_MOCK, VARIATION_2_MOCK); - expect(nameEntry).toStrictEqual({ - name: NAME_MOCK, - proposedNames: {}, - sourceId: SOURCE_ID_MOCK, - origin: ORIGIN_MOCK, + expect(nameEntry).toStrictEqual({ + name: NAME_MOCK, + proposedNames: {}, + sourceId: SOURCE_ID_MOCK, + origin: ORIGIN_MOCK, + }); }); }); }); @@ -199,13 +212,15 @@ describe('useName', () => { }, }); - const nameEntry = useName('0xAbC123', TYPE_MOCK, VARIATION_MOCK); + renderHook(() => { + const nameEntry = useName('0xAbC123', TYPE_MOCK, VARIATION_MOCK); - expect(nameEntry).toStrictEqual({ - name: NAME_MOCK, - sourceId: SOURCE_ID_MOCK, - proposedNames: PROPOSED_NAMES_MOCK, - origin: ORIGIN_MOCK, + expect(nameEntry).toStrictEqual({ + name: NAME_MOCK, + sourceId: SOURCE_ID_MOCK, + proposedNames: PROPOSED_NAMES_MOCK, + origin: ORIGIN_MOCK, + }); }); }); }); diff --git a/ui/hooks/useOriginTrustSignals.test.ts b/ui/hooks/useOriginTrustSignals.test.ts index 953d74da73e6..a59068582024 100644 --- a/ui/hooks/useOriginTrustSignals.test.ts +++ b/ui/hooks/useOriginTrustSignals.test.ts @@ -1,3 +1,4 @@ +import { renderHook } from '@testing-library/react-hooks'; import { RecommendedAction } from '@metamask/phishing-controller'; import { getUrlScanCacheResult } from '../selectors/selectors'; import { TrustSignalDisplayState } from './useTrustSignals'; @@ -29,16 +30,18 @@ describe('useOriginTrustSignals', () => { it('returns unknown state when selector returns undefined', () => { getUrlScanCacheResultMock.mockReturnValue(undefined); - const result = useOriginTrustSignals(''); - - expect(result).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: null, + renderHook(() => { + const result = useOriginTrustSignals(''); + + expect(result).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: null, + }); + expect(getUrlScanCacheResultMock).toHaveBeenCalledWith( + undefined, + undefined, + ); }); - expect(getUrlScanCacheResultMock).toHaveBeenCalledWith( - undefined, - undefined, - ); }); it('returns malicious state when recommendedAction is Block', () => { @@ -50,16 +53,18 @@ describe('useOriginTrustSignals', () => { timestamp: TIMESTAMP_MOCK, }); - const result = useOriginTrustSignals(ORIGIN_MOCK); - - expect(result).toStrictEqual({ - state: TrustSignalDisplayState.Malicious, - label: null, + renderHook(() => { + const result = useOriginTrustSignals(ORIGIN_MOCK); + + expect(result).toStrictEqual({ + state: TrustSignalDisplayState.Malicious, + label: null, + }); + expect(getUrlScanCacheResultMock).toHaveBeenCalledWith( + undefined, + DOMAIN_NAME_MOCK, + ); }); - expect(getUrlScanCacheResultMock).toHaveBeenCalledWith( - undefined, - DOMAIN_NAME_MOCK, - ); }); it('returns warning state when recommendedAction is Warn', () => { @@ -71,11 +76,13 @@ describe('useOriginTrustSignals', () => { timestamp: TIMESTAMP_MOCK, }); - const result = useOriginTrustSignals(ORIGIN_MOCK); + renderHook(() => { + const result = useOriginTrustSignals(ORIGIN_MOCK); - expect(result).toStrictEqual({ - state: TrustSignalDisplayState.Warning, - label: null, + expect(result).toStrictEqual({ + state: TrustSignalDisplayState.Warning, + label: null, + }); }); }); @@ -88,11 +95,13 @@ describe('useOriginTrustSignals', () => { timestamp: TIMESTAMP_MOCK, }); - const result = useOriginTrustSignals(ORIGIN_MOCK); + renderHook(() => { + const result = useOriginTrustSignals(ORIGIN_MOCK); - expect(result).toStrictEqual({ - state: TrustSignalDisplayState.Verified, - label: null, + expect(result).toStrictEqual({ + state: TrustSignalDisplayState.Verified, + label: null, + }); }); }); @@ -105,11 +114,13 @@ describe('useOriginTrustSignals', () => { timestamp: TIMESTAMP_MOCK, }); - const result = useOriginTrustSignals(ORIGIN_MOCK); + renderHook(() => { + const result = useOriginTrustSignals(ORIGIN_MOCK); - expect(result).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: null, + expect(result).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: null, + }); }); }); @@ -122,11 +133,13 @@ describe('useOriginTrustSignals', () => { timestamp: TIMESTAMP_MOCK, }); - const result = useOriginTrustSignals(ORIGIN_MOCK); + renderHook(() => { + const result = useOriginTrustSignals(ORIGIN_MOCK); - expect(result).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: null, + expect(result).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: null, + }); }); }); @@ -139,26 +152,30 @@ describe('useOriginTrustSignals', () => { timestamp: TIMESTAMP_MOCK, }); - const result = useOriginTrustSignals(ORIGIN_MOCK); + renderHook(() => { + const result = useOriginTrustSignals(ORIGIN_MOCK); - expect(result).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: null, + expect(result).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: null, + }); }); }); it('returns unknown state when origin is invalid URL', () => { getUrlScanCacheResultMock.mockReturnValue(undefined); - const result = useOriginTrustSignals('not-a-valid-url'); - - expect(result).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: null, + renderHook(() => { + const result = useOriginTrustSignals('not-a-valid-url'); + + expect(result).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: null, + }); + expect(getUrlScanCacheResultMock).toHaveBeenCalledWith( + undefined, + undefined, + ); }); - expect(getUrlScanCacheResultMock).toHaveBeenCalledWith( - undefined, - undefined, - ); }); }); diff --git a/ui/hooks/useTrustSignals.test.ts b/ui/hooks/useTrustSignals.test.ts index 82ecc0cab24a..ab9fec28c50a 100644 --- a/ui/hooks/useTrustSignals.test.ts +++ b/ui/hooks/useTrustSignals.test.ts @@ -1,3 +1,4 @@ +import { renderHook } from '@testing-library/react-hooks'; import { NameType } from '@metamask/name-controller'; import { getAddressSecurityAlertResponse } from '../selectors'; import { @@ -60,15 +61,17 @@ describe('useTrustSignals', () => { label: TRUST_LABEL_MOCK, }); - const result = useTrustSignal( - VALUE_MOCK, - NameType.ETHEREUM_ADDRESS, - '0x1', - ); + renderHook(() => { + const result = useTrustSignal( + VALUE_MOCK, + NameType.ETHEREUM_ADDRESS, + '0x1', + ); - expect(result).toStrictEqual({ - state: TrustSignalDisplayState.Malicious, - label: TRUST_LABEL_MOCK, + expect(result).toStrictEqual({ + state: TrustSignalDisplayState.Malicious, + label: TRUST_LABEL_MOCK, + }); }); }); }); @@ -91,18 +94,20 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Malicious, - label: TRUST_LABEL_MOCK, - }); + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Malicious, + label: TRUST_LABEL_MOCK, + }); - expect(getAddressSecurityAlertResponseMock).toHaveBeenCalledWith( - undefined, - `ethereum:${VALUE_MOCK.toLowerCase()}`, - ); + expect(getAddressSecurityAlertResponseMock).toHaveBeenCalledWith( + undefined, + `ethereum:${VALUE_MOCK.toLowerCase()}`, + ); + }); }); it('returns unknown state when no chain id is provided', () => { @@ -121,12 +126,14 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: null, + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: null, + }); }); }); @@ -146,12 +153,14 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Warning, - label: WARNING_LABEL_MOCK, + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Warning, + label: WARNING_LABEL_MOCK, + }); }); }); @@ -171,12 +180,14 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Verified, - label: VERIFIED_LABEL_MOCK, + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Verified, + label: VERIFIED_LABEL_MOCK, + }); }); }); @@ -196,12 +207,14 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: 'Benign Address', + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: 'Benign Address', + }); }); }); @@ -221,12 +234,14 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: 'Error occurred', + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: 'Error occurred', + }); }); }); @@ -243,12 +258,14 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: 'Some label', + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: 'Some label', + }); }); }); @@ -267,12 +284,14 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Verified, - label: null, + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Verified, + label: null, + }); }); }); }); @@ -289,12 +308,14 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: null, + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: null, + }); }); }); @@ -309,12 +330,14 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Unknown, - label: null, + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Unknown, + label: null, + }); }); }); @@ -334,12 +357,14 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(1); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Loading, - label: null, + expect(results).toHaveLength(1); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Loading, + label: null, + }); }); }); }); @@ -373,36 +398,40 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(2); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Malicious, - label: TRUST_LABEL_MOCK, - }); - expect(results[1]).toStrictEqual({ - state: TrustSignalDisplayState.Verified, - label: VERIFIED_LABEL_MOCK, - }); + expect(results).toHaveLength(2); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Malicious, + label: TRUST_LABEL_MOCK, + }); + expect(results[1]).toStrictEqual({ + state: TrustSignalDisplayState.Verified, + label: VERIFIED_LABEL_MOCK, + }); - expect(getAddressSecurityAlertResponseMock).toHaveBeenCalledTimes(2); - expect(getAddressSecurityAlertResponseMock).toHaveBeenNthCalledWith( - 1, - undefined, - `ethereum:${VALUE_MOCK.toLowerCase()}`, - ); - expect(getAddressSecurityAlertResponseMock).toHaveBeenNthCalledWith( - 2, - undefined, - `ethereum:${VALUE_MOCK_2.toLowerCase()}`, - ); + expect(getAddressSecurityAlertResponseMock).toHaveBeenCalledTimes(2); + expect(getAddressSecurityAlertResponseMock).toHaveBeenNthCalledWith( + 1, + undefined, + `ethereum:${VALUE_MOCK.toLowerCase()}`, + ); + expect(getAddressSecurityAlertResponseMock).toHaveBeenNthCalledWith( + 2, + undefined, + `ethereum:${VALUE_MOCK_2.toLowerCase()}`, + ); + }); }); it('handles empty requests array', () => { - const results = useTrustSignals([]); + renderHook(() => { + const results = useTrustSignals([]); - expect(results).toHaveLength(0); - expect(getAddressSecurityAlertResponseMock).not.toHaveBeenCalled(); + expect(results).toHaveLength(0); + expect(getAddressSecurityAlertResponseMock).not.toHaveBeenCalled(); + }); }); }); @@ -428,16 +457,18 @@ describe('useTrustSignals', () => { }, ]; - const results = useTrustSignals(requests); + renderHook(() => { + const results = useTrustSignals(requests); - expect(results).toHaveLength(2); - expect(results[0]).toStrictEqual({ - state: TrustSignalDisplayState.Malicious, - label: TRUST_LABEL_MOCK, - }); - expect(results[1]).toStrictEqual({ - state: TrustSignalDisplayState.Malicious, - label: TRUST_LABEL_MOCK, + expect(results).toHaveLength(2); + expect(results[0]).toStrictEqual({ + state: TrustSignalDisplayState.Malicious, + label: TRUST_LABEL_MOCK, + }); + expect(results[1]).toStrictEqual({ + state: TrustSignalDisplayState.Malicious, + label: TRUST_LABEL_MOCK, + }); }); }); }); diff --git a/ui/pages/bridge/awaiting-signatures/awaiting-signatures.tsx b/ui/pages/bridge/awaiting-signatures/awaiting-signatures.tsx index f968fb202b57..e6ef84a46274 100644 --- a/ui/pages/bridge/awaiting-signatures/awaiting-signatures.tsx +++ b/ui/pages/bridge/awaiting-signatures/awaiting-signatures.tsx @@ -79,7 +79,6 @@ export default function AwaitingSignatures() { token_to_amount: activeQuote?.quote?.destTokenAmount ?? '', }, }); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const isSwap = diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.tsx index eaafc9afe075..c8a63f16d192 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.tsx @@ -419,16 +419,20 @@ const PrepareBridgePage = ({ ], ); - const debouncedUpdateQuoteRequestInController = useCallback( + // `useRef` is used here to manually memoize a function reference. + // `useCallback` and React Compiler don't understand that `debounce` returns an inline function reference. + // The function contains reactive dependencies, but they are `dispatch` and an action, + // making it safe not to worry about recreating this function on dependency updates. + const debouncedUpdateQuoteRequestInController = useRef( debounce((...args: Parameters) => { dispatch(updateQuoteRequestParams(...args)); }, 300), - [dispatch], ); useEffect(() => { return () => { - debouncedUpdateQuoteRequestInController.cancel(); + // This `ref` is safe from unintended mutations, because it points to a function reference, not any reactive node or element. + debouncedUpdateQuoteRequestInController.current.cancel(); }; }, []); @@ -453,8 +457,10 @@ const PrepareBridgePage = ({ Boolean, ) as string[], }; - debouncedUpdateQuoteRequestInController(quoteParams, eventProperties); - // eslint-disable-next-line react-hooks/exhaustive-deps + debouncedUpdateQuoteRequestInController.current( + quoteParams, + eventProperties, + ); }, [quoteParams]); // Use smart slippage defaults @@ -799,7 +805,7 @@ const PrepareBridgePage = ({ if (!quoteParams) { return; } - debouncedUpdateQuoteRequestInController(quoteParams, { + debouncedUpdateQuoteRequestInController.current(quoteParams, { // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 // eslint-disable-next-line @typescript-eslint/naming-convention stx_enabled: smartTransactionsEnabled, diff --git a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js index 581961844b2a..3183867afe54 100644 --- a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js +++ b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js @@ -179,7 +179,6 @@ const ConfirmAddSuggestedToken = () => { useEffect(() => { goBackIfNoSuggestedTokensOnFirstRender(); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts b/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts index d824638c021d..53f4eec35d75 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts @@ -7,7 +7,7 @@ import { decodeTransactionData } from '../../../../../../store/actions'; import { DecodedTransactionDataResponse } from '../../../../../../../shared/types/transaction-decode'; import { useConfirmContext } from '../../../../context/confirm'; import { hasTransactionData } from '../../../../../../../shared/modules/transaction.utils'; -import { use4ByteResolutionSelector } from '../../../../../../selectors'; +import { getUse4ByteResolution } from '../../../../../../selectors'; export function useDecodedTransactionData({ data, @@ -19,7 +19,7 @@ export function useDecodedTransactionData({ transactionTypeFilter?: string; } = {}): AsyncResult { const { currentConfirmation } = useConfirmContext(); - const isDecodeEnabled = useSelector(use4ByteResolutionSelector); + const isDecodeEnabled = useSelector(getUse4ByteResolution); const currentTransactionType = currentConfirmation?.type; const chainId = currentConfirmation?.chainId as Hex; diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts index 32f4a778f94d..a637460f5f50 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts @@ -3,14 +3,14 @@ import { useEffect } from 'react'; import { Hex } from '@metamask/utils'; import { getKnownMethodData, - use4ByteResolutionSelector, + getUse4ByteResolution, } from '../../../../../../selectors'; import { getContractMethodData } from '../../../../../../store/actions'; import { hasTransactionData } from '../../../../../../../shared/modules/transaction.utils'; export const useFourByte = ({ to, data }: { to?: Hex; data?: Hex }) => { const dispatch = useDispatch(); - const isFourByteEnabled = useSelector(use4ByteResolutionSelector); + const isFourByteEnabled = useSelector(getUse4ByteResolution); const transactionTo = to as Hex | undefined; const transactionData = data as Hex | undefined; diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.ts b/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.ts index f04a5ca70b52..940b9936f896 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.ts @@ -15,7 +15,7 @@ export function useNestedTransactionLabels({ const { data, to } = nestedTransaction; // It's safe to call useFourByte here because the length of nestedTransactions // remains stable throughout the component's lifecycle. - // eslint-disable-next-line react-hooks/rules-of-hooks + // eslint-disable-next-line react-compiler/react-compiler, react-hooks/rules-of-hooks const methodData = useFourByte({ data, to }); const functionName = methodData?.name; diff --git a/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.js b/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.js index 0edd91ad42e0..a80bd4b6a159 100644 --- a/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.js +++ b/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.js @@ -29,7 +29,6 @@ export default function SimulationErrorMessage({ ], }, }); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return userAcknowledgedGasMissing === true ? ( diff --git a/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js b/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js index aee6c3c6fddd..8d8874851bcd 100644 --- a/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js +++ b/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js @@ -26,7 +26,7 @@ import { usePrevious } from '../../../hooks/usePrevious'; import { unconfirmedTransactionsHashSelector, unconfirmedTransactionsListSelector, - use4ByteResolutionSelector, + getUse4ByteResolution, } from '../../../selectors'; import { endBackgroundTrace, @@ -71,7 +71,7 @@ const ConfirmTransaction = () => { unconfirmedTxsSorted, ]); const [transaction, setTransaction] = useState(getTransaction); - const use4ByteResolution = useSelector(use4ByteResolutionSelector); + const use4ByteResolution = useSelector(getUse4ByteResolution); const { currentConfirmation } = useCurrentConfirmation(); useEffect(() => { @@ -137,8 +137,6 @@ const ConfirmTransaction = () => { dispatch(setTransactionToConfirm(txId)); } } - - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { diff --git a/ui/pages/confirmations/confirmation/confirmation.js b/ui/pages/confirmations/confirmation/confirmation.js index 49fd9c0d7bac..d69f92668e98 100644 --- a/ui/pages/confirmations/confirmation/confirmation.js +++ b/ui/pages/confirmations/confirmation/confirmation.js @@ -34,7 +34,7 @@ import { getUnapprovedTxCount, getApprovalFlows, getTotalUnapprovedCount, - useSafeChainsListValidationSelector, + getUseSafeChainsListValidation, getSnapsMetadata, getHideSnapBranding, } from '../../../selectors'; @@ -237,7 +237,7 @@ export default function ConfirmationPage({ const approvalFlows = useSelector(getApprovalFlows, isEqual); const totalUnapprovedCount = useSelector(getTotalUnapprovedCount); const useSafeChainsListValidation = useSelector( - useSafeChainsListValidationSelector, + getUseSafeChainsListValidation, ); const networkConfigurationsByChainId = useSelector( getNetworkConfigurationsByChainId, diff --git a/ui/pages/notifications/notification-components/snap/snap-footer-button.tsx b/ui/pages/notifications/notification-components/snap/snap-footer-button.tsx index f8239d29529a..4cde9e0dc677 100644 --- a/ui/pages/notifications/notification-components/snap/snap-footer-button.tsx +++ b/ui/pages/notifications/notification-components/snap/snap-footer-button.tsx @@ -44,8 +44,8 @@ export const SnapFooterButton = (props: { notification: SnapNotification }) => { if (isExternal) { setIsOpen(true); } else { - // This hook is safe to include in this event handler, because its only reactive component is `useNavigate` - // eslint-disable-next-line react-hooks/rules-of-hooks + // This hook is safe to call in this event handler, because its only reactive component is `useNavigate` + // eslint-disable-next-line react-compiler/react-compiler, react-hooks/rules-of-hooks useSnapNavigate(href); } }, diff --git a/ui/pages/settings/networks-tab/networks-form/use-safe-chains.ts b/ui/pages/settings/networks-tab/networks-form/use-safe-chains.ts index af7c1d40c4ec..f78fc96c7c29 100644 --- a/ui/pages/settings/networks-tab/networks-form/use-safe-chains.ts +++ b/ui/pages/settings/networks-tab/networks-form/use-safe-chains.ts @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; import { isStrictHexString } from '@metamask/utils'; -import { useSafeChainsListValidationSelector } from '../../../../selectors'; +import { getUseSafeChainsListValidation } from '../../../../selectors'; import fetchWithCache from '../../../../../shared/lib/fetch-with-cache'; import { CHAIN_SPEC_URL } from '../../../../../shared/constants/network'; import { DAY } from '../../../../../shared/constants/time'; @@ -17,7 +17,7 @@ export type SafeChain = { export const useSafeChains = () => { const useSafeChainsListValidation = useSelector( - useSafeChainsListValidationSelector, + getUseSafeChainsListValidation, ); const [safeChains, setSafeChains] = useState<{ diff --git a/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js b/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js index a96da8baeba2..0de989898955 100644 --- a/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js +++ b/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js @@ -71,7 +71,6 @@ export default function AwaitingSignatures() { stx_user_opt_in: smartTransactionsOptInStatus, }, }); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const headerText = needsTwoConfirmations diff --git a/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js b/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js index 1e387af5314f..1de8c7196785 100644 --- a/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js +++ b/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js @@ -560,7 +560,6 @@ export default function PrepareSwapPage({ if (!fromToken?.symbol && !fetchParamsFromToken?.symbol) { dispatch(setSwapsFromToken(defaultSwapsToken)); } - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { @@ -766,7 +765,6 @@ export default function PrepareSwapPage({ if (fromToken?.address && !selectedToToken?.address && defaultToToken) { dispatch(setSwapToToken(defaultToToken)); } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [fromToken?.address]); const onOpenImportTokenModalClick = (item) => { diff --git a/ui/pages/swaps/prepare-swap-page/review-quote.js b/ui/pages/swaps/prepare-swap-page/review-quote.js index eaea99f25a32..3eaf2eab9ef2 100644 --- a/ui/pages/swaps/prepare-swap-page/review-quote.js +++ b/ui/pages/swaps/prepare-swap-page/review-quote.js @@ -44,7 +44,7 @@ import { fetchSwapsSmartTransactionFees, getSmartTransactionFees, getCurrentSmartTransactionsEnabled, - getIsEstimatedReturnLow, + useGetIsEstimatedReturnLow, } from '../../../ducks/swaps/swaps'; import { getCurrentChainId } from '../../../../shared/modules/selectors/networks'; import { @@ -1133,7 +1133,7 @@ export default function ReviewQuote({ currentCurrency, ]); - const isEstimatedReturnLow = getIsEstimatedReturnLow({ + const isEstimatedReturnLow = useGetIsEstimatedReturnLow({ usedQuote, rawNetworkFees, }); diff --git a/ui/selectors/confirm-transaction.js b/ui/selectors/confirm-transaction.js index 5f0f891fb15d..72e240ca15d2 100644 --- a/ui/selectors/confirm-transaction.js +++ b/ui/selectors/confirm-transaction.js @@ -104,7 +104,7 @@ export const unconfirmedMessagesHashSelector = createSelector( }; }, ); -export const use4ByteResolutionSelector = (state) => +export const getUse4ByteResolution = (state) => state.metamask.use4ByteResolution; export const currentCurrencySelector = (state) => state.metamask.currentCurrency; diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 7721c6be03d4..e23e5695cf8c 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -3491,7 +3491,7 @@ export const getUpdatedAndSortedAccountsWithCaipAccountId = }); }); -export const useSafeChainsListValidationSelector = (state) => { +export const getUseSafeChainsListValidation = (state) => { return state.metamask.useSafeChainsListValidation; }; diff --git a/ui/store/background-connection.ts b/ui/store/background-connection.ts index 06565769c141..74297b18c6df 100644 --- a/ui/store/background-connection.ts +++ b/ui/store/background-connection.ts @@ -30,7 +30,7 @@ export function submitRequestToBackground( // tests don't always set the `background` property for convenience, as // the return values for various RPC calls aren't always used. In production // builds, this will not happen, and even if it did MM wouldn't work. - if (!background) { + if (typeof background?.[method] !== 'function') { console.warn(NO_BACKGROUND_CONNECTION_MESSAGE); return Promise.resolve() as Promise; } From 3d6ddc143756dee07d0b3bb3692577af37f95384 Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Mon, 3 Nov 2025 14:43:42 -0500 Subject: [PATCH 10/68] Fix logical rule violations --- .../hooks/useProcessNewDecimalValue.tsx | 6 +- .../hooks/useTokenExchangeRate.tsx | 24 +++-- .../app/qr-hardware-popover/base-reader.js | 94 +++++++++---------- .../select-wrapper/select-wrapper.stories.tsx | 3 +- .../text-field/text-field.tsx | 2 + .../hooks/useAssetMetadata.ts | 10 +- .../deprecated-networks.js | 19 +++- .../preloader/preloader-icon.component.js | 1 + ui/contexts/metametrics.js | 1 + ui/hooks/useAsync.ts | 1 + ui/hooks/useModalProps.test.ts | 9 +- ui/hooks/useModalProps.ts | 13 ++- ui/hooks/useMultiPolling.ts | 30 ++++-- ui/hooks/usePolling.ts | 29 ++++-- ui/pages/asset/components/asset-page.tsx | 34 ++++--- ui/pages/asset/types/asset.ts | 31 +++++- .../confirm-decrypt-message.component.js | 4 +- .../stories/add-ethereum-chain.stories.js | 16 +++- .../hooks/useConfirmationAlertMetrics.ts | 59 +++++++----- .../hooks/useGetTokenStandardAndDetails.ts | 24 ++--- 20 files changed, 260 insertions(+), 150 deletions(-) diff --git a/ui/components/app/currency-input/hooks/useProcessNewDecimalValue.tsx b/ui/components/app/currency-input/hooks/useProcessNewDecimalValue.tsx index 88ee8b462312..1ead7d50902a 100644 --- a/ui/components/app/currency-input/hooks/useProcessNewDecimalValue.tsx +++ b/ui/components/app/currency-input/hooks/useProcessNewDecimalValue.tsx @@ -16,6 +16,9 @@ export default function useProcessNewDecimalValue( isTokenPrimary: boolean, tokenToFiatConversionRate: Numeric | undefined, ) { + const tokenToFiatConversionRateToString = + tokenToFiatConversionRate?.toString(); + return useCallback( (newDecimalValue: string, isTokenPrimaryOverride?: boolean) => { let newFiatDecimalValue, newTokenDecimalValue; @@ -55,6 +58,7 @@ export default function useProcessNewDecimalValue( return { newFiatDecimalValue, newTokenDecimalValue }; }, - [tokenToFiatConversionRate?.toString(), isTokenPrimary, assetDecimals], + // `tokenToFiatConversionRate` intentionally excluded to ensure that re-renders are only triggered when conversion rate value actually changes. + [tokenToFiatConversionRateToString, isTokenPrimary, assetDecimals], ); } diff --git a/ui/components/app/currency-input/hooks/useTokenExchangeRate.tsx b/ui/components/app/currency-input/hooks/useTokenExchangeRate.tsx index a4799d94ce88..3514bc868c09 100644 --- a/ui/components/app/currency-input/hooks/useTokenExchangeRate.tsx +++ b/ui/components/app/currency-input/hooks/useTokenExchangeRate.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from 'react'; +import { useMemo, useState, useEffect } from 'react'; import { toChecksumAddress } from 'ethereumjs-util'; import { shallowEqual, useSelector } from 'react-redux'; import { getCurrentChainId } from '../../../../../shared/modules/selectors/networks'; @@ -41,6 +41,19 @@ export default function useTokenExchangeRate( Record >({}); + const contractExchangeRate = tokenAddress + ? contractExchangeRates[tokenAddress] || exchangeRates[tokenAddress] + : undefined; + + useEffect(() => { + if (!contractExchangeRate && tokenAddress) { + setExchangeRates((prev) => ({ + ...prev, + [tokenAddress]: LOADING, + })); + } + }, [contractExchangeRate, tokenAddress]); + return useMemo(() => { if (!selectedNativeConversionRate) { return undefined; @@ -62,14 +75,7 @@ export default function useTokenExchangeRate( return undefined; } - const contractExchangeRate = - contractExchangeRates[tokenAddress] || exchangeRates[tokenAddress]; - if (!contractExchangeRate) { - setExchangeRates((prev) => ({ - ...prev, - [tokenAddress]: LOADING, - })); fetchTokenExchangeRates(nativeCurrency, [tokenAddress], chainId) .then((addressToExchangeRate) => { setExchangeRates((prev) => ({ @@ -95,6 +101,6 @@ export default function useTokenExchangeRate( nativeCurrency, tokenAddress, selectedNativeConversionRate, - contractExchangeRates, + contractExchangeRate, ]); } diff --git a/ui/components/app/qr-hardware-popover/base-reader.js b/ui/components/app/qr-hardware-popover/base-reader.js index 4c9ed983d900..569f230415b3 100644 --- a/ui/components/app/qr-hardware-popover/base-reader.js +++ b/ui/components/app/qr-hardware-popover/base-reader.js @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useRef, useState, useCallback } from 'react'; import log from 'loglevel'; import { URDecoder } from '@ngraveio/bc-ur'; import PropTypes from 'prop-types'; @@ -30,7 +30,7 @@ const BaseReader = ({ const [urDecoder, setURDecoder] = useState(new URDecoder()); const [progress, setProgress] = useState(0); - let permissionChecker = null; + const permissionCheckerRef = useRef(null); const mounted = useRef(false); const reset = () => { @@ -40,29 +40,7 @@ const BaseReader = ({ setProgress(0); }; - const checkEnvironment = async () => { - try { - const { environmentReady } = await WebcamUtils.checkStatus(); - if ( - !environmentReady && - getEnvironmentType() !== ENVIRONMENT_TYPE_FULLSCREEN - ) { - const currentUrl = new URL(window.location.href); - const currentHash = currentUrl.hash; - const currentRoute = currentHash ? currentHash.substring(1) : null; - global.platform.openExtensionInBrowser(currentRoute); - } - } catch (e) { - if (mounted.current) { - setError(e); - } - } - // initial attempt is required to trigger permission prompt - // eslint-disable-next-line no-use-before-define - return initCamera(); - }; - - const checkPermissions = async () => { + const checkPermissions = useCallback(async () => { try { const { permissions } = await WebcamUtils.checkStatus(); if (permissions) { @@ -74,7 +52,7 @@ const BaseReader = ({ setReady(READY_STATE.READY); } else if (mounted.current) { // Keep checking for permissions - permissionChecker = setTimeout(checkPermissions, SECOND); + permissionCheckerRef.current = setTimeout(checkPermissions, SECOND); setReady(READY_STATE.NEED_TO_ALLOW_ACCESS); } } catch (e) { @@ -82,7 +60,44 @@ const BaseReader = ({ setError(e); } } - }; + }, []); + + const initCamera = useCallback(() => { + try { + checkPermissions(); + } catch (e) { + if (!mounted.current) { + return; + } + if (e.name === 'NotAllowedError') { + log.info(`Permission denied: '${e}'`); + setReady(READY_STATE.NEED_TO_ALLOW_ACCESS); + } else { + setError(e); + } + } + }, [checkPermissions]); + + const checkEnvironment = useCallback(async () => { + try { + const { environmentReady } = await WebcamUtils.checkStatus(); + if ( + !environmentReady && + getEnvironmentType() !== ENVIRONMENT_TYPE_FULLSCREEN + ) { + const currentUrl = new URL(window.location.href); + const currentHash = currentUrl.hash; + const currentRoute = currentHash ? currentHash.substring(1) : null; + global.platform.openExtensionInBrowser(currentRoute); + } + } catch (e) { + if (mounted.current) { + setError(e); + } + } + // initial attempt is required to trigger permission prompt + return initCamera(); + }, [initCamera]); const handleScan = (data) => { try { @@ -105,30 +120,14 @@ const BaseReader = ({ } }; - const initCamera = () => { - try { - checkPermissions(); - } catch (e) { - if (!mounted.current) { - return; - } - if (e.name === 'NotAllowedError') { - log.info(`Permission denied: '${e}'`); - setReady(READY_STATE.NEED_TO_ALLOW_ACCESS); - } else { - setError(e); - } - } - }; - useEffect(() => { mounted.current = true; checkEnvironment(); return () => { mounted.current = false; - clearTimeout(permissionChecker); + clearTimeout(permissionCheckerRef.current); + permissionCheckerRef.current = null; }; - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { @@ -137,11 +136,10 @@ const BaseReader = ({ } else if (ready === READY_STATE.NEED_TO_ALLOW_ACCESS) { checkPermissions(); } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ready]); + }, [ready, checkPermissions, initCamera]); const tryAgain = () => { - clearTimeout(permissionChecker); + clearTimeout(permissionCheckerRef.current); reset(); checkEnvironment(); }; diff --git a/ui/components/component-library/select-wrapper/select-wrapper.stories.tsx b/ui/components/component-library/select-wrapper/select-wrapper.stories.tsx index 6e836d00a7f1..3df8a86f85cc 100644 --- a/ui/components/component-library/select-wrapper/select-wrapper.stories.tsx +++ b/ui/components/component-library/select-wrapper/select-wrapper.stories.tsx @@ -172,8 +172,9 @@ UncontrolledValue.args = { }; export const UseSelectContext: StoryFn = (args) => { - // Note that the SelectContext is being used inside a component, because the SelectContext needs to be called within the SelectWrapper component and not before const CustomClose = () => { + // Note that the SelectContext is being used inside a component, because the SelectContext needs to be called within the SelectWrapper component and not before + // eslint-disable-next-line react-compiler/react-compiler const { toggleUncontrolledOpen } = useSelectContext(); return ( diff --git a/ui/components/component-library/text-field/text-field.tsx b/ui/components/component-library/text-field/text-field.tsx index 79a1f8f810a5..b8116ed09218 100644 --- a/ui/components/component-library/text-field/text-field.tsx +++ b/ui/components/component-library/text-field/text-field.tsx @@ -93,6 +93,8 @@ export const TextField: TextFieldComponent = React.forwardRef( // Check if an external ref (inputRef) is provided and is a ref object if (inputRef && 'current' in inputRef) { // Assign the input element reference to the external ref + // TODO: Use `ref` prop instead. `forwardRef` is deprecated in React v19. + // eslint-disable-next-line react-compiler/react-compiler inputRef.current = inputElementRef; } // Check if an external ref (inputRef) is a callback function diff --git a/ui/components/multichain/asset-picker-amount/asset-picker-modal/hooks/useAssetMetadata.ts b/ui/components/multichain/asset-picker-amount/asset-picker-modal/hooks/useAssetMetadata.ts index 3a435ad67779..3ef58dfdd759 100644 --- a/ui/components/multichain/asset-picker-amount/asset-picker-modal/hooks/useAssetMetadata.ts +++ b/ui/components/multichain/asset-picker-amount/asset-picker-modal/hooks/useAssetMetadata.ts @@ -1,4 +1,5 @@ import { CaipAssetType, CaipChainId, Hex } from '@metamask/utils'; +import { useEffect } from 'react'; import { useSelector } from 'react-redux'; import { getUseExternalServices } from '../../../../../selectors'; import { @@ -25,6 +26,13 @@ export const useAssetMetadata = ( ) => { const allowExternalServices = useSelector(getUseExternalServices); + useEffect(() => { + return () => { + abortControllerRef.current?.abort(); + abortControllerRef.current = null; + }; + }, [abortControllerRef]); + const { value: assetMetadata } = useAsyncResult< | { address: Hex | CaipAssetType | string; @@ -49,7 +57,7 @@ export const useAssetMetadata = ( shouldFetchMetadata && trimmedSearchQuery.length > 30 ) { - abortControllerRef.current = new AbortController(); + abortControllerRef.current ??= new AbortController(); const metadata = await fetchAssetMetadata( trimmedSearchQuery, chainId, diff --git a/ui/components/ui/deprecated-networks/deprecated-networks.js b/ui/components/ui/deprecated-networks/deprecated-networks.js index 02ba7e674136..0ec74f8474bd 100644 --- a/ui/components/ui/deprecated-networks/deprecated-networks.js +++ b/ui/components/ui/deprecated-networks/deprecated-networks.js @@ -76,11 +76,20 @@ export default function DeprecatedNetworks() { setIsClosed(true); const networkConfiguration = networkConfigurations[chainId]; - networkConfiguration.rpcEndpoints[ - networkConfiguration.defaultRpcEndpointIndex - ].url = 'https://mainnet.aurora.dev'; - - await dispatch(updateNetwork(networkConfiguration)); + await dispatch( + updateNetwork({ + ...networkConfiguration, + rpcEndpoints: { + ...networkConfiguration.rpcEndpoints, + [networkConfiguration.defaultRpcEndpointIndex]: { + ...networkConfiguration.rpcEndpoints[ + networkConfiguration.defaultRpcEndpointIndex + ], + url: 'https://mainnet.aurora.dev', + }, + }, + }), + ); }, }; } diff --git a/ui/components/ui/icon/preloader/preloader-icon.component.js b/ui/components/ui/icon/preloader/preloader-icon.component.js index b478ee7dc7cd..df837abe40ed 100644 --- a/ui/components/ui/icon/preloader/preloader-icon.component.js +++ b/ui/components/ui/icon/preloader/preloader-icon.component.js @@ -19,6 +19,7 @@ const Preloader = ({ className, size }) => ( /> ( setResult(createErrorResult(error as Error)); } } + // eslint-disable-next-line react-compiler/react-compiler }, deps); return [execute, result]; diff --git a/ui/hooks/useModalProps.test.ts b/ui/hooks/useModalProps.test.ts index c507d6b7c100..99616bc0dd2a 100644 --- a/ui/hooks/useModalProps.test.ts +++ b/ui/hooks/useModalProps.test.ts @@ -1,3 +1,4 @@ +import { renderHook } from '@testing-library/react-hooks'; import { useModalProps } from './useModalProps'; const MOCK_PROPS = { @@ -26,9 +27,11 @@ jest.mock('../store/actions', () => ({ describe('useModalProps', () => { it('should return modal props and hideModal function', () => { - const { props, hideModal } = useModalProps(); + renderHook(() => { + const { props, hideModal } = useModalProps(); - expect(props).toStrictEqual(MOCK_PROPS); - expect(hideModal).toStrictEqual(expect.any(Function)); + expect(props).toStrictEqual(MOCK_PROPS); + expect(hideModal).toStrictEqual(expect.any(Function)); + }); }); }); diff --git a/ui/hooks/useModalProps.ts b/ui/hooks/useModalProps.ts index 03d85f41aeb7..780ff778517e 100644 --- a/ui/hooks/useModalProps.ts +++ b/ui/hooks/useModalProps.ts @@ -1,4 +1,6 @@ +import { useMemo, useCallback } from 'react'; import { useSelector, useDispatch } from 'react-redux'; +import type { MetaMaskReduxState } from '../store/store'; import { hideModal } from '../store/actions'; type ModalProps = { @@ -9,14 +11,15 @@ type ModalProps = { }; export function useModalProps(): ModalProps { - // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31973 - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const modalProps = useSelector((state: any) => { + const modalProps = useSelector((state: MetaMaskReduxState) => { return state.appState.modal.modalState?.props; }); const dispatch = useDispatch(); - const onHideModal = () => dispatch(hideModal()); + const onHideModal = useCallback(() => dispatch(hideModal()), [dispatch]); - return { props: modalProps, hideModal: onHideModal }; + return useMemo( + () => ({ props: modalProps, hideModal: onHideModal }), + [modalProps, onHideModal], + ); } diff --git a/ui/hooks/useMultiPolling.ts b/ui/hooks/useMultiPolling.ts index c28967ef2b51..34b84996e01f 100644 --- a/ui/hooks/useMultiPolling.ts +++ b/ui/hooks/useMultiPolling.ts @@ -17,9 +17,16 @@ const useMultiPolling = ( const completedOnboarding = useSelector(getCompletedOnboarding); const pollingTokens = useRef>(new Map()); + const prevPollingInputStringified = useRef(null); + const hasPollingInputChanged = + JSON.stringify(usePollingOptions.input) !== + prevPollingInputStringified.current; + + const isMounted = useRef(true); + useEffect(() => { - if (!completedOnboarding) { - // don't start polling if no selected account or onboarding is not completed yet + if (!completedOnboarding || !hasPollingInputChanged) { + // don't start polling if no selected account, or onboarding is incomplete, or polling inputs haven't changed return; } @@ -27,9 +34,11 @@ const useMultiPolling = ( for (const input of usePollingOptions.input) { const key = JSON.stringify(input); if (!pollingTokens.current.has(key)) { - usePollingOptions - .startPolling(input) - .then((token) => pollingTokens.current.set(key, token)); + usePollingOptions.startPolling(input).then((token) => { + if (isMounted.current) { + pollingTokens.current.set(key, token); + } + }); } } @@ -44,10 +53,11 @@ const useMultiPolling = ( pollingTokens.current.delete(inputKey); } } - }, [ - completedOnboarding, - usePollingOptions.input && JSON.stringify(usePollingOptions.input), - ]); + + prevPollingInputStringified.current = JSON.stringify( + usePollingOptions.input, + ); + }, [usePollingOptions, hasPollingInputChanged, completedOnboarding]); // stop all polling on dismount useEffect(() => { @@ -55,6 +65,8 @@ const useMultiPolling = ( for (const token of pollingTokens.current.values()) { usePollingOptions.stopPollingByPollingToken(token); } + prevPollingInputStringified.current = null; + isMounted.current = false; }; }, []); }; diff --git a/ui/hooks/usePolling.ts b/ui/hooks/usePolling.ts index 5bbd022effce..c0acfe0e06d0 100644 --- a/ui/hooks/usePolling.ts +++ b/ui/hooks/usePolling.ts @@ -13,16 +13,21 @@ const usePolling = ( ) => { const pollTokenRef = useRef(null); const cleanupRef = useRef void)>(null); - let isMounted = false; + + const prevPollingInputStringified = useRef(null); + const hasPollingInputChanged = + JSON.stringify(usePollingOptions.input) !== + prevPollingInputStringified.current; + + const isMounted = useRef(true); + useEffect(() => { - if (usePollingOptions.enabled === false) { + if (usePollingOptions.enabled === false || !hasPollingInputChanged) { return () => { // noop }; } - isMounted = true; - const cleanup = () => { if (pollTokenRef.current) { usePollingOptions.stopPollingByPollingToken(pollTokenRef.current); @@ -35,21 +40,25 @@ const usePolling = ( .startPolling(usePollingOptions.input) .then((pollToken) => { pollTokenRef.current = pollToken; - // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31880 - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - cleanupRef.current = usePollingOptions.callback?.(pollToken) || null; - if (!isMounted) { + cleanupRef.current = usePollingOptions.callback?.(pollToken) ?? null; + if (!isMounted.current) { cleanup(); } }); + prevPollingInputStringified.current = JSON.stringify( + usePollingOptions.input, + ); + // Return a cleanup function to stop polling when the component unmounts return () => { - isMounted = false; + isMounted.current = false; + prevPollingInputStringified.current = null; cleanup(); }; }, [ - usePollingOptions.input && JSON.stringify(usePollingOptions.input), + usePollingOptions.input, + hasPollingInputChanged, usePollingOptions.enabled, ]); }; diff --git a/ui/pages/asset/components/asset-page.tsx b/ui/pages/asset/components/asset-page.tsx index 5c8bba3a0c49..a73e8a53fbb6 100644 --- a/ui/pages/asset/components/asset-page.tsx +++ b/ui/pages/asset/components/asset-page.tsx @@ -78,7 +78,7 @@ import { import { getInternalAccountBySelectedAccountGroupAndCaip } from '../../../selectors/multichain-accounts/account-tree'; import { useSafeChains } from '../../settings/networks-tab/networks-form/use-safe-chains'; import { useCurrentPrice } from '../hooks/useCurrentPrice'; -import { Asset } from '../types/asset'; +import { isNativeAsset, type Asset } from '../types/asset'; import { AssetMarketDetails } from './asset-market-details'; import AssetChart from './chart/asset-chart'; import TokenButtons from './token-buttons'; @@ -159,7 +159,7 @@ const AssetPage = ({ return false; } }) ?? { - // TODO: remve the fallback case where the mutichainTokenWithFiatAmount is undefined + // TODO: remove the fallback case where the mutichainTokenWithFiatAmount is undefined // Root cause: There is a race condition where when switching from a non-EVM network // to an EVM network, the mutichainTokenWithFiatAmount is undefined // This is a workaround to avoid the error @@ -203,7 +203,7 @@ const AssetPage = ({ const { currentPrice } = useCurrentPrice(asset); - let balance, tokenFiatAmount, assetId; + let balance, tokenFiatAmount, assetId, updatedAsset; if (isMultichainAccountsState2Enabled) { const assetWithBalance = accountGroupIdAssets[chainId]?.find( (item) => @@ -218,10 +218,13 @@ const AssetPage = ({ tokenFiatAmount = assetWithBalance?.fiat?.balance ?? 0; const tokenHexBalance = assetWithBalance?.rawBalance as string; - asset.balance = { - value: hexToDecimal(tokenHexBalance), - display: balance, - fiat: String(tokenFiatAmount), + updatedAsset = { + ...asset, + balance: { + value: hexToDecimal(tokenHexBalance), + display: balance, + fiat: String(tokenFiatAmount), + }, }; } else { const tokenHexBalance = @@ -241,10 +244,13 @@ const AssetPage = ({ : 0; // this is needed in order to assign the correct balances to TokenButtons before navigating to send/swap screens - asset.balance = { - value: hexToDecimal(tokenHexBalance), - display: String(balance), - fiat: String(tokenFiatAmount), + updatedAsset = { + ...asset, + balance: { + value: hexToDecimal(tokenHexBalance), + display: String(balance), + fiat: String(tokenFiatAmount), + }, }; } @@ -355,7 +361,7 @@ const AssetPage = ({ asset={tokenWithFiatAmount as TokenFiatDisplayInfo} /> - {type === AssetType.native ? ( + {isNativeAsset(updatedAsset) ? ( ) : ( - + )} )} - + & { + type: typeof AssetType.native; + isOriginalNativeSymbol: boolean; +}; + +export type TokenAsset = Omit & { + type: typeof AssetType.token; + address: string; + aggregators?: string[]; +}; + +export const isNativeAsset = (inputAsset: Asset): inputAsset is NativeAsset => + inputAsset.type === AssetType.native && + 'isOriginalNativeSymbol' in inputAsset && + typeof inputAsset.isOriginalNativeSymbol === 'boolean'; + +export const isTokenAsset = (inputAsset: Asset): inputAsset is TokenAsset => + inputAsset.type === AssetType.token && + 'address' in inputAsset && + typeof inputAsset.address === 'string' && + ('aggregators' in inputAsset + ? typeof inputAsset.aggregators === 'object' && + (!inputAsset.aggregators.length || + typeof inputAsset.aggregators[0] === 'string') + : true); diff --git a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js index d286b4cad6d1..1c5965aa2b70 100644 --- a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js +++ b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js @@ -212,7 +212,7 @@ const MessageBody = forwardRef( const onDecryptMessage = async (event) => { event.stopPropagation(event); - const params = messageData.msgParams; + const params = { ...messageData.msgParams }; params.metamaskId = messageData.id; const result = await dispatch(decryptMsgInline(params)); @@ -349,7 +349,7 @@ const Footer = ({ const onSubmitClick = async (event) => { event.stopPropagation(event); - const params = messageData.msgParams; + const params = { ...messageData.msgParams }; params.metamaskId = messageData.id; await dispatch(decryptMsg(params)); diff --git a/ui/pages/confirmations/confirmation/stories/add-ethereum-chain.stories.js b/ui/pages/confirmations/confirmation/stories/add-ethereum-chain.stories.js index 7675396ad7a2..e31b71adb5ad 100644 --- a/ui/pages/confirmations/confirmation/stories/add-ethereum-chain.stories.js +++ b/ui/pages/confirmations/confirmation/stories/add-ethereum-chain.stories.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { ApprovalType } from '@metamask/controller-utils'; import ConfirmationPage from '../confirmation'; import { PendingApproval } from './util'; @@ -51,14 +51,20 @@ export default { export const DefaultStory = (args) => { const { blockExplorerUrl, ...finalArgs } = args; - finalArgs.rpcPrefs = { - blockExplorerUrl, - }; + const requestData = useMemo( + () => ({ + ...finalArgs, + rpcPrefs: { + blockExplorerUrl, + }, + }), + [finalArgs, blockExplorerUrl], + ); return ( diff --git a/ui/pages/confirmations/hooks/useConfirmationAlertMetrics.ts b/ui/pages/confirmations/hooks/useConfirmationAlertMetrics.ts index 84bd123e4bee..eb5c0b905dc5 100644 --- a/ui/pages/confirmations/hooks/useConfirmationAlertMetrics.ts +++ b/ui/pages/confirmations/hooks/useConfirmationAlertMetrics.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { validate as isUuid } from 'uuid'; import useAlerts from '../../../hooks/useAlerts'; @@ -55,7 +55,31 @@ function getAlertName(alertKey: string): string { export function useConfirmationAlertMetrics() { const { currentConfirmation } = useConfirmContext(); const ownerId = currentConfirmation?.id ?? ''; + const { alerts, isAlertConfirmed } = useAlerts(ownerId); + const alertsProperties = useMemo(() => { + return alerts.length > 0 + ? { + // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 + // eslint-disable-next-line @typescript-eslint/naming-convention + alert_triggered_count: alerts.length, + // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 + // eslint-disable-next-line @typescript-eslint/naming-convention + alert_triggered: getAlertNames(alerts), + // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 + // eslint-disable-next-line @typescript-eslint/naming-convention + alert_resolved_count: alerts.filter((alert) => + isAlertConfirmed(alert.key), + ).length, + // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 + // eslint-disable-next-line @typescript-eslint/naming-convention + alert_resolved: getAlertNames( + alerts.filter((alert) => isAlertConfirmed(alert.key)), + ), + } + : undefined; + }, [alerts, isAlertConfirmed]); + const { updateSignatureEventFragment } = useSignatureEventFragment(); const { updateTransactionEventFragment } = useTransactionEventFragment(); @@ -75,28 +99,11 @@ export function useConfirmationAlertMetrics() { alert_action_clicked: [], }); - const properties = - alerts.length > 0 - ? { - // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 - // eslint-disable-next-line @typescript-eslint/naming-convention - alert_triggered_count: alerts.length, - // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 - // eslint-disable-next-line @typescript-eslint/naming-convention - alert_triggered: getAlertNames(alerts), - // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 - // eslint-disable-next-line @typescript-eslint/naming-convention - alert_resolved_count: alerts.filter((alert) => - isAlertConfirmed(alert.key), - ).length, - // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 - // eslint-disable-next-line @typescript-eslint/naming-convention - alert_resolved: getAlertNames( - alerts.filter((alert) => isAlertConfirmed(alert.key)), - ), - ...metricsProperties, - } + const properties = useMemo(() => { + return alertsProperties + ? { ...alertsProperties, ...metricsProperties } : undefined; + }, [alertsProperties, metricsProperties]); const trackAlertRender = useCallback((alertKey: string) => { setMetricsProperties((prevState) => { @@ -145,7 +152,13 @@ export function useConfirmationAlertMetrics() { } else { updateTransactionEventFragment({ properties }, ownerId); } - }, [JSON.stringify(properties), updateTransactionEventFragment, ownerId]); + }, [ + updateSignatureEventFragment, + updateTransactionEventFragment, + ownerId, + properties, + currentConfirmation, + ]); useEffect(() => { updateAlertMetrics(); diff --git a/ui/pages/confirmations/hooks/useGetTokenStandardAndDetails.ts b/ui/pages/confirmations/hooks/useGetTokenStandardAndDetails.ts index 8273c742102c..0dd988ea5a17 100644 --- a/ui/pages/confirmations/hooks/useGetTokenStandardAndDetails.ts +++ b/ui/pages/confirmations/hooks/useGetTokenStandardAndDetails.ts @@ -1,3 +1,4 @@ +import { useMemo } from 'react'; import { Hex } from '@metamask/utils'; import { TokenStandard } from '../../../../shared/constants/transaction'; @@ -29,17 +30,18 @@ export const useGetTokenStandardAndDetails = ( )) as TokenDetailsERC20; }, [tokenAddress]); - if (!details) { - return { decimalsNumber: undefined }; - } + return useMemo(() => { + if (!details) { + return { decimalsNumber: undefined }; + } + const { decimals, standard } = details; - const { decimals, standard } = details || {}; + if (standard === TokenStandard.ERC20) { + const parsedDecimals = + parseTokenDetailDecimals(decimals) ?? ERC20_DEFAULT_DECIMALS; + return { ...details, decimalsNumber: parsedDecimals }; + } - if (standard === TokenStandard.ERC20) { - const parsedDecimals = - parseTokenDetailDecimals(decimals) ?? ERC20_DEFAULT_DECIMALS; - details.decimalsNumber = parsedDecimals; - } - - return details; + return details; + }, [details]); }; From 8f719cb2abdc1309fc8b564e145bd5ab75cc3a19 Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Mon, 3 Nov 2025 14:44:00 -0500 Subject: [PATCH 11/68] Fix breakages --- .../general-alert/general-alert.tsx | 2 +- .../backup-and-sync-features-toggles.tsx | 6 ++++- .../permission-page-container.component.js | 4 +-- .../snap-ui-renderer/snap-ui-renderer.js | 3 +++ .../metafox-logo.component.test.js | 11 +++++--- ui/ducks/confirm-alerts/confirm-alerts.ts | 14 +++++------ ui/helpers/utils/notification.util.ts | 4 ++- ui/hooks/useScrollRequired.js | 8 +++--- ui/hooks/useTrustSignals.ts | 3 +++ .../transaction-details.tsx | 2 +- .../components/confirm/info/utils.ts | 2 +- .../alerts/TemplateAlertContext.tsx | 2 +- .../confirmation/alerts/useAlertsActions.tsx | 10 +++----- .../alerts/useTemplateConfirmationAlerts.ts | 2 +- .../alerts/useUpdateEthereumChainAlerts.ts | 6 ++--- .../confirmations/context/confirm/index.tsx | 6 ++--- .../confirmations/hooks/useAssetDetails.js | 25 ++++++++++++++++--- .../create-account/connect-hardware/index.js | 4 +-- ui/pages/onboarding-flow/onboarding-flow.js | 2 ++ .../snaps/snap-install/snap-install.js | 4 +-- .../snaps/snap-result/snap-result.js | 2 +- .../snaps/snap-update/snap-update.js | 4 +-- .../snaps/snaps-connect/snaps-connect.js | 2 +- ui/selectors/approvals.ts | 2 +- ui/selectors/shield/coverage.ts | 13 +++++++--- 25 files changed, 89 insertions(+), 54 deletions(-) diff --git a/ui/components/app/alert-system/general-alert/general-alert.tsx b/ui/components/app/alert-system/general-alert/general-alert.tsx index ea619a6450d2..a33719f4dcba 100644 --- a/ui/components/app/alert-system/general-alert/general-alert.tsx +++ b/ui/components/app/alert-system/general-alert/general-alert.tsx @@ -82,7 +82,7 @@ function AlertDetails({ return ( - {details instanceof Array ? ( + {Array.isArray(details) ? ( {details.map((detail, index) => ( diff --git a/ui/components/app/identity/backup-and-sync-features-toggles/backup-and-sync-features-toggles.tsx b/ui/components/app/identity/backup-and-sync-features-toggles/backup-and-sync-features-toggles.tsx index 67d98054c2ae..6d0a1649aa8e 100644 --- a/ui/components/app/identity/backup-and-sync-features-toggles/backup-and-sync-features-toggles.tsx +++ b/ui/components/app/identity/backup-and-sync-features-toggles/backup-and-sync-features-toggles.tsx @@ -62,10 +62,12 @@ const FeatureToggle = ({ section, isBackupAndSyncUpdateLoading, isBackupAndSyncEnabled, + key, }: { section: (typeof backupAndSyncFeaturesTogglesSections)[number]; isBackupAndSyncUpdateLoading: boolean; isBackupAndSyncEnabled: boolean; + key: number; }) => { const t = useI18nContext(); const trackEvent = useContext(MetaMetricsContext); @@ -107,6 +109,7 @@ const FeatureToggle = ({ return ( { {t('backupAndSyncManageWhatYouSyncDescription')} - {backupAndSyncFeaturesTogglesSections.map((section) => + {backupAndSyncFeaturesTogglesSections.map((section, index) => FeatureToggle({ section, isBackupAndSyncUpdateLoading, isBackupAndSyncEnabled, + key: index, }), )} diff --git a/ui/components/app/permission-page-container/permission-page-container.component.js b/ui/components/app/permission-page-container/permission-page-container.component.js index 7fec9c3233f5..27c90fc56009 100644 --- a/ui/components/app/permission-page-container/permission-page-container.component.js +++ b/ui/components/app/permission-page-container/permission-page-container.component.js @@ -134,7 +134,7 @@ export default class PermissionPageContainer extends Component { onCancel = () => { const { request, rejectPermissionsRequest } = this.props; - rejectPermissionsRequest(request.metadata.id); + rejectPermissionsRequest(request?.metadata?.id); }; onSubmit = () => { @@ -169,7 +169,7 @@ export default class PermissionPageContainer extends Component { if (Object.keys(request.permissions).length > 0) { approvePermissionsRequest(request); } else { - rejectPermissionsRequest(request.metadata.id); + rejectPermissionsRequest(request?.metadata?.id); } }; diff --git a/ui/components/app/snaps/snap-ui-renderer/snap-ui-renderer.js b/ui/components/app/snaps/snap-ui-renderer/snap-ui-renderer.js index f97107cf32e5..09f74cbe77d3 100644 --- a/ui/components/app/snaps/snap-ui-renderer/snap-ui-renderer.js +++ b/ui/components/app/snaps/snap-ui-renderer/snap-ui-renderer.js @@ -45,6 +45,9 @@ const SnapUIRendererComponent = ({ contentBackgroundColor, PERF_DEBUG, }) => { + // eslint-disable-next-line react-compiler/react-compiler + 'use no memo'; + const t = useI18nContext(); const interfaceState = useSelector( diff --git a/ui/components/ui/metafox-logo/metafox-logo.component.test.js b/ui/components/ui/metafox-logo/metafox-logo.component.test.js index e8c680a830d3..532e555e2ae2 100644 --- a/ui/components/ui/metafox-logo/metafox-logo.component.test.js +++ b/ui/components/ui/metafox-logo/metafox-logo.component.test.js @@ -2,10 +2,13 @@ import React from 'react'; import { renderWithProvider } from '../../../../test/lib/render-helpers'; import MetaFoxLogo from '.'; -// eslint-disable-next-line react/display-name -jest.mock('./horizontal-logo.js', () => () => { - return
; -}); +jest.mock( + './horizontal-logo.js', + () => + function mockRender() { + return
; + }, +); describe('MetaFoxLogo', () => { it('should match snapshot with img width and height default set to 42', () => { diff --git a/ui/ducks/confirm-alerts/confirm-alerts.ts b/ui/ducks/confirm-alerts/confirm-alerts.ts index d69f66397e6a..50d1db85f894 100644 --- a/ui/ducks/confirm-alerts/confirm-alerts.ts +++ b/ui/ducks/confirm-alerts/confirm-alerts.ts @@ -168,7 +168,7 @@ export type ConfirmAlertsState = { type UpdateAlertsAction = { type: 'UPDATE_ALERTS'; - ownerId: string; + ownerId: string | undefined; alerts: Alert[]; }; @@ -181,7 +181,7 @@ type SetAlertConfirmedAction = { type ClearAlertsAction = { type: 'CLEAR_ALERTS'; - ownerId: string; + ownerId: string | undefined; }; type Action = UpdateAlertsAction | SetAlertConfirmedAction | ClearAlertsAction; @@ -202,7 +202,7 @@ export default function confirmAlertsReducer( ...state, alerts: { ...state.alerts, - [action.ownerId]: action.alerts, + [action.ownerId ?? '']: action.alerts, }, }; @@ -223,11 +223,11 @@ export default function confirmAlertsReducer( ...state, alerts: { ...state.alerts, - [action.ownerId]: [], + [action.ownerId ?? '']: [], }, confirmed: { ...state.confirmed, - [action.ownerId]: {}, + [action.ownerId ?? '']: {}, }, }; @@ -237,7 +237,7 @@ export default function confirmAlertsReducer( } export function updateAlerts( - ownerId: string, + ownerId: string | undefined, alerts: Alert[], ): UpdateAlertsAction { return { @@ -260,7 +260,7 @@ export function setAlertConfirmed( }; } -export function clearAlerts(ownerId: string): ClearAlertsAction { +export function clearAlerts(ownerId: string | undefined): ClearAlertsAction { return { type: 'CLEAR_ALERTS', ownerId, diff --git a/ui/helpers/utils/notification.util.ts b/ui/helpers/utils/notification.util.ts index 9a784fb635bf..6be8493f5628 100644 --- a/ui/helpers/utils/notification.util.ts +++ b/ui/helpers/utils/notification.util.ts @@ -410,7 +410,9 @@ export function hasNetworkFeeFields( return 'network_fee' in notification.data; } -export const getNetworkFees = async (notification: OnChainRawNotification) => { +export const getNetworkFees = async ( + notification: OnChainRawNotificationsWithNetworkFields, +) => { if (!hasNetworkFeeFields(notification)) { throw new Error('Invalid notification type'); } diff --git a/ui/hooks/useScrollRequired.js b/ui/hooks/useScrollRequired.js index 20ea25121227..3a4cd3ffd3ff 100644 --- a/ui/hooks/useScrollRequired.js +++ b/ui/hooks/useScrollRequired.js @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import { debounce } from 'lodash'; import { usePrevious } from './usePrevious'; @@ -24,7 +24,7 @@ export const useScrollRequired = ( const [isScrollableState, setIsScrollable] = useState(false); const [isScrolledToBottomState, setIsScrolledToBottom] = useState(false); - const update = () => { + const update = useCallback(() => { if (!ref.current) { return; } @@ -51,7 +51,7 @@ export const useScrollRequired = ( if (!isScrollable || isScrolledToBottom) { setHasScrolledToBottom(true); } - }; + }, [isScrollableState, offsetPxFromBottom]); useEffect(update, [ref, ...dependencies]); @@ -59,7 +59,7 @@ export const useScrollRequired = ( if (prevOffsetHeight !== ref.current?.offsetHeight) { update(); } - }, [ref.current?.offsetHeight]); + }, [update, ref.current?.offsetHeight, prevOffsetHeight]); const scrollToBottom = () => { setIsScrolledToBottom(true); diff --git a/ui/hooks/useTrustSignals.ts b/ui/hooks/useTrustSignals.ts index 70b9e29a54bf..662d16105305 100644 --- a/ui/hooks/useTrustSignals.ts +++ b/ui/hooks/useTrustSignals.ts @@ -1,3 +1,6 @@ +'use no memo'; +// TODO: Fix - Calling `useTrustSignals` from `useTrustSignal`, which is not a component, violates the rules of hooks. + import { useSelector } from 'react-redux'; import { NameType } from '@metamask/name-controller'; import { getAddressSecurityAlertResponse } from '../selectors'; diff --git a/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx b/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx index ea45fd9b32bc..8d63d908fc98 100644 --- a/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx +++ b/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx @@ -46,7 +46,7 @@ export const OriginRow = () => { return ( confirmation.id === confirmationId, - ) ?? pendingConfirmations[0]; + ) ?? pendingConfirmations?.[0]; const [isAlertsModalVisible, setIsAlertsModalVisible] = useState(false); const alertOwnerId = pendingConfirmation?.id; diff --git a/ui/pages/confirmations/confirmation/alerts/useAlertsActions.tsx b/ui/pages/confirmations/confirmation/alerts/useAlertsActions.tsx index 09d95d355d3b..4229d7093cd1 100644 --- a/ui/pages/confirmations/confirmation/alerts/useAlertsActions.tsx +++ b/ui/pages/confirmations/confirmation/alerts/useAlertsActions.tsx @@ -11,19 +11,17 @@ import { export const useAlertsActions = ( hideAlertModal: () => void, - pendingConfirmation: ApprovalRequest<{ id: string }>, + pendingConfirmation: ApprovalRequest<{ id: string }> | undefined, ) => { + const { origin } = pendingConfirmation ?? {}; const pendingConfirmationsFromOrigin = useSelector((state) => - getApprovalsByOrigin( - state as ApprovalsMetaMaskState, - pendingConfirmation?.origin, - ), + getApprovalsByOrigin(state as ApprovalsMetaMaskState, origin as string), ); const { getIndex, navigateToIndex } = useConfirmationNavigation(); const navigateToPendingConfirmation = useCallback(() => { - const { id } = pendingConfirmation; + const { id } = pendingConfirmation ?? {}; const pendingConfirmations = pendingConfirmationsFromOrigin?.filter( (confirmation) => confirmation.id !== id, ); diff --git a/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.ts b/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.ts index 7393d526a828..844f90288c40 100644 --- a/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.ts +++ b/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.ts @@ -10,7 +10,7 @@ import { import { useUpdateEthereumChainAlerts } from './useUpdateEthereumChainAlerts'; export const useTemplateConfirmationAlerts = ( - pendingConfirmation: ApprovalRequest<{ id: string }>, + pendingConfirmation: ApprovalRequest<{ id: string }> | undefined, ) => { const dispatch = useDispatch(); const addEthereumChainAlerts = diff --git a/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.ts b/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.ts index 6c852f372fc4..07f347e3c995 100644 --- a/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.ts +++ b/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.ts @@ -19,7 +19,7 @@ const VALIDATED_APPROVAL_TYPES = [ ]; export function useUpdateEthereumChainAlerts( - pendingConfirmation: ApprovalRequest>, + pendingConfirmation: ApprovalRequest> | undefined, ): Alert[] { const pendingConfirmationsFromOrigin = useSelector((state) => getApprovalsByOrigin( @@ -33,7 +33,7 @@ export function useUpdateEthereumChainAlerts( if ( pendingConfirmationsFromOrigin?.length <= 1 || (!VALIDATED_APPROVAL_TYPES.includes( - pendingConfirmation.type as ApprovalType, + pendingConfirmation?.type as ApprovalType, ) && (pendingConfirmation?.requestData?.metadata as Record) ?.isSwitchEthereumChain !== true) @@ -51,7 +51,7 @@ export function useUpdateEthereumChainAlerts( ], key: 'pendingConfirmationFromSameOrigin', message: t( - pendingConfirmation.type === ApprovalType.AddEthereumChain + pendingConfirmation?.type === ApprovalType.AddEthereumChain ? 'pendingConfirmationAddNetworkAlertMessage' : 'pendingConfirmationSwitchNetworkAlertMessage', [pendingConfirmationsFromOrigin.length - 1], diff --git a/ui/pages/confirmations/context/confirm/index.tsx b/ui/pages/confirmations/context/confirm/index.tsx index 5d032b75b96e..ad7b7c3ebc13 100644 --- a/ui/pages/confirmations/context/confirm/index.tsx +++ b/ui/pages/confirmations/context/confirm/index.tsx @@ -64,9 +64,7 @@ export const ConfirmContextProvider: React.FC<{ ); }; -// TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 -// eslint-disable-next-line @typescript-eslint/naming-convention -export const useConfirmContext = () => { +export const useConfirmContext = () => { const context = useContext(ConfirmContext); if (!context) { throw new Error( @@ -74,7 +72,7 @@ export const useConfirmContext = () => { ); } return context as { - currentConfirmation: T; + currentConfirmation: CurrentConfirmation; isScrollToBottomCompleted: boolean; setIsScrollToBottomCompleted: (isScrollToBottomCompleted: boolean) => void; }; diff --git a/ui/pages/confirmations/hooks/useAssetDetails.js b/ui/pages/confirmations/hooks/useAssetDetails.js index d62b68d2271a..456d16952a08 100644 --- a/ui/pages/confirmations/hooks/useAssetDetails.js +++ b/ui/pages/confirmations/hooks/useAssetDetails.js @@ -1,5 +1,5 @@ import { isEqual } from 'lodash'; -import { useState, useEffect } from 'react'; +import { useState, useEffect, useRef } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { getTokensByChainId } from '../../../ducks/metamask/metamask'; import { getAssetDetails } from '../../../helpers/utils/token-util'; @@ -18,6 +18,7 @@ export function useAssetDetails( transactionData, chainId, ) { + const isMounted = useRef(false); const dispatch = useDispatch(); // state selectors @@ -43,8 +44,18 @@ export function useAssetDetails( const prevTokenBalance = usePrevious(tokensWithBalances); useEffect(() => { - if (!tokenAddress && !userAddress && !transactionData) { - return; + isMounted.current = true; + return () => { + isMounted.current = false; + }; + }); + + useEffect(() => { + if ( + !isMounted.current || + (!tokenAddress && !userAddress && !transactionData) + ) { + return () => undefined; } async function getAndSetAssetDetails() { @@ -57,7 +68,9 @@ export function useAssetDetails( nfts, chainId, ); - setCurrentAsset(assetDetails); + if (isMounted.current) { + setCurrentAsset(assetDetails); + } } catch (e) { console.warn('Unable to set asset details', { error: e, @@ -74,6 +87,10 @@ export function useAssetDetails( ) { getAndSetAssetDetails(); } + + return () => { + isMounted.current = false; + }; }, [ chainId, dispatch, diff --git a/ui/pages/create-account/connect-hardware/index.js b/ui/pages/create-account/connect-hardware/index.js index 8cfbcb5befd6..a07047f40942 100644 --- a/ui/pages/create-account/connect-hardware/index.js +++ b/ui/pages/create-account/connect-hardware/index.js @@ -348,7 +348,6 @@ class ConnectHardwareForm extends Component { <> {this.context.t('troubleConnectingToLedgerU2FOnFirefox', [ - // eslint-disable-next-line react/jsx-key