@metamask/assets-controllers 102.0.0 → 103.1.0
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.
- package/CHANGELOG.md +34 -1
- package/dist/AccountTrackerController.cjs +10 -1
- package/dist/AccountTrackerController.cjs.map +1 -1
- package/dist/AccountTrackerController.d.cts.map +1 -1
- package/dist/AccountTrackerController.d.mts.map +1 -1
- package/dist/AccountTrackerController.mjs +10 -1
- package/dist/AccountTrackerController.mjs.map +1 -1
- package/dist/MultichainAssetsController/MultichainAssetsController.cjs +1 -4
- package/dist/MultichainAssetsController/MultichainAssetsController.cjs.map +1 -1
- package/dist/MultichainAssetsController/MultichainAssetsController.d.cts +2 -2
- package/dist/MultichainAssetsController/MultichainAssetsController.d.cts.map +1 -1
- package/dist/MultichainAssetsController/MultichainAssetsController.d.mts +2 -2
- package/dist/MultichainAssetsController/MultichainAssetsController.d.mts.map +1 -1
- package/dist/MultichainAssetsController/MultichainAssetsController.mjs +1 -4
- package/dist/MultichainAssetsController/MultichainAssetsController.mjs.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.cjs.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts +2 -2
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts +2 -2
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.cjs.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.cts +2 -2
- package/dist/MultichainBalancesController/MultichainBalancesController.d.cts.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.mts +2 -2
- package/dist/MultichainBalancesController/MultichainBalancesController.d.mts.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.mjs.map +1 -1
- package/dist/NftController.cjs.map +1 -1
- package/dist/NftController.d.cts +1 -2
- package/dist/NftController.d.cts.map +1 -1
- package/dist/NftController.d.mts +1 -2
- package/dist/NftController.d.mts.map +1 -1
- package/dist/NftController.mjs.map +1 -1
- package/dist/NftDetectionController.cjs.map +1 -1
- package/dist/NftDetectionController.d.cts +1 -2
- package/dist/NftDetectionController.d.cts.map +1 -1
- package/dist/NftDetectionController.d.mts +1 -2
- package/dist/NftDetectionController.d.mts.map +1 -1
- package/dist/NftDetectionController.mjs.map +1 -1
- package/dist/TokenBalancesController.cjs +73 -39
- package/dist/TokenBalancesController.cjs.map +1 -1
- package/dist/TokenBalancesController.d.cts +20 -5
- package/dist/TokenBalancesController.d.cts.map +1 -1
- package/dist/TokenBalancesController.d.mts +20 -5
- package/dist/TokenBalancesController.d.mts.map +1 -1
- package/dist/TokenBalancesController.mjs +72 -39
- package/dist/TokenBalancesController.mjs.map +1 -1
- package/dist/constants.cjs +32 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +8 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +8 -0
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +30 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/rpc-service/rpc-balance-fetcher.cjs +7 -2
- package/dist/rpc-service/rpc-balance-fetcher.cjs.map +1 -1
- package/dist/rpc-service/rpc-balance-fetcher.d.cts.map +1 -1
- package/dist/rpc-service/rpc-balance-fetcher.d.mts.map +1 -1
- package/dist/rpc-service/rpc-balance-fetcher.mjs +7 -2
- package/dist/rpc-service/rpc-balance-fetcher.mjs.map +1 -1
- package/dist/selectors/token-selectors.cjs +5 -0
- package/dist/selectors/token-selectors.cjs.map +1 -1
- package/dist/selectors/token-selectors.d.cts.map +1 -1
- package/dist/selectors/token-selectors.d.mts.map +1 -1
- package/dist/selectors/token-selectors.mjs +5 -0
- package/dist/selectors/token-selectors.mjs.map +1 -1
- package/dist/token-service.cjs +2 -1
- package/dist/token-service.cjs.map +1 -1
- package/dist/token-service.d.cts.map +1 -1
- package/dist/token-service.d.mts.map +1 -1
- package/dist/token-service.mjs +2 -1
- package/dist/token-service.mjs.map +1 -1
- package/dist/utils/create-batch-handler.cjs +54 -0
- package/dist/utils/create-batch-handler.cjs.map +1 -0
- package/dist/utils/create-batch-handler.d.cts +16 -0
- package/dist/utils/create-batch-handler.d.cts.map +1 -0
- package/dist/utils/create-batch-handler.d.mts +16 -0
- package/dist/utils/create-batch-handler.d.mts.map +1 -0
- package/dist/utils/create-batch-handler.mjs +51 -0
- package/dist/utils/create-batch-handler.mjs.map +1 -0
- package/package.json +9 -9
package/dist/constants.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SUPPORTED_NETWORKS_ACCOUNTS_API_V4 = exports.Source = void 0;
|
|
3
|
+
exports.shouldIncludeNativeToken = exports.SUPPORTED_NETWORKS_ACCOUNTS_API_V4 = exports.Source = void 0;
|
|
4
|
+
const controller_utils_1 = require("@metamask/controller-utils");
|
|
4
5
|
var Source;
|
|
5
6
|
(function (Source) {
|
|
6
7
|
Source["Custom"] = "custom";
|
|
@@ -21,4 +22,34 @@ exports.SUPPORTED_NETWORKS_ACCOUNTS_API_V4 = [
|
|
|
21
22
|
'0x8f', // 143
|
|
22
23
|
'0x3e7', // 999 HyperEVM
|
|
23
24
|
];
|
|
25
|
+
/**
|
|
26
|
+
* Determines if native token fetching should be included for the given chain.
|
|
27
|
+
* Returns false for chains that return arbitrary large numbers (e.g., Tempo networks).
|
|
28
|
+
*
|
|
29
|
+
* @param chainId - Chain ID in hex format (e.g., "0xa5bf") or CAIP-2 format (e.g., "eip155:42431").
|
|
30
|
+
* @returns True if native token should be included, false if it should be skipped.
|
|
31
|
+
*/
|
|
32
|
+
function shouldIncludeNativeToken(chainId) {
|
|
33
|
+
// Convert hex format to CAIP-2 for comparison
|
|
34
|
+
if (chainId.startsWith('0x')) {
|
|
35
|
+
try {
|
|
36
|
+
const decimal = parseInt(chainId, 16);
|
|
37
|
+
const caipChainId = `eip155:${decimal}`;
|
|
38
|
+
if (controller_utils_1.CHAIN_IDS_WITH_NO_NATIVE_TOKEN.includes(caipChainId)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// If conversion fails, assume it should be included
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
// Check CAIP-2 format directly
|
|
49
|
+
if (controller_utils_1.CHAIN_IDS_WITH_NO_NATIVE_TOKEN.includes(chainId)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
exports.shouldIncludeNativeToken = shouldIncludeNativeToken;
|
|
24
55
|
//# sourceMappingURL=constants.cjs.map
|
package/dist/constants.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.cjs","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAA,IAAY,MAIX;AAJD,WAAY,MAAM;IAChB,2BAAiB,CAAA;IACjB,uBAAa,CAAA;IACb,+BAAqB,CAAA;AACvB,CAAC,EAJW,MAAM,sBAAN,MAAM,QAIjB;AAED,wEAAwE;AAC3D,QAAA,kCAAkC,GAAG;IAChD,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,QAAQ;IAClB,SAAS,EAAE,SAAS;IACpB,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,eAAe;CACzB,CAAC","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"constants.cjs","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAA,iEAA4E;AAE5E,IAAY,MAIX;AAJD,WAAY,MAAM;IAChB,2BAAiB,CAAA;IACjB,uBAAa,CAAA;IACb,+BAAqB,CAAA;AACvB,CAAC,EAJW,MAAM,sBAAN,MAAM,QAIjB;AAED,wEAAwE;AAC3D,QAAA,kCAAkC,GAAG;IAChD,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,QAAQ;IAClB,SAAS,EAAE,SAAS;IACpB,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,eAAe;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,SAAgB,wBAAwB,CAAC,OAAe;IACtD,8CAA8C;IAC9C,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACtC,MAAM,WAAW,GAAG,UAAU,OAAO,EAAE,CAAC;YACxC,IACE,iDAA8B,CAAC,QAAQ,CACrC,WAA8D,CAC/D,EACD,CAAC;gBACD,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;YACpD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+BAA+B;IAC/B,IACE,iDAA8B,CAAC,QAAQ,CACrC,OAA0D,CAC3D,EACD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AA9BD,4DA8BC","sourcesContent":["import { CHAIN_IDS_WITH_NO_NATIVE_TOKEN } from '@metamask/controller-utils';\n\nexport enum Source {\n Custom = 'custom',\n Dapp = 'dapp',\n Detected = 'detected',\n}\n\n// TODO: delete this once we have the v4 endpoint for supported networks\nexport const SUPPORTED_NETWORKS_ACCOUNTS_API_V4 = [\n '0x1', // 1\n '0x89', // 137\n '0x38', // 56\n '0xe728', // 59144\n '0x2105', // 8453\n '0xa', // 10\n '0xa4b1', // 42161\n '0x82750', // 534352\n '0x531', // 1329\n '0x8f', // 143\n '0x3e7', // 999 HyperEVM\n];\n\n/**\n * Determines if native token fetching should be included for the given chain.\n * Returns false for chains that return arbitrary large numbers (e.g., Tempo networks).\n *\n * @param chainId - Chain ID in hex format (e.g., \"0xa5bf\") or CAIP-2 format (e.g., \"eip155:42431\").\n * @returns True if native token should be included, false if it should be skipped.\n */\nexport function shouldIncludeNativeToken(chainId: string): boolean {\n // Convert hex format to CAIP-2 for comparison\n if (chainId.startsWith('0x')) {\n try {\n const decimal = parseInt(chainId, 16);\n const caipChainId = `eip155:${decimal}`;\n if (\n CHAIN_IDS_WITH_NO_NATIVE_TOKEN.includes(\n caipChainId as (typeof CHAIN_IDS_WITH_NO_NATIVE_TOKEN)[number],\n )\n ) {\n return false;\n }\n } catch {\n // If conversion fails, assume it should be included\n return true;\n }\n return true;\n }\n\n // Check CAIP-2 format directly\n if (\n CHAIN_IDS_WITH_NO_NATIVE_TOKEN.includes(\n chainId as (typeof CHAIN_IDS_WITH_NO_NATIVE_TOKEN)[number],\n )\n ) {\n return false;\n }\n\n return true;\n}\n"]}
|
package/dist/constants.d.cts
CHANGED
|
@@ -4,4 +4,12 @@ export declare enum Source {
|
|
|
4
4
|
Detected = "detected"
|
|
5
5
|
}
|
|
6
6
|
export declare const SUPPORTED_NETWORKS_ACCOUNTS_API_V4: string[];
|
|
7
|
+
/**
|
|
8
|
+
* Determines if native token fetching should be included for the given chain.
|
|
9
|
+
* Returns false for chains that return arbitrary large numbers (e.g., Tempo networks).
|
|
10
|
+
*
|
|
11
|
+
* @param chainId - Chain ID in hex format (e.g., "0xa5bf") or CAIP-2 format (e.g., "eip155:42431").
|
|
12
|
+
* @returns True if native token should be included, false if it should be skipped.
|
|
13
|
+
*/
|
|
14
|
+
export declare function shouldIncludeNativeToken(chainId: string): boolean;
|
|
7
15
|
//# sourceMappingURL=constants.d.cts.map
|
package/dist/constants.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.cts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.cts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,oBAAY,MAAM;IAChB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,QAAQ,aAAa;CACtB;AAGD,eAAO,MAAM,kCAAkC,UAY9C,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CA8BjE"}
|
package/dist/constants.d.mts
CHANGED
|
@@ -4,4 +4,12 @@ export declare enum Source {
|
|
|
4
4
|
Detected = "detected"
|
|
5
5
|
}
|
|
6
6
|
export declare const SUPPORTED_NETWORKS_ACCOUNTS_API_V4: string[];
|
|
7
|
+
/**
|
|
8
|
+
* Determines if native token fetching should be included for the given chain.
|
|
9
|
+
* Returns false for chains that return arbitrary large numbers (e.g., Tempo networks).
|
|
10
|
+
*
|
|
11
|
+
* @param chainId - Chain ID in hex format (e.g., "0xa5bf") or CAIP-2 format (e.g., "eip155:42431").
|
|
12
|
+
* @returns True if native token should be included, false if it should be skipped.
|
|
13
|
+
*/
|
|
14
|
+
export declare function shouldIncludeNativeToken(chainId: string): boolean;
|
|
7
15
|
//# sourceMappingURL=constants.d.mts.map
|
package/dist/constants.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.mts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.mts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,oBAAY,MAAM;IAChB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,QAAQ,aAAa;CACtB;AAGD,eAAO,MAAM,kCAAkC,UAY9C,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CA8BjE"}
|
package/dist/constants.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CHAIN_IDS_WITH_NO_NATIVE_TOKEN } from "@metamask/controller-utils";
|
|
1
2
|
export var Source;
|
|
2
3
|
(function (Source) {
|
|
3
4
|
Source["Custom"] = "custom";
|
|
@@ -18,4 +19,33 @@ export const SUPPORTED_NETWORKS_ACCOUNTS_API_V4 = [
|
|
|
18
19
|
'0x8f', // 143
|
|
19
20
|
'0x3e7', // 999 HyperEVM
|
|
20
21
|
];
|
|
22
|
+
/**
|
|
23
|
+
* Determines if native token fetching should be included for the given chain.
|
|
24
|
+
* Returns false for chains that return arbitrary large numbers (e.g., Tempo networks).
|
|
25
|
+
*
|
|
26
|
+
* @param chainId - Chain ID in hex format (e.g., "0xa5bf") or CAIP-2 format (e.g., "eip155:42431").
|
|
27
|
+
* @returns True if native token should be included, false if it should be skipped.
|
|
28
|
+
*/
|
|
29
|
+
export function shouldIncludeNativeToken(chainId) {
|
|
30
|
+
// Convert hex format to CAIP-2 for comparison
|
|
31
|
+
if (chainId.startsWith('0x')) {
|
|
32
|
+
try {
|
|
33
|
+
const decimal = parseInt(chainId, 16);
|
|
34
|
+
const caipChainId = `eip155:${decimal}`;
|
|
35
|
+
if (CHAIN_IDS_WITH_NO_NATIVE_TOKEN.includes(caipChainId)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// If conversion fails, assume it should be included
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
// Check CAIP-2 format directly
|
|
46
|
+
if (CHAIN_IDS_WITH_NO_NATIVE_TOKEN.includes(chainId)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
21
51
|
//# sourceMappingURL=constants.mjs.map
|
package/dist/constants.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,MAIX;AAJD,WAAY,MAAM;IAChB,2BAAiB,CAAA;IACjB,uBAAa,CAAA;IACb,+BAAqB,CAAA;AACvB,CAAC,EAJW,MAAM,KAAN,MAAM,QAIjB;AAED,wEAAwE;AACxE,MAAM,CAAC,MAAM,kCAAkC,GAAG;IAChD,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,QAAQ;IAClB,SAAS,EAAE,SAAS;IACpB,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,eAAe;CACzB,CAAC","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,mCAAmC;AAE5E,MAAM,CAAN,IAAY,MAIX;AAJD,WAAY,MAAM;IAChB,2BAAiB,CAAA;IACjB,uBAAa,CAAA;IACb,+BAAqB,CAAA;AACvB,CAAC,EAJW,MAAM,KAAN,MAAM,QAIjB;AAED,wEAAwE;AACxE,MAAM,CAAC,MAAM,kCAAkC,GAAG;IAChD,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,QAAQ;IAClB,SAAS,EAAE,SAAS;IACpB,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,eAAe;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,8CAA8C;IAC9C,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACtC,MAAM,WAAW,GAAG,UAAU,OAAO,EAAE,CAAC;YACxC,IACE,8BAA8B,CAAC,QAAQ,CACrC,WAA8D,CAC/D,EACD,CAAC;gBACD,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;YACpD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+BAA+B;IAC/B,IACE,8BAA8B,CAAC,QAAQ,CACrC,OAA0D,CAC3D,EACD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { CHAIN_IDS_WITH_NO_NATIVE_TOKEN } from '@metamask/controller-utils';\n\nexport enum Source {\n Custom = 'custom',\n Dapp = 'dapp',\n Detected = 'detected',\n}\n\n// TODO: delete this once we have the v4 endpoint for supported networks\nexport const SUPPORTED_NETWORKS_ACCOUNTS_API_V4 = [\n '0x1', // 1\n '0x89', // 137\n '0x38', // 56\n '0xe728', // 59144\n '0x2105', // 8453\n '0xa', // 10\n '0xa4b1', // 42161\n '0x82750', // 534352\n '0x531', // 1329\n '0x8f', // 143\n '0x3e7', // 999 HyperEVM\n];\n\n/**\n * Determines if native token fetching should be included for the given chain.\n * Returns false for chains that return arbitrary large numbers (e.g., Tempo networks).\n *\n * @param chainId - Chain ID in hex format (e.g., \"0xa5bf\") or CAIP-2 format (e.g., \"eip155:42431\").\n * @returns True if native token should be included, false if it should be skipped.\n */\nexport function shouldIncludeNativeToken(chainId: string): boolean {\n // Convert hex format to CAIP-2 for comparison\n if (chainId.startsWith('0x')) {\n try {\n const decimal = parseInt(chainId, 16);\n const caipChainId = `eip155:${decimal}`;\n if (\n CHAIN_IDS_WITH_NO_NATIVE_TOKEN.includes(\n caipChainId as (typeof CHAIN_IDS_WITH_NO_NATIVE_TOKEN)[number],\n )\n ) {\n return false;\n }\n } catch {\n // If conversion fails, assume it should be included\n return true;\n }\n return true;\n }\n\n // Check CAIP-2 format directly\n if (\n CHAIN_IDS_WITH_NO_NATIVE_TOKEN.includes(\n chainId as (typeof CHAIN_IDS_WITH_NO_NATIVE_TOKEN)[number],\n )\n ) {\n return false;\n }\n\n return true;\n}\n"]}
|
|
@@ -19,6 +19,7 @@ exports.RpcBalanceFetcher = void 0;
|
|
|
19
19
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
20
20
|
const bn_js_1 = __importDefault(require("bn.js"));
|
|
21
21
|
const AssetsContractController_1 = require("../AssetsContractController.cjs");
|
|
22
|
+
const constants_1 = require("../constants.cjs");
|
|
22
23
|
const multicall_1 = require("../multicall.cjs");
|
|
23
24
|
const RPC_TIMEOUT_MS = 30000;
|
|
24
25
|
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
@@ -55,8 +56,12 @@ class RpcBalanceFetcher {
|
|
|
55
56
|
}
|
|
56
57
|
const provider = __classPrivateFieldGet(this, _RpcBalanceFetcher_getProvider, "f").call(this, chainId);
|
|
57
58
|
await __classPrivateFieldGet(this, _RpcBalanceFetcher_instances, "m", _RpcBalanceFetcher_ensureFreshBlockData).call(this, chainId);
|
|
59
|
+
// Skip native token fetching for chains that return arbitrary large numbers
|
|
60
|
+
const includeNative = (0, constants_1.shouldIncludeNativeToken)(chainId);
|
|
58
61
|
const balanceResult = await (0, controller_utils_1.safelyExecuteWithTimeout)(async () => {
|
|
59
|
-
return await (0, multicall_1.getTokenBalancesForMultipleAddresses)(accountTokenGroups, chainId, provider,
|
|
62
|
+
return await (0, multicall_1.getTokenBalancesForMultipleAddresses)(accountTokenGroups, chainId, provider,
|
|
63
|
+
// Skip native for Tempo chains
|
|
64
|
+
includeNative && includeNativeAndStaked, includeNativeAndStaked);
|
|
60
65
|
}, true, RPC_TIMEOUT_MS);
|
|
61
66
|
// If timeout or error occurred, return empty array for this chain
|
|
62
67
|
if (!balanceResult) {
|
|
@@ -64,7 +69,7 @@ class RpcBalanceFetcher {
|
|
|
64
69
|
}
|
|
65
70
|
const { tokenBalances, stakedBalances } = balanceResult;
|
|
66
71
|
const chainResults = [];
|
|
67
|
-
if (includeNativeAndStaked) {
|
|
72
|
+
if (includeNative && includeNativeAndStaked) {
|
|
68
73
|
// Add native token entries for all addresses being processed
|
|
69
74
|
const allAddressesForNative = new Set();
|
|
70
75
|
accountTokenGroups.forEach((group) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-balance-fetcher.cjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-balance-fetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Web3Provider } from '@ethersproject/providers';\nimport {\n toChecksumHexAddress,\n safelyExecuteWithTimeout,\n} from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkClient } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from '../AssetsContractController';\nimport type { UnprocessedTokens } from '../multi-chain-accounts-service/api-balance-fetcher';\nimport { getTokenBalancesForMultipleAddresses } from '../multicall';\nimport type { TokensControllerState } from '../TokensController';\n\nconst RPC_TIMEOUT_MS = 30000;\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nexport type ProcessedBalance = {\n success: boolean;\n value?: BN;\n account: ChecksumAddress;\n token: ChecksumAddress;\n chainId: ChainIdHex;\n};\n\nexport type BalanceFetchResult = {\n balances: ProcessedBalance[];\n unprocessedChainIds?: ChainIdHex[];\n unprocessedTokens?: UnprocessedTokens;\n};\n\nexport type BalanceFetcher = {\n supports(chainId: ChainIdHex): boolean;\n fetch(input: {\n chainIds: ChainIdHex[];\n queryAllAccounts: boolean;\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n unprocessedTokens?: UnprocessedTokens;\n }): Promise<BalanceFetchResult>;\n};\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\nexport class RpcBalanceFetcher implements BalanceFetcher {\n readonly #getProvider: (chainId: ChainIdHex) => Web3Provider;\n\n readonly #getNetworkClient: (chainId: ChainIdHex) => NetworkClient;\n\n readonly #getTokensState: () => {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n };\n\n constructor(\n getProvider: (chainId: ChainIdHex) => Web3Provider,\n getNetworkClient: (chainId: ChainIdHex) => NetworkClient,\n getTokensState: () => {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n },\n ) {\n this.#getProvider = getProvider;\n this.#getNetworkClient = getNetworkClient;\n this.#getTokensState = getTokensState;\n }\n\n supports(): boolean {\n return true; // fallback – supports every chain\n }\n\n #getStakingContractAddress(chainId: ChainIdHex): string | undefined {\n return STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainId];\n }\n\n async fetch({\n chainIds,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n unprocessedTokens,\n }: Parameters<BalanceFetcher['fetch']>[0]): Promise<BalanceFetchResult> {\n // Process all chains in parallel for better performance\n const chainProcessingPromises = chainIds.map(async (chainId) => {\n // if there are unprocessed tokens for a chain, it means the chain was partially processed.\n // because of this, we need to build distinct account <-> token groups to process\n const hasUnprocessedTokensForChain = queryAllAccounts\n ? Object.values(unprocessedTokens ?? {}).some((chainMap) =>\n Boolean(chainMap[chainId] && chainMap[chainId].length > 0),\n )\n : Boolean(\n unprocessedTokens?.[selectedAccount.toLowerCase()]?.[chainId] &&\n unprocessedTokens[selectedAccount.toLowerCase()][chainId].length >\n 0,\n );\n\n const tokensState = this.#getTokensState();\n const { accountTokenGroups, includeNativeAndStaked } =\n hasUnprocessedTokensForChain\n ? buildUnprocessedAccountTokenGroupsStatic(\n chainId,\n queryAllAccounts,\n selectedAccount,\n unprocessedTokens as UnprocessedTokens,\n )\n : buildAccountTokenGroupsStatic(\n chainId,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n tokensState.allTokens,\n tokensState.allDetectedTokens,\n );\n\n if (!accountTokenGroups.length) {\n return [];\n }\n\n const provider = this.#getProvider(chainId);\n await this.#ensureFreshBlockData(chainId);\n\n const balanceResult = await safelyExecuteWithTimeout(\n async () => {\n return await getTokenBalancesForMultipleAddresses(\n accountTokenGroups,\n chainId,\n provider,\n includeNativeAndStaked,\n includeNativeAndStaked,\n );\n },\n true,\n RPC_TIMEOUT_MS,\n );\n\n // If timeout or error occurred, return empty array for this chain\n if (!balanceResult) {\n return [];\n }\n\n const { tokenBalances, stakedBalances } = balanceResult;\n const chainResults: ProcessedBalance[] = [];\n\n if (includeNativeAndStaked) {\n // Add native token entries for all addresses being processed\n const allAddressesForNative = new Set<string>();\n accountTokenGroups.forEach((group) => {\n allAddressesForNative.add(group.accountAddress);\n });\n\n // Ensure native token entries exist for all addresses\n allAddressesForNative.forEach((address) => {\n const nativeBalance = tokenBalances[ZERO_ADDRESS]?.[address] || null;\n chainResults.push({\n success: true,\n value: nativeBalance || new BN('0'),\n account: address as ChecksumAddress,\n token: ZERO_ADDRESS,\n chainId,\n });\n });\n }\n\n // Add other token balances\n Object.entries(tokenBalances).forEach(([tokenAddr, balances]) => {\n // Skip native token since we handled it explicitly above\n if (tokenAddr === ZERO_ADDRESS) {\n return;\n }\n Object.entries(balances).forEach(([acct, bn]) => {\n chainResults.push({\n success: bn !== null,\n value: bn,\n account: acct as ChecksumAddress,\n token: checksum(tokenAddr),\n chainId,\n });\n });\n });\n\n // Add staked balances for all addresses being processed\n const stakingContractAddress = this.#getStakingContractAddress(chainId);\n if (includeNativeAndStaked && stakingContractAddress) {\n // Get all unique addresses being processed for this chain\n const allAddresses = new Set<string>();\n accountTokenGroups.forEach((group) => {\n allAddresses.add(group.accountAddress);\n });\n\n // Add staked balance entry for each address\n const checksummedStakingAddress = checksum(stakingContractAddress);\n allAddresses.forEach((address) => {\n const stakedBalance = stakedBalances?.[address] ?? null;\n chainResults.push({\n success: true,\n value: stakedBalance ?? new BN('0'),\n account: address as ChecksumAddress,\n token: checksummedStakingAddress,\n chainId,\n });\n });\n }\n\n return chainResults;\n });\n\n // Wait for all chains to complete (or fail) and collect results\n const chainResultsArray = await Promise.allSettled(chainProcessingPromises);\n const results: ProcessedBalance[] = [];\n\n chainResultsArray.forEach((chainResult) => {\n if (chainResult.status === 'fulfilled') {\n results.push(...chainResult.value);\n }\n });\n\n return { balances: results };\n }\n\n /**\n * Ensures that the block tracker has the latest block data before performing multicall operations.\n * This is a temporary fix to ensure that the block number is up to date.\n *\n * @param chainId - The chain id to update block data for.\n */\n async #ensureFreshBlockData(chainId: Hex): Promise<void> {\n // Force fresh block data before multicall\n // TODO: This is a temporary fix to ensure that the block number is up to date.\n // We should remove this once we have a better solution for this on the block tracker controller.\n const networkClient = this.#getNetworkClient(chainId);\n await networkClient.blockTracker?.checkForLatestBlock?.();\n }\n}\n\ntype AccountTokenGroup = {\n accountAddress: ChecksumAddress;\n tokenAddresses: ChecksumAddress[];\n};\n\nfunction buildAccountTokenGroups(\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n accountTokenMap: { [account: string]: string[] },\n): AccountTokenGroup[] {\n const pairs: {\n accountAddress: ChecksumAddress;\n tokenAddress: ChecksumAddress;\n }[] = [];\n\n const add = ([account, tokens]: [string, string[]]): void => {\n const checksumAccount = checksum(account);\n const shouldInclude =\n queryAllAccounts || checksumAccount === checksum(selectedAccount);\n if (!shouldInclude) {\n return;\n }\n tokens.forEach((token: string) =>\n pairs.push({\n accountAddress: account as ChecksumAddress,\n tokenAddress: checksum(token),\n }),\n );\n };\n\n Object.entries(accountTokenMap).forEach(add);\n\n // group by account\n const map = new Map<ChecksumAddress, ChecksumAddress[]>();\n pairs.forEach(({ accountAddress, tokenAddress }) => {\n if (!map.has(accountAddress)) {\n map.set(accountAddress, []);\n }\n const tokens = map.get(accountAddress);\n if (tokens) {\n tokens.push(tokenAddress);\n }\n });\n\n return Array.from(map.entries()).map(([accountAddress, tokenAddresses]) => ({\n accountAddress,\n tokenAddresses,\n }));\n}\n\n/**\n * Merges imported & detected tokens for the requested chain and returns a list\n * of `{ accountAddress, tokenAddresses[] }` suitable for getTokenBalancesForMultipleAddresses.\n *\n * @param chainId - The chain ID to build account token groups for\n * @param queryAllAccounts - Whether to query all accounts or just the selected one\n * @param selectedAccount - The currently selected account\n * @param allAccounts - All available accounts\n * @param allTokens - All tokens from TokensController\n * @param allDetectedTokens - All detected tokens from TokensController\n * @returns Array of account/token groups for multicall\n */\nfunction buildAccountTokenGroupsStatic(\n chainId: ChainIdHex,\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n allAccounts: InternalAccount[],\n allTokens: TokensControllerState['allTokens'],\n allDetectedTokens: TokensControllerState['allDetectedTokens'],\n): {\n accountTokenGroups: AccountTokenGroup[];\n includeNativeAndStaked: true;\n} {\n const accountTokenMap: { [account: string]: string[] } = {};\n\n // Add all tokens\n Object.entries(allTokens[chainId] ?? {}).forEach(([account, tokens]) => {\n accountTokenMap[account] = tokens.map((token) => token.address);\n });\n\n // Add all detected tokens\n Object.entries(allDetectedTokens[chainId] ?? {}).forEach(\n ([account, tokens]) => {\n if (!accountTokenMap[account]) {\n accountTokenMap[account] = [];\n }\n accountTokenMap[account] = Array.from(\n new Set([\n ...accountTokenMap[account],\n ...tokens.map((token) => token.address),\n ]),\n );\n },\n );\n\n // Add native tokens\n if (queryAllAccounts) {\n allAccounts.forEach((a) => {\n accountTokenMap[a.address] ??= [];\n accountTokenMap[a.address].push(ZERO_ADDRESS);\n });\n } else {\n accountTokenMap[selectedAccount] ??= [];\n accountTokenMap[selectedAccount].push(ZERO_ADDRESS);\n }\n\n return {\n accountTokenGroups: buildAccountTokenGroups(\n queryAllAccounts,\n selectedAccount,\n accountTokenMap,\n ),\n includeNativeAndStaked: true,\n };\n}\n\nfunction buildUnprocessedAccountTokenGroupsStatic(\n chainId: ChainIdHex,\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n unprocessedTokens: UnprocessedTokens,\n): {\n accountTokenGroups: AccountTokenGroup[];\n includeNativeAndStaked: false;\n} {\n const accountTokenMap: { [account: string]: string[] } = {};\n Object.entries(unprocessedTokens).forEach(([account, tokens]) => {\n const lowercaseAccount = account.toLowerCase();\n if (\n queryAllAccounts ||\n lowercaseAccount === selectedAccount.toLowerCase()\n ) {\n const tokenAddresses =\n tokens?.[chainId]?.map((tokenAddress) => tokenAddress.toLowerCase()) ??\n [];\n accountTokenMap[lowercaseAccount] = tokenAddresses;\n }\n });\n\n return {\n accountTokenGroups: buildAccountTokenGroups(\n queryAllAccounts,\n selectedAccount,\n accountTokenMap,\n ),\n includeNativeAndStaked: false,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rpc-balance-fetcher.cjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-balance-fetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Web3Provider } from '@ethersproject/providers';\nimport {\n toChecksumHexAddress,\n safelyExecuteWithTimeout,\n} from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkClient } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from '../AssetsContractController';\nimport { shouldIncludeNativeToken } from '../constants';\nimport type { UnprocessedTokens } from '../multi-chain-accounts-service/api-balance-fetcher';\nimport { getTokenBalancesForMultipleAddresses } from '../multicall';\nimport type { TokensControllerState } from '../TokensController';\n\nconst RPC_TIMEOUT_MS = 30000;\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nexport type ProcessedBalance = {\n success: boolean;\n value?: BN;\n account: ChecksumAddress;\n token: ChecksumAddress;\n chainId: ChainIdHex;\n};\n\nexport type BalanceFetchResult = {\n balances: ProcessedBalance[];\n unprocessedChainIds?: ChainIdHex[];\n unprocessedTokens?: UnprocessedTokens;\n};\n\nexport type BalanceFetcher = {\n supports(chainId: ChainIdHex): boolean;\n fetch(input: {\n chainIds: ChainIdHex[];\n queryAllAccounts: boolean;\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n unprocessedTokens?: UnprocessedTokens;\n }): Promise<BalanceFetchResult>;\n};\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\nexport class RpcBalanceFetcher implements BalanceFetcher {\n readonly #getProvider: (chainId: ChainIdHex) => Web3Provider;\n\n readonly #getNetworkClient: (chainId: ChainIdHex) => NetworkClient;\n\n readonly #getTokensState: () => {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n };\n\n constructor(\n getProvider: (chainId: ChainIdHex) => Web3Provider,\n getNetworkClient: (chainId: ChainIdHex) => NetworkClient,\n getTokensState: () => {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n },\n ) {\n this.#getProvider = getProvider;\n this.#getNetworkClient = getNetworkClient;\n this.#getTokensState = getTokensState;\n }\n\n supports(): boolean {\n return true; // fallback – supports every chain\n }\n\n #getStakingContractAddress(chainId: ChainIdHex): string | undefined {\n return STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainId];\n }\n\n async fetch({\n chainIds,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n unprocessedTokens,\n }: Parameters<BalanceFetcher['fetch']>[0]): Promise<BalanceFetchResult> {\n // Process all chains in parallel for better performance\n const chainProcessingPromises = chainIds.map(async (chainId) => {\n // if there are unprocessed tokens for a chain, it means the chain was partially processed.\n // because of this, we need to build distinct account <-> token groups to process\n const hasUnprocessedTokensForChain = queryAllAccounts\n ? Object.values(unprocessedTokens ?? {}).some((chainMap) =>\n Boolean(chainMap[chainId] && chainMap[chainId].length > 0),\n )\n : Boolean(\n unprocessedTokens?.[selectedAccount.toLowerCase()]?.[chainId] &&\n unprocessedTokens[selectedAccount.toLowerCase()][chainId].length >\n 0,\n );\n\n const tokensState = this.#getTokensState();\n const { accountTokenGroups, includeNativeAndStaked } =\n hasUnprocessedTokensForChain\n ? buildUnprocessedAccountTokenGroupsStatic(\n chainId,\n queryAllAccounts,\n selectedAccount,\n unprocessedTokens as UnprocessedTokens,\n )\n : buildAccountTokenGroupsStatic(\n chainId,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n tokensState.allTokens,\n tokensState.allDetectedTokens,\n );\n\n if (!accountTokenGroups.length) {\n return [];\n }\n\n const provider = this.#getProvider(chainId);\n await this.#ensureFreshBlockData(chainId);\n\n // Skip native token fetching for chains that return arbitrary large numbers\n const includeNative = shouldIncludeNativeToken(chainId);\n\n const balanceResult = await safelyExecuteWithTimeout(\n async () => {\n return await getTokenBalancesForMultipleAddresses(\n accountTokenGroups,\n chainId,\n provider,\n // Skip native for Tempo chains\n includeNative && includeNativeAndStaked,\n includeNativeAndStaked,\n );\n },\n true,\n RPC_TIMEOUT_MS,\n );\n\n // If timeout or error occurred, return empty array for this chain\n if (!balanceResult) {\n return [];\n }\n\n const { tokenBalances, stakedBalances } = balanceResult;\n const chainResults: ProcessedBalance[] = [];\n\n if (includeNative && includeNativeAndStaked) {\n // Add native token entries for all addresses being processed\n const allAddressesForNative = new Set<string>();\n accountTokenGroups.forEach((group) => {\n allAddressesForNative.add(group.accountAddress);\n });\n\n // Ensure native token entries exist for all addresses\n allAddressesForNative.forEach((address) => {\n const nativeBalance = tokenBalances[ZERO_ADDRESS]?.[address] || null;\n chainResults.push({\n success: true,\n value: nativeBalance || new BN('0'),\n account: address as ChecksumAddress,\n token: ZERO_ADDRESS,\n chainId,\n });\n });\n }\n\n // Add other token balances\n Object.entries(tokenBalances).forEach(([tokenAddr, balances]) => {\n // Skip native token since we handled it explicitly above\n if (tokenAddr === ZERO_ADDRESS) {\n return;\n }\n Object.entries(balances).forEach(([acct, bn]) => {\n chainResults.push({\n success: bn !== null,\n value: bn,\n account: acct as ChecksumAddress,\n token: checksum(tokenAddr),\n chainId,\n });\n });\n });\n\n // Add staked balances for all addresses being processed\n const stakingContractAddress = this.#getStakingContractAddress(chainId);\n if (includeNativeAndStaked && stakingContractAddress) {\n // Get all unique addresses being processed for this chain\n const allAddresses = new Set<string>();\n accountTokenGroups.forEach((group) => {\n allAddresses.add(group.accountAddress);\n });\n\n // Add staked balance entry for each address\n const checksummedStakingAddress = checksum(stakingContractAddress);\n allAddresses.forEach((address) => {\n const stakedBalance = stakedBalances?.[address] ?? null;\n chainResults.push({\n success: true,\n value: stakedBalance ?? new BN('0'),\n account: address as ChecksumAddress,\n token: checksummedStakingAddress,\n chainId,\n });\n });\n }\n\n return chainResults;\n });\n\n // Wait for all chains to complete (or fail) and collect results\n const chainResultsArray = await Promise.allSettled(chainProcessingPromises);\n const results: ProcessedBalance[] = [];\n\n chainResultsArray.forEach((chainResult) => {\n if (chainResult.status === 'fulfilled') {\n results.push(...chainResult.value);\n }\n });\n\n return { balances: results };\n }\n\n /**\n * Ensures that the block tracker has the latest block data before performing multicall operations.\n * This is a temporary fix to ensure that the block number is up to date.\n *\n * @param chainId - The chain id to update block data for.\n */\n async #ensureFreshBlockData(chainId: Hex): Promise<void> {\n // Force fresh block data before multicall\n // TODO: This is a temporary fix to ensure that the block number is up to date.\n // We should remove this once we have a better solution for this on the block tracker controller.\n const networkClient = this.#getNetworkClient(chainId);\n await networkClient.blockTracker?.checkForLatestBlock?.();\n }\n}\n\ntype AccountTokenGroup = {\n accountAddress: ChecksumAddress;\n tokenAddresses: ChecksumAddress[];\n};\n\nfunction buildAccountTokenGroups(\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n accountTokenMap: { [account: string]: string[] },\n): AccountTokenGroup[] {\n const pairs: {\n accountAddress: ChecksumAddress;\n tokenAddress: ChecksumAddress;\n }[] = [];\n\n const add = ([account, tokens]: [string, string[]]): void => {\n const checksumAccount = checksum(account);\n const shouldInclude =\n queryAllAccounts || checksumAccount === checksum(selectedAccount);\n if (!shouldInclude) {\n return;\n }\n tokens.forEach((token: string) =>\n pairs.push({\n accountAddress: account as ChecksumAddress,\n tokenAddress: checksum(token),\n }),\n );\n };\n\n Object.entries(accountTokenMap).forEach(add);\n\n // group by account\n const map = new Map<ChecksumAddress, ChecksumAddress[]>();\n pairs.forEach(({ accountAddress, tokenAddress }) => {\n if (!map.has(accountAddress)) {\n map.set(accountAddress, []);\n }\n const tokens = map.get(accountAddress);\n if (tokens) {\n tokens.push(tokenAddress);\n }\n });\n\n return Array.from(map.entries()).map(([accountAddress, tokenAddresses]) => ({\n accountAddress,\n tokenAddresses,\n }));\n}\n\n/**\n * Merges imported & detected tokens for the requested chain and returns a list\n * of `{ accountAddress, tokenAddresses[] }` suitable for getTokenBalancesForMultipleAddresses.\n *\n * @param chainId - The chain ID to build account token groups for\n * @param queryAllAccounts - Whether to query all accounts or just the selected one\n * @param selectedAccount - The currently selected account\n * @param allAccounts - All available accounts\n * @param allTokens - All tokens from TokensController\n * @param allDetectedTokens - All detected tokens from TokensController\n * @returns Array of account/token groups for multicall\n */\nfunction buildAccountTokenGroupsStatic(\n chainId: ChainIdHex,\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n allAccounts: InternalAccount[],\n allTokens: TokensControllerState['allTokens'],\n allDetectedTokens: TokensControllerState['allDetectedTokens'],\n): {\n accountTokenGroups: AccountTokenGroup[];\n includeNativeAndStaked: true;\n} {\n const accountTokenMap: { [account: string]: string[] } = {};\n\n // Add all tokens\n Object.entries(allTokens[chainId] ?? {}).forEach(([account, tokens]) => {\n accountTokenMap[account] = tokens.map((token) => token.address);\n });\n\n // Add all detected tokens\n Object.entries(allDetectedTokens[chainId] ?? {}).forEach(\n ([account, tokens]) => {\n if (!accountTokenMap[account]) {\n accountTokenMap[account] = [];\n }\n accountTokenMap[account] = Array.from(\n new Set([\n ...accountTokenMap[account],\n ...tokens.map((token) => token.address),\n ]),\n );\n },\n );\n\n // Add native tokens\n if (queryAllAccounts) {\n allAccounts.forEach((a) => {\n accountTokenMap[a.address] ??= [];\n accountTokenMap[a.address].push(ZERO_ADDRESS);\n });\n } else {\n accountTokenMap[selectedAccount] ??= [];\n accountTokenMap[selectedAccount].push(ZERO_ADDRESS);\n }\n\n return {\n accountTokenGroups: buildAccountTokenGroups(\n queryAllAccounts,\n selectedAccount,\n accountTokenMap,\n ),\n includeNativeAndStaked: true,\n };\n}\n\nfunction buildUnprocessedAccountTokenGroupsStatic(\n chainId: ChainIdHex,\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n unprocessedTokens: UnprocessedTokens,\n): {\n accountTokenGroups: AccountTokenGroup[];\n includeNativeAndStaked: false;\n} {\n const accountTokenMap: { [account: string]: string[] } = {};\n Object.entries(unprocessedTokens).forEach(([account, tokens]) => {\n const lowercaseAccount = account.toLowerCase();\n if (\n queryAllAccounts ||\n lowercaseAccount === selectedAccount.toLowerCase()\n ) {\n const tokenAddresses =\n tokens?.[chainId]?.map((tokenAddress) => tokenAddress.toLowerCase()) ??\n [];\n accountTokenMap[lowercaseAccount] = tokenAddresses;\n }\n });\n\n return {\n accountTokenGroups: buildAccountTokenGroups(\n queryAllAccounts,\n selectedAccount,\n accountTokenMap,\n ),\n includeNativeAndStaked: false,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-balance-fetcher.d.cts","sourceRoot":"","sources":["../../src/rpc-service/rpc-balance-fetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iCAAiC;AAK7D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,qCAAqC;AAClE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,cAAc;
|
|
1
|
+
{"version":3,"file":"rpc-balance-fetcher.d.cts","sourceRoot":"","sources":["../../src/rpc-service/rpc-balance-fetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iCAAiC;AAK7D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,qCAAqC;AAClE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,cAAc;AAIvB,OAAO,KAAK,EAAE,iBAAiB,EAAE,gEAA4D;AAE7F,OAAO,KAAK,EAAE,qBAAqB,EAAE,gCAA4B;AAIjE,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC;AAC7B,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC;AAElC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,EAAE,CAAC;IACX,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,mBAAmB,CAAC,EAAE,UAAU,EAAE,CAAC;IACnC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;IACvC,KAAK,CAAC,KAAK,EAAE;QACX,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,eAAe,EAAE,eAAe,CAAC;QACjC,WAAW,EAAE,eAAe,EAAE,CAAC;QAC/B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;KACvC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACjC,CAAC;AAQF,qBAAa,iBAAkB,YAAW,cAAc;;gBAWpD,WAAW,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,YAAY,EAClD,gBAAgB,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,aAAa,EACxD,cAAc,EAAE,MAAM;QACpB,SAAS,EAAE,qBAAqB,CAAC,WAAW,CAAC,CAAC;QAC9C,iBAAiB,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;KAC/D;IAOH,QAAQ,IAAI,OAAO;IAQb,KAAK,CAAC,EACV,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,iBAAiB,GAClB,EAAE,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA2JxE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-balance-fetcher.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-balance-fetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iCAAiC;AAK7D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,qCAAqC;AAClE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,cAAc;
|
|
1
|
+
{"version":3,"file":"rpc-balance-fetcher.d.mts","sourceRoot":"","sources":["../../src/rpc-service/rpc-balance-fetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iCAAiC;AAK7D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,qCAAqC;AAClE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,cAAc;AAIvB,OAAO,KAAK,EAAE,iBAAiB,EAAE,gEAA4D;AAE7F,OAAO,KAAK,EAAE,qBAAqB,EAAE,gCAA4B;AAIjE,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC;AAC7B,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC;AAElC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,EAAE,CAAC;IACX,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,mBAAmB,CAAC,EAAE,UAAU,EAAE,CAAC;IACnC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;IACvC,KAAK,CAAC,KAAK,EAAE;QACX,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,eAAe,EAAE,eAAe,CAAC;QACjC,WAAW,EAAE,eAAe,EAAE,CAAC;QAC/B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;KACvC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACjC,CAAC;AAQF,qBAAa,iBAAkB,YAAW,cAAc;;gBAWpD,WAAW,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,YAAY,EAClD,gBAAgB,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,aAAa,EACxD,cAAc,EAAE,MAAM;QACpB,SAAS,EAAE,qBAAqB,CAAC,WAAW,CAAC,CAAC;QAC9C,iBAAiB,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;KAC/D;IAOH,QAAQ,IAAI,OAAO;IAQb,KAAK,CAAC,EACV,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,iBAAiB,GAClB,EAAE,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA2JxE"}
|
|
@@ -20,6 +20,7 @@ import { toChecksumHexAddress, safelyExecuteWithTimeout } from "@metamask/contro
|
|
|
20
20
|
import $BN from "bn.js";
|
|
21
21
|
const BN = $importDefault($BN);
|
|
22
22
|
import { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from "../AssetsContractController.mjs";
|
|
23
|
+
import { shouldIncludeNativeToken } from "../constants.mjs";
|
|
23
24
|
import { getTokenBalancesForMultipleAddresses } from "../multicall.mjs";
|
|
24
25
|
const RPC_TIMEOUT_MS = 30000;
|
|
25
26
|
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
@@ -56,8 +57,12 @@ export class RpcBalanceFetcher {
|
|
|
56
57
|
}
|
|
57
58
|
const provider = __classPrivateFieldGet(this, _RpcBalanceFetcher_getProvider, "f").call(this, chainId);
|
|
58
59
|
await __classPrivateFieldGet(this, _RpcBalanceFetcher_instances, "m", _RpcBalanceFetcher_ensureFreshBlockData).call(this, chainId);
|
|
60
|
+
// Skip native token fetching for chains that return arbitrary large numbers
|
|
61
|
+
const includeNative = shouldIncludeNativeToken(chainId);
|
|
59
62
|
const balanceResult = await safelyExecuteWithTimeout(async () => {
|
|
60
|
-
return await getTokenBalancesForMultipleAddresses(accountTokenGroups, chainId, provider,
|
|
63
|
+
return await getTokenBalancesForMultipleAddresses(accountTokenGroups, chainId, provider,
|
|
64
|
+
// Skip native for Tempo chains
|
|
65
|
+
includeNative && includeNativeAndStaked, includeNativeAndStaked);
|
|
61
66
|
}, true, RPC_TIMEOUT_MS);
|
|
62
67
|
// If timeout or error occurred, return empty array for this chain
|
|
63
68
|
if (!balanceResult) {
|
|
@@ -65,7 +70,7 @@ export class RpcBalanceFetcher {
|
|
|
65
70
|
}
|
|
66
71
|
const { tokenBalances, stakedBalances } = balanceResult;
|
|
67
72
|
const chainResults = [];
|
|
68
|
-
if (includeNativeAndStaked) {
|
|
73
|
+
if (includeNative && includeNativeAndStaked) {
|
|
69
74
|
// Add native token entries for all addresses being processed
|
|
70
75
|
const allAddressesForNative = new Set();
|
|
71
76
|
accountTokenGroups.forEach((group) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-balance-fetcher.mjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-balance-fetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Web3Provider } from '@ethersproject/providers';\nimport {\n toChecksumHexAddress,\n safelyExecuteWithTimeout,\n} from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkClient } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from '../AssetsContractController';\nimport type { UnprocessedTokens } from '../multi-chain-accounts-service/api-balance-fetcher';\nimport { getTokenBalancesForMultipleAddresses } from '../multicall';\nimport type { TokensControllerState } from '../TokensController';\n\nconst RPC_TIMEOUT_MS = 30000;\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nexport type ProcessedBalance = {\n success: boolean;\n value?: BN;\n account: ChecksumAddress;\n token: ChecksumAddress;\n chainId: ChainIdHex;\n};\n\nexport type BalanceFetchResult = {\n balances: ProcessedBalance[];\n unprocessedChainIds?: ChainIdHex[];\n unprocessedTokens?: UnprocessedTokens;\n};\n\nexport type BalanceFetcher = {\n supports(chainId: ChainIdHex): boolean;\n fetch(input: {\n chainIds: ChainIdHex[];\n queryAllAccounts: boolean;\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n unprocessedTokens?: UnprocessedTokens;\n }): Promise<BalanceFetchResult>;\n};\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\nexport class RpcBalanceFetcher implements BalanceFetcher {\n readonly #getProvider: (chainId: ChainIdHex) => Web3Provider;\n\n readonly #getNetworkClient: (chainId: ChainIdHex) => NetworkClient;\n\n readonly #getTokensState: () => {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n };\n\n constructor(\n getProvider: (chainId: ChainIdHex) => Web3Provider,\n getNetworkClient: (chainId: ChainIdHex) => NetworkClient,\n getTokensState: () => {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n },\n ) {\n this.#getProvider = getProvider;\n this.#getNetworkClient = getNetworkClient;\n this.#getTokensState = getTokensState;\n }\n\n supports(): boolean {\n return true; // fallback – supports every chain\n }\n\n #getStakingContractAddress(chainId: ChainIdHex): string | undefined {\n return STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainId];\n }\n\n async fetch({\n chainIds,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n unprocessedTokens,\n }: Parameters<BalanceFetcher['fetch']>[0]): Promise<BalanceFetchResult> {\n // Process all chains in parallel for better performance\n const chainProcessingPromises = chainIds.map(async (chainId) => {\n // if there are unprocessed tokens for a chain, it means the chain was partially processed.\n // because of this, we need to build distinct account <-> token groups to process\n const hasUnprocessedTokensForChain = queryAllAccounts\n ? Object.values(unprocessedTokens ?? {}).some((chainMap) =>\n Boolean(chainMap[chainId] && chainMap[chainId].length > 0),\n )\n : Boolean(\n unprocessedTokens?.[selectedAccount.toLowerCase()]?.[chainId] &&\n unprocessedTokens[selectedAccount.toLowerCase()][chainId].length >\n 0,\n );\n\n const tokensState = this.#getTokensState();\n const { accountTokenGroups, includeNativeAndStaked } =\n hasUnprocessedTokensForChain\n ? buildUnprocessedAccountTokenGroupsStatic(\n chainId,\n queryAllAccounts,\n selectedAccount,\n unprocessedTokens as UnprocessedTokens,\n )\n : buildAccountTokenGroupsStatic(\n chainId,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n tokensState.allTokens,\n tokensState.allDetectedTokens,\n );\n\n if (!accountTokenGroups.length) {\n return [];\n }\n\n const provider = this.#getProvider(chainId);\n await this.#ensureFreshBlockData(chainId);\n\n const balanceResult = await safelyExecuteWithTimeout(\n async () => {\n return await getTokenBalancesForMultipleAddresses(\n accountTokenGroups,\n chainId,\n provider,\n includeNativeAndStaked,\n includeNativeAndStaked,\n );\n },\n true,\n RPC_TIMEOUT_MS,\n );\n\n // If timeout or error occurred, return empty array for this chain\n if (!balanceResult) {\n return [];\n }\n\n const { tokenBalances, stakedBalances } = balanceResult;\n const chainResults: ProcessedBalance[] = [];\n\n if (includeNativeAndStaked) {\n // Add native token entries for all addresses being processed\n const allAddressesForNative = new Set<string>();\n accountTokenGroups.forEach((group) => {\n allAddressesForNative.add(group.accountAddress);\n });\n\n // Ensure native token entries exist for all addresses\n allAddressesForNative.forEach((address) => {\n const nativeBalance = tokenBalances[ZERO_ADDRESS]?.[address] || null;\n chainResults.push({\n success: true,\n value: nativeBalance || new BN('0'),\n account: address as ChecksumAddress,\n token: ZERO_ADDRESS,\n chainId,\n });\n });\n }\n\n // Add other token balances\n Object.entries(tokenBalances).forEach(([tokenAddr, balances]) => {\n // Skip native token since we handled it explicitly above\n if (tokenAddr === ZERO_ADDRESS) {\n return;\n }\n Object.entries(balances).forEach(([acct, bn]) => {\n chainResults.push({\n success: bn !== null,\n value: bn,\n account: acct as ChecksumAddress,\n token: checksum(tokenAddr),\n chainId,\n });\n });\n });\n\n // Add staked balances for all addresses being processed\n const stakingContractAddress = this.#getStakingContractAddress(chainId);\n if (includeNativeAndStaked && stakingContractAddress) {\n // Get all unique addresses being processed for this chain\n const allAddresses = new Set<string>();\n accountTokenGroups.forEach((group) => {\n allAddresses.add(group.accountAddress);\n });\n\n // Add staked balance entry for each address\n const checksummedStakingAddress = checksum(stakingContractAddress);\n allAddresses.forEach((address) => {\n const stakedBalance = stakedBalances?.[address] ?? null;\n chainResults.push({\n success: true,\n value: stakedBalance ?? new BN('0'),\n account: address as ChecksumAddress,\n token: checksummedStakingAddress,\n chainId,\n });\n });\n }\n\n return chainResults;\n });\n\n // Wait for all chains to complete (or fail) and collect results\n const chainResultsArray = await Promise.allSettled(chainProcessingPromises);\n const results: ProcessedBalance[] = [];\n\n chainResultsArray.forEach((chainResult) => {\n if (chainResult.status === 'fulfilled') {\n results.push(...chainResult.value);\n }\n });\n\n return { balances: results };\n }\n\n /**\n * Ensures that the block tracker has the latest block data before performing multicall operations.\n * This is a temporary fix to ensure that the block number is up to date.\n *\n * @param chainId - The chain id to update block data for.\n */\n async #ensureFreshBlockData(chainId: Hex): Promise<void> {\n // Force fresh block data before multicall\n // TODO: This is a temporary fix to ensure that the block number is up to date.\n // We should remove this once we have a better solution for this on the block tracker controller.\n const networkClient = this.#getNetworkClient(chainId);\n await networkClient.blockTracker?.checkForLatestBlock?.();\n }\n}\n\ntype AccountTokenGroup = {\n accountAddress: ChecksumAddress;\n tokenAddresses: ChecksumAddress[];\n};\n\nfunction buildAccountTokenGroups(\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n accountTokenMap: { [account: string]: string[] },\n): AccountTokenGroup[] {\n const pairs: {\n accountAddress: ChecksumAddress;\n tokenAddress: ChecksumAddress;\n }[] = [];\n\n const add = ([account, tokens]: [string, string[]]): void => {\n const checksumAccount = checksum(account);\n const shouldInclude =\n queryAllAccounts || checksumAccount === checksum(selectedAccount);\n if (!shouldInclude) {\n return;\n }\n tokens.forEach((token: string) =>\n pairs.push({\n accountAddress: account as ChecksumAddress,\n tokenAddress: checksum(token),\n }),\n );\n };\n\n Object.entries(accountTokenMap).forEach(add);\n\n // group by account\n const map = new Map<ChecksumAddress, ChecksumAddress[]>();\n pairs.forEach(({ accountAddress, tokenAddress }) => {\n if (!map.has(accountAddress)) {\n map.set(accountAddress, []);\n }\n const tokens = map.get(accountAddress);\n if (tokens) {\n tokens.push(tokenAddress);\n }\n });\n\n return Array.from(map.entries()).map(([accountAddress, tokenAddresses]) => ({\n accountAddress,\n tokenAddresses,\n }));\n}\n\n/**\n * Merges imported & detected tokens for the requested chain and returns a list\n * of `{ accountAddress, tokenAddresses[] }` suitable for getTokenBalancesForMultipleAddresses.\n *\n * @param chainId - The chain ID to build account token groups for\n * @param queryAllAccounts - Whether to query all accounts or just the selected one\n * @param selectedAccount - The currently selected account\n * @param allAccounts - All available accounts\n * @param allTokens - All tokens from TokensController\n * @param allDetectedTokens - All detected tokens from TokensController\n * @returns Array of account/token groups for multicall\n */\nfunction buildAccountTokenGroupsStatic(\n chainId: ChainIdHex,\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n allAccounts: InternalAccount[],\n allTokens: TokensControllerState['allTokens'],\n allDetectedTokens: TokensControllerState['allDetectedTokens'],\n): {\n accountTokenGroups: AccountTokenGroup[];\n includeNativeAndStaked: true;\n} {\n const accountTokenMap: { [account: string]: string[] } = {};\n\n // Add all tokens\n Object.entries(allTokens[chainId] ?? {}).forEach(([account, tokens]) => {\n accountTokenMap[account] = tokens.map((token) => token.address);\n });\n\n // Add all detected tokens\n Object.entries(allDetectedTokens[chainId] ?? {}).forEach(\n ([account, tokens]) => {\n if (!accountTokenMap[account]) {\n accountTokenMap[account] = [];\n }\n accountTokenMap[account] = Array.from(\n new Set([\n ...accountTokenMap[account],\n ...tokens.map((token) => token.address),\n ]),\n );\n },\n );\n\n // Add native tokens\n if (queryAllAccounts) {\n allAccounts.forEach((a) => {\n accountTokenMap[a.address] ??= [];\n accountTokenMap[a.address].push(ZERO_ADDRESS);\n });\n } else {\n accountTokenMap[selectedAccount] ??= [];\n accountTokenMap[selectedAccount].push(ZERO_ADDRESS);\n }\n\n return {\n accountTokenGroups: buildAccountTokenGroups(\n queryAllAccounts,\n selectedAccount,\n accountTokenMap,\n ),\n includeNativeAndStaked: true,\n };\n}\n\nfunction buildUnprocessedAccountTokenGroupsStatic(\n chainId: ChainIdHex,\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n unprocessedTokens: UnprocessedTokens,\n): {\n accountTokenGroups: AccountTokenGroup[];\n includeNativeAndStaked: false;\n} {\n const accountTokenMap: { [account: string]: string[] } = {};\n Object.entries(unprocessedTokens).forEach(([account, tokens]) => {\n const lowercaseAccount = account.toLowerCase();\n if (\n queryAllAccounts ||\n lowercaseAccount === selectedAccount.toLowerCase()\n ) {\n const tokenAddresses =\n tokens?.[chainId]?.map((tokenAddress) => tokenAddress.toLowerCase()) ??\n [];\n accountTokenMap[lowercaseAccount] = tokenAddresses;\n }\n });\n\n return {\n accountTokenGroups: buildAccountTokenGroups(\n queryAllAccounts,\n selectedAccount,\n accountTokenMap,\n ),\n includeNativeAndStaked: false,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rpc-balance-fetcher.mjs","sourceRoot":"","sources":["../../src/rpc-service/rpc-balance-fetcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AACA,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACzB,mCAAmC;AAIpC,OAAO,GAAE,cAAc;;AAEvB,OAAO,EAAE,mCAAmC,EAAE,wCAAoC;AAClF,OAAO,EAAE,wBAAwB,EAAE,yBAAqB;AAExD,OAAO,EAAE,oCAAoC,EAAE,yBAAqB;AAGpE,MAAM,cAAc,GAAG,KAAK,CAAC;AA8B7B,MAAM,YAAY,GAChB,4CAA+D,CAAC;AAElE,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAmB,EAAE,CACjD,oBAAoB,CAAC,IAAI,CAAoB,CAAC;AAEhD,MAAM,OAAO,iBAAiB;IAU5B,YACE,WAAkD,EAClD,gBAAwD,EACxD,cAGC;;QAfM,iDAAoD;QAEpD,sDAA0D;QAE1D,oDAGP;QAUA,uBAAA,IAAI,kCAAgB,WAAW,MAAA,CAAC;QAChC,uBAAA,IAAI,uCAAqB,gBAAgB,MAAA,CAAC;QAC1C,uBAAA,IAAI,qCAAmB,cAAc,MAAA,CAAC;IACxC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,CAAC,kCAAkC;IACjD,CAAC;IAMD,KAAK,CAAC,KAAK,CAAC,EACV,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,iBAAiB,GACsB;QACvC,wDAAwD;QACxD,MAAM,uBAAuB,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7D,2FAA2F;YAC3F,iFAAiF;YACjF,MAAM,4BAA4B,GAAG,gBAAgB;gBACnD,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAC3D;gBACH,CAAC,CAAC,OAAO,CACL,iBAAiB,EAAE,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;oBAC3D,iBAAiB,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM;wBAC9D,CAAC,CACN,CAAC;YAEN,MAAM,WAAW,GAAG,uBAAA,IAAI,yCAAgB,MAApB,IAAI,CAAkB,CAAC;YAC3C,MAAM,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,GAClD,4BAA4B;gBAC1B,CAAC,CAAC,wCAAwC,CACtC,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,iBAAsC,CACvC;gBACH,CAAC,CAAC,6BAA6B,CAC3B,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,WAAW,CAAC,SAAS,EACrB,WAAW,CAAC,iBAAiB,CAC9B,CAAC;YAER,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC;gBAC/B,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,QAAQ,GAAG,uBAAA,IAAI,sCAAa,MAAjB,IAAI,EAAc,OAAO,CAAC,CAAC;YAC5C,MAAM,uBAAA,IAAI,6EAAsB,MAA1B,IAAI,EAAuB,OAAO,CAAC,CAAC;YAE1C,4EAA4E;YAC5E,MAAM,aAAa,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;YAExD,MAAM,aAAa,GAAG,MAAM,wBAAwB,CAClD,KAAK,IAAI,EAAE;gBACT,OAAO,MAAM,oCAAoC,CAC/C,kBAAkB,EAClB,OAAO,EACP,QAAQ;gBACR,+BAA+B;gBAC/B,aAAa,IAAI,sBAAsB,EACvC,sBAAsB,CACvB,CAAC;YACJ,CAAC,EACD,IAAI,EACJ,cAAc,CACf,CAAC;YAEF,kEAAkE;YAClE,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,aAAa,CAAC;YACxD,MAAM,YAAY,GAAuB,EAAE,CAAC;YAE5C,IAAI,aAAa,IAAI,sBAAsB,EAAE,CAAC;gBAC5C,6DAA6D;gBAC7D,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;gBAChD,kBAAkB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;oBACnC,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;gBAClD,CAAC,CAAC,CAAC;gBAEH,sDAAsD;gBACtD,qBAAqB,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBACxC,MAAM,aAAa,GAAG,aAAa,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;oBACrE,YAAY,CAAC,IAAI,CAAC;wBAChB,OAAO,EAAE,IAAI;wBACb,KAAK,EAAE,aAAa,IAAI,IAAI,EAAE,CAAC,GAAG,CAAC;wBACnC,OAAO,EAAE,OAA0B;wBACnC,KAAK,EAAE,YAAY;wBACnB,OAAO;qBACR,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC;YAED,2BAA2B;YAC3B,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE;gBAC9D,yDAAyD;gBACzD,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;oBAC/B,OAAO;gBACT,CAAC;gBACD,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;oBAC9C,YAAY,CAAC,IAAI,CAAC;wBAChB,OAAO,EAAE,EAAE,KAAK,IAAI;wBACpB,KAAK,EAAE,EAAE;wBACT,OAAO,EAAE,IAAuB;wBAChC,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC;wBAC1B,OAAO;qBACR,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,wDAAwD;YACxD,MAAM,sBAAsB,GAAG,uBAAA,IAAI,kFAA2B,MAA/B,IAAI,EAA4B,OAAO,CAAC,CAAC;YACxE,IAAI,sBAAsB,IAAI,sBAAsB,EAAE,CAAC;gBACrD,0DAA0D;gBAC1D,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;gBACvC,kBAAkB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;oBACnC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;gBACzC,CAAC,CAAC,CAAC;gBAEH,4CAA4C;gBAC5C,MAAM,yBAAyB,GAAG,QAAQ,CAAC,sBAAsB,CAAC,CAAC;gBACnE,YAAY,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBAC/B,MAAM,aAAa,GAAG,cAAc,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;oBACxD,YAAY,CAAC,IAAI,CAAC;wBAChB,OAAO,EAAE,IAAI;wBACb,KAAK,EAAE,aAAa,IAAI,IAAI,EAAE,CAAC,GAAG,CAAC;wBACnC,OAAO,EAAE,OAA0B;wBACnC,KAAK,EAAE,yBAAyB;wBAChC,OAAO;qBACR,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC;YAED,OAAO,YAAY,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,gEAAgE;QAChE,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;QAC5E,MAAM,OAAO,GAAuB,EAAE,CAAC;QAEvC,iBAAiB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;YACxC,IAAI,WAAW,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBACvC,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;YACrC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAC/B,CAAC;CAeF;2SArK4B,OAAmB;IAC5C,OAAO,mCAAmC,CAAC,OAAO,CAAC,CAAC;AACtD,CAAC;AAsJD;;;;;GAKG;AACH,KAAK,kDAAuB,OAAY;IACtC,0CAA0C;IAC1C,+EAA+E;IAC/E,iGAAiG;IACjG,MAAM,aAAa,GAAG,uBAAA,IAAI,2CAAkB,MAAtB,IAAI,EAAmB,OAAO,CAAC,CAAC;IACtD,MAAM,aAAa,CAAC,YAAY,EAAE,mBAAmB,EAAE,EAAE,CAAC;AAC5D,CAAC;AAQH,SAAS,uBAAuB,CAC9B,gBAAyB,EACzB,eAAgC,EAChC,eAAgD;IAEhD,MAAM,KAAK,GAGL,EAAE,CAAC;IAET,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAqB,EAAQ,EAAE;QAC1D,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,aAAa,GACjB,gBAAgB,IAAI,eAAe,KAAK,QAAQ,CAAC,eAAe,CAAC,CAAC;QACpE,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,EAAE,CAC/B,KAAK,CAAC,IAAI,CAAC;YACT,cAAc,EAAE,OAA0B;YAC1C,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC;SAC9B,CAAC,CACH,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE7C,mBAAmB;IACnB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsC,CAAC;IAC1D,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE,EAAE,EAAE;QACjD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC9B,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACvC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,EAAE,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1E,cAAc;QACd,cAAc;KACf,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,6BAA6B,CACpC,OAAmB,EACnB,gBAAyB,EACzB,eAAgC,EAChC,WAA8B,EAC9B,SAA6C,EAC7C,iBAA6D;IAK7D,MAAM,eAAe,GAAoC,EAAE,CAAC;IAE5D,iBAAiB;IACjB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE;QACrE,eAAe,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,0BAA0B;IAC1B,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CACtD,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE;QACpB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAChC,CAAC;QACD,eAAe,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,CACnC,IAAI,GAAG,CAAC;YACN,GAAG,eAAe,CAAC,OAAO,CAAC;YAC3B,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;SACxC,CAAC,CACH,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,oBAAoB;IACpB,IAAI,gBAAgB,EAAE,CAAC;QACrB,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;;YACxB,eAAe,MAAC,CAAC,CAAC,OAAO,MAAzB,eAAe,OAAgB,EAAE,EAAC;YAClC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,eAAe,CAAC,eAAe,MAA/B,eAAe,CAAC,eAAe,IAAM,EAAE,EAAC;QACxC,eAAe,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACtD,CAAC;IAED,OAAO;QACL,kBAAkB,EAAE,uBAAuB,CACzC,gBAAgB,EAChB,eAAe,EACf,eAAe,CAChB;QACD,sBAAsB,EAAE,IAAI;KAC7B,CAAC;AACJ,CAAC;AAED,SAAS,wCAAwC,CAC/C,OAAmB,EACnB,gBAAyB,EACzB,eAAgC,EAChC,iBAAoC;IAKpC,MAAM,eAAe,GAAoC,EAAE,CAAC;IAC5D,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE;QAC9D,MAAM,gBAAgB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QAC/C,IACE,gBAAgB;YAChB,gBAAgB,KAAK,eAAe,CAAC,WAAW,EAAE,EAClD,CAAC;YACD,MAAM,cAAc,GAClB,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;gBACpE,EAAE,CAAC;YACL,eAAe,CAAC,gBAAgB,CAAC,GAAG,cAAc,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,kBAAkB,EAAE,uBAAuB,CACzC,gBAAgB,EAChB,eAAe,EACf,eAAe,CAChB;QACD,sBAAsB,EAAE,KAAK;KAC9B,CAAC;AACJ,CAAC","sourcesContent":["import type { Web3Provider } from '@ethersproject/providers';\nimport {\n toChecksumHexAddress,\n safelyExecuteWithTimeout,\n} from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkClient } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from '../AssetsContractController';\nimport { shouldIncludeNativeToken } from '../constants';\nimport type { UnprocessedTokens } from '../multi-chain-accounts-service/api-balance-fetcher';\nimport { getTokenBalancesForMultipleAddresses } from '../multicall';\nimport type { TokensControllerState } from '../TokensController';\n\nconst RPC_TIMEOUT_MS = 30000;\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nexport type ProcessedBalance = {\n success: boolean;\n value?: BN;\n account: ChecksumAddress;\n token: ChecksumAddress;\n chainId: ChainIdHex;\n};\n\nexport type BalanceFetchResult = {\n balances: ProcessedBalance[];\n unprocessedChainIds?: ChainIdHex[];\n unprocessedTokens?: UnprocessedTokens;\n};\n\nexport type BalanceFetcher = {\n supports(chainId: ChainIdHex): boolean;\n fetch(input: {\n chainIds: ChainIdHex[];\n queryAllAccounts: boolean;\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n unprocessedTokens?: UnprocessedTokens;\n }): Promise<BalanceFetchResult>;\n};\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\nexport class RpcBalanceFetcher implements BalanceFetcher {\n readonly #getProvider: (chainId: ChainIdHex) => Web3Provider;\n\n readonly #getNetworkClient: (chainId: ChainIdHex) => NetworkClient;\n\n readonly #getTokensState: () => {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n };\n\n constructor(\n getProvider: (chainId: ChainIdHex) => Web3Provider,\n getNetworkClient: (chainId: ChainIdHex) => NetworkClient,\n getTokensState: () => {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n },\n ) {\n this.#getProvider = getProvider;\n this.#getNetworkClient = getNetworkClient;\n this.#getTokensState = getTokensState;\n }\n\n supports(): boolean {\n return true; // fallback – supports every chain\n }\n\n #getStakingContractAddress(chainId: ChainIdHex): string | undefined {\n return STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainId];\n }\n\n async fetch({\n chainIds,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n unprocessedTokens,\n }: Parameters<BalanceFetcher['fetch']>[0]): Promise<BalanceFetchResult> {\n // Process all chains in parallel for better performance\n const chainProcessingPromises = chainIds.map(async (chainId) => {\n // if there are unprocessed tokens for a chain, it means the chain was partially processed.\n // because of this, we need to build distinct account <-> token groups to process\n const hasUnprocessedTokensForChain = queryAllAccounts\n ? Object.values(unprocessedTokens ?? {}).some((chainMap) =>\n Boolean(chainMap[chainId] && chainMap[chainId].length > 0),\n )\n : Boolean(\n unprocessedTokens?.[selectedAccount.toLowerCase()]?.[chainId] &&\n unprocessedTokens[selectedAccount.toLowerCase()][chainId].length >\n 0,\n );\n\n const tokensState = this.#getTokensState();\n const { accountTokenGroups, includeNativeAndStaked } =\n hasUnprocessedTokensForChain\n ? buildUnprocessedAccountTokenGroupsStatic(\n chainId,\n queryAllAccounts,\n selectedAccount,\n unprocessedTokens as UnprocessedTokens,\n )\n : buildAccountTokenGroupsStatic(\n chainId,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n tokensState.allTokens,\n tokensState.allDetectedTokens,\n );\n\n if (!accountTokenGroups.length) {\n return [];\n }\n\n const provider = this.#getProvider(chainId);\n await this.#ensureFreshBlockData(chainId);\n\n // Skip native token fetching for chains that return arbitrary large numbers\n const includeNative = shouldIncludeNativeToken(chainId);\n\n const balanceResult = await safelyExecuteWithTimeout(\n async () => {\n return await getTokenBalancesForMultipleAddresses(\n accountTokenGroups,\n chainId,\n provider,\n // Skip native for Tempo chains\n includeNative && includeNativeAndStaked,\n includeNativeAndStaked,\n );\n },\n true,\n RPC_TIMEOUT_MS,\n );\n\n // If timeout or error occurred, return empty array for this chain\n if (!balanceResult) {\n return [];\n }\n\n const { tokenBalances, stakedBalances } = balanceResult;\n const chainResults: ProcessedBalance[] = [];\n\n if (includeNative && includeNativeAndStaked) {\n // Add native token entries for all addresses being processed\n const allAddressesForNative = new Set<string>();\n accountTokenGroups.forEach((group) => {\n allAddressesForNative.add(group.accountAddress);\n });\n\n // Ensure native token entries exist for all addresses\n allAddressesForNative.forEach((address) => {\n const nativeBalance = tokenBalances[ZERO_ADDRESS]?.[address] || null;\n chainResults.push({\n success: true,\n value: nativeBalance || new BN('0'),\n account: address as ChecksumAddress,\n token: ZERO_ADDRESS,\n chainId,\n });\n });\n }\n\n // Add other token balances\n Object.entries(tokenBalances).forEach(([tokenAddr, balances]) => {\n // Skip native token since we handled it explicitly above\n if (tokenAddr === ZERO_ADDRESS) {\n return;\n }\n Object.entries(balances).forEach(([acct, bn]) => {\n chainResults.push({\n success: bn !== null,\n value: bn,\n account: acct as ChecksumAddress,\n token: checksum(tokenAddr),\n chainId,\n });\n });\n });\n\n // Add staked balances for all addresses being processed\n const stakingContractAddress = this.#getStakingContractAddress(chainId);\n if (includeNativeAndStaked && stakingContractAddress) {\n // Get all unique addresses being processed for this chain\n const allAddresses = new Set<string>();\n accountTokenGroups.forEach((group) => {\n allAddresses.add(group.accountAddress);\n });\n\n // Add staked balance entry for each address\n const checksummedStakingAddress = checksum(stakingContractAddress);\n allAddresses.forEach((address) => {\n const stakedBalance = stakedBalances?.[address] ?? null;\n chainResults.push({\n success: true,\n value: stakedBalance ?? new BN('0'),\n account: address as ChecksumAddress,\n token: checksummedStakingAddress,\n chainId,\n });\n });\n }\n\n return chainResults;\n });\n\n // Wait for all chains to complete (or fail) and collect results\n const chainResultsArray = await Promise.allSettled(chainProcessingPromises);\n const results: ProcessedBalance[] = [];\n\n chainResultsArray.forEach((chainResult) => {\n if (chainResult.status === 'fulfilled') {\n results.push(...chainResult.value);\n }\n });\n\n return { balances: results };\n }\n\n /**\n * Ensures that the block tracker has the latest block data before performing multicall operations.\n * This is a temporary fix to ensure that the block number is up to date.\n *\n * @param chainId - The chain id to update block data for.\n */\n async #ensureFreshBlockData(chainId: Hex): Promise<void> {\n // Force fresh block data before multicall\n // TODO: This is a temporary fix to ensure that the block number is up to date.\n // We should remove this once we have a better solution for this on the block tracker controller.\n const networkClient = this.#getNetworkClient(chainId);\n await networkClient.blockTracker?.checkForLatestBlock?.();\n }\n}\n\ntype AccountTokenGroup = {\n accountAddress: ChecksumAddress;\n tokenAddresses: ChecksumAddress[];\n};\n\nfunction buildAccountTokenGroups(\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n accountTokenMap: { [account: string]: string[] },\n): AccountTokenGroup[] {\n const pairs: {\n accountAddress: ChecksumAddress;\n tokenAddress: ChecksumAddress;\n }[] = [];\n\n const add = ([account, tokens]: [string, string[]]): void => {\n const checksumAccount = checksum(account);\n const shouldInclude =\n queryAllAccounts || checksumAccount === checksum(selectedAccount);\n if (!shouldInclude) {\n return;\n }\n tokens.forEach((token: string) =>\n pairs.push({\n accountAddress: account as ChecksumAddress,\n tokenAddress: checksum(token),\n }),\n );\n };\n\n Object.entries(accountTokenMap).forEach(add);\n\n // group by account\n const map = new Map<ChecksumAddress, ChecksumAddress[]>();\n pairs.forEach(({ accountAddress, tokenAddress }) => {\n if (!map.has(accountAddress)) {\n map.set(accountAddress, []);\n }\n const tokens = map.get(accountAddress);\n if (tokens) {\n tokens.push(tokenAddress);\n }\n });\n\n return Array.from(map.entries()).map(([accountAddress, tokenAddresses]) => ({\n accountAddress,\n tokenAddresses,\n }));\n}\n\n/**\n * Merges imported & detected tokens for the requested chain and returns a list\n * of `{ accountAddress, tokenAddresses[] }` suitable for getTokenBalancesForMultipleAddresses.\n *\n * @param chainId - The chain ID to build account token groups for\n * @param queryAllAccounts - Whether to query all accounts or just the selected one\n * @param selectedAccount - The currently selected account\n * @param allAccounts - All available accounts\n * @param allTokens - All tokens from TokensController\n * @param allDetectedTokens - All detected tokens from TokensController\n * @returns Array of account/token groups for multicall\n */\nfunction buildAccountTokenGroupsStatic(\n chainId: ChainIdHex,\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n allAccounts: InternalAccount[],\n allTokens: TokensControllerState['allTokens'],\n allDetectedTokens: TokensControllerState['allDetectedTokens'],\n): {\n accountTokenGroups: AccountTokenGroup[];\n includeNativeAndStaked: true;\n} {\n const accountTokenMap: { [account: string]: string[] } = {};\n\n // Add all tokens\n Object.entries(allTokens[chainId] ?? {}).forEach(([account, tokens]) => {\n accountTokenMap[account] = tokens.map((token) => token.address);\n });\n\n // Add all detected tokens\n Object.entries(allDetectedTokens[chainId] ?? {}).forEach(\n ([account, tokens]) => {\n if (!accountTokenMap[account]) {\n accountTokenMap[account] = [];\n }\n accountTokenMap[account] = Array.from(\n new Set([\n ...accountTokenMap[account],\n ...tokens.map((token) => token.address),\n ]),\n );\n },\n );\n\n // Add native tokens\n if (queryAllAccounts) {\n allAccounts.forEach((a) => {\n accountTokenMap[a.address] ??= [];\n accountTokenMap[a.address].push(ZERO_ADDRESS);\n });\n } else {\n accountTokenMap[selectedAccount] ??= [];\n accountTokenMap[selectedAccount].push(ZERO_ADDRESS);\n }\n\n return {\n accountTokenGroups: buildAccountTokenGroups(\n queryAllAccounts,\n selectedAccount,\n accountTokenMap,\n ),\n includeNativeAndStaked: true,\n };\n}\n\nfunction buildUnprocessedAccountTokenGroupsStatic(\n chainId: ChainIdHex,\n queryAllAccounts: boolean,\n selectedAccount: ChecksumAddress,\n unprocessedTokens: UnprocessedTokens,\n): {\n accountTokenGroups: AccountTokenGroup[];\n includeNativeAndStaked: false;\n} {\n const accountTokenMap: { [account: string]: string[] } = {};\n Object.entries(unprocessedTokens).forEach(([account, tokens]) => {\n const lowercaseAccount = account.toLowerCase();\n if (\n queryAllAccounts ||\n lowercaseAccount === selectedAccount.toLowerCase()\n ) {\n const tokenAddresses =\n tokens?.[chainId]?.map((tokenAddress) => tokenAddress.toLowerCase()) ??\n [];\n accountTokenMap[lowercaseAccount] = tokenAddresses;\n }\n });\n\n return {\n accountTokenGroups: buildAccountTokenGroups(\n queryAllAccounts,\n selectedAccount,\n accountTokenMap,\n ),\n includeNativeAndStaked: false,\n };\n}\n"]}
|
|
@@ -6,6 +6,7 @@ const keyring_api_1 = require("@metamask/keyring-api");
|
|
|
6
6
|
const utils_1 = require("@metamask/utils");
|
|
7
7
|
const reselect_1 = require("reselect");
|
|
8
8
|
const stringify_balance_1 = require("./stringify-balance.cjs");
|
|
9
|
+
const constants_1 = require("../constants.cjs");
|
|
9
10
|
const codefi_v2_1 = require("../token-prices-service/codefi-v2.cjs");
|
|
10
11
|
// Asset Tron Filters
|
|
11
12
|
exports.TRON_RESOURCE = {
|
|
@@ -50,6 +51,10 @@ const selectAllEvmAccountNativeBalances = createAssetListSelector([
|
|
|
50
51
|
var _a;
|
|
51
52
|
const groupAssets = {};
|
|
52
53
|
for (const [chainId, chainAccounts] of Object.entries(accountsByChainId)) {
|
|
54
|
+
// Skip native tokens on Tempo networks
|
|
55
|
+
if (!(0, constants_1.shouldIncludeNativeToken)(chainId)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
53
58
|
for (const [accountAddress, accountBalance] of Object.entries(chainAccounts)) {
|
|
54
59
|
const account = accountsMap[accountAddress.toLowerCase()];
|
|
55
60
|
if (!account) {
|