@metamask/assets-controllers 42.0.0 → 43.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 +24 -1
- package/dist/AccountTrackerController.cjs +30 -10
- package/dist/AccountTrackerController.cjs.map +1 -1
- package/dist/AccountTrackerController.d.cts +14 -9
- package/dist/AccountTrackerController.d.cts.map +1 -1
- package/dist/AccountTrackerController.d.mts +14 -9
- package/dist/AccountTrackerController.d.mts.map +1 -1
- package/dist/AccountTrackerController.mjs +30 -10
- package/dist/AccountTrackerController.mjs.map +1 -1
- package/dist/AssetsContractController.cjs +61 -1
- package/dist/AssetsContractController.cjs.map +1 -1
- package/dist/AssetsContractController.d.cts +13 -0
- package/dist/AssetsContractController.d.cts.map +1 -1
- package/dist/AssetsContractController.d.mts +13 -0
- package/dist/AssetsContractController.d.mts.map +1 -1
- package/dist/AssetsContractController.mjs +61 -1
- package/dist/AssetsContractController.mjs.map +1 -1
- package/dist/CurrencyRateController.d.cts +4 -4
- package/dist/CurrencyRateController.d.mts +4 -4
- package/dist/RatesController/RatesController.cjs +12 -1
- package/dist/RatesController/RatesController.cjs.map +1 -1
- package/dist/RatesController/RatesController.d.cts +8 -1
- package/dist/RatesController/RatesController.d.cts.map +1 -1
- package/dist/RatesController/RatesController.d.mts +8 -1
- package/dist/RatesController/RatesController.d.mts.map +1 -1
- package/dist/RatesController/RatesController.mjs +12 -1
- package/dist/RatesController/RatesController.mjs.map +1 -1
- package/dist/TokenDetectionController.cjs +191 -127
- package/dist/TokenDetectionController.cjs.map +1 -1
- package/dist/TokenDetectionController.d.cts +20 -11
- package/dist/TokenDetectionController.d.cts.map +1 -1
- package/dist/TokenDetectionController.d.mts +20 -11
- package/dist/TokenDetectionController.d.mts.map +1 -1
- package/dist/TokenDetectionController.mjs +190 -127
- package/dist/TokenDetectionController.mjs.map +1 -1
- package/dist/TokenListController.cjs +60 -53
- package/dist/TokenListController.cjs.map +1 -1
- package/dist/TokenListController.d.cts +25 -14
- package/dist/TokenListController.d.cts.map +1 -1
- package/dist/TokenListController.d.mts +25 -14
- package/dist/TokenListController.d.mts.map +1 -1
- package/dist/TokenListController.mjs +60 -53
- package/dist/TokenListController.mjs.map +1 -1
- package/dist/TokenRatesController.d.cts +4 -4
- package/dist/TokenRatesController.d.mts +4 -4
- package/dist/TokensController.cjs +7 -4
- package/dist/TokensController.cjs.map +1 -1
- package/dist/TokensController.d.cts.map +1 -1
- package/dist/TokensController.d.mts.map +1 -1
- package/dist/TokensController.mjs +7 -4
- package/dist/TokensController.mjs.map +1 -1
- package/dist/assetsUtil.cjs +13 -1
- package/dist/assetsUtil.cjs.map +1 -1
- package/dist/assetsUtil.d.cts +7 -0
- package/dist/assetsUtil.d.cts.map +1 -1
- package/dist/assetsUtil.d.mts +7 -0
- package/dist/assetsUtil.d.mts.map +1 -1
- package/dist/assetsUtil.mjs +12 -0
- package/dist/assetsUtil.mjs.map +1 -1
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.cjs +18 -0
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.cjs.map +1 -1
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.d.cts.map +1 -1
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.d.mts.map +1 -1
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.mjs +18 -0
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.mjs.map +1 -1
- package/package.json +9 -9
|
@@ -13,9 +13,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _TokenDetectionController_instances, _TokenDetectionController_intervalId, _TokenDetectionController_selectedAccountId, _TokenDetectionController_networkClientId, _TokenDetectionController_tokensChainsCache, _TokenDetectionController_disabled, _TokenDetectionController_isUnlocked, _TokenDetectionController_isDetectionEnabledFromPreferences, _TokenDetectionController_isDetectionEnabledForNetwork, _TokenDetectionController_getBalancesInSingleCall, _TokenDetectionController_trackMetaMetricsEvent, _TokenDetectionController_accountsAPI, _TokenDetectionController_registerEventListeners, _TokenDetectionController_stopPolling, _TokenDetectionController_startPolling, _TokenDetectionController_compareTokensChainsCache, _TokenDetectionController_getCorrectChainIdAndNetworkClientId, _TokenDetectionController_restartTokenDetection, _TokenDetectionController_getSlicesOfTokensToDetect, _TokenDetectionController_getConvertedStaticMainnetTokenList, _TokenDetectionController_addDetectedTokensViaAPI, _TokenDetectionController_addDetectedTokens, _TokenDetectionController_getSelectedAccount, _TokenDetectionController_getSelectedAddress;
|
|
16
|
+
var _TokenDetectionController_instances, _TokenDetectionController_intervalId, _TokenDetectionController_selectedAccountId, _TokenDetectionController_networkClientId, _TokenDetectionController_tokensChainsCache, _TokenDetectionController_disabled, _TokenDetectionController_isUnlocked, _TokenDetectionController_isDetectionEnabledFromPreferences, _TokenDetectionController_isDetectionEnabledForNetwork, _TokenDetectionController_getBalancesInSingleCall, _TokenDetectionController_trackMetaMetricsEvent, _TokenDetectionController_accountsAPI, _TokenDetectionController_registerEventListeners, _TokenDetectionController_stopPolling, _TokenDetectionController_startPolling, _TokenDetectionController_compareTokensChainsCache, _TokenDetectionController_getCorrectNetworkClientIdByChainId, _TokenDetectionController_getCorrectChainIdAndNetworkClientId, _TokenDetectionController_restartTokenDetection, _TokenDetectionController_getChainsToDetect, _TokenDetectionController_attemptAccountAPIDetection, _TokenDetectionController_addChainsToRpcDetection, _TokenDetectionController_shouldDetectTokens, _TokenDetectionController_detectTokensUsingRpc, _TokenDetectionController_getSlicesOfTokensToDetect, _TokenDetectionController_getConvertedStaticMainnetTokenList, _TokenDetectionController_addDetectedTokensViaAPI, _TokenDetectionController_filterAndBuildTokensWithBalance, _TokenDetectionController_addDetectedTokens, _TokenDetectionController_getSelectedAccount, _TokenDetectionController_getSelectedAddress;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.TokenDetectionController = exports.controllerName = exports.STATIC_MAINNET_TOKEN_LIST = void 0;
|
|
18
|
+
exports.TokenDetectionController = exports.controllerName = exports.mapChainIdWithTokenListMap = exports.STATIC_MAINNET_TOKEN_LIST = void 0;
|
|
19
19
|
const contract_metadata_1 = __importDefault(require("@metamask/contract-metadata"));
|
|
20
20
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
21
21
|
const polling_controller_1 = require("@metamask/polling-controller");
|
|
@@ -49,6 +49,7 @@ function mapChainIdWithTokenListMap(tokensChainsCache) {
|
|
|
49
49
|
return value;
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
+
exports.mapChainIdWithTokenListMap = mapChainIdWithTokenListMap;
|
|
52
53
|
exports.controllerName = 'TokenDetectionController';
|
|
53
54
|
/**
|
|
54
55
|
* Controller that passively polls on a set interval for Tokens auto detection
|
|
@@ -108,18 +109,15 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
|
|
|
108
109
|
this.supportedNetworksCache = result;
|
|
109
110
|
return result;
|
|
110
111
|
},
|
|
111
|
-
async
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const chainIdNumber = (0, utils_1.hexToNumber)(chainId);
|
|
116
|
-
const supportedNetworks = await this.getSupportedNetworks();
|
|
117
|
-
if (!supportedNetworks || !supportedNetworks.includes(chainIdNumber)) {
|
|
112
|
+
async getMultiNetworksBalances(address, chainIds, supportedNetworks) {
|
|
113
|
+
const chainIdNumbers = chainIds.map((chainId) => (0, utils_1.hexToNumber)(chainId));
|
|
114
|
+
if (!supportedNetworks ||
|
|
115
|
+
!chainIdNumbers.every((id) => supportedNetworks.includes(id))) {
|
|
118
116
|
const supportedNetworksErrStr = (supportedNetworks ?? []).toString();
|
|
119
|
-
throw new Error(`Unsupported Network: supported networks ${supportedNetworksErrStr},
|
|
117
|
+
throw new Error(`Unsupported Network: supported networks ${supportedNetworksErrStr}, requested networks: ${chainIdNumbers.toString()}`);
|
|
120
118
|
}
|
|
121
119
|
const result = await (0, multi_chain_accounts_service_1.fetchMultiChainBalances)(address, {
|
|
122
|
-
networks:
|
|
120
|
+
networks: chainIdNumbers,
|
|
123
121
|
}, this.platform);
|
|
124
122
|
return result.balances;
|
|
125
123
|
},
|
|
@@ -175,12 +173,12 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
|
|
|
175
173
|
this.disable();
|
|
176
174
|
__classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_stopPolling).call(this);
|
|
177
175
|
}
|
|
178
|
-
async _executePoll({
|
|
176
|
+
async _executePoll({ chainIds, address, }) {
|
|
179
177
|
if (!this.isActive) {
|
|
180
178
|
return;
|
|
181
179
|
}
|
|
182
180
|
await this.detectTokens({
|
|
183
|
-
|
|
181
|
+
chainIds,
|
|
184
182
|
selectedAddress: address,
|
|
185
183
|
});
|
|
186
184
|
}
|
|
@@ -189,51 +187,35 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
|
|
|
189
187
|
* 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.
|
|
190
188
|
*
|
|
191
189
|
* @param options - Options for token detection.
|
|
192
|
-
* @param options.
|
|
190
|
+
* @param options.chainIds - The chain IDs of the network client to use.
|
|
193
191
|
* @param options.selectedAddress - the selectedAddress against which to detect for token balances.
|
|
194
192
|
*/
|
|
195
|
-
async detectTokens({
|
|
193
|
+
async detectTokens({ chainIds, selectedAddress, } = {}) {
|
|
196
194
|
if (!this.isActive) {
|
|
197
195
|
return;
|
|
198
196
|
}
|
|
199
|
-
const
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return;
|
|
197
|
+
const addressToDetect = selectedAddress ?? __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSelectedAddress).call(this);
|
|
198
|
+
const clientNetworks = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getCorrectNetworkClientIdByChainId).call(this, chainIds);
|
|
199
|
+
let supportedNetworks;
|
|
200
|
+
if (__classPrivateFieldGet(this, _TokenDetectionController_accountsAPI, "f").isAccountsAPIEnabled) {
|
|
201
|
+
supportedNetworks = await __classPrivateFieldGet(this, _TokenDetectionController_accountsAPI, "f").getSupportedNetworks();
|
|
205
202
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
203
|
+
const { chainsToDetectUsingRpc, chainsToDetectUsingAccountAPI } = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getChainsToDetect).call(this, clientNetworks, supportedNetworks);
|
|
204
|
+
// Try detecting tokens via Account API first if conditions allow
|
|
205
|
+
if (supportedNetworks && chainsToDetectUsingAccountAPI.length > 0) {
|
|
206
|
+
const apiResult = await __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_attemptAccountAPIDetection).call(this, chainsToDetectUsingAccountAPI, addressToDetect, supportedNetworks);
|
|
207
|
+
// If API succeeds and no chains are left for RPC detection, we can return early
|
|
208
|
+
if (apiResult?.result === 'success' &&
|
|
209
|
+
chainsToDetectUsingRpc.length === 0) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
// If API fails or chainsToDetectUsingRpc still has items, add chains to RPC detection
|
|
213
|
+
__classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_addChainsToRpcDetection).call(this, chainsToDetectUsingRpc, chainsToDetectUsingAccountAPI, clientNetworks);
|
|
209
214
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, isTokenDetectionInactiveInMainnet
|
|
214
|
-
? __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getConvertedStaticMainnetTokenList).call(this)
|
|
215
|
-
: tokensChainsCache ?? {}, "f");
|
|
216
|
-
const tokenCandidateSlices = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSlicesOfTokensToDetect).call(this, {
|
|
217
|
-
chainId: chainIdAgainstWhichToDetect,
|
|
218
|
-
selectedAddress: addressAgainstWhichToDetect,
|
|
219
|
-
});
|
|
220
|
-
// Attempt Accounts API Detection
|
|
221
|
-
const accountAPIResult = await __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_addDetectedTokensViaAPI).call(this, {
|
|
222
|
-
chainId: chainIdAgainstWhichToDetect,
|
|
223
|
-
selectedAddress: addressAgainstWhichToDetect,
|
|
224
|
-
tokenCandidateSlices,
|
|
225
|
-
});
|
|
226
|
-
if (accountAPIResult?.result === 'success') {
|
|
227
|
-
return;
|
|
215
|
+
// Proceed with RPC detection if there are chains remaining in chainsToDetectUsingRpc
|
|
216
|
+
if (chainsToDetectUsingRpc.length > 0) {
|
|
217
|
+
await __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_detectTokensUsingRpc).call(this, chainsToDetectUsingRpc, addressToDetect);
|
|
228
218
|
}
|
|
229
|
-
// Attempt RPC Detection
|
|
230
|
-
const tokenDetectionPromises = tokenCandidateSlices.map((tokensSlice) => __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_addDetectedTokens).call(this, {
|
|
231
|
-
tokensSlice,
|
|
232
|
-
selectedAddress: addressAgainstWhichToDetect,
|
|
233
|
-
networkClientId: networkClientIdAgainstWhichToDetect,
|
|
234
|
-
chainId: chainIdAgainstWhichToDetect,
|
|
235
|
-
}));
|
|
236
|
-
await Promise.all(tokenDetectionPromises);
|
|
237
219
|
}
|
|
238
220
|
}
|
|
239
221
|
exports.TokenDetectionController = TokenDetectionController;
|
|
@@ -282,20 +264,6 @@ _TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_
|
|
|
282
264
|
});
|
|
283
265
|
}
|
|
284
266
|
});
|
|
285
|
-
this.messagingSystem.subscribe('NetworkController:networkDidChange',
|
|
286
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
287
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
288
|
-
async ({ selectedNetworkClientId }) => {
|
|
289
|
-
const isNetworkClientIdChanged = __classPrivateFieldGet(this, _TokenDetectionController_networkClientId, "f") !== selectedNetworkClientId;
|
|
290
|
-
const { chainId: newChainId } = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getCorrectChainIdAndNetworkClientId).call(this, selectedNetworkClientId);
|
|
291
|
-
__classPrivateFieldSet(this, _TokenDetectionController_isDetectionEnabledForNetwork, (0, assetsUtil_1.isTokenDetectionSupportedForNetwork)(newChainId), "f");
|
|
292
|
-
if (isNetworkClientIdChanged && __classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledForNetwork, "f")) {
|
|
293
|
-
__classPrivateFieldSet(this, _TokenDetectionController_networkClientId, selectedNetworkClientId, "f");
|
|
294
|
-
await __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_restartTokenDetection).call(this, {
|
|
295
|
-
networkClientId: __classPrivateFieldGet(this, _TokenDetectionController_networkClientId, "f"),
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
267
|
}, _TokenDetectionController_stopPolling = function _TokenDetectionController_stopPolling() {
|
|
300
268
|
if (__classPrivateFieldGet(this, _TokenDetectionController_intervalId, "f")) {
|
|
301
269
|
clearInterval(__classPrivateFieldGet(this, _TokenDetectionController_intervalId, "f"));
|
|
@@ -320,16 +288,26 @@ async function _TokenDetectionController_startPolling() {
|
|
|
320
288
|
const cleanTokensChainsCache = mapChainIdWithTokenListMap(tokensChainsCache);
|
|
321
289
|
const isEqualValues = (0, lodash_1.isEqual)(cleanTokensChainsCache, cleanPreviousTokensChainsCache);
|
|
322
290
|
return isEqualValues;
|
|
323
|
-
},
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
291
|
+
}, _TokenDetectionController_getCorrectNetworkClientIdByChainId = function _TokenDetectionController_getCorrectNetworkClientIdByChainId(chainIds) {
|
|
292
|
+
const { networkConfigurationsByChainId, selectedNetworkClientId } = this.messagingSystem.call('NetworkController:getState');
|
|
293
|
+
if (!chainIds) {
|
|
294
|
+
const networkConfiguration = this.messagingSystem.call('NetworkController:getNetworkConfigurationByNetworkClientId', selectedNetworkClientId);
|
|
295
|
+
return [
|
|
296
|
+
{
|
|
297
|
+
chainId: networkConfiguration?.chainId ?? controller_utils_1.ChainId.mainnet,
|
|
298
|
+
networkClientId: selectedNetworkClientId,
|
|
299
|
+
},
|
|
300
|
+
];
|
|
332
301
|
}
|
|
302
|
+
return chainIds.map((chainId) => {
|
|
303
|
+
const configuration = networkConfigurationsByChainId[chainId];
|
|
304
|
+
return {
|
|
305
|
+
chainId,
|
|
306
|
+
networkClientId: configuration.rpcEndpoints[configuration.defaultRpcEndpointIndex]
|
|
307
|
+
.networkClientId,
|
|
308
|
+
};
|
|
309
|
+
});
|
|
310
|
+
}, _TokenDetectionController_getCorrectChainIdAndNetworkClientId = function _TokenDetectionController_getCorrectChainIdAndNetworkClientId() {
|
|
333
311
|
const { selectedNetworkClientId } = this.messagingSystem.call('NetworkController:getState');
|
|
334
312
|
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
|
|
335
313
|
return {
|
|
@@ -343,14 +321,76 @@ async function _TokenDetectionController_startPolling() {
|
|
|
343
321
|
*
|
|
344
322
|
* @param options - Options for restart token detection.
|
|
345
323
|
* @param options.selectedAddress - the selectedAddress against which to detect for token balances
|
|
346
|
-
* @param options.
|
|
324
|
+
* @param options.chainIds - The chain IDs of the network client to use.
|
|
347
325
|
*/
|
|
348
|
-
async function _TokenDetectionController_restartTokenDetection({ selectedAddress,
|
|
326
|
+
async function _TokenDetectionController_restartTokenDetection({ selectedAddress, chainIds, } = {}) {
|
|
349
327
|
await this.detectTokens({
|
|
350
|
-
|
|
328
|
+
chainIds,
|
|
351
329
|
selectedAddress,
|
|
352
330
|
});
|
|
353
331
|
this.setIntervalLength(DEFAULT_INTERVAL);
|
|
332
|
+
}, _TokenDetectionController_getChainsToDetect = function _TokenDetectionController_getChainsToDetect(clientNetworks, supportedNetworks) {
|
|
333
|
+
const chainsToDetectUsingAccountAPI = [];
|
|
334
|
+
const chainsToDetectUsingRpc = [];
|
|
335
|
+
clientNetworks.forEach(({ chainId, networkClientId }) => {
|
|
336
|
+
if (supportedNetworks?.includes((0, utils_1.hexToNumber)(chainId))) {
|
|
337
|
+
chainsToDetectUsingAccountAPI.push(chainId);
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
chainsToDetectUsingRpc.push({ chainId, networkClientId });
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
return { chainsToDetectUsingRpc, chainsToDetectUsingAccountAPI };
|
|
344
|
+
}, _TokenDetectionController_attemptAccountAPIDetection = async function _TokenDetectionController_attemptAccountAPIDetection(chainsToDetectUsingAccountAPI, addressToDetect, supportedNetworks) {
|
|
345
|
+
return await __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_addDetectedTokensViaAPI).call(this, {
|
|
346
|
+
chainIds: chainsToDetectUsingAccountAPI,
|
|
347
|
+
selectedAddress: addressToDetect,
|
|
348
|
+
supportedNetworks,
|
|
349
|
+
});
|
|
350
|
+
}, _TokenDetectionController_addChainsToRpcDetection = function _TokenDetectionController_addChainsToRpcDetection(chainsToDetectUsingRpc, chainsToDetectUsingAccountAPI, clientNetworks) {
|
|
351
|
+
chainsToDetectUsingAccountAPI.forEach((chainId) => {
|
|
352
|
+
const networkEntry = clientNetworks.find((network) => network.chainId === chainId);
|
|
353
|
+
if (networkEntry) {
|
|
354
|
+
chainsToDetectUsingRpc.push({
|
|
355
|
+
chainId: networkEntry.chainId,
|
|
356
|
+
networkClientId: networkEntry.networkClientId,
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
}, _TokenDetectionController_shouldDetectTokens = function _TokenDetectionController_shouldDetectTokens(chainId) {
|
|
361
|
+
if (!(0, assetsUtil_1.isTokenDetectionSupportedForNetwork)(chainId)) {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
if (!__classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, "f") &&
|
|
365
|
+
chainId !== controller_utils_1.ChainId.mainnet) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
const isMainnetDetectionInactive = !__classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, "f") && chainId === controller_utils_1.ChainId.mainnet;
|
|
369
|
+
if (isMainnetDetectionInactive) {
|
|
370
|
+
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getConvertedStaticMainnetTokenList).call(this), "f");
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
const { tokensChainsCache } = this.messagingSystem.call('TokenListController:getState');
|
|
374
|
+
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, tokensChainsCache ?? {}, "f");
|
|
375
|
+
}
|
|
376
|
+
return true;
|
|
377
|
+
}, _TokenDetectionController_detectTokensUsingRpc = async function _TokenDetectionController_detectTokensUsingRpc(chainsToDetectUsingRpc, addressToDetect) {
|
|
378
|
+
for (const { chainId, networkClientId } of chainsToDetectUsingRpc) {
|
|
379
|
+
if (!__classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_shouldDetectTokens).call(this, chainId)) {
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
const tokenCandidateSlices = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSlicesOfTokensToDetect).call(this, {
|
|
383
|
+
chainId,
|
|
384
|
+
selectedAddress: addressToDetect,
|
|
385
|
+
});
|
|
386
|
+
const tokenDetectionPromises = tokenCandidateSlices.map((tokensSlice) => __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_addDetectedTokens).call(this, {
|
|
387
|
+
tokensSlice,
|
|
388
|
+
selectedAddress: addressToDetect,
|
|
389
|
+
networkClientId,
|
|
390
|
+
chainId,
|
|
391
|
+
}));
|
|
392
|
+
await Promise.all(tokenDetectionPromises);
|
|
393
|
+
}
|
|
354
394
|
}, _TokenDetectionController_getSlicesOfTokensToDetect = function _TokenDetectionController_getSlicesOfTokensToDetect({ chainId, selectedAddress, }) {
|
|
355
395
|
const { allTokens, allDetectedTokens, allIgnoredTokens } = this.messagingSystem.call('TokensController:getState');
|
|
356
396
|
const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [
|
|
@@ -396,68 +436,92 @@ async function _TokenDetectionController_restartTokenDetection({ selectedAddress
|
|
|
396
436
|
* This adds detected tokens from the Accounts API, avoiding the multi-call RPC calls for balances
|
|
397
437
|
* @param options - method arguments
|
|
398
438
|
* @param options.selectedAddress - address to check against
|
|
399
|
-
* @param options.
|
|
400
|
-
* @param options.
|
|
401
|
-
* We will use these these token candidates to determine if a token found from the API is valid to be added on the users wallet.
|
|
402
|
-
* It will also prevent us to adding tokens a user already has
|
|
439
|
+
* @param options.chainIds - array of chainIds to check tokens for
|
|
440
|
+
* @param options.supportedNetworks - array of chainIds to check tokens for
|
|
403
441
|
* @returns a success or failed object
|
|
404
442
|
*/
|
|
405
|
-
async function _TokenDetectionController_addDetectedTokensViaAPI({ selectedAddress,
|
|
443
|
+
async function _TokenDetectionController_addDetectedTokensViaAPI({ selectedAddress, chainIds, supportedNetworks, }) {
|
|
406
444
|
return await (0, controller_utils_1.safelyExecute)(async () => {
|
|
407
|
-
|
|
408
|
-
|
|
445
|
+
// Fetch balances for multiple chain IDs at once
|
|
446
|
+
const tokenBalancesByChain = await __classPrivateFieldGet(this, _TokenDetectionController_accountsAPI, "f")
|
|
447
|
+
.getMultiNetworksBalances(selectedAddress, chainIds, supportedNetworks)
|
|
409
448
|
.catch(() => null);
|
|
410
|
-
if (!
|
|
449
|
+
if (!tokenBalancesByChain ||
|
|
450
|
+
Object.keys(tokenBalancesByChain).length === 0) {
|
|
411
451
|
return { result: 'failed' };
|
|
412
452
|
}
|
|
413
|
-
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
// We need specific data from tokensChainsCache to correctly create a token
|
|
424
|
-
// So even if we have a token that was detected correctly by the API, if its missing data we cannot safely add it.
|
|
425
|
-
if (!__classPrivateFieldGet(this, _TokenDetectionController_tokensChainsCache, "f")[chainId].data[token.address]) {
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
428
|
-
const { decimals, symbol, aggregators, iconUrl, name } = __classPrivateFieldGet(this, _TokenDetectionController_tokensChainsCache, "f")[chainId].data[token.address];
|
|
429
|
-
eventTokensDetails.push(`${symbol} - ${tokenAddress}`);
|
|
430
|
-
tokensWithBalance.push({
|
|
431
|
-
address: tokenAddress,
|
|
432
|
-
decimals,
|
|
433
|
-
symbol,
|
|
434
|
-
aggregators,
|
|
435
|
-
image: iconUrl,
|
|
436
|
-
isERC721: false,
|
|
437
|
-
name,
|
|
438
|
-
});
|
|
439
|
-
});
|
|
440
|
-
if (tokensWithBalance.length) {
|
|
441
|
-
__classPrivateFieldGet(this, _TokenDetectionController_trackMetaMetricsEvent, "f").call(this, {
|
|
442
|
-
event: 'Token Detected',
|
|
443
|
-
category: 'Wallet',
|
|
444
|
-
properties: {
|
|
445
|
-
tokens: eventTokensDetails,
|
|
446
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
447
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
448
|
-
token_standard: controller_utils_1.ERC20,
|
|
449
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
450
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
451
|
-
asset_type: controller_utils_1.ASSET_TYPES.TOKEN,
|
|
452
|
-
},
|
|
453
|
-
});
|
|
454
|
-
await this.messagingSystem.call('TokensController:addDetectedTokens', tokensWithBalance, {
|
|
455
|
-
selectedAddress,
|
|
453
|
+
// Process each chain ID individually
|
|
454
|
+
for (const chainId of chainIds) {
|
|
455
|
+
const isTokenDetectionInactiveInMainnet = !__classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, "f") &&
|
|
456
|
+
chainId === controller_utils_1.ChainId.mainnet;
|
|
457
|
+
const { tokensChainsCache } = this.messagingSystem.call('TokenListController:getState');
|
|
458
|
+
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, isTokenDetectionInactiveInMainnet
|
|
459
|
+
? __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getConvertedStaticMainnetTokenList).call(this)
|
|
460
|
+
: tokensChainsCache ?? {}, "f");
|
|
461
|
+
// Generate token candidates based on chainId and selectedAddress
|
|
462
|
+
const tokenCandidateSlices = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSlicesOfTokensToDetect).call(this, {
|
|
456
463
|
chainId,
|
|
464
|
+
selectedAddress,
|
|
457
465
|
});
|
|
466
|
+
// Filter balances for the current chainId
|
|
467
|
+
const tokenBalances = tokenBalancesByChain.filter((balance) => balance.chainId === (0, utils_1.hexToNumber)(chainId));
|
|
468
|
+
if (!tokenBalances || tokenBalances.length === 0) {
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
// Use helper function to filter tokens with balance for this chainId
|
|
472
|
+
const { tokensWithBalance, eventTokensDetails } = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_filterAndBuildTokensWithBalance).call(this, tokenCandidateSlices, tokenBalances, chainId);
|
|
473
|
+
if (tokensWithBalance.length) {
|
|
474
|
+
__classPrivateFieldGet(this, _TokenDetectionController_trackMetaMetricsEvent, "f").call(this, {
|
|
475
|
+
event: 'Token Detected',
|
|
476
|
+
category: 'Wallet',
|
|
477
|
+
properties: {
|
|
478
|
+
tokens: eventTokensDetails,
|
|
479
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
480
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
481
|
+
token_standard: controller_utils_1.ERC20,
|
|
482
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
483
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
484
|
+
asset_type: controller_utils_1.ASSET_TYPES.TOKEN,
|
|
485
|
+
},
|
|
486
|
+
});
|
|
487
|
+
await this.messagingSystem.call('TokensController:addDetectedTokens', tokensWithBalance, {
|
|
488
|
+
selectedAddress,
|
|
489
|
+
chainId,
|
|
490
|
+
});
|
|
491
|
+
}
|
|
458
492
|
}
|
|
459
493
|
return { result: 'success' };
|
|
460
494
|
});
|
|
495
|
+
}, _TokenDetectionController_filterAndBuildTokensWithBalance = function _TokenDetectionController_filterAndBuildTokensWithBalance(tokenCandidateSlices, tokenBalances, chainId) {
|
|
496
|
+
const tokensWithBalance = [];
|
|
497
|
+
const eventTokensDetails = [];
|
|
498
|
+
const tokenCandidateSet = new Set(tokenCandidateSlices.flat());
|
|
499
|
+
tokenBalances?.forEach((token) => {
|
|
500
|
+
const tokenAddress = token.address;
|
|
501
|
+
// Make sure the token to add is in our candidate list
|
|
502
|
+
if (!tokenCandidateSet.has(tokenAddress)) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
// Retrieve token data from cache to safely add it
|
|
506
|
+
const tokenData = __classPrivateFieldGet(this, _TokenDetectionController_tokensChainsCache, "f")[chainId]?.data[tokenAddress];
|
|
507
|
+
// We need specific data from tokensChainsCache to correctly create a token
|
|
508
|
+
// So even if we have a token that was detected correctly by the API, if its missing data we cannot safely add it.
|
|
509
|
+
if (!tokenData) {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
const { decimals, symbol, aggregators, iconUrl, name } = tokenData;
|
|
513
|
+
eventTokensDetails.push(`${symbol} - ${tokenAddress}`);
|
|
514
|
+
tokensWithBalance.push({
|
|
515
|
+
address: tokenAddress,
|
|
516
|
+
decimals,
|
|
517
|
+
symbol,
|
|
518
|
+
aggregators,
|
|
519
|
+
image: iconUrl,
|
|
520
|
+
isERC721: false,
|
|
521
|
+
name,
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
return { tokensWithBalance, eventTokensDetails };
|
|
461
525
|
}, _TokenDetectionController_addDetectedTokens = async function _TokenDetectionController_addDetectedTokens({ tokensSlice, selectedAddress, networkClientId, chainId, }) {
|
|
462
526
|
await (0, controller_utils_1.safelyExecute)(async () => {
|
|
463
527
|
const balances = await __classPrivateFieldGet(this, _TokenDetectionController_getBalancesInSingleCall, "f").call(this, selectedAddress, tokensSlice, networkClientId);
|