Skip to content

Commit c1c8fd6

Browse files
authored
fix: token name sort (#31302)
## **Description** We recently decided that we wanted to sort by token name, rather than symbol. The problem is that native tokens for several chains display `Ethereum` when in actuality the name we get from the token API is something like `Linea`. This would cause native tokens on some EVM chains to be miscategorized in sort. This PR overrides the token name for this scenario. It also consolidates the `name` and `title` fields to support both EVM and nonEVM chains. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/31302?quickstart=1) ## **Related issues** Fixes: #31235 ## **Manual testing steps** 1. Please test on both flask and non flask builds. 2. EVM and Solana tokens should now be sorted by their display name (not symbol) 3. Check on both firefox and chrome ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** Before scenarios in bug ticket linked. ### **After** Chrome: <img width="360" alt="Screenshot 2025-03-25 at 12 58 45 PM" src="https://github.com/user-attachments/assets/b5262950-c649-47da-b18c-1b1daa9c5c01" /> <img width="1087" alt="Screenshot 2025-03-25 at 1 01 00 PM" src="https://github.com/user-attachments/assets/a818d72a-22fc-438a-981b-318dc8faedaa" /> Firefox: <img width="539" alt="Screenshot 2025-03-25 at 1 07 11 PM" src="https://github.com/user-attachments/assets/f6a2143d-c4a3-4d83-b0ca-bc943b6ba77f" /> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
1 parent 11a9d98 commit c1c8fd6

File tree

5 files changed

+26
-27
lines changed

5 files changed

+26
-27
lines changed

ui/components/app/assets/asset-list/sort-control/sort-control.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ import {
1818
MetaMetricsEventName,
1919
MetaMetricsUserTrait,
2020
} from '../../../../../../shared/constants/metametrics';
21-
import {
22-
getIsEvmMultichainNetworkSelected,
23-
getTokenSortConfig,
24-
} from '../../../../../selectors';
21+
import { getTokenSortConfig } from '../../../../../selectors';
2522
import { getCurrentCurrency } from '../../../../../ducks/metamask/metamask';
2623
import { useI18nContext } from '../../../../../hooks/useI18nContext';
2724
import { getCurrencySymbol } from '../../../../../helpers/utils/common.util';
@@ -79,7 +76,6 @@ const SortControl = ({ handleClose }: SortControlProps) => {
7976
const trackEvent = useContext(MetaMetricsContext);
8077
const tokenSortConfig = useSelector(getTokenSortConfig);
8178
const currentCurrency = useSelector(getCurrentCurrency);
82-
const isEvmSelected = useSelector(getIsEvmMultichainNetworkSelected);
8379

8480
const dispatch = useDispatch();
8581

@@ -113,7 +109,7 @@ const SortControl = ({ handleClose }: SortControlProps) => {
113109
}
114110
onClick={() =>
115111
// TODO: consolidate name and title fields in token to avoid this switch
116-
handleSort(isEvmSelected ? 'name' : 'title', 'alphaNumeric', 'asc')
112+
handleSort('title', 'alphaNumeric', 'asc')
117113
}
118114
testId="sortByAlphabetically"
119115
>

ui/components/app/assets/token-list/token-list.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,24 +58,17 @@ function TokenList({ onTokenClick }: TokenListProps) {
5858
},
5959
]);
6060

61-
// TODO: consolidate name & title in token fields to avoid this switch
62-
if (tokenSortConfig.sortCallback === 'alphaNumeric') {
63-
return sortAssets([...filteredAssets], {
64-
key: isEvm ? 'name' : 'title',
65-
sortCallback: 'alphaNumeric',
66-
order: 'asc',
67-
});
68-
}
69-
7061
// sort filtered tokens based on the tokenSortConfig in state
7162
return sortAssets([...filteredAssets], tokenSortConfig);
63+
// eslint-disable-next-line react-hooks/exhaustive-deps
7264
}, [
7365
isEvm,
7466
evmBalances,
7567
multichainAssets,
7668
networkFilter,
7769
currentNetwork.chainId,
7870
tokenSortConfig,
71+
// newTokensImported included in deps, but not in hook's logic
7972
newTokensImported,
8073
]);
8174

ui/components/app/assets/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export type NonEvmBaseToken = {
3535
// Token type with optional aggregators
3636
export type Token = (BaseToken | NonEvmBaseToken) & {
3737
aggregators?: string[];
38+
name?: string;
3839
};
3940

4041
// Token with balance and optional display values

ui/hooks/useMultichainBalances.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ describe('useMultichainBalances', () => {
2929
secondary: 0,
3030
string: '0.000000000000000014',
3131
symbol: 'ETH',
32-
title: '',
32+
title: 'Ethereum',
3333
tokenFiatAmount: 3.53395e-14,
3434
type: 'NATIVE',
3535
},
@@ -45,7 +45,7 @@ describe('useMultichainBalances', () => {
4545
secondary: 0,
4646
string: '0.00000000000000001',
4747
symbol: 'ETH',
48-
title: '',
48+
title: 'Ethereum',
4949
tokenFiatAmount: 2.5242500000000003e-14,
5050
type: 'NATIVE',
5151
},
@@ -72,7 +72,7 @@ describe('useMultichainBalances', () => {
7272
primary: '',
7373
secondary: 0,
7474
string: '0.00184',
75-
title: '',
75+
title: undefined,
7676
tokenFiatAmount: 0.004232,
7777
type: 'TOKEN',
7878
},
@@ -88,7 +88,7 @@ describe('useMultichainBalances', () => {
8888
secondary: 0,
8989
string: '0.000000000000000014',
9090
symbol: 'ETH',
91-
title: '',
91+
title: 'Ethereum',
9292
tokenFiatAmount: 3.53395e-14,
9393
type: 'NATIVE',
9494
},
@@ -104,7 +104,7 @@ describe('useMultichainBalances', () => {
104104
secondary: 0,
105105
string: '0.00000000000000001',
106106
symbol: 'ETH',
107-
title: '',
107+
title: 'Ethereum',
108108
tokenFiatAmount: 2.5242500000000003e-14,
109109
type: 'NATIVE',
110110
},
@@ -113,24 +113,24 @@ describe('useMultichainBalances', () => {
113113
balance: '1',
114114
chainId: '0x1',
115115
isNative: false,
116+
primary: '',
117+
secondary: 0,
116118
string: '1',
119+
title: undefined,
117120
tokenFiatAmount: null,
118121
type: 'TOKEN',
119-
primary: '',
120-
secondary: 0,
121-
title: '',
122122
},
123123
{
124124
address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
125125
balance: '0',
126126
chainId: '0xe708',
127127
isNative: false,
128+
primary: '',
129+
secondary: 0,
128130
string: '0',
131+
title: undefined,
129132
tokenFiatAmount: null,
130133
type: 'TOKEN',
131-
primary: '',
132-
secondary: 0,
133-
title: '',
134134
},
135135
]),
136136
);

ui/selectors/assets.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export const getTokenBalancesEvm = createDeepEqualSelector(
106106
const tokenList = tokens as Token[];
107107
tokenList.forEach((token: Token) => {
108108
const { isNative, address, decimals } = token;
109+
109110
const balance =
110111
calculateTokenBalance({
111112
isNative,
@@ -138,6 +139,14 @@ export const getTokenBalancesEvm = createDeepEqualSelector(
138139
balance !== '0' ||
139140
(token.isNative && isOnCurrentNetwork)
140141
) {
142+
// title is used for sorting. We override native ETH to Ethereum
143+
let title;
144+
if (token.isNative) {
145+
title = token.symbol === 'ETH' ? 'Ethereum' : token.symbol;
146+
} else {
147+
title = token.name || token.symbol;
148+
}
149+
141150
tokensWithBalance.push({
142151
...token,
143152
address: token.address as CaipAssetType,
@@ -147,7 +156,7 @@ export const getTokenBalancesEvm = createDeepEqualSelector(
147156
string: String(balance),
148157
primary: '',
149158
secondary: 0,
150-
title: '',
159+
title,
151160
});
152161
}
153162
});

0 commit comments

Comments
 (0)