Skip to content

Commit

Permalink
Merge branch 'main' into STAKE-921-mobile-asset-detail-staking-balanc…
Browse files Browse the repository at this point in the history
…e-shows-for-eth-assets-on-unsupported-chains-with-popular-networks-filter
  • Loading branch information
nickewansmith authored Jan 15, 2025
2 parents a30b360 + 4e7a190 commit a551ef7
Show file tree
Hide file tree
Showing 60 changed files with 495 additions and 183 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ module.exports = {
'selectProviderType',
'selectRpcUrl',
'selectSelectedNetworkClientId',
'selectTicker'
'selectTicker',
]
.map((method) => `(${method})`)
.join('|')}/]`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,43 @@ describe('NetworkVerificationInfo', () => {

expect(getByText('10')).toBeTruthy();
});

it('should not render Network URL warning banner when the custom rpc url has all ascii characters', () => {
(useSelector as jest.Mock).mockReturnValue(true);
const { getByText } = render(
<NetworkVerificationInfo
customNetworkInformation={mockNetworkInfo}
onReject={() => undefined}
onConfirm={() => undefined}
/>,
);

expect(() =>
getByText(
"Attackers sometimes mimic sites by making small changes to the site address. Make sure you're interacting with the intended Network URL before you continue. Punycode version: https://xn--ifura-dig.io/gnosis",
),
).toThrow('Unable to find an element with text');
});

describe('when the custom rpc url has non-ascii characters', () => {
it('should render Network URL warning banner and display punycode encoded version', () => {
(useSelector as jest.Mock).mockReturnValue(true);
const { getByText } = render(
<NetworkVerificationInfo
customNetworkInformation={{
...mockNetworkInfo,
rpcUrl: 'https://iոfura.io/gnosis',
}}
onReject={() => undefined}
onConfirm={() => undefined}
/>,
);

expect(
getByText(
"Attackers sometimes mimic sites by making small changes to the site address. Make sure you're interacting with the intended Network URL before you continue. Punycode version: https://xn--ifura-dig.io/gnosis",
),
).toBeTruthy();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { toggleUseSafeChainsListValidation } from '../../../util/networks/engine
import { NetworkApprovalBottomSheetSelectorsIDs } from '../../../../e2e/selectors/Network/NetworkApprovalBottomSheet.selectors';
import hideKeyFromUrl from '../../../util/hideKeyFromUrl';
import { convertHexToDecimal } from '@metamask/controller-utils';
import { isValidASCIIURL, toPunycodeURL } from '../../../util/url';

interface Alert {
alertError: string;
Expand Down Expand Up @@ -83,6 +84,8 @@ const NetworkVerificationInfo = ({
const showReviewDefaultRpcUrlChangesModal = () =>
setShowReviewDefaultRpcUrlChanges(!showReviewDefaultRpcUrlChanges);

const customRpcUrl = customNetworkInformation.rpcUrl;

const goToLearnMore = () => {
Linking.openURL(
'https://support.metamask.io/networks-and-sidechains/managing-networks/verifying-custom-network-information/',
Expand Down Expand Up @@ -236,9 +239,7 @@ const NetworkVerificationInfo = ({
: strings('add_custom_network.network_url')}
</Text>
)}
<Text style={styles.textSection}>
{hideKeyFromUrl(customNetworkInformation.rpcUrl)}
</Text>
<Text style={styles.textSection}>{hideKeyFromUrl(customRpcUrl)}</Text>

<Accordion
title={strings('spend_limit_edition.view_details')}
Expand Down Expand Up @@ -291,6 +292,27 @@ const NetworkVerificationInfo = ({
return null;
};

const renderBannerNetworkUrlNonAsciiDetected = () => {
if (!customRpcUrl || isValidASCIIURL(customRpcUrl)) {
return null;
}
const punycodeUrl = toPunycodeURL(customRpcUrl);

return (
<View style={styles.alertBar}>
<Banner
severity={BannerAlertSeverity.Warning}
variant={BannerVariant.Alert}
description={
strings('networks.network_rpc_url_warning_punycode') +
'\n' +
punycodeUrl
}
/>
</View>
);
};

const renderCustomNetworkBanner = () => (
<View style={styles.alertBar}>
<Banner
Expand Down Expand Up @@ -331,9 +353,7 @@ const NetworkVerificationInfo = ({
<Text variant={TextVariant.BodyMDBold}>
{strings('networks.current_label')}
</Text>
<Text style={styles.textSection}>
{customNetworkInformation.rpcUrl}
</Text>
<Text style={styles.textSection}>{customRpcUrl}</Text>
<Text variant={TextVariant.BodyMDBold}>
{strings('networks.new_label')}
</Text>
Expand Down Expand Up @@ -442,6 +462,7 @@ const NetworkVerificationInfo = ({
/>
{renderAlerts()}
{renderBanner()}
{renderBannerNetworkUrlNonAsciiDetected()}
{isMultichainVersion1Enabled &&
isCustomNetwork &&
renderCustomNetworkBanner()}
Expand Down
8 changes: 7 additions & 1 deletion app/components/UI/PermissionsSummary/PermissionsSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,13 @@ const PermissionsSummary = ({
</TextComponent>
<View style={styles.permissionRequestAccountInfo}>
<View style={styles.permissionRequestAccountName}>
<TextComponent numberOfLines={1} ellipsizeMode="tail">
<TextComponent
testID={
PermissionSummaryBottomSheetSelectorsIDs.ACCOUNT_PERMISSION_CONTAINER
}
numberOfLines={1}
ellipsizeMode="tail"
>
<TextComponent variant={TextVariant.BodySM}>
{getAccountLabel()}
</TextComponent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ exports[`PermissionsSummary should render correctly 1`] = `
"lineHeight": 22,
}
}
testID="permission-summary-account-text"
>
<Text
accessibilityRole="text"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Routes from '../../../../../constants/navigation/Routes';
import { MetaMetricsEvents } from '../../../../../core/Analytics';
import {
selectChainId,
selectIsPopularNetwork,
selectProviderConfig,
selectTicker,
} from '../../../../../selectors/networkController';
Expand Down Expand Up @@ -68,11 +69,14 @@ export const PortfolioBalance = () => {
const isTokenNetworkFilterEqualCurrentNetwork = useSelector(
selectIsTokenNetworkFilterEqualCurrentNetwork,
);
const isPopularNetwork = useSelector(selectIsPopularNetwork);

const formattedTokensWithBalancesPerChain = useGetFormattedTokensPerChain(
[selectedInternalAccount as InternalAccount],
isTokenNetworkFilterEqualCurrentNetwork,
!isTokenNetworkFilterEqualCurrentNetwork && isPopularNetwork,
allChainIDs,
);

const totalFiatBalancesCrossChain: TotalFiatBalancesCrossChains =
useGetTotalFiatBalanceCrossChains(
[selectedInternalAccount as InternalAccount],
Expand Down
9 changes: 5 additions & 4 deletions app/components/Views/confirmations/Confirm/Confirm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import {
} from '../../../../util/test/confirm-data-helpers';
import Confirm from './index';

jest.mock('../../../../core/Engine', () => ({
getTotalFiatAccountBalance: () => ({ tokenFiat: 10 }),
}));

jest.mock('../../../../util/address', () => ({
...jest.requireActual('../../../../util/address'),
getAddressAccountType: (str: string) => str,
Expand All @@ -23,11 +27,8 @@ describe('Confirm', () => {
state: personalSignatureConfirmationState,
});
expect(getByText('Signature request')).toBeDefined();
expect(getByText('Estimated changes')).toBeDefined();
expect(
getByText(
'You’re signing into a site and there are no predicted changes to your account.',
),
getByText('Review request details before you confirm.'),
).toBeDefined();
expect(getByText('Request from')).toBeDefined();
expect(getByText('metamask.github.io')).toBeDefined();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ const styleSheet = (_params: {
}) =>
StyleSheet.create({
attributionBase: Object.assign({
height: 24,
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'flex-start',
height: 40,
marginTop: 8,
} as ViewStyle),
attributionItem: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import renderWithProvider from '../../../../../../util/test/renderWithProvider';
import { personalSignatureConfirmationState } from '../../../../../../util/test/confirm-data-helpers';
import AccountNetworkInfo from './AccountNetworkInfo';

jest.mock('../../../../../../core/Engine', () => ({
getTotalFiatAccountBalance: () => ({ tokenFiat: 10 }),
}));

describe('AccountNetworkInfo', () => {
it('should render correctly', async () => {
const { getByText } = renderWithProvider(<AccountNetworkInfo />, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import renderWithProvider from '../../../../../../../util/test/renderWithProvide
import { personalSignatureConfirmationState } from '../../../../../../../util/test/confirm-data-helpers';
import AccountNetworkInfoCollapsed from './AccountNetworkInfoCollapsed';

jest.mock('../../../../../../../core/Engine', () => ({
getTotalFiatAccountBalance: () => ({ tokenFiat: 10 }),
}));

describe('AccountNetworkInfoCollapsed', () => {
it('should render correctly', async () => {
const { getByText } = renderWithProvider(<AccountNetworkInfoCollapsed />, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ import renderWithProvider from '../../../../../../../util/test/renderWithProvide
import { personalSignatureConfirmationState } from '../../../../../../../util/test/confirm-data-helpers';
import AccountNetworkInfoExpanded from './AccountNetworkInfoExpanded';

jest.mock('../../../../../../../core/Engine', () => ({
getTotalFiatAccountBalance: () => ({ tokenFiat: 10 }),
}));

describe('AccountNetworkInfoExpanded', () => {
it('should render correctly', async () => {
const { getByText } = renderWithProvider(<AccountNetworkInfoExpanded />, {
state: personalSignatureConfirmationState,
});
expect(getByText('Account')).toBeDefined();
expect(getByText('Balance')).toBeDefined();
expect(getByText('0 ETH')).toBeDefined();
expect(getByText('$10')).toBeDefined();
expect(getByText('Network')).toBeDefined();
expect(getByText('Ethereum Mainnet')).toBeDefined();
expect(getByText('RPC URL')).toBeDefined();
expect(getByText('mainnet.infura.io/v3/')).toBeDefined();
});
});
Original file line number Diff line number Diff line change
@@ -1,57 +1,36 @@
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { View } from 'react-native';
import { useSelector } from 'react-redux';

import { strings } from '../../../../../../../../locales/i18n';
import {
selectChainId,
selectProviderConfig,
} from '../../../../../../../selectors/networkController';
import { selectChainId } from '../../../../../../../selectors/networkController';
import { renderShortAddress } from '../../../../../../../util/address';
import useAccountInfo from '../../../../hooks/useAccountInfo';
import useApprovalRequest from '../../../../hooks/useApprovalRequest';
import InfoSection from '../../../UI/InfoRow/InfoSection';
import InfoRow from '../../../UI/InfoRow';
import Address from '../../../UI/InfoRow/InfoValue/Address';
import DisplayURL from '../../../UI/InfoRow/InfoValue/DisplayURL';
import Network from '../../../UI/InfoRow/InfoValue/Network';

const styles = StyleSheet.create({
addressRowValue: {
paddingTop: 8,
},
});

const AccountNetworkInfoExpanded = () => {
const { approvalRequest } = useApprovalRequest();
const chainId = useSelector(selectChainId);
const { rpcUrl: networkRpcUrl, type: networkType } =
useSelector(selectProviderConfig);
const fromAddress = approvalRequest?.requestData?.from;
const { accountAddress, accountBalance } = useAccountInfo(fromAddress);
const { accountAddress, accountFiatBalance } = useAccountInfo(fromAddress);

return (
<View>
<InfoSection>
<InfoRow label={strings('confirm.account')}>
<View style={styles.addressRowValue}>
<Address address={accountAddress} chainId={chainId} />
</View>
{renderShortAddress(accountAddress, 5)}
</InfoRow>
<InfoRow label={strings('confirm.balance')}>
{accountFiatBalance}
</InfoRow>
<InfoRow label={strings('confirm.balance')}>{accountBalance}</InfoRow>
</InfoSection>
<InfoSection>
<InfoRow
label={strings('confirm.network')}
// todo: add tooltip content when available
tooltip={strings('confirm.network')}
>
<InfoRow label={strings('confirm.network')}>
<Network chainId={chainId} />
</InfoRow>
<InfoRow label={strings('confirm.rpc_url')}>
<DisplayURL
url={networkRpcUrl ?? `https://${networkType}.infura.io/v3/`}
/>
</InfoRow>
</InfoSection>
</View>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const createStyles = (depth: number) =>
},
dataRow: {
paddingHorizontal: 0,
paddingBottom: 0,
paddingBottom: 16,
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import { StyleSheet } from 'react-native';

import { Theme } from '../../../../../../util/theme/models';

const styleSheet = (params: { theme: Theme }) => {
const { theme } = params;
const styleSheet = (params: { theme: Theme; vars: { hasError: boolean } }) => {
const { theme, vars } = params;

return StyleSheet.create({
confirmButton: {
flex: 1,
backgroundColor: vars.hasError
? theme.colors.error.default
: theme.colors.primary.default,
},
rejectButton: {
flex: 1,
Expand All @@ -19,7 +22,7 @@ const styleSheet = (params: { theme: Theme }) => {
},
buttonsContainer: {
flexDirection: 'row',
padding: 16,
paddingVertical: 16,
},
buttonDivider: {
width: 8,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ import { View } from 'react-native';
import { strings } from '../../../../../../../locales/i18n';
import StyledButton from '../../../../../../components/UI/StyledButton';
import { useStyles } from '../../../../../../component-library/hooks';
import useApprovalRequest from '../../../hooks/useApprovalRequest';
import { useConfirmActions } from '../../../hooks/useConfirmActions';
import styleSheet from './Footer.styles';

const Footer = () => {
const { onConfirm, onReject } = useConfirmActions();
const { styles } = useStyles(styleSheet, {});
const { approvalRequest } = useApprovalRequest();
const securityAlertResponse =
approvalRequest?.requestData?.securityAlertResponse;
const { styles } = useStyles(styleSheet, {
hasError: securityAlertResponse !== undefined,
});

return (
<View style={styles.buttonsContainer}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ describe('PersonalSign', () => {
const { getByText } = renderWithProvider(<PersonalSign />, {
state: personalSignatureConfirmationState,
});
expect(getByText('Estimated changes')).toBeDefined();
expect(
getByText(
'You’re signing into a site and there are no predicted changes to your account.',
),
).toBeDefined();
expect(getByText('Request from')).toBeDefined();
expect(getByText('metamask.github.io')).toBeDefined();
expect(getByText('Message')).toBeDefined();
Expand Down
Loading

0 comments on commit a551ef7

Please sign in to comment.