@metamask-previews/assets-controllers 73.0.1-preview-bf50b46b → 73.0.1-preview-e4e5ca5c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +1 -13
  2. package/dist/AccountTrackerController.cjs +5 -167
  3. package/dist/AccountTrackerController.cjs.map +1 -1
  4. package/dist/AccountTrackerController.d.cts +2 -14
  5. package/dist/AccountTrackerController.d.cts.map +1 -1
  6. package/dist/AccountTrackerController.d.mts +2 -14
  7. package/dist/AccountTrackerController.d.mts.map +1 -1
  8. package/dist/AccountTrackerController.mjs +5 -167
  9. package/dist/AccountTrackerController.mjs.map +1 -1
  10. package/dist/TokenBalancesController.cjs +321 -267
  11. package/dist/TokenBalancesController.cjs.map +1 -1
  12. package/dist/TokenBalancesController.d.cts +93 -51
  13. package/dist/TokenBalancesController.d.cts.map +1 -1
  14. package/dist/TokenBalancesController.d.mts +93 -51
  15. package/dist/TokenBalancesController.d.mts.map +1 -1
  16. package/dist/TokenBalancesController.mjs +320 -270
  17. package/dist/TokenBalancesController.mjs.map +1 -1
  18. package/dist/assetsUtil.cjs +1 -13
  19. package/dist/assetsUtil.cjs.map +1 -1
  20. package/dist/assetsUtil.d.cts +0 -8
  21. package/dist/assetsUtil.d.cts.map +1 -1
  22. package/dist/assetsUtil.d.mts +0 -8
  23. package/dist/assetsUtil.d.mts.map +1 -1
  24. package/dist/assetsUtil.mjs +1 -12
  25. package/dist/assetsUtil.mjs.map +1 -1
  26. package/dist/constants.cjs +1 -12
  27. package/dist/constants.cjs.map +1 -1
  28. package/dist/constants.d.cts +0 -1
  29. package/dist/constants.d.cts.map +1 -1
  30. package/dist/constants.d.mts +0 -1
  31. package/dist/constants.d.mts.map +1 -1
  32. package/dist/constants.mjs +0 -11
  33. package/dist/constants.mjs.map +1 -1
  34. package/dist/index.cjs +3 -3
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +3 -2
  37. package/dist/index.d.cts.map +1 -1
  38. package/dist/index.d.mts +3 -2
  39. package/dist/index.d.mts.map +1 -1
  40. package/dist/index.mjs +1 -1
  41. package/dist/index.mjs.map +1 -1
  42. package/dist/multi-chain-accounts-service/multi-chain-accounts.cjs +1 -35
  43. package/dist/multi-chain-accounts-service/multi-chain-accounts.cjs.map +1 -1
  44. package/dist/multi-chain-accounts-service/multi-chain-accounts.d.cts +0 -16
  45. package/dist/multi-chain-accounts-service/multi-chain-accounts.d.cts.map +1 -1
  46. package/dist/multi-chain-accounts-service/multi-chain-accounts.d.mts +0 -16
  47. package/dist/multi-chain-accounts-service/multi-chain-accounts.d.mts.map +1 -1
  48. package/dist/multi-chain-accounts-service/multi-chain-accounts.mjs +0 -33
  49. package/dist/multi-chain-accounts-service/multi-chain-accounts.mjs.map +1 -1
  50. package/dist/multi-chain-accounts-service/types.cjs.map +1 -1
  51. package/dist/multi-chain-accounts-service/types.d.cts +0 -8
  52. package/dist/multi-chain-accounts-service/types.d.cts.map +1 -1
  53. package/dist/multi-chain-accounts-service/types.d.mts +0 -8
  54. package/dist/multi-chain-accounts-service/types.d.mts.map +1 -1
  55. package/dist/multi-chain-accounts-service/types.mjs.map +1 -1
  56. package/dist/multicall.cjs +22 -397
  57. package/dist/multicall.cjs.map +1 -1
  58. package/dist/multicall.d.cts +0 -39
  59. package/dist/multicall.d.cts.map +1 -1
  60. package/dist/multicall.d.mts +0 -39
  61. package/dist/multicall.d.mts.map +1 -1
  62. package/dist/multicall.mjs +21 -398
  63. package/dist/multicall.mjs.map +1 -1
  64. package/dist/selectors/balanceSelectors.cjs +275 -0
  65. package/dist/selectors/balanceSelectors.cjs.map +1 -0
  66. package/dist/selectors/balanceSelectors.d.cts +248 -0
  67. package/dist/selectors/balanceSelectors.d.cts.map +1 -0
  68. package/dist/selectors/balanceSelectors.d.mts +248 -0
  69. package/dist/selectors/balanceSelectors.d.mts.map +1 -0
  70. package/dist/selectors/balanceSelectors.mjs +268 -0
  71. package/dist/selectors/balanceSelectors.mjs.map +1 -0
  72. package/package.json +6 -3
  73. package/dist/multi-chain-accounts-service/api-balance-fetcher.cjs +0 -98
  74. package/dist/multi-chain-accounts-service/api-balance-fetcher.cjs.map +0 -1
  75. package/dist/multi-chain-accounts-service/api-balance-fetcher.d.cts +0 -28
  76. package/dist/multi-chain-accounts-service/api-balance-fetcher.d.cts.map +0 -1
  77. package/dist/multi-chain-accounts-service/api-balance-fetcher.d.mts +0 -28
  78. package/dist/multi-chain-accounts-service/api-balance-fetcher.d.mts.map +0 -1
  79. package/dist/multi-chain-accounts-service/api-balance-fetcher.mjs +0 -98
  80. package/dist/multi-chain-accounts-service/api-balance-fetcher.mjs.map +0 -1
  81. package/dist/rpc-service/rpc-balance-fetcher.cjs +0 -128
  82. package/dist/rpc-service/rpc-balance-fetcher.cjs.map +0 -1
  83. package/dist/rpc-service/rpc-balance-fetcher.d.cts +0 -34
  84. package/dist/rpc-service/rpc-balance-fetcher.d.cts.map +0 -1
  85. package/dist/rpc-service/rpc-balance-fetcher.d.mts +0 -34
  86. package/dist/rpc-service/rpc-balance-fetcher.d.mts.map +0 -1
  87. package/dist/rpc-service/rpc-balance-fetcher.mjs +0 -124
  88. package/dist/rpc-service/rpc-balance-fetcher.mjs.map +0 -1
  89. package/dist/selectors.cjs +0 -64
  90. package/dist/selectors.cjs.map +0 -1
  91. package/dist/selectors.d.cts +0 -51
  92. package/dist/selectors.d.cts.map +0 -1
  93. package/dist/selectors.d.mts +0 -51
  94. package/dist/selectors.d.mts.map +0 -1
  95. package/dist/selectors.mjs +0 -61
  96. package/dist/selectors.mjs.map +0 -1
@@ -1,13 +1,4 @@
1
- function $importDefault(module) {
2
- if (module?.__esModule) {
3
- return module.default;
4
- }
5
- return module;
6
- }
7
1
  import { Contract } from "@ethersproject/contracts";
8
- import $BN from "bn.js";
9
- const BN = $importDefault($BN);
10
- import { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from "./AssetsContractController.mjs";
11
2
  import { reduceInBatchesSerially } from "./assetsUtil.mjs";
12
3
  // https://github.com/mds1/multicall/blob/main/deployments.json
13
4
  const MULTICALL_CONTRACT_BY_CHAINID = {
@@ -136,7 +127,7 @@ const MULTICALL_CONTRACT_BY_CHAINID = {
136
127
  '0x96f': '0xcA11bde05977b3631167028862bE2a173976CA11',
137
128
  '0x3cc5': '0xcA11bde05977b3631167028862bE2a173976CA11',
138
129
  '0x4571': '0xcA11bde05977b3631167028862bE2a173976CA11',
139
- '0xe99': '0xca11bde05977b3631167028862be2a173976ca11',
130
+ '0xe99': '0xcA11bde05977b3631167028862bE2a173976CA11',
140
131
  '0x7d0': '0xcA11bde05977b3631167028862bE2a173976CA11',
141
132
  '0x1297': '0xcA11bde05977b3631167028862bE2a173976CA11',
142
133
  '0x1d5e': '0xcA11bde05977b3631167028862bE2a173976CA11',
@@ -198,11 +189,30 @@ const MULTICALL_CONTRACT_BY_CHAINID = {
198
189
  '0xa1337': '0xcA11bde05977b3631167028862bE2a173976CA11',
199
190
  '0x1f2b': '0xcA11bde05977b3631167028862bE2a173976CA11',
200
191
  '0xf63': '0xcA11bde05977b3631167028862bE2a173976CA11',
201
- '0x144': '0xcA11bde05977b3631167028862bE2a173976CA11',
192
+ '0x144': '0xF9cda624FBC7e059355ce98a31693d299FACd963',
202
193
  '0x118': '0xF9cda624FBC7e059355ce98a31693d299FACd963',
203
194
  '0x12c': '0xF9cda624FBC7e059355ce98a31693d299FACd963',
204
195
  '0x18995f': '0xF9cda624FBC7e059355ce98a31693d299FACd963',
205
196
  '0x2b74': '0xF9cda624FBC7e059355ce98a31693d299FACd963',
197
+ '0xfc': '0xcA11bde05977b3631167028862bE2a173976CA11',
198
+ '0x9da': '0xcA11bde05977b3631167028862bE2a173976CA11',
199
+ '0x137': '0xcA11bde05977b3631167028862bE2a173976CA11',
200
+ '0x13ed': '0xcA11bde05977b3631167028862bE2a173976CA11',
201
+ '0x24b1': '0xcA11bde05977b3631167028862bE2a173976CA11',
202
+ '0xba9302': '0xcA11bde05977b3631167028862bE2a173976CA11',
203
+ '0x7c8': '0xcA11bde05977b3631167028862bE2a173976CA11',
204
+ '0x138d5': '0xcA11bde05977b3631167028862bE2a173976CA11',
205
+ '0x6d': '0xcA11bde05977b3631167028862bE2a173976CA11',
206
+ '0x343b': '0xcA11bde05977b3631167028862bE2a173976CA11',
207
+ '0x34a1': '0xcA11bde05977b3631167028862bE2a173976CA11',
208
+ '0x3109': '0xcA11bde05977b3631167028862bE2a173976CA11',
209
+ '0x91b': '0xcA11bde05977b3631167028862bE2a173976CA11',
210
+ '0xa96': '0xcA11bde05977b3631167028862bE2a173976CA11',
211
+ '0x22c3': '0xcA11bde05977b3631167028862bE2a173976CA11',
212
+ '0x2be3': '0xcA11bde05977b3631167028862bE2a173976CA11',
213
+ '0xbf03': '0xcA11bde05977b3631167028862bE2a173976CA11',
214
+ '0x1b254': '0xcA11bde05977b3631167028862bE2a173976CA11',
215
+ '0xa7b14': '0xcA11bde05977b3631167028862bE2a173976CA11',
206
216
  '0x2276': '0xcA11bde05977b3631167028862bE2a173976CA11',
207
217
  '0x1b9e': '0xcA11bde05977b3631167028862bE2a173976CA11',
208
218
  '0x6a63bb8': '0xcA11bde05977b3631167028862bE2a173976CA11',
@@ -272,70 +282,6 @@ const multicallAbi = [
272
282
  ],
273
283
  },
274
284
  ];
275
- // Multicall3 ABI for aggregate3 function
276
- const multicall3Abi = [
277
- {
278
- name: 'aggregate3',
279
- type: 'function',
280
- stateMutability: 'payable',
281
- inputs: [
282
- {
283
- name: 'calls',
284
- type: 'tuple[]',
285
- components: [
286
- { name: 'target', type: 'address' },
287
- { name: 'allowFailure', type: 'bool' },
288
- { name: 'callData', type: 'bytes' },
289
- ],
290
- },
291
- ],
292
- outputs: [
293
- {
294
- name: 'returnData',
295
- type: 'tuple[]',
296
- components: [
297
- { name: 'success', type: 'bool' },
298
- { name: 'returnData', type: 'bytes' },
299
- ],
300
- },
301
- ],
302
- },
303
- ];
304
- // Constants for encoded strings and addresses
305
- const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
306
- const BALANCE_OF_FUNCTION = 'balanceOf(address)';
307
- const GET_ETH_BALANCE_FUNCTION = 'getEthBalance';
308
- const GET_SHARES_FUNCTION = 'getShares';
309
- // ERC20 balanceOf ABI
310
- const ERC20_BALANCE_OF_ABI = [
311
- {
312
- name: 'balanceOf',
313
- type: 'function',
314
- inputs: [{ name: 'account', type: 'address' }],
315
- outputs: [{ name: '', type: 'uint256' }],
316
- stateMutability: 'view',
317
- },
318
- ];
319
- // Multicall3 getEthBalance ABI
320
- const MULTICALL3_GET_ETH_BALANCE_ABI = [
321
- {
322
- name: 'getEthBalance',
323
- type: 'function',
324
- inputs: [{ name: 'addr', type: 'address' }],
325
- outputs: [{ name: 'balance', type: 'uint256' }],
326
- stateMutability: 'view',
327
- },
328
- ];
329
- // Staking contract getShares ABI
330
- const STAKING_GET_SHARES_ABI = [
331
- {
332
- inputs: [{ internalType: 'address', name: 'account', type: 'address' }],
333
- name: 'getShares',
334
- outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
335
- stateMutability: 'view',
336
- type: 'function',
337
- },
338
- ];
339
285
  const multicall = async (calls, multicallAddress, provider, maxCallsPerMulticall) => {
340
286
  const multicallContract = new Contract(multicallAddress, multicallAbi, provider);
341
287
  return await reduceInBatchesSerially({
@@ -410,327 +356,4 @@ export const multicallOrFallback = async (calls, chainId, provider, maxCallsPerM
410
356
  }
411
357
  return await fallback(calls, maxCallsParallel);
412
358
  };
413
- /**
414
- * Execute multiple contract calls using Multicall3's aggregate3 function.
415
- * This allows for more efficient batch calls with individual failure handling.
416
- *
417
- * @param calls - Array of calls to execute via aggregate3
418
- * @param chainId - The hexadecimal chain id
419
- * @param provider - An ethers rpc provider
420
- * @returns Promise resolving to array of results from aggregate3
421
- */
422
- export const aggregate3 = async (calls, chainId, provider) => {
423
- if (calls.length === 0) {
424
- return [];
425
- }
426
- const multicall3Address = MULTICALL_CONTRACT_BY_CHAINID[chainId];
427
- const multicall3Contract = new Contract(multicall3Address, multicall3Abi, provider);
428
- return await multicall3Contract.callStatic.aggregate3(calls);
429
- };
430
- /**
431
- * Processes and decodes balance results from aggregate3 calls
432
- *
433
- * @param results - Array of results from aggregate3 calls
434
- * @param callMapping - Array mapping call indices to token and user addresses
435
- * @param chainId - The hexadecimal chain id
436
- * @param provider - An ethers rpc provider
437
- * @param includeStaked - Whether to include staked balances
438
- * @returns Map of token address to map of user address to balance
439
- */
440
- const processBalanceResults = (results, callMapping, chainId, provider, includeStaked) => {
441
- const balanceMap = {};
442
- const stakedBalanceMap = {};
443
- // Create contract instances for decoding
444
- const erc20Contract = new Contract(ZERO_ADDRESS, ERC20_BALANCE_OF_ABI, provider);
445
- const multicall3Address = MULTICALL_CONTRACT_BY_CHAINID[chainId];
446
- const multicall3Contract = new Contract(multicall3Address, MULTICALL3_GET_ETH_BALANCE_ABI, provider);
447
- const stakingContractAddress = STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainId];
448
- const stakingContract = stakingContractAddress
449
- ? new Contract(stakingContractAddress, STAKING_GET_SHARES_ABI, provider)
450
- : null;
451
- results.forEach((result, index) => {
452
- if (result.success) {
453
- const { tokenAddress, userAddress, callType } = callMapping[index];
454
- let balance;
455
- if (callType === 'native') {
456
- // For native token, decode the getEthBalance result
457
- balance = multicall3Contract.interface.decodeFunctionResult(GET_ETH_BALANCE_FUNCTION, result.returnData)[0];
458
- if (!balanceMap[tokenAddress]) {
459
- balanceMap[tokenAddress] = {};
460
- }
461
- balanceMap[tokenAddress][userAddress] = balance;
462
- }
463
- else if (callType === 'staking') {
464
- // For staking contract, decode the getShares result
465
- if (stakingContract) {
466
- balance = stakingContract.interface.decodeFunctionResult(GET_SHARES_FUNCTION, result.returnData)[0];
467
- stakedBalanceMap[userAddress] = balance;
468
- }
469
- }
470
- else {
471
- // For ERC20 tokens, decode the balanceOf result
472
- balance = erc20Contract.interface.decodeFunctionResult(BALANCE_OF_FUNCTION, result.returnData)[0];
473
- if (!balanceMap[tokenAddress]) {
474
- balanceMap[tokenAddress] = {};
475
- }
476
- balanceMap[tokenAddress][userAddress] = balance;
477
- }
478
- }
479
- });
480
- const result = { tokenBalances: balanceMap };
481
- if (includeStaked && Object.keys(stakedBalanceMap).length > 0) {
482
- result.stakedBalances = stakedBalanceMap;
483
- }
484
- return result;
485
- };
486
- /**
487
- * Fallback function to get native token balances using individual eth_getBalance calls
488
- * when Multicall3 is not supported on the chain.
489
- *
490
- * @param userAddresses - Array of user addresses to check balances for
491
- * @param provider - An ethers rpc provider
492
- * @param maxCallsParallel - Maximum number of parallel calls (default: 20)
493
- * @returns Promise resolving to map of user address to balance
494
- */
495
- const getNativeBalancesFallback = async (userAddresses, provider, maxCallsParallel = 20) => {
496
- const balanceMap = {};
497
- await reduceInBatchesSerially({
498
- values: userAddresses,
499
- batchSize: maxCallsParallel,
500
- initialResult: undefined,
501
- eachBatch: async (_, batch) => {
502
- const results = await Promise.allSettled(batch.map(async (userAddress) => {
503
- const balance = await provider.getBalance(userAddress);
504
- return {
505
- success: true,
506
- balance: new BN(balance.toString()),
507
- userAddress,
508
- };
509
- }));
510
- results.forEach((result) => {
511
- if (result.status === 'fulfilled' &&
512
- result.value.success &&
513
- result.value.balance !== null) {
514
- balanceMap[result.value.userAddress] = result.value.balance;
515
- }
516
- });
517
- },
518
- });
519
- return balanceMap;
520
- };
521
- /**
522
- * Fallback function to get token balances using individual calls
523
- * when Multicall3 is not supported or when aggregate3 calls fail.
524
- *
525
- * @param tokenAddresses - Array of ERC20 token contract addresses
526
- * @param userAddresses - Array of user addresses to check balances for
527
- * @param provider - An ethers rpc provider
528
- * @param includeNative - Whether to include native token balances (default: true)
529
- * @param maxCallsParallel - Maximum number of parallel calls (default: 20)
530
- * @returns Promise resolving to map of token address to map of user address to balance
531
- */
532
- const getTokenBalancesFallback = async (tokenAddresses, userAddresses, provider, includeNative, maxCallsParallel) => {
533
- const balanceMap = {};
534
- // Handle ERC20 token balances using the existing fallback function
535
- if (tokenAddresses.length > 0) {
536
- const erc20Calls = [];
537
- const callMapping = [];
538
- tokenAddresses.forEach((tokenAddress) => {
539
- userAddresses.forEach((userAddress) => {
540
- const contract = new Contract(tokenAddress, ERC20_BALANCE_OF_ABI, provider);
541
- erc20Calls.push({
542
- contract,
543
- functionSignature: BALANCE_OF_FUNCTION,
544
- arguments: [userAddress],
545
- });
546
- callMapping.push({ tokenAddress, userAddress });
547
- });
548
- });
549
- const erc20Results = await fallback(erc20Calls, maxCallsParallel);
550
- erc20Results.forEach((result, index) => {
551
- if (result.success) {
552
- const { tokenAddress, userAddress } = callMapping[index];
553
- if (!balanceMap[tokenAddress]) {
554
- balanceMap[tokenAddress] = {};
555
- }
556
- balanceMap[tokenAddress][userAddress] = result.value;
557
- }
558
- });
559
- }
560
- // Handle native token balances using the native fallback function
561
- if (includeNative) {
562
- const nativeBalances = await getNativeBalancesFallback(userAddresses, provider, maxCallsParallel);
563
- if (Object.keys(nativeBalances).length > 0) {
564
- balanceMap[ZERO_ADDRESS] = nativeBalances;
565
- }
566
- }
567
- return balanceMap;
568
- };
569
- /**
570
- * Fallback function to get staked balances using individual calls
571
- * when Multicall3 is not supported or when aggregate3 calls fail.
572
- *
573
- * @param userAddresses - Array of user addresses to check staked balances for
574
- * @param chainId - The hexadecimal chain id
575
- * @param provider - An ethers rpc provider
576
- * @param maxCallsParallel - Maximum number of parallel calls (default: 20)
577
- * @returns Promise resolving to map of user address to staked balance
578
- */
579
- const getStakedBalancesFallback = async (userAddresses, chainId, provider, maxCallsParallel) => {
580
- const stakedBalanceMap = {};
581
- const stakingContractAddress = STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainId];
582
- if (!stakingContractAddress) {
583
- // No staking support for this chain
584
- return stakedBalanceMap;
585
- }
586
- const stakingCalls = [];
587
- const callMapping = [];
588
- userAddresses.forEach((userAddress) => {
589
- const contract = new Contract(stakingContractAddress, STAKING_GET_SHARES_ABI, provider);
590
- stakingCalls.push({
591
- contract,
592
- functionSignature: GET_SHARES_FUNCTION,
593
- arguments: [userAddress],
594
- });
595
- callMapping.push({ userAddress });
596
- });
597
- const stakingResults = await fallback(stakingCalls, maxCallsParallel);
598
- stakingResults.forEach((result, index) => {
599
- if (result.success) {
600
- const { userAddress } = callMapping[index];
601
- stakedBalanceMap[userAddress] = result.value;
602
- }
603
- });
604
- return stakedBalanceMap;
605
- };
606
- /**
607
- * Get token balances (both ERC20 and native) for multiple addresses using aggregate3.
608
- * This is more efficient than individual balanceOf calls for multiple addresses and tokens.
609
- * Native token balances are mapped to the zero address (0x0000000000000000000000000000000000000000).
610
- *
611
- * @param accountTokenGroups - Array of objects containing account addresses and their associated token addresses
612
- * @param chainId - The hexadecimal chain id
613
- * @param provider - An ethers rpc provider
614
- * @param includeNative - Whether to include native token balances (default: true)
615
- * @param includeStaked - Whether to include staked balances from supported staking contracts (default: false)
616
- * @returns Promise resolving to object containing tokenBalances map and optional stakedBalances map
617
- */
618
- export const getTokenBalancesForMultipleAddresses = async (accountTokenGroups, chainId, provider, includeNative, includeStaked) => {
619
- // Return early if no groups provided
620
- if (accountTokenGroups.length === 0 && !includeNative && !includeStaked) {
621
- return { tokenBalances: {} };
622
- }
623
- // Extract unique token addresses and user addresses from groups
624
- const uniqueTokenAddresses = Array.from(new Set(accountTokenGroups.flatMap((group) => group.tokenAddresses))).filter((tokenAddress) => tokenAddress !== ZERO_ADDRESS); // Exclude native token from ERC20 calls
625
- const uniqueUserAddresses = Array.from(new Set(accountTokenGroups.map((group) => group.accountAddress)));
626
- // Check if Multicall3 is supported on this chain
627
- if (!MULTICALL_CONTRACT_BY_CHAINID[chainId]) {
628
- // Fallback to individual balance calls when Multicall3 is not supported
629
- const tokenBalances = await getTokenBalancesFallback(uniqueTokenAddresses, uniqueUserAddresses, provider, includeNative, 20);
630
- const result = { tokenBalances };
631
- // Handle staked balances fallback if requested
632
- if (includeStaked) {
633
- const stakedBalances = await getStakedBalancesFallback(uniqueUserAddresses, chainId, provider, 20);
634
- if (Object.keys(stakedBalances).length > 0) {
635
- result.stakedBalances = stakedBalances;
636
- }
637
- }
638
- return result;
639
- }
640
- try {
641
- // Create calls directly from pairs
642
- const allCalls = [];
643
- const allCallMapping = [];
644
- // Create a temporary ERC20 contract for encoding
645
- const tempERC20Contract = new Contract(ZERO_ADDRESS, ERC20_BALANCE_OF_ABI, provider);
646
- // Create ERC20 balance calls for all account-token combinations
647
- accountTokenGroups.forEach((group) => {
648
- group.tokenAddresses
649
- .filter((tokenAddress) => tokenAddress !== ZERO_ADDRESS)
650
- .forEach((tokenAddress) => {
651
- allCalls.push({
652
- target: tokenAddress,
653
- allowFailure: true,
654
- callData: tempERC20Contract.interface.encodeFunctionData(BALANCE_OF_FUNCTION, [group.accountAddress]),
655
- });
656
- allCallMapping.push({
657
- tokenAddress,
658
- userAddress: group.accountAddress,
659
- callType: 'erc20',
660
- });
661
- });
662
- });
663
- // Add native token balance calls if requested
664
- if (includeNative) {
665
- const multicall3Address = MULTICALL_CONTRACT_BY_CHAINID[chainId];
666
- const multicall3TempContract = new Contract(multicall3Address, MULTICALL3_GET_ETH_BALANCE_ABI, provider);
667
- uniqueUserAddresses.forEach((userAddress) => {
668
- allCalls.push({
669
- target: multicall3Address,
670
- allowFailure: true,
671
- callData: multicall3TempContract.interface.encodeFunctionData(GET_ETH_BALANCE_FUNCTION, [userAddress]),
672
- });
673
- allCallMapping.push({
674
- tokenAddress: ZERO_ADDRESS,
675
- userAddress,
676
- callType: 'native',
677
- });
678
- });
679
- }
680
- // Add staking balance calls if requested
681
- if (includeStaked) {
682
- const stakingContractAddress = STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainId];
683
- if (stakingContractAddress) {
684
- const stakingContract = new Contract(stakingContractAddress, STAKING_GET_SHARES_ABI, provider);
685
- uniqueUserAddresses.forEach((userAddress) => {
686
- allCalls.push({
687
- target: stakingContractAddress,
688
- allowFailure: true,
689
- callData: stakingContract.interface.encodeFunctionData(GET_SHARES_FUNCTION, [userAddress]),
690
- });
691
- allCallMapping.push({
692
- tokenAddress: stakingContractAddress,
693
- userAddress,
694
- callType: 'staking',
695
- });
696
- });
697
- }
698
- }
699
- // Execute all calls in batches
700
- const maxCallsPerBatch = 300; // Limit calls per batch to avoid gas/size limits
701
- const allResults = [];
702
- await reduceInBatchesSerially({
703
- values: allCalls,
704
- batchSize: maxCallsPerBatch,
705
- initialResult: undefined,
706
- eachBatch: async (_, batch) => {
707
- const batchResults = await aggregate3(batch, chainId, provider);
708
- allResults.push(...batchResults);
709
- },
710
- });
711
- // Process and return results
712
- return processBalanceResults(allResults, allCallMapping, chainId, provider, includeStaked);
713
- }
714
- catch (error) {
715
- // Fallback only on revert
716
- // https://docs.ethers.org/v5/troubleshooting/errors/#help-CALL_EXCEPTION
717
- if (!error ||
718
- typeof error !== 'object' ||
719
- !('code' in error) ||
720
- error.code !== 'CALL_EXCEPTION') {
721
- throw error;
722
- }
723
- // Fallback to individual balance calls when aggregate3 fails
724
- const tokenBalances = await getTokenBalancesFallback(uniqueTokenAddresses, uniqueUserAddresses, provider, includeNative, 20);
725
- const result = { tokenBalances };
726
- // Handle staked balances fallback if requested
727
- if (includeStaked) {
728
- const stakedBalances = await getStakedBalancesFallback(uniqueUserAddresses, chainId, provider, 20);
729
- if (Object.keys(stakedBalances).length > 0) {
730
- result.stakedBalances = stakedBalances;
731
- }
732
- }
733
- return result;
734
- }
735
- };
736
359
  //# sourceMappingURL=multicall.mjs.map