Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove global network usage from signatures #28167

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions test/data/confirmations/personal_sign.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { CHAIN_IDS } from '@metamask/transaction-controller';
import { SignatureRequestType } from '../../../ui/pages/confirmations/types/confirm';

export const PERSONAL_SIGN_SENDER_ADDRESS =
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc';

export const unapprovedPersonalSignMsg = {
id: '0050d5b0-c023-11ee-a0cb-3390a510a0ab',
chainId: CHAIN_IDS.GOERLI,
status: 'unapproved',
time: new Date().getTime(),
type: 'personal_sign',
Expand All @@ -20,6 +22,7 @@ export const unapprovedPersonalSignMsg = {

export const signatureRequestSIWE = {
id: '210ca3b0-1ccb-11ef-b096-89c4d726ebb5',
chainId: CHAIN_IDS.GOERLI,
securityAlertResponse: {
reason: 'loading',
result_type: 'validation_in_progress',
Expand Down Expand Up @@ -57,6 +60,7 @@ export const signatureRequestSIWE = {

export const SignatureRequestSIWEWithResources = {
id: '210ca3b0-1ccb-11ef-b096-89c4d726ebb5',
chainId: CHAIN_IDS.GOERLI,
securityAlertResponse: {
reason: 'loading',
result_type: 'validation_in_progress',
Expand Down
11 changes: 10 additions & 1 deletion test/data/confirmations/typed_sign.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { TransactionType } from '@metamask/transaction-controller';
import { CHAIN_IDS, TransactionType } from '@metamask/transaction-controller';
import { MESSAGE_TYPE } from '../../../shared/constants/app';
import { SignatureRequestType } from '../../../ui/pages/confirmations/types/confirm';

export const unapprovedTypedSignMsgV1 = {
id: '82ab2400-e2c6-11ee-9627-73cc88f00492',
chainId: CHAIN_IDS.GOERLI,
securityAlertResponse: {
reason: 'loading',
result_type: 'validation_in_progress',
Expand Down Expand Up @@ -60,6 +61,7 @@ const rawMessageV3 = {

export const unapprovedTypedSignMsgV3 = {
id: '17e41af0-e073-11ee-9eec-5fd284826685',
chainId: CHAIN_IDS.GOERLI,
securityAlertResponse: {
reason: 'loading',
result_type: 'validation_in_progress',
Expand Down Expand Up @@ -129,6 +131,7 @@ export const rawMessageV4 = {

export const unapprovedTypedSignMsgV4 = {
id: '0050d5b0-c023-11ee-a0cb-3390a510a0ab',
chainId: CHAIN_IDS.GOERLI,
status: 'unapproved',
time: new Date().getTime(),
chainid: '0x5',
Expand All @@ -145,6 +148,7 @@ export const unapprovedTypedSignMsgV4 = {

export const orderSignatureMsg = {
id: 'e5249ae0-4b6b-11ef-831f-65b48eb489ec',
chainId: CHAIN_IDS.GOERLI,
securityAlertResponse: {
result_type: 'loading',
reason: 'validation_in_progress',
Expand All @@ -165,6 +169,7 @@ export const orderSignatureMsg = {

export const permitSignatureMsg = {
id: '0b1787a0-1c44-11ef-b70d-e7064bd7b659',
chainId: CHAIN_IDS.GOERLI,
securityAlertResponse: {
reason: 'loading',
result_type: 'validation_in_progress',
Expand All @@ -185,6 +190,7 @@ export const permitSignatureMsg = {

export const permitNFTSignatureMsg = {
id: 'c5067710-87cf-11ef-916c-71f266571322',
chainId: CHAIN_IDS.GOERLI,
status: 'unapproved',
time: 1728651190529,
type: 'eth_signTypedData',
Expand All @@ -200,6 +206,7 @@ export const permitNFTSignatureMsg = {

export const permitSignatureMsgWithNoDeadline = {
id: '0b1787a0-1c44-11ef-b70d-e7064bd7b659',
chainId: CHAIN_IDS.GOERLI,
securityAlertResponse: {
reason: 'loading',
result_type: 'validation_in_progress',
Expand All @@ -219,6 +226,7 @@ export const permitSignatureMsgWithNoDeadline = {

export const permitBatchSignatureMsg = {
id: '0b1787a0-1c44-11ef-b70d-e7064bd7b659',
chainId: CHAIN_IDS.GOERLI,
securityAlertResponse: {
reason: 'loading',
result_type: 'validation_in_progress',
Expand All @@ -239,6 +247,7 @@ export const permitBatchSignatureMsg = {

export const permitSingleSignatureMsg = {
id: '0b1787a0-1c44-11ef-b70d-e7064bd7b659',
chainId: CHAIN_IDS.GOERLI,
securityAlertResponse: {
reason: 'loading',
result_type: 'validation_in_progress',
Expand Down
2 changes: 2 additions & 0 deletions test/integration/confirmations/signatures/permit.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ApprovalType } from '@metamask/controller-utils';
import { act, fireEvent, screen, waitFor } from '@testing-library/react';
import nock from 'nock';
import { CHAIN_IDS } from '@metamask/transaction-controller';
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
import {
MetaMetricsEventCategory,
Expand Down Expand Up @@ -42,6 +43,7 @@ const getMetaMaskStateWithUnapprovedPermitSign = (accountAddress: string) => {
unapprovedTypedMessages: {
[pendingPermitId]: {
id: pendingPermitId,
chainId: CHAIN_IDS.SEPOLIA,
status: 'unapproved',
time: pendingPermitTime,
type: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ApprovalType } from '@metamask/controller-utils';
import { act, fireEvent, screen, waitFor } from '@testing-library/react';
import { CHAIN_IDS } from '@metamask/transaction-controller';
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
import {
MetaMetricsEventCategory,
Expand Down Expand Up @@ -34,6 +35,7 @@ const getMetaMaskStateWithUnapprovedPersonalSign = (accountAddress: string) => {
unapprovedPersonalMsgs: {
[pendingPersonalSignId]: {
id: pendingPersonalSignId,
chainId: CHAIN_IDS.SEPOLIA,
status: 'unapproved',
time: pendingPersonalSignTime,
type: MESSAGE_TYPE.PERSONAL_SIGN,
Expand Down
1 change: 0 additions & 1 deletion ui/hooks/useName.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ jest.mock('react-redux', () => ({
}));

jest.mock('../selectors', () => ({
getCurrentChainId: jest.fn(),
getNames: jest.fn(),
}));

Expand Down
4 changes: 0 additions & 4 deletions ui/hooks/useNftCollectionsMetadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ jest.mock('react-redux', () => ({
useSelector: (selector: any) => selector(),
}));

jest.mock('../selectors', () => ({
getCurrentChainId: jest.fn(),
}));

jest.mock('../store/actions', () => ({
getNFTContractInfo: jest.fn(),
getTokenStandardAndDetails: jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const PermitSimulationValueDisplay: React.FC<

const tokenDetails = useGetTokenStandardAndDetails(tokenContract);
useTrackERC20WithoutDecimalInformation(
chainId,
tokenContract,
tokenDetails as TokenDetailsERC20,
MetaMetricsEventLocation.SignatureConfirmation,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import React, { useCallback, useEffect, useState } from 'react';
import { useSelector } from 'react-redux';

import { Hex } from '@metamask/utils';
import { Box } from '../../../../../components/component-library';
import { Toast } from '../../../../../components/multichain';
import {
getLastInteractedConfirmationInfo,
setLastInteractedConfirmationInfo,
} from '../../../../../store/actions';
import {
getCurrentChainId,
getNetworkConfigurationsByChainId,
} from '../../../../../selectors';
import { useI18nContext } from '../../../../../hooks/useI18nContext';
import { selectNetworkConfigurationByChainId } from '../../../../../selectors';

const CHAIN_CHANGE_THRESHOLD_MILLISECONDS = 60 * 1000; // 1 Minute
const TOAST_TIMEOUT_MILLISECONDS = 5 * 1000; // 5 Seconds
Expand All @@ -22,22 +18,25 @@ const NetworkChangeToastLegacy = ({
}: {
confirmation: { id: string; chainId: string };
}) => {
const chainId = useSelector(getCurrentChainId);
const newChainId = confirmation?.chainId ?? chainId;
const newChainId = confirmation?.chainId;
const [toastVisible, setToastVisible] = useState(false);
const t = useI18nContext();
const networkConfigurations = useSelector(getNetworkConfigurationsByChainId);
const network = networkConfigurations[newChainId as Hex];

const network = useSelector((state) =>
selectNetworkConfigurationByChainId(state, newChainId),
);

const hideToast = useCallback(() => {
setToastVisible(false);
}, [setToastVisible]);

useEffect(() => {
let isMounted = true;

if (!confirmation) {
return undefined;
}

(async () => {
const lastInteractedConfirmationInfo =
await getLastInteractedConfirmationInfo();
Expand Down Expand Up @@ -71,7 +70,7 @@ const NetworkChangeToastLegacy = ({
return () => {
isMounted = false;
};
}, [confirmation?.id, chainId]);
}, [confirmation?.id]);

if (!toastVisible) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default function ContractDetailsModal({
tokenAddress,
toAddress,
chainId,
rpcPrefs,
blockExplorerUrl,
tokenId,
assetName,
assetStandard,
Expand Down Expand Up @@ -178,7 +178,7 @@ export default function ContractDetailsModal({
tokenAddress,
chainId,
{
blockExplorerUrl: rpcPrefs?.blockExplorerUrl ?? null,
blockExplorerUrl: blockExplorerUrl ?? null,
},
null,
);
Expand Down Expand Up @@ -287,7 +287,7 @@ export default function ContractDetailsModal({
toAddress,
chainId,
{
blockExplorerUrl: rpcPrefs?.blockExplorerUrl ?? null,
blockExplorerUrl: blockExplorerUrl ?? null,
},
null,
);
Expand Down Expand Up @@ -338,9 +338,9 @@ ContractDetailsModal.propTypes = {
*/
chainId: PropTypes.string,
/**
* RPC prefs of the current network
* Block explorer URL of the current network
*/
rpcPrefs: PropTypes.object,
blockExplorerUrl: PropTypes.string,
/**
* The token id of the NFT
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
import { captureException } from '@sentry/browser';
import BlockaidPackage from '@blockaid/ppom_release/package.json';

import { useSelector } from 'react-redux';
import { NETWORK_TO_NAME_MAP } from '../../../../../../shared/constants/network';
import { OverflowWrap } from '../../../../../helpers/constants/design-system';
import { I18nContext } from '../../../../../contexts/i18n';
Expand All @@ -20,7 +19,6 @@ import { useTransactionEventFragment } from '../../../hooks/useTransactionEventF

import SecurityProviderBannerAlert from '../security-provider-banner-alert';
import LoadingIndicator from '../../../../../components/ui/loading-indicator';
import { getCurrentChainId } from '../../../../../selectors';
import { getReportUrl } from './blockaid-banner-utils';

const zlib = require('zlib');
Expand Down Expand Up @@ -59,8 +57,6 @@ function BlockaidBannerAlert({ txData, ...props }) {
const { securityAlertResponse, origin, msgParams, type, txParams, chainId } =
txData;

const selectorChainId = useSelector(getCurrentChainId);

const t = useContext(I18nContext);
const { updateTransactionEventFragment } = useTransactionEventFragment();

Expand Down Expand Up @@ -131,7 +127,7 @@ function BlockaidBannerAlert({ txData, ...props }) {
const reportData = {
blockNumber: block,
blockaidVersion: BlockaidPackage.version,
chain: NETWORK_TO_NAME_MAP[chainId ?? selectorChainId],
chain: NETWORK_TO_NAME_MAP[chainId],
classification: isFailedResultType ? 'error' : reason,
domain: origin ?? msgParams?.origin ?? txParams?.origin,
jsonRpcMethod: type,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { RpcEndpointType } from '@metamask/network-controller';
import { NetworkType } from '@metamask/controller-utils';
import { useI18nContext } from '../../../../hooks/useI18nContext';

import {
getNativeCurrency,
getProviderConfig,
} from '../../../../ducks/metamask/metamask';
import {
accountsWithSendEtherInfoSelector,
getCurrentChainId,
getCurrentCurrency,
selectDefaultRpcEndpointByChainId,
selectNetworkConfigurationByChainId,
} from '../../../../selectors';
import { formatCurrency } from '../../../../helpers/utils/confirm-tx.util';
import {
Expand All @@ -26,22 +25,33 @@ import NetworkAccountBalanceHeader from '../../../../components/app/network-acco
const SignatureRequestHeader = ({ txData }) => {
const t = useI18nContext();
const {
chainId,
msgParams: { from },
} = txData;
const allAccounts = useSelector(accountsWithSendEtherInfoSelector);
const fromAccount = getAccountByAddress(allAccounts, from);
const nativeCurrency = useSelector(getNativeCurrency);
const currentCurrency = useSelector(getCurrentCurrency);
const currentChainId = useSelector(getCurrentChainId);

const providerConfig = useSelector(getProviderConfig);
const networkName = getNetworkNameFromProviderType(providerConfig.type);
const { nativeCurrency, name: networkNickname } = useSelector((state) =>
selectNetworkConfigurationByChainId(state, chainId),
);

const defaultRpcEndpoint = useSelector((state) =>
selectDefaultRpcEndpointByChainId(state, chainId),
);

const networkType =
defaultRpcEndpoint.type === RpcEndpointType.Custom
? NetworkType.rpc
: defaultRpcEndpoint.networkClientId;

const networkName = getNetworkNameFromProviderType(networkType);

const conversionRate = null; // setting conversion rate to null by default to display balance in native

const currentNetwork =
networkName === ''
? providerConfig.nickname || t('unknownNetwork')
? networkNickname || t('unknownNetwork')
: t(networkName);

const balanceInBaseAsset = conversionRate
Expand Down Expand Up @@ -71,7 +81,7 @@ const SignatureRequestHeader = ({ txData }) => {
conversionRate ? currentCurrency?.toUpperCase() : nativeCurrency
}
accountAddress={fromAccount.address}
chainId={currentChainId}
chainId={chainId}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
import React from 'react';
import { CHAIN_IDS } from '@metamask/transaction-controller';
import { Provider } from 'react-redux';
import configureStore from '../../../../store/store';
import testData from '../../../../../.storybook/test-data';
import { mockNetworkState } from '../../../../../test/stub/networks';
import SignatureRequestHeader from './signature-request-header';

const CHAIN_ID_MOCK = CHAIN_IDS.MAINNET;

const store = configureStore({
...testData,
metamask: {
...testData.metamask,
...mockNetworkState({ chainId: CHAIN_ID_MOCK }),
},
});

export default {
title: 'Confirmations/Components/SignatureRequestHeader',
decorators: [(story) => <Provider store={store}>{story()}</Provider>],
argTypes: {
txData: { control: 'object' },
},
args: {
txData: {
chainId: CHAIN_ID_MOCK,
msgParams: {
from: '0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e',
data: JSON.stringify({
Expand Down
Loading