Skip to content

Commit 07d4265

Browse files
bergerongambinish
andauthored
feat: only poll popular networks (#29071)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** To reduce the impact of showing assets across all networks, which can be unbounded, this PR scopes the portfolio view to the 9 popular networks built into metamask. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/29071?quickstart=1) ## **Related issues** Fixes: #29055 ## **Manual testing steps** 1. On popular networks: - The token filter should allow switching between popular networks and current network - The filter should work as described - RPC requests in the background should only hit the popular networks 2. On other networks - The token filter should become disabled and scoped to the current network - RPC requests in the background should only hit the current network ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] 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). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] 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. --------- Co-authored-by: Nicholas Gambino <[email protected]>
1 parent 5f8af0e commit 07d4265

File tree

10 files changed

+73
-35
lines changed

10 files changed

+73
-35
lines changed

app/_locales/en/messages.json

+6-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

shared/constants/network.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,11 @@ export const FEATURED_RPCS: AddNetworkFields[] = [
10961096
},
10971097
];
10981098

1099+
export const FEATURED_NETWORK_CHAIN_IDS = [
1100+
CHAIN_IDS.MAINNET,
1101+
...FEATURED_RPCS.map((rpc) => rpc.chainId),
1102+
];
1103+
10991104
export const infuraChainIdsTestNets: string[] = [
11001105
CHAIN_IDS.SEPOLIA,
11011106
CHAIN_IDS.HOLESKY,

test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json

-6
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,6 @@
242242
"tokenSortConfig": "object",
243243
"shouldShowAggregatedBalancePopover": "boolean",
244244
"tokenNetworkFilter": {
245-
"0x1": "boolean",
246-
"0xaa36a7": "boolean",
247-
"0xe705": "boolean",
248-
"0xe708": "boolean",
249245
"0x539": "boolean"
250246
},
251247
"redesignedConfirmationsEnabled": true,
@@ -334,8 +330,6 @@
334330
"TokenListController": {
335331
"tokenList": "object",
336332
"tokensChainsCache": {
337-
"0x1": "object",
338-
"0xe708": "object",
339333
"0x539": "object"
340334
},
341335
"preventPollingOnNetworkRestart": false

test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json

-6
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@
3838
"tokenSortConfig": "object",
3939
"shouldShowAggregatedBalancePopover": "boolean",
4040
"tokenNetworkFilter": {
41-
"0x1": "boolean",
42-
"0xaa36a7": "boolean",
43-
"0xe705": "boolean",
44-
"0xe708": "boolean",
4541
"0x539": "boolean"
4642
},
4743
"redesignedConfirmationsEnabled": true,
@@ -180,8 +176,6 @@
180176
"nonRPCGasFeeApisDisabled": "boolean",
181177
"tokenList": "object",
182178
"tokensChainsCache": {
183-
"0x1": "object",
184-
"0xe708": "object",
185179
"0x539": "object"
186180
},
187181
"preventPollingOnNetworkRestart": false,

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

+14-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useEffect, useRef, useState, useContext, useMemo } from 'react';
22
import { useDispatch, useSelector } from 'react-redux';
33
import {
44
getCurrentNetwork,
5+
getIsTokenNetworkFilterEqualCurrentNetwork,
56
getTokenNetworkFilter,
67
} from '../../../../../selectors';
78
import { getNetworkConfigurationsByChainId } from '../../../../../../shared/modules/selectors/networks';
@@ -26,7 +27,10 @@ import {
2627
import ImportControl from '../import-control';
2728
import { useI18nContext } from '../../../../../hooks/useI18nContext';
2829
import { MetaMetricsContext } from '../../../../../contexts/metametrics';
29-
import { TEST_CHAINS } from '../../../../../../shared/constants/network';
30+
import {
31+
FEATURED_NETWORK_CHAIN_IDS,
32+
TEST_CHAINS,
33+
} from '../../../../../../shared/constants/network';
3034
import {
3135
MetaMetricsEventCategory,
3236
MetaMetricsEventName,
@@ -57,6 +61,9 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => {
5761
const popoverRef = useRef<HTMLDivElement>(null);
5862
const currentNetwork = useSelector(getCurrentNetwork);
5963
const allNetworks = useSelector(getNetworkConfigurationsByChainId);
64+
const isTokenNetworkFilterEqualCurrentNetwork = useSelector(
65+
getIsTokenNetworkFilterEqualCurrentNetwork,
66+
);
6067

6168
const tokenNetworkFilter = useSelector(getTokenNetworkFilter);
6269
const [isTokenSortPopoverOpen, setIsTokenSortPopoverOpen] = useState(false);
@@ -74,10 +81,6 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => {
7481
allOpts[chainId] = true;
7582
});
7683

77-
const allNetworksFilterShown =
78-
Object.keys(tokenNetworkFilter).length !==
79-
Object.keys(allOpts || {}).length;
80-
8184
useEffect(() => {
8285
if (isTestNetwork) {
8386
const testnetFilter = { [currentNetwork.chainId]: true };
@@ -175,7 +178,10 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => {
175178
className="asset-list-control-bar__button asset-list-control-bar__network_control"
176179
onClick={toggleNetworkFilterPopover}
177180
size={ButtonBaseSize.Sm}
178-
disabled={isTestNetwork}
181+
disabled={
182+
isTestNetwork ||
183+
!FEATURED_NETWORK_CHAIN_IDS.includes(currentNetwork.chainId)
184+
}
179185
endIconName={IconName.ArrowDown}
180186
backgroundColor={
181187
isNetworkFilterPopoverOpen
@@ -186,9 +192,9 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => {
186192
marginRight={isFullScreen ? 2 : null}
187193
ellipsis
188194
>
189-
{allNetworksFilterShown
195+
{isTokenNetworkFilterEqualCurrentNetwork
190196
? currentNetwork?.nickname ?? t('currentNetwork')
191-
: t('allNetworks')}
197+
: t('popularNetworks')}
192198
</ButtonBase>
193199
)}
194200

ui/components/app/assets/asset-list/network-filter/network-filter.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => {
119119
variant={TextVariant.bodyMdMedium}
120120
color={TextColor.textDefault}
121121
>
122-
{t('allNetworks')}
122+
{t('popularNetworks')}
123123
</Text>
124124
<Text
125125
variant={TextVariant.bodySmMedium}

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import TokenCell from '../token-cell';
55
import { TEST_CHAINS } from '../../../../../shared/constants/network';
66
import { sortAssets } from '../util/sort';
77
import {
8+
getChainIdsToPoll,
89
getCurrencyRates,
910
getCurrentNetwork,
1011
getIsTestnet,
@@ -93,6 +94,7 @@ export default function TokenList({
9394
const tokenNetworkFilter = useSelector(getTokenNetworkFilter);
9495
const selectedAccount = useSelector(getSelectedAccount);
9596
const conversionRate = useSelector(getConversionRate);
97+
const chainIdsToPoll = useSelector(getChainIdsToPoll);
9698
const contractExchangeRates = useSelector(
9799
getTokenExchangeRates,
98100
shallowEqual,
@@ -103,7 +105,9 @@ export default function TokenList({
103105
getIsTokenNetworkFilterEqualCurrentNetwork,
104106
);
105107

106-
const { tokenBalances } = useTokenBalances();
108+
const { tokenBalances } = useTokenBalances({
109+
chainIds: chainIdsToPoll as Hex[],
110+
});
107111
const selectedAccountTokenBalancesAcrossChains =
108112
tokenBalances[selectedAccount.address];
109113

ui/components/multichain/network-list-menu/network-list-menu.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import {
5454
getAllDomains,
5555
getPermittedChainsForSelectedTab,
5656
getPermittedAccountsForSelectedTab,
57-
getTokenNetworkFilter,
57+
getPreferences,
5858
} from '../../../selectors';
5959
import ToggleButton from '../../ui/toggle-button';
6060
import {
@@ -116,7 +116,7 @@ export const NetworkListMenu = ({ onClose }: { onClose: () => void }) => {
116116
const dispatch = useDispatch();
117117
const trackEvent = useContext(MetaMetricsContext);
118118

119-
const tokenNetworkFilter = useSelector(getTokenNetworkFilter);
119+
const { tokenNetworkFilter } = useSelector(getPreferences);
120120
const showTestNetworks = useSelector(getShowTestNetworks);
121121
const currentChainId = useSelector(getCurrentChainId);
122122
const selectedTabOrigin = useSelector(getOriginOfCurrentTab);
@@ -294,7 +294,7 @@ export const NetworkListMenu = ({ onClose }: { onClose: () => void }) => {
294294

295295
// as a user, I don't want my network selection to force update my filter when I have "All Networks" toggled on
296296
// however, if I am already filtered on "Current Network", we'll want to filter by the selected network when the network changes
297-
if (Object.keys(tokenNetworkFilter).length <= 1) {
297+
if (Object.keys(tokenNetworkFilter || {}).length <= 1) {
298298
dispatch(setTokenNetworkFilter({ [network.chainId]: true }));
299299
} else if (process.env.PORTFOLIO_VIEW) {
300300
dispatch(setTokenNetworkFilter(allOpts));

ui/pages/asset/components/asset-page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ const AssetPage = ({
139139
getSelectedAccountNativeTokenCachedBalanceByChainId,
140140
) as Record<Hex, Hex>;
141141

142-
const { tokenBalances } = useTokenBalances();
142+
const { tokenBalances } = useTokenBalances({ chainIds: [chainId] });
143143
const selectedAccountTokenBalancesAcrossChains =
144144
tokenBalances[selectedAccount.address];
145145

ui/selectors/selectors.js

+38-4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import {
4949
MOONBEAM_DISPLAY_NAME,
5050
MOONRIVER_DISPLAY_NAME,
5151
TEST_NETWORK_IDS,
52+
FEATURED_NETWORK_CHAIN_IDS,
5253
} from '../../shared/constants/network';
5354
import {
5455
WebHIDConnectedStatuses,
@@ -1086,9 +1087,35 @@ export function getIsTokenNetworkFilterEqualCurrentNetwork(state) {
10861087
return false;
10871088
}
10881089

1090+
/**
1091+
* Returns an object indicating which networks
1092+
* tokens should be shown on in the portfolio view.
1093+
*
1094+
* @param {*} state
1095+
* @returns {Record<Hex, boolean>}
1096+
*/
10891097
export function getTokenNetworkFilter(state) {
1098+
const currentChainId = getCurrentChainId(state);
10901099
const { tokenNetworkFilter } = getPreferences(state);
1091-
return tokenNetworkFilter || {};
1100+
1101+
// Portfolio view not enabled outside popular networks
1102+
if (
1103+
!process.env.PORTFOLIO_VIEW ||
1104+
!FEATURED_NETWORK_CHAIN_IDS.includes(currentChainId)
1105+
) {
1106+
return { [currentChainId]: true };
1107+
}
1108+
1109+
// Portfolio view only enabled on featured networks
1110+
return Object.entries(tokenNetworkFilter || {}).reduce(
1111+
(acc, [chainId, value]) => {
1112+
if (FEATURED_NETWORK_CHAIN_IDS.includes(chainId)) {
1113+
acc[chainId] = value;
1114+
}
1115+
return acc;
1116+
},
1117+
{},
1118+
);
10921119
}
10931120

10941121
export function getUseTransactionSimulations(state) {
@@ -2364,7 +2391,9 @@ export const getAllChainsToPoll = createDeepEqualSelector(
23642391
}
23652392

23662393
return Object.keys(networkConfigurations).filter(
2367-
(chainId) => chainId === currentChainId || !TEST_CHAINS.includes(chainId),
2394+
(chainId) =>
2395+
chainId === currentChainId ||
2396+
FEATURED_NETWORK_CHAIN_IDS.includes(chainId),
23682397
);
23692398
},
23702399
);
@@ -2386,7 +2415,9 @@ export const getChainIdsToPoll = createDeepEqualSelector(
23862415
}
23872416

23882417
return Object.keys(networkConfigurations).filter(
2389-
(chainId) => chainId === currentChainId || !TEST_CHAINS.includes(chainId),
2418+
(chainId) =>
2419+
chainId === currentChainId ||
2420+
FEATURED_NETWORK_CHAIN_IDS.includes(chainId),
23902421
);
23912422
},
23922423
);
@@ -2414,7 +2445,10 @@ export const getNetworkClientIdsToPoll = createDeepEqualSelector(
24142445

24152446
return Object.entries(networkConfigurations).reduce(
24162447
(acc, [chainId, network]) => {
2417-
if (chainId === currentChainId || !TEST_CHAINS.includes(chainId)) {
2448+
if (
2449+
chainId === currentChainId ||
2450+
FEATURED_NETWORK_CHAIN_IDS.includes(chainId)
2451+
) {
24182452
acc.push(
24192453
network.rpcEndpoints[network.defaultRpcEndpointIndex]
24202454
.networkClientId,

0 commit comments

Comments
 (0)