-
-
Notifications
You must be signed in to change notification settings - Fork 249
feat: use aggregate3 or accountAPI to fetch balances #6232
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
feat: use aggregate3 or accountAPI to fetch balances #6232
Conversation
9d24a01
to
28235f7
Compare
1ca38cc
to
a830bd8
Compare
if (includeStakedAssets) { | ||
await this.refreshStakedBalances(networkClientIds); | ||
} | ||
if (includeNativeAssets) { | ||
await this.refreshNativeBalances(networkClientIds); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice separation here. Only caveat is that both of these have independent state updates. Meaning we could end up with multiple state updates (if we need to update staked assets then native assets).
This is a minor nit, we can clean up any additional state updates in a future design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(discuss) why are we including changes in the AccountTrackerController? I thought the new design would have everything in the TokenBalancesController?
* @param includeStaked - Whether to include staked balances | ||
* @returns Map of token address to map of user address to balance | ||
*/ | ||
const processBalanceResults = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guessing these changes are the same as this PR:
#6212
chainId: ChainIdHex; | ||
}; | ||
|
||
export type BalanceFetcher = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this meant to be a shared interface between different BalanceFetchers?
@metamaskbot publish-preview |
Preview builds have been published. See these instructions for more information about preview builds. Expand for full list of packages and versions.
|
89a94d5
to
cd0d817
Compare
expect(refreshSpy).toHaveBeenCalledTimes(5); | ||
expect(refreshSpy).toHaveBeenNthCalledWith(3, [networkClientId1]); | ||
expect(refreshSpy).toHaveBeenNthCalledWith(3, [networkClientId1]); | ||
expect(refreshSpy).toHaveBeenCalledTimes(3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Duplicate Spy Call Verification
A test expects refreshSpy.toHaveBeenNthCalledWith(3, [networkClientId1])
twice consecutively. This is logically impossible as a spy call can only occur once for a given call number, causing the test to fail. The second expectation should likely target a different call number or arguments.
account: acct as ChecksumAddress, | ||
token: checksum(tokenAddr), | ||
chainId, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Null Balance Handling Fails
The RpcBalanceFetcher
's fetch
method incorrectly casts null
balance values to BN
type. While the success
flag correctly reflects a null
balance, the value
property is unconditionally cast as BN
. This creates ProcessedBalance
objects where success
is false
but value
is null
(typed as BN
), violating the value?: BN
type definition and potentially causing runtime errors.
} | ||
if (includeNativeAssets) { | ||
await this.refreshNativeBalances(networkClientIds); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Balance Refresh Flags Required
The _executePoll
method in AccountTrackerController
no longer updates account balances by default. It now conditionally calls refreshStakedBalances
and refreshNativeBalances
only if includeStakedAssets
or includeNativeAssets
flags are explicitly set to true
in AccountTrackerPollingInput
. As these flags are optional, existing callers that do not specify them will result in undefined
values, causing no balance updates to occur. This is a breaking change from the previous behavior where _executePoll
always refreshed all balances.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Multicall Contract Missing on Fraxtal Chain
The multicall contract address for Fraxtal (chain ID 0xfc
/ 252) was unintentionally removed from the MULTICALL_CONTRACT_BY_CHAINID
map. This breaks multicall functionality for Fraxtal users, forcing them to rely on less efficient individual RPC calls.
packages/assets-controllers/src/multicall.ts#L200-L201
core/packages/assets-controllers/src/multicall.ts
Lines 200 to 201 in 01db552
'0x12c': '0xF9cda624FBC7e059355ce98a31693d299FACd963', | |
'0x18995f': '0xF9cda624FBC7e059355ce98a31693d299FACd963', |
01db552
to
8fbdbfa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Fraxtal Network Multicall Support Broken
The entry for Fraxtal (chain ID 0xfc
) was unintentionally removed from the MULTICALL_CONTRACT_BY_CHAINID
map. This breaks multicall support for the Fraxtal network, forcing it to fall back to less efficient individual RPC calls. The removal appears accidental, as noted by a PR reviewer's comment "was this meant to be nuked?".
packages/assets-controllers/src/multicall.ts#L200-L201
core/packages/assets-controllers/src/multicall.ts
Lines 200 to 201 in 8fbdbfa
'0x12c': '0xF9cda624FBC7e059355ce98a31693d299FACd963', | |
'0x18995f': '0xF9cda624FBC7e059355ce98a31693d299FACd963', |
8fbdbfa
to
4830bdb
Compare
4830bdb
to
23561b1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Multicall Contract Missing for Fraxtal Mainnet
The multicall contract address for Fraxtal Mainnet (chain ID 0xfc
/ 252) was accidentally removed from MULTICALL_CONTRACT_BY_CHAINID
. This omission, questioned by a PR reviewer, disables multicall functionality for Fraxtal, causing getTokenBalancesForMultipleAddresses
to fall back to less efficient individual RPC calls.
packages/assets-controllers/src/multicall.ts#L200-L201
core/packages/assets-controllers/src/multicall.ts
Lines 200 to 201 in 23561b1
'0x12c': '0xF9cda624FBC7e059355ce98a31693d299FACd963', | |
'0x18995f': '0xF9cda624FBC7e059355ce98a31693d299FACd963', |
@metamaskbot publish-preview |
Preview builds have been published. See these instructions for more information about preview builds. Expand for full list of packages and versions.
|
23561b1
to
494b74f
Compare
@metamaskbot publish-preview |
You're absolutely right! Let me update that section to be more precise about the fallback strategy:
Explanation
Current State and Problem
Previously, the TokenBalancesController fetched token balances using individual RPC calls for each token-account combination. This approach was inefficient and slow, especially for users with multiple accounts and many tokens across different networks. Each balance check required a separate
balanceOf
call, leading to:Solution
This PR implements a two-tier balance fetching strategy with intelligent fallback:
aggregate3
function for efficient batch RPC calls when:Key Technical Changes
Smart Fallback Architecture
TokenBalancesController
first attempts to fetch balances via the Accounts API for supported networksaggregate3
Accounts API Integration
SUPPORTED_NETWORKS_ACCOUNTS_API_V4
)Aggregate3 Fallback Implementation
When the Accounts API can't handle certain networks, the system uses Multicall3's
aggregate3
function to:balanceOf
calls into a single RPC requestPerformance Optimizations
Technical Details
The fallback mechanism ensures comprehensive network coverage:
aggregate3
(still much faster than individual calls)The
aggregate3
function provides significant improvements over individual RPC calls:allowFailure: true
)Impact
References
Addresses performance issues with token balance fetching by implementing Accounts API integration with aggregate3 RPC fallback for comprehensive and efficient balance retrieval across all networks.
Checklist