Skip to content

feat: extend TokenHero support for all ERC20 tokens - transfer transactions #15259

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

Merged
merged 84 commits into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
1815336
feat: extend useTokenValues to support all ERC20 tokens
digiwand May 8, 2025
2bb1eba
style: useTokenValues abstract logic
digiwand May 8, 2025
6c070b8
feat: create useTokenDetails hook
digiwand May 8, 2025
050a953
fix: fix flickering value by waiting for async decimals
digiwand May 8, 2025
d0017d1
refactor: change NetworkAssetLogo style prop to optional
digiwand May 8, 2025
77eeced
fix: useTokenValues fiat conversion should read per tokenAddress
digiwand May 8, 2025
f37868e
style: alphabetize useTokenValues methods
digiwand May 8, 2025
3908f52
style: clean useTokenValues
digiwand May 8, 2025
f8b097a
style: format useTokenValues
digiwand May 9, 2025
eb5b4c0
feat: useTokenValues support native tokens
digiwand May 9, 2025
64b50da
feat: extend TokenHero support to all ERC20 tokens
digiwand May 9, 2025
faf6499
style: rn displayTokenAmountIsRounded -> isRoundedTokenAmount
digiwand May 9, 2025
ac55007
style: TokenHero rm AvatarTokenNetworkWithBadge style prop
digiwand May 9, 2025
1921f63
style: rn networkAndTokenContainer -> containerAvatarTokenNetworkWith…
digiwand May 9, 2025
ee8a016
feat: add TokenHero badge conditional
digiwand May 9, 2025
c5f7f62
style: clean
digiwand May 9, 2025
aac4e06
refactor: useTokenValues use safeToChecksumAddress
digiwand May 10, 2025
b62fc93
fix: export fetchTokenFiatRates from useBalanceChanges
digiwand May 10, 2025
7471309
refactor: mv fetchTokenFiatRates util method
digiwand May 10, 2025
bbf4ec2
feat: include native networkImage
digiwand May 10, 2025
4ae75a5
refactor: create AvatarTokenWithNetworkBadge
digiwand May 10, 2025
061c8ed
Merge branch 'main' into feat-token-hero-erc20-support
digiwand May 14, 2025
365d44a
feat: TokenHero support ERC20 continued
digiwand May 14, 2025
d02097e
refactor: cleanup
digiwand May 14, 2025
fde4d1d
refactor: rm useTokenAssetByType unused native asset token parans
digiwand May 14, 2025
4244d7f
Revert "refactor: mv fetchTokenFiatRates util method"
digiwand May 15, 2025
85bb4ee
refactor: cleanup rm unused files
digiwand May 15, 2025
20ffc21
revert: async fetchTokenFiatRates
digiwand May 15, 2025
6f3b834
Merge branch 'main' into feat-token-hero-erc20-support
digiwand May 15, 2025
09baf6b
style: TokenHero format selection
digiwand May 15, 2025
67311f5
style: cleanup TokenHero
digiwand May 15, 2025
36cc8d8
revert: AvatarTokenWithNetworkBadge split components
digiwand May 15, 2025
403164a
refactor: useTokenAssetByType rm NFT logic for now
digiwand May 15, 2025
fe261f7
refactor: TokenHero cleanup
digiwand May 15, 2025
ae87ddb
feat: support "Unknown" TokenHero
digiwand May 15, 2025
bafecba
fix: utils/token lint
digiwand May 15, 2025
071295a
fix: token.unknown i18n
digiwand May 15, 2025
4fce761
fix: TokenHero tests by adding asset support
digiwand May 15, 2025
6854d6c
refactor: useTokenAssetByType
digiwand May 15, 2025
68db1a1
fix: hide network badge TokenHero transfer
digiwand May 15, 2025
f91dc4f
style: format selection TokenHero and AvatarTokenWithNetworkBadge
digiwand May 15, 2025
ba8ed05
style: rename AvatarTokenOrNetworkAssetLogo
digiwand May 15, 2025
0d69936
test: add TokenHero simple send test
digiwand May 15, 2025
f7e0eb2
refactor: deprecate useTokenValues instances
digiwand May 15, 2025
6fe7dbd
refactor: deprecate useTokenValues util
digiwand May 15, 2025
53c6bbe
refactor: rn useTokenValuesByType -> useTokenAmount
digiwand May 15, 2025
5f7b0c1
test:fix: refactored useTokenAmount output
digiwand May 15, 2025
8e83760
test: add useTokenAmount transfer test
digiwand May 15, 2025
f4201f4
test: add TokenHero avatar tests
digiwand May 15, 2025
10329e5
refactor: rn useTokenAssetByType
digiwand May 15, 2025
a107fd7
refactor: rn useTokenAssetByType path
digiwand May 15, 2025
8ae2f8c
fix: support displaying TokenHero symbol & ticker
digiwand May 16, 2025
2f02ecc
fix: rm debugging getByText
digiwand May 16, 2025
3e2df9a
test: create useTokenAsset test
digiwand May 16, 2025
f2ae7b0
fix: add TokenHero useHideFiatForTestnet
digiwand May 16, 2025
3a1caca
revert: optional NetworkAssetLogo style param
digiwand May 16, 2025
71f6412
fix: sometimes ticker exists while symbol does not
digiwand May 16, 2025
f8e106a
Merge branch 'main' into feat-token-hero-erc20-support
digiwand May 16, 2025
97885dd
fix: TokenHero transfer simple send test
digiwand May 16, 2025
0b9de27
fix: useEIP1559TxFees test
digiwand May 16, 2025
6c3532f
fix: StakingWithdrawal test
digiwand May 16, 2025
287a30b
fix: useFeeCalculations test
digiwand May 16, 2025
dbba8c8
test:fix: GasFeeDetails test
digiwand May 16, 2025
9acce73
fix: rm AvatarTokenWithNetworkBadge for now
digiwand May 16, 2025
041114a
test:fix: StakingWithdrawal
digiwand May 16, 2025
945f485
fix: enable "?" for unknown AvatarToken
digiwand May 16, 2025
4f1ee47
test:fix: useConfirmActions
digiwand May 16, 2025
8fd69d6
test:fix: CI/CD TokenHero tests
digiwand May 17, 2025
58bb12b
fix: test
digiwand May 19, 2025
2f30f45
fix: Staking don't call metric on unknown amountDisplay (async value)
digiwand May 19, 2025
9a25115
fix: staking tests
digiwand May 20, 2025
a59dc1f
refactor: useTokenValue return consistent interface
digiwand May 20, 2025
e06033b
style: rn TokenValues -> TokenAmount
digiwand May 20, 2025
fece399
refactor: rm useTokenAmount "Display" appended key name
digiwand May 20, 2025
4a7b4b7
refactor: enable network badges for transfer confirmations
digiwand May 20, 2025
9288378
style: alphabetize and optional NetworkAssetLogo testID
digiwand May 20, 2025
f9e9d90
refactor: add useTokenAsset displayName
digiwand May 20, 2025
da6a7fa
refactor: allow !fiat value and reorganize switch useTokenAmount useT…
digiwand May 20, 2025
56e1af8
refactor: rm containerAvatarTokenNetworkWithBadge from TokenHero
digiwand May 20, 2025
648511e
Merge branch 'main' into feat-token-hero-erc20-support
digiwand May 20, 2025
10cd8af
fix: use fallback ? if unknown token
digiwand May 20, 2025
b07ef62
feat: support alt bg color TokenHero Unknown
digiwand May 20, 2025
12b4c61
feat: show network badge for all TokenHero
digiwand May 20, 2025
c892d1b
style: TokenHero format selection
digiwand May 20, 2025
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
16 changes: 8 additions & 8 deletions app/components/UI/NetworkAssetLogo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ import { ChainId } from '@metamask/controller-utils';
import TokenIcon from '../Swaps/components/TokenIcon';

interface NetworkAssetLogoProps {
chainId: string;
ticker: string;
style: object;
big: boolean;
biggest: boolean;
testID: string;
chainId: string;
style: object;
ticker: string;
testID?: string;
}

function NetworkAssetLogo({
chainId,
ticker,
style,
big,
biggest,
chainId,
style,
ticker,
testID,
}: NetworkAssetLogoProps) {
if (chainId === ChainId.mainnet) {
Expand All @@ -34,8 +34,8 @@ function NetworkAssetLogo({
<TokenIcon
big={big}
biggest={biggest}
symbol={ticker}
style={style}
symbol={ticker}
testID={testID}
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { StyleSheet } from 'react-native';
import { Theme } from '../../../../../../../../util/theme/models';

export const styleSheet = (params: {
theme: Theme;
}) => {
const { theme } = params;
return StyleSheet.create({
avatarToken: {
backgroundColor: theme.colors.background.default,
borderRadius: 99,
},
base: {
justifyContent: 'center',
flexDirection: 'row',
},
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React from 'react';
import { TransactionMeta } from '@metamask/transaction-controller';
import { Hex } from '@metamask/utils';

import { strings } from '../../../../../../../../../locales/i18n';
import { AvatarSize } from '../../../../../../../../component-library/components/Avatars/Avatar/Avatar.types';
import AvatarToken from '../../../../../../../../component-library/components/Avatars/Avatar/variants/AvatarToken/AvatarToken';
import Badge, {
BadgeVariant,
} from '../../../../../../../../component-library/components/Badges/Badge';
import BadgeWrapper, {
BadgePosition,
} from '../../../../../../../../component-library/components/Badges/BadgeWrapper';
import { useStyles } from '../../../../../../../../component-library/hooks';
import NetworkAssetLogo from '../../../../../../../UI/NetworkAssetLogo';
import { TokenI } from '../../../../../../../UI/Tokens/types';
import useNetworkInfo from '../../../../../hooks/useNetworkInfo';
import { useTokenAsset } from '../../../../../hooks/useTokenAsset';
import { useTransactionMetadataRequest } from '../../../../../hooks/transactions/useTransactionMetadataRequest';
import { styleSheet } from './avatar-token-with-network-badge.styles';
import { View } from 'react-native';

const AvatarTokenOrNetworkAssetLogo = ({
asset,
chainId,
displayName,
}: {
asset: TokenI;
chainId: Hex;
displayName: string;
}) => {
const { styles } = useStyles(styleSheet, {});
const { image, isNative } = asset;
const isUnknownToken = displayName === strings('token.unknown');

return isNative ? (
<NetworkAssetLogo
big
biggest
chainId={chainId}
style={styles.avatarToken}
ticker={displayName}
/>
) : (
<AvatarToken
imageSource={image ? { uri: image } : undefined}
name={isUnknownToken ? undefined : displayName}
size={AvatarSize.Xl}
style={styles.avatarToken}
testID={`avatar-with-badge-avatar-token-${displayName}`}
/>
);
};

export const AvatarTokenWithNetworkBadge = () => {
const { styles } = useStyles(styleSheet, {});
const { chainId } =
useTransactionMetadataRequest() ?? ({} as TransactionMeta);
const { asset, displayName } = useTokenAsset();
const { networkName, networkImage } = useNetworkInfo(chainId);

return (
<View style={styles.base}>
<BadgeWrapper
badgePosition={BadgePosition.BottomRight}
badgeElement={
<Badge
imageSource={networkImage}
name={networkName}
variant={BadgeVariant.Network}
/>
}
>
<AvatarTokenOrNetworkAssetLogo
asset={asset}
chainId={chainId}
displayName={displayName}
/>
</BadgeWrapper>
</View>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AvatarTokenWithNetworkBadge } from './avatar-token-with-network-badge';
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,13 @@ const styleSheet = (params: {
assetAmountText: {
textAlign: 'center',
},
assetTextUnknown: {
color: theme.colors.text.alternative,
},
assetFiatConversionText: {
textAlign: 'center',
color: theme.colors.text.alternative,
},
networkAndTokenContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
networkLogo: {
width: 48,
height: 48,
},
container: {
paddingBottom: 16,
paddingTop: isFlatConfirmation ? 16 : 0,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';

import renderWithProvider, { DeepPartial } from '../../../../../../../util/test/renderWithProvider';
import { stakingDepositConfirmationState } from '../../../../../../../util/test/confirm-data-helpers';
import { stakingDepositConfirmationState, transferConfirmationState } from '../../../../../../../util/test/confirm-data-helpers';
import TokenHero from './token-hero';
import { fireEvent, waitFor } from '@testing-library/react-native';
import { merge } from 'lodash';
Expand All @@ -17,16 +17,52 @@ jest.mock('../../../../../../../core/Engine', () => ({
}));

describe('TokenHero', () => {
it('contains token and fiat values for staking deposit', async () => {
const { getByText } = renderWithProvider(<TokenHero />, {
it('displays avatar, amount, and fiat values for a simple send transfer', async () => {
const state: DeepPartial<RootState> = merge(
{},
transferConfirmationState,
{
engine: {
backgroundState: {
TransactionController: {
transactions: [
{ txParams: { value: `0x${decGWEIToHexWEI(55555555)}` } },
],
},
},
},
},
);
const { getByText, queryByTestId } = renderWithProvider(<TokenHero />, { state });

await waitFor(async () => {
expect(queryByTestId('avatar-with-badge-avatar-token-ETH')).toBeTruthy();
expect(getByText('0.0556 ETH')).toBeDefined();
expect(getByText('$199.79')).toBeDefined();
});

const tokenAmountText = getByText('0.0556 ETH');
fireEvent.press(tokenAmountText);

await waitFor(() => {
expect(getByText('Amount')).toBeDefined();
expect(getByText('0.055555555')).toBeDefined();
});
});

it('displays avatar, amount, and fiat values for staking deposit', async () => {
const { getByText, queryByTestId } = renderWithProvider(<TokenHero />, {
state: stakingDepositConfirmationState,
});

expect(getByText('0.0001 ETH')).toBeDefined();
expect(getByText('$0.36')).toBeDefined();
await waitFor(async () => {
expect(queryByTestId('avatar-with-badge-avatar-token-ETH')).toBeTruthy();
expect(getByText('0.0001 ETH')).toBeDefined();
expect(getByText('$0.36')).toBeDefined();
});
});

it('contains token and fiat values for staking deposit', async () => {
it('displays avatar, rounded amount, amount, and fiat values for staking deposit', async () => {
const state: DeepPartial<RootState> = merge(
{},
stakingDepositConfirmationState,
Expand All @@ -43,13 +79,16 @@ describe('TokenHero', () => {
},
);

const { getByText } = renderWithProvider(
const { getByText, queryByTestId } = renderWithProvider(
<TokenHero />,
{ state },
);

expect(getByText('0.0123 ETH')).toBeDefined();
expect(getByText('$44.40')).toBeDefined();
await waitFor(() => {
expect(queryByTestId('avatar-with-badge-avatar-token-ETH')).toBeTruthy();
expect(getByText('0.0123 ETH')).toBeDefined();
expect(getByText('$44.40')).toBeDefined();
});

const tokenAmountText = getByText('0.0123 ETH');
fireEvent.press(tokenAmountText);
Expand Down
Loading
Loading