Skip to content
Open
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
Binary file added app/images/tempo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/images/tempo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions shared/constants/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ export const CHAIN_IDS = {
MONAD: '0x8f',
HYPE: '0x3e7',
X_LAYER: '0xc4',
TEMPO_TESTNET: '0xa5bd',
} as const;

export const CHAINLIST_CHAIN_IDS_MAP = {
Expand Down Expand Up @@ -652,6 +653,7 @@ export const XRPLEVM_TESTNET_NATIVE_TOKEN_IMAGE_URL =
export const LENS_IMAGE_URL = './images/lens.png';
export const LENS_NATIVE_TOKEN_IMAGE_URL = './images/lens-native.svg';
export const PLUME_IMAGE_URL = './images/plume.png';
export const TEMPO_TOKEN_IMAGE_URL = './images/tempo.svg';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tempo Testnet missing from TEST_CHAINS array

Medium Severity

CHAIN_IDS.TEMPO_TESTNET is added but not included in the TEST_CHAINS array, unlike other testnets such as MEGAETH_TESTNET and MONAD_TESTNET. This array is used in useTokenDisplayInfo.tsx to determine isTestnetSelected, which affects the shouldShowFiat calculation. Without this addition, Tempo Testnet will be incorrectly treated as a mainnet, causing fiat values to display according to mainnet logic rather than respecting the user's testnet fiat display preferences.

Fix in Cursor Fix in Web

export const PLUME_NATIVE_TOKEN_IMAGE_URL = './images/plume-native.svg';
export const MATCHAIN_IMAGE_URL = './images/matchain.svg';
export const FLOW_IMAGE_URL = './images/flow.svg';
Expand Down Expand Up @@ -1091,6 +1093,7 @@ export const CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP: Record<string, string> = {
[CHAIN_IDS.MEGAETH_MAINNET]: MEGAETH_MAINNET_IMAGE_URL,
[CHAIN_IDS.NEAR]: NEAR_IMAGE_URL,
[CHAIN_IDS.NEAR_TESTNET]: NEAR_IMAGE_URL,
[CHAIN_IDS.TEMPO_TESTNET]: TEMPO_TOKEN_IMAGE_URL,
[CHAINLIST_CHAIN_IDS_MAP.ARBITRUM_NOVA]: ARBITRUM_NOVA_IMAGE_URL,
[CHAINLIST_CHAIN_IDS_MAP.ASTAR]: ASTAR_IMAGE_URL,
[CHAINLIST_CHAIN_IDS_MAP.BAHAMUT_MAINNET]: BAHAMUT_IMAGE_URL,
Expand Down
10 changes: 8 additions & 2 deletions ui/components/app/assets/hooks/useTokenDisplayInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import { useMultichainSelector } from '../../../../hooks/useMultichainSelector';
import { useFormatters } from '../../../../hooks/useFormatters';
import { isEvmChainId } from '../../../../../shared/lib/asset-utils';
import { getInternalAccountBySelectedAccountGroupAndCaip } from '../../../../selectors/multichain-accounts/account-tree';
import { TEST_CHAINS } from '../../../../../shared/constants/network';
import { CHAIN_IDS, TEST_CHAINS } from '../../../../../shared/constants/network';
import { hexToDecimal } from '../../../../../shared/modules/conversion.utils';

type UseTokenDisplayInfoProps = {
token: TokenWithFiatAmount;
Expand Down Expand Up @@ -106,13 +107,18 @@ export const useTokenDisplayInfo = ({
]?.name) ||
token.symbol;

const tokenImage =
let tokenImage =
tokenData?.iconUrl ||
(token.chainId &&
erc20TokensByChain?.[token.chainId]?.data?.[token.address.toLowerCase()]
?.iconUrl) ||
token.image;

// Temporary override for Tempo Testnet tokens until Tempo token assets are
// served from Metamask CDN
if (token.chainId === CHAIN_IDS.TEMPO_TESTNET && token.address)
tokenImage = `https://tempoxyz.github.io/tempo-apps/${hexToDecimal(token.chainId)}/icons/${token.address.toLowerCase()}.svg`;

return {
title,
tokenImage,
Expand Down
16 changes: 16 additions & 0 deletions ui/pages/confirmations/components/UI/asset/asset.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { BtcAccountType } from '@metamask/keyring-api';
import createMockStore from 'redux-mock-store';

import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate';
import { CHAIN_IDS } from '../../../../../../shared/constants/network';
import { useNftImageUrl } from '../../../hooks/useNftImageUrl';
import { AssetStandard } from '../../../types/send';
import { Asset } from './asset';
Expand Down Expand Up @@ -103,6 +104,21 @@ describe('TokenAsset', () => {
expect(getByTestId('token-asset-undefined-TEST')).toBeInTheDocument();
expect(queryByRole('img', { name: 'Ethereum' })).not.toBeInTheDocument();
});

it('uses override image URL for Tempo Testnet tokens', () => {
const tempoTokenAsset = {
...mockTokenAsset,
chainId: CHAIN_IDS.TEMPO_TESTNET,
address: '0x1234567890abcdef1234567890abcdef12345678',
};
const { getByAltText } = render(<Asset asset={tempoTokenAsset} />);

const image = getByAltText('TEST logo');
expect(image).toHaveAttribute(
'src',
'https://tempoxyz.github.io/tempo-apps/42429/icons/0x1234567890abcdef1234567890abcdef12345678.svg',
);
});
});

describe('NFTAsset', () => {
Expand Down
10 changes: 8 additions & 2 deletions ui/pages/confirmations/components/UI/asset/asset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { useNftImageUrl } from '../../../hooks/useNftImageUrl';
import { accountTypeLabel } from '../../../constants/network';
import { useFormatters } from '../../../../../hooks/useFormatters';
import { AccountTypeLabel } from '../account-type-label';
import { hexToDecimal } from '../../../../../../shared/modules/conversion.utils';
import { CHAIN_IDS } from '../../../../../../shared/constants/network';

type AssetProps = {
asset: AssetType;
Expand Down Expand Up @@ -118,12 +120,16 @@ const NftAsset = ({ asset, onClick, isSelected }: AssetProps) => {

const TokenAsset = ({ asset, onClick, isSelected }: AssetProps) => {
const tokenData = asset;
const { chainId, image, name, balance, symbol = '', fiat } = tokenData;
const { chainId, address, image, name, balance, symbol = '', fiat } = tokenData;
const { formatCurrencyWithMinThreshold, formatTokenQuantity } =
useFormatters();

const typeLabel = accountTypeLabel[asset.accountType as KeyringAccountType];

// Temporary override for Tempo Testnet tokens until Tempo token assets are
// served from Metamask CDN
const overrideImage = (chainId === CHAIN_IDS.TEMPO_TESTNET && address) ? `https://tempoxyz.github.io/tempo-apps/${hexToDecimal(chainId)}/icons/${address.toLowerCase()}.svg` : undefined;

return (
<Box
alignItems={AlignItems.center}
Expand Down Expand Up @@ -155,7 +161,7 @@ const TokenAsset = ({ asset, onClick, isSelected }: AssetProps) => {
>
<AvatarToken
size={AvatarTokenSize.Md}
src={image}
src={overrideImage || image}
name={symbol}
showHalo={false}
/>
Expand Down
Loading