+
-`;
-
-exports[`App Header unlocked state matches snapshot: unlocked 1`] = `
-
+
+
diff --git a/ui/components/multichain/app-header/app-header-locked-content.tsx b/ui/components/multichain/app-header/app-header-locked-content.tsx
index 5ac709cfc94a..3efb393fe08b 100644
--- a/ui/components/multichain/app-header/app-header-locked-content.tsx
+++ b/ui/components/multichain/app-header/app-header-locked-content.tsx
@@ -1,6 +1,6 @@
import { type MultichainNetworkConfiguration } from '@metamask/multichain-network-controller';
import React from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { useI18nContext } from '../../../hooks/useI18nContext';
import MetafoxLogo from '../../ui/metafox-logo';
diff --git a/ui/components/multichain/app-header/app-header-unlocked-content.tsx b/ui/components/multichain/app-header/app-header-unlocked-content.tsx
index ca2785986c35..04491f85264d 100644
--- a/ui/components/multichain/app-header/app-header-unlocked-content.tsx
+++ b/ui/components/multichain/app-header/app-header-unlocked-content.tsx
@@ -9,7 +9,7 @@ import React, {
import browser from 'webextension-polyfill';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
AlignItems,
BackgroundColor,
diff --git a/ui/components/multichain/app-header/app-header.js b/ui/components/multichain/app-header/app-header.js
index d432e33639d4..646fb1fcbd24 100644
--- a/ui/components/multichain/app-header/app-header.js
+++ b/ui/components/multichain/app-header/app-header.js
@@ -2,7 +2,7 @@ import React, { useCallback, useContext, useRef } from 'react';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
-import { matchPath } from 'react-router-dom-v5-compat';
+import { matchPath } from 'react-router-dom';
import { MetaMetricsContext } from '../../../contexts/metametrics';
import {
MetaMetricsEventCategory,
diff --git a/ui/components/multichain/app-header/app-header.test.js b/ui/components/multichain/app-header/app-header.test.js
index a0413c642811..5b4b38aea1f0 100644
--- a/ui/components/multichain/app-header/app-header.test.js
+++ b/ui/components/multichain/app-header/app-header.test.js
@@ -15,7 +15,8 @@ jest.mock('../../../../app/scripts/lib/util', () => ({
getEnvironmentType: jest.fn(),
}));
-jest.mock('react-router-dom-v5-compat', () => ({
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
// eslint-disable-next-line react/prop-types
Link: ({ children, ...props }) =>
{children} ,
// eslint-disable-next-line react/prop-types
diff --git a/ui/components/multichain/app-header/multichain-meta-fox-logo.js b/ui/components/multichain/app-header/multichain-meta-fox-logo.js
index e79da9c9b3b5..442fe527e6fa 100644
--- a/ui/components/multichain/app-header/multichain-meta-fox-logo.js
+++ b/ui/components/multichain/app-header/multichain-meta-fox-logo.js
@@ -1,6 +1,6 @@
import React, { useCallback } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { DEFAULT_ROUTE } from '../../../helpers/constants/routes';
import { useTheme } from '../../../hooks/useTheme';
diff --git a/ui/components/multichain/asset-picker-amount/asset-balance/asset-balance-text.test.tsx b/ui/components/multichain/asset-picker-amount/asset-balance/asset-balance-text.test.tsx
index 88db613fd837..30edf5236aaf 100644
--- a/ui/components/multichain/asset-picker-amount/asset-balance/asset-balance-text.test.tsx
+++ b/ui/components/multichain/asset-picker-amount/asset-balance/asset-balance-text.test.tsx
@@ -3,7 +3,7 @@ import { AssetType } from '../../../../../shared/constants/transaction';
import mockSendState from '../../../../../test/data/mock-send-state.json';
import configureStore from '../../../../store/store';
import { TextColor } from '../../../../helpers/constants/design-system';
-import { renderWithProvider } from '../../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { AssetBalanceText } from './asset-balance-text';
const store = configureStore({
diff --git a/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-network.test.tsx b/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-network.test.tsx
index fcabe7412be2..244330e3a34b 100644
--- a/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-network.test.tsx
+++ b/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-network.test.tsx
@@ -4,7 +4,7 @@ import thunk from 'redux-thunk';
import { screen, fireEvent } from '@testing-library/react';
import { RpcEndpointType } from '@metamask/network-controller';
import { CHAIN_IDS } from '@metamask/transaction-controller';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-send-state.json';
import { NETWORK_TO_SHORT_NETWORK_NAME_MAP } from '../../../../../shared/constants/bridge';
import { AssetPickerModalNetwork } from './asset-picker-modal-network';
diff --git a/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-nft-tab.tsx b/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-nft-tab.tsx
index 89e76f447051..4d6df125879c 100644
--- a/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-nft-tab.tsx
+++ b/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-nft-tab.tsx
@@ -1,6 +1,6 @@
import React, { useContext } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { Box } from '../../../component-library';
import Spinner from '../../../ui/spinner';
import {
diff --git a/ui/components/multichain/asset-picker-amount/asset-picker/asset-picker.test.tsx b/ui/components/multichain/asset-picker-amount/asset-picker/asset-picker.test.tsx
index 37237c8bd525..7c101b8613a9 100644
--- a/ui/components/multichain/asset-picker-amount/asset-picker/asset-picker.test.tsx
+++ b/ui/components/multichain/asset-picker-amount/asset-picker/asset-picker.test.tsx
@@ -17,9 +17,9 @@ import { AssetPicker } from './asset-picker';
const unknownChainId = '0x2489078';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/components/multichain/avatar-group/avatar-group.test.tsx b/ui/components/multichain/avatar-group/avatar-group.test.tsx
index 22feec62d524..deca7e065a54 100644
--- a/ui/components/multichain/avatar-group/avatar-group.test.tsx
+++ b/ui/components/multichain/avatar-group/avatar-group.test.tsx
@@ -3,7 +3,7 @@ import { screen } from '@testing-library/react';
import React from 'react';
import configureMockStore from 'redux-mock-store';
import mockState from '../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { AvatarGroup } from './avatar-group';
diff --git a/ui/components/multichain/badge-status/badge-status.test.js b/ui/components/multichain/badge-status/badge-status.test.js
index c7980e52ebc4..146f70e123d3 100644
--- a/ui/components/multichain/badge-status/badge-status.test.js
+++ b/ui/components/multichain/badge-status/badge-status.test.js
@@ -6,7 +6,7 @@ import {
BorderColor,
} from '../../../helpers/constants/design-system';
import configureStore from '../../../store/store';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { BadgeStatus } from './badge-status';
describe('Badge Status', () => {
diff --git a/ui/components/multichain/connect-accounts-modal/connect-accounts-modal-list.test.tsx b/ui/components/multichain/connect-accounts-modal/connect-accounts-modal-list.test.tsx
index faeb18ff7e0c..bbba33de4d6a 100644
--- a/ui/components/multichain/connect-accounts-modal/connect-accounts-modal-list.test.tsx
+++ b/ui/components/multichain/connect-accounts-modal/connect-accounts-modal-list.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { EthAccountType, EthScope } from '@metamask/keyring-api';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { ETH_EOA_METHODS } from '../../../../shared/constants/eth-methods';
import { ConnectAccountsModalList } from './connect-accounts-modal-list';
diff --git a/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.test.tsx b/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.test.tsx
index ae4f4ef84d98..c532b69c0959 100644
--- a/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.test.tsx
+++ b/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.test.tsx
@@ -6,7 +6,7 @@ import { waitFor } from '@testing-library/react';
import messages from '../../../../app/_locales/en/messages.json';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { createMockInternalAccount } from '../../../../test/jest/mocks';
import { shortenAddress } from '../../../helpers/utils/util';
// TODO: Remove restricted import
diff --git a/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.test.tsx b/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.test.tsx
index 34a80f6604bd..2f506024541e 100644
--- a/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.test.tsx
+++ b/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
import { EthAccountType, EthMethod } from '@metamask/keyring-api';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
import { createMockInternalAccount } from '../../../../test/jest/mocks';
diff --git a/ui/components/multichain/connected-site-menu/connected-site-menu.test.js b/ui/components/multichain/connected-site-menu/connected-site-menu.test.js
index 31c5cb3a1611..7d7617b5836a 100644
--- a/ui/components/multichain/connected-site-menu/connected-site-menu.test.js
+++ b/ui/components/multichain/connected-site-menu/connected-site-menu.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import {
STATUS_CONNECTED,
STATUS_CONNECTED_TO_ANOTHER_ACCOUNT,
diff --git a/ui/components/multichain/connected-site-popover/connected-site-popover.test.tsx b/ui/components/multichain/connected-site-popover/connected-site-popover.test.tsx
index 908b232b534d..d5a9ff9075eb 100644
--- a/ui/components/multichain/connected-site-popover/connected-site-popover.test.tsx
+++ b/ui/components/multichain/connected-site-popover/connected-site-popover.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { fireEvent } from '@testing-library/react';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { ConnectedSitePopover } from './connected-site-popover';
const props = {
diff --git a/ui/components/multichain/create-account/create-account.tsx b/ui/components/multichain/create-account/create-account.tsx
index 5f266c979abe..906c8dbd4fb3 100644
--- a/ui/components/multichain/create-account/create-account.tsx
+++ b/ui/components/multichain/create-account/create-account.tsx
@@ -8,7 +8,7 @@ import React, {
useState,
} from 'react';
import { useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { InternalAccount } from '@metamask/keyring-internal-api';
import { CaipChainId } from '@metamask/utils';
import { KeyringTypes } from '@metamask/keyring-controller';
diff --git a/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx b/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx
index 0df8d261ffa5..f654ef6d657f 100644
--- a/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx
+++ b/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx
@@ -1,6 +1,6 @@
import React, { useCallback } from 'react';
import { useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { InternalAccount } from '@metamask/keyring-internal-api';
import { KeyringTypes } from '@metamask/keyring-controller';
import { CreateAccount } from '..';
diff --git a/ui/components/multichain/detected-token-banner/detected-token-banner.test.js b/ui/components/multichain/detected-token-banner/detected-token-banner.test.js
index 262147179ad1..77c48fe7890e 100644
--- a/ui/components/multichain/detected-token-banner/detected-token-banner.test.js
+++ b/ui/components/multichain/detected-token-banner/detected-token-banner.test.js
@@ -1,5 +1,6 @@
import React from 'react';
-import { fireEvent, renderWithProvider, screen } from '../../../../test/jest';
+import { fireEvent } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import testData from '../../../../.storybook/test-data';
@@ -37,13 +38,14 @@ describe('DetectedTokensBanner', () => {
});
it('should render number of tokens detected link', () => {
const store = configureStore(mockStore);
- renderWithProvider(
, store);
+ const { getByText } = renderWithProvider(
+
,
+ store,
+ );
- expect(
- screen.getByText('3 new tokens found in this account'),
- ).toBeInTheDocument();
+ expect(getByText('3 new tokens found in this account')).toBeInTheDocument();
- fireEvent.click(screen.getByText('Import tokens'));
+ fireEvent.click(getByText('Import tokens'));
expect(setShowDetectedTokensSpy).toHaveBeenCalled();
});
});
diff --git a/ui/components/multichain/disconnect-permissions-modal/disconnect-permissions-modal.test.tsx b/ui/components/multichain/disconnect-permissions-modal/disconnect-permissions-modal.test.tsx
index e268d7603a5f..076173c79960 100644
--- a/ui/components/multichain/disconnect-permissions-modal/disconnect-permissions-modal.test.tsx
+++ b/ui/components/multichain/disconnect-permissions-modal/disconnect-permissions-modal.test.tsx
@@ -3,7 +3,7 @@ import configureMockStore from 'redux-mock-store';
import { Hex } from '@metamask/utils';
import { fireEvent } from '../../../../test/jest';
import mockState from '../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { DisconnectPermissionsModal } from '.';
diff --git a/ui/components/multichain/edit-networks-modal/edit-networks-modal.test.js b/ui/components/multichain/edit-networks-modal/edit-networks-modal.test.js
index 4ac721ab2dc0..0e77fc9a022e 100644
--- a/ui/components/multichain/edit-networks-modal/edit-networks-modal.test.js
+++ b/ui/components/multichain/edit-networks-modal/edit-networks-modal.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
-import { renderWithProvider } from '../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
import configureStore from '../../../store/store';
import { EditNetworksModal } from '.';
diff --git a/ui/components/multichain/funding-method-modal/funding-method-modal.test.tsx b/ui/components/multichain/funding-method-modal/funding-method-modal.test.tsx
index 56cd2cd3a8d4..80148c8e50d1 100644
--- a/ui/components/multichain/funding-method-modal/funding-method-modal.test.tsx
+++ b/ui/components/multichain/funding-method-modal/funding-method-modal.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { fireEvent } from '@testing-library/react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
-import { renderWithProvider } from '../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
import useRamps from '../../../hooks/ramps/useRamps/useRamps';
import { FundingMethodModal } from './funding-method-modal';
diff --git a/ui/components/multichain/global-menu/global-menu.test.tsx b/ui/components/multichain/global-menu/global-menu.test.tsx
index 3d0d9cf0f169..72f7e8349c83 100644
--- a/ui/components/multichain/global-menu/global-menu.test.tsx
+++ b/ui/components/multichain/global-menu/global-menu.test.tsx
@@ -34,8 +34,8 @@ const render = (metamaskStateChanges = {}) => {
};
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
Link: ({
children,
diff --git a/ui/components/multichain/global-menu/global-menu.tsx b/ui/components/multichain/global-menu/global-menu.tsx
index fc9872166c48..965a6f1b58cb 100644
--- a/ui/components/multichain/global-menu/global-menu.tsx
+++ b/ui/components/multichain/global-menu/global-menu.tsx
@@ -1,5 +1,5 @@
import React, { useContext, useMemo } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import browser from 'webextension-polyfill';
import {
diff --git a/ui/components/multichain/import-account/json.test.tsx b/ui/components/multichain/import-account/json.test.tsx
index bad3e4befc87..de84b7bf8741 100644
--- a/ui/components/multichain/import-account/json.test.tsx
+++ b/ui/components/multichain/import-account/json.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import { fireEvent, waitFor } from '@testing-library/react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
// TODO: Remove restricted import
// eslint-disable-next-line import/no-restricted-paths
diff --git a/ui/components/multichain/import-nfts-modal/import-nfts-modal.js b/ui/components/multichain/import-nfts-modal/import-nfts-modal.js
index e7de4e120a37..0d03d505078a 100644
--- a/ui/components/multichain/import-nfts-modal/import-nfts-modal.js
+++ b/ui/components/multichain/import-nfts-modal/import-nfts-modal.js
@@ -2,7 +2,7 @@ import { isValidHexAddress } from '@metamask/controller-utils';
import PropTypes from 'prop-types';
import React, { useContext, useState, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { getErrorMessage } from '../../../../shared/modules/error';
import {
MetaMetricsEventName,
diff --git a/ui/components/multichain/import-nfts-modal/import-nfts-modal.test.js b/ui/components/multichain/import-nfts-modal/import-nfts-modal.test.js
index cd7758e180b7..586126bf7e9c 100644
--- a/ui/components/multichain/import-nfts-modal/import-nfts-modal.test.js
+++ b/ui/components/multichain/import-nfts-modal/import-nfts-modal.test.js
@@ -2,7 +2,7 @@ import React from 'react';
import { fireEvent, waitFor } from '@testing-library/react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
import { DEFAULT_ROUTE } from '../../../helpers/constants/routes';
import {
@@ -36,9 +36,9 @@ jest.mock('../../../store/actions.ts', () => ({
}));
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/components/multichain/import-tokens-modal/import-tokens-modal.js b/ui/components/multichain/import-tokens-modal/import-tokens-modal.js
index bd3dbe309840..4163f57f1106 100644
--- a/ui/components/multichain/import-tokens-modal/import-tokens-modal.js
+++ b/ui/components/multichain/import-tokens-modal/import-tokens-modal.js
@@ -12,7 +12,7 @@ import {
isNonEvmChainId,
} from '@metamask/bridge-controller';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import PropTypes from 'prop-types';
import { getTokenTrackerLink } from '@metamask/etherscan-link/dist/token-tracker-link';
import { CHAIN_IDS } from '@metamask/transaction-controller';
diff --git a/ui/components/multichain/menu-items/account-details-menu-item.js b/ui/components/multichain/menu-items/account-details-menu-item.js
index 0bb01deb1935..2078c9653f45 100644
--- a/ui/components/multichain/menu-items/account-details-menu-item.js
+++ b/ui/components/multichain/menu-items/account-details-menu-item.js
@@ -1,9 +1,7 @@
import React, { useCallback, useContext } from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
-
-import { useNavigate } from 'react-router-dom-v5-compat';
-
+import { useNavigate } from 'react-router-dom';
import { MenuItem } from '../../ui/menu';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { MetaMetricsContext } from '../../../contexts/metametrics';
@@ -13,7 +11,7 @@ import {
} from '../../../../shared/constants/metametrics';
import { IconName, Text } from '../../component-library';
import { getSelectedAccountGroup } from '../../../selectors/multichain-accounts/account-tree';
-import { getHDEntropyIndex } from '../../../selectors/selectors';
+import { getHDEntropyIndex } from '../../../selectors';
import { MULTICHAIN_ACCOUNT_DETAILS_PAGE_ROUTE } from '../../../helpers/constants/routes';
export const AccountDetailsMenuItem = ({
diff --git a/ui/components/multichain/menu-items/account-details-menu-item.test.js b/ui/components/multichain/menu-items/account-details-menu-item.test.js
index 6fc2a317cec8..33d7698a773c 100644
--- a/ui/components/multichain/menu-items/account-details-menu-item.test.js
+++ b/ui/components/multichain/menu-items/account-details-menu-item.test.js
@@ -11,8 +11,8 @@ const mockInternalAccount = getSelectedInternalAccountFromMockState(mockState);
const mockNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
}));
diff --git a/ui/components/multichain/menu-items/discover-menu-item.test.tsx b/ui/components/multichain/menu-items/discover-menu-item.test.tsx
index 1a11bb351649..2436c9a6a9d1 100644
--- a/ui/components/multichain/menu-items/discover-menu-item.test.tsx
+++ b/ui/components/multichain/menu-items/discover-menu-item.test.tsx
@@ -1,5 +1,6 @@
import React from 'react';
-import { fireEvent, renderWithProvider } from '../../../../test/jest';
+import { fireEvent } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
import { DiscoverMenuItem } from './discover-menu-item';
diff --git a/ui/components/multichain/menu-items/view-explorer-menu-item.tsx b/ui/components/multichain/menu-items/view-explorer-menu-item.tsx
index aade38141a3f..b5c7fd0d45db 100644
--- a/ui/components/multichain/menu-items/view-explorer-menu-item.tsx
+++ b/ui/components/multichain/menu-items/view-explorer-menu-item.tsx
@@ -1,6 +1,6 @@
import React, { useContext } from 'react';
import { useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { parseCaipChainId } from '@metamask/utils';
import { InternalAccount } from '@metamask/keyring-internal-api';
diff --git a/ui/components/multichain/multi-srp/select-srp/select-srp.test.tsx b/ui/components/multichain/multi-srp/select-srp/select-srp.test.tsx
index 8e2fcd5de239..3875a2c35c05 100644
--- a/ui/components/multichain/multi-srp/select-srp/select-srp.test.tsx
+++ b/ui/components/multichain/multi-srp/select-srp/select-srp.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { fireEvent } from '@testing-library/react';
import configureMockStore from 'redux-mock-store';
import mockState from '../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { SelectSrp, SelectSrpProps } from './select-srp';
const mockSrpName = 'Test Srp';
diff --git a/ui/components/multichain/multi-srp/srp-list/srp-list-item.test.tsx b/ui/components/multichain/multi-srp/srp-list/srp-list-item.test.tsx
index aac53049c5fb..6488258270d8 100644
--- a/ui/components/multichain/multi-srp/srp-list/srp-list-item.test.tsx
+++ b/ui/components/multichain/multi-srp/srp-list/srp-list-item.test.tsx
@@ -4,7 +4,7 @@ import thunk from 'redux-thunk';
import mockState from '../../../../../test/data/mock-state.json';
import { createMockInternalAccount } from '../../../../../test/jest/mocks';
import { InternalAccountWithBalance } from '../../../../selectors';
-import { renderWithProvider } from '../../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { shortenAddress } from '../../../../helpers/utils/util';
import { SrpListItem } from './srp-list-item';
diff --git a/ui/components/multichain/multi-srp/srp-list/srp-list.test.tsx b/ui/components/multichain/multi-srp/srp-list/srp-list.test.tsx
index 204149f733f5..8bd26ab7abc9 100644
--- a/ui/components/multichain/multi-srp/srp-list/srp-list.test.tsx
+++ b/ui/components/multichain/multi-srp/srp-list/srp-list.test.tsx
@@ -3,7 +3,7 @@ import { fireEvent } from '@testing-library/react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { KeyringTypes } from '@metamask/keyring-controller';
-import { renderWithProvider } from '../../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import { InternalAccountWithBalance } from '../../../../selectors';
import { shortenAddress } from '../../../../helpers/utils/util';
diff --git a/ui/components/multichain/multichain-accounts/wallet-details-account-item/wallet-details-account-item.test.tsx b/ui/components/multichain/multichain-accounts/wallet-details-account-item/wallet-details-account-item.test.tsx
index c9e3dacf26cc..5a72daaccc4a 100644
--- a/ui/components/multichain/multichain-accounts/wallet-details-account-item/wallet-details-account-item.test.tsx
+++ b/ui/components/multichain/multichain-accounts/wallet-details-account-item/wallet-details-account-item.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { fireEvent } from '@testing-library/react';
import { InternalAccount } from '@metamask/keyring-internal-api';
import configureStore from '../../../../store/store';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import WalletDetailsAccountItem from './wallet-details-account-item';
diff --git a/ui/components/multichain/network-list-menu/network-confirmation-popover/network-confirmation-popover.test.tsx b/ui/components/multichain/network-list-menu/network-confirmation-popover/network-confirmation-popover.test.tsx
index 8efca30b61fc..68de8a62d5ab 100644
--- a/ui/components/multichain/network-list-menu/network-confirmation-popover/network-confirmation-popover.test.tsx
+++ b/ui/components/multichain/network-list-menu/network-confirmation-popover/network-confirmation-popover.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import { ApprovalType } from '@metamask/controller-utils';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import NetworkConfirmationPopover from './network-confirmation-popover';
diff --git a/ui/components/multichain/network-list-menu/network-list-menu.test.tsx b/ui/components/multichain/network-list-menu/network-list-menu.test.tsx
index 494048dfaa12..0cd1a92206aa 100644
--- a/ui/components/multichain/network-list-menu/network-list-menu.test.tsx
+++ b/ui/components/multichain/network-list-menu/network-list-menu.test.tsx
@@ -16,7 +16,7 @@ import {
MONAD_TESTNET_DISPLAY_NAME,
} from '../../../../shared/constants/network';
import { hexToDecimal } from '../../../../shared/modules/conversion.utils';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { NetworkListMenu } from '.';
const mockSetShowTestNetworks = jest.fn();
diff --git a/ui/components/multichain/network-list-menu/popular-network-list/popular-network-list.test.tsx b/ui/components/multichain/network-list-menu/popular-network-list/popular-network-list.test.tsx
index 1ffb957df1c7..7103edd7419a 100644
--- a/ui/components/multichain/network-list-menu/popular-network-list/popular-network-list.test.tsx
+++ b/ui/components/multichain/network-list-menu/popular-network-list/popular-network-list.test.tsx
@@ -4,7 +4,7 @@ import '@testing-library/jest-dom';
import { useDispatch, useSelector } from 'react-redux';
import configureStore from 'redux-mock-store';
import { RpcEndpointType } from '@metamask/network-controller';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { getUnapprovedConfirmations } from '../../../../selectors';
import { CHAIN_IDS } from '../../../../../shared/constants/network';
import PopularNetworkList from './popular-network-list';
diff --git a/ui/components/multichain/network-list-menu/select-rpc-url-modal/select-rpc-url-modal.tsx b/ui/components/multichain/network-list-menu/select-rpc-url-modal/select-rpc-url-modal.tsx
index 3d4e0ae276c0..a07ed7d33ee4 100644
--- a/ui/components/multichain/network-list-menu/select-rpc-url-modal/select-rpc-url-modal.tsx
+++ b/ui/components/multichain/network-list-menu/select-rpc-url-modal/select-rpc-url-modal.tsx
@@ -4,7 +4,7 @@ import { NetworkConfiguration } from '@metamask/network-controller';
import { type CaipChainId } from '@metamask/utils';
import classnames from 'classnames';
import { useDispatch, useSelector } from 'react-redux';
-import { useLocation } from 'react-router-dom-v5-compat';
+import { useLocation } from 'react-router-dom';
import {
AvatarNetwork,
AvatarNetworkSize,
diff --git a/ui/components/multichain/network-manager/components/add-network/AddNetwork.tsx b/ui/components/multichain/network-manager/components/add-network/AddNetwork.tsx
index 6239e4e4ede4..db82cd2029bf 100644
--- a/ui/components/multichain/network-manager/components/add-network/AddNetwork.tsx
+++ b/ui/components/multichain/network-manager/components/add-network/AddNetwork.tsx
@@ -1,6 +1,6 @@
import { UpdateNetworkFields } from '@metamask/network-controller';
import React from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { NetworksForm } from '../../../../../pages/settings/networks-tab/networks-form/networks-form';
import { useNetworkFormState } from '../../../../../pages/settings/networks-tab/networks-form/networks-form-state';
diff --git a/ui/components/multichain/network-manager/components/additional-networks-info/additional-networks-info.test.tsx b/ui/components/multichain/network-manager/components/additional-networks-info/additional-networks-info.test.tsx
index 47106d3e87a0..05cc57486b24 100644
--- a/ui/components/multichain/network-manager/components/additional-networks-info/additional-networks-info.test.tsx
+++ b/ui/components/multichain/network-manager/components/additional-networks-info/additional-networks-info.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { screen, fireEvent, act } from '@testing-library/react';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import ZENDESK_URLS from '../../../../../helpers/constants/zendesk-url';
import { AdditionalNetworksInfo } from './additional-networks-info';
diff --git a/ui/components/multichain/network-manager/components/custom-networks/custom-networks.tsx b/ui/components/multichain/network-manager/components/custom-networks/custom-networks.tsx
index 6aa3202b4202..2f1e0d4ba06f 100644
--- a/ui/components/multichain/network-manager/components/custom-networks/custom-networks.tsx
+++ b/ui/components/multichain/network-manager/components/custom-networks/custom-networks.tsx
@@ -1,7 +1,7 @@
import { type MultichainNetworkConfiguration } from '@metamask/multichain-network-controller';
import React, { useCallback, useEffect, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { endTrace, TraceName } from '../../../../../../shared/lib/trace';
import {
convertCaipToHexChainId,
diff --git a/ui/components/multichain/network-manager/hooks/useNetworkItemCallbacks.ts b/ui/components/multichain/network-manager/hooks/useNetworkItemCallbacks.ts
index cbe0dd40a571..5d4cb60b4048 100644
--- a/ui/components/multichain/network-manager/hooks/useNetworkItemCallbacks.ts
+++ b/ui/components/multichain/network-manager/hooks/useNetworkItemCallbacks.ts
@@ -3,7 +3,7 @@ import { EthScope } from '@metamask/keyring-api';
import { type MultichainNetworkConfiguration } from '@metamask/multichain-network-controller';
import { type Hex } from '@metamask/utils';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { CHAIN_ID_PORTFOLIO_LANDING_PAGE_URL_MAP } from '../../../../../shared/constants/network';
import {
convertCaipToHexChainId,
diff --git a/ui/components/multichain/network-manager/hooks/useNetworkManagerState.test.ts b/ui/components/multichain/network-manager/hooks/useNetworkManagerState.test.ts
index 556cd3c44d6e..e06a599986e5 100644
--- a/ui/components/multichain/network-manager/hooks/useNetworkManagerState.test.ts
+++ b/ui/components/multichain/network-manager/hooks/useNetworkManagerState.test.ts
@@ -1,5 +1,5 @@
import { SolScope } from '@metamask/keyring-api';
-import { renderHookWithProviderTyped } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../../../test/lib/render-helpers-navigate';
import { getAllEnabledNetworksForAllNamespaces } from '../../../../selectors';
import { useNetworkManagerInitialTab } from './useNetworkManagerState';
diff --git a/ui/components/multichain/network-manager/network-manager.tsx b/ui/components/multichain/network-manager/network-manager.tsx
index 0afb3d087fb6..3f867eccba86 100644
--- a/ui/components/multichain/network-manager/network-manager.tsx
+++ b/ui/components/multichain/network-manager/network-manager.tsx
@@ -5,12 +5,7 @@ import {
} from '@metamask/network-controller';
import React, { useCallback, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import {
- Route,
- Routes,
- useNavigate,
- useLocation,
-} from 'react-router-dom-v5-compat';
+import { Route, Routes, useNavigate, useLocation } from 'react-router-dom';
import * as URI from 'uri-js';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { useNetworkFormState } from '../../../pages/settings/networks-tab/networks-form/networks-form-state';
diff --git a/ui/components/multichain/nft-item/nft-item.test.js b/ui/components/multichain/nft-item/nft-item.test.js
index b2dc0b7f5ca0..c04d142fa12b 100644
--- a/ui/components/multichain/nft-item/nft-item.test.js
+++ b/ui/components/multichain/nft-item/nft-item.test.js
@@ -3,7 +3,7 @@ import { fireEvent } from '@testing-library/react';
import configureStore from '../../../store/store';
import '@testing-library/jest-dom';
import mockState from '../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { NftItem } from '.';
const store = configureStore(mockState);
diff --git a/ui/components/multichain/notification-detail-address/notification-detail-address.test.tsx b/ui/components/multichain/notification-detail-address/notification-detail-address.test.tsx
index d97692b5e206..6158c2e6ebb9 100644
--- a/ui/components/multichain/notification-detail-address/notification-detail-address.test.tsx
+++ b/ui/components/multichain/notification-detail-address/notification-detail-address.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { screen } from '@testing-library/react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
import configureStore from '../../../store/store';
import { NotificationDetailAddress } from './notification-detail-address';
diff --git a/ui/components/multichain/notification-detail-nft/notification-detail-nft.test.tsx b/ui/components/multichain/notification-detail-nft/notification-detail-nft.test.tsx
index 231d32431d87..d93e2509e673 100644
--- a/ui/components/multichain/notification-detail-nft/notification-detail-nft.test.tsx
+++ b/ui/components/multichain/notification-detail-nft/notification-detail-nft.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { screen } from '@testing-library/react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
import { NotificationDetailNft } from './notification-detail-nft';
diff --git a/ui/components/multichain/notifications-settings-account/notifications-settings-account.test.tsx b/ui/components/multichain/notifications-settings-account/notifications-settings-account.test.tsx
index be7ac97996b7..feb3fdc0c085 100644
--- a/ui/components/multichain/notifications-settings-account/notifications-settings-account.test.tsx
+++ b/ui/components/multichain/notifications-settings-account/notifications-settings-account.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { screen } from '@testing-library/react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import { NotificationsSettingsAccount } from './notifications-settings-account';
diff --git a/ui/components/multichain/notifications-settings-box/notifications-settings-box.test.tsx b/ui/components/multichain/notifications-settings-box/notifications-settings-box.test.tsx
index 68a0f332ec11..addecc26d771 100644
--- a/ui/components/multichain/notifications-settings-box/notifications-settings-box.test.tsx
+++ b/ui/components/multichain/notifications-settings-box/notifications-settings-box.test.tsx
@@ -36,7 +36,7 @@ describe('NotificationsSettingsBox', () => {
it('toggles value on click', () => {
const onToggleMock = jest.fn();
const testId = 'test-id';
- const { container } = render(
+ render(
{
,
);
- console.log(container.innerHTML);
fireEvent.click(screen.getByTestId(`${testId}-toggle-input`));
expect(onToggleMock).toHaveBeenCalledTimes(1);
diff --git a/ui/components/multichain/pages/connections/components/no-connections.test.tsx b/ui/components/multichain/pages/connections/components/no-connections.test.tsx
index f696f11083a3..264d963dfb6d 100644
--- a/ui/components/multichain/pages/connections/components/no-connections.test.tsx
+++ b/ui/components/multichain/pages/connections/components/no-connections.test.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { NoConnectionContent } from './no-connection';
describe('No Connections Content', () => {
diff --git a/ui/components/multichain/pages/connections/connections.test.tsx b/ui/components/multichain/pages/connections/connections.test.tsx
index 857f38ecc84a..f01a07dcf945 100644
--- a/ui/components/multichain/pages/connections/connections.test.tsx
+++ b/ui/components/multichain/pages/connections/connections.test.tsx
@@ -8,9 +8,9 @@ import { Connections } from './connections';
const mockUseNavigate = jest.fn();
const mockUseParams = jest.fn();
const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useParams: () => mockUseParams(),
useLocation: () => mockUseLocation(),
diff --git a/ui/components/multichain/pages/connections/connections.tsx b/ui/components/multichain/pages/connections/connections.tsx
index 5a8f2e735131..767c7b0f2f68 100644
--- a/ui/components/multichain/pages/connections/connections.tsx
+++ b/ui/components/multichain/pages/connections/connections.tsx
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate, useParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useParams } from 'react-router-dom';
import { NonEmptyArray } from '@metamask/utils';
import {
AlignItems,
@@ -68,28 +68,11 @@ import {
} from './components/connections.types';
import { NoConnectionContent } from './components/no-connection';
-type ConnectionsProps = {
- params?: { origin: string };
- navigate?: (
- to: string | number,
- options?: { replace?: boolean; state?: Record
},
- ) => void;
-};
-
-export const Connections = ({
- params,
- navigate: navigateProp,
-}: ConnectionsProps = {}) => {
+export const Connections = () => {
const t = useI18nContext();
const dispatch = useDispatch();
- const navigateHook = useNavigate();
- const urlParamsHook = useParams<{ origin: string }>();
-
- // Use props if provided, otherwise fall back to hooks
- const navigate = (navigateProp || navigateHook) as NonNullable<
- typeof navigateProp
- >;
- const urlParams = params || urlParamsHook;
+ const navigate = useNavigate();
+ const urlParams = useParams<{ origin: string }>();
const [showConnectAccountsModal, setShowConnectAccountsModal] =
useState(false);
diff --git a/ui/components/multichain/pages/gator-permissions/components/permission-group-list-item.test.tsx b/ui/components/multichain/pages/gator-permissions/components/permission-group-list-item.test.tsx
index 5c143d0d659b..9eac4f978793 100644
--- a/ui/components/multichain/pages/gator-permissions/components/permission-group-list-item.test.tsx
+++ b/ui/components/multichain/pages/gator-permissions/components/permission-group-list-item.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { Hex } from '@metamask/utils';
import mockState from '../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import { PermissionGroupListItem } from './permission-group-list-item';
diff --git a/ui/components/multichain/pages/gator-permissions/components/permission-list-item.test.tsx b/ui/components/multichain/pages/gator-permissions/components/permission-list-item.test.tsx
index 199a3e9701e9..fa7df9dce1a9 100644
--- a/ui/components/multichain/pages/gator-permissions/components/permission-list-item.test.tsx
+++ b/ui/components/multichain/pages/gator-permissions/components/permission-list-item.test.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { PermissionListItem } from './permission-list-item';
describe('Permission List Item', () => {
diff --git a/ui/components/multichain/pages/gator-permissions/components/permissions-cell-connection-list-item.test.tsx b/ui/components/multichain/pages/gator-permissions/components/permissions-cell-connection-list-item.test.tsx
index bdd287232807..6e3b961250f7 100644
--- a/ui/components/multichain/pages/gator-permissions/components/permissions-cell-connection-list-item.test.tsx
+++ b/ui/components/multichain/pages/gator-permissions/components/permissions-cell-connection-list-item.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { fireEvent } from '@testing-library/react';
import { CaipChainId } from '@metamask/utils';
import { BoxSpacing, IconName } from '@metamask/design-system-react';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import mockState from '../../../../../../test/data/mock-state.json';
import { PermissionsCellConnectionListItem } from './permissions-cell-connection-list-item';
diff --git a/ui/components/multichain/pages/gator-permissions/components/permissions-cell-tooltip.test.tsx b/ui/components/multichain/pages/gator-permissions/components/permissions-cell-tooltip.test.tsx
index a64e985b9e62..005bd499b8c2 100644
--- a/ui/components/multichain/pages/gator-permissions/components/permissions-cell-tooltip.test.tsx
+++ b/ui/components/multichain/pages/gator-permissions/components/permissions-cell-tooltip.test.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import mockState from '../../../../../../test/data/mock-state.json';
import { PermissionsCellTooltip } from './permissions-cell-tooltip';
diff --git a/ui/components/multichain/pages/gator-permissions/components/permissions-cell.test.tsx b/ui/components/multichain/pages/gator-permissions/components/permissions-cell.test.tsx
index 88e02193675d..3ea62cc6a7a7 100644
--- a/ui/components/multichain/pages/gator-permissions/components/permissions-cell.test.tsx
+++ b/ui/components/multichain/pages/gator-permissions/components/permissions-cell.test.tsx
@@ -10,9 +10,9 @@ import { EvmAndMultichainNetworkConfigurationsWithCaipChainId } from '../../../.
import { PermissionsCell } from './permissions-cell';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/components/multichain/pages/gator-permissions/components/permissions-cell.tsx b/ui/components/multichain/pages/gator-permissions/components/permissions-cell.tsx
index ee8ead43bfd8..a76a6b9c2180 100644
--- a/ui/components/multichain/pages/gator-permissions/components/permissions-cell.tsx
+++ b/ui/components/multichain/pages/gator-permissions/components/permissions-cell.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
Box,
BoxBackgroundColor,
diff --git a/ui/components/multichain/pages/gator-permissions/components/review-gator-permission-item.test.tsx b/ui/components/multichain/pages/gator-permissions/components/review-gator-permission-item.test.tsx
index 5c0a52c1c06c..0374fe22c544 100644
--- a/ui/components/multichain/pages/gator-permissions/components/review-gator-permission-item.test.tsx
+++ b/ui/components/multichain/pages/gator-permissions/components/review-gator-permission-item.test.tsx
@@ -10,7 +10,7 @@ import {
} from '@metamask/gator-permissions-controller';
import { fireEvent } from '@testing-library/react';
import { Settings } from 'luxon';
-import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import mockState from '../../../../../../test/data/mock-state.json';
import { ReviewGatorPermissionItem } from './review-gator-permission-item';
diff --git a/ui/components/multichain/pages/gator-permissions/gator-permissions-page.tsx b/ui/components/multichain/pages/gator-permissions/gator-permissions-page.tsx
index e2f1b5f4a3ca..5846529d74e0 100644
--- a/ui/components/multichain/pages/gator-permissions/gator-permissions-page.tsx
+++ b/ui/components/multichain/pages/gator-permissions/gator-permissions-page.tsx
@@ -1,5 +1,5 @@
import React, { useRef } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { Content, Header, Page } from '../page';
import {
diff --git a/ui/components/multichain/pages/gator-permissions/review-permissions/review-gator-permissions-page.tsx b/ui/components/multichain/pages/gator-permissions/review-permissions/review-gator-permissions-page.tsx
index 7344520d119a..0f073947a3f4 100644
--- a/ui/components/multichain/pages/gator-permissions/review-permissions/review-gator-permissions-page.tsx
+++ b/ui/components/multichain/pages/gator-permissions/review-permissions/review-gator-permissions-page.tsx
@@ -5,7 +5,7 @@ import React, {
useRef,
useState,
} from 'react';
-import { useNavigate, useParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useParams } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { Hex } from '@metamask/utils';
import {
@@ -44,28 +44,15 @@ import {
import { ReviewGatorPermissionItem } from '../components';
import { PREVIOUS_ROUTE } from '../../../../../helpers/constants/routes';
-type ReviewGatorPermissionsPageProps = {
- params?: { chainId: string; permissionGroupName: string; origin?: string };
- navigate?: (
- to: string | number,
- options?: { replace?: boolean; state?: Record },
- ) => void;
-};
-
-export const ReviewGatorPermissionsPage = ({
- params,
- navigate: navigateProp,
-}: ReviewGatorPermissionsPageProps = {}) => {
+export const ReviewGatorPermissionsPage = () => {
const t = useI18nContext();
- const navigateHook = useNavigate();
- const navigate = navigateProp || navigateHook;
- const urlParamsHook = useParams<{
+ const navigate = useNavigate();
+ const { chainId, origin } = useParams<{
chainId: string;
permissionGroupName: string;
origin?: string;
}>();
- const { chainId, origin } = params || urlParamsHook;
const originDecoded = origin ? safeDecodeURIComponent(origin) : undefined;
const [, evmNetworks] = useSelector(
diff --git a/ui/components/multichain/pages/gator-permissions/token-transfer/token-transfer-page.tsx b/ui/components/multichain/pages/gator-permissions/token-transfer/token-transfer-page.tsx
index 3f5835c7f44f..5ea12172d987 100644
--- a/ui/components/multichain/pages/gator-permissions/token-transfer/token-transfer-page.tsx
+++ b/ui/components/multichain/pages/gator-permissions/token-transfer/token-transfer-page.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { useNavigate, useParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useParams } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { Hex } from '@metamask/utils';
import {
@@ -33,25 +33,10 @@ import {
} from '../../../../../selectors/gator-permissions/gator-permissions';
import { getDisplayOrigin, safeDecodeURIComponent } from '../helper';
-type TokenTransferPageProps = {
- params?: { origin?: string };
- navigate?: (
- to: string | number,
- options?: { replace?: boolean; state?: Record },
- ) => void;
-};
-
-export const TokenTransferPage = ({
- params,
- navigate: navigateProp,
-}: TokenTransferPageProps = {}) => {
+export const TokenTransferPage = () => {
const t = useI18nContext();
- const navigateHook = useNavigate();
- const navigate = (navigateProp || navigateHook) as NonNullable<
- typeof navigateProp
- >;
- const urlParamsHook = useParams<{ origin?: string }>();
- const urlParams = params || urlParamsHook;
+ const navigate = useNavigate();
+ const urlParams = useParams<{ origin?: string }>();
const origin = urlParams.origin
? safeDecodeURIComponent(urlParams.origin)
: undefined;
diff --git a/ui/components/multichain/pages/page/page.tsx b/ui/components/multichain/pages/page/page.tsx
index ddf6a6b62721..b6cc14c870aa 100644
--- a/ui/components/multichain/pages/page/page.tsx
+++ b/ui/components/multichain/pages/page/page.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
-import { useLocation } from 'react-router-dom-v5-compat';
+import { useLocation } from 'react-router-dom';
import { Box } from '../../../component-library';
import {
BackgroundColor,
diff --git a/ui/components/multichain/pages/permissions-page/connection-list-item.test.js b/ui/components/multichain/pages/permissions-page/connection-list-item.test.js
index fab896a66235..c925a061c8b8 100644
--- a/ui/components/multichain/pages/permissions-page/connection-list-item.test.js
+++ b/ui/components/multichain/pages/permissions-page/connection-list-item.test.js
@@ -4,7 +4,7 @@ import { fireEvent } from '@testing-library/react';
import configureStore from '../../../../store/store';
import mockState from '../../../../../test/data/mock-state.json';
import { getURLHost } from '../../../../helpers/utils/util';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { getAccountGroupWithInternalAccounts } from '../../../../selectors/multichain-accounts/account-tree';
import { ConnectionListItem } from './connection-list-item';
diff --git a/ui/components/multichain/pages/permissions-page/permissions-page.js b/ui/components/multichain/pages/permissions-page/permissions-page.js
index 03d193e2d6cb..a1c9770f1971 100644
--- a/ui/components/multichain/pages/permissions-page/permissions-page.js
+++ b/ui/components/multichain/pages/permissions-page/permissions-page.js
@@ -1,5 +1,5 @@
import React, { useEffect, useRef, useState } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { isSnapId } from '@metamask/snaps-utils';
import { Content, Header, Page } from '../page';
diff --git a/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx b/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx
index 42759939f3cc..a30544d8d39d 100644
--- a/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx
+++ b/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx
@@ -1,6 +1,6 @@
import React, { useEffect, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate, useParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useParams } from 'react-router-dom';
import {
CaipAccountId,
CaipChainId,
@@ -61,28 +61,11 @@ import { CAIP_FORMATTED_EVM_TEST_CHAINS } from '../../../../../shared/constants/
import { endTrace, trace, TraceName } from '../../../../../shared/lib/trace';
import { SiteCell } from './site-cell/site-cell';
-type ReviewPermissionsProps = {
- params?: { origin: string };
- navigate?: (
- to: string | number,
- options?: { replace?: boolean; state?: Record },
- ) => void;
-};
-
-export const ReviewPermissions = ({
- params,
- navigate: navigateProp,
-}: ReviewPermissionsProps = {}) => {
+export const ReviewPermissions = () => {
const t = useI18nContext();
const dispatch = useDispatch();
- const navigateHook = useNavigate();
- const urlParamsHook = useParams<{ origin: string }>();
-
- // Use props if provided, otherwise fall back to hooks
- const navigate = (navigateProp || navigateHook) as NonNullable<
- typeof navigateProp
- >;
- const urlParams = params || urlParamsHook;
+ const navigate = useNavigate();
+ const urlParams = useParams<{ origin: string }>();
// @ts-expect-error TODO: Fix this type error by handling undefined parameters
const securedOrigin = decodeURIComponent(urlParams.origin);
diff --git a/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell-tooltip.test.js b/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell-tooltip.test.js
index 568e077ad0ed..91f7a7abb7d1 100644
--- a/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell-tooltip.test.js
+++ b/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell-tooltip.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import mockState from '../../../../../../test/data/mock-state.json';
import { SiteCellTooltip } from './site-cell-tooltip';
diff --git a/ui/components/multichain/pages/send/components/network-picker.test.tsx b/ui/components/multichain/pages/send/components/network-picker.test.tsx
index f7610072744b..a55c0221823e 100644
--- a/ui/components/multichain/pages/send/components/network-picker.test.tsx
+++ b/ui/components/multichain/pages/send/components/network-picker.test.tsx
@@ -1,7 +1,8 @@
import React from 'react';
import configureStore from '../../../../../store/store';
import mockState from '../../../../../../test/data/mock-state.json';
-import { fireEvent, renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
+import { fireEvent } from '../../../../../../test/jest';
import { SendPageNetworkPicker } from '.';
const mockToggleNetworkMenu = jest.fn();
diff --git a/ui/components/multichain/pages/send/components/recipient.test.tsx b/ui/components/multichain/pages/send/components/recipient.test.tsx
index 4d4874510d0a..83f59773ea1c 100644
--- a/ui/components/multichain/pages/send/components/recipient.test.tsx
+++ b/ui/components/multichain/pages/send/components/recipient.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import configureStore from '../../../../../store/store';
import mockState from '../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import {
CONFUSING_ENS_ERROR,
ENS_UNKNOWN_ERROR,
diff --git a/ui/components/multichain/pages/send/components/your-accounts.test.tsx b/ui/components/multichain/pages/send/components/your-accounts.test.tsx
index 48bebd93cad9..4b1371b702d3 100644
--- a/ui/components/multichain/pages/send/components/your-accounts.test.tsx
+++ b/ui/components/multichain/pages/send/components/your-accounts.test.tsx
@@ -2,7 +2,8 @@ import React from 'react';
import { BtcAccountType } from '@metamask/keyring-api';
import configureStore from '../../../../../store/store';
import mockState from '../../../../../../test/data/mock-state.json';
-import { fireEvent, renderWithProvider } from '../../../../../../test/jest';
+import { fireEvent } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { createMockInternalAccount } from '../../../../../../test/jest/mocks';
import { MultichainNativeAssets } from '../../../../../../shared/constants/multichain/assets';
import { SendPageYourAccounts } from '.';
diff --git a/ui/components/multichain/pages/send/send.js b/ui/components/multichain/pages/send/send.js
index 05ce1fa7080b..9b93178b028b 100644
--- a/ui/components/multichain/pages/send/send.js
+++ b/ui/components/multichain/pages/send/send.js
@@ -7,7 +7,7 @@ import React, {
} from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import { Tooltip } from 'react-tippy';
import { I18nContext } from '../../../../contexts/i18n';
import {
@@ -96,8 +96,7 @@ export const SendPage = ({
const sendStage = useSelector(getSendStage);
const isSwapAndSend = getIsDraftSwapAndSend(draftTransaction);
- // Use v5-compat hooks as fallback (works in test environment with CompatRouter)
- // In production, props are provided by createV5CompatRoute
+ // Use React Router v6 hooks
const navigateHook = useNavigate();
const locationHook = useLocation();
const navigate = navigateProp || navigateHook;
diff --git a/ui/components/multichain/permission-details-modal/permission-details-modal.test.tsx b/ui/components/multichain/permission-details-modal/permission-details-modal.test.tsx
index 8a43e6072472..fd6f70ede179 100644
--- a/ui/components/multichain/permission-details-modal/permission-details-modal.test.tsx
+++ b/ui/components/multichain/permission-details-modal/permission-details-modal.test.tsx
@@ -1,7 +1,8 @@
import React from 'react';
import configureStore from 'redux-mock-store';
import { EthAccountType, EthMethod, EthScope } from '@metamask/keyring-api';
-import { fireEvent, renderWithProvider } from '../../../../test/jest';
+import { fireEvent } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { mockNetworkState } from '../../../../test/stub/networks';
import { CHAIN_IDS } from '../../../../shared/constants/network';
import { ETH_EOA_METHODS } from '../../../../shared/constants/eth-methods';
diff --git a/ui/components/multichain/permissions-header/permissions-header.tsx b/ui/components/multichain/permissions-header/permissions-header.tsx
index 8eba3829f4b5..543702d8754d 100644
--- a/ui/components/multichain/permissions-header/permissions-header.tsx
+++ b/ui/components/multichain/permissions-header/permissions-header.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
AlignItems,
BackgroundColor,
diff --git a/ui/components/multichain/receive-modal/receive-modal.test.js b/ui/components/multichain/receive-modal/receive-modal.test.js
index 16cc5b1e5f28..99f3ae8d0ee0 100644
--- a/ui/components/multichain/receive-modal/receive-modal.test.js
+++ b/ui/components/multichain/receive-modal/receive-modal.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import { screen } from '@testing-library/react';
import mockState from '../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import { ReceiveModal } from '.';
diff --git a/ui/components/multichain/token-list-item/token-list-item.tsx b/ui/components/multichain/token-list-item/token-list-item.tsx
index 832a9bdde7b6..72c89e24927e 100644
--- a/ui/components/multichain/token-list-item/token-list-item.tsx
+++ b/ui/components/multichain/token-list-item/token-list-item.tsx
@@ -1,6 +1,6 @@
import React, { useContext, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import classnames from 'classnames';
import { getNativeTokenAddress } from '@metamask/assets-controllers';
import { type Hex } from '@metamask/utils';
diff --git a/ui/components/ui/account-list/account-list.test.js b/ui/components/ui/account-list/account-list.test.js
index 30b6d89ac166..83d7fbc34b1f 100644
--- a/ui/components/ui/account-list/account-list.test.js
+++ b/ui/components/ui/account-list/account-list.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import { screen, fireEvent } from '@testing-library/react';
import { BtcAccountType, BtcMethod, BtcScope } from '@metamask/keyring-api';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
import { MultichainNativeAssets } from '../../../../shared/constants/multichain/assets';
diff --git a/ui/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js b/ui/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js
index d04cb9179ec5..3bfbec5f2487 100644
--- a/ui/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js
+++ b/ui/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
import AccountMismatchWarning from './account-mismatch-warning.component';
diff --git a/ui/components/ui/actionable-message/actionable-message.test.js b/ui/components/ui/actionable-message/actionable-message.test.js
index 9c86be37b089..90be697ee3c3 100644
--- a/ui/components/ui/actionable-message/actionable-message.test.js
+++ b/ui/components/ui/actionable-message/actionable-message.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import ActionableMessage from '.';
const createProps = (customProps = {}) => {
diff --git a/ui/components/ui/aggregated-balance/index.test.tsx b/ui/components/ui/aggregated-balance/index.test.tsx
index 623305589225..7680c7e7bb67 100644
--- a/ui/components/ui/aggregated-balance/index.test.tsx
+++ b/ui/components/ui/aggregated-balance/index.test.tsx
@@ -5,7 +5,7 @@ import '@testing-library/jest-dom';
import thunk from 'redux-thunk';
import { SolAccountType, SolMethod, SolScope } from '@metamask/keyring-api';
import { Cryptocurrency } from '@metamask/assets-controllers';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { MultichainNativeAssets } from '../../../../shared/constants/multichain/assets';
import mockState from '../../../../test/data/mock-state.json';
import { SOLANA_WALLET_SNAP_ID } from '../../../../shared/lib/accounts';
diff --git a/ui/components/ui/alert/index.test.js b/ui/components/ui/alert/index.test.js
index 7c5900f811e9..af871dba6500 100644
--- a/ui/components/ui/alert/index.test.js
+++ b/ui/components/ui/alert/index.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import Alert from '.';
describe('Alert', () => {
diff --git a/ui/components/ui/button-group/button-group-component.test.js b/ui/components/ui/button-group/button-group-component.test.js
index 584042491867..ed512514cc7e 100644
--- a/ui/components/ui/button-group/button-group-component.test.js
+++ b/ui/components/ui/button-group/button-group-component.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import ButtonGroup from '.';
describe('ButtonGroup Component', () => {
diff --git a/ui/components/ui/confusable/confusable.component.test.js b/ui/components/ui/confusable/confusable.component.test.js
index c541751c5fed..14f8415d67e3 100644
--- a/ui/components/ui/confusable/confusable.component.test.js
+++ b/ui/components/ui/confusable/confusable.component.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import Confusable from '.';
describe('Confusable component', () => {
diff --git a/ui/components/ui/currency-display/currency-display.component.test.js b/ui/components/ui/currency-display/currency-display.component.test.js
index 897e6e844f9b..24ed170fa4f9 100644
--- a/ui/components/ui/currency-display/currency-display.component.test.js
+++ b/ui/components/ui/currency-display/currency-display.component.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
import CurrencyDisplay from '.';
diff --git a/ui/components/ui/form-combo-field/__snapshots__/form-combo-field.test.tsx.snap b/ui/components/ui/form-combo-field/__snapshots__/form-combo-field.test.tsx.snap
index e41638c1fd28..612c4d0a7a36 100644
--- a/ui/components/ui/form-combo-field/__snapshots__/form-combo-field.test.tsx.snap
+++ b/ui/components/ui/form-combo-field/__snapshots__/form-combo-field.test.tsx.snap
@@ -25,7 +25,7 @@ exports[`FormComboField renders with no options 1`] = `
value="TestValue"
/>
{
/>,
);
- const clearButton = getByLabelText('[clear]');
+ const clearButton = getByLabelText('Clear');
await act(async () => {
fireEvent.click(clearButton);
diff --git a/ui/components/ui/hex-to-decimal/hex-to-decimal.component.test.js b/ui/components/ui/hex-to-decimal/hex-to-decimal.component.test.js
index d8e380318651..8faa5809c533 100644
--- a/ui/components/ui/hex-to-decimal/hex-to-decimal.component.test.js
+++ b/ui/components/ui/hex-to-decimal/hex-to-decimal.component.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import HexToDecimal from '.';
describe('HexToDecimal Component', () => {
diff --git a/ui/components/ui/identicon/identicon.component.test.js b/ui/components/ui/identicon/identicon.component.test.js
index 5fb16e8abc88..dd99018ffa4e 100644
--- a/ui/components/ui/identicon/identicon.component.test.js
+++ b/ui/components/ui/identicon/identicon.component.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { getTokenList } from '../../../selectors';
import { getNftContractsByAddressOnCurrentChain } from '../../../selectors/nft';
import Identicon from '.';
diff --git a/ui/components/ui/list-item/list-item.component.test.js b/ui/components/ui/list-item/list-item.component.test.js
index b0ae94459779..b2987a8f4e0c 100644
--- a/ui/components/ui/list-item/list-item.component.test.js
+++ b/ui/components/ui/list-item/list-item.component.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import Preloader from '../icon/preloader/preloader-icon.component';
import Send from '../icon/send-icon.component';
import ListItem from './list-item.component';
diff --git a/ui/components/ui/menu/menu-item.tsx b/ui/components/ui/menu/menu-item.tsx
index d162194ac44a..ca99c336a89b 100644
--- a/ui/components/ui/menu/menu-item.tsx
+++ b/ui/components/ui/menu/menu-item.tsx
@@ -1,6 +1,6 @@
import React, { memo } from 'react';
import classnames from 'classnames';
-import { Link } from 'react-router-dom-v5-compat';
+import { Link } from 'react-router-dom';
import {
BadgeWrapper,
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 532e555e2ae2..485b0834315d 100644
--- a/ui/components/ui/metafox-logo/metafox-logo.component.test.js
+++ b/ui/components/ui/metafox-logo/metafox-logo.component.test.js
@@ -1,12 +1,12 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import MetaFoxLogo from '.';
jest.mock(
'./horizontal-logo.js',
() =>
function mockRender() {
- return
;
+ return
;
},
);
diff --git a/ui/components/ui/nickname-popover/nickname-popover.component.js b/ui/components/ui/nickname-popover/nickname-popover.component.js
index 74bd3d80bfed..2377ad015017 100644
--- a/ui/components/ui/nickname-popover/nickname-popover.component.js
+++ b/ui/components/ui/nickname-popover/nickname-popover.component.js
@@ -1,7 +1,7 @@
import React, { useCallback, useContext } from 'react';
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { I18nContext } from '../../../contexts/i18n';
import Tooltip from '../tooltip';
import Popover from '../popover';
diff --git a/ui/components/ui/origin-pill/origin-pill.test.tsx b/ui/components/ui/origin-pill/origin-pill.test.tsx
index 13034a6a83e1..3078fda97c3e 100644
--- a/ui/components/ui/origin-pill/origin-pill.test.tsx
+++ b/ui/components/ui/origin-pill/origin-pill.test.tsx
@@ -2,7 +2,7 @@ import { screen } from '@testing-library/dom';
import React from 'react';
import configureMockStore from 'redux-mock-store';
import mockState from '../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import OriginPill from './origin-pill';
describe(' ', () => {
diff --git a/ui/components/ui/page-container/page-container-footer/__snapshots__/page-container-footer.component.test.js.snap b/ui/components/ui/page-container/page-container-footer/__snapshots__/page-container-footer.component.test.js.snap
index 1176b1d49429..d307acdf6aed 100644
--- a/ui/components/ui/page-container/page-container-footer/__snapshots__/page-container-footer.component.test.js.snap
+++ b/ui/components/ui/page-container/page-container-footer/__snapshots__/page-container-footer.component.test.js.snap
@@ -33,13 +33,13 @@ exports[`Page Footer should render a secondary footer inside page-container__foo
class="mm-box mm-text mm-button-base mm-button-base--size-lg mm-button-base--block page-container__footer-button page-container__footer-button__cancel mm-button-secondary mm-text--body-md-medium mm-box--padding-0 mm-box--padding-right-4 mm-box--padding-left-4 mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-text-default mm-box--background-color-background-muted mm-box--rounded-xl"
data-testid="page-container-footer-cancel"
>
- [cancel]
+ Cancel
- [next]
+ Next
{
diff --git a/ui/components/ui/qr-code-view/qr-code-view.test.tsx b/ui/components/ui/qr-code-view/qr-code-view.test.tsx
index b8c70526c5c6..a8163ed5dfef 100644
--- a/ui/components/ui/qr-code-view/qr-code-view.test.tsx
+++ b/ui/components/ui/qr-code-view/qr-code-view.test.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
import QRCodeView from './qr-code-view';
diff --git a/ui/components/ui/site-origin/site-origin.test.js b/ui/components/ui/site-origin/site-origin.test.js
index 6c2b426747c7..a64a1da4d757 100644
--- a/ui/components/ui/site-origin/site-origin.test.js
+++ b/ui/components/ui/site-origin/site-origin.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import SiteOrigin from './site-origin';
describe('SiteOrigin', () => {
diff --git a/ui/components/ui/survey-toast/survey-toast.test.tsx b/ui/components/ui/survey-toast/survey-toast.test.tsx
index e7a454c5f8ab..29be2b8baba4 100644
--- a/ui/components/ui/survey-toast/survey-toast.test.tsx
+++ b/ui/components/ui/survey-toast/survey-toast.test.tsx
@@ -4,7 +4,7 @@ import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { act } from 'react-dom/test-utils';
import fetchWithCache from '../../../../shared/lib/fetch-with-cache';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { MetaMetricsContext } from '../../../contexts/metametrics';
import {
MetaMetricsEventCategory,
diff --git a/ui/components/ui/token-input/token-input.component.test.js b/ui/components/ui/token-input/token-input.component.test.js
index 3708d5407d4d..905f67f87375 100644
--- a/ui/components/ui/token-input/token-input.component.test.js
+++ b/ui/components/ui/token-input/token-input.component.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import { fireEvent } from '@testing-library/react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
import {
CHAIN_IDS,
diff --git a/ui/components/ui/unit-input/unit-input.component.test.js b/ui/components/ui/unit-input/unit-input.component.test.js
index 75018952000a..91aa51cd51ca 100644
--- a/ui/components/ui/unit-input/unit-input.component.test.js
+++ b/ui/components/ui/unit-input/unit-input.component.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import UnitInput from './unit-input.component';
describe('UnitInput Component', () => {
diff --git a/ui/components/ui/update-nickname-popover/update-nickname-popover.test.js b/ui/components/ui/update-nickname-popover/update-nickname-popover.test.js
index d03380694682..70785dae15be 100644
--- a/ui/components/ui/update-nickname-popover/update-nickname-popover.test.js
+++ b/ui/components/ui/update-nickname-popover/update-nickname-popover.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import { screen } from '@testing-library/react';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
import UpdateNicknamePopover from './update-nickname-popover';
diff --git a/ui/contexts/metamask-notifications/metamask-notifications.test.ts b/ui/contexts/metamask-notifications/metamask-notifications.test.ts
index e14c804066aa..723fc7b6fb5a 100644
--- a/ui/contexts/metamask-notifications/metamask-notifications.test.ts
+++ b/ui/contexts/metamask-notifications/metamask-notifications.test.ts
@@ -6,7 +6,7 @@ import * as Selectors from '../../selectors/selectors';
import * as MetamaskDucks from '../../ducks/metamask/metamask';
import * as AuthenticationSelectors from '../../selectors/identity/authentication';
import * as StorageHelpers from '../../../shared/lib/storage-helpers';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import {
useBasicFunctionalityDisableEffect,
useEnableNotificationsByDefaultEffect,
diff --git a/ui/contexts/metametrics.js b/ui/contexts/metametrics.js
index 0460105f7726..38d3131b0f01 100644
--- a/ui/contexts/metametrics.js
+++ b/ui/contexts/metametrics.js
@@ -12,12 +12,7 @@ import React, {
useContext,
} from 'react';
import PropTypes from 'prop-types';
-// NOTE: Mixed v5/v5-compat imports during router migration
-// - useLocation from v5: Works with the v5 HashRouter to detect navigation changes
-// - matchPath from v5-compat: Provides v6 API (reversed args, pattern.path structure)
-// When v6 migration is complete, change both imports to: import { useLocation, matchPath } from 'react-router-dom';
-import { useLocation } from 'react-router-dom';
-import { matchPath } from 'react-router-dom-v5-compat';
+import { useLocation, matchPath } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { omit } from 'lodash';
diff --git a/ui/contexts/navigation-state/index.tsx b/ui/contexts/navigation-state/index.tsx
deleted file mode 100644
index 5d33edb14155..000000000000
--- a/ui/contexts/navigation-state/index.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import React, {
- createContext,
- useContext,
- useState,
- ReactNode,
- Dispatch,
- SetStateAction,
-} from 'react';
-
-// Define types
-type NavState = Record
| null;
-type SetNavState = Dispatch>;
-
-// Create contexts
-const NavStateContext = createContext(null);
-const SetNavStateContext = createContext(() => {
- // noop default
-});
-
-type NavigationStateProviderProps = {
- children: ReactNode;
-};
-
-export const NavigationStateProvider = ({
- children,
-}: NavigationStateProviderProps) => {
- const [navState, setNavState] = useState(null);
-
- return (
-
-
- {children}
-
-
- );
-};
-
-export const useNavState = (): NavState | null => {
- return useContext(NavStateContext);
-};
-
-export const useSetNavState = (): SetNavState => {
- return useContext(SetNavStateContext);
-};
diff --git a/ui/ducks/send/send.test.js b/ui/ducks/send/send.test.js
index 3e4dc6548c8b..7e835940b833 100644
--- a/ui/ducks/send/send.test.js
+++ b/ui/ducks/send/send.test.js
@@ -94,9 +94,9 @@ jest.mock('lodash', () => ({
}));
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/helpers/higher-order-components/authenticated/authenticated-v5-compat.tsx b/ui/helpers/higher-order-components/authenticated/authenticated-v5-compat.tsx
deleted file mode 100644
index 6807c4c05c94..000000000000
--- a/ui/helpers/higher-order-components/authenticated/authenticated-v5-compat.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import React from 'react';
-import { useSelector } from 'react-redux';
-import { Navigate, useLocation } from 'react-router-dom-v5-compat';
-import { UNLOCK_ROUTE, ONBOARDING_ROUTE } from '../../constants/routes';
-
-type AuthenticatedV5CompatProps = {
- children: React.ReactNode;
-};
-
-/**
- * AuthenticatedV5Compat - A wrapper component for v5-compat routes that require authentication
- *
- * This component checks if the user is unlocked and has completed onboarding.
- * If not, it redirects to the appropriate route using v5-compat Navigate.
- *
- * Unlike the v5 Authenticated HOC, this returns the element directly (not wrapped in Route)
- * because v5-compat Routes handle their children differently.
- *
- * @param props - Component props
- * @param props.children - Child components to render when authenticated
- * @returns Navigate component or children
- */
-const AuthenticatedV5Compat = ({ children }: AuthenticatedV5CompatProps) => {
- const location = useLocation();
- const isUnlocked = useSelector(
- (state: { metamask: { isUnlocked: boolean } }) => state.metamask.isUnlocked,
- );
- const completedOnboarding = useSelector(
- (state: { metamask: { completedOnboarding: boolean } }) =>
- state.metamask.completedOnboarding,
- );
-
- if (!completedOnboarding) {
- return ;
- }
-
- if (!isUnlocked) {
- return ;
- }
-
- return <>{children}>;
-};
-
-export default AuthenticatedV5Compat;
diff --git a/ui/helpers/higher-order-components/authenticated/authenticated.component.js b/ui/helpers/higher-order-components/authenticated/authenticated.component.js
index 660b8b79d702..122c6cd6c9c5 100644
--- a/ui/helpers/higher-order-components/authenticated/authenticated.component.js
+++ b/ui/helpers/higher-order-components/authenticated/authenticated.component.js
@@ -1,41 +1,40 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Redirect, Route, useLocation } from 'react-router-dom';
+import { Navigate, useLocation } from 'react-router-dom';
import { UNLOCK_ROUTE, ONBOARDING_ROUTE } from '../../constants/routes';
-const OnboardingRoute = { pathname: ONBOARDING_ROUTE };
-
/**
- * Authenticated - A wrapper component for v5 routes that require authentication
+ * Authenticated - A wrapper component for v6 routes that require authentication
*
* This component checks if the user is unlocked and has completed onboarding.
- * If not, it redirects to the appropriate route using v5 Redirect.
- *
- * This is the original v5 implementation - for v5-compat routes, use AuthenticatedV5Compat instead.
+ * If not, it redirects to the appropriate route using v6 Navigate.
*
* @param {object} props - Component props
- * @returns {React.Element} Route or Redirect component
+ * @param {boolean} props.isUnlocked - Whether the user is unlocked
+ * @param {boolean} props.completedOnboarding - Whether the user has completed onboarding
+ * @param {React.ReactNode} props.children - Child elements to render if authenticated
+ * @returns {React.Element} Children or Navigate component
*/
-export default function Authenticated(props) {
- const { isUnlocked, completedOnboarding } = props;
+export default function Authenticated({
+ isUnlocked,
+ completedOnboarding,
+ children,
+}) {
const location = useLocation();
- switch (true) {
- case isUnlocked && completedOnboarding:
- return ;
- case !completedOnboarding:
- return ;
- default:
- return (
-
- );
+ if (!completedOnboarding) {
+ return ;
}
+
+ if (!isUnlocked) {
+ return ;
+ }
+
+ return children;
}
Authenticated.propTypes = {
isUnlocked: PropTypes.bool,
completedOnboarding: PropTypes.bool,
- path: PropTypes.string,
- component: PropTypes.elementType,
- exact: PropTypes.bool,
+ children: PropTypes.node,
};
diff --git a/ui/helpers/higher-order-components/feature-toggled-route.js b/ui/helpers/higher-order-components/feature-toggled-route.js
index 0591c9a32819..b8371f74aa18 100644
--- a/ui/helpers/higher-order-components/feature-toggled-route.js
+++ b/ui/helpers/higher-order-components/feature-toggled-route.js
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Navigate } from 'react-router-dom-v5-compat';
+import { Navigate } from 'react-router-dom';
export default function FeatureToggledRoute({ flag, redirectRoute, element }) {
if (flag) {
diff --git a/ui/helpers/higher-order-components/initialized/initialized-v5-compat.test.tsx b/ui/helpers/higher-order-components/initialized/initialized-v5-compat.test.tsx
deleted file mode 100644
index 84f0f951f614..000000000000
--- a/ui/helpers/higher-order-components/initialized/initialized-v5-compat.test.tsx
+++ /dev/null
@@ -1,136 +0,0 @@
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import { Provider } from 'react-redux';
-import { MemoryRouter, Routes, Route } from 'react-router-dom-v5-compat';
-import configureStore from 'redux-mock-store';
-import { ONBOARDING_ROUTE } from '../../constants/routes';
-import InitializedV5Compat from './initialized-v5-compat';
-
-jest.mock('../../../ducks/metamask/metamask', () => ({
- getCompletedOnboarding: (state: {
- metamask: { completedOnboarding: boolean };
- }) => state.metamask.completedOnboarding,
-}));
-
-const mockStore = configureStore();
-
-describe('InitializedV5Compat', () => {
- const MockChildComponent = () => (
- Child Component
- );
- const MockOnboardingComponent = () => (
- Onboarding Page
- );
-
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
- it('should render children when onboarding is completed', () => {
- const store = mockStore({
- metamask: {
- completedOnboarding: true,
- },
- });
-
- render(
-
-
-
-
-
-
- }
- />
- }
- />
-
-
- ,
- );
-
- expect(screen.getByTestId('child-component')).toBeInTheDocument();
- expect(screen.getByText('Child Component')).toBeInTheDocument();
- expect(screen.queryByTestId('onboarding')).not.toBeInTheDocument();
- });
-
- it('should redirect to onboarding route when onboarding is not completed', () => {
- const store = mockStore({
- metamask: {
- completedOnboarding: false,
- },
- });
-
- render(
-
-
-
-
-
-
- }
- />
- }
- />
-
-
- ,
- );
-
- expect(screen.queryByTestId('child-component')).not.toBeInTheDocument();
- expect(screen.getByTestId('onboarding')).toBeInTheDocument();
- expect(screen.getByText('Onboarding Page')).toBeInTheDocument();
- });
-
- it('should accept and render complex React node structures as children', () => {
- const store = mockStore({
- metamask: {
- completedOnboarding: true,
- },
- });
-
- const NestedComponent = () => (
- Nested Content
- );
-
- render(
-
-
-
-
-
-
- }
- />
- }
- />
-
-
- ,
- );
-
- expect(screen.getByTestId('parent')).toBeInTheDocument();
- expect(screen.getByTestId('nested')).toBeInTheDocument();
- expect(screen.getByTestId('paragraph')).toBeInTheDocument();
- expect(screen.getByText('Nested Content')).toBeInTheDocument();
- expect(screen.getByText('Some text')).toBeInTheDocument();
- });
-});
diff --git a/ui/helpers/higher-order-components/initialized/initialized-v5-compat.tsx b/ui/helpers/higher-order-components/initialized/initialized-v5-compat.tsx
deleted file mode 100644
index 4ee9460834ab..000000000000
--- a/ui/helpers/higher-order-components/initialized/initialized-v5-compat.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import React from 'react';
-import { useSelector } from 'react-redux';
-import { Navigate } from 'react-router-dom-v5-compat';
-import { getCompletedOnboarding } from '../../../ducks/metamask/metamask';
-import { ONBOARDING_ROUTE } from '../../constants/routes';
-
-type InitializedV5CompatProps = {
- children: React.ReactNode;
-};
-
-/**
- * InitializedV5Compat - A wrapper component for v5-compat routes that require initialization
- *
- * This component checks if the user has completed onboarding.
- * If not, it redirects to the onboarding route using v5-compat Navigate.
- *
- * Unlike the v5 Initialized HOC, this returns the element directly (not wrapped in Route)
- * because v5-compat Routes handle their children differently.
- *
- * @param props - Component props
- * @param props.children - Child components to render when initialized
- * @returns Navigate component or children
- */
-const InitializedV5Compat = ({ children }: InitializedV5CompatProps) => {
- const completedOnboarding = useSelector(getCompletedOnboarding);
-
- if (!completedOnboarding) {
- return ;
- }
-
- return <>{children}>;
-};
-
-export default InitializedV5Compat;
diff --git a/ui/helpers/higher-order-components/initialized/initialized.component.js b/ui/helpers/higher-order-components/initialized/initialized.component.js
index 7ab8ad60dc25..95ded1a8089e 100644
--- a/ui/helpers/higher-order-components/initialized/initialized.component.js
+++ b/ui/helpers/higher-order-components/initialized/initialized.component.js
@@ -1,21 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Redirect, Route } from 'react-router-dom';
+import { Navigate } from 'react-router-dom';
import { ONBOARDING_ROUTE } from '../../constants/routes';
-const onboardingRoute = { pathname: ONBOARDING_ROUTE };
+/**
+ * Initialized - A wrapper component for v6 routes that require onboarding completion
+ *
+ * This component checks if the user has completed onboarding.
+ * If not, it redirects to the onboarding route using v6 Navigate.
+ *
+ * @param {object} props - Component props
+ * @param {boolean} props.completedOnboarding - Whether the user has completed onboarding
+ * @param {React.ReactNode} props.children - Child elements to render if initialized
+ * @returns {React.Element} Children or Navigate component
+ */
+export default function Initialized({ completedOnboarding, children }) {
+ if (!completedOnboarding) {
+ return ;
+ }
-export default function Initialized(props) {
- return props.completedOnboarding ? (
-
- ) : (
-
- );
+ return children;
}
Initialized.propTypes = {
completedOnboarding: PropTypes.bool,
- path: PropTypes.string,
- component: PropTypes.func,
- exact: PropTypes.bool,
+ children: PropTypes.node,
};
diff --git a/ui/helpers/higher-order-components/with-modal-props/with-modal-props.test.js b/ui/helpers/higher-order-components/with-modal-props/with-modal-props.test.js
index cd58d5a061b6..5166e68150e7 100644
--- a/ui/helpers/higher-order-components/with-modal-props/with-modal-props.test.js
+++ b/ui/helpers/higher-order-components/with-modal-props/with-modal-props.test.js
@@ -1,6 +1,6 @@
import configureMockStore from 'redux-mock-store';
import React from 'react';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import withModalProps from './with-modal-props';
const mockState = {
diff --git a/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.test.tsx b/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.test.tsx
index 622b15216df5..f3a6a9db7045 100644
--- a/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.test.tsx
+++ b/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.test.tsx
@@ -1,9 +1,9 @@
import React from 'react';
import { render } from '@testing-library/react';
-import { MemoryRouter } from 'react-router-dom-v5-compat';
+import { MemoryRouter } from 'react-router-dom';
import withRouterHooks, { RouterHooksProps } from './with-router-hooks';
-// Mock the react-router-dom-v5-compat hooks
+// Mock the react-router-dom hooks
const mockUseNavigate = jest.fn();
const mockUseLocation = {
pathname: '/test',
@@ -13,8 +13,8 @@ const mockUseLocation = {
};
const mockUseParams = { id: 'test-id' };
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => mockUseLocation,
useParams: () => mockUseParams,
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 b24ebe4b5005..0ddd8eea45da 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
@@ -1,9 +1,5 @@
import React from 'react';
-import {
- useNavigate,
- useLocation,
- useParams,
-} from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation, useParams } from 'react-router-dom';
// Types for the router hooks
export type RouterHooksProps = {
diff --git a/ui/helpers/utils/i18n-helper.test.js b/ui/helpers/utils/i18n-helper.test.js
index 8bd2b249a2cd..21fd8941fa89 100644
--- a/ui/helpers/utils/i18n-helper.test.js
+++ b/ui/helpers/utils/i18n-helper.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import { captureException } from '../../../shared/lib/sentry';
import { getMessage as getMessageShared } from '../../../shared/modules/i18n';
-import { renderWithProvider } from '../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../test/lib/render-helpers-navigate';
import { getMessage } from './i18n-helper';
jest.mock('../../../shared/modules/i18n');
diff --git a/ui/hooks/accounts/useAccountsOperationsLoadingStates.test.ts b/ui/hooks/accounts/useAccountsOperationsLoadingStates.test.ts
index a78486ceb74a..765cdbf1353b 100644
--- a/ui/hooks/accounts/useAccountsOperationsLoadingStates.test.ts
+++ b/ui/hooks/accounts/useAccountsOperationsLoadingStates.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProviderTyped } from '../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../test/lib/render-helpers-navigate';
import { useAccountsOperationsLoadingStates } from './useAccountsOperationsLoadingStates';
describe('useAccountsOperationsLoadingStates', () => {
diff --git a/ui/hooks/bridge/useBridgeQueryParams.test.ts b/ui/hooks/bridge/useBridgeQueryParams.test.ts
index 8eaa05118a9a..7706b3bce4f1 100644
--- a/ui/hooks/bridge/useBridgeQueryParams.test.ts
+++ b/ui/hooks/bridge/useBridgeQueryParams.test.ts
@@ -1,6 +1,6 @@
import * as bridgeControllerUtils from '@metamask/bridge-controller';
import { BigNumber } from 'ethers';
-import { useLocation } from 'react-router-dom-v5-compat';
+import { useLocation } from 'react-router-dom';
import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { createBridgeMockStore } from '../../../test/data/bridge/mock-bridge-store';
import * as assetUtils from '../../../shared/lib/asset-utils';
@@ -10,7 +10,7 @@ import { mockNetworkState } from '../../../test/stub/networks';
import { useBridgeQueryParams } from './useBridgeQueryParams';
// Helper hook that combines useBridgeQueryParams with useLocation
-// so we can inspect the router state from the same v5-compat context
+// so we can inspect the router state from the same v6 context
const useBridgeQueryParamsWithLocation = () => {
const location = useLocation();
useBridgeQueryParams();
diff --git a/ui/hooks/bridge/useBridgeQueryParams.ts b/ui/hooks/bridge/useBridgeQueryParams.ts
index dde7bda93b01..b5303ae343c0 100644
--- a/ui/hooks/bridge/useBridgeQueryParams.ts
+++ b/ui/hooks/bridge/useBridgeQueryParams.ts
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useCallback, useState, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import {
CaipAssetType,
CaipAssetTypeStruct,
diff --git a/ui/hooks/bridge/useBridgeTxHistoryData.ts b/ui/hooks/bridge/useBridgeTxHistoryData.ts
index d1e090cdcf81..d8fbeba8af67 100644
--- a/ui/hooks/bridge/useBridgeTxHistoryData.ts
+++ b/ui/hooks/bridge/useBridgeTxHistoryData.ts
@@ -4,7 +4,7 @@ import {
type TransactionMeta,
TransactionStatus,
} from '@metamask/transaction-controller';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { StatusTypes } from '@metamask/bridge-controller';
import { isBridgeComplete } from '../../../shared/lib/bridge-status/utils';
import { CROSS_CHAIN_SWAP_TX_DETAILS_ROUTE } from '../../helpers/constants/routes';
diff --git a/ui/hooks/bridge/useBridging.test.ts b/ui/hooks/bridge/useBridging.test.ts
index bc3cbe385462..89cbef6d23ad 100644
--- a/ui/hooks/bridge/useBridging.test.ts
+++ b/ui/hooks/bridge/useBridging.test.ts
@@ -9,9 +9,9 @@ import * as bridgeSelectors from '../../ducks/bridge/selectors';
import useBridging from './useBridging';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/hooks/bridge/useBridging.ts b/ui/hooks/bridge/useBridging.ts
index 66bc824c2023..19d9d5101c29 100644
--- a/ui/hooks/bridge/useBridging.ts
+++ b/ui/hooks/bridge/useBridging.ts
@@ -1,6 +1,6 @@
import { useCallback, useContext } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
type BridgeAsset,
formatChainIdToCaip,
diff --git a/ui/hooks/bridge/useCountdownTimer.test.ts b/ui/hooks/bridge/useCountdownTimer.test.ts
index 843b71816cfd..8548c47c3833 100644
--- a/ui/hooks/bridge/useCountdownTimer.test.ts
+++ b/ui/hooks/bridge/useCountdownTimer.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { createBridgeMockStore } from '../../../test/data/bridge/mock-bridge-store';
import { flushPromises } from '../../../test/lib/timer-helpers';
import { useCountdownTimer } from './useCountdownTimer';
diff --git a/ui/hooks/bridge/useRewards.test.ts b/ui/hooks/bridge/useRewards.test.ts
index 8ed865bc4c4a..50eebd4be657 100644
--- a/ui/hooks/bridge/useRewards.test.ts
+++ b/ui/hooks/bridge/useRewards.test.ts
@@ -3,7 +3,7 @@ import { act } from '@testing-library/react-hooks';
import log from 'loglevel';
import { useSelector } from 'react-redux';
import { selectBridgeQuotes } from '@metamask/bridge-controller';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { createMockInternalAccount } from '../../../test/jest/mocks';
import {
getRewardsHasAccountOptedIn,
diff --git a/ui/hooks/bridge/useTokenAlerts.test.ts b/ui/hooks/bridge/useTokenAlerts.test.ts
index 4b011028bdc4..1992a9477cb6 100644
--- a/ui/hooks/bridge/useTokenAlerts.test.ts
+++ b/ui/hooks/bridge/useTokenAlerts.test.ts
@@ -1,5 +1,5 @@
import { ChainId, formatChainIdToCaip } from '@metamask/bridge-controller';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { CHAIN_IDS } from '../../../shared/constants/network';
import { MultichainNetworks } from '../../../shared/constants/multichain/networks';
import { createBridgeMockStore } from '../../../test/data/bridge/mock-bridge-store';
diff --git a/ui/hooks/bridge/useTokensWithFiltering.test.ts b/ui/hooks/bridge/useTokensWithFiltering.test.ts
index ba85c2a9d2a5..4597e8d74c24 100644
--- a/ui/hooks/bridge/useTokensWithFiltering.test.ts
+++ b/ui/hooks/bridge/useTokensWithFiltering.test.ts
@@ -2,7 +2,7 @@ import { getNativeAssetForChainId } from '@metamask/bridge-controller';
import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS } from '@metamask/multichain-network-controller';
import { SolScope } from '@metamask/keyring-api';
import { MultichainNetwork } from '@metamask/multichain-transactions-controller';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { createBridgeMockStore } from '../../../test/data/bridge/mock-bridge-store';
import { STATIC_MAINNET_TOKEN_LIST } from '../../../shared/constants/tokens';
import { CHAIN_IDS } from '../../../shared/constants/network';
diff --git a/ui/hooks/defi/useDeFiPolling.test.ts b/ui/hooks/defi/useDeFiPolling.test.ts
index eb9f6a5acaea..090d49c6f022 100644
--- a/ui/hooks/defi/useDeFiPolling.test.ts
+++ b/ui/hooks/defi/useDeFiPolling.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import useDeFiPolling from './useDeFiPolling';
import { deFiStartPolling, deFiStopPolling } from './defiPollingActions';
diff --git a/ui/hooks/identity/useAccountSyncing/useAccountSyncing.test.tsx b/ui/hooks/identity/useAccountSyncing/useAccountSyncing.test.tsx
index 8b9f2cbc13d0..698b814f31d5 100644
--- a/ui/hooks/identity/useAccountSyncing/useAccountSyncing.test.tsx
+++ b/ui/hooks/identity/useAccountSyncing/useAccountSyncing.test.tsx
@@ -1,5 +1,5 @@
import { waitFor } from '@testing-library/react';
-import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate';
import * as actions from '../../../store/actions';
import { MetamaskIdentityProvider } from '../../../contexts/identity';
import {
diff --git a/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx b/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx
index cdbca570c477..04db88c78341 100644
--- a/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx
+++ b/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx
@@ -1,5 +1,5 @@
import { act } from '@testing-library/react-hooks';
-import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate';
import * as actions from '../../../store/actions';
import { MetamaskIdentityProvider } from '../../../contexts/identity';
import { useAutoSignIn } from './useAutoSignIn';
diff --git a/ui/hooks/identity/useAuthentication/useAutoSignOut.test.tsx b/ui/hooks/identity/useAuthentication/useAutoSignOut.test.tsx
index 6e23bd2a36cb..f899b01b427f 100644
--- a/ui/hooks/identity/useAuthentication/useAutoSignOut.test.tsx
+++ b/ui/hooks/identity/useAuthentication/useAutoSignOut.test.tsx
@@ -1,5 +1,5 @@
import { act } from '@testing-library/react-hooks';
-import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate';
import * as actions from '../../../store/actions';
import { MetamaskIdentityProvider } from '../../../contexts/identity';
import { useAutoSignOut } from './useAutoSignOut';
diff --git a/ui/hooks/identity/useAuthentication/useSignIn.test.tsx b/ui/hooks/identity/useAuthentication/useSignIn.test.tsx
index 8bbdc2650022..d380af19d935 100644
--- a/ui/hooks/identity/useAuthentication/useSignIn.test.tsx
+++ b/ui/hooks/identity/useAuthentication/useSignIn.test.tsx
@@ -1,5 +1,5 @@
import { act } from '@testing-library/react-hooks';
-import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate';
import * as actions from '../../../store/actions';
import { MetamaskIdentityProvider } from '../../../contexts/identity';
import { useSignIn } from './useSignIn';
diff --git a/ui/hooks/identity/useAuthentication/useSignOut.test.tsx b/ui/hooks/identity/useAuthentication/useSignOut.test.tsx
index deb1f9dec269..3e6f6e817550 100644
--- a/ui/hooks/identity/useAuthentication/useSignOut.test.tsx
+++ b/ui/hooks/identity/useAuthentication/useSignOut.test.tsx
@@ -1,5 +1,5 @@
import { act } from '@testing-library/react-hooks';
-import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate';
import * as actions from '../../../store/actions';
import { MetamaskIdentityProvider } from '../../../contexts/identity';
import { useSignOut } from './useSignOut';
diff --git a/ui/hooks/identity/useBackupAndSync/useBackupAndSync.test.tsx b/ui/hooks/identity/useBackupAndSync/useBackupAndSync.test.tsx
index bb434065e0eb..3e2c8e3363ce 100644
--- a/ui/hooks/identity/useBackupAndSync/useBackupAndSync.test.tsx
+++ b/ui/hooks/identity/useBackupAndSync/useBackupAndSync.test.tsx
@@ -1,6 +1,6 @@
import { act } from '@testing-library/react-hooks';
import { BACKUPANDSYNC_FEATURES } from '@metamask/profile-sync-controller/user-storage';
-import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate';
import { MetamaskIdentityProvider } from '../../../contexts/identity';
import * as actions from '../../../store/actions';
import { useBackupAndSync } from './useBackupAndSync';
diff --git a/ui/hooks/identity/useContactSyncing/useContactSyncing.test.tsx b/ui/hooks/identity/useContactSyncing/useContactSyncing.test.tsx
index c3a4fbf31f04..93ecbc1056d1 100644
--- a/ui/hooks/identity/useContactSyncing/useContactSyncing.test.tsx
+++ b/ui/hooks/identity/useContactSyncing/useContactSyncing.test.tsx
@@ -1,5 +1,5 @@
import { waitFor } from '@testing-library/react';
-import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate';
import * as actions from '../../../store/actions';
import { MetamaskIdentityProvider } from '../../../contexts/identity';
import {
diff --git a/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx b/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx
index 7e5963044706..f3a9bc21b687 100644
--- a/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx
+++ b/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx
@@ -1,7 +1,7 @@
import { waitFor } from '@testing-library/react';
import * as ActionsModule from '../../store/actions';
import * as NotificationSelectorsModule from '../../selectors/metamask-notifications/metamask-notifications';
-import { renderHookWithProviderTyped } from '../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../test/lib/render-helpers-navigate';
import {
useSwitchFeatureAnnouncementsChange,
useSwitchAccountNotificationsChange,
diff --git a/ui/hooks/multi-srp/useHdKeyringsWithSnapAccounts.test.ts b/ui/hooks/multi-srp/useHdKeyringsWithSnapAccounts.test.ts
index 9b029b9ca518..2c824bb0cccd 100644
--- a/ui/hooks/multi-srp/useHdKeyringsWithSnapAccounts.test.ts
+++ b/ui/hooks/multi-srp/useHdKeyringsWithSnapAccounts.test.ts
@@ -1,5 +1,5 @@
import { KeyringTypes } from '@metamask/keyring-controller';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { getMetaMaskHdKeyrings } from '../../selectors';
import { getInternalAccounts } from '../../selectors/accounts';
import { createMockInternalAccount } from '../../../test/jest/mocks';
diff --git a/ui/hooks/rewards/useCandidateSubscriptionId.test.ts b/ui/hooks/rewards/useCandidateSubscriptionId.test.ts
index ed392f96d0d8..6fb40f2931fc 100644
--- a/ui/hooks/rewards/useCandidateSubscriptionId.test.ts
+++ b/ui/hooks/rewards/useCandidateSubscriptionId.test.ts
@@ -1,7 +1,7 @@
import { act } from '@testing-library/react-hooks';
import { waitFor } from '@testing-library/react';
import log from 'loglevel';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { useCandidateSubscriptionId } from './useCandidateSubscriptionId';
// Mock store actions used by the hook
diff --git a/ui/hooks/rewards/useGeoRewardsMetadata.test.ts b/ui/hooks/rewards/useGeoRewardsMetadata.test.ts
index 846a1f9b0594..d69727aa3913 100644
--- a/ui/hooks/rewards/useGeoRewardsMetadata.test.ts
+++ b/ui/hooks/rewards/useGeoRewardsMetadata.test.ts
@@ -1,6 +1,6 @@
import { act } from '@testing-library/react-hooks';
import { waitFor } from '@testing-library/react';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { RewardsGeoMetadata } from '../../../shared/types/rewards';
import { useGeoRewardsMetadata } from './useGeoRewardsMetadata';
diff --git a/ui/hooks/rewards/useLinkAccountAddress.test.tsx b/ui/hooks/rewards/useLinkAccountAddress.test.tsx
index a6dc281783d4..9d8690ee2a0b 100644
--- a/ui/hooks/rewards/useLinkAccountAddress.test.tsx
+++ b/ui/hooks/rewards/useLinkAccountAddress.test.tsx
@@ -1,7 +1,7 @@
import { act } from '@testing-library/react-hooks';
import React from 'react';
import { InternalAccount } from '@metamask/keyring-internal-api';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { MetaMetricsContext } from '../../contexts/metametrics';
import { createMockInternalAccount } from '../../../test/jest/mocks';
import {
diff --git a/ui/hooks/rewards/useLinkAccountGroup.test.tsx b/ui/hooks/rewards/useLinkAccountGroup.test.tsx
index f529a8e21978..94414a5b461e 100644
--- a/ui/hooks/rewards/useLinkAccountGroup.test.tsx
+++ b/ui/hooks/rewards/useLinkAccountGroup.test.tsx
@@ -8,7 +8,7 @@ import {
AccountWalletStatus,
} from '@metamask/account-api';
import { InternalAccount } from '@metamask/keyring-internal-api';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { MetaMetricsContext } from '../../contexts/metametrics';
import { createMockInternalAccount } from '../../../test/jest/mocks';
import { createMockMultichainAccountsState } from '../../selectors/multichain-accounts/test-utils';
diff --git a/ui/hooks/rewards/useOptIn.test.tsx b/ui/hooks/rewards/useOptIn.test.tsx
index 5a2bce527fa1..14a601838ffc 100644
--- a/ui/hooks/rewards/useOptIn.test.tsx
+++ b/ui/hooks/rewards/useOptIn.test.tsx
@@ -1,7 +1,7 @@
import { act } from '@testing-library/react-hooks';
import React from 'react';
import { InternalAccount } from '@metamask/keyring-internal-api';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { MetaMetricsContext } from '../../contexts/metametrics';
import {
MetaMetricsEventName,
diff --git a/ui/hooks/rewards/useSeasonStatus.test.ts b/ui/hooks/rewards/useSeasonStatus.test.ts
index a349ff7cae84..fd46af055aff 100644
--- a/ui/hooks/rewards/useSeasonStatus.test.ts
+++ b/ui/hooks/rewards/useSeasonStatus.test.ts
@@ -1,6 +1,6 @@
import { act } from '@testing-library/react-hooks';
import { waitFor } from '@testing-library/react';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import {
SeasonDtoState,
SeasonStatusState,
diff --git a/ui/hooks/rewards/useValidateReferralCode.test.tsx b/ui/hooks/rewards/useValidateReferralCode.test.tsx
index 9b3f88efc9ee..52be14c37166 100644
--- a/ui/hooks/rewards/useValidateReferralCode.test.tsx
+++ b/ui/hooks/rewards/useValidateReferralCode.test.tsx
@@ -1,6 +1,6 @@
import { act } from '@testing-library/react-hooks';
import { waitFor } from '@testing-library/react';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import { useValidateReferralCode } from './useValidateReferralCode';
jest.useFakeTimers();
diff --git a/ui/hooks/shield/useClaimState.ts b/ui/hooks/shield/useClaimState.ts
index 7b743534cd00..ed1e5d576f3e 100644
--- a/ui/hooks/shield/useClaimState.ts
+++ b/ui/hooks/shield/useClaimState.ts
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';
-import { useLocation } from 'react-router-dom-v5-compat';
+import { useLocation } from 'react-router-dom';
import { Attachment as ClaimAttachment } from '@metamask/claims-controller';
import { useClaims } from '../../contexts/claims/claims';
import { generateClaimSignature } from '../../store/actions';
diff --git a/ui/hooks/snaps/useSnapNameResolution.test.ts b/ui/hooks/snaps/useSnapNameResolution.test.ts
index a19048f4ccc5..8f125539b789 100644
--- a/ui/hooks/snaps/useSnapNameResolution.test.ts
+++ b/ui/hooks/snaps/useSnapNameResolution.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import baseMockState from '../../../test/data/mock-state.json';
import { useSnapNameResolution } from './useSnapNameResolution';
diff --git a/ui/hooks/snaps/useSnapNavigation.ts b/ui/hooks/snaps/useSnapNavigation.ts
index 6a6230925cdc..86261742fef1 100644
--- a/ui/hooks/snaps/useSnapNavigation.ts
+++ b/ui/hooks/snaps/useSnapNavigation.ts
@@ -1,5 +1,5 @@
import { useCallback, useMemo } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { parseMetaMaskUrl } from '@metamask/snaps-utils';
import { getSnapRoute } from '../../helpers/utils/util';
diff --git a/ui/hooks/subscription/useAddFundTrigger.test.ts b/ui/hooks/subscription/useAddFundTrigger.test.ts
index 40d41ecef312..5e1a1d8e6b2b 100644
--- a/ui/hooks/subscription/useAddFundTrigger.test.ts
+++ b/ui/hooks/subscription/useAddFundTrigger.test.ts
@@ -9,7 +9,7 @@ import {
} from '@metamask/subscription-controller';
import { cloneDeep } from 'lodash';
import { flushPromises } from '../../../test/lib/timer-helpers';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import mockState from '../../../test/data/mock-state.json';
import * as actions from '../../store/actions';
import { MINUTE } from '../../../shared/constants/time';
diff --git a/ui/hooks/subscription/useHandlePayment.ts b/ui/hooks/subscription/useHandlePayment.ts
index e9d733e3325a..e3ec02aed71e 100644
--- a/ui/hooks/subscription/useHandlePayment.ts
+++ b/ui/hooks/subscription/useHandlePayment.ts
@@ -1,5 +1,5 @@
import { useCallback, useMemo } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
CRYPTO_PAYMENT_METHOD_ERRORS,
PAYMENT_TYPES,
diff --git a/ui/hooks/subscription/useSubscription.ts b/ui/hooks/subscription/useSubscription.ts
index cdc9c3f8880c..88da96d78784 100644
--- a/ui/hooks/subscription/useSubscription.ts
+++ b/ui/hooks/subscription/useSubscription.ts
@@ -12,7 +12,7 @@ import {
ModalType,
} from '@metamask/subscription-controller';
import log from 'loglevel';
-import { useLocation, useNavigate } from 'react-router-dom-v5-compat';
+import { useLocation, useNavigate } from 'react-router-dom';
import {
TransactionParams,
TransactionType,
diff --git a/ui/hooks/subscription/useSubscriptionPricing.test.ts b/ui/hooks/subscription/useSubscriptionPricing.test.ts
index 8d2baf5def85..ffd2fab7cc70 100644
--- a/ui/hooks/subscription/useSubscriptionPricing.test.ts
+++ b/ui/hooks/subscription/useSubscriptionPricing.test.ts
@@ -6,7 +6,7 @@ import {
ProductType,
PaymentType,
} from '@metamask/subscription-controller';
-import { renderHookWithProvider } from '../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate';
import baseMockState from '../../../test/data/mock-state.json';
import {
useSubscriptionPricing,
diff --git a/ui/hooks/useAlerts.test.ts b/ui/hooks/useAlerts.test.ts
index a2db52fc3052..f8254f711c9a 100644
--- a/ui/hooks/useAlerts.test.ts
+++ b/ui/hooks/useAlerts.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import {
Alert,
AlertSeverity,
diff --git a/ui/hooks/useCurrencyRatePolling.test.ts b/ui/hooks/useCurrencyRatePolling.test.ts
index 51958472a443..a9c4cab778bb 100644
--- a/ui/hooks/useCurrencyRatePolling.test.ts
+++ b/ui/hooks/useCurrencyRatePolling.test.ts
@@ -1,6 +1,6 @@
import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS } from '@metamask/multichain-network-controller';
import { BtcScope } from '@metamask/keyring-api';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import { getOriginalNativeTokenSymbol } from '../helpers/utils/isOriginalNativeTokenSymbol';
import {
currencyRateStartPolling,
diff --git a/ui/hooks/useCurrentAsset.js b/ui/hooks/useCurrentAsset.js
index c5e8cbd086d9..4b593190e5a9 100644
--- a/ui/hooks/useCurrentAsset.js
+++ b/ui/hooks/useCurrentAsset.js
@@ -1,5 +1,5 @@
import { useSelector } from 'react-redux';
-import { useMatch } from 'react-router-dom-v5-compat';
+import { useMatch } from 'react-router-dom';
import { getTokens } from '../ducks/metamask/metamask';
import { getCurrentChainId } from '../../shared/modules/selectors/networks';
import { ASSET_ROUTE } from '../helpers/constants/routes';
diff --git a/ui/hooks/useDecodedTransactionData.test.ts b/ui/hooks/useDecodedTransactionData.test.ts
index a608ca386983..01249c6948ef 100644
--- a/ui/hooks/useDecodedTransactionData.test.ts
+++ b/ui/hooks/useDecodedTransactionData.test.ts
@@ -7,7 +7,7 @@ import {
import { Hex } from '@metamask/utils';
import { renderHook } from '@testing-library/react-hooks';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import { decodeTransactionData } from '../store/actions';
import {
TRANSACTION_DATA_UNISWAP,
diff --git a/ui/hooks/useDisplayName.test.ts b/ui/hooks/useDisplayName.test.ts
index d6384861b95f..566ed25fe0a8 100644
--- a/ui/hooks/useDisplayName.test.ts
+++ b/ui/hooks/useDisplayName.test.ts
@@ -7,7 +7,7 @@ import {
FIRST_PARTY_CONTRACT_NAMES,
} from '../../shared/constants/first-party-contracts';
import mockState from '../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import { getDomainResolutions } from '../ducks/domains';
import { IconName } from '../components/component-library';
import { IconColor } from '../helpers/constants/design-system';
diff --git a/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts b/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts
index 5d12650cc08e..64a7a931a99e 100644
--- a/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts
+++ b/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts
@@ -1,6 +1,6 @@
import { waitFor } from '@testing-library/react';
import { CaipChainId, Hex } from '@metamask/utils';
-import { renderHookWithProviderTyped } from '../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../test/lib/render-helpers-navigate';
import * as SelectorsModule from '../selectors/selectors';
import * as MultichainSelectorsModule from '../selectors/multichain';
import * as IsOriginalNativeTokenSymbolModule from '../helpers/utils/isOriginalNativeTokenSymbol';
diff --git a/ui/hooks/useIsOriginalTokenSymbol.test.js b/ui/hooks/useIsOriginalTokenSymbol.test.js
index 136481b9b968..f6256338fea6 100644
--- a/ui/hooks/useIsOriginalTokenSymbol.test.js
+++ b/ui/hooks/useIsOriginalTokenSymbol.test.js
@@ -2,7 +2,7 @@ import { act } from '@testing-library/react-hooks';
import * as actions from '../store/actions';
import mockState from '../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import { useIsOriginalTokenSymbol } from './useIsOriginalTokenSymbol';
// Mocking the getTokenSymbol function
diff --git a/ui/hooks/useMultiPolling.test.ts b/ui/hooks/useMultiPolling.test.ts
index 865221eeac99..99a1446eaf20 100644
--- a/ui/hooks/useMultiPolling.test.ts
+++ b/ui/hooks/useMultiPolling.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import useMultiPolling from './useMultiPolling';
describe('useMultiPolling', () => {
diff --git a/ui/hooks/useMultichainAccountsIntroModal.test.ts b/ui/hooks/useMultichainAccountsIntroModal.test.ts
index b31b0659f9cc..67d31699da55 100644
--- a/ui/hooks/useMultichainAccountsIntroModal.test.ts
+++ b/ui/hooks/useMultichainAccountsIntroModal.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import {
useMultichainAccountsIntroModal,
BIP44_ACCOUNTS_INTRODUCTION_VERSION,
diff --git a/ui/hooks/useMultichainBalances.test.ts b/ui/hooks/useMultichainBalances.test.ts
index 8deedbcb20fa..9dc738207512 100644
--- a/ui/hooks/useMultichainBalances.test.ts
+++ b/ui/hooks/useMultichainBalances.test.ts
@@ -1,5 +1,5 @@
import { createBridgeMockStore } from '../../test/data/bridge/mock-bridge-store';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import { useMultichainBalances } from './useMultichainBalances';
describe('useMultichainBalances', () => {
diff --git a/ui/hooks/useMultichainSelector.test.ts b/ui/hooks/useMultichainSelector.test.ts
index f04fef64783a..74c46445d8cc 100644
--- a/ui/hooks/useMultichainSelector.test.ts
+++ b/ui/hooks/useMultichainSelector.test.ts
@@ -1,6 +1,6 @@
import { InternalAccount } from '@metamask/keyring-internal-api';
import { createMockInternalAccount } from '../../test/jest/mocks';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import { getSelectedNetworkClientId } from '../../shared/modules/selectors/networks';
import { MultichainState, getMultichainIsEvm } from '../selectors/multichain';
import { CHAIN_IDS } from '../../shared/constants/network';
diff --git a/ui/hooks/useNetworkConnectionBanner.test.ts b/ui/hooks/useNetworkConnectionBanner.test.ts
index 147f0c594efd..0e009a3b50fd 100644
--- a/ui/hooks/useNetworkConnectionBanner.test.ts
+++ b/ui/hooks/useNetworkConnectionBanner.test.ts
@@ -1,6 +1,6 @@
import { act } from '@testing-library/react';
import { RpcEndpointType } from '@metamask/network-controller';
-import { renderHookWithProviderTyped } from '../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../test/lib/render-helpers-navigate';
import { selectFirstUnavailableEvmNetwork } from '../selectors/multichain/networks';
import { getNetworkConnectionBanner } from '../selectors/selectors';
import { updateNetworkConnectionBanner } from '../store/actions';
diff --git a/ui/hooks/usePolling.test.js b/ui/hooks/usePolling.test.js
index a556bb86be54..a08ea872bd84 100644
--- a/ui/hooks/usePolling.test.js
+++ b/ui/hooks/usePolling.test.js
@@ -1,5 +1,5 @@
import { cleanup } from '@testing-library/react-hooks';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import usePolling from './usePolling';
describe('usePolling', () => {
diff --git a/ui/hooks/useSafeNavigation.test.ts b/ui/hooks/useSafeNavigation.test.ts
deleted file mode 100644
index 3d5fccab2f4c..000000000000
--- a/ui/hooks/useSafeNavigation.test.ts
+++ /dev/null
@@ -1,435 +0,0 @@
-import { renderHook, act } from '@testing-library/react-hooks';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
-import { useSetNavState } from '../contexts/navigation-state';
-import { useSafeNavigation } from './useSafeNavigation';
-
-// Mock dependencies
-jest.mock('react-router-dom-v5-compat', () => ({
- useNavigate: jest.fn(),
- useLocation: jest.fn(),
-}));
-
-jest.mock('../contexts/navigation-state', () => ({
- useSetNavState: jest.fn(),
-}));
-
-describe('useSafeNavigation', () => {
- let mockDefaultNavigate: jest.Mock;
- let mockSetNavState: jest.Mock;
- let mockLocation: { pathname: string };
-
- beforeEach(() => {
- jest.useFakeTimers();
- mockDefaultNavigate = jest.fn();
- mockSetNavState = jest.fn();
- mockLocation = { pathname: '/test' };
-
- (useNavigate as jest.Mock).mockReturnValue(mockDefaultNavigate);
- (useSetNavState as jest.Mock).mockReturnValue(mockSetNavState);
- (useLocation as jest.Mock).mockReturnValue(mockLocation);
- });
-
- afterEach(() => {
- jest.clearAllMocks();
- jest.useRealTimers();
- });
-
- describe('with defaultNavigate', () => {
- it('should navigate without state and clean up', async () => {
- const { result } = renderHook(() => useSafeNavigation());
-
- act(() => {
- result.current.navigate('/destination');
- });
-
- // Should set state to null (no state provided)
- expect(mockSetNavState).toHaveBeenCalledWith(null);
-
- // Should call default navigate
- expect(mockDefaultNavigate).toHaveBeenCalledWith('/destination', {
- replace: false,
- state: undefined,
- });
-
- // Should schedule cleanup
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockSetNavState).toHaveBeenCalledTimes(2);
- expect(mockSetNavState).toHaveBeenLastCalledWith(null);
- });
-
- it('should navigate with state and clean up after 100ms', async () => {
- const { result } = renderHook(() => useSafeNavigation());
- const testState = { stayOnHomePage: true };
-
- act(() => {
- result.current.navigate('/destination', { state: testState });
- });
-
- // Should set state immediately
- expect(mockSetNavState).toHaveBeenCalledWith(testState);
-
- // Should call default navigate with state
- expect(mockDefaultNavigate).toHaveBeenCalledWith('/destination', {
- replace: false,
- state: testState,
- });
-
- // State should not be cleared immediately
- expect(mockSetNavState).toHaveBeenCalledTimes(1);
-
- // After 100ms, state should be cleared
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockSetNavState).toHaveBeenCalledTimes(2);
- expect(mockSetNavState).toHaveBeenLastCalledWith(null);
- });
-
- it('should handle replace option', () => {
- const { result } = renderHook(() => useSafeNavigation());
-
- act(() => {
- result.current.navigate('/destination', { replace: true });
- });
-
- expect(mockDefaultNavigate).toHaveBeenCalledWith('/destination', {
- replace: true,
- state: undefined,
- });
- });
- });
-
- describe('with customNavigate', () => {
- it('should navigate without state and clean up (bug fix)', async () => {
- const mockCustomNavigate = jest.fn();
- const { result } = renderHook(() =>
- useSafeNavigation(mockCustomNavigate),
- );
-
- act(() => {
- result.current.navigate('/destination');
- });
-
- // Should set state to null
- expect(mockSetNavState).toHaveBeenCalledWith(null);
-
- // Should call custom navigate
- expect(mockCustomNavigate).toHaveBeenCalledWith(
- '/destination',
- undefined,
- );
-
- // Should NOT call default navigate
- expect(mockDefaultNavigate).not.toHaveBeenCalled();
-
- // CRITICAL: Cleanup should still happen after 100ms (this is the bug fix)
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockSetNavState).toHaveBeenCalledTimes(2);
- expect(mockSetNavState).toHaveBeenLastCalledWith(null);
- });
-
- it('should navigate with state and clean up after 100ms (bug fix)', async () => {
- const mockCustomNavigate = jest.fn();
- const { result } = renderHook(() =>
- useSafeNavigation(mockCustomNavigate),
- );
- const testState = { stayOnHomePage: true };
-
- act(() => {
- result.current.navigate('/destination', { state: testState });
- });
-
- // Should set state immediately
- expect(mockSetNavState).toHaveBeenCalledWith(testState);
-
- // Should call custom navigate with state
- expect(mockCustomNavigate).toHaveBeenCalledWith('/destination', {
- state: testState,
- });
-
- // Should NOT call default navigate
- expect(mockDefaultNavigate).not.toHaveBeenCalled();
-
- // State should not be cleared immediately
- expect(mockSetNavState).toHaveBeenCalledTimes(1);
-
- // CRITICAL: After 100ms, state MUST be cleared (this is the bug fix)
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockSetNavState).toHaveBeenCalledTimes(2);
- expect(mockSetNavState).toHaveBeenLastCalledWith(null);
- });
-
- it('should handle replace option with custom navigate', () => {
- const mockCustomNavigate = jest.fn();
- const { result } = renderHook(() =>
- useSafeNavigation(mockCustomNavigate),
- );
-
- act(() => {
- result.current.navigate('/destination', { replace: true });
- });
-
- expect(mockCustomNavigate).toHaveBeenCalledWith('/destination', {
- replace: true,
- });
-
- // Cleanup should still happen
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockSetNavState).toHaveBeenLastCalledWith(null);
- });
-
- it('should handle both state and replace options with custom navigate', () => {
- const mockCustomNavigate = jest.fn();
- const { result } = renderHook(() =>
- useSafeNavigation(mockCustomNavigate),
- );
- const testState = { foo: 'bar' };
-
- act(() => {
- result.current.navigate('/destination', {
- state: testState,
- replace: true,
- });
- });
-
- expect(mockSetNavState).toHaveBeenCalledWith(testState);
- expect(mockCustomNavigate).toHaveBeenCalledWith('/destination', {
- state: testState,
- replace: true,
- });
-
- // Cleanup should happen after 100ms
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockSetNavState).toHaveBeenLastCalledWith(null);
- });
- });
-
- describe('memory leak prevention', () => {
- it('should clean up state for multiple consecutive navigations with customNavigate', () => {
- const mockCustomNavigate = jest.fn();
- const { result } = renderHook(() =>
- useSafeNavigation(mockCustomNavigate),
- );
-
- // First navigation
- act(() => {
- result.current.navigate('/page1', { state: { page: 1 } });
- });
-
- expect(mockSetNavState).toHaveBeenCalledWith({ page: 1 });
-
- // Second navigation before cleanup - this clears the first timeout
- act(() => {
- result.current.navigate('/page2', { state: { page: 2 } });
- });
-
- expect(mockSetNavState).toHaveBeenCalledWith({ page: 2 });
-
- // Advance timers - only the second cleanup should execute (first was cleared)
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- // Should have been called: page1 state, page2 state, cleanup2 only = 3 calls
- // (cleanup1 was cleared when page2 navigation happened)
- expect(mockSetNavState).toHaveBeenCalledTimes(3);
- expect(mockSetNavState).toHaveBeenLastCalledWith(null);
- });
-
- it('should not accumulate state across multiple navigations', () => {
- const mockCustomNavigate = jest.fn();
- const { result } = renderHook(() =>
- useSafeNavigation(mockCustomNavigate),
- );
-
- // Multiple navigations - each clears the previous timeout
- for (let i = 0; i < 5; i++) {
- act(() => {
- result.current.navigate(`/page${i}`, { state: { id: i } });
- });
- }
-
- // Fast forward all timers
- act(() => {
- jest.advanceTimersByTime(500);
- });
-
- // Last call should always be cleanup (null)
- expect(mockSetNavState).toHaveBeenLastCalledWith(null);
-
- // Should have 5 state sets + 1 cleanup (only the last one) = 6 total calls
- // Previous 4 cleanup timeouts were cleared by subsequent navigations
- expect(mockSetNavState).toHaveBeenCalledTimes(6);
- });
- });
-
- describe('return value', () => {
- it('should return navigate function and location', () => {
- const { result } = renderHook(() => useSafeNavigation());
-
- expect(result.current).toHaveProperty('navigate');
- expect(result.current).toHaveProperty('location');
- expect(typeof result.current.navigate).toBe('function');
- expect(result.current.location).toBe(mockLocation);
- });
-
- it('should maintain stable navigate reference', () => {
- const { result, rerender } = renderHook(() => useSafeNavigation());
- const firstNavigate = result.current.navigate;
-
- rerender();
-
- expect(result.current.navigate).toBe(firstNavigate);
- });
- });
-
- describe('edge cases', () => {
- it('should handle navigation with empty state object', () => {
- const { result } = renderHook(() => useSafeNavigation());
-
- act(() => {
- result.current.navigate('/destination', { state: {} });
- });
-
- expect(mockSetNavState).toHaveBeenCalledWith({});
-
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockSetNavState).toHaveBeenLastCalledWith(null);
- });
-
- it('should handle navigation with null state explicitly', () => {
- const { result } = renderHook(() => useSafeNavigation());
-
- act(() => {
- // @ts-expect-error - testing edge case
- result.current.navigate('/destination', { state: null });
- });
-
- expect(mockSetNavState).toHaveBeenCalledWith(null);
- });
-
- it('should handle navigation with undefined options', () => {
- const mockCustomNavigate = jest.fn();
- const { result } = renderHook(() =>
- useSafeNavigation(mockCustomNavigate),
- );
-
- act(() => {
- result.current.navigate('/destination', undefined);
- });
-
- expect(mockCustomNavigate).toHaveBeenCalledWith(
- '/destination',
- undefined,
- );
- expect(mockSetNavState).toHaveBeenCalledWith(null);
- });
- });
-
- describe('timeout cleanup', () => {
- it('should clear previous timeout when navigate is called multiple times', () => {
- const { result } = renderHook(() => useSafeNavigation());
-
- act(() => {
- result.current.navigate('/path1', { state: { first: true } });
- });
-
- // First timeout scheduled, advance time partially
- act(() => {
- jest.advanceTimersByTime(50);
- });
-
- // Navigate again before first timeout completes
- act(() => {
- result.current.navigate('/path2', { state: { second: true } });
- });
-
- // Advance remaining time from first timeout (should not trigger)
- act(() => {
- jest.advanceTimersByTime(50);
- });
-
- // Only the second navigation's state should remain (not cleaned up yet)
- // First timeout was cleared, so we should have: initial calls + second call
- expect(mockSetNavState).toHaveBeenCalledWith({ first: true });
- expect(mockSetNavState).toHaveBeenCalledWith({ second: true });
-
- // Now advance time to trigger second timeout
- act(() => {
- jest.advanceTimersByTime(50);
- });
-
- // Second timeout should clean up
- expect(mockSetNavState).toHaveBeenLastCalledWith(null);
- });
-
- it('should clear timeout on unmount', () => {
- const { result, unmount } = renderHook(() => useSafeNavigation());
-
- act(() => {
- result.current.navigate('/destination', { state: { test: true } });
- });
-
- // Unmount before timeout completes
- unmount();
-
- // Advance time past when cleanup would have happened
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- // The cleanup after unmount should not trigger setNavState again
- // We should only see the initial call, not a cleanup call
- const callCount = mockSetNavState.mock.calls.length;
-
- // Advancing timers again should not add more calls
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockSetNavState.mock.calls.length).toBe(callCount);
- });
-
- it('should not accumulate timeouts', () => {
- const { result } = renderHook(() => useSafeNavigation());
-
- // Navigate 5 times quickly
- act(() => {
- for (let i = 0; i < 5; i++) {
- result.current.navigate(`/path${i}`, { state: { count: i } });
- }
- });
-
- // Clear all mock calls to focus on cleanup behavior
- mockSetNavState.mockClear();
-
- // Advance time to trigger cleanup
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- // Only ONE cleanup should happen (from the last navigate call)
- expect(mockSetNavState).toHaveBeenCalledTimes(1);
- expect(mockSetNavState).toHaveBeenCalledWith(null);
- });
- });
-});
diff --git a/ui/hooks/useSafeNavigation.ts b/ui/hooks/useSafeNavigation.ts
deleted file mode 100644
index 4498e6c1a9d7..000000000000
--- a/ui/hooks/useSafeNavigation.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
-import { useCallback, useRef, useEffect } from 'react';
-import { useSetNavState } from '../contexts/navigation-state';
-
-type SafeNavigateOptions = {
- state?: Record;
- replace?: boolean;
-};
-
-export const useSafeNavigation = (
- customNavigate?: (path: string, options?: SafeNavigateOptions) => void,
-): {
- navigate: (path: string, options?: SafeNavigateOptions) => void;
- location: ReturnType;
-} => {
- const defaultNavigate = useNavigate();
- const location = useLocation();
- const setNavState = useSetNavState();
- const cleanupTimeoutRef = useRef(null);
-
- // Clear timeout on unmount to prevent memory leaks
- useEffect(() => {
- return () => {
- if (cleanupTimeoutRef.current) {
- clearTimeout(cleanupTimeoutRef.current);
- }
- };
- }, []);
-
- // Memoize the navigate function to prevent unnecessary re-renders
- // This is critical for useEffect dependencies that include navigate
- const safeNavigate = useCallback(
- (path: string, options?: SafeNavigateOptions) => {
- if (options?.state) {
- setNavState(options.state);
- } else {
- setNavState(null);
- }
-
- // Clear any existing timeout before scheduling a new one
- if (cleanupTimeoutRef.current) {
- clearTimeout(cleanupTimeoutRef.current);
- }
-
- // Schedule cleanup for both custom and default navigate to prevent memory leaks
- cleanupTimeoutRef.current = setTimeout(() => {
- setNavState(null);
- cleanupTimeoutRef.current = null;
- }, 100);
-
- if (customNavigate) {
- customNavigate(path, options);
- return;
- }
-
- defaultNavigate(path, {
- replace: Boolean(options?.replace),
- state: options?.state,
- });
- },
- [customNavigate, defaultNavigate, setNavState],
- );
-
- return {
- navigate: safeNavigate,
- location,
- };
-};
diff --git a/ui/hooks/useSegmentContext.js b/ui/hooks/useSegmentContext.js
index c1fad3a05f59..5887e31aca10 100644
--- a/ui/hooks/useSegmentContext.js
+++ b/ui/hooks/useSegmentContext.js
@@ -1,5 +1,5 @@
import { useSelector } from 'react-redux';
-import { useLocation, matchPath } from 'react-router-dom-v5-compat';
+import { useLocation, matchPath } from 'react-router-dom';
import { PATH_NAME_MAP, getPaths } from '../helpers/constants/routes';
import { txDataSelector } from '../selectors';
@@ -19,7 +19,6 @@ export function useSegmentContext() {
const paths = getPaths();
// Try to match the current location against each path
- // Note: v5-compat matchPath uses v6 signature (pattern first, pathname second)
let match;
paths.find((path) => {
match = matchPath(
diff --git a/ui/hooks/useShouldShowSpeedUp.test.ts b/ui/hooks/useShouldShowSpeedUp.test.ts
index 2de83c26021f..b87d7fae9148 100644
--- a/ui/hooks/useShouldShowSpeedUp.test.ts
+++ b/ui/hooks/useShouldShowSpeedUp.test.ts
@@ -1,5 +1,5 @@
import { act } from '@testing-library/react-hooks';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import mockState from '../../test/data/mock-state.json';
import { useShouldShowSpeedUp } from './useShouldShowSpeedUp';
diff --git a/ui/hooks/useTheme.test.ts b/ui/hooks/useTheme.test.ts
index 486117f5e13a..be2dc9e1f7ef 100644
--- a/ui/hooks/useTheme.test.ts
+++ b/ui/hooks/useTheme.test.ts
@@ -1,5 +1,5 @@
import { ThemeType } from '../../shared/constants/preferences';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import { useTheme } from './useTheme';
jest.mock('../selectors', () => ({
diff --git a/ui/hooks/useTokenDetectionPolling.test.ts b/ui/hooks/useTokenDetectionPolling.test.ts
index 52f6fb2fbf8a..a84ff6b18d2a 100644
--- a/ui/hooks/useTokenDetectionPolling.test.ts
+++ b/ui/hooks/useTokenDetectionPolling.test.ts
@@ -1,5 +1,5 @@
import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS } from '@metamask/multichain-network-controller';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import {
tokenDetectionStartPolling,
tokenDetectionStopPollingByPollingToken,
diff --git a/ui/hooks/useTokenListPolling.test.ts b/ui/hooks/useTokenListPolling.test.ts
index f60bef7b0027..2be5916de8a3 100644
--- a/ui/hooks/useTokenListPolling.test.ts
+++ b/ui/hooks/useTokenListPolling.test.ts
@@ -1,6 +1,6 @@
import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS } from '@metamask/multichain-network-controller';
import { BtcScope } from '@metamask/keyring-api';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import {
tokenListStartPolling,
tokenListStopPollingByPollingToken,
diff --git a/ui/hooks/useTokenRatesPolling.test.ts b/ui/hooks/useTokenRatesPolling.test.ts
index a16f9c63b730..8d57253ba562 100644
--- a/ui/hooks/useTokenRatesPolling.test.ts
+++ b/ui/hooks/useTokenRatesPolling.test.ts
@@ -1,6 +1,6 @@
import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS } from '@metamask/multichain-network-controller';
import { BtcScope } from '@metamask/keyring-api';
-import { renderHookWithProvider } from '../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate';
import {
tokenRatesStartPolling,
tokenRatesStopPollingByPollingToken,
diff --git a/ui/hooks/useTransactionDisplayData.js b/ui/hooks/useTransactionDisplayData.js
index 6115fe801ea4..93a6645897c4 100644
--- a/ui/hooks/useTransactionDisplayData.js
+++ b/ui/hooks/useTransactionDisplayData.js
@@ -8,7 +8,7 @@ import {
getKnownMethodData,
getSelectedAddress,
selectERC20TokensByChain,
-} from '../selectors/selectors';
+} from '../selectors';
import {
getStatusKey,
getTransactionTypeTitle,
diff --git a/ui/layouts/header.tsx b/ui/layouts/header.tsx
index dadd8d148199..fad46c9926e6 100644
--- a/ui/layouts/header.tsx
+++ b/ui/layouts/header.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { useLocation } from 'react-router-dom-v5-compat';
+import { useLocation } from 'react-router-dom';
import { AppHeader } from '../components/multichain';
import { hideAppHeader, showAppHeader } from '../pages/routes/utils';
diff --git a/ui/layouts/route-with-layout.tsx b/ui/layouts/route-with-layout.tsx
index 61f6b0f59639..d7d15ea84f9d 100644
--- a/ui/layouts/route-with-layout.tsx
+++ b/ui/layouts/route-with-layout.tsx
@@ -1,82 +1,69 @@
-import React, { ComponentType, ReactNode, useMemo } from 'react';
-import { Route, RouteComponentProps } from 'react-router-dom';
+import React, { ComponentType, ReactNode } from 'react';
+import type { RouteObject } from 'react-router-dom';
import Authenticated from '../helpers/higher-order-components/authenticated/authenticated.container';
+import Initialized from '../helpers/higher-order-components/initialized';
+import type { RootLayout } from './root-layout';
+import type { LegacyLayout } from './legacy-layout';
-type Props = {
+export type RouteWithLayoutConfig = {
path: string;
- exact?: boolean;
- component?: ComponentType;
- children?: ReactNode;
- layout: ComponentType<{ children: ReactNode }>;
+ element?: ReactNode;
+ component?: ComponentType; // eslint-disable-line @typescript-eslint/no-explicit-any
+ layout:
+ | typeof RootLayout
+ | typeof LegacyLayout
+ | ComponentType<{ children: ReactNode }>;
authenticated?: boolean;
+ initialized?: boolean;
+ children?: ReactNode;
};
-/*
-Once migrated, we can use layouts like this:
- }>
- } />
- } />
-
-*/
-
/**
- * Interim helper to wrap a component with a layout while we migrate React Router
+ * Helper function that creates a React Router v6 RouteObject with layout and auth wrapping.
+ * This is used with the useRoutes() hook for programmatic routing.
*
- * @param props - Route props
- * @param props.path - Path for the route
- * @param props.exact - Whether the route should match exactly
- * @param props.component - The component to render for the route (receives route props)
- * @param props.children - Alternative to component prop, renders children directly
- * @param props.layout - The layout to use for the route
- * @param props.authenticated - Whether to wrap with the Authenticated component
- * @returns Component wrapped in the layout
+ * @param config - Route configuration
+ * @param config.path - Path for the route
+ * @param config.element - The element to render for the route
+ * @param config.component - Component to instantiate (alternative to element)
+ * @param config.layout - The layout to use for the route
+ * @param config.authenticated - Whether to wrap with the Authenticated component
+ * @param config.initialized - Whether to wrap with the Initialized component
+ * @param config.children - Nested route content
+ * @returns RouteObject ready for useRoutes()
*/
-export const RouteWithLayout = ({
- layout: Layout,
- component: Component,
- children,
- authenticated,
- ...routeProps
-}: Props) => {
- // Exclude function children from deps to prevent re-memoization when render functions change reference
- // This is safe because render functions from createV5CompatRoute don't close over changing values
- const childrenDep = typeof children === 'function' ? null : children;
+export const createRouteWithLayout = (
+ config: RouteWithLayoutConfig,
+): RouteObject => {
+ const {
+ path,
+ layout: Layout,
+ element,
+ component: Component,
+ authenticated,
+ initialized,
+ children,
+ } = config;
- const WrappedComponent = useMemo(() => {
- if (Component) {
- return (props: RouteComponentProps) => (
-
-
-
- );
- }
- return (props: RouteComponentProps) => (
-
- {typeof children === 'function' ? children(props) : children}
-
- );
- }, [Layout, Component, childrenDep]);
+ // Determine content: children > element > component
+ let content: ReactNode =
+ children || element || (Component ? : null);
+
+ // Wrap with Initialized first (outermost guard)
+ if (initialized && content) {
+ content = {content} ;
+ }
- if (authenticated) {
- return ;
+ // Then wrap with Authenticated (inner guard)
+ if (authenticated && content) {
+ content = {content} ;
}
- return (
- {
- let content;
- if (Component) {
- content = ;
- } else if (typeof children === 'function') {
- content = children(props);
- } else {
- content = children;
- }
+ // Finally wrap with Layout
+ const wrappedElement = {content} ;
- return {content} ;
- }}
- />
- );
+ return {
+ path,
+ element: wrappedElement,
+ };
};
diff --git a/ui/pages/asset/asset.tsx b/ui/pages/asset/asset.tsx
index 7ec76073e488..cf13f513e5e1 100644
--- a/ui/pages/asset/asset.tsx
+++ b/ui/pages/asset/asset.tsx
@@ -2,7 +2,7 @@ import { Nft } from '@metamask/assets-controllers';
import { CaipChainId, Hex } from '@metamask/utils';
import React, { useEffect } from 'react';
import { useSelector } from 'react-redux';
-import { Navigate } from 'react-router-dom-v5-compat';
+import { Navigate, useParams } from 'react-router-dom';
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
import NftDetails from '../../components/app/assets/nfts/nft-details/nft-details';
import { getNFTsByChainId } from '../../ducks/metamask/metamask';
@@ -11,21 +11,13 @@ import { getTokenByAccountAndAddressAndChainId } from '../../selectors/assets';
import NativeAsset from './components/native-asset';
import TokenAsset from './components/token-asset';
-type AssetProps = {
- params: {
- chainId?: Hex;
- asset?: string;
- id?: string;
- };
-};
+const Asset = () => {
+ const params = useParams<{
+ chainId: Hex;
+ asset: string;
+ id: string;
+ }>();
-/**
- * A page representing a native, token, or NFT asset
- *
- * @param options0 - Component props
- * @param options0.params - Route parameters including chainId, asset, and id
- */
-const Asset = ({ params }: AssetProps) => {
const { chainId, asset, id } = params;
const decodedAsset = asset ? decodeURIComponent(asset) : undefined;
diff --git a/ui/pages/asset/components/asset-options.js b/ui/pages/asset/components/asset-options.js
index 302c0e9fa529..0e62037dadb4 100644
--- a/ui/pages/asset/components/asset-options.js
+++ b/ui/pages/asset/components/asset-options.js
@@ -1,7 +1,6 @@
import React, { useContext, useRef, useState } from 'react';
import PropTypes from 'prop-types';
-
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { I18nContext } from '../../../contexts/i18n';
import { MetaMetricsContext } from '../../../contexts/metametrics';
diff --git a/ui/pages/asset/components/asset-page.tsx b/ui/pages/asset/components/asset-page.tsx
index 5d9d6efc0ef5..dea446a228be 100644
--- a/ui/pages/asset/components/asset-page.tsx
+++ b/ui/pages/asset/components/asset-page.tsx
@@ -15,7 +15,7 @@ import {
} from '@metamask/utils';
import React, { ReactNode, useEffect, useMemo } from 'react';
import { useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { AssetType } from '../../../../shared/constants/transaction';
import { isEvmChainId } from '../../../../shared/lib/asset-utils';
import { endTrace, TraceName } from '../../../../shared/lib/trace';
diff --git a/ui/pages/asset/components/token-asset.tsx b/ui/pages/asset/components/token-asset.tsx
index db071369cc5d..7b9bc9dcf2f1 100644
--- a/ui/pages/asset/components/token-asset.tsx
+++ b/ui/pages/asset/components/token-asset.tsx
@@ -9,7 +9,7 @@ import {
} from '@metamask/utils';
import React, { useContext } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { InternalAccount } from '@metamask/keyring-internal-api';
import { formatChainIdToCaip } from '@metamask/bridge-controller';
import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics';
diff --git a/ui/pages/asset/components/token-buttons.tsx b/ui/pages/asset/components/token-buttons.tsx
index a982b7d0d705..b2dc89e54972 100644
--- a/ui/pages/asset/components/token-buttons.tsx
+++ b/ui/pages/asset/components/token-buttons.tsx
@@ -1,6 +1,6 @@
import React, { useCallback, useContext, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
///: BEGIN:ONLY_INCLUDE_IF(multichain)
import { isEvmAccountType } from '@metamask/keyring-api';
import { CaipAssetType } from '@metamask/utils';
diff --git a/ui/pages/asset/hooks/useChartTimeRanges.test.ts b/ui/pages/asset/hooks/useChartTimeRanges.test.ts
index 16220551cb96..bca4253fc191 100644
--- a/ui/pages/asset/hooks/useChartTimeRanges.test.ts
+++ b/ui/pages/asset/hooks/useChartTimeRanges.test.ts
@@ -1,5 +1,5 @@
import { CaipAssetType } from '@metamask/utils';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { useChartTimeRanges } from './useChartTimeRanges';
describe('useChartTimeRanges', () => {
diff --git a/ui/pages/asset/hooks/useCurrentPrice.test.ts b/ui/pages/asset/hooks/useCurrentPrice.test.ts
index d0fac4b631de..2eb4b7b105b0 100644
--- a/ui/pages/asset/hooks/useCurrentPrice.test.ts
+++ b/ui/pages/asset/hooks/useCurrentPrice.test.ts
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { AssetType } from '@metamask/bridge-controller';
import { EthScope, SolScope } from '@metamask/keyring-api';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { Asset } from '../types/asset';
import { useCurrentPrice } from './useCurrentPrice';
diff --git a/ui/pages/asset/hooks/useHistoricalPrices.test.ts b/ui/pages/asset/hooks/useHistoricalPrices.test.ts
index ad1291c7ea4b..cf4ae74870fe 100644
--- a/ui/pages/asset/hooks/useHistoricalPrices.test.ts
+++ b/ui/pages/asset/hooks/useHistoricalPrices.test.ts
@@ -3,7 +3,7 @@ import { EthScope, SolScope } from '@metamask/keyring-api';
import { waitFor } from '@testing-library/react';
import { cloneDeep } from 'lodash';
import fetchWithCache from '../../../../shared/lib/fetch-with-cache';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import {
DEFAULT_USE_HISTORICAL_PRICES_METADATA,
useHistoricalPrices,
diff --git a/ui/pages/bridge/awaiting-signatures/awaiting-signatures-cancel-button.tsx b/ui/pages/bridge/awaiting-signatures/awaiting-signatures-cancel-button.tsx
index 0fe89df424bb..90f8125dae8f 100644
--- a/ui/pages/bridge/awaiting-signatures/awaiting-signatures-cancel-button.tsx
+++ b/ui/pages/bridge/awaiting-signatures/awaiting-signatures-cancel-button.tsx
@@ -1,5 +1,5 @@
import React, { useContext } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
CROSS_CHAIN_SWAP_ROUTE,
PREPARE_SWAP_ROUTE,
diff --git a/ui/pages/bridge/hooks/useDestinationAccount.test.tsx b/ui/pages/bridge/hooks/useDestinationAccount.test.tsx
index 35541b61ace9..490efe41095a 100644
--- a/ui/pages/bridge/hooks/useDestinationAccount.test.tsx
+++ b/ui/pages/bridge/hooks/useDestinationAccount.test.tsx
@@ -6,7 +6,7 @@ import {
MOCK_LEDGER_ACCOUNT,
MOCK_SOLANA_ACCOUNT,
} from '../../../../test/data/bridge/mock-bridge-store';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import {
getFromAccount,
getFromChain,
diff --git a/ui/pages/bridge/hooks/useExternalAccountResolution.test.tsx b/ui/pages/bridge/hooks/useExternalAccountResolution.test.tsx
index f1d6c4d0521f..05e236a7487b 100644
--- a/ui/pages/bridge/hooks/useExternalAccountResolution.test.tsx
+++ b/ui/pages/bridge/hooks/useExternalAccountResolution.test.tsx
@@ -1,5 +1,5 @@
import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { useExternalAccountResolution } from './useExternalAccountResolution';
const renderUseExternalAccountResolution = (
diff --git a/ui/pages/bridge/hooks/useGasIncluded7702.test.ts b/ui/pages/bridge/hooks/useGasIncluded7702.test.ts
index 517666f41243..8dd057b73194 100644
--- a/ui/pages/bridge/hooks/useGasIncluded7702.test.ts
+++ b/ui/pages/bridge/hooks/useGasIncluded7702.test.ts
@@ -1,5 +1,5 @@
import { act, waitFor } from '@testing-library/react';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { getIsSmartTransaction } from '../../../../shared/modules/selectors';
import { useGasIncluded7702 } from './useGasIncluded7702';
diff --git a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx
index 92902febdc4b..60a7f771af36 100644
--- a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx
+++ b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx
@@ -3,7 +3,7 @@ import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { renderHook } from '@testing-library/react-hooks';
import { Provider } from 'react-redux';
-import { MemoryRouter } from 'react-router-dom-v5-compat';
+import { MemoryRouter } from 'react-router-dom';
import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store';
import * as bridgeStatusActions from '../../../ducks/bridge-status/actions';
import {
@@ -14,9 +14,9 @@ import { DEFAULT_ROUTE } from '../../../helpers/constants/routes';
import useSubmitBridgeTransaction from './useSubmitBridgeTransaction';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
@@ -182,7 +182,6 @@ describe('ui/pages/bridge/hooks/useSubmitBridgeTransaction', () => {
// Assert
expect(mockUseNavigate).toHaveBeenCalledWith(DEFAULT_ROUTE, {
- replace: false,
state: { stayOnHomePage: true },
});
});
diff --git a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts
index 5f061e300e47..48d1c2c6fe60 100644
--- a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts
+++ b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts
@@ -1,4 +1,5 @@
import { useDispatch, useSelector } from 'react-redux';
+import { useNavigate } from 'react-router-dom';
import { isNonEvmChainId } from '@metamask/bridge-controller';
import type { QuoteMetadata, QuoteResponse } from '@metamask/bridge-controller';
import {
@@ -16,7 +17,6 @@ import {
getIsStxEnabled,
} from '../../../ducks/bridge/selectors';
import { captureException } from '../../../../shared/lib/sentry';
-import { useSafeNavigation } from '../../../hooks/useSafeNavigation';
const ALLOWANCE_RESET_ERROR = 'Eth USDT allowance reset failed';
const APPROVAL_TX_ERROR = 'Approve transaction failed';
@@ -52,7 +52,7 @@ const isHardwareWalletUserRejection = (error: unknown): boolean => {
};
export default function useSubmitBridgeTransaction() {
- const { navigate } = useSafeNavigation();
+ const navigate = useNavigate();
const dispatch = useDispatch();
const hardwareWalletUsed = useSelector(isHardwareWallet);
diff --git a/ui/pages/bridge/index.test.tsx b/ui/pages/bridge/index.test.tsx
index eed819695af9..9871ddbf2de1 100644
--- a/ui/pages/bridge/index.test.tsx
+++ b/ui/pages/bridge/index.test.tsx
@@ -6,10 +6,7 @@ import { setBackgroundConnection } from '../../store/background-connection';
import { MOCKS, CONSTANTS } from '../../../test/jest';
import { renderWithProvider } from '../../../test/lib/render-helpers-navigate';
import { createBridgeMockStore } from '../../../test/data/bridge/mock-bridge-store';
-import {
- CROSS_CHAIN_SWAP_ROUTE,
- PREPARE_SWAP_ROUTE,
-} from '../../helpers/constants/routes';
+import { PREPARE_SWAP_ROUTE } from '../../helpers/constants/routes';
import CrossChainSwap from '.';
const mockResetBridgeState = jest.fn();
@@ -35,9 +32,9 @@ setBackgroundConnection({
} as any);
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => ({
pathname: '/cross-chain/swaps/prepare-swap-page',
@@ -107,7 +104,7 @@ describe('Bridge', () => {
const { container, getByText } = renderWithProvider(
,
store,
- CROSS_CHAIN_SWAP_ROUTE + PREPARE_SWAP_ROUTE,
+ PREPARE_SWAP_ROUTE,
);
expect(getByText('Swap')).toBeInTheDocument();
diff --git a/ui/pages/bridge/index.tsx b/ui/pages/bridge/index.tsx
index 6edaa5f1139b..6d7199c61510 100644
--- a/ui/pages/bridge/index.tsx
+++ b/ui/pages/bridge/index.tsx
@@ -1,6 +1,6 @@
import React, { useContext, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { Route, Routes } from 'react-router-dom-v5-compat';
+import { Route, Routes, useNavigate, useLocation } from 'react-router-dom';
import {
UnifiedSwapBridgeEventName,
isNonEvmChainId,
@@ -10,10 +10,10 @@ import { clearSwapsState } from '../../ducks/swaps/swaps';
import {
DEFAULT_ROUTE,
PREPARE_SWAP_ROUTE,
- CROSS_CHAIN_SWAP_ROUTE,
AWAITING_SIGNATURES_ROUTE,
TRANSACTION_SHIELD_ROUTE,
} from '../../helpers/constants/routes';
+import { toRelativeRoutePath } from '../routes/utils';
import { resetBackgroundSwapsState } from '../../store/actions';
import {
ButtonIcon,
@@ -40,29 +40,20 @@ import { useQuoteFetchEvents } from '../../hooks/bridge/useQuoteFetchEvents';
import { TextVariant } from '../../helpers/constants/design-system';
import { useTxAlerts } from '../../hooks/bridge/useTxAlerts';
import { getFromChain, getBridgeQuotes } from '../../ducks/bridge/selectors';
-import { useSafeNavigation } from '../../hooks/useSafeNavigation';
import PrepareBridgePage from './prepare/prepare-bridge-page';
import AwaitingSignaturesCancelButton from './awaiting-signatures/awaiting-signatures-cancel-button';
import AwaitingSignatures from './awaiting-signatures/awaiting-signatures';
import { BridgeTransactionSettingsModal } from './prepare/bridge-transaction-settings-modal';
-type CrossChainSwapProps = {
- location?: {
- search?: string;
- };
-};
-
-const CrossChainSwap = ({ location }: CrossChainSwapProps) => {
+const CrossChainSwap = () => {
const t = useContext(I18nContext);
// Load swaps feature flags so that we can use smart transactions
useSwapsFeatureFlags();
useBridging();
-
- const { navigate } = useSafeNavigation();
const dispatch = useDispatch();
-
- const { search } = location ?? {};
+ const navigate = useNavigate();
+ const { search } = useLocation();
const isFromTransactionShield = new URLSearchParams(search || '').get(
'isFromTransactionShield',
@@ -157,7 +148,7 @@ const CrossChainSwap = ({ location }: CrossChainSwapProps) => {
{
}
/>
diff --git a/ui/pages/bridge/prepare/bridge-transaction-settings-modal.test.tsx b/ui/pages/bridge/prepare/bridge-transaction-settings-modal.test.tsx
index afaa158688a8..4a0734271505 100644
--- a/ui/pages/bridge/prepare/bridge-transaction-settings-modal.test.tsx
+++ b/ui/pages/bridge/prepare/bridge-transaction-settings-modal.test.tsx
@@ -7,10 +7,7 @@ import configureStore from '../../../store/store';
import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store';
import * as bridgeSelectors from '../../../ducks/bridge/selectors';
import CrossChainSwap from '..';
-import {
- CROSS_CHAIN_SWAP_ROUTE,
- PREPARE_SWAP_ROUTE,
-} from '../../../helpers/constants/routes';
+import { PREPARE_SWAP_ROUTE } from '../../../helpers/constants/routes';
import { waitForElementById } from '../../../../test/integration/helpers';
import { setSlippage } from '../../../ducks/bridge/actions';
import { sanitizeAmountInput } from '../utils/quote';
@@ -29,7 +26,7 @@ const renderModal = (initialSlippage?: number) => {
const renderResult = renderWithProvider(
,
store,
- CROSS_CHAIN_SWAP_ROUTE + PREPARE_SWAP_ROUTE,
+ PREPARE_SWAP_ROUTE,
);
store.dispatch(setSlippage(initialSlippage));
return { ...renderResult, store };
diff --git a/ui/pages/bridge/prepare/components/destination-account-picker-modal.test.tsx b/ui/pages/bridge/prepare/components/destination-account-picker-modal.test.tsx
index fa10f1b258e1..fbfcd98100c2 100644
--- a/ui/pages/bridge/prepare/components/destination-account-picker-modal.test.tsx
+++ b/ui/pages/bridge/prepare/components/destination-account-picker-modal.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { createBridgeMockStore } from '../../../../../test/data/bridge/mock-bridge-store';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../store/store';
import { getToAccounts } from '../../../../ducks/bridge/selectors';
import { DestinationAccountPickerModal } from './destination-account-picker-modal';
diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx
index a4cb977b1eb5..4db262d6a6de 100644
--- a/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx
+++ b/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { Provider } from 'react-redux';
import { useEffect } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import configureStore from '../../../store/store';
import { CHAIN_IDS } from '../../../../shared/constants/network';
import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store';
diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx
index 7f003343465d..2ecf85057d64 100644
--- a/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx
+++ b/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { act } from '@testing-library/react';
-import * as reactRouterUtils from 'react-router-dom-v5-compat';
+import * as reactRouterUtils from 'react-router-dom';
import { userEvent } from '@testing-library/user-event';
import { toEvmCaipChainId } from '@metamask/multichain-network-controller';
import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
diff --git a/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx b/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx
index 83635ad436fc..48f704b3fc01 100644
--- a/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx
+++ b/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { RequestStatus } from '@metamask/bridge-controller';
import mockBridgeQuotesErc20Erc20 from '../../../../test/data/bridge/mock-quotes-erc20-erc20.json';
import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import { CHAIN_IDS } from '../../../../shared/constants/network';
import { mockNetworkState } from '../../../../test/stub/networks';
diff --git a/ui/pages/bridge/quotes/multichain-bridge-quote-card.test.tsx b/ui/pages/bridge/quotes/multichain-bridge-quote-card.test.tsx
index 6c8a1fe9913f..f582e58dc1e6 100644
--- a/ui/pages/bridge/quotes/multichain-bridge-quote-card.test.tsx
+++ b/ui/pages/bridge/quotes/multichain-bridge-quote-card.test.tsx
@@ -5,7 +5,7 @@ import {
formatChainIdToCaip,
} from '@metamask/bridge-controller';
import { zeroAddress } from 'ethereumjs-util';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store';
import { CHAIN_IDS } from '../../../../shared/constants/network';
diff --git a/ui/pages/bridge/transaction-details/transaction-details.test.tsx b/ui/pages/bridge/transaction-details/transaction-details.test.tsx
index 10800ba2839c..2147f28eca76 100644
--- a/ui/pages/bridge/transaction-details/transaction-details.test.tsx
+++ b/ui/pages/bridge/transaction-details/transaction-details.test.tsx
@@ -1,10 +1,10 @@
import React from 'react';
-import type { Location as RouterLocation } from 'react-router-dom-v5-compat';
+import type { Location as RouterLocation } from 'react-router-dom';
import { EthAccountType, EthScope } from '@metamask/keyring-api';
import { TransactionStatus } from '@metamask/transaction-controller';
import type { BridgeHistoryItem } from '@metamask/bridge-status-controller';
import { StatusTypes } from '@metamask/bridge-controller';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockBridgeTxData from '../../../../test/data/bridge/mock-bridge-transaction-details.json';
import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store';
import { mockNetworkState } from '../../../../test/stub/networks';
diff --git a/ui/pages/bridge/transaction-details/transaction-details.tsx b/ui/pages/bridge/transaction-details/transaction-details.tsx
index 806daba6ad54..c6d15844dc20 100644
--- a/ui/pages/bridge/transaction-details/transaction-details.tsx
+++ b/ui/pages/bridge/transaction-details/transaction-details.tsx
@@ -1,6 +1,6 @@
import React, { useContext } from 'react';
import { useSelector } from 'react-redux';
-import type { Location as RouterLocation } from 'react-router-dom-v5-compat';
+import type { Location as RouterLocation } from 'react-router-dom';
import {
TransactionStatus,
TransactionType,
diff --git a/ui/pages/confirm-add-suggested-nft/confirm-add-suggested-nft.js b/ui/pages/confirm-add-suggested-nft/confirm-add-suggested-nft.js
index 925c17db5362..0c589e57c930 100644
--- a/ui/pages/confirm-add-suggested-nft/confirm-add-suggested-nft.js
+++ b/ui/pages/confirm-add-suggested-nft/confirm-add-suggested-nft.js
@@ -1,7 +1,6 @@
import React, { useCallback, useContext, useEffect, useState } from 'react';
-import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import { providerErrors, serializeError } from '@metamask/rpc-errors';
import { getTokenTrackerLink } from '@metamask/etherscan-link';
import classnames from 'classnames';
@@ -64,17 +63,11 @@ import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
import { Nav } from '../confirmations/components/confirm/nav';
import { hideAppHeader } from '../routes/utils';
-const ConfirmAddSuggestedNFT = ({
- navigate: routeNavigate,
- location: routeLocation,
-} = {}) => {
+const ConfirmAddSuggestedNFT = () => {
const t = useContext(I18nContext);
const dispatch = useDispatch();
- const hookNavigate = useNavigate();
- const hookLocation = useLocation();
- // Use navigate/location from props (v5 route) if available, otherwise fall back to hooks (v6)
- const navigate = routeNavigate || hookNavigate;
- const location = routeLocation || hookLocation;
+ const navigate = useNavigate();
+ const location = useLocation();
const hasAppHeader = location?.pathname ? !hideAppHeader({ location }) : true;
@@ -195,7 +188,7 @@ const ConfirmAddSuggestedNFT = ({
};
addImageUrlToSuggestedNFTs();
- }, [suggestedNfts]); // rerender when suggestedNfts changes
+ }, [suggestedNfts, ipfsGateway]); // rerender when suggestedNfts or ipfsGateway changes
return (
({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
useLocation: () => mockUseLocation(),
}));
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 d42de2739eb5..a7510204108b 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
@@ -1,7 +1,6 @@
import React, { useCallback, useContext, useEffect, useMemo } from 'react';
-import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import classnames from 'classnames';
import { providerErrors, serializeError } from '@metamask/rpc-errors';
import {
@@ -84,16 +83,11 @@ function hasDuplicateSymbolAndDiffAddress(suggestedTokens, tokens) {
return Boolean(duplicate);
}
-const ConfirmAddSuggestedToken = ({
- navigate: routeNavigate,
- location: routeLocation,
-} = {}) => {
+const ConfirmAddSuggestedToken = () => {
const t = useContext(I18nContext);
const dispatch = useDispatch();
- const hookNavigate = useNavigate();
- const hookLocation = useLocation();
- const navigate = routeNavigate || hookNavigate;
- const location = routeLocation || hookLocation;
+ const navigate = useNavigate();
+ const location = useLocation();
const hasAppHeader = location?.pathname ? !hideAppHeader({ location }) : true;
@@ -242,15 +236,4 @@ const ConfirmAddSuggestedToken = ({
);
};
-ConfirmAddSuggestedToken.propTypes = {
- navigate: PropTypes.func,
- location: PropTypes.shape({
- pathname: PropTypes.string,
- search: PropTypes.string,
- hash: PropTypes.string,
- state: PropTypes.object,
- key: PropTypes.string,
- }),
-};
-
export default ConfirmAddSuggestedToken;
diff --git a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.test.js b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.test.js
index 93029fee6dd1..590288d48e30 100644
--- a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.test.js
+++ b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.test.js
@@ -16,8 +16,8 @@ import ConfirmAddSuggestedToken from '.';
const mockNavigate = jest.fn();
const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
useLocation: () => mockUseLocation(),
}));
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 321b34c7c4e8..948de0d2ba3c 100644
--- a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js
+++ b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js
@@ -5,7 +5,7 @@ import copyToClipboard from 'copy-to-clipboard';
import classnames from 'classnames';
import log from 'loglevel';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate, useParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useParams } from 'react-router-dom';
import { cloneDeep } from 'lodash';
import AccountListItem from '../../components/app/account-list-item';
diff --git a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.test.js b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.test.js
index ef90aab03576..c6af76e65844 100644
--- a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.test.js
+++ b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.test.js
@@ -16,9 +16,9 @@ import ConfirmDecryptMessage from './confirm-decrypt-message.component';
const messageIdMock = '12345';
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useParams: () => ({
id: messageIdMock,
}),
diff --git a/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.stories.js b/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.stories.js
index c85f904c80ca..2f7fdcefcc19 100644
--- a/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.stories.js
+++ b/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.stories.js
@@ -1,6 +1,5 @@
import React from 'react';
import { Provider } from 'react-redux';
-import { action } from '@storybook/addon-actions';
import configureStore from '../../store/store';
import testData from '../../../.storybook/test-data';
import ConfirmEncryptionPublicKey from './confirm-encryption-public-key.component';
@@ -33,9 +32,9 @@ export default {
type: 'number',
},
},
- history: {
+ navigate: {
control: {
- type: 'object',
+ type: 'function',
},
},
requesterAddress: {
@@ -66,9 +65,6 @@ export default {
},
args: {
fromAccount: Object.values(metamask.internalAccounts.accounts)[0],
- history: {
- push: action('history.push()'),
- },
requesterAddress: confirmTransaction.txData.txParams.from,
txData: confirmTransaction.txData,
subjectMetadata: metamask.subjectMetadata,
diff --git a/ui/pages/confirmations/components/UI/asset/asset.test.tsx b/ui/pages/confirmations/components/UI/asset/asset.test.tsx
index 0dc78c5c6901..f5c1c331a98c 100644
--- a/ui/pages/confirmations/components/UI/asset/asset.test.tsx
+++ b/ui/pages/confirmations/components/UI/asset/asset.test.tsx
@@ -3,7 +3,7 @@ import { fireEvent } from '@testing-library/react';
import { BtcAccountType } from '@metamask/keyring-api';
import createMockStore from 'redux-mock-store';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { useNftImageUrl } from '../../../hooks/useNftImageUrl';
import { AssetStandard } from '../../../types/send';
import { Asset } from './asset';
diff --git a/ui/pages/confirmations/components/UI/send-hero/send-hero.test.tsx b/ui/pages/confirmations/components/UI/send-hero/send-hero.test.tsx
index 501db761222b..38d0ed94f702 100644
--- a/ui/pages/confirmations/components/UI/send-hero/send-hero.test.tsx
+++ b/ui/pages/confirmations/components/UI/send-hero/send-hero.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import mockDefaultState from '../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import { Asset, AssetStandard } from '../../../types/send';
import { SendHero } from './send-hero';
diff --git a/ui/pages/confirmations/components/advanced-gas-controls/advanced-gas-controls.test.js b/ui/pages/confirmations/components/advanced-gas-controls/advanced-gas-controls.test.js
index 13e2637ecb96..d3638791b15e 100644
--- a/ui/pages/confirmations/components/advanced-gas-controls/advanced-gas-controls.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-controls/advanced-gas-controls.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
-import { renderWithProvider } from '../../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import AdvancedGasControls from './advanced-gas-controls.component';
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js
index 07c7fc8faaab..5f93e476b2a3 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js
@@ -5,7 +5,7 @@ import {
EditGasModes,
GasEstimateTypes,
} from '../../../../../../shared/constants/gas';
-import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import mockEstimates from '../../../../../../test/data/mock-estimates.json';
import mockState from '../../../../../../test/data/mock-state.json';
import * as Actions from '../../../../../store/actions';
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
index 066b428d6ad5..a66c4b05f777 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
@@ -2,7 +2,7 @@ import React from 'react';
import { act, fireEvent, screen } from '@testing-library/react';
import { GasEstimateTypes } from '../../../../../../shared/constants/gas';
-import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import mockEstimates from '../../../../../../test/data/mock-estimates.json';
import mockState from '../../../../../../test/data/mock-state.json';
import { MAX_GAS_LIMIT_DEC } from '../../../send-legacy/send.constants';
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js
index 6aacf0cc1a26..d24c57efc852 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import { act } from '@testing-library/react';
-import { renderWithProvider, screen } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import AdvancedGasFeeInputSubtext from './advanced-gas-fee-input-subtext';
@@ -37,127 +37,127 @@ const renderComponent = async ({ props = {}, state = {} } = {}) => {
describe('AdvancedGasFeeInputSubtext', () => {
describe('when "latest" is non-nullish', () => {
it('should render the latest fee if given a fee', async () => {
- await renderComponent({
+ const { getByText } = await renderComponent({
props: {
latest: '123.12345',
},
});
- expect(screen.getByText('123.12 GWEI')).toBeInTheDocument();
+ expect(getByText('123.12 GWEI')).toBeInTheDocument();
});
it('should render the latest fee range if given a fee range', async () => {
- await renderComponent({
+ const { getByText } = await renderComponent({
props: {
latest: ['123.456', '456.789'],
},
});
- expect(screen.getByText('123.46 - 456.79 GWEI')).toBeInTheDocument();
+ expect(getByText('123.46 - 456.79 GWEI')).toBeInTheDocument();
});
it('should render a fee trend arrow image if given "up" as the trend', async () => {
- await renderComponent({
+ const { getByTitle } = await renderComponent({
props: {
latest: '123.12345',
trend: 'up',
},
});
- expect(screen.getByTitle('up arrow')).toBeInTheDocument();
+ expect(getByTitle('up arrow')).toBeInTheDocument();
});
it('should render a fee trend arrow image if given "down" as the trend', async () => {
- await renderComponent({
+ const { getByTitle } = await renderComponent({
props: {
latest: '123.12345',
trend: 'down',
},
});
- expect(screen.getByTitle('down arrow')).toBeInTheDocument();
+ expect(getByTitle('down arrow')).toBeInTheDocument();
});
it('should render a fee trend arrow image if given "level" as the trend', async () => {
- await renderComponent({
+ const { getByTitle } = await renderComponent({
props: {
latest: '123.12345',
trend: 'level',
},
});
- expect(screen.getByTitle('level arrow')).toBeInTheDocument();
+ expect(getByTitle('level arrow')).toBeInTheDocument();
});
it('should not render a fee trend arrow image if given an invalid trend', async () => {
// Suppress warning from PropTypes, which we expect
jest.spyOn(console, 'error').mockImplementation();
- await renderComponent({
+ const { queryByTestId } = await renderComponent({
props: {
latest: '123.12345',
trend: 'whatever',
},
});
- expect(screen.queryByTestId('fee-arrow')).not.toBeInTheDocument();
+ expect(queryByTestId('fee-arrow')).not.toBeInTheDocument();
});
it('should not render a fee trend arrow image if given a nullish trend', async () => {
- await renderComponent({
+ const { queryByTestId } = await renderComponent({
props: {
latest: '123.12345',
trend: null,
},
});
- expect(screen.queryByTestId('fee-arrow')).not.toBeInTheDocument();
+ expect(queryByTestId('fee-arrow')).not.toBeInTheDocument();
});
});
describe('when "latest" is nullish', () => {
it('should not render the container for the latest fee', async () => {
- await renderComponent({
+ const { queryByTestId } = await renderComponent({
props: {
latest: null,
},
});
- expect(screen.queryByTestId('latest')).not.toBeInTheDocument();
+ expect(queryByTestId('latest')).not.toBeInTheDocument();
});
});
describe('when "historical" is not nullish', () => {
it('should render the historical fee if given a fee', async () => {
- await renderComponent({
+ const { getByText } = await renderComponent({
props: {
historical: '123.12345',
},
});
- expect(screen.getByText('123.12 GWEI')).toBeInTheDocument();
+ expect(getByText('123.12 GWEI')).toBeInTheDocument();
});
it('should render the historical fee range if given a fee range', async () => {
- await renderComponent({
+ const { getByText } = await renderComponent({
props: {
historical: ['123.456', '456.789'],
},
});
- expect(screen.getByText('123.46 - 456.79 GWEI')).toBeInTheDocument();
+ expect(getByText('123.46 - 456.79 GWEI')).toBeInTheDocument();
});
});
describe('when "historical" is nullish', () => {
it('should not render the container for the historical fee', async () => {
- await renderComponent({
+ const { queryByTestId } = await renderComponent({
props: {
historical: null,
},
});
- expect(screen.queryByTestId('historical')).not.toBeInTheDocument();
+ expect(queryByTestId('historical')).not.toBeInTheDocument();
});
});
});
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
index 18c244d31885..f302ea5c4e4e 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
@@ -5,7 +5,7 @@ import {
EditGasModes,
GasEstimateTypes,
} from '../../../../../../../shared/constants/gas';
-import { renderWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import mockEstimates from '../../../../../../../test/data/mock-estimates.json';
import mockState from '../../../../../../../test/data/mock-state.json';
import { GasFeeContextProvider } from '../../../../../../contexts/gasFee';
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
index 94dd3edf5609..02f2b38fab01 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
@@ -5,7 +5,7 @@ import {
EditGasModes,
GasEstimateTypes,
} from '../../../../../../../shared/constants/gas';
-import { renderWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import mockEstimates from '../../../../../../../test/data/mock-estimates.json';
import mockState from '../../../../../../../test/data/mock-state.json';
import { GasFeeContextProvider } from '../../../../../../contexts/gasFee';
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js
index ca20b4a8eece..5257661ff455 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js
@@ -2,7 +2,7 @@ import React from 'react';
import { act, fireEvent, screen } from '@testing-library/react';
import { GasEstimateTypes } from '../../../../../shared/constants/gas';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockEstimates from '../../../../../test/data/mock-estimates.json';
import mockState from '../../../../../test/data/mock-state.json';
import { MAX_GAS_LIMIT_DEC } from '../../send-legacy/send.constants';
diff --git a/ui/pages/confirmations/components/confirm/footer/footer.test.tsx b/ui/pages/confirmations/components/confirm/footer/footer.test.tsx
index 28325efbcf6a..628af4051ea8 100644
--- a/ui/pages/confirmations/components/confirm/footer/footer.test.tsx
+++ b/ui/pages/confirmations/components/confirm/footer/footer.test.tsx
@@ -97,9 +97,9 @@ jest.mock('../../../hooks/useConfirmSendNavigation', () => ({
const mockUseNavigate = jest.fn();
const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => mockUseLocation(),
};
diff --git a/ui/pages/confirmations/components/confirm/footer/footer.tsx b/ui/pages/confirmations/components/confirm/footer/footer.tsx
index 928e2ed471f3..ff190af1c70d 100644
--- a/ui/pages/confirmations/components/confirm/footer/footer.tsx
+++ b/ui/pages/confirmations/components/confirm/footer/footer.tsx
@@ -5,7 +5,7 @@ import {
import React, { useCallback, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { PRODUCT_TYPES } from '@metamask/subscription-controller';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { MetaMetricsEventLocation } from '../../../../../../shared/constants/metametrics';
import { isCorrectDeveloperTransactionType } from '../../../../../../shared/lib/confirmation.utils';
import { ConfirmAlertModal } from '../../../../../components/app/alert-system/confirm-alert-modal';
diff --git a/ui/pages/confirmations/components/confirm/footer/origin-throttle-modal.test.tsx b/ui/pages/confirmations/components/confirm/footer/origin-throttle-modal.test.tsx
index af5f0f1df703..deba263e5ab1 100644
--- a/ui/pages/confirmations/components/confirm/footer/origin-throttle-modal.test.tsx
+++ b/ui/pages/confirmations/components/confirm/footer/origin-throttle-modal.test.tsx
@@ -4,7 +4,7 @@ import { screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import { I18nContext } from '../../../../../contexts/i18n';
import { useOriginThrottling } from '../../../hooks/useOriginThrottling';
-import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../../test/data/mock-state.json';
import { MetaMetricsEventLocation } from '../../../../../../shared/constants/metametrics';
import OriginThrottleModal from './origin-throttle-modal';
diff --git a/ui/pages/confirmations/components/confirm/header/header.test.tsx b/ui/pages/confirmations/components/confirm/header/header.test.tsx
index 1af8c6e2772b..9eea986f3959 100644
--- a/ui/pages/confirmations/components/confirm/header/header.test.tsx
+++ b/ui/pages/confirmations/components/confirm/header/header.test.tsx
@@ -11,8 +11,8 @@ import { renderWithConfirmContextProvider } from '../../../../../../test/lib/con
import configureStore from '../../../../../store/store';
import Header from './header';
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => jest.fn(),
}));
diff --git a/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.test.tsx b/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.test.tsx
index 7b39d48759cc..ee44a815d774 100644
--- a/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.test.tsx
+++ b/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.test.tsx
@@ -20,8 +20,8 @@ jest.mock('../../../hooks/useRedesignedSendFlow', () => ({
useRedesignedSendFlow: jest.fn().mockReturnValue({ enabled: false }),
}));
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => jest.fn(),
}));
diff --git a/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.tsx b/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.tsx
index 0f8142ba542c..a6d17557c578 100644
--- a/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.tsx
+++ b/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.tsx
@@ -4,7 +4,7 @@ import {
} from '@metamask/transaction-controller';
import React, { useCallback } from 'react';
import { useDispatch } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { MetaMetricsEventLocation } from '../../../../../../shared/constants/metametrics';
import { AssetType } from '../../../../../../shared/constants/transaction';
import {
diff --git a/ui/pages/confirmations/components/confirm/info/approve/hooks/use-is-nft.test.ts b/ui/pages/confirmations/components/confirm/info/approve/hooks/use-is-nft.test.ts
index 2749da270bed..f13b74ed724d 100644
--- a/ui/pages/confirmations/components/confirm/info/approve/hooks/use-is-nft.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/approve/hooks/use-is-nft.test.ts
@@ -5,7 +5,7 @@ import {
genUnapprovedContractInteractionConfirmation,
} from '../../../../../../../../test/data/confirmations/contract-interaction';
import mockState from '../../../../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../../../../test/lib/render-helpers-navigate';
import { getTokenStandardAndDetailsByChain } from '../../../../../../../store/actions';
import { useIsNFT } from './use-is-nft';
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useEIP1559TxFees.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useEIP1559TxFees.test.ts
index 4c7a53f8b041..4cc8243b18eb 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useEIP1559TxFees.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useEIP1559TxFees.test.ts
@@ -4,7 +4,7 @@ import {
genUnapprovedContractInteractionConfirmation,
} from '../../../../../../../test/data/confirmations/contract-interaction';
import mockState from '../../../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import { useEIP1559TxFees } from './useEIP1559TxFees';
describe('useEIP1559TxFees', () => {
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts
index dd986ed1b4dd..d4f98b87e95f 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts
@@ -1,5 +1,5 @@
import mockState from '../../../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import { useFourByte } from './useFourByte';
const DATA_MOCK = '0xd0e30db0';
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.test.ts
index 95c8f8a5a63d..cf621dc240df 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.test.ts
@@ -1,6 +1,6 @@
import { renderHook } from '@testing-library/react-hooks';
import { TransactionType } from '@metamask/transaction-controller';
-import { useSearchParams } from 'react-router-dom-v5-compat';
+import { useSearchParams } from 'react-router-dom';
import { merge } from 'lodash';
import { updateEditableParams } from '../../../../../../store/actions';
@@ -13,8 +13,8 @@ import {
import { useMaxValueRefresher } from './useMaxValueRefresher';
import { useSupportsEIP1559 } from './useSupportsEIP1559';
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useLocation: () => ({ pathname: '/send/asset' }),
useSearchParams: jest.fn().mockReturnValue([{ get: () => null }]),
}));
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.ts b/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.ts
index c5d966cb8fe8..54a6265e9e7b 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.ts
@@ -5,7 +5,7 @@ import {
type TransactionMeta,
} from '@metamask/transaction-controller';
import { Hex } from '@metamask/utils';
-import { useSearchParams } from 'react-router-dom-v5-compat';
+import { useSearchParams } from 'react-router-dom';
import {
getCrossChainMetaMaskCachedBalances,
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.test.ts
index 018bb34703fa..5ba35f0340d1 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.test.ts
@@ -1,5 +1,5 @@
import { BatchTransactionParams } from '@metamask/transaction-controller';
-import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../../../test/data/mock-state.json';
import { useNestedTransactionLabels } from './useNestedTransactionLabels';
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useSupportsEIP1559.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useSupportsEIP1559.test.ts
index 378526b96262..26657e56d94b 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useSupportsEIP1559.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useSupportsEIP1559.test.ts
@@ -7,7 +7,7 @@ import {
genUnapprovedContractInteractionConfirmation,
} from '../../../../../../../test/data/confirmations/contract-interaction';
import mockState from '../../../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import { useSupportsEIP1559 } from './useSupportsEIP1559';
describe('useSupportsEIP1559', () => {
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useTokenDetails.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useTokenDetails.test.ts
index c16049de9fbf..2d58032a822a 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useTokenDetails.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useTokenDetails.test.ts
@@ -2,7 +2,7 @@ import { TransactionMeta } from '@metamask/transaction-controller';
import { useSelector } from 'react-redux';
import { genUnapprovedTokenTransferConfirmation } from '../../../../../../../test/data/confirmations/token-transfer';
import mockState from '../../../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import { selectERC20TokensByChain } from '../../../../../../selectors';
import { useTokenDetails } from './useTokenDetails';
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useTransactionGasFeeEstimate.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useTransactionGasFeeEstimate.test.ts
index 5531aeccff52..089fef260ccb 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useTransactionGasFeeEstimate.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useTransactionGasFeeEstimate.test.ts
@@ -4,7 +4,7 @@ import {
genUnapprovedContractInteractionConfirmation,
} from '../../../../../../../test/data/confirmations/contract-interaction';
import mockState from '../../../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import { useGasFeeEstimates } from '../../../../../../hooks/useGasFeeEstimates';
import { useTransactionGasFeeEstimate } from './useTransactionGasFeeEstimate';
diff --git a/ui/pages/confirmations/components/confirm/info/info.test.tsx b/ui/pages/confirmations/components/confirm/info/info.test.tsx
index a5dda92e7016..748b26157c64 100644
--- a/ui/pages/confirmations/components/confirm/info/info.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/info.test.tsx
@@ -1,7 +1,7 @@
import { screen, waitFor } from '@testing-library/react';
import React from 'react';
import configureMockStore from 'redux-mock-store';
-import { useParams } from 'react-router-dom-v5-compat';
+import { useParams } from 'react-router-dom';
import {
getMockAddEthereumChainConfirmState,
getMockApproveConfirmState,
@@ -58,8 +58,8 @@ jest.mock('../../../../../../shared/modules/environment', () => ({
isGatorPermissionsFeatureEnabled: jest.fn().mockReturnValue(true),
}));
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useParams: jest.fn(),
}));
diff --git a/ui/pages/confirmations/components/confirm/info/native-transfer/native-transfer.test.tsx b/ui/pages/confirmations/components/confirm/info/native-transfer/native-transfer.test.tsx
index 3af59bbf7cdd..3168e55b1997 100644
--- a/ui/pages/confirmations/components/confirm/info/native-transfer/native-transfer.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/native-transfer/native-transfer.test.tsx
@@ -9,8 +9,8 @@ jest.mock('../../../simulation-details/useBalanceChanges', () => ({
useBalanceChanges: jest.fn(() => ({ pending: false, value: [] })),
}));
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useLocation: () => ({ pathname: '/' }),
useSearchParams: jest.fn().mockReturnValue([{ get: () => null }]),
}));
diff --git a/ui/pages/confirmations/components/confirm/info/shared/edit-gas-icon/edit-gas-icon-button.test.tsx b/ui/pages/confirmations/components/confirm/info/shared/edit-gas-icon/edit-gas-icon-button.test.tsx
index aefbc806de9f..4f4d031d7c6c 100644
--- a/ui/pages/confirmations/components/confirm/info/shared/edit-gas-icon/edit-gas-icon-button.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shared/edit-gas-icon/edit-gas-icon-button.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import mockState from '../../../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../../test/lib/render-helpers-navigate';
import { EditGasIconButton } from './edit-gas-icon-button';
describe(' ', () => {
diff --git a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/account-details.test.tsx b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/account-details.test.tsx
index 966e15f496ce..a00c7080bebf 100644
--- a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/account-details.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/account-details.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import configureMockStore from 'redux-mock-store';
import { getMockConfirmState } from '../../../../../../../test/data/confirmations/helper';
import { tEn } from '../../../../../../../test/lib/i18n-helpers';
-import { renderWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import { AccountDetails } from './account-details';
jest.mock('../../../../../../components/app/confirm/info/row/address', () => ({
diff --git a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/estimated-changes.test.tsx b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/estimated-changes.test.tsx
index 7d449a3aac5f..ea6e1ac12acf 100644
--- a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/estimated-changes.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/estimated-changes.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import configureMockStore from 'redux-mock-store';
import { getMockConfirmState } from '../../../../../../../test/data/confirmations/helper';
import { tEn } from '../../../../../../../test/lib/i18n-helpers';
-import { renderWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import { EstimatedChanges } from './estimated-changes';
jest.mock('../../../../../../components/app/name/name', () => ({
diff --git a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/subscription-details.test.tsx b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/subscription-details.test.tsx
index 9a915cb55ba1..201def2853c8 100644
--- a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/subscription-details.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/subscription-details.test.tsx
@@ -6,7 +6,7 @@ import {
} from '@metamask/subscription-controller';
import { getMockConfirmState } from '../../../../../../../test/data/confirmations/helper';
import { tEn } from '../../../../../../../test/lib/i18n-helpers';
-import { renderWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import { SubscriptionDetails } from './subscription-details';
const mockProductPrice: ProductPrice = {
diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/native-value-display/native-value-display.test.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/native-value-display/native-value-display.test.tsx
index 74a5bb1894b0..b693f752a67f 100644
--- a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/native-value-display/native-value-display.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/native-value-display/native-value-display.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import configureMockStore from 'redux-mock-store';
import mockState from '../../../../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../../../test/lib/render-helpers-navigate';
import NativeValueDisplay from './native-value-display';
describe('NativeValueDisplay', () => {
diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/value-display/value-display.test.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/value-display/value-display.test.tsx
index aaa5225dc37e..b9beadb31fbc 100644
--- a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/value-display/value-display.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/value-display/value-display.test.tsx
@@ -3,7 +3,7 @@ import { act } from 'react-dom/test-utils';
import configureMockStore from 'redux-mock-store';
import mockState from '../../../../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../../../test/lib/render-helpers-navigate';
import { MetaMetricsContext } from '../../../../../../../../contexts/metametrics';
import PermitSimulationValueDisplay from './value-display';
diff --git a/ui/pages/confirmations/components/confirm/nav/nav.test.tsx b/ui/pages/confirmations/components/confirm/nav/nav.test.tsx
index 8d72d9502b3a..8b530e2fafe7 100644
--- a/ui/pages/confirmations/components/confirm/nav/nav.test.tsx
+++ b/ui/pages/confirmations/components/confirm/nav/nav.test.tsx
@@ -17,9 +17,9 @@ jest.mock('react-redux', () => ({
}));
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/confirmations/components/confirm/row/dataTree.test.tsx b/ui/pages/confirmations/components/confirm/row/dataTree.test.tsx
index 35dafe552cb7..90e69f4d2b71 100644
--- a/ui/pages/confirmations/components/confirm/row/dataTree.test.tsx
+++ b/ui/pages/confirmations/components/confirm/row/dataTree.test.tsx
@@ -5,7 +5,7 @@ import {
permitSignatureMsg,
} from '../../../../../../test/data/confirmations/typed_sign';
import mockState from '../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import { DataTree } from './dataTree';
diff --git a/ui/pages/confirmations/components/confirm/row/typed-sign-data-v1/typedSignDataV1.test.tsx b/ui/pages/confirmations/components/confirm/row/typed-sign-data-v1/typedSignDataV1.test.tsx
index e01a42782033..95ee7e04f0f8 100644
--- a/ui/pages/confirmations/components/confirm/row/typed-sign-data-v1/typedSignDataV1.test.tsx
+++ b/ui/pages/confirmations/components/confirm/row/typed-sign-data-v1/typedSignDataV1.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import mockState from '../../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import { unapprovedTypedSignMsgV1 } from '../../../../../../../test/data/confirmations/typed_sign';
import { TypedSignDataV1Type } from '../../../../types/confirm';
import { ConfirmInfoRowTypedSignDataV1 } from './typedSignDataV1';
diff --git a/ui/pages/confirmations/components/confirm/row/typed-sign-data/typedSignData.test.tsx b/ui/pages/confirmations/components/confirm/row/typed-sign-data/typedSignData.test.tsx
index 0d7b6d7e0979..0fa84334b063 100644
--- a/ui/pages/confirmations/components/confirm/row/typed-sign-data/typedSignData.test.tsx
+++ b/ui/pages/confirmations/components/confirm/row/typed-sign-data/typedSignData.test.tsx
@@ -4,7 +4,7 @@ import {
unapprovedTypedSignMsgV4,
} from '../../../../../../../test/data/confirmations/typed_sign';
import mockState from '../../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../../store/store';
import { ConfirmInfoRowTypedSignData } from './typedSignData';
diff --git a/ui/pages/confirmations/components/confirm/smart-account-tab/account-network/account-network.test.tsx b/ui/pages/confirmations/components/confirm/smart-account-tab/account-network/account-network.test.tsx
index 35f167231a5c..28380d2ac67e 100644
--- a/ui/pages/confirmations/components/confirm/smart-account-tab/account-network/account-network.test.tsx
+++ b/ui/pages/confirmations/components/confirm/smart-account-tab/account-network/account-network.test.tsx
@@ -3,7 +3,7 @@ import { Hex } from '@metamask/utils';
import { fireEvent } from '@testing-library/dom';
import mockState from '../../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../../store/store';
import { EIP7702NetworkConfiguration } from '../../../../hooks/useBatchAuthorizationRequests';
import { AccountNetwork } from './account-network';
diff --git a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.test.tsx b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.test.tsx
index 349e85c312b0..d6b93f3dd9f0 100644
--- a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.test.tsx
+++ b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.test.tsx
@@ -7,9 +7,9 @@ import { renderWithConfirmContextProvider } from '../../../../../../test/lib/con
import { SmartAccountUpdateSuccess } from './smart-account-update-success';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.tsx b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.tsx
index 06c6a62121ed..456e1ecfc55a 100644
--- a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.tsx
+++ b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.tsx
@@ -1,5 +1,5 @@
import React, { useCallback } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import ZENDESK_URLS from '../../../../../helpers/constants/zendesk-url';
import {
diff --git a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.test.tsx b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.test.tsx
index 1d9a478c4e3f..adac87a9b468 100644
--- a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.test.tsx
+++ b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.test.tsx
@@ -10,9 +10,9 @@ import { setSmartAccountOptIn } from '../../../../../store/actions';
import { SmartAccountUpdate } from './smart-account-update';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.tsx b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.tsx
index 884c237c65ab..036780652b78 100644
--- a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.tsx
+++ b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.tsx
@@ -1,6 +1,6 @@
import React, { useCallback, useState } from 'react';
import { useDispatch } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
Box,
diff --git a/ui/pages/confirmations/components/edit-gas-display/edit-gas-display.test.js b/ui/pages/confirmations/components/edit-gas-display/edit-gas-display.test.js
index c59a1e134dc4..9d177ab5da04 100644
--- a/ui/pages/confirmations/components/edit-gas-display/edit-gas-display.test.js
+++ b/ui/pages/confirmations/components/edit-gas-display/edit-gas-display.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider } from '../../../../../test/jest';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../store/store';
import EditGasDisplay from '.';
diff --git a/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js b/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
index 55b27e3d4234..42bdf9e93a2e 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
@@ -9,7 +9,7 @@ import {
} from '../../../../../shared/constants/gas';
import { GasFeeContextProvider } from '../../../../contexts/gasFee';
-import { renderWithProvider } from '../../../../../test/jest';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockEstimates from '../../../../../test/data/mock-estimates.json';
import mockState from '../../../../../test/data/mock-state.json';
import configureStore from '../../../../store/store';
diff --git a/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js b/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js
index 1781314edbc6..4b990e2c5d01 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import { act, fireEvent, screen } from '@testing-library/react';
-import { renderWithProvider } from '../../../../../test/jest';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { GasFeeContextProvider } from '../../../../contexts/gasFee';
import configureStore from '../../../../store/store';
import mockState from '../../../../../test/data/mock-state.json';
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js
index 4d74e34be902..3f05286bd675 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js
@@ -7,7 +7,7 @@ import {
TransactionType,
} from '@metamask/transaction-controller';
import { EditGasModes } from '../../../../../shared/constants/gas';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../store/store';
import { GasFeeContextProvider } from '../../../../contexts/gasFee';
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js
index 95bd45506003..aa8ba6ce34d3 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js
@@ -5,7 +5,7 @@ import {
EditGasModes,
PriorityLevels,
} from '../../../../../../shared/constants/gas';
-import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import { GasFeeContextProvider } from '../../../../../contexts/gasFee';
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js
index 558190bb7dd3..71a40db9e57d 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import { act } from '@testing-library/react';
import configureStore from '../../../../../store/store';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { GasFeeContextProvider } from '../../../../../contexts/gasFee';
import { mockNetworkState } from '../../../../../../test/stub/networks';
import { CHAIN_IDS } from '../../../../../../shared/constants/network';
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/network-statistics.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/network-statistics.test.js
index 125495d09c83..2605f1ae9d0c 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/network-statistics.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/network-statistics.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { renderWithProvider, screen } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import { GasFeeContext } from '../../../../../contexts/gasFee';
import NetworkStatistics from './network-statistics';
@@ -16,53 +16,49 @@ const renderComponent = ({ gasFeeContext = {}, state = {} } = {}) => {
describe('NetworkStatistics', () => {
it('should render the latest base fee rounded to no decimal places', () => {
- renderComponent({
+ const { getByText } = renderComponent({
gasFeeContext: {
gasFeeEstimates: {
estimatedBaseFee: '50.0112',
},
},
});
- expect(screen.getByText('50 GWEI')).toBeInTheDocument();
+ expect(getByText('50 GWEI')).toBeInTheDocument();
});
it('should not render the latest base fee if it is not present', () => {
- renderComponent({
+ const { queryByTestId } = renderComponent({
gasFeeContext: {
gasFeeEstimates: {
estimatedBaseFee: null,
},
},
});
- expect(
- screen.queryByTestId('formatted-latest-base-fee'),
- ).not.toBeInTheDocument();
+ expect(queryByTestId('formatted-latest-base-fee')).not.toBeInTheDocument();
});
it('should not render the latest base fee if no gas fee estimates are available', () => {
- renderComponent({
+ const { queryByTestId } = renderComponent({
gasFeeContext: {
gasFeeEstimates: null,
},
});
- expect(
- screen.queryByTestId('formatted-latest-base-fee'),
- ).not.toBeInTheDocument();
+ expect(queryByTestId('formatted-latest-base-fee')).not.toBeInTheDocument();
});
it('should render the latest priority fee range, with the low end of the range rounded to 1 decimal place and the high end rounded to no decimal places', () => {
- renderComponent({
+ const { getByText } = renderComponent({
gasFeeContext: {
gasFeeEstimates: {
latestPriorityFeeRange: ['1.100001668', '2.5634234'],
},
},
});
- expect(screen.getByText('1.1 - 3 GWEI')).toBeInTheDocument();
+ expect(getByText('1.1 - 3 GWEI')).toBeInTheDocument();
});
it('should not render the latest priority fee range if it is not present', () => {
- renderComponent({
+ const { queryByTestId } = renderComponent({
gasFeeContext: {
gasFeeEstimates: {
latestPriorityFeeRange: null,
@@ -70,49 +66,49 @@ describe('NetworkStatistics', () => {
},
});
expect(
- screen.queryByTestId('formatted-latest-priority-fee-range'),
+ queryByTestId('formatted-latest-priority-fee-range'),
).not.toBeInTheDocument();
});
it('should not render the latest priority fee range if no gas fee estimates are available', () => {
- renderComponent({
+ const { queryByTestId } = renderComponent({
gasFeeContext: {
gasFeeEstimates: null,
},
});
expect(
- screen.queryByTestId('formatted-latest-priority-fee-range'),
+ queryByTestId('formatted-latest-priority-fee-range'),
).not.toBeInTheDocument();
});
it('should render the network status slider', () => {
- renderComponent({
+ const { getByText } = renderComponent({
gasFeeContext: {
gasFeeEstimates: {
networkCongestion: 0.5,
},
},
});
- expect(screen.getByText('Stable')).toBeInTheDocument();
+ expect(getByText('Stable')).toBeInTheDocument();
});
it('should not render the network status slider if the network congestion is not available', () => {
- renderComponent({
+ const { queryByTestId } = renderComponent({
gasFeeContext: {
gasFeeEstimates: {
networkCongestion: null,
},
},
});
- expect(screen.queryByTestId('status-slider-label')).not.toBeInTheDocument();
+ expect(queryByTestId('status-slider-label')).not.toBeInTheDocument();
});
it('should not render the network status slider if no gas fee estimates are available', () => {
- renderComponent({
+ const { queryByTestId } = renderComponent({
gasFeeContext: {
gasFeeEstimates: null,
},
});
- expect(screen.queryByTestId('status-slider-label')).not.toBeInTheDocument();
+ expect(queryByTestId('status-slider-label')).not.toBeInTheDocument();
});
});
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js
index 4811469a667b..04fdf348bdd7 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js
@@ -1,6 +1,6 @@
import React from 'react';
-import { renderWithProvider } from '../../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate';
import { GasFeeContext } from '../../../../../../contexts/gasFee';
import configureStore from '../../../../../../store/store';
diff --git a/ui/pages/confirmations/components/fee-details-component/fee-details-component.test.js b/ui/pages/confirmations/components/fee-details-component/fee-details-component.test.js
index 99f7812a4978..3e0d544b163b 100644
--- a/ui/pages/confirmations/components/fee-details-component/fee-details-component.test.js
+++ b/ui/pages/confirmations/components/fee-details-component/fee-details-component.test.js
@@ -2,7 +2,7 @@ import React from 'react';
import { act, screen } from '@testing-library/react';
import configureStore from 'redux-mock-store';
import mockState from '../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { mockNetworkState } from '../../../../../test/stub/networks';
import { CHAIN_IDS } from '../../../../../shared/constants/network';
import FeeDetailsComponent from './fee-details-component';
diff --git a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
index 3e45b4c87722..b895e7c2adf7 100644
--- a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
+++ b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
@@ -5,7 +5,7 @@ import { GasEstimateTypes } from '../../../../../shared/constants/gas';
import mockEstimates from '../../../../../test/data/mock-estimates.json';
import mockState from '../../../../../test/data/mock-state.json';
import { GasFeeContextProvider } from '../../../../contexts/gasFee';
-import { renderWithProvider } from '../../../../../test/jest';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../store/store';
import { getSelectedInternalAccountFromMockState } from '../../../../../test/jest/mocks';
diff --git a/ui/pages/confirmations/components/gas-timing/gas-timing.component.test.js b/ui/pages/confirmations/components/gas-timing/gas-timing.component.test.js
index 5252fd8df6da..6469ea8347f0 100644
--- a/ui/pages/confirmations/components/gas-timing/gas-timing.component.test.js
+++ b/ui/pages/confirmations/components/gas-timing/gas-timing.component.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import { waitFor } from '@testing-library/react';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { GasEstimateTypes } from '../../../../../shared/constants/gas';
import mockState from '../../../../../test/data/mock-state.json';
diff --git a/ui/pages/confirmations/components/multilayer-fee-message/multi-layer-fee-message.test.js b/ui/pages/confirmations/components/multilayer-fee-message/multi-layer-fee-message.test.js
index 42f28d3f980b..23176b4c2508 100644
--- a/ui/pages/confirmations/components/multilayer-fee-message/multi-layer-fee-message.test.js
+++ b/ui/pages/confirmations/components/multilayer-fee-message/multi-layer-fee-message.test.js
@@ -2,7 +2,7 @@ import React from 'react';
import { toHex } from '@metamask/controller-utils';
import mockState from '../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../store/store';
import MultilayerFeeMessage from './multi-layer-fee-message';
diff --git a/ui/pages/confirmations/components/send/amount-recipient/amount-recipient.test.tsx b/ui/pages/confirmations/components/send/amount-recipient/amount-recipient.test.tsx
index b85ff48214fa..3cbdf63bd935 100644
--- a/ui/pages/confirmations/components/send/amount-recipient/amount-recipient.test.tsx
+++ b/ui/pages/confirmations/components/send/amount-recipient/amount-recipient.test.tsx
@@ -19,8 +19,8 @@ import { AmountRecipient } from './amount-recipient';
const MOCK_ADDRESS = '0xdB055877e6c13b6A6B25aBcAA29B393777dD0a73';
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useLocation: () => ({ pathname: '/send/asset' }),
useSearchParams: jest.fn().mockReturnValue([{ get: () => null }]),
}));
diff --git a/ui/pages/confirmations/components/send/amount/amount.test.tsx b/ui/pages/confirmations/components/send/amount/amount.test.tsx
index 8acf541b6c54..2db1c5eff672 100644
--- a/ui/pages/confirmations/components/send/amount/amount.test.tsx
+++ b/ui/pages/confirmations/components/send/amount/amount.test.tsx
@@ -9,7 +9,7 @@ import {
SOLANA_ASSET,
} from '../../../../../../test/data/send/assets';
import { Numeric } from '../../../../../../shared/modules/Numeric';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import * as AmountSelectionMetrics from '../../../hooks/send/metrics/useAmountSelectionMetrics';
import * as BalanceFunctions from '../../../hooks/send/useBalance';
diff --git a/ui/pages/confirmations/components/send/header/header.test.tsx b/ui/pages/confirmations/components/send/header/header.test.tsx
index 865e5abe3d59..915c8cc14ad7 100644
--- a/ui/pages/confirmations/components/send/header/header.test.tsx
+++ b/ui/pages/confirmations/components/send/header/header.test.tsx
@@ -7,8 +7,8 @@ import configureStore from '../../../../../store/store';
import { Header } from './header';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => ({ pathname: '/send/asset' }),
useSearchParams: jest
diff --git a/ui/pages/confirmations/components/send/hex-data/hex-data.test.tsx b/ui/pages/confirmations/components/send/hex-data/hex-data.test.tsx
index 09dedbe4a68c..a0d4f75ef148 100644
--- a/ui/pages/confirmations/components/send/hex-data/hex-data.test.tsx
+++ b/ui/pages/confirmations/components/send/hex-data/hex-data.test.tsx
@@ -7,7 +7,7 @@ import {
EVM_NATIVE_ASSET,
MOCK_NFT1155,
} from '../../../../../../test/data/send/assets';
-import { renderWithProvider } from '../../../../../../test/jest';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../../store/store';
import * as SendContext from '../../../context/send';
import { HexData } from './hex-data';
diff --git a/ui/pages/confirmations/components/send/loader/loader.test.tsx b/ui/pages/confirmations/components/send/loader/loader.test.tsx
index c825fc6e4181..2ca9cf3626da 100644
--- a/ui/pages/confirmations/components/send/loader/loader.test.tsx
+++ b/ui/pages/confirmations/components/send/loader/loader.test.tsx
@@ -10,9 +10,9 @@ import { CONFIRMATION_V_NEXT_ROUTE } from '../../../../../helpers/constants/rout
import { Loader } from './loader';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/confirmations/components/send/loader/loader.tsx b/ui/pages/confirmations/components/send/loader/loader.tsx
index 260858f7ea67..94aab8b149b2 100644
--- a/ui/pages/confirmations/components/send/loader/loader.tsx
+++ b/ui/pages/confirmations/components/send/loader/loader.tsx
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import {
diff --git a/ui/pages/confirmations/components/send/recipient-input/recipient-input.test.tsx b/ui/pages/confirmations/components/send/recipient-input/recipient-input.test.tsx
index 58b5cb25e125..c3f01b2020f3 100644
--- a/ui/pages/confirmations/components/send/recipient-input/recipient-input.test.tsx
+++ b/ui/pages/confirmations/components/send/recipient-input/recipient-input.test.tsx
@@ -3,7 +3,7 @@ import { fireEvent } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import configureStore from '../../../../../store/store';
import mockState from '../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { useI18nContext } from '../../../../../hooks/useI18nContext';
import { useRecipientSelectionMetrics } from '../../../hooks/send/metrics/useRecipientSelectionMetrics';
import { useSendContext } from '../../../context/send';
diff --git a/ui/pages/confirmations/components/send/recipient/recipient.test.tsx b/ui/pages/confirmations/components/send/recipient/recipient.test.tsx
index 12af8303871a..84b886d070c0 100644
--- a/ui/pages/confirmations/components/send/recipient/recipient.test.tsx
+++ b/ui/pages/confirmations/components/send/recipient/recipient.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { fireEvent } from '@testing-library/react';
import configureStore from '../../../../../store/store';
import mockState from '../../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { useI18nContext } from '../../../../../hooks/useI18nContext';
import { useRecipientSelectionMetrics } from '../../../hooks/send/metrics/useRecipientSelectionMetrics';
import { useSendContext } from '../../../context/send';
diff --git a/ui/pages/confirmations/components/simulation-details/asset-pill.test.tsx b/ui/pages/confirmations/components/simulation-details/asset-pill.test.tsx
index f6593346ca3f..954e7aad37e3 100644
--- a/ui/pages/confirmations/components/simulation-details/asset-pill.test.tsx
+++ b/ui/pages/confirmations/components/simulation-details/asset-pill.test.tsx
@@ -4,7 +4,7 @@ import { NameType } from '@metamask/name-controller';
import { Hex } from '@metamask/utils';
import { TokenStandard } from '../../../../../shared/constants/transaction';
import Name from '../../../../components/app/name';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../store/store';
import { CHAIN_IDS } from '../../../../../shared/constants/network';
import { AvatarNetwork } from '../../../../components/component-library/avatar-network';
diff --git a/ui/pages/confirmations/components/simulation-details/fiat-display.test.tsx b/ui/pages/confirmations/components/simulation-details/fiat-display.test.tsx
index 6dd575f202d5..c3f2cd0697c3 100644
--- a/ui/pages/confirmations/components/simulation-details/fiat-display.test.tsx
+++ b/ui/pages/confirmations/components/simulation-details/fiat-display.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { screen } from '@testing-library/react';
import configureStore from 'redux-mock-store';
import { merge } from 'lodash';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import { mockNetworkState } from '../../../../../test/stub/networks';
import { CHAIN_IDS } from '../../../../../shared/constants/network';
diff --git a/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx b/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx
index febc51d93fb3..7e8259ccbf56 100644
--- a/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx
+++ b/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx
@@ -12,7 +12,7 @@ import configureStore from 'redux-mock-store';
import { cloneDeep } from 'lodash';
import { TokenStandard } from '../../../../../shared/constants/transaction';
import mockState from '../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { AlertMetricsProvider } from '../../../../components/app/alert-system/contexts/alertMetricsContext';
import { BalanceChangeList } from './balance-change-list';
import { SimulationDetails, StaticRow } from './simulation-details';
diff --git a/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.test.js b/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.test.js
index a99935e4fb42..2c803d6a33c5 100644
--- a/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.test.js
+++ b/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import { fireEvent } from '@testing-library/react';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import SimulationErrorMessage from './simulation-error-message';
describe('Simulation Error Message', () => {
diff --git a/ui/pages/confirmations/components/smart-transactions-banner-alert/smart-transactions-banner-alert.test.tsx b/ui/pages/confirmations/components/smart-transactions-banner-alert/smart-transactions-banner-alert.test.tsx
index 773a4d5d2928..6b30a51dd5c7 100644
--- a/ui/pages/confirmations/components/smart-transactions-banner-alert/smart-transactions-banner-alert.test.tsx
+++ b/ui/pages/confirmations/components/smart-transactions-banner-alert/smart-transactions-banner-alert.test.tsx
@@ -4,7 +4,7 @@ import { screen } from '@testing-library/react';
import { TransactionType } from '@metamask/transaction-controller';
import { ConfirmContext, ConfirmContextType } from '../../context/confirm';
import type { Confirmation, SignatureRequestType } from '../../types/confirm';
-import { renderWithProvider } from '../../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../../store/store';
import { AlertTypes } from '../../../../../shared/constants/alerts';
import { setAlertEnabledness } from '../../../../store/actions';
diff --git a/ui/pages/confirmations/components/snap-account-error-message/SnapAccountErrorMessage.test.tsx b/ui/pages/confirmations/components/snap-account-error-message/SnapAccountErrorMessage.test.tsx
index 6fcf1b499944..00cd2f8e728f 100644
--- a/ui/pages/confirmations/components/snap-account-error-message/SnapAccountErrorMessage.test.tsx
+++ b/ui/pages/confirmations/components/snap-account-error-message/SnapAccountErrorMessage.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import configureStore from '../../../../store/store';
import mockState from '../../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../../test/jest';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import SnapAccountErrorMessage from './SnapAccountErrorMessage';
const store = configureStore({
diff --git a/ui/pages/confirmations/components/snap-account-success-message/SnapAccountSuccessMessage.test.tsx b/ui/pages/confirmations/components/snap-account-success-message/SnapAccountSuccessMessage.test.tsx
index 10a690bd2f27..33c07ebf93e5 100644
--- a/ui/pages/confirmations/components/snap-account-success-message/SnapAccountSuccessMessage.test.tsx
+++ b/ui/pages/confirmations/components/snap-account-success-message/SnapAccountSuccessMessage.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import configureStore from '../../../../store/store';
// Use mock-send-state to have some identites being populated
import mockState from '../../../../../test/data/mock-send-state.json';
-import { renderWithProvider } from '../../../../../test/jest';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import SnapAccountSuccessMessage from './SnapAccountSuccessMessage';
const store = configureStore(mockState);
diff --git a/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js b/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
index 26a03506737c..e91848a7a594 100644
--- a/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
+++ b/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
@@ -5,7 +5,7 @@ import { TransactionEnvelopeType } from '@metamask/transaction-controller';
import { GasEstimateTypes } from '../../../../../shared/constants/gas';
import { GasFeeContextProvider } from '../../../../contexts/gasFee';
-import { renderWithProvider } from '../../../../../test/jest';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockEstimates from '../../../../../test/data/mock-estimates.json';
import mockState from '../../../../../test/data/mock-state.json';
import configureStore from '../../../../store/store';
diff --git a/ui/pages/confirmations/confirm-transaction-switch/confirm-transaction-switch.component.js b/ui/pages/confirmations/confirm-transaction-switch/confirm-transaction-switch.component.js
index 920930ffb739..1535a6080734 100644
--- a/ui/pages/confirmations/confirm-transaction-switch/confirm-transaction-switch.component.js
+++ b/ui/pages/confirmations/confirm-transaction-switch/confirm-transaction-switch.component.js
@@ -1,6 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import { Navigate } from 'react-router-dom-v5-compat';
+import { Navigate } from 'react-router-dom';
import Loading from '../../../components/ui/loading-screen';
import {
CONFIRM_TRANSACTION_ROUTE,
diff --git a/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js b/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js
index 681385d5d335..df7943ef3e8a 100644
--- a/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js
+++ b/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { Routes, Route } from 'react-router-dom-v5-compat';
+import { Routes, Route } from 'react-router-dom';
import ConfirmTransactionSwitch from '../confirm-transaction-switch';
export default function ConfirmTokenTransactionSwitch() {
diff --git a/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js b/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js
index 25b3220d7730..23738b9ae68e 100644
--- a/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js
+++ b/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js
@@ -1,13 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react';
-import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
-import {
- Routes,
- Route,
- useNavigate,
- useParams,
- useLocation,
-} from 'react-router-dom-v5-compat';
+import { Routes, Route, useNavigate, useParams } from 'react-router-dom';
import {
ENVIRONMENT_TYPE_NOTIFICATION,
ORIGIN_METAMASK,
@@ -22,11 +15,11 @@ import { getMostRecentOverviewPage } from '../../../ducks/history/history';
import { getSendTo } from '../../../ducks/send';
import { getSelectedNetworkClientId } from '../../../../shared/modules/selectors/networks';
import {
- CONFIRM_TRANSACTION_ROUTE,
DECRYPT_MESSAGE_REQUEST_PATH,
DEFAULT_ROUTE,
ENCRYPTION_PUBLIC_KEY_REQUEST_PATH,
} from '../../../helpers/constants/routes';
+import { toRelativeRoutePath } from '../../routes/utils';
import { isTokenMethodAction } from '../../../helpers/utils/transactions.util';
import usePolling from '../../../hooks/usePolling';
import { usePrevious } from '../../../hooks/usePrevious';
@@ -54,20 +47,12 @@ import { useAsyncResult } from '../../../hooks/useAsync';
import { TraceName } from '../../../../shared/lib/trace';
import ConfirmTokenTransactionSwitch from './confirm-token-transaction-switch';
-const ConfirmTransaction = ({
- params: routeParams,
- location: routeLocation,
-} = {}) => {
+const ConfirmTransaction = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
const urlParams = useParams();
- const hookLocation = useLocation();
-
- // Use params from props (v5 route) if available, otherwise fall back to useParams (v6)
- const { id: paramsTransactionId } = routeParams || urlParams;
- // Use location from props (v5 route) if available, otherwise fall back to useLocation (v6)
- const location = routeLocation || hookLocation;
+ const { id: paramsTransactionId } = urlParams;
const mostRecentOverviewPage = useSelector(getMostRecentOverviewPage);
const sendTo = useSelector(getSendTo);
@@ -216,13 +201,13 @@ const ConfirmTransaction = ({
// support URLs of /confirm-transaction or /confirm-transaction/
if (isValidTransactionId) {
return (
-
+
}
/>
}
/>
} />
@@ -233,17 +218,4 @@ const ConfirmTransaction = ({
return ;
};
-ConfirmTransaction.propTypes = {
- params: PropTypes.shape({
- id: PropTypes.string,
- }),
- location: PropTypes.shape({
- pathname: PropTypes.string,
- search: PropTypes.string,
- hash: PropTypes.string,
- state: PropTypes.object,
- key: PropTypes.string,
- }),
-};
-
export default ConfirmTransaction;
diff --git a/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js b/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js
index 4834cb4c895a..b8be113b9490 100644
--- a/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js
+++ b/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js
@@ -1,11 +1,19 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
+import { Provider } from 'react-redux';
+import { render } from '@testing-library/react';
+import { MemoryRouter, Routes, Route } from 'react-router-dom';
import * as ConfirmTransactionDucks from '../../../ducks/confirm-transaction/confirm-transaction.duck';
import * as Actions from '../../../store/actions';
import _mockState from '../../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
+import {
+ renderWithProvider,
+ I18nProvider,
+} from '../../../../test/lib/render-helpers-navigate';
+import { LegacyI18nProvider } from '../../../contexts/i18n';
import { setBackgroundConnection } from '../../../store/background-connection';
+import * as en from '../../../../app/_locales/en/messages.json';
import {
CONFIRM_TRANSACTION_ROUTE,
@@ -47,14 +55,17 @@ jest.mock(
setTransactionToConfirm: jest.fn().mockImplementation((txId) => {
return { type: 'mock-set-transaction-to-confirm', value: txId };
}),
+ clearConfirmTransaction: jest.fn().mockImplementation(() => {
+ return { type: 'mock-clear-confirm-transaction' };
+ }),
}),
);
const mockUseNavigate = jest.fn();
const mockUseSearchParams = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useSearchParams: () => mockUseSearchParams(),
};
@@ -129,11 +140,37 @@ describe('Confirmation Transaction Page', () => {
[ENCRYPTION_PUBLIC_KEY_REQUEST_PATH, '.mock-confirm-encryption-public-key'],
].forEach(([componentPath, mockClassNameMatch]) => {
it(`should render "${componentPath}" route`, () => {
- const mockStore = configureMockStore(middleware)(mockState);
- const { container } = renderWithProvider(
- ,
- mockStore,
- `${CONFIRM_TRANSACTION_ROUTE}/${mockUnapprovedTx.id}${componentPath}`,
+ // Use string ID to match what useParams() returns
+ const txId = String(mockUnapprovedTx.id);
+ // Update the state to use string ID for consistency
+ const stateWithStringId = {
+ ...mockState,
+ metamask: {
+ ...mockState.metamask,
+ transactions: mockState.metamask.transactions.map((tx) => ({
+ ...tx,
+ id: String(tx.id),
+ })),
+ },
+ };
+ const mockStore = configureMockStore(middleware)(stateWithStringId);
+ const fullPath = `${CONFIRM_TRANSACTION_ROUTE}/${txId}${componentPath}`;
+ // Wrap in Routes with parent route to properly handle nested routing
+ const { container } = render(
+
+
+
+
+
+ }
+ />
+
+
+
+
+ ,
);
expect(container.querySelector(mockClassNameMatch)).toBeInTheDocument();
diff --git a/ui/pages/confirmations/confirm/confirm.test.tsx b/ui/pages/confirmations/confirm/confirm.test.tsx
index 1de0e9f11560..902fd40d5404 100644
--- a/ui/pages/confirmations/confirm/confirm.test.tsx
+++ b/ui/pages/confirmations/confirm/confirm.test.tsx
@@ -35,8 +35,8 @@ jest.mock('../hooks/gas/useIsGaslessLoading', () => ({
}));
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
- const actual = jest.requireActual('react-router-dom-v5-compat');
+jest.mock('react-router-dom', () => {
+ const actual = jest.requireActual('react-router-dom');
return {
...actual,
useNavigate: () => mockUseNavigate,
diff --git a/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts b/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts
index d56e7f7da0a9..9043c25a8187 100644
--- a/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts
+++ b/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts
@@ -2,7 +2,7 @@ import { ApprovalRequest } from '@metamask/approval-controller';
import { useDispatch } from 'react-redux';
import mockState from '../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import * as AlertActions from '../../../../ducks/confirm-alerts/confirm-alerts';
import * as UpdateEthereumChainAlerts from './useUpdateEthereumChainAlerts';
diff --git a/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.test.ts b/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.test.ts
index 37fb5afba54d..2327fbcbf2dc 100644
--- a/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.test.ts
+++ b/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.test.ts
@@ -3,7 +3,7 @@ import { ApprovalType } from '@metamask/controller-utils';
import mockState from '../../../../../test/data/mock-state.json';
import { getMockPersonalSignConfirmState } from '../../../../../test/data/confirmations/helper';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import * as AlertActions from '../../../../ducks/confirm-alerts/confirm-alerts';
import { useUpdateEthereumChainAlerts } from './useUpdateEthereumChainAlerts';
diff --git a/ui/pages/confirmations/confirmation/confirmation.js b/ui/pages/confirmations/confirmation/confirmation.js
index 3c6b72af4943..ae4186cbf91b 100644
--- a/ui/pages/confirmations/confirmation/confirmation.js
+++ b/ui/pages/confirmations/confirmation/confirmation.js
@@ -9,7 +9,7 @@ import React, {
} from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate, useParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useParams } from 'react-router-dom';
import { isEqual } from 'lodash';
import { produce } from 'immer';
import log from 'loglevel';
@@ -225,7 +225,6 @@ function Header({ confirmation, isSnapCustomUIDialog, onCancel }) {
export default function ConfirmationPage({
redirectToHomeOnZeroConfirmations = true,
- params: routeParams,
}) {
const t = useI18nContext();
const trackEvent = useContext(MetaMetricsContext);
@@ -245,8 +244,7 @@ export default function ConfirmationPage({
);
const [approvalFlowLoadingText, setApprovalFlowLoadingText] = useState(null);
- const urlParams = useParams();
- const { id } = routeParams || urlParams;
+ const { id } = useParams();
const pendingRoutedConfirmation = pendingConfirmations.find(
(confirmation) => confirmation.id === id,
@@ -617,7 +615,4 @@ export default function ConfirmationPage({
ConfirmationPage.propTypes = {
redirectToHomeOnZeroConfirmations: PropTypes.bool,
- params: PropTypes.shape({
- id: PropTypes.string,
- }),
};
diff --git a/ui/pages/confirmations/confirmation/templates/add-ethereum-chain.js b/ui/pages/confirmations/confirmation/templates/add-ethereum-chain.js
index b7d7d1572049..17941099d620 100644
--- a/ui/pages/confirmations/confirmation/templates/add-ethereum-chain.js
+++ b/ui/pages/confirmations/confirmation/templates/add-ethereum-chain.js
@@ -228,7 +228,7 @@ function getState(pendingApproval) {
return {};
}
-function getValues(pendingApproval, t, actions, history, data) {
+function getValues(pendingApproval, t, actions, navigate, data) {
const originIsMetaMask = pendingApproval.origin === 'metamask';
const customRpcUrl = pendingApproval.requestData.rpcUrl;
@@ -409,7 +409,7 @@ function getValues(pendingApproval, t, actions, history, data) {
locationPath === ONBOARDING_PRIVACY_SETTINGS_ROUTE;
if (!isOnboardingRoute) {
- history.push(DEFAULT_ROUTE);
+ navigate(DEFAULT_ROUTE);
}
}
return [];
diff --git a/ui/pages/confirmations/confirmation/templates/create-named-snap-account.js b/ui/pages/confirmations/confirmation/templates/create-named-snap-account.js
index 0b2b4aefbf40..addf06eb5ecf 100644
--- a/ui/pages/confirmations/confirmation/templates/create-named-snap-account.js
+++ b/ui/pages/confirmations/confirmation/templates/create-named-snap-account.js
@@ -10,13 +10,13 @@ import {
* @param {object} pendingApproval - The pending confirmation object.
* @param {Function} t - Translation function.
* @param {object} actions - Object containing safe actions that the template can invoke.
- * @param {object} _history - The application's history object (not used in this function).
+ * @param {object} _navigate - The application's navigate function (not used in this function).
* @param {object} _data - The data object passed into the template from the confirmation page (not
* used in this function).
* @param {object} contexts - Context objects passed into the template from the confirmation page.
* @returns {object} An object containing templated values for the confirmation page.
*/
-function getValues(pendingApproval, t, actions, _history, _data, contexts) {
+function getValues(pendingApproval, t, actions, _navigate, _data, contexts) {
const { origin: snapId, snapName, requestData } = pendingApproval;
const { snapSuggestedAccountName } = requestData;
const { trackEvent } = contexts;
diff --git a/ui/pages/confirmations/confirmation/templates/create-named-snap-account.test.js b/ui/pages/confirmations/confirmation/templates/create-named-snap-account.test.js
index e1c0269c71b8..7d3ea2db0aec 100644
--- a/ui/pages/confirmations/confirmation/templates/create-named-snap-account.test.js
+++ b/ui/pages/confirmations/confirmation/templates/create-named-snap-account.test.js
@@ -85,9 +85,9 @@ const mockBaseStore = {
};
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/confirmations/confirmation/templates/create-snap-account.js b/ui/pages/confirmations/confirmation/templates/create-snap-account.js
index 3ff9892f90c2..e3699510475c 100644
--- a/ui/pages/confirmations/confirmation/templates/create-snap-account.js
+++ b/ui/pages/confirmations/confirmation/templates/create-snap-account.js
@@ -4,7 +4,7 @@ import {
MetaMetricsEventAccountType,
} from '../../../../../shared/constants/metametrics';
-function getValues(pendingApproval, t, actions, _history, _data, contexts) {
+function getValues(pendingApproval, t, actions, _navigate, _data, contexts) {
const { origin: snapId, snapName } = pendingApproval;
const { trackEvent } = contexts;
diff --git a/ui/pages/confirmations/confirmation/templates/remove-snap-account.js b/ui/pages/confirmations/confirmation/templates/remove-snap-account.js
index f7f0324f5889..4c5e64f8712a 100644
--- a/ui/pages/confirmations/confirmation/templates/remove-snap-account.js
+++ b/ui/pages/confirmations/confirmation/templates/remove-snap-account.js
@@ -4,7 +4,7 @@ import {
MetaMetricsEventAccountType,
} from '../../../../../shared/constants/metametrics';
-function getValues(pendingApproval, t, actions, _history, _data, contexts) {
+function getValues(pendingApproval, t, actions, _navigate, _data, contexts) {
const { origin: snapId, snapName } = pendingApproval;
const { publicAddress } = pendingApproval.requestData;
const { trackEvent } = contexts;
diff --git a/ui/pages/confirmations/confirmation/templates/smart-transaction-status-page.js b/ui/pages/confirmations/confirmation/templates/smart-transaction-status-page.js
index 0143e26310ae..1d3ec6d2645a 100644
--- a/ui/pages/confirmations/confirmation/templates/smart-transaction-status-page.js
+++ b/ui/pages/confirmations/confirmation/templates/smart-transaction-status-page.js
@@ -1,5 +1,5 @@
// eslint-disable-next-line no-unused-vars
-function getValues(pendingApproval, t, actions, _history) {
+function getValues(pendingApproval, t, actions, _navigate) {
const { id, requestState } = pendingApproval;
return {
content: [
diff --git a/ui/pages/confirmations/confirmation/templates/snap-account-redirect.js b/ui/pages/confirmations/confirmation/templates/snap-account-redirect.js
index b987eff014ad..4356560ee73e 100644
--- a/ui/pages/confirmations/confirmation/templates/snap-account-redirect.js
+++ b/ui/pages/confirmations/confirmation/templates/snap-account-redirect.js
@@ -4,7 +4,7 @@ import {
MetaMetricsEventAccountType,
} from '../../../../../shared/constants/metametrics';
-function getValues(pendingApproval, t, actions, _history, _data, contexts) {
+function getValues(pendingApproval, t, actions, _navigate, _data, contexts) {
const { origin: snapId, snapName } = pendingApproval;
const { url, message, isBlockedUrl } = pendingApproval.requestData;
const { trackEvent } = contexts;
diff --git a/ui/pages/confirmations/context/confirm/index.tsx b/ui/pages/confirmations/context/confirm/index.tsx
index f74e270ee6b9..19871e35c2f4 100644
--- a/ui/pages/confirmations/context/confirm/index.tsx
+++ b/ui/pages/confirmations/context/confirm/index.tsx
@@ -27,7 +27,7 @@ export const ConfirmContextProvider: React.FC<{
const [isScrollToBottomCompleted, setIsScrollToBottomCompleted] =
useState(true);
const { currentConfirmation } = useCurrentConfirmation(confirmationId);
- useSyncConfirmPath(currentConfirmation, confirmationId);
+ useSyncConfirmPath(currentConfirmation);
const value = useMemo(
() => ({
diff --git a/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.test.ts b/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.test.ts
index 62c9178ea302..c076d5124095 100644
--- a/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.test.ts
+++ b/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.test.ts
@@ -19,9 +19,9 @@ jest.mock('../transactions/useEnableShieldCoverageChecks', () => ({
}));
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.ts b/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.ts
index 1d982ea1a464..d6a92df76f73 100644
--- a/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.ts
+++ b/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.ts
@@ -2,7 +2,7 @@ import { SignatureRequest } from '@metamask/signature-controller';
import { TransactionMeta } from '@metamask/transaction-controller';
import { useCallback, useEffect, useMemo } from 'react';
import { useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { CoverageStatus } from '@metamask/shield-controller';
import { RowAlertKey } from '../../../../components/app/confirm/info/row/constants';
import { Alert } from '../../../../ducks/confirm-alerts/confirm-alerts';
diff --git a/ui/pages/confirmations/hooks/send/metrics/useAmountSelectionMetrics.test.tsx b/ui/pages/confirmations/hooks/send/metrics/useAmountSelectionMetrics.test.tsx
index 275cd68aba14..b7155fea2aea 100644
--- a/ui/pages/confirmations/hooks/send/metrics/useAmountSelectionMetrics.test.tsx
+++ b/ui/pages/confirmations/hooks/send/metrics/useAmountSelectionMetrics.test.tsx
@@ -1,7 +1,7 @@
import React, { ReactChildren } from 'react';
import mockState from '../../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { MetaMetricsContext } from '../../../../../contexts/metametrics';
import { useAmountSelectionMetrics } from './useAmountSelectionMetrics';
diff --git a/ui/pages/confirmations/hooks/send/metrics/useAssetSelectionMetrics.test.tsx b/ui/pages/confirmations/hooks/send/metrics/useAssetSelectionMetrics.test.tsx
index 0db6739c8d2f..609f707e9d00 100644
--- a/ui/pages/confirmations/hooks/send/metrics/useAssetSelectionMetrics.test.tsx
+++ b/ui/pages/confirmations/hooks/send/metrics/useAssetSelectionMetrics.test.tsx
@@ -8,7 +8,7 @@ import {
MOCK_NFT1155,
SOLANA_NATIVE_ASSET,
} from '../../../../../../test/data/send/assets';
-import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { MetaMetricsContext } from '../../../../../contexts/metametrics';
import {
AssetFilterMethod,
diff --git a/ui/pages/confirmations/hooks/send/metrics/useRecipientSelectionMetrics.test.tsx b/ui/pages/confirmations/hooks/send/metrics/useRecipientSelectionMetrics.test.tsx
index 323642bba844..7511097c5a0f 100644
--- a/ui/pages/confirmations/hooks/send/metrics/useRecipientSelectionMetrics.test.tsx
+++ b/ui/pages/confirmations/hooks/send/metrics/useRecipientSelectionMetrics.test.tsx
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/naming-convention */
import React, { ReactChildren } from 'react';
import mockTestState from '../../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { MetaMetricsContext } from '../../../../../contexts/metametrics';
import { RecipientInputMethod } from '../../../context/send-metrics';
diff --git a/ui/pages/confirmations/hooks/send/useAccountAddressSeedIconMap.test.ts b/ui/pages/confirmations/hooks/send/useAccountAddressSeedIconMap.test.ts
index 7e1de3c33862..3e05f923e2d6 100644
--- a/ui/pages/confirmations/hooks/send/useAccountAddressSeedIconMap.test.ts
+++ b/ui/pages/confirmations/hooks/send/useAccountAddressSeedIconMap.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import * as accountTreeSelectors from '../../../../selectors/multichain-accounts/account-tree';
import { AccountGroupWithInternalAccounts } from '../../../../selectors/multichain-accounts/account-tree.types';
diff --git a/ui/pages/confirmations/hooks/send/useAccountRecipients.test.ts b/ui/pages/confirmations/hooks/send/useAccountRecipients.test.ts
index cedc4b8e1b5d..26aadc00f58c 100644
--- a/ui/pages/confirmations/hooks/send/useAccountRecipients.test.ts
+++ b/ui/pages/confirmations/hooks/send/useAccountRecipients.test.ts
@@ -1,7 +1,7 @@
import { BtcAccountType } from '@metamask/keyring-api';
import { cloneDeep } from 'lodash';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import { ConsolidatedWallets } from '../../../../selectors/multichain-accounts/account-tree.types';
import * as accountTreeSelectors from '../../../../selectors/multichain-accounts/account-tree';
diff --git a/ui/pages/confirmations/hooks/send/useAmountValidation.test.ts b/ui/pages/confirmations/hooks/send/useAmountValidation.test.ts
index 5f69babb2256..f68cdb39a522 100644
--- a/ui/pages/confirmations/hooks/send/useAmountValidation.test.ts
+++ b/ui/pages/confirmations/hooks/send/useAmountValidation.test.ts
@@ -3,7 +3,7 @@ import { waitFor } from '@testing-library/react';
import { Numeric } from '../../../../../shared/modules/Numeric';
import mockState from '../../../../../test/data/mock-state.json';
import { EVM_NATIVE_ASSET } from '../../../../../test/data/send/assets';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { Asset, AssetStandard } from '../../types/send';
import * as SendContext from '../../context/send';
import {
diff --git a/ui/pages/confirmations/hooks/send/useBalance.test.ts b/ui/pages/confirmations/hooks/send/useBalance.test.ts
index 530c69bbca0b..40e08fb8bbc6 100644
--- a/ui/pages/confirmations/hooks/send/useBalance.test.ts
+++ b/ui/pages/confirmations/hooks/send/useBalance.test.ts
@@ -6,7 +6,7 @@ import {
MOCK_NFT1155,
} from '../../../../../test/data/send/assets';
import { Numeric } from '../../../../../shared/modules/Numeric';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import * as SendContext from '../../context/send';
import { useBalance } from './useBalance';
diff --git a/ui/pages/confirmations/hooks/send/useContactRecipients.test.ts b/ui/pages/confirmations/hooks/send/useContactRecipients.test.ts
index b069cb6fca4a..53e2515adcdf 100644
--- a/ui/pages/confirmations/hooks/send/useContactRecipients.test.ts
+++ b/ui/pages/confirmations/hooks/send/useContactRecipients.test.ts
@@ -1,5 +1,5 @@
import { isAddress as isEvmAddress } from 'ethers/lib/utils';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import * as selectors from '../../../../selectors';
import * as SendContext from '../../context/send';
diff --git a/ui/pages/confirmations/hooks/send/useCurrencyConversions.test.ts b/ui/pages/confirmations/hooks/send/useCurrencyConversions.test.ts
index d66e88f503e3..45338a73ec70 100644
--- a/ui/pages/confirmations/hooks/send/useCurrencyConversions.test.ts
+++ b/ui/pages/confirmations/hooks/send/useCurrencyConversions.test.ts
@@ -7,7 +7,7 @@ import {
MOCK_NFT1155,
MOCK_NFT721,
} from '../../../../../test/data/send/assets';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import * as SendContext from '../../context/send';
import { useCurrencyConversions } from './useCurrencyConversions';
diff --git a/ui/pages/confirmations/hooks/send/useMaxAmount.test.ts b/ui/pages/confirmations/hooks/send/useMaxAmount.test.ts
index 91933ac7e66b..d59e65ac59dd 100644
--- a/ui/pages/confirmations/hooks/send/useMaxAmount.test.ts
+++ b/ui/pages/confirmations/hooks/send/useMaxAmount.test.ts
@@ -7,7 +7,7 @@ import {
SOLANA_ASSET,
} from '../../../../../test/data/send/assets';
import mockState from '../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import * as SendContext from '../../context/send';
import { useMaxAmount } from './useMaxAmount';
import { useBalance } from './useBalance';
diff --git a/ui/pages/confirmations/hooks/send/useNameValidation.test.ts b/ui/pages/confirmations/hooks/send/useNameValidation.test.ts
index 91a95ce995d8..cba407d3dfbd 100644
--- a/ui/pages/confirmations/hooks/send/useNameValidation.test.ts
+++ b/ui/pages/confirmations/hooks/send/useNameValidation.test.ts
@@ -1,7 +1,7 @@
import { AddressResolution } from '@metamask/snaps-sdk';
import mockState from '../../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { lookupDomainName } from '../../../../ducks/domains';
// eslint-disable-next-line import/no-namespace
import * as SnapNameResolution from '../../../../hooks/snaps/useSnapNameResolution';
diff --git a/ui/pages/confirmations/hooks/send/useNavigateSendPage.test.ts b/ui/pages/confirmations/hooks/send/useNavigateSendPage.test.ts
index 6a5bac09313b..49eefe8af051 100644
--- a/ui/pages/confirmations/hooks/send/useNavigateSendPage.test.ts
+++ b/ui/pages/confirmations/hooks/send/useNavigateSendPage.test.ts
@@ -5,8 +5,8 @@ import { SendPages } from '../../constants/send';
import { useNavigateSendPage } from './useNavigateSendPage';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => ({ pathname: '/send/asset' }),
useSearchParams: jest
diff --git a/ui/pages/confirmations/hooks/send/useNavigateSendPage.ts b/ui/pages/confirmations/hooks/send/useNavigateSendPage.ts
index 98be7fb7623c..f6919c3482bb 100644
--- a/ui/pages/confirmations/hooks/send/useNavigateSendPage.ts
+++ b/ui/pages/confirmations/hooks/send/useNavigateSendPage.ts
@@ -1,5 +1,5 @@
import { useCallback } from 'react';
-import { useNavigate, useSearchParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useSearchParams } from 'react-router-dom';
import {
SEND_ROUTE,
diff --git a/ui/pages/confirmations/hooks/send/useRecipientValidation.test.ts b/ui/pages/confirmations/hooks/send/useRecipientValidation.test.ts
index 4d31718a86b2..dc81582ecb9e 100644
--- a/ui/pages/confirmations/hooks/send/useRecipientValidation.test.ts
+++ b/ui/pages/confirmations/hooks/send/useRecipientValidation.test.ts
@@ -6,7 +6,7 @@ import {
EVM_ASSET,
SOLANA_ASSET,
} from '../../../../../test/data/send/assets';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { useI18nContext } from '../../../../hooks/useI18nContext';
import { useSendContext } from '../../context/send';
import * as SendValidationUtils from '../../utils/sendValidations';
diff --git a/ui/pages/confirmations/hooks/send/useRecipients.test.ts b/ui/pages/confirmations/hooks/send/useRecipients.test.ts
index 4f330d81a13f..bd2bad279bbb 100644
--- a/ui/pages/confirmations/hooks/send/useRecipients.test.ts
+++ b/ui/pages/confirmations/hooks/send/useRecipients.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import { type Recipient, useRecipients } from './useRecipients';
import * as useContactRecipientsModule from './useContactRecipients';
diff --git a/ui/pages/confirmations/hooks/send/useSendActions.test.ts b/ui/pages/confirmations/hooks/send/useSendActions.test.ts
index 9e7c354f0723..c6fe536d8af3 100644
--- a/ui/pages/confirmations/hooks/send/useSendActions.test.ts
+++ b/ui/pages/confirmations/hooks/send/useSendActions.test.ts
@@ -21,9 +21,9 @@ jest.mock('../../../../store/actions', () => ({
}));
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/confirmations/hooks/send/useSendActions.ts b/ui/pages/confirmations/hooks/send/useSendActions.ts
index bcd0da87de67..bc6d60995f80 100644
--- a/ui/pages/confirmations/hooks/send/useSendActions.ts
+++ b/ui/pages/confirmations/hooks/send/useSendActions.ts
@@ -2,7 +2,7 @@ import { CaipAssetType, Hex } from '@metamask/utils';
import { InternalAccount } from '@metamask/keyring-internal-api';
import { useCallback } from 'react';
import { useDispatch } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
CONFIRM_TRANSACTION_ROUTE,
diff --git a/ui/pages/confirmations/hooks/send/useSendAssetFilter.test.ts b/ui/pages/confirmations/hooks/send/useSendAssetFilter.test.ts
index bfe7767a6051..c6221b257c90 100644
--- a/ui/pages/confirmations/hooks/send/useSendAssetFilter.test.ts
+++ b/ui/pages/confirmations/hooks/send/useSendAssetFilter.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import { type Asset } from '../../types/send';
import { useSendAssetFilter } from './useSendAssetFilter';
diff --git a/ui/pages/confirmations/hooks/send/useSendAssets.test.ts b/ui/pages/confirmations/hooks/send/useSendAssets.test.ts
index 16dbda7939f8..e9efd34d9ee7 100644
--- a/ui/pages/confirmations/hooks/send/useSendAssets.test.ts
+++ b/ui/pages/confirmations/hooks/send/useSendAssets.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import { type Asset } from '../../types/send';
import { useSendAssets } from './useSendAssets';
diff --git a/ui/pages/confirmations/hooks/send/useSendNfts.test.ts b/ui/pages/confirmations/hooks/send/useSendNfts.test.ts
index a4ab2708bd1d..e0743475d2c9 100644
--- a/ui/pages/confirmations/hooks/send/useSendNfts.test.ts
+++ b/ui/pages/confirmations/hooks/send/useSendNfts.test.ts
@@ -1,7 +1,7 @@
import { waitFor } from '@testing-library/react';
import { useSelector } from 'react-redux';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import {
getAccountGroupWithInternalAccounts,
diff --git a/ui/pages/confirmations/hooks/send/useSendQueryParams.test.ts b/ui/pages/confirmations/hooks/send/useSendQueryParams.test.ts
index 74d947243528..259b88ced830 100644
--- a/ui/pages/confirmations/hooks/send/useSendQueryParams.test.ts
+++ b/ui/pages/confirmations/hooks/send/useSendQueryParams.test.ts
@@ -1,6 +1,6 @@
import { DefaultRootState, useSelector } from 'react-redux';
-import { useSearchParams } from 'react-router-dom-v5-compat';
-import { SetURLSearchParams } from 'react-router-dom-v5-compat/dist/react-router-dom';
+import { useSearchParams } from 'react-router-dom';
+import type { SetURLSearchParams } from 'react-router-dom';
import mockState from '../../../../../test/data/mock-state.json';
import { EVM_ASSET, MOCK_NFT1155 } from '../../../../../test/data/send/assets';
@@ -12,8 +12,8 @@ import * as SendContext from '../../context/send';
import { useSendQueryParams } from './useSendQueryParams';
import { useSendNfts } from './useSendNfts';
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useLocation: () => ({ pathname: '/send/asset' }),
useSearchParams: jest.fn().mockReturnValue([{ get: () => null }]),
}));
diff --git a/ui/pages/confirmations/hooks/send/useSendQueryParams.ts b/ui/pages/confirmations/hooks/send/useSendQueryParams.ts
index 0f9d1f01ec3b..9c83c5f30130 100644
--- a/ui/pages/confirmations/hooks/send/useSendQueryParams.ts
+++ b/ui/pages/confirmations/hooks/send/useSendQueryParams.ts
@@ -1,10 +1,6 @@
import { Hex } from '@metamask/utils';
import { useEffect, useMemo } from 'react';
-import {
- useNavigate,
- useLocation,
- useSearchParams,
-} from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation, useSearchParams } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { SEND_ROUTE } from '../../../../helpers/constants/routes';
diff --git a/ui/pages/confirmations/hooks/send/useSendRecipientFilter.test.ts b/ui/pages/confirmations/hooks/send/useSendRecipientFilter.test.ts
index 0ff2ae647fea..7c0cd63569ee 100644
--- a/ui/pages/confirmations/hooks/send/useSendRecipientFilter.test.ts
+++ b/ui/pages/confirmations/hooks/send/useSendRecipientFilter.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import { type Recipient } from './useRecipients';
import { useSendRecipientFilter } from './useSendRecipientFilter';
diff --git a/ui/pages/confirmations/hooks/send/useSendTokens.test.ts b/ui/pages/confirmations/hooks/send/useSendTokens.test.ts
index 53b38c425a95..2a9d1d297627 100644
--- a/ui/pages/confirmations/hooks/send/useSendTokens.test.ts
+++ b/ui/pages/confirmations/hooks/send/useSendTokens.test.ts
@@ -1,6 +1,6 @@
import { useSelector } from 'react-redux';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../../test/data/mock-state.json';
import { getAssetsBySelectedAccountGroup } from '../../../../selectors/assets';
import * as useFiatFormatterModule from '../../../../hooks/useFiatFormatter';
diff --git a/ui/pages/confirmations/hooks/send/useSendType.test.ts b/ui/pages/confirmations/hooks/send/useSendType.test.ts
index c5b2b16741b6..4ebe3a5ba653 100644
--- a/ui/pages/confirmations/hooks/send/useSendType.test.ts
+++ b/ui/pages/confirmations/hooks/send/useSendType.test.ts
@@ -6,12 +6,12 @@ import {
SOLANA_ASSET,
SOLANA_NATIVE_ASSET,
} from '../../../../../test/data/send/assets';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import * as SendContext from '../../context/send';
import { useSendType } from './useSendType';
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useLocation: () => ({ pathname: '/send/asset' }),
useSearchParams: () => [{ get: () => null }],
}));
diff --git a/ui/pages/confirmations/hooks/send/useSnapAmountOnInput.test.ts b/ui/pages/confirmations/hooks/send/useSnapAmountOnInput.test.ts
index 65d936a4c870..f841fdc45b9d 100644
--- a/ui/pages/confirmations/hooks/send/useSnapAmountOnInput.test.ts
+++ b/ui/pages/confirmations/hooks/send/useSnapAmountOnInput.test.ts
@@ -1,7 +1,7 @@
import { InternalAccount } from '@metamask/keyring-internal-api';
import { CaipAssetType } from '@metamask/utils';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import * as SendContext from '../../context/send';
import * as MultichainSnaps from '../../utils/multichain-snaps';
import { useSnapAmountOnInput } from './useSnapAmountOnInput';
diff --git a/ui/pages/confirmations/hooks/transactions/useEnableShieldCoverageChecks.test.ts b/ui/pages/confirmations/hooks/transactions/useEnableShieldCoverageChecks.test.ts
index ea6f4fdf9554..e81e8e24c757 100644
--- a/ui/pages/confirmations/hooks/transactions/useEnableShieldCoverageChecks.test.ts
+++ b/ui/pages/confirmations/hooks/transactions/useEnableShieldCoverageChecks.test.ts
@@ -2,7 +2,7 @@ import {
PRODUCT_TYPES,
SUBSCRIPTION_STATUSES,
} from '@metamask/subscription-controller';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { useEnableShieldCoverageChecks } from './useEnableShieldCoverageChecks';
jest.mock('../../../../hooks/subscription/useSubscription', () => ({
diff --git a/ui/pages/confirmations/hooks/transactions/useShieldConfirm.test.ts b/ui/pages/confirmations/hooks/transactions/useShieldConfirm.test.ts
index dbccbbee6e1b..c82009d61330 100644
--- a/ui/pages/confirmations/hooks/transactions/useShieldConfirm.test.ts
+++ b/ui/pages/confirmations/hooks/transactions/useShieldConfirm.test.ts
@@ -2,12 +2,12 @@ import {
TransactionMeta,
TransactionType,
} from '@metamask/transaction-controller';
-import { renderHookWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { PREVIOUS_ROUTE } from '../../../../helpers/constants/routes';
import { useShieldConfirm } from './useShieldConfirm';
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: jest.fn(),
}));
@@ -16,7 +16,7 @@ const mockNavigate = jest.fn();
describe('useShieldConfirm', () => {
beforeEach(() => {
jest.resetAllMocks();
- const { useNavigate } = jest.requireMock('react-router-dom-v5-compat');
+ const { useNavigate } = jest.requireMock('react-router-dom');
useNavigate.mockReturnValue(mockNavigate);
});
diff --git a/ui/pages/confirmations/hooks/transactions/useShieldConfirm.ts b/ui/pages/confirmations/hooks/transactions/useShieldConfirm.ts
index d566cbfc48ed..1704fd55a3ce 100644
--- a/ui/pages/confirmations/hooks/transactions/useShieldConfirm.ts
+++ b/ui/pages/confirmations/hooks/transactions/useShieldConfirm.ts
@@ -3,7 +3,7 @@ import {
TransactionType,
} from '@metamask/transaction-controller';
import { useCallback } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
TRANSACTION_SHIELD_ROUTE,
PREVIOUS_ROUTE,
diff --git a/ui/pages/confirmations/hooks/transactions/useTransactionConfirm.test.ts b/ui/pages/confirmations/hooks/transactions/useTransactionConfirm.test.ts
index 6b5d7bc5f4fe..5ef4b00e0f4b 100644
--- a/ui/pages/confirmations/hooks/transactions/useTransactionConfirm.test.ts
+++ b/ui/pages/confirmations/hooks/transactions/useTransactionConfirm.test.ts
@@ -28,9 +28,9 @@ jest.mock('../../../../store/actions', () => ({
}));
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/confirmations/hooks/useBatchAuthorizationRequests.test.ts b/ui/pages/confirmations/hooks/useBatchAuthorizationRequests.test.ts
index cdef3e73e4d9..9fc95f91834a 100644
--- a/ui/pages/confirmations/hooks/useBatchAuthorizationRequests.test.ts
+++ b/ui/pages/confirmations/hooks/useBatchAuthorizationRequests.test.ts
@@ -1,7 +1,7 @@
import { TransactionStatus } from '@metamask/transaction-controller';
import { getMockConfirmStateForTransaction } from '../../../../test/data/confirmations/helper';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { Confirmation } from '../types/confirm';
import { useBatchAuthorizationRequests } from './useBatchAuthorizationRequests';
diff --git a/ui/pages/confirmations/hooks/useChainNetworkNameAndImage.test.ts b/ui/pages/confirmations/hooks/useChainNetworkNameAndImage.test.ts
index 91beed49c39b..159744819d31 100644
--- a/ui/pages/confirmations/hooks/useChainNetworkNameAndImage.test.ts
+++ b/ui/pages/confirmations/hooks/useChainNetworkNameAndImage.test.ts
@@ -1,5 +1,5 @@
import mockState from '../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { useChainNetworkNameAndImageMap } from './useChainNetworkNameAndImage';
function renderHook() {
diff --git a/ui/pages/confirmations/hooks/useConfirmSendNavigation.test.ts b/ui/pages/confirmations/hooks/useConfirmSendNavigation.test.ts
index 49efb582baf9..01148df46aee 100644
--- a/ui/pages/confirmations/hooks/useConfirmSendNavigation.test.ts
+++ b/ui/pages/confirmations/hooks/useConfirmSendNavigation.test.ts
@@ -7,9 +7,9 @@ import { useConfirmSendNavigation } from './useConfirmSendNavigation';
const mockUseRedesignedSendFlow = jest.mocked(useRedesignedSendFlow);
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/confirmations/hooks/useConfirmSendNavigation.ts b/ui/pages/confirmations/hooks/useConfirmSendNavigation.ts
index 084a3ac8114c..9d3c488e4a74 100644
--- a/ui/pages/confirmations/hooks/useConfirmSendNavigation.ts
+++ b/ui/pages/confirmations/hooks/useConfirmSendNavigation.ts
@@ -3,7 +3,7 @@ import {
TransactionType,
} from '@metamask/transaction-controller';
import { useCallback } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useConfirmContext } from '../context/confirm';
import { PREVIOUS_ROUTE } from '../../../helpers/constants/routes';
diff --git a/ui/pages/confirmations/hooks/useConfirmationAlertActions.test.ts b/ui/pages/confirmations/hooks/useConfirmationAlertActions.test.ts
index a278bffcb34b..7cb940b3695f 100644
--- a/ui/pages/confirmations/hooks/useConfirmationAlertActions.test.ts
+++ b/ui/pages/confirmations/hooks/useConfirmationAlertActions.test.ts
@@ -1,4 +1,4 @@
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
import { AlertActionKey } from '../../../components/app/confirm/info/row/constants';
import { useTransactionModalContext } from '../../../contexts/transaction-modal';
diff --git a/ui/pages/confirmations/hooks/useConfirmationAlerts.test.ts b/ui/pages/confirmations/hooks/useConfirmationAlerts.test.ts
index 983b21a61541..452b0e19cf42 100644
--- a/ui/pages/confirmations/hooks/useConfirmationAlerts.test.ts
+++ b/ui/pages/confirmations/hooks/useConfirmationAlerts.test.ts
@@ -3,9 +3,9 @@ import mockState from '../../../../test/data/mock-state.json';
import useConfirmationAlerts from './useConfirmationAlerts';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/confirmations/hooks/useConfirmationNavigation.test.ts b/ui/pages/confirmations/hooks/useConfirmationNavigation.test.ts
index 3a67f2587780..8e6bdb4130bb 100644
--- a/ui/pages/confirmations/hooks/useConfirmationNavigation.test.ts
+++ b/ui/pages/confirmations/hooks/useConfirmationNavigation.test.ts
@@ -17,9 +17,9 @@ import { useConfirmationNavigation } from './useConfirmationNavigation';
const mockUseNavigate = jest.fn();
const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => mockUseLocation(),
};
diff --git a/ui/pages/confirmations/hooks/useConfirmationNavigation.ts b/ui/pages/confirmations/hooks/useConfirmationNavigation.ts
index c3150999918e..8dfc30c9415f 100644
--- a/ui/pages/confirmations/hooks/useConfirmationNavigation.ts
+++ b/ui/pages/confirmations/hooks/useConfirmationNavigation.ts
@@ -1,6 +1,6 @@
import { useCallback } from 'react';
import { useSelector } from 'react-redux';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import { ApprovalType } from '@metamask/controller-utils';
import { isEqual } from 'lodash';
import { ApprovalRequest } from '@metamask/approval-controller';
diff --git a/ui/pages/confirmations/hooks/useCurrentConfirmation.test.ts b/ui/pages/confirmations/hooks/useCurrentConfirmation.test.ts
index 4f66a2ad4743..87e6f8439670 100644
--- a/ui/pages/confirmations/hooks/useCurrentConfirmation.test.ts
+++ b/ui/pages/confirmations/hooks/useCurrentConfirmation.test.ts
@@ -23,9 +23,9 @@ const MESSAGE_MOCK = {
};
const mockUseParams = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useParams: () => mockUseParams(),
};
});
diff --git a/ui/pages/confirmations/hooks/useCurrentConfirmation.ts b/ui/pages/confirmations/hooks/useCurrentConfirmation.ts
index 5fd4fb9cec31..21aa93c8882b 100644
--- a/ui/pages/confirmations/hooks/useCurrentConfirmation.ts
+++ b/ui/pages/confirmations/hooks/useCurrentConfirmation.ts
@@ -2,7 +2,7 @@ import { ApprovalType } from '@metamask/controller-utils';
import { TransactionMeta } from '@metamask/transaction-controller';
import { useMemo } from 'react';
import { useSelector } from 'react-redux';
-import { useParams } from 'react-router-dom-v5-compat';
+import { useParams } from 'react-router-dom';
import {
ApprovalsMetaMaskState,
getUnapprovedTransaction,
diff --git a/ui/pages/confirmations/hooks/useEIP7702Account.test.ts b/ui/pages/confirmations/hooks/useEIP7702Account.test.ts
index 20f29286afa2..a3fa54661d43 100644
--- a/ui/pages/confirmations/hooks/useEIP7702Account.test.ts
+++ b/ui/pages/confirmations/hooks/useEIP7702Account.test.ts
@@ -9,7 +9,7 @@ import {
getCode,
} from '../../../store/actions';
import { EIP_7702_REVOKE_ADDRESS } from '../../../../shared/lib/eip7702-utils';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { useConfirmationNavigation } from './useConfirmationNavigation';
import { useEIP7702Account } from './useEIP7702Account';
diff --git a/ui/pages/confirmations/hooks/useEIP7702Networks.test.ts b/ui/pages/confirmations/hooks/useEIP7702Networks.test.ts
index 3c098917140a..d78b0d72e409 100644
--- a/ui/pages/confirmations/hooks/useEIP7702Networks.test.ts
+++ b/ui/pages/confirmations/hooks/useEIP7702Networks.test.ts
@@ -1,5 +1,5 @@
import { waitFor } from '@testing-library/react';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import {
useEIP7702Networks,
EIP7702NetworkConfiguration,
diff --git a/ui/pages/confirmations/hooks/useRedesignedSendFlow.test.ts b/ui/pages/confirmations/hooks/useRedesignedSendFlow.test.ts
index ac890f7e2050..0d59c3cbecf0 100644
--- a/ui/pages/confirmations/hooks/useRedesignedSendFlow.test.ts
+++ b/ui/pages/confirmations/hooks/useRedesignedSendFlow.test.ts
@@ -1,5 +1,5 @@
import mockState from '../../../../test/data/mock-state.json';
-import { renderHookWithProvider } from '../../../../test/lib/render-helpers';
+import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { getRemoteFeatureFlags } from '../../../selectors/remote-feature-flags';
import { useRedesignedSendFlow } from './useRedesignedSendFlow';
diff --git a/ui/pages/confirmations/hooks/useRouting.js b/ui/pages/confirmations/hooks/useRouting.js
index 3dc238d31c7e..c66d7869585e 100644
--- a/ui/pages/confirmations/hooks/useRouting.js
+++ b/ui/pages/confirmations/hooks/useRouting.js
@@ -1,5 +1,5 @@
import { useCallback } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { getMostRecentOverviewPage } from '../../../ducks/history/history';
diff --git a/ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts b/ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts
index 19bd2d8795b8..a058a5ef1bb7 100644
--- a/ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts
+++ b/ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts
@@ -7,9 +7,9 @@ import useSyncConfirmPath from './useSyncConfirmPath';
const mockUseNavigate = jest.fn();
const mockUseParams = jest.fn();
const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useParams: () => mockUseParams(),
useLocation: () => mockUseLocation(),
@@ -30,8 +30,15 @@ const STATE_MOCK = {
};
describe('useSyncConfirmPath', () => {
+ const originalLocation = window.location;
+
beforeEach(() => {
jest.clearAllMocks();
+ // Mock window.location since the hook reads from global location
+ Object.defineProperty(window, 'location', {
+ value: { pathname: '/confirm-transaction' },
+ writable: true,
+ });
// Default mock: on confirmation route with no params
mockUseLocation.mockReturnValue({
pathname: '/confirm-transaction',
@@ -42,6 +49,13 @@ describe('useSyncConfirmPath', () => {
mockUseParams.mockReturnValue({});
});
+ afterEach(() => {
+ Object.defineProperty(window, 'location', {
+ value: originalLocation,
+ writable: true,
+ });
+ });
+
it('should execute correctly', () => {
const result = renderHookWithConfirmContextProvider(
() => useSyncConfirmPath(unapprovedPersonalSignMsg),
diff --git a/ui/pages/confirmations/hooks/useSyncConfirmPath.ts b/ui/pages/confirmations/hooks/useSyncConfirmPath.ts
index d4de723a9bab..d7e075250b65 100644
--- a/ui/pages/confirmations/hooks/useSyncConfirmPath.ts
+++ b/ui/pages/confirmations/hooks/useSyncConfirmPath.ts
@@ -1,5 +1,5 @@
import { useEffect } from 'react';
-import { useParams, useLocation } from 'react-router-dom-v5-compat';
+import { useParams } from 'react-router-dom';
import {
CONFIRM_TRANSACTION_ROUTE,
@@ -8,17 +8,10 @@ import {
import { Confirmation } from '../types/confirm';
import { useConfirmationNavigation } from './useConfirmationNavigation';
-const useSyncConfirmPath = (
- currentConfirmation?: Confirmation,
- routeParamId?: string,
-) => {
+const useSyncConfirmPath = (currentConfirmation?: Confirmation) => {
const { navigateToId } = useConfirmationNavigation();
- const location = useLocation();
-
- // Use routeParamId from props if available (passed from v5 Route),
- // otherwise fall back to useParams() for v5-compat Routes
- const urlParams = useParams<{ id: string }>();
- const paramId = routeParamId || urlParams.id;
+ const { id: paramId } = useParams<{ id: string }>();
+ const confirmationId = currentConfirmation?.id;
useEffect(() => {
// Only sync path if we're on a confirmation route
@@ -35,11 +28,11 @@ const useSyncConfirmPath = (
// This ensures /confirm-transaction always becomes /confirm-transaction/
// which is critical for popup/notification windows and "X of Y" navigation
if (!paramId && currentConfirmation) {
- navigateToId(currentConfirmation.id);
+ navigateToId(confirmationId);
}
// Note: confirmations is intentionally excluded from dependencies
// navigateToId is memoized with useCallback and is sufficient for tracking changes
- }, [paramId, currentConfirmation, navigateToId, location.pathname]);
+ }, [paramId, currentConfirmation, navigateToId, confirmationId]);
};
export default useSyncConfirmPath;
diff --git a/ui/pages/confirmations/send/send-inner.test.tsx b/ui/pages/confirmations/send/send-inner.test.tsx
index c9225e13810a..16d474f173f9 100644
--- a/ui/pages/confirmations/send/send-inner.test.tsx
+++ b/ui/pages/confirmations/send/send-inner.test.tsx
@@ -7,8 +7,8 @@ import * as SendContext from '../context/send';
import { SendPages } from '../constants/send';
import { SendInner } from './send-inner';
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useLocation: () => ({ pathname: '' }),
useSearchParams: () => [{ get: () => null }],
}));
diff --git a/ui/pages/confirmations/utils/send.ts b/ui/pages/confirmations/utils/send.ts
index 4c05f6694fd7..176360283a76 100644
--- a/ui/pages/confirmations/utils/send.ts
+++ b/ui/pages/confirmations/utils/send.ts
@@ -5,7 +5,7 @@ import {
TransactionType,
} from '@metamask/transaction-controller';
import { addHexPrefix } from 'ethereumjs-util';
-import { NavigateFunction } from 'react-router-dom-v5-compat';
+import { NavigateFunction } from 'react-router-dom';
import { Numeric, NumericBase } from '../../../../shared/modules/Numeric';
import {
diff --git a/ui/pages/core/hyperliquid-referral-consent/hyperliquid-referral-consent.test.tsx b/ui/pages/core/hyperliquid-referral-consent/hyperliquid-referral-consent.test.tsx
index 5d4c9540ab07..84bf3ee92b2e 100644
--- a/ui/pages/core/hyperliquid-referral-consent/hyperliquid-referral-consent.test.tsx
+++ b/ui/pages/core/hyperliquid-referral-consent/hyperliquid-referral-consent.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import configureMockStore from 'redux-mock-store';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
import { HyperliquidReferralConsent } from './hyperliquid-referral-consent';
diff --git a/ui/pages/create-account/connect-hardware/index.test.tsx b/ui/pages/create-account/connect-hardware/index.test.tsx
index 14a489d5d706..e94c3256c4d7 100644
--- a/ui/pages/create-account/connect-hardware/index.test.tsx
+++ b/ui/pages/create-account/connect-hardware/index.test.tsx
@@ -2,7 +2,7 @@ import { fireEvent, waitFor } from '@testing-library/react';
import thunk from 'redux-thunk';
import React from 'react';
import configureMockStore from 'redux-mock-store';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import {
@@ -48,11 +48,9 @@ jest.mock('../../../ducks/history/history', () => ({
.mockImplementation(() => MOCK_RECENT_PAGE),
}));
-// Mock React Router v5-compat hooks that withRouterHooks uses
const mockUseNavigate = jest.fn();
-
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => ({ pathname: '/test' }),
useParams: () => ({}),
diff --git a/ui/pages/create-account/create-account.component.js b/ui/pages/create-account/create-account.component.js
index 145a74ac1a69..99f3b5bab84d 100644
--- a/ui/pages/create-account/create-account.component.js
+++ b/ui/pages/create-account/create-account.component.js
@@ -1,17 +1,13 @@
import React from 'react';
-import { Routes, Route } from 'react-router-dom-v5-compat';
+import { Routes, Route } from 'react-router-dom';
import { Box } from '../../components/component-library';
-import { CONNECT_HARDWARE_ROUTE } from '../../helpers/constants/routes';
import ConnectHardwareForm from './connect-hardware';
export default function CreateAccountPage() {
return (
- }
- />
+ } />
);
diff --git a/ui/pages/deep-link/deep-link.tsx b/ui/pages/deep-link/deep-link.tsx
index 6c1c7c892c54..a790426d6ae6 100644
--- a/ui/pages/deep-link/deep-link.tsx
+++ b/ui/pages/deep-link/deep-link.tsx
@@ -1,5 +1,5 @@
import React, { useEffect, useRef, useState } from 'react';
-import type { Location as RouterLocation } from 'react-router-dom-v5-compat';
+import { useLocation } from 'react-router-dom';
import log from 'loglevel';
import { useDispatch, useSelector } from 'react-redux';
import {
@@ -160,11 +160,8 @@ async function updateStateFromUrl(
}
}
-type DeepLinkProps = {
- location: RouterLocation;
-};
-
-export const DeepLink = ({ location }: DeepLinkProps) => {
+export const DeepLink = () => {
+ const location = useLocation();
const t = useI18nContext() as TranslateFunction;
const dispatch = useDispatch();
// it's technically not possible for a natural flow to reach this page
diff --git a/ui/pages/defi/components/defi-details-list.test.tsx b/ui/pages/defi/components/defi-details-list.test.tsx
index c7cce1096d5b..e173bfe99f75 100644
--- a/ui/pages/defi/components/defi-details-list.test.tsx
+++ b/ui/pages/defi/components/defi-details-list.test.tsx
@@ -11,9 +11,9 @@ const mockUseParams = jest
.mockReturnValue({ chainId: CHAIN_IDS.MAINNET, protocolId: 'aave' });
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useParams: () => mockUseParams(),
};
diff --git a/ui/pages/defi/components/defi-details-page.test.tsx b/ui/pages/defi/components/defi-details-page.test.tsx
index 7b2d72092fd8..8db95125bec8 100644
--- a/ui/pages/defi/components/defi-details-page.test.tsx
+++ b/ui/pages/defi/components/defi-details-page.test.tsx
@@ -1,4 +1,5 @@
import React from 'react';
+import { Route, Routes } from 'react-router-dom';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { CHAIN_IDS } from '../../../../shared/constants/network';
@@ -6,12 +7,11 @@ import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate
import mockState from '../../../../test/data/mock-state.json';
import DeFiPage from './defi-details-page';
-const mockNavigate = jest.fn();
-
describe('DeFiDetailsPage', () => {
const mockStore = {
...mockState,
metamask: {
+ ...mockState.metamask,
allDeFiPositions: {
[mockState.metamask.selectedAddress]: {
'0x1': {
@@ -64,7 +64,6 @@ describe('DeFiDetailsPage', () => {
},
},
},
- ...mockState.metamask,
},
};
@@ -81,11 +80,11 @@ describe('DeFiDetailsPage', () => {
it('renders defi asset page', () => {
const { container } = renderWithProvider(
- ,
+
+ } />
+ ,
store,
+ `/defi/${CHAIN_IDS.MAINNET}/aave`,
);
expect(container).toMatchSnapshot();
diff --git a/ui/pages/defi/components/defi-details-page.tsx b/ui/pages/defi/components/defi-details-page.tsx
index bd6597203ad4..29dc1f311485 100644
--- a/ui/pages/defi/components/defi-details-page.tsx
+++ b/ui/pages/defi/components/defi-details-page.tsx
@@ -1,5 +1,5 @@
import React, { useMemo } from 'react';
-import { Navigate } from 'react-router-dom-v5-compat';
+import { Navigate, useNavigate, useParams } from 'react-router-dom';
import { useSelector } from 'react-redux';
import {
Display,
@@ -45,14 +45,10 @@ const useExtractUnderlyingTokens = (
);
}, [positions]);
-type DeFiPageProps = {
- navigate: (to: string | number) => void;
- params: { chainId: string; protocolId: string };
-};
-
-const DeFiPage = ({ navigate, params }: DeFiPageProps) => {
+const DeFiPage = () => {
const { formatCurrencyWithMinThreshold } = useFormatters();
- const { chainId, protocolId } = params;
+ const { chainId, protocolId } = useParams();
+ const navigate = useNavigate();
const defiPositions = useSelector(getDefiPositions);
const selectedAccount = useSelector(getSelectedAccount);
@@ -61,9 +57,11 @@ const DeFiPage = ({ navigate, params }: DeFiPageProps) => {
// TODO: Get value in user's preferred currency
const protocolPosition =
- defiPositions[selectedAccount.address]?.[
- chainId as keyof (typeof defiPositions)[string]
- ]?.protocols[protocolId];
+ chainId && protocolId
+ ? defiPositions[selectedAccount.address]?.[
+ chainId as keyof (typeof defiPositions)[string]
+ ]?.protocols[protocolId]
+ : undefined;
const extractedTokens = useMemo(() => {
return Object.keys(protocolPosition?.positionTypes || {}).reduce(
diff --git a/ui/pages/error-page/error-component.test.tsx b/ui/pages/error-page/error-component.test.tsx
index 239ba038f445..378cb52f0454 100644
--- a/ui/pages/error-page/error-component.test.tsx
+++ b/ui/pages/error-page/error-component.test.tsx
@@ -5,7 +5,7 @@ import browser from 'webextension-polyfill';
import { fireEvent } from '@testing-library/react';
import thunk from 'redux-thunk';
import configureMockState from 'redux-mock-store';
-import { renderWithProvider } from '../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../test/lib/render-helpers-navigate';
import { useI18nContext } from '../../hooks/useI18nContext';
import { MetaMetricsContext } from '../../contexts/metametrics';
import { getParticipateInMetaMetrics } from '../../selectors';
diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js
index b82c984a260f..7349be2138ce 100644
--- a/ui/pages/home/home.component.js
+++ b/ui/pages/home/home.component.js
@@ -1,6 +1,6 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
-import { Navigate } from 'react-router-dom-v5-compat';
+import { Navigate } from 'react-router-dom';
import { Text, TextVariant, TextColor } from '@metamask/design-system-react';
import { COHORT_NAMES } from '@metamask/subscription-controller';
import {
diff --git a/ui/pages/home/home.component.stories.tsx b/ui/pages/home/home.component.stories.tsx
index 751cd0a8e9ae..e2a3431749ff 100644
--- a/ui/pages/home/home.component.stories.tsx
+++ b/ui/pages/home/home.component.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { StoryObj, Meta } from '@storybook/react';
import { Provider } from 'react-redux';
-import { MemoryRouter } from 'react-router-dom-v5-compat';
+import { MemoryRouter } from 'react-router-dom';
import Home from './home.component';
import mockState from '../../../test/data/mock-state.json';
import configureStore from '../../store/store';
diff --git a/ui/pages/home/home.container.js b/ui/pages/home/home.container.js
index 0842ddb51fcb..f8a2e1576375 100644
--- a/ui/pages/home/home.container.js
+++ b/ui/pages/home/home.container.js
@@ -2,7 +2,6 @@ import React from 'react';
import { compose } from 'redux';
import { connect } from 'react-redux';
import withRouterHooks from '../../helpers/higher-order-components/with-router-hooks/with-router-hooks';
-import { useNavState } from '../../contexts/navigation-state';
import { useShieldSubscriptionContext } from '../../contexts/shield/shield-subscription';
import {
activeTabHasPermissions,
@@ -88,7 +87,6 @@ import {
getRedirectAfterDefaultPage,
clearRedirectAfterDefaultPage,
} from '../../ducks/history/history';
-
import Home from './home.component';
const mapStateToProps = (state) => {
@@ -250,18 +248,12 @@ const mapDispatchToProps = (dispatch) => {
// Strip unused 'match' prop from withRouter
// It causes cascading, unnecessary re-renders
-// Also inject navState from NavigationStateContext for v5-compat navigation
// eslint-disable-next-line react/prop-types
const HomeWithRouter = ({ match: _match, ...props }) => {
- const navState = useNavState();
const { evaluateCohortEligibility } = useShieldSubscriptionContext();
return (
-
+
);
};
diff --git a/ui/pages/index.js b/ui/pages/index.js
index 0f0c2b1d934d..6c24d69ffdf3 100644
--- a/ui/pages/index.js
+++ b/ui/pages/index.js
@@ -2,7 +2,6 @@ import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Provider } from 'react-redux';
import { HashRouter } from 'react-router-dom';
-import { CompatRouter } from 'react-router-dom-v5-compat';
import { captureException } from '../../shared/lib/sentry';
import { I18nProvider, LegacyI18nProvider } from '../contexts/i18n';
import {
@@ -13,7 +12,6 @@ import { MetamaskNotificationsProvider } from '../contexts/metamask-notification
import { AssetPollingProvider } from '../contexts/assetPolling';
import { MetamaskIdentityProvider } from '../contexts/identity';
import { ShieldSubscriptionProvider } from '../contexts/shield/shield-subscription';
-import { NavigationStateProvider } from '../contexts/navigation-state';
import RiveWasmProvider from '../contexts/rive-wasm';
import ErrorPage from './error-page/error-page.component';
@@ -48,30 +46,26 @@ class Index extends PureComponent {
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
diff --git a/ui/pages/keychains/reveal-seed.js b/ui/pages/keychains/reveal-seed.js
index f16f3ec13989..69e34db1274a 100644
--- a/ui/pages/keychains/reveal-seed.js
+++ b/ui/pages/keychains/reveal-seed.js
@@ -2,6 +2,7 @@ import qrCode from 'qrcode-generator';
import React, { useContext, useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
+import { useNavigate } from 'react-router-dom';
import { getErrorMessage } from '../../../shared/modules/error';
import {
MetaMetricsEventCategory,
@@ -38,15 +39,16 @@ import {
import ZENDESK_URLS from '../../helpers/constants/zendesk-url';
import { useI18nContext } from '../../hooks/useI18nContext';
import { requestRevealSeedWords } from '../../store/actions';
-import { getHDEntropyIndex } from '../../selectors/selectors';
+import { getHDEntropyIndex } from '../../selectors';
import { endTrace, trace, TraceName } from '../../../shared/lib/trace';
import { PREVIOUS_ROUTE } from '../../helpers/constants/routes';
const PASSWORD_PROMPT_SCREEN = 'PASSWORD_PROMPT_SCREEN';
const REVEAL_SEED_SCREEN = 'REVEAL_SEED_SCREEN';
-function RevealSeedPage({ navigate, keyringId }) {
+function RevealSeedPage({ keyringId }) {
const dispatch = useDispatch();
+ const navigate = useNavigate();
const t = useI18nContext();
const trackEvent = useContext(MetaMetricsContext);
const hdEntropyIndex = useSelector(getHDEntropyIndex);
@@ -410,7 +412,6 @@ function RevealSeedPage({ navigate, keyringId }) {
}
RevealSeedPage.propTypes = {
- navigate: PropTypes.func.isRequired,
keyringId: PropTypes.string,
};
diff --git a/ui/pages/multi-srp/import-srp/import-srp.test.tsx b/ui/pages/multi-srp/import-srp/import-srp.test.tsx
index 2eadb7e00e5e..cae8a42e289f 100644
--- a/ui/pages/multi-srp/import-srp/import-srp.test.tsx
+++ b/ui/pages/multi-srp/import-srp/import-srp.test.tsx
@@ -32,8 +32,8 @@ jest.mock('../../../components/app/toast-master/utils', () => ({
}));
const mockNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
}));
diff --git a/ui/pages/multi-srp/import-srp/import-srp.tsx b/ui/pages/multi-srp/import-srp/import-srp.tsx
index a260344a97fb..30634b9af802 100644
--- a/ui/pages/multi-srp/import-srp/import-srp.tsx
+++ b/ui/pages/multi-srp/import-srp/import-srp.tsx
@@ -1,6 +1,6 @@
import React, { useEffect, useState, useContext } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useI18nContext } from '../../../hooks/useI18nContext';
import {
hideWarning,
diff --git a/ui/pages/multichain-accounts/account-list/account-list.test.tsx b/ui/pages/multichain-accounts/account-list/account-list.test.tsx
index fb86119d473f..1a399040bd6a 100644
--- a/ui/pages/multichain-accounts/account-list/account-list.test.tsx
+++ b/ui/pages/multichain-accounts/account-list/account-list.test.tsx
@@ -8,9 +8,9 @@ import mockState from '../../../../test/data/mock-state.json';
import { AccountList } from './account-list';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/multichain-accounts/account-list/account-list.tsx b/ui/pages/multichain-accounts/account-list/account-list.tsx
index 7963d78f1605..5a39f7def98e 100644
--- a/ui/pages/multichain-accounts/account-list/account-list.tsx
+++ b/ui/pages/multichain-accounts/account-list/account-list.tsx
@@ -1,5 +1,5 @@
import React, { useCallback, useMemo, useState } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import {
diff --git a/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.test.tsx b/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.test.tsx
index 445ab6858cc4..3b3ab5667a89 100644
--- a/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.test.tsx
+++ b/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.test.tsx
@@ -9,8 +9,8 @@ import { AddWalletPage } from './add-wallet-page';
const mockNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
}));
diff --git a/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.tsx b/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.tsx
index 8e8fd6015ca2..cb8ba3987208 100644
--- a/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.tsx
+++ b/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.tsx
@@ -1,6 +1,6 @@
import React, { useCallback } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
ButtonIcon,
ButtonIconSize,
diff --git a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.stories.tsx b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.stories.tsx
index 6160ff243af0..525b547c708e 100644
--- a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.stories.tsx
+++ b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.stories.tsx
@@ -1,7 +1,7 @@
import React, { ReactNode } from 'react';
import { StoryObj, Meta } from '@storybook/react';
import { Provider } from 'react-redux';
-import { MemoryRouter, Route } from 'react-router-dom-v5-compat';
+import { MemoryRouter, Route } from 'react-router-dom';
import configureStore from 'redux-mock-store';
import { AccountGroupId } from '@metamask/account-api';
import { MultichainAccountAddressListPage } from './multichain-account-address-list-page';
diff --git a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.test.tsx b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.test.tsx
index 406a57971af5..58a22ca8f4c0 100644
--- a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.test.tsx
+++ b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.test.tsx
@@ -17,9 +17,9 @@ const MOCK_GROUP_NAME = 'Account 1';
const mockUseNavigate = jest.fn();
const mockUseParams = jest.fn();
const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useParams: () => mockUseParams(),
useLocation: () => mockUseLocation(),
diff --git a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.tsx b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.tsx
index be7e1708eae3..82503756153a 100644
--- a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.tsx
+++ b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.tsx
@@ -1,10 +1,6 @@
import React, { useState, useCallback } from 'react';
-import {
- useNavigate,
- useLocation,
- useParams,
-} from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation, useParams } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { CaipChainId } from '@metamask/utils';
import {
diff --git a/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.test.tsx b/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.test.tsx
index 5456b4bbf14b..c2bcb9c0bbfe 100644
--- a/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.test.tsx
+++ b/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.test.tsx
@@ -18,9 +18,9 @@ const accountNameInputDataTestId = 'account-name-input';
const mockUseNavigate = jest.fn();
const mockUseParams = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useParams: () => mockUseParams(),
};
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 2db1840ef3ff..6896e825264e 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
@@ -1,5 +1,5 @@
import React, { useCallback, useContext, useEffect, useState } from 'react';
-import { useNavigate, useParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useParams } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { AccountGroupId, AccountWalletType } from '@metamask/account-api';
import classnames from 'classnames';
@@ -53,17 +53,12 @@ import {
} from '../../../../shared/constants/metametrics';
import { MetaMetricsContext } from '../../../contexts/metametrics';
-export const MultichainAccountDetailsPage = ({
- id: idProp,
-}: { id?: string } = {}) => {
+export const MultichainAccountDetailsPage = () => {
const t = useI18nContext();
const navigate = useNavigate();
const dispatch = useDispatch();
const trackEvent = useContext(MetaMetricsContext);
- const { id: idFromParams } = useParams();
-
- // Use prop if provided (from createV5CompatRoute), otherwise fall back to hook
- const id = idProp || idFromParams;
+ const { id } = useParams();
const accountGroupId = decodeURIComponent(id ?? '') as AccountGroupId;
const multichainAccount = useSelector((state) =>
diff --git a/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.test.tsx b/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.test.tsx
index 763ac33da7a3..4c3b6694dec7 100644
--- a/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.test.tsx
+++ b/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.test.tsx
@@ -13,8 +13,8 @@ const backButtonTestId = 'multichain-account-address-list-page-back-button';
// Use actual group IDs from mock-state.json
const MOCK_GROUP_ID = 'entropy:01JKAF3DSGM3AB87EM9N0K41AJ/0' as AccountGroupId;
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
useParams: () => mockUseParams(),
}));
diff --git a/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.tsx b/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.tsx
index 1af5beb0244c..30aacc4bd1a3 100644
--- a/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.tsx
+++ b/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.tsx
@@ -1,6 +1,6 @@
import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
-import { useNavigate, useParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useParams } from 'react-router-dom';
import {
Box,
BoxFlexDirection,
diff --git a/ui/pages/multichain-accounts/smart-account-page/smart-account-page.test.tsx b/ui/pages/multichain-accounts/smart-account-page/smart-account-page.test.tsx
index 202066ffa64e..95ba0f3157b7 100644
--- a/ui/pages/multichain-accounts/smart-account-page/smart-account-page.test.tsx
+++ b/ui/pages/multichain-accounts/smart-account-page/smart-account-page.test.tsx
@@ -10,8 +10,8 @@ const mockUseParams = jest.fn();
const MOCK_ADDRESS = '0x1234567890abcdef1234567890abcdef12345678';
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
useParams: () => mockUseParams(),
}));
diff --git a/ui/pages/multichain-accounts/smart-account-page/smart-account-page.tsx b/ui/pages/multichain-accounts/smart-account-page/smart-account-page.tsx
index f9966bf34ec7..b0df1dd79388 100644
--- a/ui/pages/multichain-accounts/smart-account-page/smart-account-page.tsx
+++ b/ui/pages/multichain-accounts/smart-account-page/smart-account-page.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { useNavigate, useParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useParams } from 'react-router-dom';
import {
Box,
BoxFlexDirection,
@@ -17,18 +17,10 @@ import { useI18nContext } from '../../../hooks/useI18nContext';
import { SmartContractAccountToggleSection } from '../../../components/multichain-accounts/smart-contract-account-toggle-section';
import { PREVIOUS_ROUTE } from '../../../helpers/constants/routes';
-type SmartAccountPageProps = {
- params?: { address: string };
-};
-
-export const SmartAccountPage = ({
- params: propsParams,
-}: SmartAccountPageProps = {}) => {
+export const SmartAccountPage = () => {
const t = useI18nContext();
const navigate = useNavigate();
- const hookParams = useParams<{ address: string }>();
-
- const { address } = propsParams || hookParams;
+ const { address } = useParams<{ address: string }>();
const decodedAddress = address ? decodeURIComponent(address) : null;
diff --git a/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.test.tsx b/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.test.tsx
index c3d26059ddf8..c3cceb50ea48 100644
--- a/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.test.tsx
+++ b/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.test.tsx
@@ -12,9 +12,9 @@ const mockUseParams = jest.fn().mockImplementation(() => ({
}));
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useParams: () => mockUseParams(),
};
diff --git a/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.tsx b/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.tsx
index ab4b3e06800f..e5652ebf2b0d 100644
--- a/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.tsx
+++ b/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.tsx
@@ -1,5 +1,5 @@
import React, { useEffect, useMemo } from 'react';
-import { useNavigate, useParams } from 'react-router-dom-v5-compat';
+import { useNavigate, useParams } from 'react-router-dom';
import { useSelector } from 'react-redux';
import {
AccountGroupId,
diff --git a/ui/pages/nonevm-balance-check/index.tsx b/ui/pages/nonevm-balance-check/index.tsx
index 27d5454afb55..996b65c58fb7 100644
--- a/ui/pages/nonevm-balance-check/index.tsx
+++ b/ui/pages/nonevm-balance-check/index.tsx
@@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { CaipChainId } from '@metamask/utils';
import { InternalAccount } from '@metamask/keyring-internal-api';
-import type { Location as HistoryLocation } from 'history';
+import { useLocation } from 'react-router-dom';
import {
Box,
Modal,
@@ -65,12 +65,9 @@ const getBuyUrl = (
return buyUrl.toString();
};
-type NonEvmBalanceCheckProps = {
- location: HistoryLocation;
-};
-
-export const NonEvmBalanceCheck = ({ location }: NonEvmBalanceCheckProps) => {
+export const NonEvmBalanceCheck = () => {
const dispatch = useDispatch();
+ const location = useLocation();
const metaMetricsId = useSelector(getMetaMetricsId);
const isMetaMetricsEnabled = useSelector(getParticipateInMetaMetrics);
const isMarketingEnabled = useSelector(getDataCollectionForMarketing);
diff --git a/ui/pages/notification-details/notification-details.tsx b/ui/pages/notification-details/notification-details.tsx
index 8f108ae74a0c..3ba9d90ceb29 100644
--- a/ui/pages/notification-details/notification-details.tsx
+++ b/ui/pages/notification-details/notification-details.tsx
@@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
import { useSelector } from 'react-redux';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import {
TRIGGER_TYPES,
type INotification,
@@ -26,10 +26,9 @@ import { NotificationDetailsHeader } from './notification-details-header/notific
import { NotificationDetailsBody } from './notification-details-body/notification-details-body';
import { NotificationDetailsFooter } from './notification-details-footer/notification-details-footer';
-function useNotificationByPath(propsParams?: { uuid: string }) {
+function useNotificationByPath() {
const { pathname } = useLocation();
- // If params are provided as props, use them; otherwise extract from pathname
- const id = propsParams?.uuid || getExtractIdentifier(pathname);
+ const id = getExtractIdentifier(pathname);
const notification = useSelector(getMetamaskNotificationById(id));
return {
@@ -60,25 +59,11 @@ function useEffectOnNotificationView(notificationData?: INotification) {
}, []);
}
-type NotificationDetailsProps = {
- params?: { uuid: string };
- navigate?: (
- to: string | number,
- options?: { replace?: boolean; state?: Record },
- ) => void;
-};
-
// TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
// eslint-disable-next-line @typescript-eslint/naming-convention
-export default function NotificationDetails({
- params,
- navigate: navigateProp,
-}: NotificationDetailsProps = {}) {
- const navigateHook = useNavigate();
- const navigate = (navigateProp || navigateHook) as NonNullable<
- typeof navigateProp
- >;
- const { notification } = useNotificationByPath(params);
+export default function NotificationDetails() {
+ const navigate = useNavigate();
+ const { notification } = useNotificationByPath();
useEffectOnNotificationView(notification);
// No Notification
diff --git a/ui/pages/notifications-settings/notifications-settings.tsx b/ui/pages/notifications-settings/notifications-settings.tsx
index 79ba1a4221c1..b2205a921b4c 100644
--- a/ui/pages/notifications-settings/notifications-settings.tsx
+++ b/ui/pages/notifications-settings/notifications-settings.tsx
@@ -1,6 +1,6 @@
import React, { useMemo, useState } from 'react';
import { useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useI18nContext } from '../../hooks/useI18nContext';
import {
NOTIFICATIONS_ROUTE,
diff --git a/ui/pages/notifications/notification-components/snap/snap-footer-button.test.tsx b/ui/pages/notifications/notification-components/snap/snap-footer-button.test.tsx
index 412b8046165c..d4ad28822d2a 100644
--- a/ui/pages/notifications/notification-components/snap/snap-footer-button.test.tsx
+++ b/ui/pages/notifications/notification-components/snap/snap-footer-button.test.tsx
@@ -2,16 +2,16 @@ import React from 'react';
import { processNotification } from '@metamask/notification-services-controller/notification-services';
import { fireEvent, waitFor } from '@testing-library/react';
import { createMockSnapNotification } from '@metamask/notification-services-controller/notification-services/mocks';
-import { renderWithProvider } from '../../../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate';
import { DEFAULT_ROUTE } from '../../../../helpers/constants/routes';
import { SnapFooterButton } from './snap-footer-button';
import { DetailedViewData, SnapNotification } from './types';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
@@ -80,8 +80,8 @@ describe('SnapFooterButton', () => {
// Confirm Leave
await waitFor(() => {
- const leaveModalTitle = getByText('[leaveMetaMask]');
- const leaveModalButton = getByText('[visitSite]');
+ const leaveModalTitle = getByText('Leave MetaMask?');
+ const leaveModalButton = getByText('Visit site');
expect(leaveModalTitle).toBeInTheDocument();
expect(leaveModalButton).toBeInTheDocument();
});
diff --git a/ui/pages/notifications/notification-components/snap/snap.tsx b/ui/pages/notifications/notification-components/snap/snap.tsx
index 9cf50bc5c26d..d37462b9697f 100644
--- a/ui/pages/notifications/notification-components/snap/snap.tsx
+++ b/ui/pages/notifications/notification-components/snap/snap.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { TRIGGER_TYPES } from '@metamask/notification-services-controller/notification-services';
import {
NotificationDetailTitle,
diff --git a/ui/pages/notifications/notifications-list-item.tsx b/ui/pages/notifications/notifications-list-item.tsx
index 9a2d8fc48e30..169aea12da7c 100644
--- a/ui/pages/notifications/notifications-list-item.tsx
+++ b/ui/pages/notifications/notifications-list-item.tsx
@@ -1,5 +1,5 @@
import React, { useContext, useCallback } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { hasProperty } from '@metamask/utils';
import type { INotification } from '@metamask/notification-services-controller/notification-services';
import { MetaMetricsContext } from '../../contexts/metametrics';
diff --git a/ui/pages/notifications/notifications.tsx b/ui/pages/notifications/notifications.tsx
index 8d0ad050e441..db1bf47f606c 100644
--- a/ui/pages/notifications/notifications.tsx
+++ b/ui/pages/notifications/notifications.tsx
@@ -1,6 +1,6 @@
import React, { useState, useMemo, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
type INotification,
TRIGGER_TYPES,
diff --git a/ui/pages/onboarding-flow/account-exist/account-exist.test.tsx b/ui/pages/onboarding-flow/account-exist/account-exist.test.tsx
index 159c8d6d6ace..d304f710a794 100644
--- a/ui/pages/onboarding-flow/account-exist/account-exist.test.tsx
+++ b/ui/pages/onboarding-flow/account-exist/account-exist.test.tsx
@@ -14,9 +14,9 @@ import AccountExist from './account-exist';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/onboarding-flow/account-exist/account-exist.tsx b/ui/pages/onboarding-flow/account-exist/account-exist.tsx
index 2bf6d58c22f8..cb14fdc23507 100644
--- a/ui/pages/onboarding-flow/account-exist/account-exist.tsx
+++ b/ui/pages/onboarding-flow/account-exist/account-exist.tsx
@@ -1,5 +1,5 @@
import React, { useEffect, useContext } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import {
Button,
diff --git a/ui/pages/onboarding-flow/account-not-found/account-not-found.test.tsx b/ui/pages/onboarding-flow/account-not-found/account-not-found.test.tsx
index d792d5024388..72268ec44ad6 100644
--- a/ui/pages/onboarding-flow/account-not-found/account-not-found.test.tsx
+++ b/ui/pages/onboarding-flow/account-not-found/account-not-found.test.tsx
@@ -14,9 +14,9 @@ import AccountNotFound from './account-not-found';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/onboarding-flow/account-not-found/account-not-found.tsx b/ui/pages/onboarding-flow/account-not-found/account-not-found.tsx
index 62364e8b055f..a4bc0115480c 100644
--- a/ui/pages/onboarding-flow/account-not-found/account-not-found.tsx
+++ b/ui/pages/onboarding-flow/account-not-found/account-not-found.tsx
@@ -1,5 +1,5 @@
import React, { useEffect, useContext } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import {
Button,
diff --git a/ui/pages/onboarding-flow/create-password/create-password.test.tsx b/ui/pages/onboarding-flow/create-password/create-password.test.tsx
index 61079d9fd768..dc9b8ad57724 100644
--- a/ui/pages/onboarding-flow/create-password/create-password.test.tsx
+++ b/ui/pages/onboarding-flow/create-password/create-password.test.tsx
@@ -16,9 +16,9 @@ import CreatePassword from './create-password';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/onboarding-flow/create-password/create-password.tsx b/ui/pages/onboarding-flow/create-password/create-password.tsx
index b1714fc61bd7..4ed594ea6d7c 100644
--- a/ui/pages/onboarding-flow/create-password/create-password.tsx
+++ b/ui/pages/onboarding-flow/create-password/create-password.tsx
@@ -1,5 +1,5 @@
import React, { useState, useContext, useEffect, useCallback } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { useI18nContext } from '../../../hooks/useI18nContext';
import {
diff --git a/ui/pages/onboarding-flow/creation-successful/creation-successful.test.tsx b/ui/pages/onboarding-flow/creation-successful/creation-successful.test.tsx
index c0409f381896..3785aeab6098 100644
--- a/ui/pages/onboarding-flow/creation-successful/creation-successful.test.tsx
+++ b/ui/pages/onboarding-flow/creation-successful/creation-successful.test.tsx
@@ -12,9 +12,9 @@ import CreationSuccessful from './creation-successful';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => ({ search: '' }),
};
diff --git a/ui/pages/onboarding-flow/creation-successful/creation-successful.tsx b/ui/pages/onboarding-flow/creation-successful/creation-successful.tsx
index 70d7b2ceb366..99ff452c5796 100644
--- a/ui/pages/onboarding-flow/creation-successful/creation-successful.tsx
+++ b/ui/pages/onboarding-flow/creation-successful/creation-successful.tsx
@@ -1,5 +1,5 @@
import React, { useCallback, useMemo, useContext } from 'react';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import browser from 'webextension-polyfill';
import {
diff --git a/ui/pages/onboarding-flow/download-app/download-app.test.tsx b/ui/pages/onboarding-flow/download-app/download-app.test.tsx
index c909b96423e6..5eeb83bede95 100644
--- a/ui/pages/onboarding-flow/download-app/download-app.test.tsx
+++ b/ui/pages/onboarding-flow/download-app/download-app.test.tsx
@@ -12,9 +12,9 @@ import DownloadApp from './download-app';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/onboarding-flow/download-app/download-app.tsx b/ui/pages/onboarding-flow/download-app/download-app.tsx
index 441d90e49fb9..e922f22dd7c9 100644
--- a/ui/pages/onboarding-flow/download-app/download-app.tsx
+++ b/ui/pages/onboarding-flow/download-app/download-app.tsx
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { useI18nContext } from '../../../hooks/useI18nContext';
import {
diff --git a/ui/pages/onboarding-flow/import-srp/import-srp.test.tsx b/ui/pages/onboarding-flow/import-srp/import-srp.test.tsx
index 76fce9d7983b..753d32151ba5 100644
--- a/ui/pages/onboarding-flow/import-srp/import-srp.test.tsx
+++ b/ui/pages/onboarding-flow/import-srp/import-srp.test.tsx
@@ -14,9 +14,9 @@ import ImportSrp from './import-srp';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/onboarding-flow/import-srp/import-srp.tsx b/ui/pages/onboarding-flow/import-srp/import-srp.tsx
index 8459358b5262..87ea5445c66e 100644
--- a/ui/pages/onboarding-flow/import-srp/import-srp.tsx
+++ b/ui/pages/onboarding-flow/import-srp/import-srp.tsx
@@ -1,5 +1,5 @@
import React, { useState, useEffect, useContext, useCallback } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { isValidMnemonic } from '@ethersproject/hdnode';
import {
diff --git a/ui/pages/onboarding-flow/metametrics/metametrics.test.tsx b/ui/pages/onboarding-flow/metametrics/metametrics.test.tsx
index 70531915f436..5994202bc99f 100644
--- a/ui/pages/onboarding-flow/metametrics/metametrics.test.tsx
+++ b/ui/pages/onboarding-flow/metametrics/metametrics.test.tsx
@@ -21,9 +21,9 @@ import OnboardingMetametrics from './metametrics';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: jest.fn(() => ({ search: '' })),
};
diff --git a/ui/pages/onboarding-flow/metametrics/metametrics.tsx b/ui/pages/onboarding-flow/metametrics/metametrics.tsx
index 67f2e7e6a467..90ea8e5b28bf 100644
--- a/ui/pages/onboarding-flow/metametrics/metametrics.tsx
+++ b/ui/pages/onboarding-flow/metametrics/metametrics.tsx
@@ -1,6 +1,6 @@
import React, { useContext, useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import log from 'loglevel';
import {
diff --git a/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.test.tsx b/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.test.tsx
index f3de687426bf..c42a26b5995c 100644
--- a/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.test.tsx
+++ b/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.test.tsx
@@ -2,7 +2,7 @@ import { fireEvent } from '@testing-library/react';
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
-import type { Location as RouterLocation } from 'react-router-dom-v5-compat';
+import type { Location as RouterLocation } from 'react-router-dom';
import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import { ONBOARDING_COMPLETION_ROUTE } from '../../../helpers/constants/routes';
import OnboardingAppHeader from './onboarding-app-header';
diff --git a/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.tsx b/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.tsx
index 77ab28f9682f..45e514c2bc47 100644
--- a/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.tsx
+++ b/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import type { Location as RouterLocation } from 'react-router-dom-v5-compat';
+import type { Location as RouterLocation } from 'react-router-dom';
import classnames from 'classnames';
import MetaFoxLogo from '../../../components/ui/metafox-logo';
import { useI18nContext } from '../../../hooks/useI18nContext';
diff --git a/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.test.tsx b/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.test.tsx
index 8459e97fe15b..9ff9c75d0df6 100644
--- a/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.test.tsx
+++ b/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import PropTypes from 'prop-types';
-import { useLocation } from 'react-router-dom-v5-compat';
+import { useLocation } from 'react-router-dom';
import {
DEFAULT_ROUTE,
ONBOARDING_COMPLETION_ROUTE,
diff --git a/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.tsx b/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.tsx
index 650a95cf00af..b1115debdeba 100644
--- a/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.tsx
+++ b/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { useSelector } from 'react-redux';
-import { Navigate } from 'react-router-dom-v5-compat';
+import { Navigate } from 'react-router-dom';
import {
DEFAULT_ROUTE,
ONBOARDING_COMPLETION_ROUTE,
diff --git a/ui/pages/onboarding-flow/onboarding-flow.test.tsx b/ui/pages/onboarding-flow/onboarding-flow.test.tsx
index 8624a6d37ff5..e079c7c80fa8 100644
--- a/ui/pages/onboarding-flow/onboarding-flow.test.tsx
+++ b/ui/pages/onboarding-flow/onboarding-flow.test.tsx
@@ -2,6 +2,7 @@ import { fireEvent, waitFor } from '@testing-library/react';
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
+import { Routes, Route } from 'react-router-dom';
import { renderWithProvider } from '../../../test/lib/render-helpers-navigate';
import {
ONBOARDING_EXPERIMENTAL_AREA,
@@ -28,14 +29,20 @@ import { FirstTimeFlowType } from '../../../shared/constants/onboarding';
import OnboardingFlow from './onboarding-flow';
const mockUseNavigate = jest.fn();
-const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
- useLocation: () => mockUseLocation(),
}));
+// Wrapper component that provides proper route context for nested Routes
+// OnboardingFlow uses relative paths expecting to be mounted at /onboarding/*
+const OnboardingFlowWithRouteContext = () => (
+
+ } />
+
+);
+
// Mock Rive animation components
jest.mock('./welcome/fox-appear-animation', () => ({
// eslint-disable-next-line @typescript-eslint/naming-convention
@@ -127,16 +134,6 @@ describe('Onboarding Flow', () => {
const store = configureMockStore([thunk])(mockState);
- beforeEach(() => {
- mockUseLocation.mockReturnValue({
- key: 'test-key',
- pathname: ONBOARDING_ROUTE,
- search: '',
- hash: '',
- state: null,
- });
- });
-
afterEach(() => {
jest.resetAllMocks();
});
@@ -173,7 +170,11 @@ describe('Onboarding Flow', () => {
completedOnboardingState,
);
- renderWithProvider( , completedOnboardingStore, '/other');
+ renderWithProvider(
+ ,
+ completedOnboardingStore,
+ ONBOARDING_ROUTE,
+ );
expect(mockUseNavigate).toHaveBeenCalledWith(DEFAULT_ROUTE);
});
@@ -181,7 +182,7 @@ describe('Onboarding Flow', () => {
describe('Create Password', () => {
it('should render create password', () => {
const { queryByTestId } = renderWithProvider(
- ,
+ ,
store,
ONBOARDING_CREATE_PASSWORD_ROUTE,
);
@@ -192,7 +193,7 @@ describe('Onboarding Flow', () => {
it('should call createNewVaultAndGetSeedPhrase when creating a new wallet password', async () => {
const { queryByTestId, queryByText } = renderWithProvider(
- ,
+ ,
configureMockStore([thunk])({
...mockState,
metamask: {
@@ -228,7 +229,11 @@ describe('Onboarding Flow', () => {
});
it('should redirect to reveal recovery phrase when going to review recovery phrase without srp', () => {
- renderWithProvider( , store, ONBOARDING_REVIEW_SRP_ROUTE);
+ renderWithProvider(
+ ,
+ store,
+ ONBOARDING_REVIEW_SRP_ROUTE,
+ );
expect(mockUseNavigate).toHaveBeenCalledWith(
{
@@ -240,7 +245,11 @@ describe('Onboarding Flow', () => {
});
it('should redirect to reveal recovery phrase when going to confirm recovery phrase without srp', () => {
- renderWithProvider( , store, ONBOARDING_CONFIRM_SRP_ROUTE);
+ renderWithProvider(
+ ,
+ store,
+ ONBOARDING_CONFIRM_SRP_ROUTE,
+ );
expect(mockUseNavigate).toHaveBeenCalledWith(
`${ONBOARDING_REVEAL_SRP_ROUTE}`,
@@ -250,7 +259,7 @@ describe('Onboarding Flow', () => {
it('should render import seed phrase', () => {
const { queryByTestId } = renderWithProvider(
- ,
+ ,
store,
ONBOARDING_IMPORT_WITH_SRP_ROUTE,
);
@@ -262,7 +271,7 @@ describe('Onboarding Flow', () => {
describe('Unlock Screen', () => {
it('should render unlock page', () => {
const { queryByTestId } = renderWithProvider(
- ,
+ ,
store,
ONBOARDING_UNLOCK_ROUTE,
);
@@ -273,7 +282,7 @@ describe('Onboarding Flow', () => {
it('should call unlockAndGetSeedPhrase when unlocking with a password', async () => {
const { getByLabelText, getByText } = renderWithProvider(
- ,
+ ,
configureMockStore([thunk])({
...mockState,
metamask: {
@@ -296,7 +305,7 @@ describe('Onboarding Flow', () => {
it('should render privacy settings', () => {
const { queryByTestId } = renderWithProvider(
- ,
+ ,
store,
ONBOARDING_PRIVACY_SETTINGS_ROUTE,
);
@@ -307,7 +316,7 @@ describe('Onboarding Flow', () => {
it('should render onboarding creation/completion successful', async () => {
const { queryByTestId } = renderWithProvider(
- ,
+ ,
store,
ONBOARDING_COMPLETION_ROUTE,
);
@@ -319,15 +328,8 @@ describe('Onboarding Flow', () => {
});
it('should render onboarding Login page screen', async () => {
- mockUseLocation.mockReturnValue({
- key: 'test-key',
- pathname: ONBOARDING_WELCOME_ROUTE,
- search: '',
- hash: '',
- state: null,
- });
const { queryByTestId } = renderWithProvider(
- ,
+ ,
store,
ONBOARDING_WELCOME_ROUTE,
);
@@ -335,13 +337,11 @@ describe('Onboarding Flow', () => {
await waitFor(() => {
expect(queryByTestId('get-started')).toBeInTheDocument();
});
-
- jest.clearAllMocks();
});
it('should render onboarding metametrics screen', () => {
const { queryByTestId } = renderWithProvider(
- ,
+ ,
store,
ONBOARDING_METAMETRICS,
);
@@ -352,7 +352,7 @@ describe('Onboarding Flow', () => {
it('should render onboarding experimental screen', () => {
const { queryByTestId } = renderWithProvider(
- ,
+ ,
store,
ONBOARDING_EXPERIMENTAL_AREA,
);
diff --git a/ui/pages/onboarding-flow/onboarding-flow.tsx b/ui/pages/onboarding-flow/onboarding-flow.tsx
index 1a5c0bd13371..c2ae47ef65b7 100644
--- a/ui/pages/onboarding-flow/onboarding-flow.tsx
+++ b/ui/pages/onboarding-flow/onboarding-flow.tsx
@@ -1,12 +1,5 @@
import React, { useEffect, useState, useContext, useMemo } from 'react';
-import {
- Routes as Switch,
- Route,
- useNavigate,
- useLocation,
- type NavigateFunction,
- type Location as RouterLocation,
-} from 'react-router-dom-v5-compat';
+import { Routes, Route, useNavigate, useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import classnames from 'classnames';
import Unlock from '../unlock-page';
@@ -20,6 +13,7 @@ import {
ONBOARDING_UNLOCK_ROUTE,
ONBOARDING_WELCOME_ROUTE,
DEFAULT_ROUTE,
+ ONBOARDING_ROUTE,
ONBOARDING_PRIVACY_SETTINGS_ROUTE,
ONBOARDING_COMPLETION_ROUTE,
ONBOARDING_IMPORT_WITH_SRP_ROUTE,
@@ -31,6 +25,7 @@ import {
ONBOARDING_REVEAL_SRP_ROUTE,
ONBOARDING_DOWNLOAD_APP_ROUTE,
} from '../../helpers/constants/routes';
+import { toRelativeRoutePath } from '../routes/utils';
import {
getCompletedOnboarding,
getIsPrimarySeedPhraseBackedUp,
@@ -90,27 +85,18 @@ import AccountNotFound from './account-not-found/account-not-found';
import RevealRecoveryPhrase from './recovery-phrase/reveal-recovery-phrase';
import OnboardingDownloadApp from './download-app/download-app';
-type OnboardingFlowProps = {
- navigate?: NavigateFunction;
- location?: RouterLocation;
-};
+// Helper to convert onboarding paths to relative paths for nested route matching
+const toRelativePath = (path: string) =>
+ toRelativeRoutePath(path, ONBOARDING_ROUTE);
-// TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
// eslint-disable-next-line @typescript-eslint/naming-convention
-export default function OnboardingFlow({
- navigate: navigateProp,
- location: locationProp,
-}: OnboardingFlowProps) {
+export default function OnboardingFlow() {
const [secretRecoveryPhrase, setSecretRecoveryPhrase] = useState('');
const [isLoading, setIsLoading] = useState(false);
const dispatch = useDispatch();
- const hookLocation = useLocation();
- const hookNavigate = useNavigate();
-
- // Use passed props if they exist, otherwise fall back to hooks
- const location = locationProp ?? hookLocation;
- const navigate = navigateProp ?? hookNavigate;
+ const location = useLocation();
const { pathname, search } = location;
+ const navigate = useNavigate();
const completedOnboarding: boolean = useSelector(getCompletedOnboarding);
const openedWithSidepanel = useSelector(getOpenedWithSidepanel);
const nextRoute = useSelector(getFirstTimeFlowTypeRouteAfterUnlock);
@@ -303,14 +289,17 @@ export default function OnboardingFlow({
marginInline="auto"
borderColor={BorderColor.borderMuted}
>
-
- } />
+
+ }
+ />
}
/>
}
/>
- }
+ path={toRelativePath(ONBOARDING_UNLOCK_ROUTE)}
+ element={ }
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
{
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
}
}
/>
{
///: END:ONLY_INCLUDE_IF
}
} />
-
+
{isLoading && }
diff --git a/ui/pages/onboarding-flow/pin-extension/pin-extension.js b/ui/pages/onboarding-flow/pin-extension/pin-extension.js
index 16902cfaed45..95c8c60b73f0 100644
--- a/ui/pages/onboarding-flow/pin-extension/pin-extension.js
+++ b/ui/pages/onboarding-flow/pin-extension/pin-extension.js
@@ -1,5 +1,5 @@
import React, { useState, useContext, useEffect } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { Carousel } from 'react-responsive-carousel';
import classnames from 'classnames';
diff --git a/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js b/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js
index e26e401a39cd..ff8d1794f73f 100644
--- a/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js
+++ b/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js
@@ -32,9 +32,9 @@ jest.mock('react-redux', () => ({
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/onboarding-flow/privacy-settings/privacy-settings.tsx b/ui/pages/onboarding-flow/privacy-settings/privacy-settings.tsx
index 0d140747a65c..5c0a34435050 100644
--- a/ui/pages/onboarding-flow/privacy-settings/privacy-settings.tsx
+++ b/ui/pages/onboarding-flow/privacy-settings/privacy-settings.tsx
@@ -1,6 +1,6 @@
import React, { useContext, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import classnames from 'classnames';
import log from 'loglevel';
// TODO: Remove restricted import
diff --git a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.test.tsx b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.test.tsx
index 4014e01146ec..9400f78646f6 100644
--- a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.test.tsx
+++ b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.test.tsx
@@ -21,9 +21,9 @@ jest.mock('../../../store/actions.ts', () => ({
const mockUseNavigate = jest.fn();
const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => mockUseLocation(),
};
diff --git a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.tsx b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.tsx
index 56b82e34c3c2..13eaa9046118 100644
--- a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.tsx
+++ b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.tsx
@@ -5,7 +5,7 @@ import React, {
useMemo,
useState,
} from 'react';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import {
diff --git a/ui/pages/onboarding-flow/recovery-phrase/reveal-recovery-phrase.tsx b/ui/pages/onboarding-flow/recovery-phrase/reveal-recovery-phrase.tsx
index 4128d24e089c..6a3e9a71fa78 100644
--- a/ui/pages/onboarding-flow/recovery-phrase/reveal-recovery-phrase.tsx
+++ b/ui/pages/onboarding-flow/recovery-phrase/reveal-recovery-phrase.tsx
@@ -1,5 +1,5 @@
import React, { FormEvent, useCallback, useState } from 'react';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import { useI18nContext } from '../../../hooks/useI18nContext';
import {
Text,
diff --git a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.test.tsx b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.test.tsx
index 7d7560b755bf..8c5c2001fa42 100644
--- a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.test.tsx
+++ b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.test.tsx
@@ -11,9 +11,9 @@ import RecoveryPhrase from './review-recovery-phrase';
const mockUseNavigate = jest.fn();
const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => mockUseLocation(),
};
diff --git a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.tsx b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.tsx
index 797be07d3c47..7625479cc5b1 100644
--- a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.tsx
+++ b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.tsx
@@ -1,5 +1,5 @@
import React, { useState, useContext, useCallback, useEffect } from 'react';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import PropTypes from 'prop-types';
import { useI18nContext } from '../../../hooks/useI18nContext';
diff --git a/ui/pages/onboarding-flow/welcome/welcome-login.tsx b/ui/pages/onboarding-flow/welcome/welcome-login.tsx
index b287e5070201..ca201d1d3e0a 100644
--- a/ui/pages/onboarding-flow/welcome/welcome-login.tsx
+++ b/ui/pages/onboarding-flow/welcome/welcome-login.tsx
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
-import { useSearchParams, useNavigate } from 'react-router-dom-v5-compat';
+import { useSearchParams, useNavigate } from 'react-router-dom';
import {
Box,
Button,
diff --git a/ui/pages/onboarding-flow/welcome/welcome.test.tsx b/ui/pages/onboarding-flow/welcome/welcome.test.tsx
index 3a2d42c2c486..dd1e04a0e9de 100644
--- a/ui/pages/onboarding-flow/welcome/welcome.test.tsx
+++ b/ui/pages/onboarding-flow/welcome/welcome.test.tsx
@@ -18,9 +18,9 @@ import Welcome from './welcome';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/onboarding-flow/welcome/welcome.tsx b/ui/pages/onboarding-flow/welcome/welcome.tsx
index a0bbb3c1e7e4..29d0758d6497 100644
--- a/ui/pages/onboarding-flow/welcome/welcome.tsx
+++ b/ui/pages/onboarding-flow/welcome/welcome.tsx
@@ -8,7 +8,7 @@ import React, {
type ComponentType,
} from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { Box } from '../../../components/component-library';
import {
ONBOARDING_COMPLETION_ROUTE,
diff --git a/ui/pages/permissions-connect/index.js b/ui/pages/permissions-connect/index.js
index 263242e1a869..4f5c6c661105 100644
--- a/ui/pages/permissions-connect/index.js
+++ b/ui/pages/permissions-connect/index.js
@@ -1 +1 @@
-export { default } from './permissions-connect.container';
+export { default } from './permissions-connect';
diff --git a/ui/pages/permissions-connect/permissions-connect.component.js b/ui/pages/permissions-connect/permissions-connect.component.js
deleted file mode 100644
index 75103cc0ab1d..000000000000
--- a/ui/pages/permissions-connect/permissions-connect.component.js
+++ /dev/null
@@ -1,620 +0,0 @@
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-import { Routes, Route } from 'react-router-dom-v5-compat';
-import { providerErrors, serializeError } from '@metamask/rpc-errors';
-import { SubjectType } from '@metamask/permission-controller';
-import { isSnapId } from '@metamask/snaps-utils';
-import {
- getAllNamespacesFromCaip25CaveatValue,
- getAllScopesFromCaip25CaveatValue,
- getEthAccounts,
- getPermittedEthChainIds,
-} from '@metamask/chain-agnostic-permission';
-import {
- KnownCaipNamespace,
- parseCaipAccountId,
- parseCaipChainId,
-} from '@metamask/utils';
-import { getRelativeLocationForNestedRoutes } from '../routes/utils';
-// TODO: Remove restricted import
-// eslint-disable-next-line import/no-restricted-paths
-import { isEthAddress } from '../../../app/scripts/lib/multichain/address';
-import { MILLISECOND } from '../../../shared/constants/time';
-import {
- DEFAULT_ROUTE,
- CONNECT_CONFIRM_PERMISSIONS_ROUTE,
- CONNECT_SNAPS_CONNECT_ROUTE,
- CONNECT_SNAP_INSTALL_ROUTE,
- CONNECT_SNAP_UPDATE_ROUTE,
- CONNECT_SNAP_RESULT_ROUTE,
-} from '../../helpers/constants/routes';
-import PermissionPageContainer from '../../components/app/permission-page-container';
-import { Box } from '../../components/component-library';
-import SnapAuthorshipHeader from '../../components/app/snaps/snap-authorship-header/snap-authorship-header';
-import { State2Wrapper } from '../../components/multichain-accounts/state2-wrapper/state2-wrapper';
-import { MultichainAccountsConnectPage } from '../multichain-accounts/multichain-accounts-connect-page/multichain-accounts-connect-page';
-import { supportsChainIds } from '../../hooks/useAccountGroupsForPermissions';
-import { getCaip25AccountIdsFromAccountGroupAndScope } from '../../../shared/lib/multichain/scope-utils';
-import { MultichainEditAccountsPageWrapper } from '../../components/multichain-accounts/permissions/multichain-edit-accounts-page/multichain-edit-account-wrapper';
-import ChooseAccount from './choose-account';
-import PermissionsRedirect from './redirect';
-import SnapsConnect from './snaps/snaps-connect';
-import SnapInstall from './snaps/snap-install';
-import SnapUpdate from './snaps/snap-update';
-import SnapResult from './snaps/snap-result';
-import { ConnectPage } from './connect-page/connect-page';
-import { getCaip25CaveatValueFromPermissions } from './connect-page/utils';
-
-const APPROVE_TIMEOUT = MILLISECOND * 1200;
-
-function getDefaultSelectedAccounts(currentAddress, permissions) {
- const requestedCaip25CaveatValue =
- getCaip25CaveatValueFromPermissions(permissions);
- const requestedAccounts = getEthAccounts(requestedCaip25CaveatValue);
-
- if (requestedAccounts.length > 0) {
- return new Set(
- requestedAccounts
- .map((address) => address.toLowerCase())
- // We only consider EVM accounts here (used for `eth_requestAccounts` or `eth_accounts`)
- .filter(isEthAddress),
- );
- }
-
- // We only consider EVM accounts here (used for `eth_requestAccounts` or `eth_accounts`)
- return new Set(isEthAddress(currentAddress) ? [currentAddress] : []);
-}
-
-function getRequestedChainIds(permissions) {
- const requestedCaip25CaveatValue =
- getCaip25CaveatValueFromPermissions(permissions);
- return getPermittedEthChainIds(requestedCaip25CaveatValue);
-}
-
-export default class PermissionConnect extends Component {
- static propTypes = {
- approvePermissionsRequest: PropTypes.func.isRequired,
- rejectPermissionsRequest: PropTypes.func.isRequired,
- getRequestAccountTabIds: PropTypes.func.isRequired,
- accounts: PropTypes.arrayOf(
- PropTypes.shape({
- id: PropTypes.string.isRequired,
- address: PropTypes.string.isRequired,
- metadata: PropTypes.shape({
- name: PropTypes.string.isRequired,
- snap: PropTypes.shape({
- id: PropTypes.string.isRequired,
- name: PropTypes.string,
- enabled: PropTypes.bool,
- }),
- keyring: PropTypes.shape({
- type: PropTypes.string.isRequired,
- }).isRequired,
- }).isRequired,
- addressLabel: PropTypes.string.isRequired,
- label: PropTypes.string.isRequired,
- balance: PropTypes.string.isRequired,
- }),
- ).isRequired,
- accountGroups: PropTypes.arrayOf(
- PropTypes.shape({
- id: PropTypes.string.isRequired,
- accounts: PropTypes.arrayOf(PropTypes.object.isRequired),
- }),
- ).isRequired,
- currentAddress: PropTypes.string.isRequired,
- origin: PropTypes.string,
- showNewAccountModal: PropTypes.func.isRequired,
- newAccountNumber: PropTypes.number.isRequired,
- nativeCurrency: PropTypes.string,
- permissionsRequest: PropTypes.object,
- addressLastConnectedMap: PropTypes.object.isRequired,
- lastConnectedInfo: PropTypes.object.isRequired,
- permissionsRequestId: PropTypes.string,
- navigate: PropTypes.func.isRequired,
- location: PropTypes.object.isRequired,
- connectPath: PropTypes.string.isRequired,
- confirmPermissionPath: PropTypes.string.isRequired,
- requestType: PropTypes.string.isRequired,
- snapsConnectPath: PropTypes.string.isRequired,
- snapInstallPath: PropTypes.string.isRequired,
- snapUpdatePath: PropTypes.string.isRequired,
- snapResultPath: PropTypes.string.isRequired,
- requestState: PropTypes.object.isRequired,
- approvePendingApproval: PropTypes.func.isRequired,
- rejectPendingApproval: PropTypes.func.isRequired,
- setSnapsInstallPrivacyWarningShownStatus: PropTypes.func.isRequired,
- snapsInstallPrivacyWarningShown: PropTypes.bool.isRequired,
- hideTopBar: PropTypes.bool,
- targetSubjectMetadata: PropTypes.shape({
- extensionId: PropTypes.string,
- iconUrl: PropTypes.string,
- name: PropTypes.string,
- origin: PropTypes.string,
- subjectType: PropTypes.string,
- }),
- isRequestingAccounts: PropTypes.bool.isRequired,
- };
-
- static defaultProps = {
- origin: '',
- nativeCurrency: '',
- permissionsRequest: undefined,
- permissionsRequestId: '',
- };
-
- static contextTypes = {
- t: PropTypes.func,
- };
-
- state = {
- redirecting: false,
- selectedAccountAddresses: getDefaultSelectedAccounts(
- this.props.currentAddress,
- this.props.permissionsRequest?.permissions,
- ),
- permissionsApproved: null,
- origin: this.props.origin,
- targetSubjectMetadata: this.props.targetSubjectMetadata || {},
- snapsInstallPrivacyWarningShown: this.props.snapsInstallPrivacyWarningShown,
- };
-
- componentDidMount() {
- const {
- connectPath,
- confirmPermissionPath,
- snapsConnectPath,
- snapInstallPath,
- snapUpdatePath,
- snapResultPath,
- requestType,
- getRequestAccountTabIds,
- permissionsRequest,
- navigate,
- location,
- isRequestingAccounts,
- } = this.props;
- getRequestAccountTabIds();
-
- if (!permissionsRequest) {
- navigate(DEFAULT_ROUTE, { replace: true });
- return;
- }
- if (location.pathname === connectPath && !isRequestingAccounts) {
- switch (requestType) {
- case 'wallet_installSnap':
- navigate(snapInstallPath, { replace: true });
- break;
- case 'wallet_updateSnap':
- navigate(snapUpdatePath, { replace: true });
- break;
- case 'wallet_installSnapResult':
- navigate(snapResultPath, { replace: true });
- break;
- case 'wallet_connectSnaps':
- navigate(snapsConnectPath, { replace: true });
- break;
- default:
- navigate(confirmPermissionPath, { replace: true });
- }
- }
- }
-
- componentDidUpdate(prevProps) {
- const { permissionsRequest, lastConnectedInfo, targetSubjectMetadata } =
- this.props;
- const { redirecting, origin } = this.state;
-
- // We cache the last known good targetSubjectMetadata since it may be null when the approval is cleared
- if (
- targetSubjectMetadata?.origin &&
- prevProps.targetSubjectMetadata?.origin !== targetSubjectMetadata?.origin
- ) {
- this.setState({ targetSubjectMetadata });
- }
-
- if (!permissionsRequest && prevProps.permissionsRequest && !redirecting) {
- const accountsLastApprovedTime =
- lastConnectedInfo[origin]?.lastApproved || 0;
- const initialAccountsLastApprovedTime =
- prevProps.lastConnectedInfo[origin]?.lastApproved || 0;
-
- const approved =
- accountsLastApprovedTime > initialAccountsLastApprovedTime;
- this.redirect(approved);
- }
- }
-
- selectAccounts = (addresses) => {
- const {
- confirmPermissionPath,
- requestType,
- snapsConnectPath,
- snapInstallPath,
- snapUpdatePath,
- snapResultPath,
- navigate,
- } = this.props;
- this.setState(
- {
- selectedAccountAddresses: addresses,
- },
- () => {
- switch (requestType) {
- case 'wallet_installSnap':
- navigate(snapInstallPath);
- break;
- case 'wallet_updateSnap':
- navigate(snapUpdatePath);
- break;
- case 'wallet_installSnapResult':
- navigate(snapResultPath);
- break;
- case 'wallet_connectSnaps':
- navigate(snapsConnectPath, { replace: true });
- break;
- default:
- navigate(confirmPermissionPath);
- }
- },
- );
- };
-
- redirect(approved) {
- const { navigate, permissionsRequest } = this.props;
-
- let shouldRedirect = true;
-
- const isRequestingSnap =
- permissionsRequest?.permissions &&
- Object.keys(permissionsRequest.permissions).includes('wallet_snap');
-
- shouldRedirect = !isRequestingSnap;
-
- this.setState({
- redirecting: shouldRedirect,
- permissionsApproved: approved,
- });
-
- if (shouldRedirect && approved) {
- setTimeout(() => navigate(DEFAULT_ROUTE), APPROVE_TIMEOUT);
- return;
- }
- navigate(DEFAULT_ROUTE);
- }
-
- cancelPermissionsRequest = async (requestId) => {
- const { rejectPermissionsRequest } = this.props;
-
- if (requestId) {
- await rejectPermissionsRequest(requestId);
- this.redirect(false);
- }
- };
-
- goBack() {
- const { navigate, connectPath } = this.props;
- navigate(connectPath);
- }
-
- renderSnapChooseAccountState1 = () => {
- const {
- accounts,
- nativeCurrency,
- showNewAccountModal,
- newAccountNumber,
- addressLastConnectedMap,
- permissionsRequestId,
- targetSubjectMetadata,
- } = this.props;
- const { selectedAccountAddresses } = this.state;
-
- return (
- this.selectAccounts(addresses)}
- selectNewAccountViaModal={(handleAccountClick) => {
- showNewAccountModal({
- onCreateNewAccount: (address) => handleAccountClick(address),
- newAccountNumber,
- });
- }}
- addressLastConnectedMap={addressLastConnectedMap}
- cancelPermissionsRequest={(requestId) =>
- this.cancelPermissionsRequest(requestId)
- }
- permissionsRequestId={permissionsRequestId}
- selectedAccountAddresses={selectedAccountAddresses}
- targetSubjectMetadata={targetSubjectMetadata}
- />
- );
- };
-
- renderSnapChooseAccountState2 = () => {
- const { permissionsRequestId, accountGroups, permissionsRequest } =
- this.props;
- const { t } = this.context;
- const requestedCaip25CaveatValue = getCaip25CaveatValueFromPermissions(
- permissionsRequest?.permissions,
- );
-
- const caipChainIdsToUse = [];
-
- const requestedCaipChainIds = getAllScopesFromCaip25CaveatValue(
- requestedCaip25CaveatValue,
- ).filter((chainId) => {
- const { namespace } = parseCaipChainId(chainId);
- return namespace !== KnownCaipNamespace.Wallet;
- });
- const requestedNamespaces = getAllNamespacesFromCaip25CaveatValue(
- requestedCaip25CaveatValue,
- );
-
- if (requestedCaipChainIds.length > 0) {
- requestedCaipChainIds.forEach((chainId) => {
- caipChainIdsToUse.push(chainId);
- });
- }
-
- if (requestedNamespaces.includes(KnownCaipNamespace.Eip155)) {
- caipChainIdsToUse.push(`${KnownCaipNamespace.Eip155}:0`);
- }
-
- return (
- {
- const filteredAccountGroups = accountGroups.filter(
- (group) =>
- accountGroupIds.includes(group.id) &&
- supportsChainIds(group, caipChainIdsToUse),
- );
- const addresses = getCaip25AccountIdsFromAccountGroupAndScope(
- filteredAccountGroups,
- caipChainIdsToUse,
- ).map(
- (caip25AccountId) => parseCaipAccountId(caip25AccountId).address,
- );
- this.selectAccounts(new Set(addresses));
- }}
- onClose={() => this.cancelPermissionsRequest(permissionsRequestId)}
- />
- );
- };
-
- renderConnectPageState1 = () => {
- const connectPageProps = {
- rejectPermissionsRequest: (requestId) =>
- this.cancelPermissionsRequest(requestId),
- activeTabOrigin: this.state.origin,
- request: this.props.permissionsRequest || {},
- permissionsRequestId: this.props.permissionsRequestId,
- approveConnection: this.approveConnection,
- targetSubjectMetadata: this.props.targetSubjectMetadata,
- };
-
- return ;
- };
-
- renderConnectPageState2 = () => {
- const connectPageProps = {
- rejectPermissionsRequest: (requestId) =>
- this.cancelPermissionsRequest(requestId),
- activeTabOrigin: this.state.origin,
- request: this.props.permissionsRequest || {},
- permissionsRequestId: this.props.permissionsRequestId,
- approveConnection: this.approveConnection,
- targetSubjectMetadata: this.props.targetSubjectMetadata,
- };
-
- return ;
- };
-
- renderTopBar(permissionsRequestId) {
- const { targetSubjectMetadata } = this.state;
- const handleCancelFromHeader = () => {
- this.cancelPermissionsRequest(permissionsRequestId);
- };
- return (
-
- {targetSubjectMetadata.subjectType === SubjectType.Snap && (
-
- )}
-
- );
- }
-
- approveConnection = (...args) => {
- const { approvePermissionsRequest } = this.props;
- approvePermissionsRequest(...args);
- this.redirect(true);
- };
-
- render() {
- const {
- accounts,
- permissionsRequest,
- permissionsRequestId,
- connectPath,
- hideTopBar,
- targetSubjectMetadata,
- requestState,
- approvePendingApproval,
- rejectPendingApproval,
- setSnapsInstallPrivacyWarningShownStatus,
- approvePermissionsRequest,
- navigate,
- location,
- } = this.props;
- const {
- selectedAccountAddresses,
- permissionsApproved,
- redirecting,
- snapsInstallPrivacyWarningShown,
- } = this.state;
-
- const isRequestingSnap = isSnapId(permissionsRequest?.metadata?.origin);
-
- // Create a relative location for nested v5-compat Routes
- const relativeLocation = getRelativeLocationForNestedRoutes(
- location,
- connectPath,
- );
-
- return (
-
- {!hideTopBar && this.renderTopBar(permissionsRequestId)}
- {redirecting && permissionsApproved ? (
-
- ) : (
-
- {
- if (isRequestingSnap) {
- return (
-
- );
- }
- return (
-
- );
- })()}
- />
- {
- approvePermissionsRequest(...args);
- this.redirect(true);
- }}
- rejectPermissionsRequest={(requestId) =>
- this.cancelPermissionsRequest(requestId)
- }
- selectedAccounts={accounts.filter((account) =>
- selectedAccountAddresses.has(account.address),
- )}
- requestedChainIds={getRequestedChainIds(
- permissionsRequest?.permissions,
- )}
- targetSubjectMetadata={targetSubjectMetadata}
- navigate={navigate}
- connectPath={connectPath}
- snapsInstallPrivacyWarningShown={
- snapsInstallPrivacyWarningShown
- }
- setSnapsInstallPrivacyWarningShownStatus={
- setSnapsInstallPrivacyWarningShownStatus
- }
- />
- }
- />
-
- this.cancelPermissionsRequest(requestId)
- }
- targetSubjectMetadata={targetSubjectMetadata}
- snapsInstallPrivacyWarningShown={
- snapsInstallPrivacyWarningShown
- }
- setSnapsInstallPrivacyWarningShownStatus={
- setSnapsInstallPrivacyWarningShownStatus
- }
- />
- }
- />
- {
- approvePendingApproval(requestId, {
- ...permissionsRequest,
- permissions: requestState.permissions,
- approvedAccounts: [...selectedAccountAddresses],
- });
- this.setState({ permissionsApproved: true });
- }}
- rejectSnapInstall={(requestId) => {
- rejectPendingApproval(
- requestId,
- serializeError(providerErrors.userRejectedRequest()),
- );
- this.setState({ permissionsApproved: true });
- }}
- targetSubjectMetadata={targetSubjectMetadata}
- />
- }
- />
- {
- approvePendingApproval(requestId, {
- ...permissionsRequest,
- permissions: requestState.permissions,
- approvedAccounts: [...selectedAccountAddresses],
- });
- this.setState({ permissionsApproved: true });
- }}
- rejectSnapUpdate={(requestId) => {
- rejectPendingApproval(
- requestId,
- serializeError(providerErrors.userRejectedRequest()),
- );
- this.setState({ permissionsApproved: false });
- }}
- targetSubjectMetadata={targetSubjectMetadata}
- />
- }
- />
- {
- approvePendingApproval(requestId);
- this.setState({ permissionsApproved: true });
- }}
- targetSubjectMetadata={targetSubjectMetadata}
- />
- }
- />
-
- )}
-
- );
- }
-}
diff --git a/ui/pages/permissions-connect/permissions-connect.container.js b/ui/pages/permissions-connect/permissions-connect.container.js
deleted file mode 100644
index e65244439f31..000000000000
--- a/ui/pages/permissions-connect/permissions-connect.container.js
+++ /dev/null
@@ -1,195 +0,0 @@
-import { SubjectType } from '@metamask/permission-controller';
-import { WALLET_SNAP_PERMISSION_KEY } from '@metamask/snaps-rpc-methods';
-import { connect } from 'react-redux';
-import { isEvmAccountType } from '@metamask/keyring-api';
-import { Caip25EndowmentPermissionName } from '@metamask/chain-agnostic-permission';
-import {
- getAccountsWithLabels,
- getLastConnectedInfo,
- getPermissionsRequests,
- getSelectedInternalAccount,
- getSnapInstallOrUpdateRequests,
- getRequestState,
- getSnapsInstallPrivacyWarningShown,
- getRequestType,
- getTargetSubjectMetadata,
-} from '../../selectors';
-import { getNativeCurrency } from '../../ducks/metamask/metamask';
-
-import { formatDate, getURLHostName } from '../../helpers/utils/util';
-import {
- approvePermissionsRequest,
- rejectPermissionsRequest,
- showModal,
- getRequestAccountTabIds,
- resolvePendingApproval,
- rejectPendingApproval,
- setSnapsInstallPrivacyWarningShownStatus,
-} from '../../store/actions';
-import {
- CONNECT_ROUTE,
- CONNECT_CONFIRM_PERMISSIONS_ROUTE,
- CONNECT_SNAPS_CONNECT_ROUTE,
- CONNECT_SNAP_INSTALL_ROUTE,
- CONNECT_SNAP_UPDATE_ROUTE,
- CONNECT_SNAP_RESULT_ROUTE,
-} from '../../helpers/constants/routes';
-import { getAccountGroupWithInternalAccounts } from '../../selectors/multichain-accounts/account-tree';
-import PermissionApproval from './permissions-connect.component';
-
-const mapStateToProps = (state, ownProps) => {
- const {
- match: {
- params: { id: permissionsRequestId },
- },
- location: { pathname },
- } = ownProps;
- let permissionsRequests = getPermissionsRequests(state);
- permissionsRequests = [
- ...permissionsRequests,
- ...getSnapInstallOrUpdateRequests(state),
- ];
- const { address: currentAddress } = getSelectedInternalAccount(state);
-
- const permissionsRequest = permissionsRequests.find(
- (req) => req.metadata.id === permissionsRequestId,
- );
-
- const { metadata = {}, diff = {} } = permissionsRequest || {};
- const { origin } = metadata;
- const nativeCurrency = getNativeCurrency(state);
-
- const isRequestApprovalPermittedChains = Boolean(diff?.permissionDiffMap);
- const isRequestingAccounts = Boolean(
- permissionsRequest?.permissions?.[Caip25EndowmentPermissionName] &&
- !isRequestApprovalPermittedChains,
- );
-
- const targetSubjectMetadata = getTargetSubjectMetadata(state, origin) ?? {
- name: getURLHostName(origin) || origin,
- origin,
- iconUrl: null,
- extensionId: null,
- subjectType: SubjectType.Unknown,
- };
-
- let requestType = getRequestType(state, permissionsRequestId);
-
- // We want to only assign the wallet_connectSnaps request type (i.e. only show
- // SnapsConnect) if and only if we get a singular wallet_snap permission request.
- // Any other request gets pushed to the normal permission connect flow.
- if (
- permissionsRequest &&
- Object.keys(permissionsRequest.permissions || {}).length === 1 &&
- permissionsRequest.permissions?.[WALLET_SNAP_PERMISSION_KEY]
- ) {
- requestType = 'wallet_connectSnaps';
- }
-
- const requestState = getRequestState(state, permissionsRequestId) || {};
-
- // We only consider EVM accounts.
- // Connections with non-EVM accounts (Bitcoin only for now) are used implicitly and handled by the Bitcoin Snap itself.
- const accountsWithLabels = getAccountsWithLabels(state).filter((account) =>
- isEvmAccountType(account.type),
- );
-
- const lastConnectedInfo = getLastConnectedInfo(state) || {};
- const addressLastConnectedMap = lastConnectedInfo[origin]?.accounts || {};
-
- Object.keys(addressLastConnectedMap).forEach((key) => {
- addressLastConnectedMap[key] = formatDate(
- addressLastConnectedMap[key],
- 'yyyy-MM-dd',
- );
- });
-
- const connectPath = `${CONNECT_ROUTE}/${permissionsRequestId}`;
- const confirmPermissionPath = `${connectPath}${CONNECT_CONFIRM_PERMISSIONS_ROUTE}`;
- const snapsConnectPath = `${connectPath}${CONNECT_SNAPS_CONNECT_ROUTE}`;
- const snapInstallPath = `${connectPath}${CONNECT_SNAP_INSTALL_ROUTE}`;
- const snapUpdatePath = `${connectPath}${CONNECT_SNAP_UPDATE_ROUTE}`;
- const snapResultPath = `${connectPath}${CONNECT_SNAP_RESULT_ROUTE}`;
-
- const isSnapInstallOrUpdateOrResult =
- pathname === snapInstallPath ||
- pathname === snapUpdatePath ||
- pathname === snapResultPath;
-
- let totalPages = 1 + isRequestingAccounts;
- totalPages += isSnapInstallOrUpdateOrResult;
- totalPages = totalPages.toString();
-
- let page = '';
- if (pathname === connectPath) {
- page = '1';
- } else if (pathname === confirmPermissionPath) {
- page = isRequestingAccounts ? '2' : '1';
- } else if (isSnapInstallOrUpdateOrResult) {
- page = isRequestingAccounts ? '3' : '2';
- } else if (pathname === snapsConnectPath) {
- page = 1;
- } else {
- throw new Error('Incorrect path for permissions-connect component');
- }
-
- return {
- isRequestingAccounts,
- requestType,
- snapsConnectPath,
- snapInstallPath,
- snapUpdatePath,
- snapResultPath,
- confirmPermissionPath,
- requestState,
- hideTopBar: isSnapInstallOrUpdateOrResult,
- snapsInstallPrivacyWarningShown: getSnapsInstallPrivacyWarningShown(state),
- permissionsRequest,
- permissionsRequestId,
- accounts: accountsWithLabels,
- accountGroups: getAccountGroupWithInternalAccounts(state),
- currentAddress,
- origin,
- newAccountNumber: accountsWithLabels.length + 1,
- nativeCurrency,
- addressLastConnectedMap,
- lastConnectedInfo,
- connectPath,
- totalPages,
- page,
- targetSubjectMetadata,
- };
-};
-
-const mapDispatchToProps = (dispatch) => {
- return {
- approvePermissionsRequest: (request) =>
- dispatch(approvePermissionsRequest(request)),
- rejectPermissionsRequest: (requestId) =>
- dispatch(rejectPermissionsRequest(requestId)),
- approvePendingApproval: (id, value) =>
- dispatch(resolvePendingApproval(id, value)),
- rejectPendingApproval: (id, error) =>
- dispatch(rejectPendingApproval(id, error)),
- setSnapsInstallPrivacyWarningShownStatus: (shown) => {
- dispatch(setSnapsInstallPrivacyWarningShownStatus(shown));
- },
- showNewAccountModal: ({ onCreateNewAccount, newAccountNumber }) => {
- return dispatch(
- showModal({
- name: 'NEW_ACCOUNT',
- onCreateNewAccount,
- newAccountNumber,
- }),
- );
- },
- getRequestAccountTabIds: () => dispatch(getRequestAccountTabIds()),
- };
-};
-
-const PermissionApprovalContainer = connect(
- mapStateToProps,
- mapDispatchToProps,
-)(PermissionApproval);
-
-export default PermissionApprovalContainer;
diff --git a/ui/pages/permissions-connect/permissions-connect.tsx b/ui/pages/permissions-connect/permissions-connect.tsx
new file mode 100644
index 000000000000..7e53482418d8
--- /dev/null
+++ b/ui/pages/permissions-connect/permissions-connect.tsx
@@ -0,0 +1,779 @@
+import React, {
+ useEffect,
+ useState,
+ useCallback,
+ useRef,
+ useMemo,
+} from 'react';
+import { useSelector, useDispatch } from 'react-redux';
+import {
+ useNavigate,
+ useLocation,
+ useParams,
+ Routes,
+ Route,
+} from 'react-router-dom';
+import { providerErrors, serializeError } from '@metamask/rpc-errors';
+import { SubjectType } from '@metamask/permission-controller';
+import { isSnapId } from '@metamask/snaps-utils';
+import { WALLET_SNAP_PERMISSION_KEY } from '@metamask/snaps-rpc-methods';
+import { isEvmAccountType, KeyringAccountType } from '@metamask/keyring-api';
+import {
+ Caip25EndowmentPermissionName,
+ getAllNamespacesFromCaip25CaveatValue,
+ getAllScopesFromCaip25CaveatValue,
+ getEthAccounts,
+ getPermittedEthChainIds,
+} from '@metamask/chain-agnostic-permission';
+import {
+ KnownCaipNamespace,
+ parseCaipAccountId,
+ parseCaipChainId,
+} from '@metamask/utils';
+import { toRelativeRoutePath } from '../routes/utils';
+// TODO: Remove restricted import
+// eslint-disable-next-line import/no-restricted-paths
+import { isEthAddress } from '../../../app/scripts/lib/multichain/address';
+import { MILLISECOND } from '../../../shared/constants/time';
+import {
+ DEFAULT_ROUTE,
+ CONNECT_ROUTE,
+ CONNECT_CONFIRM_PERMISSIONS_ROUTE,
+ CONNECT_SNAPS_CONNECT_ROUTE,
+ CONNECT_SNAP_INSTALL_ROUTE,
+ CONNECT_SNAP_UPDATE_ROUTE,
+ CONNECT_SNAP_RESULT_ROUTE,
+} from '../../helpers/constants/routes';
+import {
+ getAccountsWithLabels,
+ getLastConnectedInfo,
+ getPermissionsRequests,
+ getSelectedInternalAccount,
+ getSnapInstallOrUpdateRequests,
+ getRequestState,
+ getSnapsInstallPrivacyWarningShown,
+ getRequestType,
+ getTargetSubjectMetadata,
+} from '../../selectors';
+import { getNativeCurrency } from '../../ducks/metamask/metamask';
+import { formatDate, getURLHostName } from '../../helpers/utils/util';
+import {
+ approvePermissionsRequest as approvePermissionsRequestAction,
+ rejectPermissionsRequest as rejectPermissionsRequestAction,
+ showModal,
+ getRequestAccountTabIds as getRequestAccountTabIdsAction,
+ resolvePendingApproval,
+ rejectPendingApproval as rejectPendingApprovalAction,
+ setSnapsInstallPrivacyWarningShownStatus as setSnapsInstallPrivacyWarningShownStatusAction,
+} from '../../store/actions';
+import { getAccountGroupWithInternalAccounts } from '../../selectors/multichain-accounts/account-tree';
+import PermissionPageContainer from '../../components/app/permission-page-container';
+import { Box } from '../../components/component-library';
+import SnapAuthorshipHeader from '../../components/app/snaps/snap-authorship-header/snap-authorship-header';
+import { State2Wrapper } from '../../components/multichain-accounts/state2-wrapper/state2-wrapper';
+import { MultichainAccountsConnectPage } from '../multichain-accounts/multichain-accounts-connect-page/multichain-accounts-connect-page';
+import { supportsChainIds } from '../../hooks/useAccountGroupsForPermissions';
+import { getCaip25AccountIdsFromAccountGroupAndScope } from '../../../shared/lib/multichain/scope-utils';
+import { MultichainEditAccountsPageWrapper } from '../../components/multichain-accounts/permissions/multichain-edit-accounts-page/multichain-edit-account-wrapper';
+import { useI18nContext } from '../../hooks/useI18nContext';
+import ChooseAccount from './choose-account';
+import PermissionsRedirect from './redirect';
+import SnapsConnect from './snaps/snaps-connect';
+import SnapInstall from './snaps/snap-install';
+import SnapUpdate from './snaps/snap-update';
+import SnapResult from './snaps/snap-result';
+import { ConnectPage } from './connect-page/connect-page';
+import {
+ getCaip25CaveatValueFromPermissions,
+ PermissionsRequest,
+} from './connect-page/utils';
+
+const APPROVE_TIMEOUT = MILLISECOND * 1200;
+
+function getDefaultSelectedAccounts(
+ currentAddress: string,
+ permissions: PermissionsRequest,
+) {
+ const requestedCaip25CaveatValue =
+ getCaip25CaveatValueFromPermissions(permissions);
+ const requestedAccounts = getEthAccounts(requestedCaip25CaveatValue);
+
+ if (requestedAccounts.length > 0) {
+ return new Set(
+ requestedAccounts
+ .map((address) => address.toLowerCase())
+ // We only consider EVM accounts here (used for `eth_requestAccounts` or `eth_accounts`)
+ .filter(isEthAddress),
+ );
+ }
+
+ // We only consider EVM accounts here (used for `eth_requestAccounts` or `eth_accounts`)
+ return new Set(isEthAddress(currentAddress) ? [currentAddress] : []);
+}
+
+function getRequestedChainIds(permissions: PermissionsRequest | undefined) {
+ const requestedCaip25CaveatValue =
+ getCaip25CaveatValueFromPermissions(permissions);
+ return getPermittedEthChainIds(requestedCaip25CaveatValue);
+}
+
+// eslint-disable-next-line @typescript-eslint/naming-convention
+function PermissionsConnect() {
+ const dispatch = useDispatch();
+ const navigate = useNavigate();
+ const location = useLocation();
+ const params = useParams();
+ const t = useI18nContext();
+
+ const permissionsRequestId = params.id;
+
+ // Selectors
+ const { pathname } = location;
+ let permissionsRequests = useSelector(getPermissionsRequests);
+ permissionsRequests = [
+ ...permissionsRequests,
+ ...useSelector(getSnapInstallOrUpdateRequests),
+ ];
+ const { address: currentAddress } = useSelector(getSelectedInternalAccount);
+
+ const permissionsRequest = permissionsRequests.find(
+ (req: Record) =>
+ (req.metadata as Record)?.id === permissionsRequestId,
+ ) as Record | undefined;
+
+ const { metadata = {}, diff = {} } = permissionsRequest || {};
+ const { origin: originFromRequest } = (metadata || {}) as Record<
+ string,
+ string
+ >;
+ const nativeCurrency = useSelector(getNativeCurrency);
+
+ const isRequestApprovalPermittedChains = Boolean(
+ (diff as Record)?.permissionDiffMap,
+ );
+ const permissions = permissionsRequest?.permissions as
+ | Record
+ | undefined;
+ const isRequestingAccounts = Boolean(
+ permissions?.[Caip25EndowmentPermissionName] &&
+ !isRequestApprovalPermittedChains,
+ );
+
+ const targetSubjectMetadataFromSelector = useSelector((state) =>
+ getTargetSubjectMetadata(state, originFromRequest),
+ );
+
+ const targetSubjectMetadataProp = useMemo(
+ () =>
+ targetSubjectMetadataFromSelector ?? {
+ name: getURLHostName(originFromRequest) || originFromRequest,
+ origin: originFromRequest,
+ iconUrl: null,
+ extensionId: null,
+ subjectType: SubjectType.Unknown,
+ },
+ [targetSubjectMetadataFromSelector, originFromRequest],
+ );
+
+ let requestType = useSelector((state) =>
+ getRequestType(state, permissionsRequestId),
+ );
+
+ // We want to only assign the wallet_connectSnaps request type (i.e. only show
+ // SnapsConnect) if and only if we get a singular wallet_snap permission request.
+ // Any other request gets pushed to the normal permission connect flow.
+ if (
+ permissionsRequest &&
+ Object.keys(permissions || {}).length === 1 &&
+ permissions?.[WALLET_SNAP_PERMISSION_KEY]
+ ) {
+ requestType = 'wallet_connectSnaps';
+ }
+
+ const requestState =
+ useSelector((state) => getRequestState(state, permissionsRequestId)) || {};
+
+ // We only consider EVM accounts.
+ // Connections with non-EVM accounts (Bitcoin only for now) are used implicitly and handled by the Bitcoin Snap itself.
+ const accountsWithLabels = useSelector(getAccountsWithLabels).filter(
+ (account: { type: string }) =>
+ isEvmAccountType(account.type as KeyringAccountType),
+ );
+
+ const accountGroups = useSelector(getAccountGroupWithInternalAccounts);
+ const lastConnectedInfoRaw = useSelector(getLastConnectedInfo);
+
+ const lastConnectedInfo = useMemo(
+ () => lastConnectedInfoRaw || {},
+ [lastConnectedInfoRaw],
+ );
+
+ const addressLastConnectedMap = useMemo(() => {
+ const map = lastConnectedInfo[originFromRequest]?.accounts || {};
+ const formattedMap: Record = {};
+ Object.keys(map).forEach((key) => {
+ formattedMap[key] = formatDate(map[key], 'yyyy-MM-dd');
+ });
+ return formattedMap;
+ }, [lastConnectedInfo, originFromRequest]);
+
+ const connectPath = `${CONNECT_ROUTE}/${permissionsRequestId}`;
+ const confirmPermissionPath = `${connectPath}${CONNECT_CONFIRM_PERMISSIONS_ROUTE}`;
+ const snapsConnectPath = `${connectPath}${CONNECT_SNAPS_CONNECT_ROUTE}`;
+ const snapInstallPath = `${connectPath}${CONNECT_SNAP_INSTALL_ROUTE}`;
+ const snapUpdatePath = `${connectPath}${CONNECT_SNAP_UPDATE_ROUTE}`;
+ const snapResultPath = `${connectPath}${CONNECT_SNAP_RESULT_ROUTE}`;
+
+ const isSnapInstallOrUpdateOrResult =
+ pathname === snapInstallPath ||
+ pathname === snapUpdatePath ||
+ pathname === snapResultPath;
+
+ const hideTopBar = isSnapInstallOrUpdateOrResult;
+ const snapsInstallPrivacyWarningShownProp = useSelector(
+ getSnapsInstallPrivacyWarningShown,
+ );
+
+ const newAccountNumber = accountsWithLabels.length + 1;
+
+ // Local state
+ const [redirecting, setRedirecting] = useState(false);
+ const [selectedAccountAddresses, setSelectedAccountAddresses] = useState(() =>
+ getDefaultSelectedAccounts(
+ currentAddress,
+ permissions as PermissionsRequest,
+ ),
+ );
+ const [permissionsApproved, setPermissionsApproved] = useState<
+ boolean | null
+ >(null);
+ const [origin] = useState(originFromRequest);
+ const [targetSubjectMetadata, setTargetSubjectMetadata] = useState(
+ targetSubjectMetadataProp || {},
+ );
+ const [snapsInstallPrivacyWarningShown] = useState(
+ snapsInstallPrivacyWarningShownProp,
+ );
+
+ const prevPermissionsRequestRef = useRef(
+ null,
+ );
+ const prevTargetSubjectMetadataRef = useRef<
+ typeof targetSubjectMetadataProp | null
+ >(null);
+ const prevLastConnectedInfoRef = useRef(
+ null,
+ );
+
+ // Define redirect function before it's used in effects
+ const redirect = useCallback(
+ (approved: boolean) => {
+ let shouldRedirect = true;
+
+ const isRequestingSnap =
+ permissions && Object.keys(permissions).includes('wallet_snap');
+
+ shouldRedirect = !isRequestingSnap;
+
+ setRedirecting(shouldRedirect);
+ setPermissionsApproved(approved);
+
+ // If requesting a snap, don't navigate - wait for the snap install request
+ if (!shouldRedirect) {
+ return;
+ }
+
+ if (approved) {
+ setTimeout(() => navigate(DEFAULT_ROUTE), APPROVE_TIMEOUT);
+ return;
+ }
+ navigate(DEFAULT_ROUTE);
+ },
+ [permissions, navigate],
+ );
+
+ // Handle initial navigation on mount
+ useEffect(() => {
+ dispatch(getRequestAccountTabIdsAction());
+
+ if (!permissionsRequest) {
+ navigate(DEFAULT_ROUTE, { replace: true });
+ return;
+ }
+
+ if (location.pathname === connectPath && !isRequestingAccounts) {
+ switch (requestType) {
+ case 'wallet_installSnap':
+ navigate(snapInstallPath, { replace: true });
+ break;
+ case 'wallet_updateSnap':
+ navigate(snapUpdatePath, { replace: true });
+ break;
+ case 'wallet_installSnapResult':
+ navigate(snapResultPath, { replace: true });
+ break;
+ case 'wallet_connectSnaps':
+ navigate(snapsConnectPath, { replace: true });
+ break;
+ default:
+ navigate(confirmPermissionPath, { replace: true });
+ }
+ }
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
+
+ // Cache targetSubjectMetadata when it changes
+ useEffect(() => {
+ if (
+ targetSubjectMetadataProp?.origin &&
+ prevTargetSubjectMetadataRef.current?.origin !==
+ targetSubjectMetadataProp?.origin
+ ) {
+ setTargetSubjectMetadata(targetSubjectMetadataProp);
+ }
+ prevTargetSubjectMetadataRef.current = targetSubjectMetadataProp;
+ }, [targetSubjectMetadataProp]);
+
+ // Handle redirect on permissions approval/rejection
+ useEffect(() => {
+ if (
+ !permissionsRequest &&
+ prevPermissionsRequestRef.current &&
+ !redirecting
+ ) {
+ const lastConnectedForOrigin = lastConnectedInfo[origin] as
+ | { lastApproved?: number; accounts?: Record }
+ | undefined;
+ const prevLastConnectedForOrigin = prevLastConnectedInfoRef.current?.[
+ origin
+ ] as
+ | { lastApproved?: number; accounts?: Record }
+ | undefined;
+
+ const accountsLastApprovedTime =
+ lastConnectedForOrigin?.lastApproved || 0;
+ const initialAccountsLastApprovedTime =
+ prevLastConnectedForOrigin?.lastApproved || 0;
+
+ const approved =
+ accountsLastApprovedTime > initialAccountsLastApprovedTime;
+ redirect(approved);
+ }
+ prevPermissionsRequestRef.current = permissionsRequest;
+ prevLastConnectedInfoRef.current = lastConnectedInfo;
+ }, [permissionsRequest, lastConnectedInfo, redirecting, origin, redirect]);
+
+ const selectAccounts = useCallback(
+ (addresses: Set) => {
+ setSelectedAccountAddresses(addresses);
+ // Navigate after state is updated
+ setTimeout(() => {
+ switch (requestType) {
+ case 'wallet_installSnap':
+ navigate(snapInstallPath);
+ break;
+ case 'wallet_updateSnap':
+ navigate(snapUpdatePath);
+ break;
+ case 'wallet_installSnapResult':
+ navigate(snapResultPath);
+ break;
+ case 'wallet_connectSnaps':
+ navigate(snapsConnectPath, { replace: true });
+ break;
+ default:
+ navigate(confirmPermissionPath);
+ }
+ }, 0);
+ },
+ [
+ requestType,
+ snapInstallPath,
+ snapUpdatePath,
+ snapResultPath,
+ snapsConnectPath,
+ confirmPermissionPath,
+ navigate,
+ ],
+ );
+
+ const cancelPermissionsRequest = useCallback(
+ async (requestId: string) => {
+ if (requestId) {
+ await dispatch(rejectPermissionsRequestAction(requestId));
+ redirect(false);
+ }
+ },
+ [dispatch, redirect],
+ );
+
+ const approveConnection = useCallback(
+ (request: Record) => {
+ // Cast through unknown to satisfy both local and controller types
+ dispatch(
+ approvePermissionsRequestAction(
+ request as unknown as PermissionsRequest,
+ ),
+ );
+ redirect(true);
+ },
+ [dispatch, redirect],
+ );
+
+ const showNewAccountModal = useCallback(
+ ({
+ onCreateNewAccount,
+ newAccountNumber: accountNumber,
+ }: {
+ onCreateNewAccount: (address: string) => void;
+ newAccountNumber: number;
+ }) => {
+ return dispatch(
+ showModal({
+ name: 'NEW_ACCOUNT',
+ onCreateNewAccount,
+ newAccountNumber: accountNumber,
+ }),
+ );
+ },
+ [dispatch],
+ );
+
+ const setSnapsInstallPrivacyWarningShownStatus = useCallback(
+ (shown: boolean) => {
+ dispatch(setSnapsInstallPrivacyWarningShownStatusAction(shown));
+ },
+ [dispatch],
+ );
+
+ const approvePendingApproval = useCallback(
+ (id: string, value?: unknown) =>
+ dispatch(resolvePendingApproval(id, value)),
+ [dispatch],
+ );
+
+ const rejectPendingApproval = useCallback(
+ (id: string, error: unknown) =>
+ dispatch(rejectPendingApprovalAction(id, error)),
+ [dispatch],
+ );
+
+ const renderSnapChooseAccountState1 = useCallback(() => {
+ return (
+ selectAccounts(addresses)}
+ selectNewAccountViaModal={(
+ handleAccountClick: (address: string) => void,
+ ) => {
+ showNewAccountModal({
+ onCreateNewAccount: (address: string) =>
+ handleAccountClick(address),
+ newAccountNumber,
+ });
+ }}
+ addressLastConnectedMap={addressLastConnectedMap}
+ cancelPermissionsRequest={(requestId: string) =>
+ cancelPermissionsRequest(requestId)
+ }
+ permissionsRequestId={permissionsRequestId || ''}
+ selectedAccountAddresses={selectedAccountAddresses}
+ targetSubjectMetadata={targetSubjectMetadata}
+ />
+ );
+ }, [
+ accountsWithLabels,
+ nativeCurrency,
+ selectAccounts,
+ showNewAccountModal,
+ newAccountNumber,
+ addressLastConnectedMap,
+ cancelPermissionsRequest,
+ permissionsRequestId,
+ selectedAccountAddresses,
+ targetSubjectMetadata,
+ ]);
+
+ const renderSnapChooseAccountState2 = useCallback(() => {
+ const requestedCaip25CaveatValue = getCaip25CaveatValueFromPermissions(
+ permissions as PermissionsRequest | undefined,
+ );
+
+ const caipChainIdsToUse: `${string}:${string}`[] = [];
+
+ const requestedCaipChainIds = getAllScopesFromCaip25CaveatValue(
+ requestedCaip25CaveatValue,
+ ).filter((chainId) => {
+ const { namespace } = parseCaipChainId(chainId);
+ return namespace !== KnownCaipNamespace.Wallet;
+ });
+ const requestedNamespaces = getAllNamespacesFromCaip25CaveatValue(
+ requestedCaip25CaveatValue,
+ );
+
+ if (requestedCaipChainIds.length > 0) {
+ requestedCaipChainIds.forEach((chainId) => {
+ caipChainIdsToUse.push(chainId);
+ });
+ }
+
+ if (requestedNamespaces.includes(KnownCaipNamespace.Eip155)) {
+ caipChainIdsToUse.push(`${KnownCaipNamespace.Eip155}:0`);
+ }
+
+ return (
+ {
+ const filteredAccountGroups = accountGroups.filter(
+ (group) =>
+ accountGroupIds.includes(group.id) &&
+ supportsChainIds(group, caipChainIdsToUse),
+ );
+ const addresses = getCaip25AccountIdsFromAccountGroupAndScope(
+ filteredAccountGroups,
+ caipChainIdsToUse,
+ ).map(
+ (caip25AccountId) => parseCaipAccountId(caip25AccountId).address,
+ );
+ selectAccounts(new Set(addresses));
+ }}
+ onClose={() => cancelPermissionsRequest(permissionsRequestId || '')}
+ />
+ );
+ }, [
+ permissions,
+ accountGroups,
+ t,
+ selectAccounts,
+ cancelPermissionsRequest,
+ permissionsRequestId,
+ ]);
+
+ const renderConnectPageState1 = useCallback(() => {
+ const connectPageProps = {
+ rejectPermissionsRequest: (requestId: string) =>
+ cancelPermissionsRequest(requestId),
+ activeTabOrigin: origin,
+ request: permissionsRequest || {},
+ permissionsRequestId: permissionsRequestId || '',
+ approveConnection,
+ targetSubjectMetadata,
+ };
+
+ return ;
+ }, [
+ cancelPermissionsRequest,
+ origin,
+ permissionsRequest,
+ permissionsRequestId,
+ approveConnection,
+ targetSubjectMetadata,
+ ]);
+
+ const renderConnectPageState2 = useCallback(() => {
+ const connectPageProps = {
+ rejectPermissionsRequest: (requestId: string) =>
+ cancelPermissionsRequest(requestId),
+ activeTabOrigin: origin,
+ request: permissionsRequest || {},
+ permissionsRequestId: permissionsRequestId || '',
+ approveConnection,
+ targetSubjectMetadata,
+ };
+
+ return ;
+ }, [
+ cancelPermissionsRequest,
+ origin,
+ permissionsRequest,
+ permissionsRequestId,
+ approveConnection,
+ targetSubjectMetadata,
+ ]);
+
+ const renderTopBar = useCallback(
+ (requestId: string) => {
+ const handleCancelFromHeader = () => {
+ cancelPermissionsRequest(requestId);
+ };
+ return (
+
+ {targetSubjectMetadata.subjectType === SubjectType.Snap && (
+
+ )}
+
+ );
+ },
+ [targetSubjectMetadata, cancelPermissionsRequest],
+ );
+
+ const isRequestingSnap = isSnapId(
+ (metadata as Record)?.origin,
+ );
+
+ return (
+
+ {!hideTopBar &&
+ permissionsRequestId &&
+ renderTopBar(permissionsRequestId)}
+ {redirecting && permissionsApproved ? (
+
+ ) : (
+
+ {
+ if (isRequestingSnap) {
+ return (
+
+ );
+ }
+ return (
+
+ );
+ })()}
+ />
+ {
+ dispatch(
+ approvePermissionsRequestAction(
+ request as unknown as PermissionsRequest,
+ ),
+ );
+ redirect(true);
+ }}
+ rejectPermissionsRequest={(requestId: string) =>
+ cancelPermissionsRequest(requestId)
+ }
+ selectedAccounts={accountsWithLabels.filter(
+ (account: { address: string }) =>
+ selectedAccountAddresses.has(account.address),
+ )}
+ requestedChainIds={getRequestedChainIds(
+ permissions as PermissionsRequest | undefined,
+ )}
+ targetSubjectMetadata={targetSubjectMetadata}
+ navigate={navigate}
+ connectPath={connectPath}
+ snapsInstallPrivacyWarningShown={
+ snapsInstallPrivacyWarningShown
+ }
+ setSnapsInstallPrivacyWarningShownStatus={
+ setSnapsInstallPrivacyWarningShownStatus
+ }
+ />
+ }
+ />
+
+ cancelPermissionsRequest(requestId)
+ }
+ targetSubjectMetadata={targetSubjectMetadata}
+ snapsInstallPrivacyWarningShown={
+ snapsInstallPrivacyWarningShown
+ }
+ setSnapsInstallPrivacyWarningShownStatus={
+ setSnapsInstallPrivacyWarningShownStatus
+ }
+ />
+ }
+ />
+ {
+ approvePendingApproval(requestId, {
+ ...permissionsRequest,
+ permissions: requestState.permissions,
+ approvedAccounts: [...selectedAccountAddresses],
+ });
+ setPermissionsApproved(true);
+ }}
+ rejectSnapInstall={(requestId) => {
+ rejectPendingApproval(
+ requestId,
+ serializeError(providerErrors.userRejectedRequest()),
+ );
+ setPermissionsApproved(true);
+ }}
+ targetSubjectMetadata={targetSubjectMetadata}
+ />
+ }
+ />
+ {
+ approvePendingApproval(requestId, {
+ ...permissionsRequest,
+ permissions: requestState.permissions,
+ approvedAccounts: [...selectedAccountAddresses],
+ });
+ setPermissionsApproved(true);
+ }}
+ rejectSnapUpdate={(requestId) => {
+ rejectPendingApproval(
+ requestId,
+ serializeError(providerErrors.userRejectedRequest()),
+ );
+ setPermissionsApproved(false);
+ }}
+ targetSubjectMetadata={targetSubjectMetadata}
+ />
+ }
+ />
+ {
+ approvePendingApproval(requestId, undefined);
+ setPermissionsApproved(true);
+ }}
+ targetSubjectMetadata={targetSubjectMetadata}
+ />
+ }
+ />
+
+ )}
+
+ );
+}
+
+export default PermissionsConnect;
diff --git a/ui/pages/remove-snap-account/remove-snap-account.test.tsx b/ui/pages/remove-snap-account/remove-snap-account.test.tsx
index 7fa4c0a08f3c..87e986f2f798 100644
--- a/ui/pages/remove-snap-account/remove-snap-account.test.tsx
+++ b/ui/pages/remove-snap-account/remove-snap-account.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
-import { renderWithProvider } from '../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../test/lib/render-helpers-navigate';
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
import mockState from '../../../test/data/mock-state.json';
import { shortenAddress } from '../../helpers/utils/util';
diff --git a/ui/pages/rewards/index.tsx b/ui/pages/rewards/index.tsx
index 7587971f3bf2..2e4f5f186e0a 100644
--- a/ui/pages/rewards/index.tsx
+++ b/ui/pages/rewards/index.tsx
@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Box } from '@metamask/design-system-react';
-import { useLocation } from 'react-router-dom';
+import { useLocation, useNavigate } from 'react-router-dom';
import LoadingIndicator from '../../components/ui/loading-indicator';
import {
selectRewardsEnabled,
@@ -13,23 +13,16 @@ import {
setOnboardingReferralCode,
} from '../../ducks/rewards';
-type RewardsPageProps = {
- navigate: (to: string, options?: { replace?: boolean }) => void;
- location: Location;
-};
-
-const RewardsPage: React.FC = ({ navigate, location }) => {
+const RewardsPage: React.FC = () => {
const rewardsEnabled = useSelector(selectRewardsEnabled);
- const hookLocation = useLocation();
+ const location = useLocation();
+ const navigate = useNavigate();
const rewardsOnboardingEnabled = useSelector(selectRewardsOnboardingEnabled);
const dispatch = useDispatch();
useEffect(() => {
if (rewardsEnabled && rewardsOnboardingEnabled) {
- const localLocation = location ?? hookLocation;
- const params = localLocation
- ? new URLSearchParams(localLocation.search)
- : new URLSearchParams();
+ const params = new URLSearchParams(location.search);
const referral = params.get('referral');
if (referral && referral.length > 0) {
dispatch(setOnboardingReferralCode(referral));
@@ -41,14 +34,7 @@ const RewardsPage: React.FC = ({ navigate, location }) => {
}
navigate(DEFAULT_ROUTE, { replace: true });
- }, [
- navigate,
- dispatch,
- rewardsEnabled,
- rewardsOnboardingEnabled,
- location,
- hookLocation,
- ]);
+ }, [navigate, dispatch, rewardsEnabled, rewardsOnboardingEnabled, location]);
return (
diff --git a/ui/pages/routes/confirmation-handler.tsx b/ui/pages/routes/confirmation-handler.tsx
index e0bb55b8c7de..bfcf4d5d9437 100644
--- a/ui/pages/routes/confirmation-handler.tsx
+++ b/ui/pages/routes/confirmation-handler.tsx
@@ -1,6 +1,5 @@
import { useCallback, useEffect } from 'react';
-import { useLocation } from 'react-router-dom';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useLocation, useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import {
@@ -35,7 +34,6 @@ import {
selectHasSwapsQuotes,
selectShowAwaitingSwapScreen,
} from '../../ducks/swaps/swaps';
-import { useNavState } from '../../contexts/navigation-state';
import { useModalState } from '../../hooks/useModalState';
const EXEMPTED_ROUTES = [
@@ -68,7 +66,6 @@ export const ConfirmationHandler = () => {
const navigate = useNavigate();
const location = useLocation();
const { pathname } = location;
- const navState = useNavState();
const { closeModals } = useModalState();
const envType = getEnvironmentType();
@@ -81,11 +78,7 @@ export const ConfirmationHandler = () => {
const swapsFetchParams = useSelector(getFetchParams);
const pendingApprovals = useSelector(selectPendingApprovalsForNavigation);
const hasApprovalFlows = useSelector(selectHasApprovalFlows);
-
- // Read stayOnHomePage from both v5 location.state and v5-compat navState
- const stayOnHomePage =
- Boolean(location.state?.stayOnHomePage) ||
- Boolean(navState?.stayOnHomePage);
+ const stayOnHomePage = Boolean(location.state?.stayOnHomePage);
const canRedirect = !isNotification && !stayOnHomePage;
diff --git a/ui/pages/routes/routes.component.tsx b/ui/pages/routes/routes.component.tsx
index 277d56632950..75deee255982 100644
--- a/ui/pages/routes/routes.component.tsx
+++ b/ui/pages/routes/routes.component.tsx
@@ -2,23 +2,13 @@
/* eslint-disable import/no-useless-path-segments */
/* eslint-disable import/extensions */
import classnames from 'classnames';
-import React, { Suspense, useCallback, useEffect, useRef } from 'react';
+import React, { Suspense, useEffect, useMemo, useRef } from 'react';
import { useDispatch } from 'react-redux';
-import {
- Route,
- type RouteComponentProps,
- Switch,
- useHistory,
- useLocation,
-} from 'react-router-dom';
-import type { To } from 'react-router-dom-v5-compat';
+import { useRoutes, useLocation, useNavigationType } from 'react-router-dom';
import IdleTimer from 'react-idle-timer';
import type { ApprovalType } from '@metamask/controller-utils';
import { useAppSelector } from '../../store/store';
-import AuthenticatedV5Compat from '../../helpers/higher-order-components/authenticated/authenticated-v5-compat';
-import Initialized from '../../helpers/higher-order-components/initialized';
-import InitializedV5Compat from '../../helpers/higher-order-components/initialized/initialized-v5-compat';
import Loading from '../../components/ui/loading-screen';
import { Modal } from '../../components/app/modals';
import Alert from '../../components/ui/alert';
@@ -150,130 +140,11 @@ import { MultichainReviewPermissions } from '../../components/multichain-account
import { State2Wrapper } from '../../components/multichain-accounts/state2-wrapper/state2-wrapper';
import { RootLayout } from '../../layouts/root-layout';
import { LegacyLayout } from '../../layouts/legacy-layout';
-import { RouteWithLayout } from '../../layouts/route-with-layout';
+import { createRouteWithLayout } from '../../layouts/route-with-layout';
import { getConnectingLabel, setTheme } from './utils';
import { ConfirmationHandler } from './confirmation-handler';
import { Modals } from './modals';
-/**
- * V5-to-v5-compat navigation function that bridges react-router-dom v5 history
- * with v5-compat components expecting the newer navigate API.
- *
- * Supports two call signatures:
- * - Navigate to a route: `navigate(path, options)`
- * - Navigate in history: `navigate(delta)` (e.g., -1 to go back)
- *
- * @example
- * // Navigate to a new route
- * navigate('/settings', { replace: true });
- * @example
- * // Go back in history
- * navigate(-1);
- */
-type V5CompatNavigate = {
- (
- to: To,
- options?: { replace?: boolean; state?: Record },
- ): void;
- (delta: number): void;
-};
-
-/**
- * Creates a v5-compat navigate function from v5 history
- * Used to bridge v5 routes with components expecting v5-compat navigation
- *
- * @param history
- */
-const createV5CompatNavigate = (
- history: RouteComponentProps['history'],
-): V5CompatNavigate => {
- return (
- to: To | number,
- options?: { replace?: boolean; state?: Record },
- ) => {
- if (typeof to === 'number') {
- history.go(to);
- } else if (options?.replace) {
- history.replace(to as string, options.state);
- } else {
- history.push(to as string, options?.state);
- }
- };
-};
-
-/**
- * Helper to create v5-compat route wrappers with less boilerplate.
- * Handles authentication, navigation, and prop passing for v5-to-v5-compat transition.
- *
- * NOTE: This is temporary scaffolding for the v5-compat transition.
- * It will be removed during the full v6 migration when routes use native v6 patterns.
- *
- * @param Component - The component to render
- * @param options - Configuration options
- * @param options.wrapper - Wrapper component (AuthenticatedV5Compat, InitializedV5Compat, or null for none)
- * @param options.includeNavigate - Whether to pass navigate prop
- * @param options.includeLocation - Whether to pass location prop
- * @param options.includeParams - Whether to pass params from route match
- * @param options.includeMatch - Whether to pass the entire match object
- * @param options.paramsAsProps - Whether to spread params as individual props (default: true)
- * @returns Route render function
- */
-const createV5CompatRoute = <
- TParams extends Record = Record<
- string,
- string | undefined
- >,
->(
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- Component: React.ComponentType,
- options: {
- wrapper?: React.ComponentType<{ children: React.ReactNode }> | null;
- includeNavigate?: boolean;
- includeLocation?: boolean;
- includeParams?: boolean;
- includeMatch?: boolean;
- paramsAsProps?: boolean;
- } = {},
-) => {
- const {
- wrapper = null,
- includeNavigate = false,
- includeLocation = false,
- includeParams = false,
- includeMatch = false,
- paramsAsProps = true,
- } = options;
-
- return (props: RouteComponentProps) => {
- const { history: v5History, location: v5Location, match } = props;
-
- const componentProps: Record = {};
-
- if (includeNavigate) {
- componentProps.navigate = createV5CompatNavigate(v5History);
- }
- if (includeLocation) {
- componentProps.location = v5Location;
- }
- if (includeMatch) {
- componentProps.match = match;
- }
- if (includeParams) {
- if (paramsAsProps) {
- Object.assign(componentProps, match.params);
- } else {
- componentProps.params = match.params;
- }
- }
-
- const element = ;
-
- return wrapper
- ? React.createElement(wrapper, { children: element })
- : element;
- };
-};
-
// TODO: Fix `as unknown as` casting once `mmLazy` is updated to handle named exports, wrapped components, and other React module types.
// Casting is preferable over `@ts-expect-error` annotations in this case,
// because it doesn't suppress competing error messages e.g. "Cannot find module..."
@@ -451,29 +322,20 @@ const ShieldPlan = mmLazy(
);
// End Lazy Routes
-const MemoizedReviewPermissionsWrapper = React.memo(
- (props: {
- params?: { origin: string };
- navigate?: (
- to: string | number,
- options?: { replace?: boolean; state?: Record },
- ) => void;
- }) => (
- }
- state2Component={
- MultichainReviewPermissions as React.ComponentType
- }
- />
- ),
-);
+const MemoizedReviewPermissionsWrapper = React.memo(() => (
+ }
+ state2Component={
+ MultichainReviewPermissions as React.ComponentType
+ }
+ />
+));
// eslint-disable-next-line @typescript-eslint/naming-convention
-export default function Routes() {
+export default function RoutesComponent() {
const dispatch = useDispatch();
- const history = useHistory();
const location = useLocation();
+ const navType = useNavigationType();
const alertOpen = useAppSelector((state) => state.appState.alertOpen);
const alertMessage = useAppSelector((state) => state.appState.alertMessage);
@@ -610,17 +472,12 @@ export default function Routes() {
}
}, [showExtensionInFullSizeView]);
+ // Track location changes for metrics
useEffect(() => {
- const unlisten = history.listen((locationObj: Location, action: 'PUSH') => {
- if (action === 'PUSH') {
- dispatch(pageChanged(locationObj.pathname));
- }
- });
-
- return () => {
- unlisten();
- };
- }, [history, dispatch]);
+ if (navType === 'PUSH') {
+ dispatch(pageChanged(location.pathname));
+ }
+ }, [location.pathname, navType, dispatch]);
useEffect(() => {
setTheme(theme);
@@ -632,478 +489,303 @@ export default function Routes() {
}
}, [currentCurrency, dispatch]);
- const renderRoutes = useCallback(() => {
- const RestoreVaultComponent = forgottenPassword ? Route : Initialized;
+ // Define all routes using createRouteWithLayout
+ const routeConfig = useMemo(
+ () => [
+ createRouteWithLayout({
+ path: `${ONBOARDING_ROUTE}/*`,
+ component: OnboardingFlow,
+ layout: LegacyLayout,
+ }),
+ createRouteWithLayout({
+ path: LOCK_ROUTE,
+ component: Lock,
+ layout: LegacyLayout,
+ }),
+ createRouteWithLayout({
+ path: UNLOCK_ROUTE,
+ component: UnlockPage,
+ layout: LegacyLayout,
+ initialized: true,
+ }),
+ createRouteWithLayout({
+ path: DEEP_LINK_ROUTE,
+ component: DeepLink,
+ layout: LegacyLayout,
+ }),
+ createRouteWithLayout({
+ path: RESTORE_VAULT_ROUTE,
+ component: RestoreVaultPage,
+ layout: LegacyLayout,
+ initialized: !forgottenPassword,
+ }),
+ createRouteWithLayout({
+ path: SMART_ACCOUNT_UPDATE,
+ component: SmartAccountUpdate,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${REVEAL_SEED_ROUTE}/:keyringId?`,
+ component: RevealSeedConfirmation,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: IMPORT_SRP_ROUTE,
+ component: ImportSrpPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${SETTINGS_ROUTE}/*`,
+ component: Settings,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: NOTIFICATIONS_SETTINGS_ROUTE,
+ component: NotificationsSettings,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${NOTIFICATIONS_ROUTE}/:uuid`,
+ component: NotificationDetails,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: NOTIFICATIONS_ROUTE,
+ component: Notifications,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: SNAPS_ROUTE,
+ component: SnapList,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${SNAPS_VIEW_ROUTE}/*`,
+ component: SnapView,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${SEND_ROUTE}/:page?`,
+ component: SendPage,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${CONFIRM_TRANSACTION_ROUTE}/:id?/*`,
+ component: ConfirmTransaction,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${SWAPS_ROUTE}/*`,
+ component: Swaps,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${CROSS_CHAIN_SWAP_TX_DETAILS_ROUTE}/:srcTxMetaId`,
+ component: CrossChainSwapTxDetails,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${CROSS_CHAIN_SWAP_ROUTE}/*`,
+ component: CrossChainSwap,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE,
+ component: ConfirmAddSuggestedTokenPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: CONFIRM_ADD_SUGGESTED_NFT_ROUTE,
+ component: ConfirmAddSuggestedNftPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${CONFIRMATION_V_NEXT_ROUTE}/:id?`,
+ component: ConfirmationPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${NEW_ACCOUNT_ROUTE}/*`,
+ component: CreateAccountPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${CONNECT_ROUTE}/:id/*`,
+ component: PermissionsConnect,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${ASSET_ROUTE}/image/:asset/:id`,
+ component: NftFullImage,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${ASSET_ROUTE}/:chainId/:asset/:id`,
+ component: Asset,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${ASSET_ROUTE}/:chainId/:asset/`,
+ component: Asset,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${ASSET_ROUTE}/:chainId`,
+ component: Asset,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${DEFI_ROUTE}/:chainId/:protocolId`,
+ component: DeFiPage,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${CONNECTIONS}/:origin`,
+ component: Connections,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: PERMISSIONS,
+ component: PermissionsPage,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: GATOR_PERMISSIONS,
+ component: GatorPermissionsPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${TOKEN_TRANSFER_ROUTE}/:origin`,
+ component: TokenTransferPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: TOKEN_TRANSFER_ROUTE,
+ component: TokenTransferPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${REVIEW_GATOR_PERMISSIONS_ROUTE}/:chainId/:permissionGroupName/:origin`,
+ component: ReviewGatorPermissionsPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${REVIEW_GATOR_PERMISSIONS_ROUTE}/:chainId/:permissionGroupName`,
+ component: ReviewGatorPermissionsPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${REVIEW_PERMISSIONS}/:origin`,
+ component: MemoizedReviewPermissionsWrapper,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: ACCOUNT_LIST_PAGE_ROUTE,
+ component: AccountList,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${MULTICHAIN_ACCOUNT_ADDRESS_LIST_PAGE_ROUTE}/:accountGroupId`,
+ component: MultichainAccountAddressListPage,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${MULTICHAIN_ACCOUNT_PRIVATE_KEY_LIST_PAGE_ROUTE}/:accountGroupId`,
+ component: MultichainAccountPrivateKeyListPage,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: ADD_WALLET_PAGE_ROUTE,
+ component: AddWalletPage,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${MULTICHAIN_ACCOUNT_DETAILS_PAGE_ROUTE}/:id`,
+ component: MultichainAccountDetailsPage,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${MULTICHAIN_SMART_ACCOUNT_PAGE_ROUTE}/:address`,
+ component: SmartAccountPage,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: `${MULTICHAIN_WALLET_DETAILS_PAGE_ROUTE}/:id`,
+ component: WalletDetailsPage,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: NONEVM_BALANCE_CHECK_ROUTE,
+ component: NonEvmBalanceCheck,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: SHIELD_PLAN_ROUTE,
+ component: ShieldPlan,
+ layout: LegacyLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: REWARDS_ROUTE,
+ component: RewardsPage,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ createRouteWithLayout({
+ path: DEFAULT_ROUTE,
+ component: Home,
+ layout: RootLayout,
+ authenticated: true,
+ }),
+ ],
+ [forgottenPassword],
+ );
- const routes = (
-
- {/* since the loading time is less than 200ms, we decided not to show a spinner fallback or anything */}
-
-
-
-
- {createV5CompatRoute(UnlockPage, {
- wrapper: InitializedV5Compat,
- includeNavigate: true,
- includeLocation: true,
- })}
-
-
- {createV5CompatRoute(DeepLink, {
- includeLocation: true,
- })}
-
-
-
-
- {createV5CompatRoute<{ keyringId?: string }>(
- RevealSeedConfirmation,
- {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- includeParams: true,
- },
- )}
-
-
-
-
-
- {createV5CompatRoute<{ uuid: string }>(NotificationDetails, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- includeNavigate: true,
- paramsAsProps: false,
- })}
-
-
-
- {createV5CompatRoute(SnapList, {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- includeLocation: true,
- })}
-
-
- {createV5CompatRoute(SnapView, {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- includeLocation: true,
- includeParams: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{ page?: string }>(SendPage, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- includeNavigate: true,
- includeLocation: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{ id?: string }>(ConfirmTransaction, {
- wrapper: AuthenticatedV5Compat,
- includeLocation: true,
- includeParams: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute(Swaps, {
- wrapper: AuthenticatedV5Compat,
- includeLocation: true,
- })}
-
-
- {createV5CompatRoute<{ srcTxMetaId: string }>(
- CrossChainSwapTxDetails,
- {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- includeLocation: true,
- includeParams: true,
- paramsAsProps: false, // Pass as params object
- },
- )}
-
-
- {createV5CompatRoute(CrossChainSwap, {
- wrapper: AuthenticatedV5Compat,
- includeLocation: true,
- })}
-
-
- {createV5CompatRoute(ConfirmAddSuggestedTokenPage, {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- includeLocation: true,
- })}
-
-
- {createV5CompatRoute(ConfirmAddSuggestedNftPage, {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- includeLocation: true,
- })}
-
-
- {createV5CompatRoute<{ id?: string }>(ConfirmationPage, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- paramsAsProps: false,
- })}
-
-
-
- {createV5CompatRoute<{ id: string }>(PermissionsConnect, {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- includeLocation: true,
- includeMatch: true,
- })}
-
-
- {createV5CompatRoute<{ asset: string; id: string }>(NftFullImage, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{
- chainId: string;
- asset: string;
- id: string;
- }>(Asset, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{
- chainId: string;
- asset: string;
- }>(Asset, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{ chainId: string }>(Asset, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{
- chainId: string;
- protocolId: string;
- }>(DeFiPage, {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- includeParams: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{ origin: string }>(Connections, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- includeNavigate: true,
- paramsAsProps: false,
- })}
-
-
-
-
- {createV5CompatRoute(TokenTransferPage, {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{ origin: string }>(TokenTransferPage, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- includeNavigate: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{
- chainId: string;
- permissionGroupName: string;
- }>(ReviewGatorPermissionsPage, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- includeNavigate: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{
- chainId: string;
- permissionGroupName: string;
- origin: string;
- }>(ReviewGatorPermissionsPage, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- includeNavigate: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{ origin: string }>(
- MemoizedReviewPermissionsWrapper,
- {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- includeNavigate: true,
- paramsAsProps: false,
- },
- )}
-
-
- {createV5CompatRoute(AccountList, {
- wrapper: AuthenticatedV5Compat,
- })}
-
-
- {createV5CompatRoute<{ accountGroupId: string }>(
- MultichainAccountAddressListPage,
- {
- wrapper: AuthenticatedV5Compat,
- includeLocation: true,
- includeParams: true,
- paramsAsProps: false,
- },
- )}
-
-
- {createV5CompatRoute<{ accountGroupId: string }>(
- MultichainAccountPrivateKeyListPage,
- {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- paramsAsProps: false,
- },
- )}
-
-
- {createV5CompatRoute(AddWalletPage, {
- wrapper: AuthenticatedV5Compat,
- })}
-
-
- {createV5CompatRoute<{ id: string }>(MultichainAccountDetailsPage, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- paramsAsProps: true,
- })}
-
-
- {createV5CompatRoute<{ address: string }>(SmartAccountPage, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- paramsAsProps: false,
- })}
-
-
- {createV5CompatRoute<{ id: string }>(WalletDetailsPage, {
- wrapper: AuthenticatedV5Compat,
- includeParams: true,
- paramsAsProps: false,
- })}
-
-
-
-
- {createV5CompatRoute(RewardsPage, {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- includeLocation: true,
- })}
-
-
- {createV5CompatRoute(Home, {
- wrapper: AuthenticatedV5Compat,
- includeNavigate: true,
- includeLocation: true,
- })}
-
-
-
- );
+ // Use useRoutes hook to render routes - called on every render to track location changes
+ const routeElements = useRoutes(routeConfig);
+
+ const renderRoutes = () => {
+ const routes = {routeElements} ;
if (autoLockTimeLimit > 0) {
return (
@@ -1117,7 +799,7 @@ export default function Routes() {
}
return routes;
- }, [autoLockTimeLimit, forgottenPassword, dispatch]);
+ };
const t = useI18nContext();
@@ -1222,16 +904,8 @@ export default function Routes() {
{renderRoutes()}
- {isUnlocked ? (
-
- ) : null}
- {React.createElement(
- ToastMaster as React.ComponentType<{
- location: RouteComponentProps['location'];
- }>,
- { location },
- )}
-
+ {isUnlocked ? : null}
+
);
diff --git a/ui/pages/routes/utils.js b/ui/pages/routes/utils.js
index c2464cbc5982..7e07ed9c688d 100644
--- a/ui/pages/routes/utils.js
+++ b/ui/pages/routes/utils.js
@@ -1,4 +1,4 @@
-import { matchPath } from 'react-router-dom-v5-compat';
+import { matchPath } from 'react-router-dom';
// eslint-disable-next-line import/no-restricted-paths
import { getEnvironmentType } from '../../../app/scripts/lib/util';
import {
@@ -382,9 +382,9 @@ export function showAppHeader(props) {
}
/**
- * Creates a relative location object for use with nested react-router-dom-v5-compat Routes.
+ * Creates a relative location object for use with nested react-router-dom Routes.
*
- * When using v5-compat and components inside a parent route,
+ * When using and components inside a parent route,
* the child Routes need to match against paths relative to the parent route,
* not the full pathname. This function strips the base path prefix from the
* location to create a relative location. The resulting pathname is guaranteed
@@ -404,7 +404,7 @@ export function showAppHeader(props) {
* );
* // relativeLocation.pathname === '/snaps-connect'
* @example
- * // Usage with v5-compat Routes:
+ * // Usage with v6 Routes:
*
* } />
* } />
@@ -425,6 +425,23 @@ export function getRelativeLocationForNestedRoutes(location, basePath) {
};
}
+/**
+ * Converts an absolute route path to a relative path for use with nested Routes.
+ *
+ * When using nested `` components inside a parent route with `/*`,
+ * child routes need to use relative paths (without the parent's base path prefix).
+ * This function strips the base path and leading slash to create a truly relative path.
+ *
+ * @param {string} absolutePath - The full absolute path (e.g., '/onboarding/completion')
+ * @param {string} [basePath] - The base path to remove (e.g., '/onboarding'). Defaults to empty string.
+ * @returns {string} The relative path suitable for nested Route matching
+ * (e.g., 'completion' or '/' for the base route)
+ */
+export function toRelativeRoutePath(absolutePath, basePath = '') {
+ const relativePath = absolutePath.replace(basePath, '').replace(/^\//u, '');
+ return relativePath || '/';
+}
+
/**
* Extracts the transaction ID from a URL pathname.
*
diff --git a/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js b/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js
index d056d7b272e4..bd486600564e 100644
--- a/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js
+++ b/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js
@@ -1,6 +1,6 @@
import React, { useState, useContext } from 'react';
import PropTypes from 'prop-types';
-import { Navigate, useNavigate } from 'react-router-dom-v5-compat';
+import { Navigate, useNavigate } from 'react-router-dom';
import { AvatarAccountSize } from '@metamask/design-system-react';
import TextField from '../../../../components/ui/text-field';
import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer';
diff --git a/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.container.test.tsx b/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.container.test.tsx
index 65d77fbabf8a..266997f050e4 100644
--- a/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.container.test.tsx
+++ b/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.container.test.tsx
@@ -21,8 +21,8 @@ const mockUseParams = jest.fn();
const MOCK_ADDRESS = '0xc42edfcc21ed14dda456aa0756c153f7985d8813';
const MOCK_ADDRESS_NAME = 'Address Book Account 1';
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => mockUseLocation(),
useParams: () => mockUseParams(),
diff --git a/ui/pages/settings/contact-list-tab/view-contact/view-contact.component.js b/ui/pages/settings/contact-list-tab/view-contact/view-contact.component.js
index 4611c74a6818..c32f875dc978 100644
--- a/ui/pages/settings/contact-list-tab/view-contact/view-contact.component.js
+++ b/ui/pages/settings/contact-list-tab/view-contact/view-contact.component.js
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Navigate } from 'react-router-dom-v5-compat';
+import { Navigate } from 'react-router-dom';
import { AvatarAccountSize } from '@metamask/design-system-react';
import {
Button,
diff --git a/ui/pages/settings/contact-list-tab/view-contact/view-contact.container.test.tsx b/ui/pages/settings/contact-list-tab/view-contact/view-contact.container.test.tsx
index c261b7f823ca..f98ed1c42e0e 100644
--- a/ui/pages/settings/contact-list-tab/view-contact/view-contact.container.test.tsx
+++ b/ui/pages/settings/contact-list-tab/view-contact/view-contact.container.test.tsx
@@ -20,8 +20,8 @@ const mockUseParams = jest.fn();
const MOCK_ADDRESS = '0xc42edfcc21ed14dda456aa0756c153f7985d8813';
const MOCK_ADDRESS_NAME = 'Address Book Account 1';
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => mockUseLocation(),
useParams: () => mockUseParams(),
diff --git a/ui/pages/settings/developer-options-tab/backup-and-sync.test.tsx b/ui/pages/settings/developer-options-tab/backup-and-sync.test.tsx
index 6a5abbcc6f8b..4b05e6c62515 100644
--- a/ui/pages/settings/developer-options-tab/backup-and-sync.test.tsx
+++ b/ui/pages/settings/developer-options-tab/backup-and-sync.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import { useDeleteAccountSyncingDataFromUserStorage } from '../../../hooks/identity/useAccountSyncing';
-import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate';
import {
BackupAndSyncDevSettings,
useDeleteAccountSyncDataProps,
diff --git a/ui/pages/settings/developer-options-tab/developer-options-tab.tsx b/ui/pages/settings/developer-options-tab/developer-options-tab.tsx
index 9fa216f4cfcd..8b73e2193b9b 100644
--- a/ui/pages/settings/developer-options-tab/developer-options-tab.tsx
+++ b/ui/pages/settings/developer-options-tab/developer-options-tab.tsx
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
Box,
diff --git a/ui/pages/settings/experimental-tab/experimental-tab.test.js b/ui/pages/settings/experimental-tab/experimental-tab.test.js
index 9a9f474dcba4..1a528d6c318e 100644
--- a/ui/pages/settings/experimental-tab/experimental-tab.test.js
+++ b/ui/pages/settings/experimental-tab/experimental-tab.test.js
@@ -1,5 +1,6 @@
import React from 'react';
-import { fireEvent, renderWithProvider, waitFor } from '../../../../test/jest';
+import { fireEvent, waitFor } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
import { LegacyMetaMetricsProvider } from '../../../contexts/metametrics';
diff --git a/ui/pages/settings/networks-tab/networks-form/use-safe-chains.test.ts b/ui/pages/settings/networks-tab/networks-form/use-safe-chains.test.ts
index 0d8e9ba9c8ff..641dcac85c76 100644
--- a/ui/pages/settings/networks-tab/networks-form/use-safe-chains.test.ts
+++ b/ui/pages/settings/networks-tab/networks-form/use-safe-chains.test.ts
@@ -1,5 +1,5 @@
import * as FetchWithCacheModule from '../../../../../shared/lib/fetch-with-cache';
-import { renderHookWithProviderTyped } from '../../../../../test/lib/render-helpers';
+import { renderHookWithProviderTyped } from '../../../../../test/lib/render-helpers-navigate';
import {
rpcIdentifierUtility,
SafeChain,
diff --git a/ui/pages/settings/security-tab/change-password/change-password.test.tsx b/ui/pages/settings/security-tab/change-password/change-password.test.tsx
index 6f24b8c4e96b..21df67263465 100644
--- a/ui/pages/settings/security-tab/change-password/change-password.test.tsx
+++ b/ui/pages/settings/security-tab/change-password/change-password.test.tsx
@@ -24,8 +24,8 @@ jest.mock('react-redux', () => {
};
});
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
}));
diff --git a/ui/pages/settings/security-tab/change-password/change-password.tsx b/ui/pages/settings/security-tab/change-password/change-password.tsx
index d596c4de708d..9d5e1f06691b 100644
--- a/ui/pages/settings/security-tab/change-password/change-password.tsx
+++ b/ui/pages/settings/security-tab/change-password/change-password.tsx
@@ -1,7 +1,7 @@
import EventEmitter from 'events';
import React, { useContext, useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import {
Box,
Button,
diff --git a/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.test.tsx b/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.test.tsx
index 639b75359bfa..8c03b583507a 100644
--- a/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.test.tsx
+++ b/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.test.tsx
@@ -8,8 +8,8 @@ import { FirstTimeFlowType } from '../../../../../shared/constants/onboarding';
import { RevealSrpList } from './reveal-srp-list';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
}));
diff --git a/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.tsx b/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.tsx
index 4ce9efaa5327..d6de3a3ebbdb 100644
--- a/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.tsx
+++ b/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.tsx
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { AuthConnection } from '@metamask/seedless-onboarding-controller';
import { capitalize } from 'lodash';
diff --git a/ui/pages/settings/security-tab/security-tab.test.js b/ui/pages/settings/security-tab/security-tab.test.js
index 8c1833041478..1710100a0401 100644
--- a/ui/pages/settings/security-tab/security-tab.test.js
+++ b/ui/pages/settings/security-tab/security-tab.test.js
@@ -50,8 +50,8 @@ jest.mock('../../../ducks/app/app.ts', () => {
});
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => ({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => ({ pathname: '/settings/security' }),
useParams: () => ({}),
diff --git a/ui/pages/settings/settings.component.js b/ui/pages/settings/settings.component.js
index 2caa5b8d7e4e..c5ea8f106dd7 100644
--- a/ui/pages/settings/settings.component.js
+++ b/ui/pages/settings/settings.component.js
@@ -5,7 +5,7 @@ import {
Route,
matchPath,
Navigate,
-} from 'react-router-dom-v5-compat';
+} from 'react-router-dom';
import classnames from 'classnames';
import TabBar from '../../components/app/tab-bar';
@@ -33,7 +33,6 @@ import {
TRANSACTION_SHIELD_ROUTE,
TRANSACTION_SHIELD_CLAIM_ROUTES,
} from '../../helpers/constants/routes';
-
import { getSettingsRoutes } from '../../helpers/utils/settings-search';
import {
ButtonIcon,
@@ -63,6 +62,7 @@ import { SnapIcon } from '../../components/app/snaps/snap-icon';
import { SnapSettingsRenderer } from '../../components/app/snaps/snap-settings-page';
import PasswordOutdatedModal from '../../components/app/password-outdated-modal';
import ShieldEntryModal from '../../components/app/shield-entry-modal';
+import { toRelativeRoutePath } from '../routes/utils';
import SettingsTab from './settings-tab';
import AdvancedTab from './advanced-tab';
import InfoTab from './info-tab';
@@ -501,25 +501,36 @@ class SettingsPage extends PureComponent {
}
renderContent() {
+ // Use toRelativeRoutePath to convert absolute paths to relative paths
+ // for nested in React Router v6
return (
}
/>
- } />
}
+ />
+ }
/>
- } />
- } />
}
+ />
+ }
+ />
+
@@ -529,7 +540,7 @@ class SettingsPage extends PureComponent {
}
/>
this.props.toggleNetworkMenu()}
@@ -537,43 +548,61 @@ class SettingsPage extends PureComponent {
}
/>
this.props.toggleNetworkMenu()}
/>
}
/>
- } />
}
+ />
+ }
/>
}
/>
- } />
+ }
+ />
{(process.env.ENABLE_SETTINGS_PAGE_DEV_OPTIONS ||
process.env.IN_TEST) && (
}
/>
)}
- } />
- } />
}
+ />
+ }
+ />
+ }
/>
}
/>
- } />
}
+ />
+ }
/>
({
- ...jest.requireActual('react-router-dom-v5-compat'),
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
useLocation: () => ({ pathname: '/settings' }),
useNavigate: () => jest.fn(),
useParams: () => ({}),
diff --git a/ui/pages/settings/transaction-shield-tab/cancel-membership-modal.test.tsx b/ui/pages/settings/transaction-shield-tab/cancel-membership-modal.test.tsx
index 59a2be435ba6..56f0bd5f9896 100644
--- a/ui/pages/settings/transaction-shield-tab/cancel-membership-modal.test.tsx
+++ b/ui/pages/settings/transaction-shield-tab/cancel-membership-modal.test.tsx
@@ -5,7 +5,7 @@ import {
SUBSCRIPTION_STATUSES,
Subscription,
} from '@metamask/subscription-controller';
-import { renderWithProvider } from '../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import CancelMembershipModal from './cancel-membership-modal';
const mockSubscription: Subscription = {
diff --git a/ui/pages/settings/transaction-shield-tab/claims-area/claims-area.tsx b/ui/pages/settings/transaction-shield-tab/claims-area/claims-area.tsx
index a21eff81ec93..a3feadbc1698 100644
--- a/ui/pages/settings/transaction-shield-tab/claims-area/claims-area.tsx
+++ b/ui/pages/settings/transaction-shield-tab/claims-area/claims-area.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { Routes as RouterRoutes, Route } from 'react-router-dom-v5-compat';
+import { Routes as RouterRoutes, Route } from 'react-router-dom';
import { ClaimsProvider } from '../../../../contexts/claims/claims';
import ClaimsList from '../claims-list';
import ClaimsForm from '../claims-form';
diff --git a/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.test.tsx b/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.test.tsx
index bb6941e547f6..2aed14b8c43d 100644
--- a/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.test.tsx
+++ b/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.test.tsx
@@ -7,9 +7,9 @@ import mockState from '../../../../../test/data/mock-state.json';
import ClaimsForm from './claims-form';
const mockUseNavigate = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
};
});
diff --git a/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.tsx b/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.tsx
index 5b34cdf5cc8f..d99f00d09b67 100644
--- a/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.tsx
+++ b/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.tsx
@@ -20,7 +20,7 @@ import {
IconSize,
} from '@metamask/design-system-react';
import { useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import classnames from 'classnames';
import { useI18nContext } from '../../../../hooks/useI18nContext';
import { useClaims } from '../../../../contexts/claims/claims';
diff --git a/ui/pages/settings/transaction-shield-tab/claims-list/claims-list.tsx b/ui/pages/settings/transaction-shield-tab/claims-list/claims-list.tsx
index 77de9a65da95..e947e3fd10c9 100644
--- a/ui/pages/settings/transaction-shield-tab/claims-list/claims-list.tsx
+++ b/ui/pages/settings/transaction-shield-tab/claims-list/claims-list.tsx
@@ -11,7 +11,7 @@ import {
IconColor,
TextAlign,
} from '@metamask/design-system-react';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import { Claim, ClaimStatusEnum } from '@metamask/claims-controller';
import LoadingScreen from '../../../../components/ui/loading-screen';
import { Tag } from '../../../../components/component-library';
diff --git a/ui/pages/settings/transaction-shield-tab/transaction-shield.test.tsx b/ui/pages/settings/transaction-shield-tab/transaction-shield.test.tsx
index b659b3e62257..6332634a35e7 100644
--- a/ui/pages/settings/transaction-shield-tab/transaction-shield.test.tsx
+++ b/ui/pages/settings/transaction-shield-tab/transaction-shield.test.tsx
@@ -9,15 +9,15 @@ import {
Subscription,
SUBSCRIPTION_STATUSES,
} from '@metamask/subscription-controller';
-import { renderWithProvider } from '../../../../test/jest/rendering';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import mockState from '../../../../test/data/mock-state.json';
import TransactionShield from './transaction-shield';
const mockUseNavigate = jest.fn();
const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => mockUseLocation,
};
diff --git a/ui/pages/settings/transaction-shield-tab/transaction-shield.tsx b/ui/pages/settings/transaction-shield-tab/transaction-shield.tsx
index 98fdbf5311a0..2269fd85f9e2 100644
--- a/ui/pages/settings/transaction-shield-tab/transaction-shield.tsx
+++ b/ui/pages/settings/transaction-shield-tab/transaction-shield.tsx
@@ -6,7 +6,7 @@ import {
RECURRING_INTERVALS,
SUBSCRIPTION_STATUSES,
} from '@metamask/subscription-controller';
-import { useLocation, useNavigate } from 'react-router-dom-v5-compat';
+import { useLocation, useNavigate } from 'react-router-dom';
import {
BannerAlert,
BannerAlertSeverity,
diff --git a/ui/pages/shield-plan/shield-payment-modal.test.tsx b/ui/pages/shield-plan/shield-payment-modal.test.tsx
index 60bf9e3bb613..63b2bf8698d2 100644
--- a/ui/pages/shield-plan/shield-payment-modal.test.tsx
+++ b/ui/pages/shield-plan/shield-payment-modal.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import configureMockStore from 'redux-mock-store';
import { fireEvent } from '@testing-library/react';
import { PAYMENT_TYPES } from '@metamask/subscription-controller';
-import { renderWithProvider } from '../../../test/lib/render-helpers';
+import { renderWithProvider } from '../../../test/lib/render-helpers-navigate';
import mockState from '../../../test/data/mock-state.json';
import { AssetType } from '../../../shared/constants/transaction';
import { TokenWithApprovalAmount } from '../../hooks/subscription/useSubscriptionPricing';
diff --git a/ui/pages/shield-plan/shield-plan.test.tsx b/ui/pages/shield-plan/shield-plan.test.tsx
index b2447c8c590c..e2ff6cf187da 100644
--- a/ui/pages/shield-plan/shield-plan.test.tsx
+++ b/ui/pages/shield-plan/shield-plan.test.tsx
@@ -6,9 +6,9 @@ import ShieldPlan from './shield-plan';
const mockUseNavigate = jest.fn();
const mockUseLocation = jest.fn();
-jest.mock('react-router-dom-v5-compat', () => {
+jest.mock('react-router-dom', () => {
return {
- ...jest.requireActual('react-router-dom-v5-compat'),
+ ...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
useLocation: () => mockUseLocation(),
};
diff --git a/ui/pages/shield-plan/shield-plan.tsx b/ui/pages/shield-plan/shield-plan.tsx
index c7b658f1bb88..daec32ba1559 100644
--- a/ui/pages/shield-plan/shield-plan.tsx
+++ b/ui/pages/shield-plan/shield-plan.tsx
@@ -8,7 +8,7 @@ import {
RecurringInterval,
} from '@metamask/subscription-controller';
import { useDispatch, useSelector } from 'react-redux';
-import { useLocation, useNavigate } from 'react-router-dom-v5-compat';
+import { useLocation, useNavigate } from 'react-router-dom';
import { Checkbox, TextVariant } from '@metamask/design-system-react';
import { Hex } from '@metamask/utils';
import {
diff --git a/ui/pages/smart-transactions/smart-transaction-status-page/smart-transactions-status-page.test.tsx b/ui/pages/smart-transactions/smart-transaction-status-page/smart-transactions-status-page.test.tsx
index 55590a2a6986..59f50f1e323d 100644
--- a/ui/pages/smart-transactions/smart-transaction-status-page/smart-transactions-status-page.test.tsx
+++ b/ui/pages/smart-transactions/smart-transaction-status-page/smart-transactions-status-page.test.tsx
@@ -7,10 +7,8 @@ import {
} from '@metamask/smart-transactions-controller';
import { fireEvent } from '@testing-library/react';
-import {
- renderWithProvider,
- createSwapsMockStore,
-} from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
+import { createSwapsMockStore } from '../../../../test/jest';
import { CHAIN_IDS } from '../../../../shared/constants/network';
import {
SmartTransactionStatusPage,
diff --git a/ui/pages/snap-account-redirect/create-snap-redirect.test.tsx b/ui/pages/snap-account-redirect/create-snap-redirect.test.tsx
index f5b5f787fc42..3f53e5566213 100644
--- a/ui/pages/snap-account-redirect/create-snap-redirect.test.tsx
+++ b/ui/pages/snap-account-redirect/create-snap-redirect.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import configureStore from '../../store/store';
import mockState from '../../../test/data/mock-state.json';
-import { renderWithProvider } from '../../../test/jest';
+import { renderWithProvider } from '../../../test/lib/render-helpers-navigate';
import { TEST_SNAPS_SIMPLE_KEYRING_WEBSITE_URL } from '../../../test/e2e/constants';
import SnapAccountRedirect from './snap-account-redirect';
diff --git a/ui/pages/snaps/snap-view/snap-settings.js b/ui/pages/snaps/snap-view/snap-settings.js
index 81e39c41147c..6d6b48a1ab18 100644
--- a/ui/pages/snaps/snap-view/snap-settings.js
+++ b/ui/pages/snaps/snap-view/snap-settings.js
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import semver from 'semver';
import { isSnapId } from '@metamask/snaps-utils';
import { useI18nContext } from '../../../hooks/useI18nContext';
diff --git a/ui/pages/snaps/snap-view/snap-view.js b/ui/pages/snaps/snap-view/snap-view.js
index ebd4d8885c70..8e3096c0d941 100644
--- a/ui/pages/snaps/snap-view/snap-view.js
+++ b/ui/pages/snaps/snap-view/snap-view.js
@@ -1,8 +1,7 @@
import React, { useEffect, useState } from 'react';
-import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { hasProperty } from '@metamask/utils';
-import { useNavigate, useLocation } from 'react-router-dom-v5-compat';
+import { useNavigate, useLocation } from 'react-router-dom';
import {
AlignItems,
BackgroundColor,
@@ -22,13 +21,9 @@ import SnapHomeMenu from '../../../components/app/snaps/snap-home-menu';
import { SnapHomeRenderer } from '../../../components/app/snaps/snap-home-page/snap-home-renderer';
import SnapSettings from './snap-settings';
-function SnapView({ navigate: navigateProp, location: locationProp }) {
- const hookNavigate = useNavigate();
- const hookLocation = useLocation();
-
- // Use passed props if they exist, otherwise fall back to hooks
- const navigate = navigateProp ?? hookNavigate;
- const location = locationProp ?? hookLocation;
+function SnapView() {
+ const navigate = useNavigate();
+ const location = useLocation();
const { pathname } = location;
// The snap ID is in URI-encoded form in the last path segment of the URL.
@@ -138,9 +133,4 @@ function SnapView({ navigate: navigateProp, location: locationProp }) {
);
}
-SnapView.propTypes = {
- navigate: PropTypes.func,
- location: PropTypes.object,
-};
-
export default SnapView;
diff --git a/ui/pages/snaps/snap-view/snap-view.test.js b/ui/pages/snaps/snap-view/snap-view.test.js
index 9d7e9bfa88d6..43d652e0225f 100644
--- a/ui/pages/snaps/snap-view/snap-view.test.js
+++ b/ui/pages/snaps/snap-view/snap-view.test.js
@@ -20,8 +20,8 @@ jest.mock('../../../store/actions.ts', () => {
};
});
-jest.mock('react-router-dom-v5-compat', () => {
- const original = jest.requireActual('react-router-dom-v5-compat');
+jest.mock('react-router-dom', () => {
+ const original = jest.requireActual('react-router-dom');
return {
...original,
useLocation: jest.fn(() => ({
diff --git a/ui/pages/snaps/snaps-list/snap-list.js b/ui/pages/snaps/snaps-list/snap-list.js
index f9c010fa24b6..2fd15435b32d 100644
--- a/ui/pages/snaps/snaps-list/snap-list.js
+++ b/ui/pages/snaps/snaps-list/snap-list.js
@@ -1,7 +1,6 @@
import React, { useRef, useEffect } from 'react';
-import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import SnapListItem from '../../../components/app/snaps/snap-list-item';
import { useI18nContext } from '../../../hooks/useI18nContext';
import {
@@ -39,14 +38,10 @@ import {
} from '../../../components/multichain/pages/page';
import { getSnapRoute } from '../../../helpers/utils/util';
-const SnapList = ({ navigate: navigateProp }) => {
+const SnapList = () => {
const t = useI18nContext();
const settingsRef = useRef();
-
- const hookNavigate = useNavigate();
-
- // Use passed props if they exist, otherwise fall back to hooks
- const navigate = navigateProp ?? hookNavigate;
+ const navigate = useNavigate();
const onClick = (snap) => {
navigate(getSnapRoute(snap.id));
};
@@ -175,8 +170,4 @@ const SnapList = ({ navigate: navigateProp }) => {
);
};
-SnapList.propTypes = {
- navigate: PropTypes.func,
-};
-
export default SnapList;
diff --git a/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js b/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js
index 0de989898955..1eab3c29130f 100644
--- a/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js
+++ b/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js
@@ -1,6 +1,6 @@
import React, { useContext, useEffect } from 'react';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import isEqual from 'lodash/isEqual';
import { I18nContext } from '../../../contexts/i18n';
import {
diff --git a/ui/pages/swaps/awaiting-signatures/swap-step-icon.test.js b/ui/pages/swaps/awaiting-signatures/swap-step-icon.test.js
index 941bca984557..fda0149d7308 100644
--- a/ui/pages/swaps/awaiting-signatures/swap-step-icon.test.js
+++ b/ui/pages/swaps/awaiting-signatures/swap-step-icon.test.js
@@ -1,6 +1,6 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import SwapStepIcon from './swap-step-icon';
describe('SwapStepIcon', () => {
diff --git a/ui/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/pages/swaps/awaiting-swap/awaiting-swap.js
index 4da39eac1d6a..377f3de22a06 100644
--- a/ui/pages/swaps/awaiting-swap/awaiting-swap.js
+++ b/ui/pages/swaps/awaiting-swap/awaiting-swap.js
@@ -2,7 +2,7 @@ import EventEmitter from 'events';
import React, { useContext, useRef, useState, useEffect } from 'react';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import isEqual from 'lodash/isEqual';
import { getBlockExplorerLink } from '@metamask/etherscan-link';
import { I18nContext } from '../../../contexts/i18n';
diff --git a/ui/pages/swaps/awaiting-swap/quotes-timeout-icon.test.js b/ui/pages/swaps/awaiting-swap/quotes-timeout-icon.test.js
index 12f2adf45af9..4b287b5dbbab 100644
--- a/ui/pages/swaps/awaiting-swap/quotes-timeout-icon.test.js
+++ b/ui/pages/swaps/awaiting-swap/quotes-timeout-icon.test.js
@@ -1,6 +1,6 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import QuotesTimeoutIcon from './quotes-timeout-icon';
describe('QuotesTimeoutIcon', () => {
diff --git a/ui/pages/swaps/awaiting-swap/swap-failure-icon.test.js b/ui/pages/swaps/awaiting-swap/swap-failure-icon.test.js
index 02af2db06e0b..63cd0cab0c83 100644
--- a/ui/pages/swaps/awaiting-swap/swap-failure-icon.test.js
+++ b/ui/pages/swaps/awaiting-swap/swap-failure-icon.test.js
@@ -1,6 +1,6 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import SwapFailureIcon from './swap-failure-icon';
describe('SwapFailureIcon', () => {
diff --git a/ui/pages/swaps/awaiting-swap/swap-success-icon.test.js b/ui/pages/swaps/awaiting-swap/swap-success-icon.test.js
index 4e735f1580c1..abbd7a4cb70a 100644
--- a/ui/pages/swaps/awaiting-swap/swap-success-icon.test.js
+++ b/ui/pages/swaps/awaiting-swap/swap-success-icon.test.js
@@ -1,6 +1,6 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import SwapSuccessIcon from './swap-success-icon';
describe('SwapSuccessIcon', () => {
diff --git a/ui/pages/swaps/countdown-timer/countdown-timer.test.js b/ui/pages/swaps/countdown-timer/countdown-timer.test.js
index a6317785df90..5b8898c395d1 100644
--- a/ui/pages/swaps/countdown-timer/countdown-timer.test.js
+++ b/ui/pages/swaps/countdown-timer/countdown-timer.test.js
@@ -1,10 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
-
-import {
- renderWithProvider,
- createSwapsMockStore,
-} from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
+import { createSwapsMockStore } from '../../../../test/jest';
import CountdownTimer from '.';
const createProps = (customProps = {}) => {
diff --git a/ui/pages/swaps/countdown-timer/timer-icon.test.js b/ui/pages/swaps/countdown-timer/timer-icon.test.js
index e1cd9d628ad2..39c9df92daea 100644
--- a/ui/pages/swaps/countdown-timer/timer-icon.test.js
+++ b/ui/pages/swaps/countdown-timer/timer-icon.test.js
@@ -1,6 +1,6 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import TimerIcon from './timer-icon';
describe('TimerIcon', () => {
diff --git a/ui/pages/swaps/create-new-swap/create-new-swap.js b/ui/pages/swaps/create-new-swap/create-new-swap.js
index a3f32eac2ea4..04fe4d468367 100644
--- a/ui/pages/swaps/create-new-swap/create-new-swap.js
+++ b/ui/pages/swaps/create-new-swap/create-new-swap.js
@@ -1,7 +1,7 @@
import React, { useContext } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
-import { useNavigate } from 'react-router-dom-v5-compat';
+import { useNavigate } from 'react-router-dom';
import isEqual from 'lodash/isEqual';
import Box from '../../../components/ui/box';
import { I18nContext } from '../../../contexts/i18n';
diff --git a/ui/pages/swaps/exchange-rate-display/exchange-rate-display.test.js b/ui/pages/swaps/exchange-rate-display/exchange-rate-display.test.js
index a4433da6a8ae..a51f71978d77 100644
--- a/ui/pages/swaps/exchange-rate-display/exchange-rate-display.test.js
+++ b/ui/pages/swaps/exchange-rate-display/exchange-rate-display.test.js
@@ -1,6 +1,6 @@
import React from 'react';
-
-import { renderWithProvider, fireEvent } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
+import { fireEvent } from '../../../../test/jest';
import ExchangeRateDisplay from '.';
const createProps = (customProps = {}) => {
diff --git a/ui/pages/swaps/fee-card/fee-card.test.js b/ui/pages/swaps/fee-card/fee-card.test.js
index 234dd5bf215b..4fde6a15d606 100644
--- a/ui/pages/swaps/fee-card/fee-card.test.js
+++ b/ui/pages/swaps/fee-card/fee-card.test.js
@@ -2,7 +2,8 @@ import React from 'react';
import { useSelector } from 'react-redux';
import { setBackgroundConnection } from '../../../store/background-connection';
-import { renderWithProvider, MOCKS, fireEvent } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
+import { MOCKS, fireEvent } from '../../../../test/jest';
import {
checkNetworkAndAccountSupports1559,
diff --git a/ui/pages/swaps/fee-card/pig-icon.test.js b/ui/pages/swaps/fee-card/pig-icon.test.js
index 6321b7dc64e4..a7ba18f61be0 100644
--- a/ui/pages/swaps/fee-card/pig-icon.test.js
+++ b/ui/pages/swaps/fee-card/pig-icon.test.js
@@ -1,6 +1,6 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import PigIcon from './pig-icon';
describe('PigIcon', () => {
diff --git a/ui/pages/swaps/import-token/import-token.test.js b/ui/pages/swaps/import-token/import-token.test.js
index ee3d74ff4685..77380b79f60c 100644
--- a/ui/pages/swaps/import-token/import-token.test.js
+++ b/ui/pages/swaps/import-token/import-token.test.js
@@ -1,6 +1,6 @@
import React from 'react';
-import { renderWithProvider } from '../../../../test/jest';
+import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate';
import ImportToken from '.';
const createProps = (customProps = {}) => {
diff --git a/ui/pages/swaps/index.js b/ui/pages/swaps/index.js
index 71ee429aea6c..a16bae2514a9 100644
--- a/ui/pages/swaps/index.js
+++ b/ui/pages/swaps/index.js
@@ -5,13 +5,17 @@ import React, {
useState,
useCallback,
} from 'react';
-import PropTypes from 'prop-types';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
-import { Routes, Route, Navigate } from 'react-router-dom-v5-compat';
+import {
+ Routes,
+ Route,
+ Navigate,
+ useNavigate,
+ useLocation,
+} from 'react-router-dom';
import { isEqual } from 'lodash';
import { TransactionStatus } from '@metamask/transaction-controller';
import { I18nContext } from '../../contexts/i18n';
-import { useSafeNavigation } from '../../hooks/useSafeNavigation';
import {
getSelectedAccount,
@@ -19,7 +23,8 @@ import {
isHardwareWallet,
getHardwareWalletType,
getHDEntropyIndex,
-} from '../../selectors/selectors';
+ getCurrentNetworkTransactions,
+} from '../../selectors';
import {
getCurrentChainId,
getSelectedNetworkClientId,
@@ -43,7 +48,6 @@ import {
setTransactionSettingsOpened,
getLatestAddedTokenTo,
} from '../../ducks/swaps/swaps';
-import { getCurrentNetworkTransactions } from '../../selectors';
import {
getSmartTransactionsEnabled,
getSmartTransactionsOptInStatusForMetrics,
@@ -60,6 +64,7 @@ import {
SWAPS_NOTIFICATION_ROUTE,
CROSS_CHAIN_SWAP_ROUTE,
} from '../../helpers/constants/routes';
+import { toRelativeRoutePath } from '../routes/utils';
import {
ERROR_FETCHING_QUOTES,
QUOTES_NOT_AVAILABLE_ERROR,
@@ -98,10 +103,10 @@ import AwaitingSwap from './awaiting-swap';
import LoadingQuote from './loading-swaps-quotes';
import NotificationPage from './notification-page/notification-page';
-export default function Swap({ location: propsLocation }) {
+export default function Swap() {
const t = useContext(I18nContext);
- const { navigate, location: hookLocation } = useSafeNavigation();
- const location = propsLocation || hookLocation;
+ const navigate = useNavigate();
+ const location = useLocation();
const dispatch = useDispatch();
const trackEvent = useContext(MetaMetricsContext);
const hdEntropyIndex = useSelector(getHDEntropyIndex);
@@ -406,9 +411,10 @@ export default function Swap({ location: propsLocation }) {