@metamask/assets-controllers 105.0.0 → 106.0.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 +73 -1
- package/dist/AccountTrackerController-method-action-types.cjs.map +1 -1
- package/dist/AccountTrackerController-method-action-types.d.cts +24 -1
- package/dist/AccountTrackerController-method-action-types.d.cts.map +1 -1
- package/dist/AccountTrackerController-method-action-types.d.mts +24 -1
- package/dist/AccountTrackerController-method-action-types.d.mts.map +1 -1
- package/dist/AccountTrackerController-method-action-types.mjs.map +1 -1
- package/dist/AccountTrackerController.cjs +2 -0
- 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 +2 -0
- package/dist/AccountTrackerController.mjs.map +1 -1
- package/dist/TokenBalancesController-method-action-types.cjs.map +1 -1
- package/dist/TokenBalancesController-method-action-types.d.cts +9 -1
- package/dist/TokenBalancesController-method-action-types.d.cts.map +1 -1
- package/dist/TokenBalancesController-method-action-types.d.mts +9 -1
- package/dist/TokenBalancesController-method-action-types.d.mts.map +1 -1
- package/dist/TokenBalancesController-method-action-types.mjs.map +1 -1
- package/dist/TokenBalancesController.cjs +19 -2
- package/dist/TokenBalancesController.cjs.map +1 -1
- package/dist/TokenBalancesController.d.cts.map +1 -1
- package/dist/TokenBalancesController.d.mts.map +1 -1
- package/dist/TokenBalancesController.mjs +20 -3
- package/dist/TokenBalancesController.mjs.map +1 -1
- package/dist/TokenDetectionController-method-action-types.cjs.map +1 -1
- package/dist/TokenDetectionController-method-action-types.d.cts +1 -1
- package/dist/TokenDetectionController-method-action-types.d.mts +1 -1
- package/dist/TokenDetectionController-method-action-types.mjs.map +1 -1
- package/dist/TokenDetectionController.cjs +139 -64
- package/dist/TokenDetectionController.cjs.map +1 -1
- package/dist/TokenDetectionController.d.cts +8 -12
- package/dist/TokenDetectionController.d.cts.map +1 -1
- package/dist/TokenDetectionController.d.mts +8 -12
- package/dist/TokenDetectionController.d.mts.map +1 -1
- package/dist/TokenDetectionController.mjs +140 -65
- package/dist/TokenDetectionController.mjs.map +1 -1
- package/dist/TokenListService.cjs +107 -0
- package/dist/TokenListService.cjs.map +1 -0
- package/dist/TokenListService.d.cts +40 -0
- package/dist/TokenListService.d.cts.map +1 -0
- package/dist/TokenListService.d.mts +40 -0
- package/dist/TokenListService.d.mts.map +1 -0
- package/dist/TokenListService.mjs +102 -0
- package/dist/TokenListService.mjs.map +1 -0
- package/dist/TokensController.cjs +46 -32
- package/dist/TokensController.cjs.map +1 -1
- package/dist/TokensController.d.cts +5 -3
- package/dist/TokensController.d.cts.map +1 -1
- package/dist/TokensController.d.mts +5 -3
- package/dist/TokensController.d.mts.map +1 -1
- package/dist/TokensController.mjs +46 -32
- package/dist/TokensController.mjs.map +1 -1
- package/dist/constants.cjs +32 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +15 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +15 -0
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +31 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/index.cjs +4 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/selectors/token-selectors.d.cts +0 -36
- package/dist/selectors/token-selectors.d.cts.map +1 -1
- package/dist/selectors/token-selectors.d.mts +0 -36
- package/dist/selectors/token-selectors.d.mts.map +1 -1
- package/dist/token-prices-service/codefi-v2.cjs +1 -0
- package/dist/token-prices-service/codefi-v2.cjs.map +1 -1
- package/dist/token-prices-service/codefi-v2.d.cts +2 -1
- package/dist/token-prices-service/codefi-v2.d.cts.map +1 -1
- package/dist/token-prices-service/codefi-v2.d.mts +2 -1
- package/dist/token-prices-service/codefi-v2.d.mts.map +1 -1
- package/dist/token-prices-service/codefi-v2.mjs +1 -0
- package/dist/token-prices-service/codefi-v2.mjs.map +1 -1
- package/package.json +14 -13
|
@@ -9,28 +9,22 @@ import type { TransactionControllerTransactionConfirmedEvent } from "@metamask/t
|
|
|
9
9
|
import type { Hex } from "@metamask/utils";
|
|
10
10
|
import type { AssetsContractController } from "./AssetsContractController.cjs";
|
|
11
11
|
import type { TokenDetectionControllerMethodActions } from "./TokenDetectionController-method-action-types.cjs";
|
|
12
|
-
import type {
|
|
12
|
+
import type { TokenListMap } from "./TokenListController.cjs";
|
|
13
|
+
import type { TokenListService } from "./TokenListService.cjs";
|
|
13
14
|
import type { TokensControllerGetStateAction } from "./TokensController.cjs";
|
|
14
15
|
import type { TokensControllerAddDetectedTokensAction, TokensControllerAddTokensAction } from "./TokensController-method-action-types.cjs";
|
|
15
16
|
type TokenDetectionMap = {
|
|
16
17
|
[P in keyof TokenListMap]: Omit<TokenListMap[P], 'occurrences'>;
|
|
17
18
|
};
|
|
18
19
|
export declare const STATIC_MAINNET_TOKEN_LIST: TokenDetectionMap;
|
|
19
|
-
/**
|
|
20
|
-
* Function that takes a TokensChainsCache object and maps chainId with TokenListMap.
|
|
21
|
-
*
|
|
22
|
-
* @param tokensChainsCache - TokensChainsCache input object
|
|
23
|
-
* @returns returns the map of chainId with TokenListMap
|
|
24
|
-
*/
|
|
25
|
-
export declare function mapChainIdWithTokenListMap(tokensChainsCache: TokensChainsCache): Record<string, unknown>;
|
|
26
20
|
export declare const controllerName = "TokenDetectionController";
|
|
27
21
|
export type TokenDetectionState = Record<never, never>;
|
|
28
22
|
export type TokenDetectionControllerGetStateAction = ControllerGetStateAction<typeof controllerName, TokenDetectionState>;
|
|
29
23
|
export type TokenDetectionControllerActions = TokenDetectionControllerGetStateAction | TokenDetectionControllerMethodActions;
|
|
30
|
-
export type AllowedActions = AccountsControllerGetSelectedAccountAction | AccountsControllerGetAccountAction | NetworkControllerGetNetworkClientByIdAction | NetworkControllerGetNetworkConfigurationByNetworkClientId | NetworkControllerGetStateAction |
|
|
24
|
+
export type AllowedActions = AccountsControllerGetSelectedAccountAction | AccountsControllerGetAccountAction | NetworkControllerGetNetworkClientByIdAction | NetworkControllerGetNetworkConfigurationByNetworkClientId | NetworkControllerGetStateAction | KeyringControllerGetStateAction | PreferencesControllerGetStateAction | TokensControllerGetStateAction | TokensControllerAddDetectedTokensAction | TokensControllerAddTokensAction | NetworkControllerFindNetworkClientIdByChainIdAction | AuthenticationController.AuthenticationControllerGetBearerTokenAction;
|
|
31
25
|
export type TokenDetectionControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;
|
|
32
26
|
export type TokenDetectionControllerEvents = TokenDetectionControllerStateChangeEvent;
|
|
33
|
-
export type AllowedEvents = AccountsControllerSelectedEvmAccountChangeEvent | NetworkControllerNetworkDidChangeEvent |
|
|
27
|
+
export type AllowedEvents = AccountsControllerSelectedEvmAccountChangeEvent | NetworkControllerNetworkDidChangeEvent | KeyringControllerLockEvent | KeyringControllerUnlockEvent | PreferencesControllerStateChangeEvent | TransactionControllerTransactionConfirmedEvent;
|
|
34
28
|
export type TokenDetectionControllerMessenger = Messenger<typeof controllerName, TokenDetectionControllerActions | AllowedActions, TokenDetectionControllerEvents | AllowedEvents>;
|
|
35
29
|
/** The input to start polling for the {@link TokenDetectionController} */
|
|
36
30
|
type TokenDetectionPollingInput = {
|
|
@@ -75,6 +69,7 @@ export declare class TokenDetectionController extends TokenDetectionController_b
|
|
|
75
69
|
*
|
|
76
70
|
* @param options - The controller options.
|
|
77
71
|
* @param options.messenger - The controller messenger.
|
|
72
|
+
* @param options.tokenListService - Shared service for fetching the token list per chain.
|
|
78
73
|
* @param options.disabled - If set to true, all network requests are blocked.
|
|
79
74
|
* @param options.interval - Polling interval used to fetch new token rates
|
|
80
75
|
* @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address.
|
|
@@ -82,7 +77,7 @@ export declare class TokenDetectionController extends TokenDetectionController_b
|
|
|
82
77
|
* @param options.useTokenDetection - Feature Switch for using token detection (default: true)
|
|
83
78
|
* @param options.useExternalServices - Feature Switch for using external services (default: false)
|
|
84
79
|
*/
|
|
85
|
-
constructor({ interval, disabled, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, useTokenDetection, useExternalServices, }: {
|
|
80
|
+
constructor({ interval, disabled, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, tokenListService, useTokenDetection, useExternalServices, }: {
|
|
86
81
|
interval?: number;
|
|
87
82
|
disabled?: boolean;
|
|
88
83
|
getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];
|
|
@@ -96,6 +91,7 @@ export declare class TokenDetectionController extends TokenDetectionController_b
|
|
|
96
91
|
};
|
|
97
92
|
}) => void;
|
|
98
93
|
messenger: TokenDetectionControllerMessenger;
|
|
94
|
+
tokenListService: TokenListService;
|
|
99
95
|
useTokenDetection?: () => boolean;
|
|
100
96
|
useExternalServices?: () => boolean;
|
|
101
97
|
});
|
|
@@ -123,7 +119,7 @@ export declare class TokenDetectionController extends TokenDetectionController_b
|
|
|
123
119
|
stop(): void;
|
|
124
120
|
_executePoll({ chainIds, address, }: TokenDetectionPollingInput): Promise<void>;
|
|
125
121
|
/**
|
|
126
|
-
* For each token in the token list provided by the
|
|
122
|
+
* For each token in the token list provided by the TokenListService, checks the token's balance for the selected account address on the active network.
|
|
127
123
|
* On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.
|
|
128
124
|
*
|
|
129
125
|
* @param options - Options for token detection.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenDetectionController.d.cts","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0CAA0C,EAC1C,kCAAkC,EAClC,+CAA+C,EAChD,sCAAsC;AACvC,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AAUnC,OAAO,KAAK,EACV,+BAA+B,EAC/B,0BAA0B,EAC1B,4BAA4B,EAC7B,qCAAqC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAEV,mDAAmD,EACnD,2CAA2C,EAC3C,yDAAyD,EACzD,+BAA+B,EAC/B,sCAAsC,EACvC,qCAAqC;AAEtC,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACtC,yCAAyC;AAC1C,OAAO,KAAK,EAAE,wBAAwB,EAAE,0CAA0C;AAClF,OAAO,KAAK,EAAE,8CAA8C,EAAE,yCAAyC;AACvG,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"TokenDetectionController.d.cts","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,28 +9,22 @@ import type { TransactionControllerTransactionConfirmedEvent } from "@metamask/t
|
|
|
9
9
|
import type { Hex } from "@metamask/utils";
|
|
10
10
|
import type { AssetsContractController } from "./AssetsContractController.mjs";
|
|
11
11
|
import type { TokenDetectionControllerMethodActions } from "./TokenDetectionController-method-action-types.mjs";
|
|
12
|
-
import type {
|
|
12
|
+
import type { TokenListMap } from "./TokenListController.mjs";
|
|
13
|
+
import type { TokenListService } from "./TokenListService.mjs";
|
|
13
14
|
import type { TokensControllerGetStateAction } from "./TokensController.mjs";
|
|
14
15
|
import type { TokensControllerAddDetectedTokensAction, TokensControllerAddTokensAction } from "./TokensController-method-action-types.mjs";
|
|
15
16
|
type TokenDetectionMap = {
|
|
16
17
|
[P in keyof TokenListMap]: Omit<TokenListMap[P], 'occurrences'>;
|
|
17
18
|
};
|
|
18
19
|
export declare const STATIC_MAINNET_TOKEN_LIST: TokenDetectionMap;
|
|
19
|
-
/**
|
|
20
|
-
* Function that takes a TokensChainsCache object and maps chainId with TokenListMap.
|
|
21
|
-
*
|
|
22
|
-
* @param tokensChainsCache - TokensChainsCache input object
|
|
23
|
-
* @returns returns the map of chainId with TokenListMap
|
|
24
|
-
*/
|
|
25
|
-
export declare function mapChainIdWithTokenListMap(tokensChainsCache: TokensChainsCache): Record<string, unknown>;
|
|
26
20
|
export declare const controllerName = "TokenDetectionController";
|
|
27
21
|
export type TokenDetectionState = Record<never, never>;
|
|
28
22
|
export type TokenDetectionControllerGetStateAction = ControllerGetStateAction<typeof controllerName, TokenDetectionState>;
|
|
29
23
|
export type TokenDetectionControllerActions = TokenDetectionControllerGetStateAction | TokenDetectionControllerMethodActions;
|
|
30
|
-
export type AllowedActions = AccountsControllerGetSelectedAccountAction | AccountsControllerGetAccountAction | NetworkControllerGetNetworkClientByIdAction | NetworkControllerGetNetworkConfigurationByNetworkClientId | NetworkControllerGetStateAction |
|
|
24
|
+
export type AllowedActions = AccountsControllerGetSelectedAccountAction | AccountsControllerGetAccountAction | NetworkControllerGetNetworkClientByIdAction | NetworkControllerGetNetworkConfigurationByNetworkClientId | NetworkControllerGetStateAction | KeyringControllerGetStateAction | PreferencesControllerGetStateAction | TokensControllerGetStateAction | TokensControllerAddDetectedTokensAction | TokensControllerAddTokensAction | NetworkControllerFindNetworkClientIdByChainIdAction | AuthenticationController.AuthenticationControllerGetBearerTokenAction;
|
|
31
25
|
export type TokenDetectionControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;
|
|
32
26
|
export type TokenDetectionControllerEvents = TokenDetectionControllerStateChangeEvent;
|
|
33
|
-
export type AllowedEvents = AccountsControllerSelectedEvmAccountChangeEvent | NetworkControllerNetworkDidChangeEvent |
|
|
27
|
+
export type AllowedEvents = AccountsControllerSelectedEvmAccountChangeEvent | NetworkControllerNetworkDidChangeEvent | KeyringControllerLockEvent | KeyringControllerUnlockEvent | PreferencesControllerStateChangeEvent | TransactionControllerTransactionConfirmedEvent;
|
|
34
28
|
export type TokenDetectionControllerMessenger = Messenger<typeof controllerName, TokenDetectionControllerActions | AllowedActions, TokenDetectionControllerEvents | AllowedEvents>;
|
|
35
29
|
/** The input to start polling for the {@link TokenDetectionController} */
|
|
36
30
|
type TokenDetectionPollingInput = {
|
|
@@ -75,6 +69,7 @@ export declare class TokenDetectionController extends TokenDetectionController_b
|
|
|
75
69
|
*
|
|
76
70
|
* @param options - The controller options.
|
|
77
71
|
* @param options.messenger - The controller messenger.
|
|
72
|
+
* @param options.tokenListService - Shared service for fetching the token list per chain.
|
|
78
73
|
* @param options.disabled - If set to true, all network requests are blocked.
|
|
79
74
|
* @param options.interval - Polling interval used to fetch new token rates
|
|
80
75
|
* @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address.
|
|
@@ -82,7 +77,7 @@ export declare class TokenDetectionController extends TokenDetectionController_b
|
|
|
82
77
|
* @param options.useTokenDetection - Feature Switch for using token detection (default: true)
|
|
83
78
|
* @param options.useExternalServices - Feature Switch for using external services (default: false)
|
|
84
79
|
*/
|
|
85
|
-
constructor({ interval, disabled, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, useTokenDetection, useExternalServices, }: {
|
|
80
|
+
constructor({ interval, disabled, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, tokenListService, useTokenDetection, useExternalServices, }: {
|
|
86
81
|
interval?: number;
|
|
87
82
|
disabled?: boolean;
|
|
88
83
|
getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];
|
|
@@ -96,6 +91,7 @@ export declare class TokenDetectionController extends TokenDetectionController_b
|
|
|
96
91
|
};
|
|
97
92
|
}) => void;
|
|
98
93
|
messenger: TokenDetectionControllerMessenger;
|
|
94
|
+
tokenListService: TokenListService;
|
|
99
95
|
useTokenDetection?: () => boolean;
|
|
100
96
|
useExternalServices?: () => boolean;
|
|
101
97
|
});
|
|
@@ -123,7 +119,7 @@ export declare class TokenDetectionController extends TokenDetectionController_b
|
|
|
123
119
|
stop(): void;
|
|
124
120
|
_executePoll({ chainIds, address, }: TokenDetectionPollingInput): Promise<void>;
|
|
125
121
|
/**
|
|
126
|
-
* For each token in the token list provided by the
|
|
122
|
+
* For each token in the token list provided by the TokenListService, checks the token's balance for the selected account address on the active network.
|
|
127
123
|
* On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.
|
|
128
124
|
*
|
|
129
125
|
* @param options - Options for token detection.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenDetectionController.d.mts","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0CAA0C,EAC1C,kCAAkC,EAClC,+CAA+C,EAChD,sCAAsC;AACvC,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AAUnC,OAAO,KAAK,EACV,+BAA+B,EAC/B,0BAA0B,EAC1B,4BAA4B,EAC7B,qCAAqC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAEV,mDAAmD,EACnD,2CAA2C,EAC3C,yDAAyD,EACzD,+BAA+B,EAC/B,sCAAsC,EACvC,qCAAqC;AAEtC,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACtC,yCAAyC;AAC1C,OAAO,KAAK,EAAE,wBAAwB,EAAE,0CAA0C;AAClF,OAAO,KAAK,EAAE,8CAA8C,EAAE,yCAAyC;AACvG,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"TokenDetectionController.d.mts","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _TokenDetectionController_instances, _TokenDetectionController_intervalId, _TokenDetectionController_selectedAccountId,
|
|
12
|
+
var _TokenDetectionController_instances, _TokenDetectionController_intervalId, _TokenDetectionController_selectedAccountId, _TokenDetectionController_tokenListService, _TokenDetectionController_disabled, _TokenDetectionController_isUnlocked, _TokenDetectionController_isDetectionEnabledFromPreferences, _TokenDetectionController_useTokenDetection, _TokenDetectionController_useExternalServices, _TokenDetectionController_getBalancesInSingleCall, _TokenDetectionController_trackMetaMetricsEvent, _TokenDetectionController_registerEventListeners, _TokenDetectionController_stopPolling, _TokenDetectionController_startPolling, _TokenDetectionController_getCorrectNetworkClientIdByChainId, _TokenDetectionController_restartTokenDetection, _TokenDetectionController_getChainCacheForDetection, _TokenDetectionController_detectTokensUsingRpc, _TokenDetectionController_getSlicesOfTokensToDetect, _TokenDetectionController_getConvertedStaticMainnetTokenList, _TokenDetectionController_buildMusdTokenListToken, _TokenDetectionController_mergeMusdIntoTokenListMap, _TokenDetectionController_applyMusdDefaultToTokensChainsCache, _TokenDetectionController_includeMusdInTokenDetectionSlice, _TokenDetectionController_addDetectedTokens, _TokenDetectionController_getSelectedAccount, _TokenDetectionController_getSelectedAddress;
|
|
13
13
|
function $importDefault(module) {
|
|
14
14
|
if (module?.__esModule) {
|
|
15
15
|
return module.default;
|
|
@@ -20,10 +20,8 @@ import $contractMap from "@metamask/contract-metadata";
|
|
|
20
20
|
const contractMap = $importDefault($contractMap);
|
|
21
21
|
import { ASSET_TYPES, ChainId, ERC20, safelyExecute, isEqualCaseInsensitive, toChecksumHexAddress } from "@metamask/controller-utils";
|
|
22
22
|
import { StaticIntervalPollingController } from "@metamask/polling-controller";
|
|
23
|
-
import
|
|
24
|
-
|
|
25
|
-
import { isTokenDetectionSupportedForNetwork } from "./assetsUtil.mjs";
|
|
26
|
-
import { SUPPORTED_NETWORKS_ACCOUNTS_API_V4 } from "./constants.mjs";
|
|
23
|
+
import { formatIconUrlWithProxy, isTokenDetectionSupportedForNetwork } from "./assetsUtil.mjs";
|
|
24
|
+
import { MUSD_ERC20_ADDRESS_LOWER, MUSD_TOKEN_DETECTION_CHAIN_IDS, MUSD_TOKEN_METADATA_BY_CHAIN, SUPPORTED_NETWORKS_ACCOUNTS_API_V4 } from "./constants.mjs";
|
|
27
25
|
const DEFAULT_INTERVAL = 180000;
|
|
28
26
|
export const STATIC_MAINNET_TOKEN_LIST = Object.entries(contractMap).reduce((acc, [base, contract]) => {
|
|
29
27
|
const { logo, erc20, erc721, ...tokenMetadata } = contract;
|
|
@@ -37,20 +35,7 @@ export const STATIC_MAINNET_TOKEN_LIST = Object.entries(contractMap).reduce((acc
|
|
|
37
35
|
},
|
|
38
36
|
};
|
|
39
37
|
}, {});
|
|
40
|
-
|
|
41
|
-
* Function that takes a TokensChainsCache object and maps chainId with TokenListMap.
|
|
42
|
-
*
|
|
43
|
-
* @param tokensChainsCache - TokensChainsCache input object
|
|
44
|
-
* @returns returns the map of chainId with TokenListMap
|
|
45
|
-
*/
|
|
46
|
-
export function mapChainIdWithTokenListMap(tokensChainsCache) {
|
|
47
|
-
return mapValues(tokensChainsCache, (value) => {
|
|
48
|
-
if (isObject(value) && 'data' in value) {
|
|
49
|
-
return get(value, ['data']);
|
|
50
|
-
}
|
|
51
|
-
return value;
|
|
52
|
-
});
|
|
53
|
-
}
|
|
38
|
+
const MUSD_TOKEN_DETECTION_CHAIN_ID_SET = new Set(MUSD_TOKEN_DETECTION_CHAIN_IDS);
|
|
54
39
|
export const controllerName = 'TokenDetectionController';
|
|
55
40
|
const MESSENGER_EXPOSED_METHODS = [
|
|
56
41
|
'addDetectedTokensViaWs',
|
|
@@ -83,6 +68,7 @@ export class TokenDetectionController extends StaticIntervalPollingController()
|
|
|
83
68
|
*
|
|
84
69
|
* @param options - The controller options.
|
|
85
70
|
* @param options.messenger - The controller messenger.
|
|
71
|
+
* @param options.tokenListService - Shared service for fetching the token list per chain.
|
|
86
72
|
* @param options.disabled - If set to true, all network requests are blocked.
|
|
87
73
|
* @param options.interval - Polling interval used to fetch new token rates
|
|
88
74
|
* @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address.
|
|
@@ -90,7 +76,7 @@ export class TokenDetectionController extends StaticIntervalPollingController()
|
|
|
90
76
|
* @param options.useTokenDetection - Feature Switch for using token detection (default: true)
|
|
91
77
|
* @param options.useExternalServices - Feature Switch for using external services (default: false)
|
|
92
78
|
*/
|
|
93
|
-
constructor({ interval = DEFAULT_INTERVAL, disabled = true, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, useTokenDetection = () => true, useExternalServices = () => true, }) {
|
|
79
|
+
constructor({ interval = DEFAULT_INTERVAL, disabled = true, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, tokenListService, useTokenDetection = () => true, useExternalServices = () => true, }) {
|
|
94
80
|
super({
|
|
95
81
|
name: controllerName,
|
|
96
82
|
messenger,
|
|
@@ -100,7 +86,7 @@ export class TokenDetectionController extends StaticIntervalPollingController()
|
|
|
100
86
|
_TokenDetectionController_instances.add(this);
|
|
101
87
|
_TokenDetectionController_intervalId.set(this, void 0);
|
|
102
88
|
_TokenDetectionController_selectedAccountId.set(this, void 0);
|
|
103
|
-
|
|
89
|
+
_TokenDetectionController_tokenListService.set(this, void 0);
|
|
104
90
|
_TokenDetectionController_disabled.set(this, void 0);
|
|
105
91
|
_TokenDetectionController_isUnlocked.set(this, void 0);
|
|
106
92
|
_TokenDetectionController_isDetectionEnabledFromPreferences.set(this, void 0);
|
|
@@ -112,8 +98,7 @@ export class TokenDetectionController extends StaticIntervalPollingController()
|
|
|
112
98
|
__classPrivateFieldSet(this, _TokenDetectionController_disabled, disabled, "f");
|
|
113
99
|
this.setIntervalLength(interval);
|
|
114
100
|
__classPrivateFieldSet(this, _TokenDetectionController_selectedAccountId, __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSelectedAccount).call(this).id, "f");
|
|
115
|
-
|
|
116
|
-
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, tokensChainsCache, "f");
|
|
101
|
+
__classPrivateFieldSet(this, _TokenDetectionController_tokenListService, tokenListService, "f");
|
|
117
102
|
const { useTokenDetection: defaultUseTokenDetection } = this.messenger.call('PreferencesController:getState');
|
|
118
103
|
__classPrivateFieldSet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, defaultUseTokenDetection, "f");
|
|
119
104
|
__classPrivateFieldSet(this, _TokenDetectionController_getBalancesInSingleCall, getBalancesInSingleCall, "f");
|
|
@@ -168,7 +153,7 @@ export class TokenDetectionController extends StaticIntervalPollingController()
|
|
|
168
153
|
});
|
|
169
154
|
}
|
|
170
155
|
/**
|
|
171
|
-
* For each token in the token list provided by the
|
|
156
|
+
* For each token in the token list provided by the TokenListService, checks the token's balance for the selected account address on the active network.
|
|
172
157
|
* On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.
|
|
173
158
|
*
|
|
174
159
|
* @param options - Options for token detection.
|
|
@@ -225,18 +210,28 @@ export class TokenDetectionController extends StaticIntervalPollingController()
|
|
|
225
210
|
if (!__classPrivateFieldGet(this, _TokenDetectionController_useExternalServices, "f").call(this)) {
|
|
226
211
|
return;
|
|
227
212
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
213
|
+
let tokenListMap;
|
|
214
|
+
try {
|
|
215
|
+
tokenListMap = await __classPrivateFieldGet(this, _TokenDetectionController_tokenListService, "f").fetchTokensByChainId(chainId);
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
// These methods return void; there is no token array to return.
|
|
219
|
+
// Gracefully exit so the caller is unaffected — the next polling cycle
|
|
220
|
+
// will retry the fetch.
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const chainCache = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_applyMusdDefaultToTokensChainsCache).call(this, chainId, {
|
|
224
|
+
[chainId]: { data: tokenListMap, timestamp: Date.now() },
|
|
225
|
+
});
|
|
226
|
+
const effectiveSlice = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_includeMusdInTokenDetectionSlice).call(this, tokensSlice, chainId);
|
|
232
227
|
const tokensWithBalance = [];
|
|
233
228
|
const eventTokensDetails = [];
|
|
234
|
-
for (const tokenAddress of
|
|
229
|
+
for (const tokenAddress of effectiveSlice) {
|
|
235
230
|
// Normalize addresses explicitly (don't assume input format)
|
|
236
231
|
const lowercaseTokenAddress = tokenAddress.toLowerCase();
|
|
237
232
|
const checksummedTokenAddress = toChecksumHexAddress(tokenAddress);
|
|
238
233
|
// Check map of validated tokens (cache keys are lowercase)
|
|
239
|
-
const tokenData =
|
|
234
|
+
const tokenData = chainCache[chainId]?.data?.[lowercaseTokenAddress];
|
|
240
235
|
if (!tokenData) {
|
|
241
236
|
continue;
|
|
242
237
|
}
|
|
@@ -292,18 +287,28 @@ export class TokenDetectionController extends StaticIntervalPollingController()
|
|
|
292
287
|
if (!__classPrivateFieldGet(this, _TokenDetectionController_useExternalServices, "f").call(this)) {
|
|
293
288
|
return;
|
|
294
289
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
290
|
+
let tokenListMap;
|
|
291
|
+
try {
|
|
292
|
+
tokenListMap = await __classPrivateFieldGet(this, _TokenDetectionController_tokenListService, "f").fetchTokensByChainId(chainId);
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
// These methods return void; there is no token array to return.
|
|
296
|
+
// Gracefully exit so the caller is unaffected — the next polling cycle
|
|
297
|
+
// will retry the fetch.
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const chainCache = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_applyMusdDefaultToTokensChainsCache).call(this, chainId, {
|
|
301
|
+
[chainId]: { data: tokenListMap, timestamp: Date.now() },
|
|
302
|
+
});
|
|
299
303
|
const selectedAddress = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSelectedAddress).call(this);
|
|
300
304
|
// Get current token states to filter out already tracked/ignored tokens
|
|
301
305
|
const { allTokens, allIgnoredTokens } = this.messenger.call('TokensController:getState');
|
|
302
306
|
const existingTokenAddresses = (allTokens[chainId]?.[selectedAddress] ?? []).map((token) => token.address.toLowerCase());
|
|
303
307
|
const ignoredTokenAddresses = (allIgnoredTokens[chainId]?.[selectedAddress] ?? []).map((address) => address.toLowerCase());
|
|
308
|
+
const effectiveSlice = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_includeMusdInTokenDetectionSlice).call(this, tokensSlice, chainId);
|
|
304
309
|
const tokensWithBalance = [];
|
|
305
310
|
const eventTokensDetails = [];
|
|
306
|
-
for (const tokenAddress of
|
|
311
|
+
for (const tokenAddress of effectiveSlice) {
|
|
307
312
|
const lowercaseTokenAddress = tokenAddress.toLowerCase();
|
|
308
313
|
const checksummedTokenAddress = toChecksumHexAddress(tokenAddress);
|
|
309
314
|
// Skip tokens already in allTokens
|
|
@@ -315,7 +320,7 @@ export class TokenDetectionController extends StaticIntervalPollingController()
|
|
|
315
320
|
continue;
|
|
316
321
|
}
|
|
317
322
|
// Check map of validated tokens (cache keys are lowercase)
|
|
318
|
-
const tokenData =
|
|
323
|
+
const tokenData = chainCache[chainId]?.data?.[lowercaseTokenAddress];
|
|
319
324
|
if (!tokenData) {
|
|
320
325
|
continue;
|
|
321
326
|
}
|
|
@@ -348,7 +353,7 @@ export class TokenDetectionController extends StaticIntervalPollingController()
|
|
|
348
353
|
}
|
|
349
354
|
}
|
|
350
355
|
}
|
|
351
|
-
_TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_selectedAccountId = new WeakMap(),
|
|
356
|
+
_TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_selectedAccountId = new WeakMap(), _TokenDetectionController_tokenListService = new WeakMap(), _TokenDetectionController_disabled = new WeakMap(), _TokenDetectionController_isUnlocked = new WeakMap(), _TokenDetectionController_isDetectionEnabledFromPreferences = new WeakMap(), _TokenDetectionController_useTokenDetection = new WeakMap(), _TokenDetectionController_useExternalServices = new WeakMap(), _TokenDetectionController_getBalancesInSingleCall = new WeakMap(), _TokenDetectionController_trackMetaMetricsEvent = new WeakMap(), _TokenDetectionController_instances = new WeakSet(), _TokenDetectionController_registerEventListeners = function _TokenDetectionController_registerEventListeners() {
|
|
352
357
|
this.messenger.subscribe('KeyringController:unlock', () => {
|
|
353
358
|
__classPrivateFieldSet(this, _TokenDetectionController_isUnlocked, true, "f");
|
|
354
359
|
__classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_restartTokenDetection).call(this).catch(() => {
|
|
@@ -359,14 +364,6 @@ _TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_
|
|
|
359
364
|
__classPrivateFieldSet(this, _TokenDetectionController_isUnlocked, false, "f");
|
|
360
365
|
__classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_stopPolling).call(this);
|
|
361
366
|
});
|
|
362
|
-
this.messenger.subscribe('TokenListController:stateChange', ({ tokensChainsCache }) => {
|
|
363
|
-
const isEqualValues = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_compareTokensChainsCache).call(this, tokensChainsCache, __classPrivateFieldGet(this, _TokenDetectionController_tokensChainsCache, "f"));
|
|
364
|
-
if (!isEqualValues) {
|
|
365
|
-
__classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_restartTokenDetection).call(this).catch(() => {
|
|
366
|
-
// Silently handle token detection errors
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
367
|
this.messenger.subscribe('PreferencesController:stateChange', ({ useTokenDetection }) => {
|
|
371
368
|
const selectedAccount = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSelectedAccount).call(this);
|
|
372
369
|
const isDetectionChangedFromPreferences = __classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, "f") !== useTokenDetection;
|
|
@@ -419,11 +416,6 @@ async function _TokenDetectionController_startPolling() {
|
|
|
419
416
|
__classPrivateFieldSet(this, _TokenDetectionController_intervalId, setInterval(async () => {
|
|
420
417
|
await this.detectTokens();
|
|
421
418
|
}, this.getIntervalLength()), "f");
|
|
422
|
-
}, _TokenDetectionController_compareTokensChainsCache = function _TokenDetectionController_compareTokensChainsCache(tokensChainsCache, previousTokensChainsCache) {
|
|
423
|
-
const cleanPreviousTokensChainsCache = mapChainIdWithTokenListMap(previousTokensChainsCache);
|
|
424
|
-
const cleanTokensChainsCache = mapChainIdWithTokenListMap(tokensChainsCache);
|
|
425
|
-
const isEqualValues = isEqual(cleanTokensChainsCache, cleanPreviousTokensChainsCache);
|
|
426
|
-
return isEqualValues;
|
|
427
419
|
}, _TokenDetectionController_getCorrectNetworkClientIdByChainId = function _TokenDetectionController_getCorrectNetworkClientIdByChainId(chainIds) {
|
|
428
420
|
const { networkConfigurationsByChainId, selectedNetworkClientId } = this.messenger.call('NetworkController:getState');
|
|
429
421
|
if (!chainIds) {
|
|
@@ -458,30 +450,41 @@ async function _TokenDetectionController_restartTokenDetection({ selectedAddress
|
|
|
458
450
|
selectedAddress,
|
|
459
451
|
});
|
|
460
452
|
this.setIntervalLength(DEFAULT_INTERVAL);
|
|
461
|
-
},
|
|
453
|
+
}, _TokenDetectionController_getChainCacheForDetection =
|
|
454
|
+
/**
|
|
455
|
+
* Returns the token cache for `chainId` if detection should proceed, or `null` if it
|
|
456
|
+
* should be skipped. Each call fetches a fresh snapshot from `TokenListService` (which
|
|
457
|
+
* may serve from its in-memory cache) so concurrent calls for different chains never
|
|
458
|
+
* overwrite each other's data.
|
|
459
|
+
*
|
|
460
|
+
* @param chainId - The chain ID to build a detection cache for.
|
|
461
|
+
* @returns A `TokensChainsCache` scoped to `chainId`, or `null` when detection should be skipped.
|
|
462
|
+
*/
|
|
463
|
+
async function _TokenDetectionController_getChainCacheForDetection(chainId) {
|
|
462
464
|
if (!isTokenDetectionSupportedForNetwork(chainId)) {
|
|
463
|
-
return
|
|
465
|
+
return null;
|
|
464
466
|
}
|
|
465
467
|
if (!__classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, "f") &&
|
|
466
468
|
chainId !== ChainId.mainnet) {
|
|
467
|
-
return
|
|
469
|
+
return null;
|
|
468
470
|
}
|
|
469
471
|
const isMainnetDetectionInactive = !__classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, "f") && chainId === ChainId.mainnet;
|
|
470
472
|
if (isMainnetDetectionInactive) {
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
else {
|
|
474
|
-
const { tokensChainsCache } = this.messenger.call('TokenListController:getState');
|
|
475
|
-
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, tokensChainsCache ?? {}, "f");
|
|
473
|
+
return __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getConvertedStaticMainnetTokenList).call(this);
|
|
476
474
|
}
|
|
477
|
-
|
|
475
|
+
const tokenListMap = await __classPrivateFieldGet(this, _TokenDetectionController_tokenListService, "f").fetchTokensByChainId(chainId);
|
|
476
|
+
return __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_applyMusdDefaultToTokensChainsCache).call(this, chainId, {
|
|
477
|
+
[chainId]: { data: tokenListMap, timestamp: Date.now() },
|
|
478
|
+
});
|
|
478
479
|
}, _TokenDetectionController_detectTokensUsingRpc = async function _TokenDetectionController_detectTokensUsingRpc(chainsToDetectUsingRpc, addressToDetect) {
|
|
479
480
|
for (const { chainId, networkClientId } of chainsToDetectUsingRpc) {
|
|
480
|
-
|
|
481
|
+
const chainCache = await __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getChainCacheForDetection).call(this, chainId);
|
|
482
|
+
if (!chainCache) {
|
|
481
483
|
continue;
|
|
482
484
|
}
|
|
483
485
|
const tokenCandidateSlices = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSlicesOfTokensToDetect).call(this, {
|
|
484
486
|
chainId,
|
|
487
|
+
chainCache,
|
|
485
488
|
selectedAddress: addressToDetect,
|
|
486
489
|
});
|
|
487
490
|
const tokenDetectionPromises = tokenCandidateSlices.map((tokensSlice) => __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_addDetectedTokens).call(this, {
|
|
@@ -489,10 +492,11 @@ async function _TokenDetectionController_restartTokenDetection({ selectedAddress
|
|
|
489
492
|
selectedAddress: addressToDetect,
|
|
490
493
|
networkClientId,
|
|
491
494
|
chainId,
|
|
495
|
+
chainCache,
|
|
492
496
|
}));
|
|
493
497
|
await Promise.all(tokenDetectionPromises);
|
|
494
498
|
}
|
|
495
|
-
}, _TokenDetectionController_getSlicesOfTokensToDetect = function _TokenDetectionController_getSlicesOfTokensToDetect({ chainId, selectedAddress, }) {
|
|
499
|
+
}, _TokenDetectionController_getSlicesOfTokensToDetect = function _TokenDetectionController_getSlicesOfTokensToDetect({ chainId, chainCache, selectedAddress, }) {
|
|
496
500
|
const { allTokens, allDetectedTokens, allIgnoredTokens } = this.messenger.call('TokensController:getState');
|
|
497
501
|
const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [
|
|
498
502
|
allTokens,
|
|
@@ -500,7 +504,7 @@ async function _TokenDetectionController_restartTokenDetection({ selectedAddress
|
|
|
500
504
|
allIgnoredTokens,
|
|
501
505
|
].map((tokens) => (tokens[chainId]?.[selectedAddress] ?? []).map((value) => typeof value === 'string' ? value : value.address));
|
|
502
506
|
const tokensToDetect = [];
|
|
503
|
-
for (const tokenAddress of Object.keys(
|
|
507
|
+
for (const tokenAddress of Object.keys(chainCache[chainId]?.data ?? {})) {
|
|
504
508
|
if ([
|
|
505
509
|
tokensAddresses,
|
|
506
510
|
detectedTokensAddresses,
|
|
@@ -526,19 +530,66 @@ async function _TokenDetectionController_restartTokenDetection({ selectedAddress
|
|
|
526
530
|
iconUrl: value?.iconUrl,
|
|
527
531
|
},
|
|
528
532
|
}), {});
|
|
533
|
+
const dataWithMusd = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_mergeMusdIntoTokenListMap).call(this, ChainId.mainnet, data);
|
|
529
534
|
return {
|
|
530
535
|
'0x1': {
|
|
531
|
-
data,
|
|
536
|
+
data: dataWithMusd,
|
|
532
537
|
timestamp: 0,
|
|
533
538
|
},
|
|
534
539
|
};
|
|
535
|
-
},
|
|
540
|
+
}, _TokenDetectionController_buildMusdTokenListToken = function _TokenDetectionController_buildMusdTokenListToken(chainId) {
|
|
541
|
+
const meta = MUSD_TOKEN_METADATA_BY_CHAIN[chainId];
|
|
542
|
+
return {
|
|
543
|
+
address: MUSD_ERC20_ADDRESS_LOWER,
|
|
544
|
+
name: meta.name,
|
|
545
|
+
symbol: meta.symbol,
|
|
546
|
+
decimals: meta.decimals,
|
|
547
|
+
aggregators: [...meta.aggregators],
|
|
548
|
+
iconUrl: formatIconUrlWithProxy({
|
|
549
|
+
chainId,
|
|
550
|
+
tokenAddress: MUSD_ERC20_ADDRESS_LOWER,
|
|
551
|
+
}),
|
|
552
|
+
occurrences: 999,
|
|
553
|
+
};
|
|
554
|
+
}, _TokenDetectionController_mergeMusdIntoTokenListMap = function _TokenDetectionController_mergeMusdIntoTokenListMap(chainId, data) {
|
|
555
|
+
return {
|
|
556
|
+
...data,
|
|
557
|
+
[MUSD_ERC20_ADDRESS_LOWER]: __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_buildMusdTokenListToken).call(this, chainId),
|
|
558
|
+
};
|
|
559
|
+
}, _TokenDetectionController_applyMusdDefaultToTokensChainsCache = function _TokenDetectionController_applyMusdDefaultToTokensChainsCache(chainId, cache) {
|
|
560
|
+
if (!MUSD_TOKEN_DETECTION_CHAIN_ID_SET.has(chainId)) {
|
|
561
|
+
return cache;
|
|
562
|
+
}
|
|
563
|
+
const existing = cache[chainId];
|
|
564
|
+
return {
|
|
565
|
+
...cache,
|
|
566
|
+
[chainId]: {
|
|
567
|
+
data: __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_mergeMusdIntoTokenListMap).call(this, chainId, existing?.data ?? {}),
|
|
568
|
+
timestamp: existing?.timestamp ?? 0,
|
|
569
|
+
},
|
|
570
|
+
};
|
|
571
|
+
}, _TokenDetectionController_includeMusdInTokenDetectionSlice = function _TokenDetectionController_includeMusdInTokenDetectionSlice(tokensSlice, chainId) {
|
|
572
|
+
if (!MUSD_TOKEN_DETECTION_CHAIN_ID_SET.has(chainId)) {
|
|
573
|
+
return tokensSlice;
|
|
574
|
+
}
|
|
575
|
+
if (tokensSlice.some((a) => isEqualCaseInsensitive(a, MUSD_ERC20_ADDRESS_LOWER))) {
|
|
576
|
+
return tokensSlice;
|
|
577
|
+
}
|
|
578
|
+
return [...tokensSlice, MUSD_ERC20_ADDRESS_LOWER];
|
|
579
|
+
}, _TokenDetectionController_addDetectedTokens = async function _TokenDetectionController_addDetectedTokens({ tokensSlice, selectedAddress, networkClientId, chainId, chainCache, }) {
|
|
536
580
|
await safelyExecute(async () => {
|
|
537
581
|
const balances = await __classPrivateFieldGet(this, _TokenDetectionController_getBalancesInSingleCall, "f").call(this, selectedAddress, tokensSlice, networkClientId);
|
|
582
|
+
const chainData = chainCache[chainId]?.data ?? {};
|
|
538
583
|
const tokensWithBalance = [];
|
|
539
584
|
const eventTokensDetails = [];
|
|
540
585
|
for (const nonZeroTokenAddress of Object.keys(balances)) {
|
|
541
|
-
|
|
586
|
+
// chainData keys are lowercase (normalised by buildTokenListMap);
|
|
587
|
+
// balance keys are checksummed, so normalise before lookup.
|
|
588
|
+
const tokenListEntry = chainData[nonZeroTokenAddress.toLowerCase()];
|
|
589
|
+
if (!tokenListEntry) {
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const { decimals, symbol, aggregators, iconUrl, name, rwaData } = tokenListEntry;
|
|
542
593
|
eventTokensDetails.push(`${symbol} - ${nonZeroTokenAddress}`);
|
|
543
594
|
tokensWithBalance.push({
|
|
544
595
|
address: nonZeroTokenAddress,
|
|
@@ -551,6 +602,30 @@ async function _TokenDetectionController_restartTokenDetection({ selectedAddress
|
|
|
551
602
|
...(rwaData && { rwaData }),
|
|
552
603
|
});
|
|
553
604
|
}
|
|
605
|
+
// mUSD is always in the chain token cache on supported networks, but
|
|
606
|
+
// getBalancesInSingleCall omits zero balances; still add mUSD so the wallet
|
|
607
|
+
// shows the asset (balance updates via the usual balance pipeline).
|
|
608
|
+
if (MUSD_TOKEN_DETECTION_CHAIN_ID_SET.has(chainId)) {
|
|
609
|
+
const musdInSlice = tokensSlice.some((addr) => isEqualCaseInsensitive(addr, MUSD_ERC20_ADDRESS_LOWER));
|
|
610
|
+
const musdHasNonZeroFromRpc = Object.keys(balances).some((addr) => isEqualCaseInsensitive(addr, MUSD_ERC20_ADDRESS_LOWER));
|
|
611
|
+
if (musdInSlice && !musdHasNonZeroFromRpc) {
|
|
612
|
+
const musdListToken = Object.entries(chainData).find(([key]) => isEqualCaseInsensitive(key, MUSD_ERC20_ADDRESS_LOWER))?.[1];
|
|
613
|
+
if (musdListToken) {
|
|
614
|
+
const { decimals, symbol, aggregators, iconUrl, name, rwaData } = musdListToken;
|
|
615
|
+
eventTokensDetails.push(`${symbol} - ${MUSD_ERC20_ADDRESS_LOWER}`);
|
|
616
|
+
tokensWithBalance.push({
|
|
617
|
+
address: MUSD_ERC20_ADDRESS_LOWER,
|
|
618
|
+
decimals,
|
|
619
|
+
symbol,
|
|
620
|
+
aggregators,
|
|
621
|
+
image: iconUrl,
|
|
622
|
+
isERC721: false,
|
|
623
|
+
name,
|
|
624
|
+
...(rwaData && { rwaData }),
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
554
629
|
if (tokensWithBalance.length) {
|
|
555
630
|
__classPrivateFieldGet(this, _TokenDetectionController_trackMetaMetricsEvent, "f").call(this, {
|
|
556
631
|
event: 'Token Detected',
|