diff --git a/app/components/Base/DetailsModal.js b/app/components/Base/DetailsModal.js index da1b0096359..92b17d86e89 100644 --- a/app/components/Base/DetailsModal.js +++ b/app/components/Base/DetailsModal.js @@ -5,7 +5,7 @@ import Ionicons from 'react-native-vector-icons/Ionicons'; import { fontStyles } from '../../styles/common'; import Text from './Text'; import { useTheme } from '../../util/theme'; -import { TransactionDetailsModalSelectorsIDs } from '../../../e2e/selectors/Modals/TransactionDetailsModal.selectors'; +import { TransactionDetailsModalSelectorsIDs } from '../../../e2e/selectors/Transactions/TransactionDetailsModal.selectors'; const createStyles = (colors) => StyleSheet.create({ diff --git a/app/components/Base/RemoteImage/index.js b/app/components/Base/RemoteImage/index.js index 12e7d1721b6..5c62258dc27 100644 --- a/app/components/Base/RemoteImage/index.js +++ b/app/components/Base/RemoteImage/index.js @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { Image, @@ -67,23 +67,36 @@ const RemoteImage = (props) => { const chainId = useSelector(selectChainId); const ticker = useSelector(selectTicker); const networkName = useSelector(selectNetworkName); - const resolvedIpfsUrl = useMemo(() => { - try { - const url = new URL(props.source.uri); - if (url.protocol !== 'ipfs:') return false; - const ipfsUrl = getFormattedIpfsUrl(ipfsGateway, props.source.uri, false); - return ipfsUrl; - } catch { - return false; - } - }, [props.source.uri, ipfsGateway]); + const [resolvedIpfsUrl, setResolvedIpfsUrl] = useState(false); - const uri = resolvedIpfsUrl || source.uri; + const uri = + resolvedIpfsUrl || + (source.uri === undefined || source.uri?.startsWith('ipfs') + ? '' + : source.uri); const onError = ({ nativeEvent: { error } }) => setError(error); const [dimensions, setDimensions] = useState(null); + useEffect(() => { + resolveIpfsUrl(); + async function resolveIpfsUrl() { + try { + const url = new URL(props.source.uri); + if (url.protocol !== 'ipfs:') setResolvedIpfsUrl(false); + const ipfsUrl = await getFormattedIpfsUrl( + ipfsGateway, + props.source.uri, + false, + ); + setResolvedIpfsUrl(ipfsUrl); + } catch (err) { + setResolvedIpfsUrl(false); + } + } + }, [props.source.uri, ipfsGateway]); + useEffect(() => { const calculateImageDimensions = (imageWidth, imageHeight) => { const deviceWidth = Dimensions.get('window').width; diff --git a/app/components/Base/RemoteImage/index.test.tsx b/app/components/Base/RemoteImage/index.test.tsx index 65691852ebe..4ea9f0beaa0 100644 --- a/app/components/Base/RemoteImage/index.test.tsx +++ b/app/components/Base/RemoteImage/index.test.tsx @@ -1,6 +1,8 @@ import React from 'react'; import { shallow } from 'enzyme'; import RemoteImage from './'; +import { getFormattedIpfsUrl } from '@metamask/assets-controllers'; +import { act, render } from '@testing-library/react-native'; jest.mock('react-redux', () => ({ ...jest.requireActual('react-redux'), @@ -11,6 +13,12 @@ jest.mock('react-redux', () => ({ jest.mock('../../../components/hooks/useIpfsGateway', () => jest.fn()); +jest.mock('@metamask/assets-controllers', () => ({ + getFormattedIpfsUrl: jest.fn(), +})); + +const mockGetFormattedIpfsUrl = getFormattedIpfsUrl as jest.Mock; + describe('RemoteImage', () => { it('should render svg correctly', () => { const wrapper = shallow( @@ -34,14 +42,18 @@ describe('RemoteImage', () => { expect(wrapper).toMatchSnapshot(); }); - it('should render ipfs sources', () => { - const wrapper = shallow( + it('should render ipfs sources', async () => { + const testIpfsUri = 'ipfs://QmeE94srcYV9WwJb1p42eM4zncdLUai2N9zmMxxukoEQ23'; + mockGetFormattedIpfsUrl.mockResolvedValue(testIpfsUri); + const wrapper = render( , ); + // eslint-disable-next-line no-empty-function + await act(async () => {}); expect(wrapper).toMatchSnapshot(); }); }); diff --git a/app/components/UI/Navbar/index.js b/app/components/UI/Navbar/index.js index 07f352786e0..1e31cfc43d2 100644 --- a/app/components/UI/Navbar/index.js +++ b/app/components/UI/Navbar/index.js @@ -28,7 +28,6 @@ import PickerNetwork from '../../../component-library/components/Pickers/PickerN import BrowserUrlBar from '../BrowserUrlBar'; import generateTestId from '../../../../wdio/utils/generateTestId'; import { NAV_ANDROID_BACK_BUTTON } from '../../../../wdio/screen-objects/testIDs/Screens/NetworksScreen.testids'; -import { REQUEST_SEARCH_RESULTS_BACK_BUTTON } from '../../../../wdio/screen-objects/testIDs/Screens/RequestToken.testIds'; import { BACK_BUTTON_SIMPLE_WEBVIEW } from '../../../../wdio/screen-objects/testIDs/Components/SimpleWebView.testIds'; import Routes from '../../../constants/navigation/Routes'; @@ -43,7 +42,7 @@ import { import { CommonSelectorsIDs } from '../../../../e2e/selectors/Common.selectors'; import { WalletViewSelectorsIDs } from '../../../../e2e/selectors/wallet/WalletView.selectors'; import { NetworksViewSelectorsIDs } from '../../../../e2e/selectors/Settings/NetworksView.selectors'; -import { SendLinkViewSelectorsIDs } from '../../../../e2e/selectors/SendLinkView.selectors'; +import { SendLinkViewSelectorsIDs } from '../../../../e2e/selectors/Receive/SendLinkView.selectors'; import { SendViewSelectorsIDs } from '../../../../e2e/selectors/SendView.selectors'; import { getBlockaidTransactionMetricsParams } from '../../../util/blockaid'; import Icon, { @@ -52,6 +51,7 @@ import Icon, { IconColor, } from '../../../component-library/components/Icons/Icon'; import { AddContactViewSelectorsIDs } from '../../../../e2e/selectors/Settings/Contacts/AddContactView.selectors'; +import { RequestPaymentViewSelectors } from '../../../../e2e/selectors/Receive/RequestPaymentView.selectors'; const trackEvent = (event, params = {}) => { MetaMetrics.getInstance().trackEvent(event, params); @@ -360,7 +360,7 @@ export function getPaymentRequestOptionsTitle( diff --git a/app/components/UI/PaymentRequestSuccess/index.js b/app/components/UI/PaymentRequestSuccess/index.js index 1310dd135d8..08a3925ab65 100644 --- a/app/components/UI/PaymentRequestSuccess/index.js +++ b/app/components/UI/PaymentRequestSuccess/index.js @@ -30,7 +30,7 @@ import { protectWalletModalVisible } from '../../../actions/user'; import ClipboardManager from '../../../core/ClipboardManager'; import { ThemeContext, mockTheme } from '../../../util/theme'; import generateTestId from '../../../../wdio/utils/generateTestId'; -import { SendLinkViewSelectorsIDs } from '../../../../e2e/selectors/SendLinkView.selectors'; +import { SendLinkViewSelectorsIDs } from '../../../../e2e/selectors/Receive/SendLinkView.selectors'; const isIos = Device.isIos(); diff --git a/app/components/UI/Ramp/Views/BuildQuote/__snapshots__/BuildQuote.test.tsx.snap b/app/components/UI/Ramp/Views/BuildQuote/__snapshots__/BuildQuote.test.tsx.snap index d8474b6cb32..c8fc6d56cfe 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/__snapshots__/BuildQuote.test.tsx.snap +++ b/app/components/UI/Ramp/Views/BuildQuote/__snapshots__/BuildQuote.test.tsx.snap @@ -8717,7 +8717,7 @@ exports[`BuildQuote View renders correctly 1`] = ` onLoadEnd={[Function]} source={ { - "uri": undefined, + "uri": "", } } style={ @@ -11839,7 +11839,7 @@ exports[`BuildQuote View renders correctly 2`] = ` onLoadEnd={[Function]} source={ { - "uri": undefined, + "uri": "", } } style={ diff --git a/app/components/UI/ReceiveRequest/index.js b/app/components/UI/ReceiveRequest/index.js index adeb81bc78c..8cdbcb0f5cb 100644 --- a/app/components/UI/ReceiveRequest/index.js +++ b/app/components/UI/ReceiveRequest/index.js @@ -28,7 +28,7 @@ import { isNetworkRampSupported } from '../Ramp/utils'; import { createBuyNavigationDetails } from '../Ramp/routes/utils'; import { selectSelectedInternalAccountChecksummedAddress } from '../../../selectors/accountsController'; import { getRampNetworks } from '../../../reducers/fiatOrders'; -import { RequestPaymentModalSelectorsIDs } from '../../../../e2e/selectors/Modals/RequestPaymentModal.selectors'; +import { RequestPaymentModalSelectorsIDs } from '../../../../e2e/selectors/Receive/RequestPaymentModal.selectors'; import { withMetricsAwareness } from '../../../components/hooks/useMetrics'; import { getDecimalChainId } from '../../../util/networks'; import QRAccountDisplay from '../../Views/QRAccountDisplay'; diff --git a/app/components/UI/Stake/Views/StakeConfirmationView/__snapshots__/StakeConfirmationView.test.tsx.snap b/app/components/UI/Stake/Views/StakeConfirmationView/__snapshots__/StakeConfirmationView.test.tsx.snap index ab1c216fd7a..32849f83ce2 100644 --- a/app/components/UI/Stake/Views/StakeConfirmationView/__snapshots__/StakeConfirmationView.test.tsx.snap +++ b/app/components/UI/Stake/Views/StakeConfirmationView/__snapshots__/StakeConfirmationView.test.tsx.snap @@ -45,7 +45,7 @@ exports[`StakeConfirmationView render matches snapshot 1`] = ` onLoadEnd={[Function]} source={ { - "uri": undefined, + "uri": "", } } style={ diff --git a/app/components/UI/Stake/Views/UnstakeConfirmationView/__snapshots__/UnstakeConfirmationView.test.tsx.snap b/app/components/UI/Stake/Views/UnstakeConfirmationView/__snapshots__/UnstakeConfirmationView.test.tsx.snap index 2b82484bc70..8bcfb049259 100644 --- a/app/components/UI/Stake/Views/UnstakeConfirmationView/__snapshots__/UnstakeConfirmationView.test.tsx.snap +++ b/app/components/UI/Stake/Views/UnstakeConfirmationView/__snapshots__/UnstakeConfirmationView.test.tsx.snap @@ -45,7 +45,7 @@ exports[`UnstakeConfirmationView render matches snapshot 1`] = ` onLoadEnd={[Function]} source={ { - "uri": undefined, + "uri": "", } } style={ diff --git a/app/components/UI/Stake/components/StakingBalance/__snapshots__/StakingBalance.test.tsx.snap b/app/components/UI/Stake/components/StakingBalance/__snapshots__/StakingBalance.test.tsx.snap index 53039c1fdf3..efb6cfa67f9 100644 --- a/app/components/UI/Stake/components/StakingBalance/__snapshots__/StakingBalance.test.tsx.snap +++ b/app/components/UI/Stake/components/StakingBalance/__snapshots__/StakingBalance.test.tsx.snap @@ -36,7 +36,7 @@ exports[`StakingBalance render matches snapshot 1`] = ` onLoadEnd={[Function]} source={ { - "uri": undefined, + "uri": "", } } style={ diff --git a/app/components/UI/Stake/components/StakingConfirmation/TokenValueStack/__snapshots__/TokenValueStack.test.tsx.snap b/app/components/UI/Stake/components/StakingConfirmation/TokenValueStack/__snapshots__/TokenValueStack.test.tsx.snap index 32f3cf0ccfc..70902df7688 100644 --- a/app/components/UI/Stake/components/StakingConfirmation/TokenValueStack/__snapshots__/TokenValueStack.test.tsx.snap +++ b/app/components/UI/Stake/components/StakingConfirmation/TokenValueStack/__snapshots__/TokenValueStack.test.tsx.snap @@ -33,7 +33,7 @@ exports[`TokenValueStack render matches snapshot 1`] = ` onLoadEnd={[Function]} source={ { - "uri": undefined, + "uri": "", } } style={ diff --git a/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap b/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap index e9e7f0f4b15..4968a992595 100644 --- a/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap +++ b/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap @@ -549,7 +549,7 @@ exports[`Tokens should hide zero balance tokens when setting is on 1`] = ` onLoadEnd={[Function]} source={ { - "uri": undefined, + "uri": "", } } style={ @@ -1795,7 +1795,7 @@ exports[`Tokens should render correctly 1`] = ` onLoadEnd={[Function]} source={ { - "uri": undefined, + "uri": "", } } style={ @@ -3059,7 +3059,7 @@ exports[`Tokens should show all balance tokens when hideZeroBalanceTokens settin onLoadEnd={[Function]} source={ { - "uri": undefined, + "uri": "", } } style={ diff --git a/app/components/Views/Notifications/Details/Badge/__snapshots__/index.test.tsx.snap b/app/components/Views/Notifications/Details/Badge/__snapshots__/index.test.tsx.snap index 053e08832c7..efdc00300ff 100644 --- a/app/components/Views/Notifications/Details/Badge/__snapshots__/index.test.tsx.snap +++ b/app/components/Views/Notifications/Details/Badge/__snapshots__/index.test.tsx.snap @@ -21,7 +21,7 @@ exports[`NotificationBadge should renders correctly 1`] = ` onLoadEnd={[Function]} source={ { - "uri": undefined, + "uri": "", } } style={ diff --git a/app/components/Views/confirmations/components/WatchAssetRequest/index.js b/app/components/Views/confirmations/components/WatchAssetRequest/index.js index a48374b1511..8598bd3adfa 100644 --- a/app/components/Views/confirmations/components/WatchAssetRequest/index.js +++ b/app/components/Views/confirmations/components/WatchAssetRequest/index.js @@ -18,7 +18,7 @@ import { selectChainId } from '../../../../../selectors/networkController'; import ApproveTransactionHeader from '../ApproveTransactionHeader'; import { getActiveTabUrl } from '../../../../../util/transactions'; import { isEqual } from 'lodash'; -import { AssetWatcherSelectorsIDs } from '../../../../../../e2e/selectors/Modals/AssetWatcher.selectors'; +import { AssetWatcherSelectorsIDs } from '../../../../../../e2e/selectors/Transactions/AssetWatcher.selectors'; import { getDecimalChainId } from '../../../../../util/networks'; import { useMetrics } from '../../../../../components/hooks/useMetrics'; diff --git a/app/core/Engine.test.ts b/app/core/Engine.test.ts index 835365d6fbb..8c05d1a7979 100644 --- a/app/core/Engine.test.ts +++ b/app/core/Engine.test.ts @@ -71,7 +71,13 @@ describe('Engine', () => { const engine = Engine.init({}); const initialBackgroundState = engine.datamodel.state; - expect(initialBackgroundState).toStrictEqual(backgroundState); + // AssetsContractController is stateless in v37 resulting in an undefined state + const newBackgroundState = { + ...backgroundState, + AssetsContractController: undefined, + }; + + expect(initialBackgroundState).toStrictEqual(newBackgroundState); }); it('setSelectedAccount throws an error if no account exists for the given address', () => { diff --git a/app/core/Engine.ts b/app/core/Engine.ts index e017203eaaf..3d72ab1a406 100644 --- a/app/core/Engine.ts +++ b/app/core/Engine.ts @@ -28,6 +28,13 @@ import { TokenListControllerActions, TokenListControllerEvents, TokenBalancesControllerState, + AssetsContractControllerGetERC20BalanceOfAction, + AssetsContractControllerGetERC721AssetNameAction, + AssetsContractControllerGetERC721AssetSymbolAction, + AssetsContractControllerGetERC721TokenURIAction, + AssetsContractControllerGetERC721OwnerOfAction, + AssetsContractControllerGetERC1155BalanceOfAction, + AssetsContractControllerGetERC1155TokenURIAction, } from '@metamask/assets-controllers'; ///: BEGIN:ONLY_INCLUDE_IF(preinstalled-snaps,external-snaps) import { AppState } from 'react-native'; @@ -308,7 +315,14 @@ type GlobalActions = | TokensControllerActions | TokenListControllerActions | SelectedNetworkControllerActions - | SmartTransactionsControllerActions; + | SmartTransactionsControllerActions + | AssetsContractControllerGetERC20BalanceOfAction + | AssetsContractControllerGetERC721AssetNameAction + | AssetsContractControllerGetERC721AssetSymbolAction + | AssetsContractControllerGetERC721TokenURIAction + | AssetsContractControllerGetERC721OwnerOfAction + | AssetsContractControllerGetERC1155BalanceOfAction + | AssetsContractControllerGetERC1155TokenURIAction; type GlobalEvents = | AddressBookControllerEvents @@ -502,19 +516,6 @@ export class Engine { ) { this.controllerMessenger = new ExtendedControllerMessenger(); - /** - * Subscribes a listener to the state change events of Preferences Controller. - * - * @param listener - The callback function to execute when the state changes. - */ - const onPreferencesStateChange = ( - listener: (preferencesState: PreferencesState) => void, - ) => { - const eventName = `PreferencesController:stateChange`; - - this.controllerMessenger.subscribe(eventName, listener); - }; - const approvalController = new ApprovalController({ messenger: this.controllerMessenger.getRestricted({ name: 'ApprovalController', @@ -569,18 +570,23 @@ export class Engine { networkController.initializeProvider(); const assetsContractController = new AssetsContractController({ - onPreferencesStateChange, - onNetworkDidChange: (listener) => - this.controllerMessenger.subscribe( - AppConstants.NETWORK_DID_CHANGE_EVENT, - // @ts-expect-error TODO: Resolve bump the assets controller version. - listener, - ), + // @ts-expect-error TODO: Resolve mismatch between base-controller versions. + messenger: this.controllerMessenger.getRestricted({ + name: 'AssetsContractController', + allowedActions: [ + 'NetworkController:getNetworkClientById', + 'NetworkController:getNetworkConfigurationByNetworkClientId', + 'NetworkController:getSelectedNetworkClient', + 'NetworkController:getState', + ], + allowedEvents: [ + 'PreferencesController:stateChange', + 'NetworkController:networkDidChange', + ], + }), chainId: networkController.getNetworkClientById( networkController?.state.selectedNetworkClientId, ).configuration.chainId, - getNetworkClientById: - networkController.getNetworkClientById.bind(networkController), }); const accountsControllerMessenger: AccountsControllerMessenger = this.controllerMessenger.getRestricted({ @@ -622,6 +628,12 @@ export class Engine { `${networkController.name}:getNetworkClientById`, 'AccountsController:getAccount', 'AccountsController:getSelectedAccount', + 'AssetsContractController:getERC721AssetName', + 'AssetsContractController:getERC721AssetSymbol', + 'AssetsContractController:getERC721TokenURI', + 'AssetsContractController:getERC721OwnerOf', + 'AssetsContractController:getERC1155BalanceOf', + 'AssetsContractController:getERC1155TokenURI', ], allowedEvents: [ 'PreferencesController:stateChange', @@ -629,25 +641,6 @@ export class Engine { 'AccountsController:selectedEvmAccountChange', ], }), - - getERC721AssetName: assetsContractController.getERC721AssetName.bind( - assetsContractController, - ), - getERC721AssetSymbol: assetsContractController.getERC721AssetSymbol.bind( - assetsContractController, - ), - getERC721TokenURI: assetsContractController.getERC721TokenURI.bind( - assetsContractController, - ), - getERC721OwnerOf: assetsContractController.getERC721OwnerOf.bind( - assetsContractController, - ), - getERC1155BalanceOf: assetsContractController.getERC1155BalanceOf.bind( - assetsContractController, - ), - getERC1155TokenURI: assetsContractController.getERC1155TokenURI.bind( - assetsContractController, - ), }); const loggingController = new LoggingController({ @@ -1508,13 +1501,18 @@ export class Engine { // @ts-expect-error TODO: Resolve mismatch between base-controller versions. messenger: this.controllerMessenger.getRestricted({ name: 'TokenBalancesController', - allowedActions: ['AccountsController:getSelectedAccount'], + allowedActions: [ + 'AccountsController:getSelectedAccount', + 'AssetsContractController:getERC20BalanceOf', + ], allowedEvents: ['TokensController:stateChange'], }), - getERC20BalanceOf: assetsContractController.getERC20BalanceOf.bind( - assetsContractController, - ), interval: 180000, + tokens: [ + ...tokensController.state.tokens, + ...tokensController.state.detectedTokens, + ], + state: initialState.TokenBalancesController, }), new TokenRatesController({ // @ts-expect-error TODO: Resolve mismatch between base-controller versions. @@ -1857,12 +1855,8 @@ export class Engine { } configureControllersOnNetworkChange() { - const { - AccountTrackerController, - AssetsContractController, - NetworkController, - SwapsController, - } = this.context; + const { AccountTrackerController, NetworkController, SwapsController } = + this.context; const { provider } = NetworkController.getProviderAndBlockTracker(); // Skip configuration if this is called before the provider is initialized @@ -1870,7 +1864,6 @@ export class Engine { return; } provider.sendAsync = provider.sendAsync.bind(provider); - AssetsContractController.configure({ provider }); SwapsController.configure({ provider, diff --git a/app/core/EngineService/EngineService.ts b/app/core/EngineService/EngineService.ts index 010a251c822..74a063fa767 100644 --- a/app/core/EngineService/EngineService.ts +++ b/app/core/EngineService/EngineService.ts @@ -53,7 +53,6 @@ class EngineService { name: 'AddressBookController', key: `${engine.context.AddressBookController.name}:stateChange`, }, - { name: 'AssetsContractController' }, { name: 'NftController', key: 'NftController:stateChange' }, { name: 'TokensController', diff --git a/app/images/ape-network.png b/app/images/ape-network.png new file mode 100644 index 00000000000..c2985568768 Binary files /dev/null and b/app/images/ape-network.png differ diff --git a/app/images/ape-token.png b/app/images/ape-token.png new file mode 100644 index 00000000000..d23724fd1d8 Binary files /dev/null and b/app/images/ape-token.png differ diff --git a/app/images/image-icons.js b/app/images/image-icons.js index 217ed6a8231..3aae4764051 100644 --- a/app/images/image-icons.js +++ b/app/images/image-icons.js @@ -11,6 +11,7 @@ import AVAX from './avalanche.png'; import LINEA_TESTNET from './linea-testnet-logo.png'; import SEPOLIA from './sepolia-logo-dark.png'; import LINEA_MAINNET from './linea-mainnet-logo.png'; +import APE_TOKEN from './ape-token.png'; import GRAVITY from './gravity.png'; export default { @@ -28,5 +29,6 @@ export default { 'LINEA-SEPOLIA': LINEA_TESTNET, SEPOLIA, 'LINEA-MAINNET': LINEA_MAINNET, + APE: APE_TOKEN, G: GRAVITY, }; diff --git a/app/util/networks/customNetworks.tsx b/app/util/networks/customNetworks.tsx index c100faa089c..fe301ceae68 100644 --- a/app/util/networks/customNetworks.tsx +++ b/app/util/networks/customNetworks.tsx @@ -133,5 +133,7 @@ export const UnpopularNetworkList = [ export const CustomNetworkImgMapping: Record<`0x${string}`, string> = { '0xe': require('../../images/flare-mainnet.png'), // Flare Mainnet '0x13': require('../../images/songbird.png'), // Songbird Testnet + '0x8157': require('../../images/ape-network.png'), // ApeChain testnet + '0x8173': require('../../images/ape-network.png'), // ApeChain mainnet '0x659': require('../../images/gravity.png'), // Gravity Alpha Mainnet }; diff --git a/e2e/api-mocking/mock-config/mock-events.js b/e2e/api-mocking/mock-config/mock-events.js new file mode 100644 index 00000000000..acfd95a6fdf --- /dev/null +++ b/e2e/api-mocking/mock-config/mock-events.js @@ -0,0 +1,57 @@ +/** + * Mock events for gas fee API responses. + */ + +import { + suggestedGasApiResponses, + suggestedGasFeesApiGanache, +} from '../mock-responses/gas-api-responses.json'; + +export const mockEvents = { + /** + * Mock GET request events. + */ + GET: { + /** + * Mainnet gas fees endpoint with a mock 500 error response. + * @property {string} urlEndpoint - API endpoint for mainnet gas fees. + * @property {Object} response - Error response data. + */ + suggestedGasFeesMainNetError: { + urlEndpoint: 'https://gas.api.cx.metamask.io/networks/1/suggestedGasFees', + response: suggestedGasApiResponses.error, + responseCode: 500, + }, + + /** + * Ganache gas fees endpoint with a mock 200 success response. + * @property {string} urlEndpoint - API endpoint for Ganache gas fees. + * @property {Object} response - Success response data. + */ + suggestedGasFeesApiGanache: { + urlEndpoint: 'https://gas.api.cx.metamask.io/networks/1337/suggestedGasFees', + response: suggestedGasFeesApiGanache, + responseCode: 200, + }, + }, + + /** + * Mock POST request events. + */ + POST: { + /** + * Mainnet gas fees endpoint with a mock success response for POST requests. + * @property {string} urlEndpoint - API endpoint for mainnet gas fees. + * @property {Object} response - Success response data. + * @property {Object} requestBody - Expected fields for the POST request body. + */ + suggestedGasApiPostResponse: { + urlEndpoint: 'https://gas.api.cx.metamask.io/networks/1/suggestedGasFees', + response: suggestedGasApiResponses.success, + requestBody: { + priorityFee: '2', + maxFee: '2.000855333', + }, + }, + }, +}; diff --git a/e2e/api-mocking/mock-config/mockUrlCollection.json b/e2e/api-mocking/mock-config/mockUrlCollection.json new file mode 100644 index 00000000000..f88f8914c1c --- /dev/null +++ b/e2e/api-mocking/mock-config/mockUrlCollection.json @@ -0,0 +1,3 @@ +{ + "defaultMockPort": 8000 +} diff --git a/e2e/api-mocking/mock-responses/gas-api-responses.json b/e2e/api-mocking/mock-responses/gas-api-responses.json new file mode 100644 index 00000000000..079d5d18335 --- /dev/null +++ b/e2e/api-mocking/mock-responses/gas-api-responses.json @@ -0,0 +1,36 @@ +{ + "suggestedGasApiResponses": { + "error": { + "message": "Internal Server Error" + } + }, + + "suggestedGasFeesApiGanache": { + "low": { + "suggestedMaxPriorityFeePerGas": "1", + "suggestedMaxFeePerGas": "1.000503137", + "minWaitTimeEstimate": 15000, + "maxWaitTimeEstimate": 60000 + }, + "medium": { + "suggestedMaxPriorityFeePerGas": "1.5", + "suggestedMaxFeePerGas": "1.500679235", + "minWaitTimeEstimate": 15000, + "maxWaitTimeEstimate": 45000 + }, + "high": { + "suggestedMaxPriorityFeePerGas": "2", + "suggestedMaxFeePerGas": "2.000855333", + "minWaitTimeEstimate": 15000, + "maxWaitTimeEstimate": 30000 + }, + "estimatedBaseFee": "0.000503137", + "networkCongestion": 0.34, + "latestPriorityFeeRange": ["1.5", "2"], + "historicalPriorityFeeRange": ["0.000001", "236.428872442"], + "historicalBaseFeeRange": ["0.000392779", "0.00100495"], + "priorityFeeTrend": "up", + "baseFeeTrend": "up", + "version": "0.0.1" + } +} diff --git a/e2e/api-mocking/mock-server.js b/e2e/api-mocking/mock-server.js new file mode 100644 index 00000000000..45fd1273820 --- /dev/null +++ b/e2e/api-mocking/mock-server.js @@ -0,0 +1,81 @@ +/* eslint-disable no-console */ +import { getLocal } from 'mockttp'; +import portfinder from 'portfinder'; + +const mockServer = getLocal(); + +/** + * Starts the mock server and sets up mock events. + * + * @param {Object} events - The events to mock, organised by method. + * @param {number} [port] - Optional port number. If not provided, a free port will be used. + * @returns {Promise} Resolves to the running mock server. + */ +export const startMockServer = async (events, port) => { + port = port || (await portfinder.getPortPromise()); + + await mockServer.start(port); + console.log(`Mockttp server running at http://localhost:${port}`); + + await mockServer + .forGet('/health-check') + .thenReply(200, 'Mock server is running'); + + for (const method in events) { + const methodEvents = events[method]; + + console.log(`Setting up mock events for ${method} requests...`); + + for (const { + urlEndpoint, + response, + requestBody, + responseCode, + } of methodEvents) { + console.log(`Mocking ${method} request to: ${urlEndpoint}`); + console.log(`Response status: ${responseCode}`); + console.log('Response:', response); + if (requestBody) { + console.log(`POST request body ${requestBody}`); + } + + if (method === 'GET') { + await mockServer + .forGet('/proxy') + .withQuery({ url: urlEndpoint }) + .thenReply(responseCode, JSON.stringify(response)); + } + + if (method === 'POST') { + await mockServer + .forPost('/proxy') + .withQuery({ url: urlEndpoint }) + .withJsonBody(requestBody || {}) + .thenReply(responseCode, JSON.stringify(response)); + } + } + } + + await mockServer.forUnmatchedRequest().thenPassThrough({ + beforeRequest: async ({ url, method }) => { + const returnUrl = new URL(url).searchParams.get('url') || url; + const updatedUrl = + device.getPlatform() === 'android' + ? returnUrl.replace('localhost', '127.0.0.1') + : returnUrl; + console.log(`Mock proxy forwarding request to: ${updatedUrl}`); + return { url: updatedUrl }; + }, + }); + + return mockServer; +}; + +/** + * Stops the mock server. + * + */ +export const stopMockServer = async () => { + await mockServer.stop(); + console.log('Mock server shutting down'); +}; diff --git a/e2e/api-specs/ConfirmationsRejectionRule.js b/e2e/api-specs/ConfirmationsRejectionRule.js index 0c8ccdf687c..5ce7225f915 100644 --- a/e2e/api-specs/ConfirmationsRejectionRule.js +++ b/e2e/api-specs/ConfirmationsRejectionRule.js @@ -5,7 +5,7 @@ import TestHelpers from '../helpers'; import Matchers from '../utils/Matchers'; import Gestures from '../utils/Gestures'; import ConnectBottomSheet from '../pages/Browser/ConnectBottomSheet'; -import AssetWatchModal from '../pages/modals/AssetWatchModal'; +import AssetWatchBottomSheet from '../pages/Transactions/AssetWatchBottomSheet'; import SpamFilterModal from '../pages/Browser/SpamFilterModal'; // eslint-disable-next-line import/no-nodejs-modules @@ -147,7 +147,7 @@ export default class ConfirmationsRejectRule { let cancelButton; await TestHelpers.delay(3000); if (this.allCapsCancel.includes(call.methodName)) { - await AssetWatchModal.tapCancelButton(); + await AssetWatchBottomSheet.tapCancelButton(); } else { cancelButton = await Matchers.getElementByText('Cancel'); await Gestures.waitAndTap(cancelButton); diff --git a/e2e/fixtures/utils.js b/e2e/fixtures/utils.js index d617b8f783d..8686101cb29 100644 --- a/e2e/fixtures/utils.js +++ b/e2e/fixtures/utils.js @@ -1,7 +1,8 @@ import { DEFAULT_GANACHE_PORT } from '../../app/util/test/ganache'; import { DEFAULT_FIXTURE_SERVER_PORT } from './fixture-server'; import { DEFAULT_DAPP_SERVER_PORT } from './fixture-helper'; -import { defaultMockPort } from './../mockServer/mockUrlCollection'; +import { DEFAULT_MOCKSERVER_PORT } from '../api-mocking/mock-server'; + function transformToValidPort(defaultPort, pid) { // Improve uniqueness by using a simple transformation @@ -30,6 +31,6 @@ export function getLocalTestDappPort() { return getServerPort(DEFAULT_DAPP_SERVER_PORT); } -export function getMockttpPort() { - return getServerPort(defaultMockPort); +export function getMockServerPort() { + return getServerPort(DEFAULT_MOCKSERVER_PORT); } diff --git a/e2e/helpers.js b/e2e/helpers.js index c3ae3dc864e..89c665fdec9 100644 --- a/e2e/helpers.js +++ b/e2e/helpers.js @@ -3,7 +3,6 @@ import { getFixturesServerPort, getGanachePort, getLocalTestDappPort, - getMockttpPort, } from './fixtures/utils'; import Utilities from './utils/Utilities'; @@ -277,7 +276,6 @@ export default class TestHelpers { await device.reverseTcpPort(getGanachePort()); await device.reverseTcpPort(getFixturesServerPort()); await device.reverseTcpPort(getLocalTestDappPort()); - await device.reverseTcpPort(getMockttpPort()); } } } diff --git a/e2e/mockServer/data/suggestedGasApiGanacheResponseBody.json b/e2e/mockServer/data/suggestedGasApiGanacheResponseBody.json deleted file mode 100644 index 19b76fe6200..00000000000 --- a/e2e/mockServer/data/suggestedGasApiGanacheResponseBody.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "low": { - "suggestedMaxPriorityFeePerGas": "1", - "suggestedMaxFeePerGas": "1.000503137", - "minWaitTimeEstimate": 15000, - "maxWaitTimeEstimate": 60000 - }, - "medium": { - "suggestedMaxPriorityFeePerGas": "1.5", - "suggestedMaxFeePerGas": "1.500679235", - "minWaitTimeEstimate": 15000, - "maxWaitTimeEstimate": 45000 - }, - "high": { - "suggestedMaxPriorityFeePerGas": "2", - "suggestedMaxFeePerGas": "2.000855333", - "minWaitTimeEstimate": 15000, - "maxWaitTimeEstimate": 30000 - }, - "estimatedBaseFee": "0.000503137", - "networkCongestion": 0.34, - "latestPriorityFeeRange": [ - "1.5", - "2" - ], - "historicalPriorityFeeRange": [ - "0.000001", - "236.428872442" - ], - "historicalBaseFeeRange": [ - "0.000392779", - "0.00100495" - ], - "priorityFeeTrend": "up", - "baseFeeTrend": "up", - "version": "0.0.1" -} diff --git a/e2e/mockServer/mockServer.js b/e2e/mockServer/mockServer.js deleted file mode 100644 index 73c89d97ac8..00000000000 --- a/e2e/mockServer/mockServer.js +++ /dev/null @@ -1,45 +0,0 @@ -/* eslint-disable no-console */ -import { getLocal } from 'mockttp'; -import { defaultMockPort } from './mockUrlCollection'; -import portfinder from 'portfinder'; - -const mockServer = getLocal(); - -export const startMockServer = async ({ - mockUrl, - responseCode = 500, - responseBody = {}, - port = defaultMockPort, -}) => { - if (!mockUrl) throw new Error('The mockUrl parameter is required'); - await portfinder.setBasePort(port); - const mockPort = await portfinder.getPortPromise(); - await mockServer.start(mockPort); - console.log(`Mockttp server running at http://localhost:${mockPort}`); - - await mockServer - .forGet('/health-check') - .thenReply(200, 'Mock server is running'); - - await mockServer - .forGet('/proxy') - .withQuery({ url: mockUrl }) - .thenReply(responseCode, JSON.stringify(responseBody)); - - await mockServer.forUnmatchedRequest().thenPassThrough({ - beforeRequest: async ({ url, method }) => { - const returnUrl = new URL(url).searchParams.get('url') || url; - const updatedUrl = device.getPlatform() === 'android' ? returnUrl.replace('localhost', '127.0.0.1') : returnUrl; - - console.log(`Mock proxy forwarding request to: ${updatedUrl}`); - return { url: updatedUrl }; - }, - }); - - return mockServer; -}; - -export const stopMockServer = async () => { - await mockServer.stop(); - console.log('Mockttp server shutting down'); -}; diff --git a/e2e/mockServer/mockUrlCollection.json b/e2e/mockServer/mockUrlCollection.json deleted file mode 100644 index 44726689158..00000000000 --- a/e2e/mockServer/mockUrlCollection.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "localhost": "localhost", - "defaultMockPort": 8000, - "urls": { - "suggestedGasApiMainnet": "https://gas.api.cx.metamask.io/networks/1/suggestedGasFees", - "suggestedGasApiGanache": "https://gas.api.cx.metamask.io/networks/1337/suggestedGasFees" - } -} diff --git a/e2e/pages/Receive/PaymentRequestQrModal.js b/e2e/pages/Receive/PaymentRequestQrBottomSheet.js similarity index 68% rename from e2e/pages/Receive/PaymentRequestQrModal.js rename to e2e/pages/Receive/PaymentRequestQrBottomSheet.js index 580c35ef172..674dba57dcd 100644 --- a/e2e/pages/Receive/PaymentRequestQrModal.js +++ b/e2e/pages/Receive/PaymentRequestQrBottomSheet.js @@ -1,8 +1,8 @@ import Matchers from '../../utils/Matchers'; import Gestures from '../../utils/Gestures'; -import { SendLinkViewSelectorsIDs } from '../../selectors/SendLinkView.selectors'; +import { SendLinkViewSelectorsIDs } from '../../selectors/Receive/SendLinkView.selectors'; -class PaymentRequestQrModal { +class PaymentRequestQrBottomSheet { get container() { return Matchers.getElementByID(SendLinkViewSelectorsIDs.QR_MODAL); } @@ -16,4 +16,4 @@ class PaymentRequestQrModal { } } -export default new PaymentRequestQrModal(); +export default new PaymentRequestQrBottomSheet(); diff --git a/e2e/pages/Receive/RequestPaymentModal.js b/e2e/pages/Receive/RequestPaymentModal.js index 450415b9340..0a01e14148e 100644 --- a/e2e/pages/Receive/RequestPaymentModal.js +++ b/e2e/pages/Receive/RequestPaymentModal.js @@ -1,4 +1,4 @@ -import { RequestPaymentModalSelectorsIDs } from '../../selectors/Modals/RequestPaymentModal.selectors'; +import { RequestPaymentModalSelectorsIDs } from '../../selectors/Receive/RequestPaymentModal.selectors'; import Matchers from '../../utils/Matchers'; import Gestures from '../../utils/Gestures'; @@ -6,7 +6,7 @@ class RequestPaymentModal { get requestPaymentButton() { return device.getPlatform() === 'android' ? Matchers.getElementByLabel( - RequestPaymentModalSelectorsIDs.REQUEST_BUTTON, + RequestPaymentModalSelectorsIDs.REQUEST_BUTTON, ) : Matchers.getElementByID(RequestPaymentModalSelectorsIDs.REQUEST_BUTTON); } diff --git a/e2e/pages/RequestPaymentView.js b/e2e/pages/Receive/RequestPaymentView.js similarity index 86% rename from e2e/pages/RequestPaymentView.js rename to e2e/pages/Receive/RequestPaymentView.js index 2dc413ac75f..22669d405d0 100644 --- a/e2e/pages/RequestPaymentView.js +++ b/e2e/pages/Receive/RequestPaymentView.js @@ -1,6 +1,6 @@ -import { RequestPaymentViewSelectors } from '../selectors/RequestPaymentView.selectors'; -import Matchers from '../utils/Matchers'; -import Gestures from '../utils/Gestures'; +import { RequestPaymentViewSelectors } from '../../selectors/Receive/RequestPaymentView.selectors'; +import Matchers from '../../utils/Matchers'; +import Gestures from '../../utils/Gestures'; class RequestPaymentView { get backButton() { diff --git a/e2e/pages/Receive/SendLinkView.js b/e2e/pages/Receive/SendLinkView.js index 73663c6bbbb..a89e479d218 100644 --- a/e2e/pages/Receive/SendLinkView.js +++ b/e2e/pages/Receive/SendLinkView.js @@ -1,6 +1,6 @@ import Matchers from '../../utils/Matchers'; import Gestures from '../../utils/Gestures'; -import { SendLinkViewSelectorsIDs } from '../../selectors/SendLinkView.selectors'; +import { SendLinkViewSelectorsIDs } from '../../selectors/Receive/SendLinkView.selectors'; class SendLinkView { get container() { diff --git a/e2e/pages/ActivitiesView.js b/e2e/pages/Transactions/ActivitiesView.js similarity index 73% rename from e2e/pages/ActivitiesView.js rename to e2e/pages/Transactions/ActivitiesView.js index 389331fc2fd..1b88464414c 100644 --- a/e2e/pages/ActivitiesView.js +++ b/e2e/pages/Transactions/ActivitiesView.js @@ -1,16 +1,12 @@ -import { ActivitiesViewSelectorsText } from '../selectors/ActivitiesView.selectors'; -import Matchers from '../utils/Matchers'; -import Gestures from '../utils/Gestures'; +import { ActivitiesViewSelectorsText } from '../../selectors/Transactions/ActivitiesView.selectors'; +import Matchers from '../../utils/Matchers'; +import Gestures from '../../utils/Gestures'; class ActivitiesView { get title() { return Matchers.getElementByText(ActivitiesViewSelectorsText.TITLE); } - get confirmedLabel() { - return Matchers.getElementByText(ActivitiesViewSelectorsText.CONFIRM_TEXT); - } - generateSwapActivityLabel(sourceToken, destinationToken) { let title = ActivitiesViewSelectorsText.SWAP; title = title.replace('{{sourceToken}}', sourceToken); diff --git a/e2e/pages/Transactions/AssetWatchBottomSheet.js b/e2e/pages/Transactions/AssetWatchBottomSheet.js new file mode 100644 index 00000000000..5179e2c4f30 --- /dev/null +++ b/e2e/pages/Transactions/AssetWatchBottomSheet.js @@ -0,0 +1,15 @@ +import { AssetWatcherSelectorsIDs } from '../../selectors/Transactions/AssetWatcher.selectors'; +import Matchers from '../../utils/Matchers'; +import Gestures from '../../utils/Gestures'; + +class AssetWatchBottomSheet { + get cancelButton() { + return Matchers.getElementByID(AssetWatcherSelectorsIDs.CANCEL_BUTTON); + } + + async tapCancelButton() { + await Gestures.waitAndTap(this.cancelButton); + } +} + +export default new AssetWatchBottomSheet(); diff --git a/e2e/pages/modals/DetailsModal.js b/e2e/pages/Transactions/TransactionDetailsModal.js similarity index 87% rename from e2e/pages/modals/DetailsModal.js rename to e2e/pages/Transactions/TransactionDetailsModal.js index cceeed5459d..26d3bcf033c 100644 --- a/e2e/pages/modals/DetailsModal.js +++ b/e2e/pages/Transactions/TransactionDetailsModal.js @@ -1,12 +1,12 @@ import { TransactionDetailsModalSelectorsText, TransactionDetailsModalSelectorsIDs, -} from '../../selectors/Modals/TransactionDetailsModal.selectors'; +} from '../../selectors/Transactions/TransactionDetailsModal.selectors'; import Matchers from '../../utils/Matchers'; import Gestures from '../../utils/Gestures'; import { CommonSelectorsIDs } from '../../selectors/Common.selectors'; -class DetailsModal { +class TransactionDetailsModal { get title() { return Matchers.getElementByID(TransactionDetailsModalSelectorsIDs.TITLE); } @@ -40,4 +40,4 @@ class DetailsModal { } } -export default new DetailsModal(); +export default new TransactionDetailsModal(); diff --git a/e2e/pages/modals/TransactionProtectionModal.js b/e2e/pages/Transactions/TransactionProtectionModal.js similarity index 90% rename from e2e/pages/modals/TransactionProtectionModal.js rename to e2e/pages/Transactions/TransactionProtectionModal.js index 0af997f56ab..250ac4239b8 100644 --- a/e2e/pages/modals/TransactionProtectionModal.js +++ b/e2e/pages/Transactions/TransactionProtectionModal.js @@ -1,4 +1,4 @@ -import { TransactionProtectionModalSelectorText } from '../../selectors/Modals/TransactionProtectionModal.selectors'; +import { TransactionProtectionModalSelectorText } from '../../selectors/Transactions/TransactionProtectionModal.selectors'; import Matchers from '../../utils/Matchers'; import Gestures from '../../utils/Gestures'; diff --git a/e2e/pages/modals/AssetWatchModal.js b/e2e/pages/modals/AssetWatchModal.js deleted file mode 100644 index 4f6ba7521cb..00000000000 --- a/e2e/pages/modals/AssetWatchModal.js +++ /dev/null @@ -1,21 +0,0 @@ -import { AssetWatcherSelectorsIDs } from '../../selectors/Modals/AssetWatcher.selectors'; -import Matchers from '../../utils/Matchers'; -import Gestures from '../../utils/Gestures'; - -class NetworkAddedModal { - get cancelButton() { - return Matchers.getElementByID(AssetWatcherSelectorsIDs.CANCEL_BUTTON); - } - get confirmButton() { - return Matchers.getElementByID(AssetWatcherSelectorsIDs.CONFIRM_BUTTON); - } - - async tapCancelButton() { - await Gestures.waitAndTap(this.cancelButton); - } - async tapConfirmButton() { - await Gestures.waitAndTap(this.confirmButton); - } -} - -export default new NetworkAddedModal(); diff --git a/e2e/selectors/Modals/RequestPaymentModal.selectors.js b/e2e/selectors/Modals/RequestPaymentModal.selectors.js deleted file mode 100644 index 7f40a1b70ec..00000000000 --- a/e2e/selectors/Modals/RequestPaymentModal.selectors.js +++ /dev/null @@ -1,6 +0,0 @@ -export const RequestPaymentModalSelectorsIDs = { - CONTAINER: 'receive-request-screen', - REQUEST_BUTTON: 'request-payment-button', - QR_MODAL: 'qr-modal', - ACCOUNT_ADDRESS: 'account-address', -}; diff --git a/e2e/selectors/Receive/RequestPaymentModal.selectors.js b/e2e/selectors/Receive/RequestPaymentModal.selectors.js new file mode 100644 index 00000000000..340e77a8073 --- /dev/null +++ b/e2e/selectors/Receive/RequestPaymentModal.selectors.js @@ -0,0 +1,3 @@ +export const RequestPaymentModalSelectorsIDs = { + REQUEST_BUTTON: 'request-payment-button', +}; diff --git a/e2e/selectors/RequestPaymentView.selectors.js b/e2e/selectors/Receive/RequestPaymentView.selectors.js similarity index 84% rename from e2e/selectors/RequestPaymentView.selectors.js rename to e2e/selectors/Receive/RequestPaymentView.selectors.js index 731e5d56b8f..5d0e8c56a1e 100644 --- a/e2e/selectors/RequestPaymentView.selectors.js +++ b/e2e/selectors/Receive/RequestPaymentView.selectors.js @@ -4,5 +4,4 @@ export const RequestPaymentViewSelectors = { REQUEST_ASSET_LIST_ID: 'searched-asset-results', REQUEST_AMOUNT_INPUT_BOX_ID: 'request-amount-input', TOKEN_SEARCH_INPUT_BOX: 'request-search-asset-input', - PAYMENT_REQUEST_CLOSE_BUTTON: 'send-link-close-button', }; diff --git a/e2e/selectors/SendLinkView.selectors.js b/e2e/selectors/Receive/SendLinkView.selectors.js similarity index 100% rename from e2e/selectors/SendLinkView.selectors.js rename to e2e/selectors/Receive/SendLinkView.selectors.js diff --git a/e2e/selectors/ActivitiesView.selectors.js b/e2e/selectors/Transactions/ActivitiesView.selectors.js similarity index 90% rename from e2e/selectors/ActivitiesView.selectors.js rename to e2e/selectors/Transactions/ActivitiesView.selectors.js index d120cd36f6a..3f352595387 100644 --- a/e2e/selectors/ActivitiesView.selectors.js +++ b/e2e/selectors/Transactions/ActivitiesView.selectors.js @@ -1,4 +1,4 @@ -import enContent from '../../locales/languages/en.json'; +import enContent from '../../../locales/languages/en.json'; function getSentUnitMessage(unit) { return enContent.transactions.sent_unit.replace('{{unit}}', unit); diff --git a/e2e/selectors/Modals/AssetWatcher.selectors.js b/e2e/selectors/Transactions/AssetWatcher.selectors.js similarity index 100% rename from e2e/selectors/Modals/AssetWatcher.selectors.js rename to e2e/selectors/Transactions/AssetWatcher.selectors.js diff --git a/e2e/selectors/Modals/TransactionDetailsModal.selectors.js b/e2e/selectors/Transactions/TransactionDetailsModal.selectors.js similarity index 87% rename from e2e/selectors/Modals/TransactionDetailsModal.selectors.js rename to e2e/selectors/Transactions/TransactionDetailsModal.selectors.js index c6c65f6abcc..026c2458128 100644 --- a/e2e/selectors/Modals/TransactionDetailsModal.selectors.js +++ b/e2e/selectors/Transactions/TransactionDetailsModal.selectors.js @@ -2,7 +2,6 @@ import enContent from '../../../locales/languages/en.json'; export const TransactionDetailsModalSelectorsText = { TITLE: enContent.swaps.transaction_label.swap, - CONFIRMED: enContent.transaction.confirmed, }; export const TransactionDetailsModalSelectorsIDs = { diff --git a/e2e/selectors/Modals/TransactionProtectionModal.selectors.js b/e2e/selectors/Transactions/TransactionProtectionModal.selectors.js similarity index 100% rename from e2e/selectors/Modals/TransactionProtectionModal.selectors.js rename to e2e/selectors/Transactions/TransactionProtectionModal.selectors.js diff --git a/e2e/specs/confirmations/advanced-gas-fees.spec.js b/e2e/specs/confirmations/advanced-gas-fees.mock.spec.js similarity index 91% rename from e2e/specs/confirmations/advanced-gas-fees.spec.js rename to e2e/specs/confirmations/advanced-gas-fees.mock.spec.js index 0771e671e65..619db01c707 100644 --- a/e2e/specs/confirmations/advanced-gas-fees.spec.js +++ b/e2e/specs/confirmations/advanced-gas-fees.mock.spec.js @@ -17,9 +17,8 @@ import Assertions from '../../utils/Assertions'; import { startMockServer, stopMockServer -} from '../../mockServer/mockServer'; -import { urls } from '../../mockServer/mockUrlCollection.json'; -import responseBody from '../../mockServer/data/suggestedGasApiGanacheResponseBody.json'; +} from '../../api-mocking/mock-server'; +import { mockEvents } from '../../api-mocking/mock-config/mock-events'; const VALID_ADDRESS = '0xebe6CcB6B55e1d094d9c58980Bc10Fed69932cAb'; @@ -28,11 +27,10 @@ describe(SmokeConfirmations('Advanced Gas Fees and Priority Tests'), () => { beforeAll(async () => { jest.setTimeout(170000); await TestHelpers.reverseServerPort(); - - mockServer = await startMockServer({ // Configure mock server - mockUrl: urls.suggestedGasApiGanache, - responseCode: 200, - responseBody + mockServer = await startMockServer({ + GET: [ + mockEvents.GET.suggestedGasFeesApiGanache + ], }); }); diff --git a/e2e/specs/confirmations/approve-custom-erc20.spec.js b/e2e/specs/confirmations/approve-custom-erc20.spec.js index 1f7d3f5a4cb..8f6392280c7 100644 --- a/e2e/specs/confirmations/approve-custom-erc20.spec.js +++ b/e2e/specs/confirmations/approve-custom-erc20.spec.js @@ -13,7 +13,7 @@ import TestDApp from '../../pages/Browser/TestDApp'; import { SMART_CONTRACTS } from '../../../app/util/test/smart-contracts'; import ContractApprovalBottomSheet from '../../pages/Browser/ContractApprovalBottomSheet'; import Assertions from '../../utils/Assertions'; -import { ActivitiesViewSelectorsText } from '../../selectors/ActivitiesView.selectors'; +import { ActivitiesViewSelectorsText } from '../../selectors/Transactions/ActivitiesView.selectors'; const HST_CONTRACT = SMART_CONTRACTS.HST; diff --git a/e2e/specs/confirmations/approve-default-erc20.spec.js b/e2e/specs/confirmations/approve-default-erc20.spec.js index c80139d992b..d56e53addc8 100644 --- a/e2e/specs/confirmations/approve-default-erc20.spec.js +++ b/e2e/specs/confirmations/approve-default-erc20.spec.js @@ -10,7 +10,7 @@ import { import { SMART_CONTRACTS } from '../../../app/util/test/smart-contracts'; import { ContractApprovalBottomSheetSelectorsText } from '../../selectors/Browser/ContractApprovalBottomSheet.selectors'; -import { ActivitiesViewSelectorsText } from '../../selectors/ActivitiesView.selectors'; +import { ActivitiesViewSelectorsText } from '../../selectors/Transactions/ActivitiesView.selectors'; import ContractApprovalBottomSheet from '../../pages/Browser/ContractApprovalBottomSheet'; import Assertions from '../../utils/Assertions'; diff --git a/e2e/specs/confirmations/increase-allowance-erc20.spec.js b/e2e/specs/confirmations/increase-allowance-erc20.spec.js index 32ffc52733b..2dc77b1bcc6 100644 --- a/e2e/specs/confirmations/increase-allowance-erc20.spec.js +++ b/e2e/specs/confirmations/increase-allowance-erc20.spec.js @@ -13,7 +13,7 @@ import TestDApp from '../../pages/Browser/TestDApp'; import { SMART_CONTRACTS } from '../../../app/util/test/smart-contracts'; import ContractApprovalBottomSheet from '../../pages/Browser/ContractApprovalBottomSheet'; import Assertions from '../../utils/Assertions'; -import { ActivitiesViewSelectorsText } from '../../selectors/ActivitiesView.selectors'; +import { ActivitiesViewSelectorsText } from '../../selectors/Transactions/ActivitiesView.selectors'; const HST_CONTRACT = SMART_CONTRACTS.HST; diff --git a/e2e/specs/confirmations/send-erc20-with-dapp.spec.js b/e2e/specs/confirmations/send-erc20-with-dapp.spec.js index 15fcfd1d28e..9a7d6fbfb7d 100644 --- a/e2e/specs/confirmations/send-erc20-with-dapp.spec.js +++ b/e2e/specs/confirmations/send-erc20-with-dapp.spec.js @@ -11,7 +11,7 @@ import { SMART_CONTRACTS, contractConfiguration, } from '../../../app/util/test/smart-contracts'; -import { ActivitiesViewSelectorsText } from '../../selectors/ActivitiesView.selectors'; +import { ActivitiesViewSelectorsText } from '../../selectors/Transactions/ActivitiesView.selectors'; import TabBarComponent from '../../pages/TabBarComponent'; import TestDApp from '../../pages/Browser/TestDApp'; diff --git a/e2e/specs/confirmations/send-erc721.spec.js b/e2e/specs/confirmations/send-erc721.spec.js index 3cc75c0ade7..712753fd003 100644 --- a/e2e/specs/confirmations/send-erc721.spec.js +++ b/e2e/specs/confirmations/send-erc721.spec.js @@ -12,7 +12,7 @@ import { defaultGanacheOptions, } from '../../fixtures/fixture-helper'; import { SMART_CONTRACTS } from '../../../app/util/test/smart-contracts'; -import { ActivitiesViewSelectorsText } from '../../selectors/ActivitiesView.selectors'; +import { ActivitiesViewSelectorsText } from '../../selectors/Transactions/ActivitiesView.selectors'; import Assertions from '../../utils/Assertions'; describe(SmokeConfirmations('ERC721 tokens'), () => { diff --git a/e2e/specs/confirmations/set-approve-for-all-erc721.spec.js b/e2e/specs/confirmations/set-approve-for-all-erc721.spec.js index e7cb9834d45..d90441de29e 100644 --- a/e2e/specs/confirmations/set-approve-for-all-erc721.spec.js +++ b/e2e/specs/confirmations/set-approve-for-all-erc721.spec.js @@ -12,7 +12,7 @@ import { defaultGanacheOptions, } from '../../fixtures/fixture-helper'; import { SMART_CONTRACTS } from '../../../app/util/test/smart-contracts'; -import { ActivitiesViewSelectorsText } from '../../selectors/ActivitiesView.selectors'; +import { ActivitiesViewSelectorsText } from '../../selectors/Transactions/ActivitiesView.selectors'; import Assertions from '../../utils/Assertions'; import { ContractApprovalBottomSheetSelectorsText } from '../../selectors/Browser/ContractApprovalBottomSheet.selectors'; import ContractApprovalBottomSheet from '../../pages/Browser/ContractApprovalBottomSheet'; diff --git a/e2e/specs/confirmations/suggestedGasApi.mock.spec.js b/e2e/specs/confirmations/suggestedGasApi.mock.spec.js new file mode 100644 index 00000000000..a534faa7702 --- /dev/null +++ b/e2e/specs/confirmations/suggestedGasApi.mock.spec.js @@ -0,0 +1,97 @@ +/* eslint-disable no-console */ +'use strict'; +import { loginToApp } from '../../viewHelper.js'; +import { Regression } from '../../tags.js'; +import TabBarComponent from '../../pages/TabBarComponent.js'; +import WalletActionsModal from '../../pages/modals/WalletActionsModal.js'; +import SendView from '../../pages/Send/SendView.js'; +import AmountView from '../../pages/Send/AmountView.js'; +import TransactionConfirmView from '../../pages/Send/TransactionConfirmView.js'; +import { + startMockServer, + stopMockServer, +} from '../../api-mocking/mock-server.js'; +import WalletView from '../../pages/wallet/WalletView.js'; +import Assertions from '../../utils/Assertions.js'; +import AccountListView from '../../pages/AccountListView.js'; +import AddAccountModal from '../../pages/modals/AddAccountModal.js'; +import ImportAccountView from '../../pages/importAccount/ImportAccountView.js'; +import Accounts from '../../../wdio/helpers/Accounts.js'; +import { withFixtures } from '../../fixtures/fixture-helper.js'; +import FixtureBuilder from '../../fixtures/fixture-builder.js'; +import TestHelpers from '../../helpers.js'; +import SuccessImportAccountView from '../../pages/importAccount/SuccessImportAccountView.js'; +import { mockEvents } from '../../api-mocking/mock-config/mock-events.js'; + +describe( + Regression( + 'Mock suggestedGasApi fallback to legacy gas endpoint when EIP1559 endpoint is down', + ), + () => { + let mockServer; + beforeAll(async () => { + jest.setTimeout(150000); + await TestHelpers.reverseServerPort(); + mockServer = await startMockServer({ + GET: [mockEvents.GET.suggestedGasFeesMainNetError], + }); + }); + + afterAll(async () => { + try { + await stopMockServer(); + } catch (error) { + // eslint-disable-next-line no-console + console.log( + 'Mock server already stopped or encountered an error:', + error, + ); + } + }); + + const RECIPIENT = '0x1FDb169Ef12954F20A15852980e1F0C122BfC1D6'; + const AMOUNT = '0.0003'; + const validPrivateKey = Accounts.getAccountPrivateKey(); + + it('should fallback to legacy gas endpoint & legacy modal when EIP1559 endpoint is down', async () => { + await withFixtures( + { + fixture: new FixtureBuilder().build(), + restartDevice: true, + }, + async () => { + await loginToApp(); + await WalletView.tapIdenticon(); + await Assertions.checkIfVisible(AccountListView.accountList); + await AccountListView.tapAddAccountButton(); + await AddAccountModal.tapImportAccount(); + await Assertions.checkIfVisible(ImportAccountView.container); + await ImportAccountView.enterPrivateKey(validPrivateKey.keys); + await Assertions.checkIfVisible(SuccessImportAccountView.container); + await SuccessImportAccountView.tapCloseButton(); + if (device.getPlatform() === 'ios') { + await AccountListView.swipeToDismissAccountsModal(); + await Assertions.checkIfNotVisible(AccountListView.title); + } else { + await WalletView.tapIdenticon(); + } + await TabBarComponent.tapActions(); + await WalletActionsModal.tapSendButton(); + await SendView.inputAddress(RECIPIENT); + await SendView.tapNextButton(); + await AmountView.typeInTransactionAmount(AMOUNT); + await AmountView.tapNextButton(); + await TransactionConfirmView.tapEstimatedGasLink(1); + await Assertions.checkIfVisible( + TransactionConfirmView.editPriorityLegacyModal, + ); + await stopMockServer(); //stop mock server to reinstate suggested gas api service + await Assertions.checkIfVisible( + TransactionConfirmView.editPriorityFeeSheetContainer, + 30000, + ); + }, + ); + }); + }, +); diff --git a/e2e/specs/quarantine/swap-token-chart.failing.js b/e2e/specs/quarantine/swap-token-chart.failing.js index 4e9b7b534de..33b11e950e6 100644 --- a/e2e/specs/quarantine/swap-token-chart.failing.js +++ b/e2e/specs/quarantine/swap-token-chart.failing.js @@ -18,8 +18,8 @@ import FixtureServer from '../../fixtures/fixture-server'; import { getFixturesServerPort } from '../../fixtures/utils'; import { Regression } from '../../tags'; import Assertions from '../../utils/Assertions'; -import ActivitiesView from '../../pages/ActivitiesView'; -import DetailsModal from '../../pages/modals/DetailsModal'; +import ActivitiesView from '../../pages/Transactions/ActivitiesView'; +import DetailsBottomSheet from '../../pages/Transactions/TransactionDetailsModal'; const fixtureServer = new FixtureServer(); const sourceTokenSymbol = 'USDT'; @@ -95,22 +95,22 @@ describe(Regression('Swap from Token view'), () => { await ActivitiesView.tapOnSwapActivity(sourceTokenSymbol, destTokenSymbol); try { - await Assertions.checkIfVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.title); } catch (e) { await ActivitiesView.tapOnSwapActivity( sourceTokenSymbol, destTokenSymbol, ); - await Assertions.checkIfVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.title); } - await Assertions.checkIfVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.title); await Assertions.checkIfElementToHaveText( - DetailsModal.title, - DetailsModal.generateExpectedTitle(sourceTokenSymbol, destTokenSymbol), + DetailsBottomSheet.title, + DetailsBottomSheet.generateExpectedTitle(sourceTokenSymbol, destTokenSymbol), ); - await Assertions.checkIfVisible(DetailsModal.statusConfirmed); - await DetailsModal.tapOnCloseIcon(); - await Assertions.checkIfNotVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.statusConfirmed); + await DetailsBottomSheet.tapOnCloseIcon(); + await Assertions.checkIfNotVisible(DetailsBottomSheet.title); }); }); diff --git a/e2e/specs/swaps/swap-action-regression.spec.js b/e2e/specs/swaps/swap-action-regression.spec.js index ef2a8acce3e..8130f7a2559 100644 --- a/e2e/specs/swaps/swap-action-regression.spec.js +++ b/e2e/specs/swaps/swap-action-regression.spec.js @@ -4,8 +4,8 @@ import Onboarding from '../../pages/swaps/OnBoarding'; import QuoteView from '../../pages/swaps/QuoteView'; import SwapView from '../../pages/swaps/SwapView'; import TabBarComponent from '../../pages/TabBarComponent'; -import ActivitiesView from '../../pages/ActivitiesView'; -import DetailsModal from '../../pages/modals/DetailsModal'; +import ActivitiesView from '../../pages/Transactions/ActivitiesView'; +import DetailsBottomSheet from '../../pages/Transactions/TransactionDetailsModal'; import WalletActionsModal from '../../pages/modals/WalletActionsModal'; import WalletView from '../../pages/wallet/WalletView'; import FixtureBuilder from '../../fixtures/fixture-builder'; @@ -116,23 +116,23 @@ describe(SmokeSwaps('Multiple Swaps from Actions'), () => { ); try { - await Assertions.checkIfVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.title); } catch (e) { await ActivitiesView.tapOnSwapActivity( sourceTokenSymbol, destTokenSymbol, ); - await Assertions.checkIfVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.title); } - await Assertions.checkIfVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.title); await Assertions.checkIfElementToHaveText( - DetailsModal.title, - DetailsModal.generateExpectedTitle(sourceTokenSymbol, destTokenSymbol), + DetailsBottomSheet.title, + DetailsBottomSheet.generateExpectedTitle(sourceTokenSymbol, destTokenSymbol), ); - await Assertions.checkIfVisible(DetailsModal.statusConfirmed); - await DetailsModal.tapOnCloseIcon(); - await Assertions.checkIfNotVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.statusConfirmed); + await DetailsBottomSheet.tapOnCloseIcon(); + await Assertions.checkIfNotVisible(DetailsBottomSheet.title); }, ); }); diff --git a/e2e/specs/swaps/swap-action-smoke.spec.js b/e2e/specs/swaps/swap-action-smoke.spec.js index ac383d4cf11..1ed47a23d1d 100644 --- a/e2e/specs/swaps/swap-action-smoke.spec.js +++ b/e2e/specs/swaps/swap-action-smoke.spec.js @@ -4,8 +4,8 @@ import Onboarding from '../../pages/swaps/OnBoarding'; import QuoteView from '../../pages/swaps/QuoteView'; import SwapView from '../../pages/swaps/SwapView'; import TabBarComponent from '../../pages/TabBarComponent'; -import ActivitiesView from '../../pages/ActivitiesView'; -import DetailsModal from '../../pages/modals/DetailsModal'; +import ActivitiesView from '../../pages/Transactions/ActivitiesView'; +import DetailsBottomSheet from '../../pages/Transactions/TransactionDetailsModal'; import WalletActionsModal from '../../pages/modals/WalletActionsModal'; import FixtureBuilder from '../../fixtures/fixture-builder'; import { @@ -115,21 +115,21 @@ describe(SmokeSwaps('Swap from Actions'), () => { ); try { - await Assertions.checkIfVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.title); } catch (e) { await ActivitiesView.tapOnSwapActivity( sourceTokenSymbol, destTokenSymbol, ); - await Assertions.checkIfVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.title); } await Assertions.checkIfElementToHaveText( - DetailsModal.title, - DetailsModal.generateExpectedTitle(sourceTokenSymbol, destTokenSymbol), + DetailsBottomSheet.title, + DetailsBottomSheet.generateExpectedTitle(sourceTokenSymbol, destTokenSymbol), ); - await Assertions.checkIfVisible(DetailsModal.statusConfirmed); - await DetailsModal.tapOnCloseIcon(); - await Assertions.checkIfNotVisible(DetailsModal.title); + await Assertions.checkIfVisible(DetailsBottomSheet.statusConfirmed); + await DetailsBottomSheet.tapOnCloseIcon(); + await Assertions.checkIfNotVisible(DetailsBottomSheet.title); }, ); }); diff --git a/e2e/specs/wallet/request-token-flow.spec.js b/e2e/specs/wallet/request-token-flow.spec.js index 01687985db2..01f11967ab1 100644 --- a/e2e/specs/wallet/request-token-flow.spec.js +++ b/e2e/specs/wallet/request-token-flow.spec.js @@ -2,8 +2,8 @@ import { SmokeCore } from '../../tags'; import RequestPaymentModal from '../../pages/Receive/RequestPaymentModal'; import SendLinkView from '../../pages/Receive/SendLinkView'; -import PaymentRequestQrModal from '../../pages/Receive/PaymentRequestQrModal'; -import RequestPaymentView from '../../pages/RequestPaymentView'; +import PaymentRequestQrBottomSheet from '../../pages/Receive/PaymentRequestQrBottomSheet'; +import RequestPaymentView from '../../pages/Receive/RequestPaymentView'; import TabBarComponent from '../../pages/TabBarComponent'; import WalletActionsModal from '../../pages/modals/WalletActionsModal'; import ProtectYourWalletModal from '../../pages/modals/ProtectYourWalletModal'; @@ -69,11 +69,11 @@ describe(SmokeCore('Request Token Flow with Unprotected Wallet'), () => { it('should see DAI request QR code', async () => { await SendLinkView.tapQRCodeButton(); - await Assertions.checkIfVisible(PaymentRequestQrModal.container); + await Assertions.checkIfVisible(PaymentRequestQrBottomSheet.container); }); it('should close request', async () => { - await PaymentRequestQrModal.tapCloseButton(); + await PaymentRequestQrBottomSheet.tapCloseButton(); await SendLinkView.tapCloseSendLinkButton(); }); diff --git a/e2e/specs/wallet/suggestedGasApi.mock.spec.js b/e2e/specs/wallet/suggestedGasApi.mock.spec.js deleted file mode 100644 index 164f9a64406..00000000000 --- a/e2e/specs/wallet/suggestedGasApi.mock.spec.js +++ /dev/null @@ -1,87 +0,0 @@ -'use strict'; -import { loginToApp } from '../../viewHelper.js'; -import { SmokeCore } from '../../tags.js'; -import TabBarComponent from '../../pages/TabBarComponent.js'; -import WalletActionsModal from '../../pages/modals/WalletActionsModal.js'; -import SendView from '../../pages/Send/SendView.js'; -import AmountView from '../../pages/Send/AmountView.js'; -import TransactionConfirmView from '../../pages/Send/TransactionConfirmView.js'; -import { startMockServer, stopMockServer } from '../../mockServer/mockServer.js'; -import WalletView from '../../pages/wallet/WalletView.js'; -import Assertions from '../../utils/Assertions.js'; -import AccountListView from '../../pages/AccountListView.js'; -import AddAccountModal from '../../pages/modals/AddAccountModal.js'; -import ImportAccountView from '../../pages/importAccount/ImportAccountView.js'; -import Accounts from '../../../wdio/helpers/Accounts.js'; -import { withFixtures } from '../../fixtures/fixture-helper.js'; -import FixtureBuilder from '../../fixtures/fixture-builder.js'; -import TestHelpers from '../../helpers.js'; -import { urls } from '../../mockServer/mockUrlCollection.json'; -import SuccessImportAccountView from '../../pages/importAccount/SuccessImportAccountView'; - -describe(SmokeCore('Mock suggestedGasApi fallback to legacy gas endpoint when EIP1559 endpoint is down'), () => { - let mockServer; - beforeAll(async () => { - jest.setTimeout(150000); - await TestHelpers.reverseServerPort(); - - mockServer = await startMockServer({ // Configure mock server - mockUrl: urls.suggestedGasApiMainnet, - responseCode: 500, - responseBody: { error: 'Internal server error' }, - }); - }); - - afterAll(async () => { - try { - await stopMockServer(); - } catch (error) { - // eslint-disable-next-line no-console - console.log('Mock server already stopped or encountered an error:', error); - } - }); - - const RECIPIENT = '0x1FDb169Ef12954F20A15852980e1F0C122BfC1D6'; - const AMOUNT = '0.0003'; - const validPrivateKey = Accounts.getAccountPrivateKey(); - - it('should fallback to legacy gas endpoint & legacy modal when EIP1559 endpoint is down', async () => { - await withFixtures( - { - fixture: new FixtureBuilder().build(), - restartDevice: true, - }, - async () => { - await loginToApp(); - await WalletView.tapIdenticon(); - await Assertions.checkIfVisible(AccountListView.accountList); - await AccountListView.tapAddAccountButton(); - await AddAccountModal.tapImportAccount(); - await Assertions.checkIfVisible(ImportAccountView.container); - await ImportAccountView.enterPrivateKey(validPrivateKey.keys); - await Assertions.checkIfVisible(SuccessImportAccountView.container); - await SuccessImportAccountView.tapCloseButton(); - if (device.getPlatform() === 'ios') { - await AccountListView.swipeToDismissAccountsModal(); - await Assertions.checkIfNotVisible(AccountListView.title); - } else { - await WalletView.tapIdenticon(); - } - await TabBarComponent.tapActions(); - await WalletActionsModal.tapSendButton(); - await SendView.inputAddress(RECIPIENT); - await SendView.tapNextButton(); - await AmountView.typeInTransactionAmount(AMOUNT); - await AmountView.tapNextButton(); - await TransactionConfirmView.tapEstimatedGasLink(1); - await Assertions.checkIfVisible( - TransactionConfirmView.editPriorityLegacyModal, - ); - await stopMockServer(); //stop mock server to reinstate suggested gas api service - await Assertions.checkIfVisible( - TransactionConfirmView.editPriorityFeeSheetContainer, 30000 - ); - }, - ); - }); -}); diff --git a/package.json b/package.json index 4f043e89406..c6ac4f12fbc 100644 --- a/package.json +++ b/package.json @@ -142,7 +142,7 @@ "@metamask/accounts-controller": "^18.2.1", "@metamask/address-book-controller": "^6.0.1", "@metamask/approval-controller": "^7.1.0", - "@metamask/assets-controllers": "^36.0.0", + "@metamask/assets-controllers": "^37.0.0", "@metamask/base-controller": "^7.0.1", "@metamask/composable-controller": "^3.0.0", "@metamask/contract-metadata": "^2.1.0", @@ -264,6 +264,7 @@ "path": "0.12.7", "pbkdf2": "3.1.2", "pify": "6.1.0", + "portfinder": "^1.0.32", "prop-types": "15.7.2", "pump": "3.0.0", "punycode": "^2.1.1", diff --git a/patches/@metamask+assets-controllers++multiformats+13.3.0.patch b/patches/@metamask+assets-controllers++multiformats+13.3.0.patch new file mode 100644 index 00000000000..dd14e2b2e28 --- /dev/null +++ b/patches/@metamask+assets-controllers++multiformats+13.3.0.patch @@ -0,0 +1,12 @@ +diff --git a/node_modules/@metamask/assets-controllers/node_modules/multiformats/package.json b/node_modules/@metamask/assets-controllers/node_modules/multiformats/package.json +index 79fd9b9..662d4c7 100644 +--- a/node_modules/@metamask/assets-controllers/node_modules/multiformats/package.json ++++ b/node_modules/@metamask/assets-controllers/node_modules/multiformats/package.json +@@ -22,6 +22,7 @@ + "multiformats" + ], + "type": "module", ++ "main": "./dist/src/index.js", + "types": "./dist/src/index.d.ts", + "typesVersions": { + "*": { diff --git a/patches/@metamask+assets-controllers+36.0.0.patch b/patches/@metamask+assets-controllers+37.0.0.patch similarity index 70% rename from patches/@metamask+assets-controllers+36.0.0.patch rename to patches/@metamask+assets-controllers+37.0.0.patch index af8d00e058a..9c930d9807d 100644 --- a/patches/@metamask+assets-controllers+36.0.0.patch +++ b/patches/@metamask+assets-controllers+37.0.0.patch @@ -1,35 +1,13 @@ -diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-DSDI75PJ.js b/node_modules/@metamask/assets-controllers/dist/chunk-DSDI75PJ.js -index f95d90f..3c33263 100644 ---- a/node_modules/@metamask/assets-controllers/dist/chunk-DSDI75PJ.js -+++ b/node_modules/@metamask/assets-controllers/dist/chunk-DSDI75PJ.js -@@ -173,6 +173,17 @@ var TokenRatesController = class extends _pollingcontroller.StaticIntervalPollin - _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _subscribeToNetworkStateChange, subscribeToNetworkStateChange_fn).call(this); - _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _subscribeToAccountChange, subscribeToAccountChange_fn).call(this); - } -+ -+ /** -+ * THIS FUNCTIONS IS CURRENTLY PATCHED AND STILL NEEDS TO BE IMPLEMENTED ON THE CORE REPO -+ * Resets to the default state -+ */ -+ reset() { -+ this.update((state) => { -+ state.marketData = {}; -+ }); -+ } -+ - /** - * Allows controller to make active and passive polling requests - */ -diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-HTIZ4JKG.js b/node_modules/@metamask/assets-controllers/dist/chunk-HTIZ4JKG.js -index a9f6736..ecd98e7 100644 ---- a/node_modules/@metamask/assets-controllers/dist/chunk-HTIZ4JKG.js -+++ b/node_modules/@metamask/assets-controllers/dist/chunk-HTIZ4JKG.js +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-2TZK6YZA.js b/node_modules/@metamask/assets-controllers/dist/chunk-2TZK6YZA.js +index 1d6c20d..abf5f3b 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-2TZK6YZA.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-2TZK6YZA.js @@ -46,7 +46,7 @@ var getDefaultNftControllerState = () => ({ allNfts: {}, ignoredNfts: [] }); --var _mutex, _selectedAccountId, _chainId, _ipfsGateway, _openSeaEnabled, _useIpfsSubdomains, _isIpfsGatewayEnabled, _getERC721AssetName, _getERC721AssetSymbol, _getERC721TokenURI, _getERC721OwnerOf, _getERC1155BalanceOf, _getERC1155TokenURI, _onNftAdded, _onNetworkControllerNetworkDidChange, onNetworkControllerNetworkDidChange_fn, _onPreferencesControllerStateChange, onPreferencesControllerStateChange_fn, _onSelectedAccountChange, onSelectedAccountChange_fn, _updateNestedNftState, updateNestedNftState_fn, _getNftInformationFromApi, getNftInformationFromApi_fn, _getNftInformationFromTokenURI, getNftInformationFromTokenURI_fn, _getNftURIAndStandard, getNftURIAndStandard_fn, _getNftInformation, getNftInformation_fn, _getNftContractInformationFromContract, getNftContractInformationFromContract_fn, _getNftContractInformation, getNftContractInformation_fn, _addIndividualNft, addIndividualNft_fn, _addNftContract, addNftContract_fn, _removeAndIgnoreIndividualNft, removeAndIgnoreIndividualNft_fn, _removeIndividualNft, removeIndividualNft_fn, _removeNftContract, removeNftContract_fn, _validateWatchNft, validateWatchNft_fn, _getCorrectChainId, getCorrectChainId_fn, _getAddressOrSelectedAddress, getAddressOrSelectedAddress_fn, _updateNftUpdateForAccount, updateNftUpdateForAccount_fn; -+var _mutex, _selectedAccountId, _chainId, _ipfsGateway, _displayNftMedia, _useIpfsSubdomains, _isIpfsGatewayEnabled, _getERC721AssetName, _getERC721AssetSymbol, _getERC721TokenURI, _getERC721OwnerOf, _getERC1155BalanceOf, _getERC1155TokenURI, _onNftAdded, _onNetworkControllerNetworkDidChange, onNetworkControllerNetworkDidChange_fn, _onPreferencesControllerStateChange, onPreferencesControllerStateChange_fn, _onSelectedAccountChange, onSelectedAccountChange_fn, _updateNestedNftState, updateNestedNftState_fn, _getNftInformationFromApi, getNftInformationFromApi_fn, _getNftInformationFromTokenURI, getNftInformationFromTokenURI_fn, _getNftURIAndStandard, getNftURIAndStandard_fn, _getNftInformation, getNftInformation_fn, _getNftContractInformationFromContract, getNftContractInformationFromContract_fn, _getNftContractInformation, getNftContractInformation_fn, _addIndividualNft, addIndividualNft_fn, _addNftContract, addNftContract_fn, _removeAndIgnoreIndividualNft, removeAndIgnoreIndividualNft_fn, _removeIndividualNft, removeIndividualNft_fn, _removeNftContract, removeNftContract_fn, _validateWatchNft, validateWatchNft_fn, _getCorrectChainId, getCorrectChainId_fn, _getAddressOrSelectedAddress, getAddressOrSelectedAddress_fn, _updateNftUpdateForAccount, updateNftUpdateForAccount_fn; +-var _mutex, _selectedAccountId, _chainId, _ipfsGateway, _openSeaEnabled, _useIpfsSubdomains, _isIpfsGatewayEnabled, _onNftAdded, _onNetworkControllerNetworkDidChange, onNetworkControllerNetworkDidChange_fn, _onPreferencesControllerStateChange, onPreferencesControllerStateChange_fn, _onSelectedAccountChange, onSelectedAccountChange_fn, _updateNestedNftState, updateNestedNftState_fn, _getNftCollectionApi, getNftCollectionApi_fn, _getNftInformationFromApi, getNftInformationFromApi_fn, _getNftInformationFromTokenURI, getNftInformationFromTokenURI_fn, _getNftURIAndStandard, getNftURIAndStandard_fn, _getNftInformation, getNftInformation_fn, _getNftContractInformationFromContract, getNftContractInformationFromContract_fn, _getNftContractInformation, getNftContractInformation_fn, _addIndividualNft, addIndividualNft_fn, _addNftContract, addNftContract_fn, _removeAndIgnoreIndividualNft, removeAndIgnoreIndividualNft_fn, _removeIndividualNft, removeIndividualNft_fn, _removeNftContract, removeNftContract_fn, _validateWatchNft, validateWatchNft_fn, _getCorrectChainId, getCorrectChainId_fn, _getAddressOrSelectedAddress, getAddressOrSelectedAddress_fn, _updateNftUpdateForAccount, updateNftUpdateForAccount_fn; ++var _mutex, _selectedAccountId, _chainId, _ipfsGateway, _displayNftMedia, _useIpfsSubdomains, _isIpfsGatewayEnabled, _onNftAdded, _onNetworkControllerNetworkDidChange, onNetworkControllerNetworkDidChange_fn, _onPreferencesControllerStateChange, onPreferencesControllerStateChange_fn, _onSelectedAccountChange, onSelectedAccountChange_fn, _updateNestedNftState, updateNestedNftState_fn, _getNftCollectionApi, getNftCollectionApi_fn, _getNftInformationFromApi, getNftInformationFromApi_fn, _getNftInformationFromTokenURI, getNftInformationFromTokenURI_fn, _getNftURIAndStandard, getNftURIAndStandard_fn, _getNftInformation, getNftInformation_fn, _getNftContractInformationFromContract, getNftContractInformationFromContract_fn, _getNftContractInformation, getNftContractInformation_fn, _addIndividualNft, addIndividualNft_fn, _addNftContract, addNftContract_fn, _removeAndIgnoreIndividualNft, removeAndIgnoreIndividualNft_fn, _removeIndividualNft, removeIndividualNft_fn, _removeNftContract, removeNftContract_fn, _validateWatchNft, validateWatchNft_fn, _getCorrectChainId, getCorrectChainId_fn, _getAddressOrSelectedAddress, getAddressOrSelectedAddress_fn, _updateNftUpdateForAccount, updateNftUpdateForAccount_fn; var NftController = class extends _basecontroller.BaseController { /** * Creates an NftController instance. @@ -41,8 +19,8 @@ index a9f6736..ecd98e7 100644 + * @param options.displayNftMedia - Controls whether the OpenSea API is used. * @param options.useIpfsSubdomains - Controls whether IPFS subdomains are used. * @param options.isIpfsGatewayEnabled - Controls whether IPFS is enabled or not. - * @param options.getERC721AssetName - Gets the name of the asset at the given address. -@@ -71,7 +71,7 @@ var NftController = class extends _basecontroller.BaseController { + * @param options.onNftAdded - Callback that is called when an NFT is added. Currently used pass data +@@ -65,7 +65,7 @@ var NftController = class extends _basecontroller.BaseController { constructor({ chainId: initialChainId, ipfsGateway = _controllerutils.IPFS_DEFAULT_GATEWAY_URL, @@ -50,8 +28,8 @@ index a9f6736..ecd98e7 100644 + displayNftMedia = false, useIpfsSubdomains = true, isIpfsGatewayEnabled = true, - getERC721AssetName, -@@ -103,7 +103,7 @@ var NftController = class extends _basecontroller.BaseController { + onNftAdded, +@@ -91,7 +91,7 @@ var NftController = class extends _basecontroller.BaseController { * Handles the state change of the preference controller. * @param preferencesState - The new state of the preference controller. * @param preferencesState.ipfsGateway - The configured IPFS gateway. @@ -60,7 +38,7 @@ index a9f6736..ecd98e7 100644 * @param preferencesState.isIpfsGatewayEnabled - Controls whether IPFS is enabled or not. */ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _onPreferencesControllerStateChange); -@@ -239,7 +239,7 @@ var NftController = class extends _basecontroller.BaseController { +@@ -228,7 +228,7 @@ var NftController = class extends _basecontroller.BaseController { _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _selectedAccountId, void 0); _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _chainId, void 0); _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _ipfsGateway, void 0); @@ -68,8 +46,8 @@ index a9f6736..ecd98e7 100644 + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _displayNftMedia, void 0); _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _useIpfsSubdomains, void 0); _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _isIpfsGatewayEnabled, void 0); - _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _getERC721AssetName, void 0); -@@ -254,7 +254,7 @@ var NftController = class extends _basecontroller.BaseController { + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _onNftAdded, void 0); +@@ -237,7 +237,7 @@ var NftController = class extends _basecontroller.BaseController { ).id); _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _chainId, initialChainId); _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _ipfsGateway, ipfsGateway); @@ -77,8 +55,8 @@ index a9f6736..ecd98e7 100644 + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _displayNftMedia, displayNftMedia); _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _useIpfsSubdomains, useIpfsSubdomains); _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _isIpfsGatewayEnabled, isIpfsGatewayEnabled); - _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _getERC721AssetName, getERC721AssetName); -@@ -281,6 +281,19 @@ var NftController = class extends _basecontroller.BaseController { + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _onNftAdded, onNftAdded); +@@ -258,6 +258,20 @@ var NftController = class extends _basecontroller.BaseController { _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _onSelectedAccountChange, onSelectedAccountChange_fn).bind(this) ); } @@ -94,11 +72,12 @@ index a9f6736..ecd98e7 100644 + state.ignoredNfts = []; + }); + } -+ ++ ++ getNftApi() { return `${_controllerutils.NFT_API_BASE_URL}/tokens`; } -@@ -799,7 +812,7 @@ _mutex = new WeakMap(); +@@ -806,7 +820,7 @@ _mutex = new WeakMap(); _selectedAccountId = new WeakMap(); _chainId = new WeakMap(); _ipfsGateway = new WeakMap(); @@ -106,8 +85,8 @@ index a9f6736..ecd98e7 100644 +_displayNftMedia = new WeakMap(); _useIpfsSubdomains = new WeakMap(); _isIpfsGatewayEnabled = new WeakMap(); - _getERC721AssetName = new WeakMap(); -@@ -824,7 +837,7 @@ onNetworkControllerNetworkDidChange_fn = function({ + _onNftAdded = new WeakMap(); +@@ -825,7 +839,7 @@ onNetworkControllerNetworkDidChange_fn = function({ _onPreferencesControllerStateChange = new WeakSet(); onPreferencesControllerStateChange_fn = async function({ ipfsGateway, @@ -116,7 +95,7 @@ index a9f6736..ecd98e7 100644 isIpfsGatewayEnabled }) { const selectedAccount = this.messagingSystem.call( -@@ -832,9 +845,9 @@ onPreferencesControllerStateChange_fn = async function({ +@@ -833,9 +847,9 @@ onPreferencesControllerStateChange_fn = async function({ ); _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _selectedAccountId, selectedAccount.id); _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _ipfsGateway, ipfsGateway); @@ -128,7 +107,7 @@ index a9f6736..ecd98e7 100644 if (needsUpdateNftMetadata && selectedAccount) { await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _updateNftUpdateForAccount, updateNftUpdateForAccount_fn).call(this, selectedAccount); } -@@ -843,7 +856,7 @@ _onSelectedAccountChange = new WeakSet(); +@@ -844,7 +858,7 @@ _onSelectedAccountChange = new WeakSet(); onSelectedAccountChange_fn = async function(internalAccount) { const oldSelectedAccountId = _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _selectedAccountId); _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _selectedAccountId, internalAccount.id); @@ -137,7 +116,7 @@ index a9f6736..ecd98e7 100644 if (needsUpdateNftMetadata) { await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _updateNftUpdateForAccount, updateNftUpdateForAccount_fn).call(this, internalAccount); } -@@ -900,7 +913,8 @@ getNftInformationFromApi_fn = async function(contractAddress, tokenId) { +@@ -905,7 +919,8 @@ getNftInformationFromApi_fn = async function(contractAddress, tokenId) { name: null, description: null, image: null, @@ -147,7 +126,7 @@ index a9f6736..ecd98e7 100644 }; } const { -@@ -961,7 +975,7 @@ getNftInformationFromTokenURI_fn = async function(contractAddress, tokenId, netw +@@ -966,7 +981,7 @@ getNftInformationFromTokenURI_fn = async function(contractAddress, tokenId, netw tokenURI: tokenURI ?? null }; } @@ -156,7 +135,7 @@ index a9f6736..ecd98e7 100644 if (!hasIpfsTokenURI && !isDisplayNFTMediaToggleEnabled) { return { image: null, -@@ -969,7 +983,8 @@ getNftInformationFromTokenURI_fn = async function(contractAddress, tokenId, netw +@@ -974,7 +989,8 @@ getNftInformationFromTokenURI_fn = async function(contractAddress, tokenId, netw description: null, standard: standard || null, favorite: false, @@ -166,7 +145,7 @@ index a9f6736..ecd98e7 100644 }; } if (hasIpfsTokenURI) { -@@ -1010,7 +1025,8 @@ getNftInformationFromTokenURI_fn = async function(contractAddress, tokenId, netw +@@ -1015,7 +1031,8 @@ getNftInformationFromTokenURI_fn = async function(contractAddress, tokenId, netw description: null, standard: standard || null, favorite: false, @@ -176,7 +155,7 @@ index a9f6736..ecd98e7 100644 }; } }; -@@ -1041,10 +1057,21 @@ getNftInformation_fn = async function(contractAddress, tokenId, networkClientId) +@@ -1056,10 +1073,21 @@ getNftInformation_fn = async function(contractAddress, tokenId, networkClientId) _controllerutils.safelyExecute.call(void 0, () => _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _getNftInformationFromTokenURI, getNftInformationFromTokenURI_fn).call(this, contractAddress, tokenId, networkClientId) ), @@ -199,7 +178,7 @@ index a9f6736..ecd98e7 100644 return { ...nftApiMetadata, name: blockchainMetadata?.name ?? nftApiMetadata?.name ?? null, -@@ -1161,7 +1188,8 @@ addIndividualNft_fn = async function(tokenAddress, tokenId, nftMetadata, nftCont +@@ -1184,7 +1212,8 @@ addIndividualNft_fn = async function(tokenAddress, tokenId, nftMetadata, nftCont symbol: nftContract.symbol, tokenId: tokenId.toString(), standard: nftMetadata.standard, @@ -209,34 +188,13 @@ index a9f6736..ecd98e7 100644 }); } } finally { -diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-NHFZIY2K.js b/node_modules/@metamask/assets-controllers/dist/chunk-NHFZIY2K.js -index 995ec6b..7222a8a 100644 ---- a/node_modules/@metamask/assets-controllers/dist/chunk-NHFZIY2K.js -+++ b/node_modules/@metamask/assets-controllers/dist/chunk-NHFZIY2K.js -@@ -19,7 +19,7 @@ function getDefaultTokenBalancesState() { - contractBalances: {} - }; - } --var _handle, _getERC20BalanceOf, _interval, _tokens, _disabled; -+var _handle, _getERC20BalanceOf, _interval, _tokens, _disabled, _updateInProgress; - var TokenBalancesController = class extends _basecontroller.BaseController { - /** - * Construct a Token Balances Controller. -@@ -54,9 +54,11 @@ var TokenBalancesController = class extends _basecontroller.BaseController { - _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _interval, void 0); - _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _tokens, void 0); - _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _disabled, void 0); -+ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _updateInProgress, void 0); - _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _disabled, disabled); - _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _interval, interval); - _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _tokens, tokens); -+ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _updateInProgress, false); - this.messagingSystem.subscribe( - "TokensController:stateChange", - ({ tokens: newTokens, detectedTokens }) => { -@@ -67,6 +69,17 @@ var TokenBalancesController = class extends _basecontroller.BaseController { - _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _getERC20BalanceOf, getERC20BalanceOf); - this.poll(); +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-ADJ3IFJH.js b/node_modules/@metamask/assets-controllers/dist/chunk-ADJ3IFJH.js +index fb25753..88208d5 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-ADJ3IFJH.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-ADJ3IFJH.js +@@ -189,6 +189,21 @@ var TokensController = class extends _basecontroller.BaseController { + } + ); } + + /** @@ -245,59 +203,29 @@ index 995ec6b..7222a8a 100644 + */ + reset() { + this.update((state) => { -+ state.contractBalances = {}; ++ state.allTokens = {}; ++ state.allIgnoredTokens = {}; ++ state.ignoredTokens = []; ++ state.tokens = []; + }); + } -+ ++ ++ /** - * Allows controller to update tracked tokens contract balances. - */ -@@ -107,20 +120,27 @@ var TokenBalancesController = class extends _basecontroller.BaseController { - "AccountsController:getSelectedAccount" - ); - const newContractBalances = {}; -- for (const token of _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _tokens)) { -+ const balancePromises = _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _tokens).map((token) => { - const { address } = token; -- try { -- const balance = await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _getERC20BalanceOf).call(this, address, selectedInternalAccount.address); -- newContractBalances[address] = _controllerutils.toHex.call(void 0, balance); -- token.hasBalanceError = false; -- } catch (error) { -- newContractBalances[address] = _controllerutils.toHex.call(void 0, 0); -- token.hasBalanceError = true; -- } -- } -+ return _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _getERC20BalanceOf).call(this, address, selectedInternalAccount.address).then((balance) => { -+ newContractBalances[address] = _controllerutils.toHex.call(void 0, balance); -+ token = { -+ ...token, -+ hasBalanceError: false -+ }; -+ }).catch((error) => { -+ newContractBalances[address] = _controllerutils.toHex.call(void 0, 0); -+ token = { -+ ...token, -+ hasBalanceError: true -+ }; -+ }); -+ }); -+ await Promise.all(balancePromises); - this.update((state) => { - state.contractBalances = newContractBalances; - }); -+ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _updateInProgress, false); - } - }; - _handle = new WeakMap(); -@@ -128,6 +148,7 @@ _getERC20BalanceOf = new WeakMap(); - _interval = new WeakMap(); - _tokens = new WeakMap(); - _disabled = new WeakMap(); -+_updateInProgress = new WeakMap(); - var TokenBalancesController_default = TokenBalancesController; - - + * Adds a token to the stored token list. + * +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-GHG3DOUK.js b/node_modules/@metamask/assets-controllers/dist/chunk-GHG3DOUK.js +index ec5a116..a82c449 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-GHG3DOUK.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-GHG3DOUK.js +@@ -72,6 +72,7 @@ var AssetsContractController = class { + * @returns Hex chain ID. + */ + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _getCorrectChainId); ++ this.name = name; + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _provider, void 0); + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _ipfsGateway, void 0); + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _chainId, void 0); diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-T5ZX5BV7.js b/node_modules/@metamask/assets-controllers/dist/chunk-T5ZX5BV7.js index 9c89a65..2ac17ba 100644 --- a/node_modules/@metamask/assets-controllers/dist/chunk-T5ZX5BV7.js @@ -351,13 +279,56 @@ index 9c89a65..2ac17ba 100644 } finally { releaseLock(); } -diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-TPUVGGNO.js b/node_modules/@metamask/assets-controllers/dist/chunk-TPUVGGNO.js -index baaf7d0..cfefb60 100644 ---- a/node_modules/@metamask/assets-controllers/dist/chunk-TPUVGGNO.js -+++ b/node_modules/@metamask/assets-controllers/dist/chunk-TPUVGGNO.js -@@ -189,6 +189,20 @@ var TokensController = class extends _basecontroller.BaseController { - } +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-X2HRAVDO.js b/node_modules/@metamask/assets-controllers/dist/chunk-X2HRAVDO.js +index 2688318..fa7521e 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-X2HRAVDO.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-X2HRAVDO.js +@@ -173,6 +173,17 @@ var TokenRatesController = class extends _pollingcontroller.StaticIntervalPollin + _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _subscribeToNetworkStateChange, subscribeToNetworkStateChange_fn).call(this); + _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _subscribeToAccountChange, subscribeToAccountChange_fn).call(this); + } ++ ++ /** ++ * THIS FUNCTIONS IS CURRENTLY PATCHED AND STILL NEEDS TO BE IMPLEMENTED ON THE CORE REPO ++ * Resets to the default state ++ */ ++ reset() { ++ this.update((state) => { ++ state.marketData = {}; ++ }); ++ } ++ + /** + * Allows controller to make active and passive polling requests + */ +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-YGGUAMHV.js b/node_modules/@metamask/assets-controllers/dist/chunk-YGGUAMHV.js +index 6550aec..b46080e 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-YGGUAMHV.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-YGGUAMHV.js +@@ -17,7 +17,7 @@ function getDefaultTokenBalancesState() { + contractBalances: {} + }; + } +-var _handle, _interval, _tokens, _disabled; ++var _handle, _interval, _tokens, _disabled, _updateInProgress; + var TokenBalancesController = class extends _basecontroller.BaseController { + /** + * Construct a Token Balances Controller. +@@ -49,9 +49,11 @@ var TokenBalancesController = class extends _basecontroller.BaseController { + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _interval, void 0); + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _tokens, void 0); + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _disabled, void 0); ++ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _updateInProgress, void 0); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _disabled, disabled); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _interval, interval); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _tokens, tokens); ++ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _updateInProgress, false); + this.messagingSystem.subscribe( + "TokensController:stateChange", + ({ tokens: newTokens, detectedTokens }) => { +@@ -61,6 +63,18 @@ var TokenBalancesController = class extends _basecontroller.BaseController { ); + this.poll(); } + + /** @@ -366,18 +337,78 @@ index baaf7d0..cfefb60 100644 + */ + reset() { + this.update((state) => { -+ state.allTokens = {}; -+ state.allIgnoredTokens = {}; -+ state.ignoredTokens = []; -+ state.tokens = []; ++ state.contractBalances = {}; + }); + } ++ + /** - * Adds a token to the stored token list. - * + * Allows controller to update tracked tokens contract balances. + */ +@@ -101,30 +115,38 @@ var TokenBalancesController = class extends _basecontroller.BaseController { + "AccountsController:getSelectedAccount" + ); + const newContractBalances = {}; +- for (const token of _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _tokens)) { ++ const balancePromises = _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _tokens).map((token) => { + const { address } = token; +- try { +- const balance = await this.messagingSystem.call( ++ return this.messagingSystem.call( + "AssetsContractController:getERC20BalanceOf", + address, + selectedInternalAccount.address +- ); +- newContractBalances[address] = _controllerutils.toHex.call(void 0, balance); +- token.hasBalanceError = false; +- } catch (error) { +- newContractBalances[address] = _controllerutils.toHex.call(void 0, 0); +- token.hasBalanceError = true; +- } +- } ++ ).then((balance) => { ++ newContractBalances[address] = _controllerutils.toHex.call(void 0, balance); ++ token = { ++ ...token, ++ hasBalanceError: false ++ }; ++ }).catch((error) => { ++ newContractBalances[address] = _controllerutils.toHex.call(void 0, 0); ++ token = { ++ ...token, ++ hasBalanceError: true ++ }; ++ }); ++ }); ++ await Promise.all(balancePromises); + this.update((state) => { + state.contractBalances = newContractBalances; + }); ++ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _updateInProgress, false); + } + }; + _handle = new WeakMap(); + _interval = new WeakMap(); + _tokens = new WeakMap(); + _disabled = new WeakMap(); ++_updateInProgress = new WeakMap(); + var TokenBalancesController_default = TokenBalancesController; + + +diff --git a/node_modules/@metamask/assets-controllers/dist/types/AssetsContractController.d.ts b/node_modules/@metamask/assets-controllers/dist/types/AssetsContractController.d.ts +index 6d364e4..33fa36f 100644 +--- a/node_modules/@metamask/assets-controllers/dist/types/AssetsContractController.d.ts ++++ b/node_modules/@metamask/assets-controllers/dist/types/AssetsContractController.d.ts +@@ -103,6 +103,7 @@ export type AssetsContractControllerMessenger = RestrictedControllerMessenger; _requestApproval(suggestedNftMeta: SuggestedNftMeta): Promise; + /** + * THIS FUNCTIONS IS CURRENTLY PATCHED AND STILL NEEDS TO BE IMPLEMENTED ON THE CORE REPO @@ -402,10 +433,10 @@ index a69c32d..077e2db 100644 //# sourceMappingURL=NftController.d.ts.map \ No newline at end of file diff --git a/node_modules/@metamask/assets-controllers/dist/types/TokenBalancesController.d.ts b/node_modules/@metamask/assets-controllers/dist/types/TokenBalancesController.d.ts -index 45d58f8..ce24723 100644 +index 09a5fe0..ce64d87 100644 --- a/node_modules/@metamask/assets-controllers/dist/types/TokenBalancesController.d.ts +++ b/node_modules/@metamask/assets-controllers/dist/types/TokenBalancesController.d.ts -@@ -79,6 +79,11 @@ export declare class TokenBalancesController extends BaseController; @@ -452,16 +483,3 @@ index a3eb08b..9bbc823 100644 export default TokensController; //# sourceMappingURL=TokensController.d.ts.map \ No newline at end of file -diff --git a/node_modules/@metamask/assets-controllers/dist/types/index.d.ts b/node_modules/@metamask/assets-controllers/dist/types/index.d.ts -index 2a42816..f0d02dc 100644 ---- a/node_modules/@metamask/assets-controllers/dist/types/index.d.ts -+++ b/node_modules/@metamask/assets-controllers/dist/types/index.d.ts -@@ -6,7 +6,7 @@ export type { NftControllerState, NftControllerMessenger, NftControllerActions, - export { getDefaultNftControllerState, NftController } from './NftController'; - export type { NftDetectionControllerMessenger, ApiNft, ApiNftContract, ApiNftLastSale, ApiNftCreator, ReservoirResponse, TokensResponse, BlockaidResultType, Blockaid, Market, TokenResponse, TopBid, LastSale, FeeBreakdown, Attributes, Collection, Royalties, Ownership, FloorAsk, Price, Metadata, } from './NftDetectionController'; - export { NftDetectionController } from './NftDetectionController'; --export type { TokenBalancesControllerMessenger, TokenBalancesControllerActions, TokenBalancesControllerGetStateAction, TokenBalancesControllerEvents, TokenBalancesControllerStateChangeEvent, } from './TokenBalancesController'; -+export type { TokenBalancesControllerMessenger, TokenBalancesControllerActions, TokenBalancesControllerGetStateAction, TokenBalancesControllerEvents, TokenBalancesControllerStateChangeEvent, TokenBalancesControllerState, } from './TokenBalancesController'; - export { TokenBalancesController } from './TokenBalancesController'; - export type { TokenDetectionControllerMessenger, TokenDetectionControllerActions, TokenDetectionControllerGetStateAction, TokenDetectionControllerEvents, TokenDetectionControllerStateChangeEvent, } from './TokenDetectionController'; - export { TokenDetectionController } from './TokenDetectionController'; diff --git a/shim.js b/shim.js index ec6b99e4e6e..3f9e7bb9181 100644 --- a/shim.js +++ b/shim.js @@ -7,7 +7,7 @@ import { testConfig, } from './app/util/test/utils.js'; import { LaunchArguments } from 'react-native-launch-arguments'; -import { defaultMockPort } from './e2e/mockServer/mockUrlCollection'; +import { defaultMockPort } from './e2e/api-mocking/mock-config/mockUrlCollection.json'; // In a testing environment, assign the fixtureServerPort to use a deterministic port if (isTest) { diff --git a/wdio/screen-objects/RequestTokenScreen.js b/wdio/screen-objects/RequestTokenScreen.js index e937ab7b6bf..01201b1588c 100644 --- a/wdio/screen-objects/RequestTokenScreen.js +++ b/wdio/screen-objects/RequestTokenScreen.js @@ -1,27 +1,22 @@ import Selectors from '../helpers/Selectors'; import Gestures from '../helpers/Gestures'; -import { - REQUEST_AMOUNT_INPUT, - REQUEST_SEARCH_ASSET_INPUT, - REQUEST_SEARCH_RESULTS_BACK_BUTTON, - REQUEST_SEARCH_SCREEN, -} from './testIDs/Screens/RequestToken.testIds'; +import { RequestPaymentViewSelectors } from '../../e2e/selectors/Receive/RequestPaymentView.selectors'; class RequestTokenScreen { get requestAmount() { - return Selectors.getElementByPlatform(REQUEST_AMOUNT_INPUT); + return Selectors.getElementByPlatform(RequestPaymentViewSelectors.REQUEST_AMOUNT_INPUT_BOX_ID); } get requestSearchInput() { - return Selectors.getElementByPlatform(REQUEST_SEARCH_ASSET_INPUT); + return Selectors.getElementByPlatform(RequestPaymentViewSelectors.TOKEN_SEARCH_INPUT_BOX); } get requestSearchBackButton() { - return Selectors.getElementByPlatform(REQUEST_SEARCH_RESULTS_BACK_BUTTON); + return Selectors.getElementByPlatform(RequestPaymentViewSelectors.BACK_BUTTON_ID); } get requestSearchScreen() { - return Selectors.getElementByPlatform(REQUEST_SEARCH_SCREEN); + return Selectors.getElementByPlatform(RequestPaymentViewSelectors.REQUEST_PAYMENT_CONTAINER_ID); } async typeAmountInRequest(amount) { diff --git a/wdio/screen-objects/SendLinkScreen.js b/wdio/screen-objects/SendLinkScreen.js index b91c03e9afa..1cf1a7367f8 100644 --- a/wdio/screen-objects/SendLinkScreen.js +++ b/wdio/screen-objects/SendLinkScreen.js @@ -1,17 +1,14 @@ import Selectors from '../helpers/Selectors'; import Gestures from '../helpers/Gestures'; -import { - PAYMENT_REQUEST_CLOSE_BUTTON, - PAYMENT_REQUEST_QR_CODE_CLOSE_ICON, -} from './testIDs/Screens/RequestToken.testIds'; +import { SendLinkViewSelectorsIDs } from '../../e2e/selectors/Receive/SendLinkView.selectors'; class SendLinkScreen { get requestCloseButton() { - return Selectors.getElementByPlatform(PAYMENT_REQUEST_CLOSE_BUTTON); + return Selectors.getElementByPlatform(SendLinkViewSelectorsIDs.CLOSE_SEND_LINK_VIEW_BUTTON); } get closeRequestPaymentQRIcon() { - return Selectors.getElementByPlatform(PAYMENT_REQUEST_QR_CODE_CLOSE_ICON); + return Selectors.getElementByPlatform(SendLinkViewSelectorsIDs.CLOSE_QR_MODAL_BUTTON); } async closePaymentRequest() { diff --git a/wdio/screen-objects/testIDs/Screens/RequestToken.testIds.js b/wdio/screen-objects/testIDs/Screens/RequestToken.testIds.js deleted file mode 100644 index 127130409b5..00000000000 --- a/wdio/screen-objects/testIDs/Screens/RequestToken.testIds.js +++ /dev/null @@ -1,8 +0,0 @@ -export const REQUEST_AMOUNT_INPUT = 'request-amount-input'; -export const PAYMENT_REQUEST_CLOSE_BUTTON = 'send-link-close-button'; -export const REQUEST_SEARCH_ASSET_INPUT = 'request-search-asset-input'; -export const REQUEST_SEARCH_RESULTS_BACK_BUTTON = - 'request-search-asset-back-button'; -export const REQUEST_SEARCH_SCREEN = 'request-screen'; -export const PAYMENT_REQUEST_QR_CODE_CLOSE_ICON = - 'payment-request-qrcode-close-button'; diff --git a/yarn.lock b/yarn.lock index eb512606053..9ffae1c415c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4294,7 +4294,7 @@ "@metamask/utils" "^3.4.1" superstruct "^1.0.3" -"@metamask/abi-utils@^2.0.2", "@metamask/abi-utils@^2.0.4": +"@metamask/abi-utils@^2.0.3", "@metamask/abi-utils@^2.0.4": version "2.0.4" resolved "https://registry.yarnpkg.com/@metamask/abi-utils/-/abi-utils-2.0.4.tgz#20908c1d910f7a17a89fdf5778a5c59d5cb8b8be" integrity sha512-StnIgUB75x7a7AgUhiaUZDpCsqGp7VkNnZh2XivXkJ6mPkE83U8ARGQj5MbRis7VJY8BC5V1AbB1fjdh0hupPQ== @@ -4328,7 +4328,7 @@ "@metamask/controller-utils" "^11.3.0" "@metamask/utils" "^9.1.0" -"@metamask/approval-controller@^7.0.0", "@metamask/approval-controller@^7.0.1", "@metamask/approval-controller@^7.0.2", "@metamask/approval-controller@^7.1.0": +"@metamask/approval-controller@^7.0.0", "@metamask/approval-controller@^7.0.2", "@metamask/approval-controller@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@metamask/approval-controller/-/approval-controller-7.1.0.tgz#34b07bc4eaf6938b15f9d915c6885d4a5c0a5205" integrity sha512-dhqUeX8wMzW88U+Vgr7oKf0Vouol10ncB3lxmvWyC1VZJhSOdO3VUkn0tH1lzt3ybxYVMOkPaB3gfdksfnNRyA== @@ -4338,37 +4338,33 @@ "@metamask/utils" "^9.1.0" nanoid "^3.1.31" -"@metamask/assets-controllers@^36.0.0": - version "36.0.0" - resolved "https://registry.yarnpkg.com/@metamask/assets-controllers/-/assets-controllers-36.0.0.tgz#17f48d65b0b444aae742b8221fd16513da148458" - integrity sha512-leYjYcH6TIxDzrQebJjeBc02H2YMx9JfWsGQ9tZHydB0BF4st3pDUZYneVZRfR2XlIAyoVS7cSgvfdXZ+tmstQ== +"@metamask/assets-controllers@^37.0.0": + version "37.0.0" + resolved "https://registry.yarnpkg.com/@metamask/assets-controllers/-/assets-controllers-37.0.0.tgz#89ab8794118066892f5da1370b4051c0e850b204" + integrity sha512-84rF+Bg65ocPP0MWHJQgWchsqnFXARck60SirulSVuYMPA2chwe276r/qe1ZtLlMxQASROCRNayjAR4VK/Aj5Q== dependencies: "@ethereumjs/util" "^8.1.0" "@ethersproject/address" "^5.7.0" "@ethersproject/bignumber" "^5.7.0" "@ethersproject/contracts" "^5.7.0" "@ethersproject/providers" "^5.7.0" - "@metamask/abi-utils" "^2.0.2" - "@metamask/accounts-controller" "^17.2.0" - "@metamask/approval-controller" "^7.0.1" - "@metamask/base-controller" "^6.0.1" + "@metamask/abi-utils" "^2.0.3" + "@metamask/base-controller" "^6.0.2" "@metamask/contract-metadata" "^2.4.0" - "@metamask/controller-utils" "^11.0.1" + "@metamask/controller-utils" "^11.0.2" "@metamask/eth-query" "^4.0.0" - "@metamask/keyring-controller" "^17.1.0" "@metamask/metamask-eth-abis" "^3.1.1" - "@metamask/network-controller" "^20.0.0" - "@metamask/polling-controller" "^9.0.0" - "@metamask/preferences-controller" "^13.0.0" + "@metamask/polling-controller" "^9.0.1" "@metamask/rpc-errors" "^6.3.1" - "@metamask/utils" "^9.0.0" + "@metamask/utils" "^9.1.0" "@types/bn.js" "^5.1.5" "@types/uuid" "^8.3.0" async-mutex "^0.5.0" bn.js "^5.2.1" cockatiel "^3.1.2" + immer "^9.0.6" lodash "^4.17.21" - multiformats "^9.5.2" + multiformats "^13.1.0" single-call-balance-checker-abi "^1.0.0" uuid "^8.3.2" @@ -4388,7 +4384,7 @@ "@metamask/utils" "^8.3.0" immer "^9.0.6" -"@metamask/base-controller@^6.0.0", "@metamask/base-controller@^6.0.1", "@metamask/base-controller@^6.0.2": +"@metamask/base-controller@^6.0.0", "@metamask/base-controller@^6.0.2": version "6.0.3" resolved "https://registry.yarnpkg.com/@metamask/base-controller/-/base-controller-6.0.3.tgz#9bb4e74234c1de5f99842c343ffa053c08055db1" integrity sha512-neUqsCXRT6QYcZO51y6Y5u9NPTHuxgNsW5Z4h///o1gDdV8lBeIG/b1ne+QPK422DZMAm4ChnkG1DDNf4PkErw== @@ -4438,7 +4434,7 @@ resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-2.2.0.tgz#277764d0d56e37180ae7644a9d11eb96295b36fc" integrity sha512-SM6A4C7vXNbVpgMTX67kfW8QWvu3eSXxMZlY5PqZBTkvri1s9zgQ0uwRkK5r2VXNEoVmXCDnnEX/tX5EzzgNUQ== -"@metamask/controller-utils@^11.0.0", "@metamask/controller-utils@^11.0.1", "@metamask/controller-utils@^11.0.2", "@metamask/controller-utils@^11.3.0": +"@metamask/controller-utils@^11.0.0", "@metamask/controller-utils@^11.0.2", "@metamask/controller-utils@^11.3.0": version "11.3.0" resolved "https://registry.yarnpkg.com/@metamask/controller-utils/-/controller-utils-11.3.0.tgz#530fd22289f717b752b4a7b6e504e1f2911b30a4" integrity sha512-5b+Jg9sKKESzvQcuipHC1D7KSh98MVIi7hXQUk7iX+YVMl4KoKDv94Bl+li8g+jCBshMOV9bRMRh25/hdEvTZQ== @@ -4882,7 +4878,7 @@ bech32 "^2.0.0" uuid "^9.0.1" -"@metamask/keyring-controller@^17.1.0", "@metamask/keyring-controller@^17.2.1", "@metamask/keyring-controller@^17.2.2": +"@metamask/keyring-controller@^17.2.1", "@metamask/keyring-controller@^17.2.2": version "17.2.2" resolved "https://registry.yarnpkg.com/@metamask/keyring-controller/-/keyring-controller-17.2.2.tgz#944bc693305b4a6e4f1e73739a82c4bc6573dd9a" integrity sha512-Shqk0ybcTPrHQLlBJ1V+InuYC7nD3/a6Ws0XCcBCOfkLTXvtSooKIWBioK83XlHMHkfsM6+bySxSqXJVgJvBZw== @@ -5170,7 +5166,7 @@ fast-json-stable-stringify "^2.1.0" uuid "^8.3.2" -"@metamask/polling-controller@^9.0.0": +"@metamask/polling-controller@^9.0.1": version "9.0.1" resolved "https://registry.yarnpkg.com/@metamask/polling-controller/-/polling-controller-9.0.1.tgz#3d72ab925bace25f5f6b2c5209777708b1fc168e" integrity sha512-GmTqEA7RlJ6fO2G15HW1hUVay1m+CQAsWJ835rU8Udz8FmIBTWPQVRMITq0bQexTHi18YZHgm1sx0iwrPscS3Q== @@ -5205,7 +5201,7 @@ eslint-plugin-n "^16.6.2" json-rpc-random-id "^1.0.1" -"@metamask/preferences-controller@^13.0.0", "@metamask/preferences-controller@^13.1.0": +"@metamask/preferences-controller@^13.1.0": version "13.1.0" resolved "https://registry.yarnpkg.com/@metamask/preferences-controller/-/preferences-controller-13.1.0.tgz#e407f6a0879d5fa4178caa0bdd4e310d178f0b34" integrity sha512-fRURU9ZJaztJ+dPq+DrLbEcddhAoRDO5poagb+T8cFmIDxvTA1OKR1Bz8mgn91xMTuWMg95M+bPnb5dbRbRViw== @@ -22649,7 +22645,12 @@ multicodec@^1.0.0: buffer "^5.6.0" varint "^5.0.0" -multiformats@^9.4.2, multiformats@^9.5.2: +multiformats@^13.1.0: + version "13.3.0" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-13.3.0.tgz#1f5188bc7c4fe08ff829ae1c18dc33409042fb71" + integrity sha512-CBiqvsufgmpo01VT5ze94O+uc+Pbf6f/sThlvWss0sBZmAOu6GQn5usrYV2sf2mr17FWYc0rO8c/CNe2T90QAA== + +multiformats@^9.4.2: version "9.9.0" resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==