Skip to content

Commit 0ec2d2e

Browse files
fix: cp-7.53.0 native token balance updates and optimise controller calls (#18092)
## **Description** Fixes an issue where the native token balances were not updating. Also updated the `AccountTrackerController.refresh` calls we make. The controller patch will be removed once this core package change is released MetaMask/core#6250 ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: fix: native token balance updates and optimise controller calls ## **Related issues** Fixes: #17958 ## **Manual testing steps** Please test native token transfers. 1. On extension, send tokens between accounts 2. On mobile, do you see the native token update after <3 min? Does the "swipe to refresh" update the native token? ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> https://www.loom.com/share/4e09abee586a46bfb584b9ae5adfc7c2?sid=1596d3dc-7e5a-4552-8ac2-bd1c6d9b7420 ### **After** https://www.loom.com/share/f17e067b35d74e71a1002bf177844b8f?sid=72499fc2-a31a-4cc9-b9db-5fd500343a5c <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/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-mobile/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 ebbb3cb commit 0ec2d2e

File tree

7 files changed

+137
-18
lines changed

7 files changed

+137
-18
lines changed

app/components/UI/Tokens/index.test.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@ jest.mock('../../../core/Engine', () => ({
9696
},
9797
},
9898
},
99+
PreferencesController: {
100+
state: {
101+
tokenNetworkFilter: {
102+
'0x00': true,
103+
'0x01': true,
104+
'0x02': true,
105+
},
106+
},
107+
},
99108
},
100109
}));
101110

app/components/UI/Tokens/util/refreshEvmTokens.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ jest.mock('../../../../core/Engine', () => ({
2929
},
3030
},
3131
},
32+
PreferencesController: {
33+
state: {
34+
tokenNetworkFilter: {
35+
'0x1': true,
36+
'0x89': true,
37+
},
38+
},
39+
},
3240
},
3341
}));
3442

app/components/UI/Tokens/util/refreshTokens.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ jest.mock('../../../../core/Engine', () => ({
3030
},
3131
},
3232
},
33+
PreferencesController: {
34+
state: {
35+
tokenNetworkFilter: {
36+
'0x1': true,
37+
'0x89': true,
38+
},
39+
},
40+
},
3341
},
3442
}));
3543

app/components/UI/Tokens/util/tokenRefreshUtils.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ jest.mock('../../../../core/Engine', () => ({
3434
},
3535
},
3636
},
37+
PreferencesController: {
38+
state: {
39+
tokenNetworkFilter: {
40+
'0x1': true,
41+
'0x2': true,
42+
},
43+
},
44+
},
3745
},
3846
}));
3947

app/components/UI/Tokens/util/tokenRefreshUtils.ts

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,42 @@ export const performEvmRefresh = async (
1616
TokenRatesController,
1717
TokenBalancesController,
1818
NetworkController,
19+
PreferencesController,
1920
} = Engine.context;
2021

21-
const networkClientIds = Object.values(
22-
NetworkController.state.networkConfigurationsByChainId,
23-
).map(
24-
(network) =>
25-
network?.rpcEndpoints?.[network.defaultRpcEndpointIndex]?.networkClientId,
26-
);
22+
const tokenListChains = PreferencesController.state.tokenNetworkFilter;
23+
const networkConfigurations =
24+
NetworkController.state.networkConfigurationsByChainId;
25+
26+
const chainIds = Object.keys(tokenListChains) as Hex[];
27+
const networkClientIds = chainIds
28+
.map((c) => {
29+
const config = networkConfigurations[c];
30+
if (!config) {
31+
return undefined;
32+
}
33+
34+
return config?.rpcEndpoints?.[config?.defaultRpcEndpointIndex]
35+
?.networkClientId;
36+
})
37+
.filter((c: string | undefined): c is string => Boolean(c));
2738

2839
const actions = [
2940
TokenDetectionController.detectTokens({
30-
chainIds: Object.keys(evmNetworkConfigurationsByChainId) as Hex[],
41+
chainIds,
3142
}),
3243
TokenBalancesController.updateBalances({
33-
chainIds: Object.keys(evmNetworkConfigurationsByChainId) as Hex[],
44+
chainIds,
3445
}),
3546
AccountTrackerController.refresh(networkClientIds),
3647
CurrencyRateController.updateExchangeRate(nativeCurrencies),
3748
TokenRatesController.updateExchangeRatesByChainId(
38-
Object.values(evmNetworkConfigurationsByChainId).filter(
39-
(n) => n.chainId && n.nativeCurrency,
40-
),
49+
chainIds
50+
.filter((chainId) => {
51+
const config = evmNetworkConfigurationsByChainId[chainId];
52+
return config?.chainId && config?.nativeCurrency;
53+
})
54+
.map((c) => evmNetworkConfigurationsByChainId[c]),
4155
),
4256
];
4357

app/components/Views/Wallet/index.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -654,13 +654,14 @@ const Wallet = ({
654654
requestAnimationFrame(async () => {
655655
const { AccountTrackerController } = Engine.context;
656656

657-
Object.values(evmNetworkConfigurations).forEach(
658-
({ defaultRpcEndpointIndex, rpcEndpoints }) => {
659-
AccountTrackerController.refresh([
657+
const networkClientIDs = Object.values(evmNetworkConfigurations)
658+
.map(
659+
({ defaultRpcEndpointIndex, rpcEndpoints }) =>
660660
rpcEndpoints[defaultRpcEndpointIndex].networkClientId,
661-
]);
662-
},
663-
);
661+
)
662+
.filter((c) => Boolean(c));
663+
664+
AccountTrackerController.refresh(networkClientIDs);
664665
});
665666
},
666667
/* eslint-disable-next-line */

patches/@metamask+assets-controllers+70.0.1.patch renamed to patches/@metamask+assets-controllers+73.0.2.patch

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,74 @@
1+
diff --git a/node_modules/@metamask/assets-controllers/dist/AccountTrackerController.cjs b/node_modules/@metamask/assets-controllers/dist/AccountTrackerController.cjs
2+
index 9749434..fed49f4 100644
3+
--- a/node_modules/@metamask/assets-controllers/dist/AccountTrackerController.cjs
4+
+++ b/node_modules/@metamask/assets-controllers/dist/AccountTrackerController.cjs
5+
@@ -148,27 +148,33 @@ class AccountTrackerController extends (0, polling_controller_1.StaticIntervalPo
6+
this.syncAccounts(chainIds);
7+
// Create an array of promises for each networkClientId
8+
const updatePromises = networkClientIds.map(async (networkClientId) => {
9+
- const { chainId, ethQuery, provider } = __classPrivateFieldGet(this, _AccountTrackerController_instances, "m", _AccountTrackerController_getCorrectNetworkClient).call(this, networkClientId);
10+
+ const { chainId, ethQuery, provider, blockTracker } = __classPrivateFieldGet(this, _AccountTrackerController_instances, "m", _AccountTrackerController_getCorrectNetworkClient).call(this, networkClientId);
11+
const { accountsByChainId } = this.state;
12+
const { isMultiAccountBalancesEnabled } = this.messagingSystem.call('PreferencesController:getState');
13+
const accountsToUpdate = isMultiAccountBalancesEnabled
14+
? Object.keys(accountsByChainId[chainId])
15+
: [(0, controller_utils_1.toChecksumHexAddress)(selectedAccount.address)];
16+
const accountsForChain = { ...accountsByChainId[chainId] };
17+
+ // Force fresh block data before multicall
18+
+ // TODO: This is a temporary fix to ensure that the block number is up to date.
19+
+ // We should remove this once we have a better solution for this on the block tracker controller.
20+
+ await (0, controller_utils_1.safelyExecuteWithTimeout)(() => blockTracker?.checkForLatestBlock?.());
21+
const stakedBalancesPromise = __classPrivateFieldGet(this, _AccountTrackerController_includeStakedAssets, "f")
22+
? __classPrivateFieldGet(this, _AccountTrackerController_getStakedBalanceForChain, "f").call(this, accountsToUpdate, networkClientId)
23+
: Promise.resolve({});
24+
if ((0, utils_1.hasProperty)(AssetsContractController_1.SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID, chainId)) {
25+
const contractAddress = AssetsContractController_1.SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID[chainId];
26+
const contract = new contracts_1.Contract(contractAddress, single_call_balance_checker_abi_1.default, new providers_1.Web3Provider(provider));
27+
- const nativeBalances = await contract.balances(accountsToUpdate, [
28+
+ const nativeBalances = await (0, controller_utils_1.safelyExecuteWithTimeout)(() => contract.balances(accountsToUpdate, [
29+
'0x0000000000000000000000000000000000000000',
30+
- ]);
31+
- accountsToUpdate.forEach((address, index) => {
32+
- accountsForChain[address] = {
33+
- balance: nativeBalances[index].toHexString(),
34+
- };
35+
- });
36+
+ ]), false, 3000);
37+
+ if (nativeBalances) {
38+
+ accountsToUpdate.forEach((address, index) => {
39+
+ accountsForChain[address] = {
40+
+ balance: nativeBalances[index].toHexString(),
41+
+ };
42+
+ });
43+
+ }
44+
}
45+
else {
46+
// Process accounts in batches using reduceInBatchesSerially
47+
@@ -191,8 +197,8 @@ class AccountTrackerController extends (0, polling_controller_1.StaticIntervalPo
48+
},
49+
});
50+
}
51+
- const stakedBalanceResult = (await stakedBalancesPromise);
52+
- Object.entries(stakedBalanceResult).forEach(([address, balance]) => {
53+
+ const stakedBalanceResult = await (0, controller_utils_1.safelyExecuteWithTimeout)(async () => (await stakedBalancesPromise));
54+
+ Object.entries(stakedBalanceResult ?? {}).forEach(([address, balance]) => {
55+
accountsForChain[address] = {
56+
...accountsForChain[address],
57+
stakedBalance: balance,
58+
@@ -269,11 +275,12 @@ _AccountTrackerController_refreshMutex = new WeakMap(), _AccountTrackerControlle
59+
const selectedNetworkClientId = networkClientId ??
60+
this.messagingSystem.call('NetworkController:getState')
61+
.selectedNetworkClientId;
62+
- const { configuration: { chainId }, provider, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
63+
+ const { configuration: { chainId }, provider, blockTracker, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
64+
return {
65+
chainId,
66+
provider,
67+
ethQuery: new eth_query_1.default(provider),
68+
+ blockTracker,
69+
};
70+
}, _AccountTrackerController_getNetworkClientIds = function _AccountTrackerController_getNetworkClientIds() {
71+
const { networkConfigurationsByChainId } = this.messagingSystem.call('NetworkController:getState');
172
diff --git a/node_modules/@metamask/assets-controllers/dist/NftController.cjs b/node_modules/@metamask/assets-controllers/dist/NftController.cjs
273
index 3e7b205..00ad856 100644
374
--- a/node_modules/@metamask/assets-controllers/dist/NftController.cjs
@@ -150,7 +221,7 @@ index 3e7b205..00ad856 100644
150221
}
151222
}
152223
diff --git a/node_modules/@metamask/assets-controllers/dist/NftController.d.cts b/node_modules/@metamask/assets-controllers/dist/NftController.d.cts
153-
index e16e91f..3168b35 100644
224+
index 4a81bbc..6cd5476 100644
154225
--- a/node_modules/@metamask/assets-controllers/dist/NftController.d.cts
155226
+++ b/node_modules/@metamask/assets-controllers/dist/NftController.d.cts
156227
@@ -110,6 +110,7 @@ export type NftMetadata = {

0 commit comments

Comments
 (0)