@metamask-previews/assets-controller 0.0.0-preview-52f4a2ca → 0.0.0-preview-2d06693a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +0 -3
  2. package/dist/AssetsController.cjs +19 -7
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts.map +1 -1
  5. package/dist/AssetsController.d.mts.map +1 -1
  6. package/dist/AssetsController.mjs +19 -7
  7. package/dist/AssetsController.mjs.map +1 -1
  8. package/dist/data-sources/RpcDataSource.cjs +42 -232
  9. package/dist/data-sources/RpcDataSource.cjs.map +1 -1
  10. package/dist/data-sources/RpcDataSource.d.cts +1 -5
  11. package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
  12. package/dist/data-sources/RpcDataSource.d.mts +1 -5
  13. package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
  14. package/dist/data-sources/RpcDataSource.mjs +42 -229
  15. package/dist/data-sources/RpcDataSource.mjs.map +1 -1
  16. package/dist/data-sources/evm-rpc-services/index.cjs.map +1 -1
  17. package/dist/data-sources/evm-rpc-services/index.d.cts +1 -1
  18. package/dist/data-sources/evm-rpc-services/index.d.cts.map +1 -1
  19. package/dist/data-sources/evm-rpc-services/index.d.mts +1 -1
  20. package/dist/data-sources/evm-rpc-services/index.d.mts.map +1 -1
  21. package/dist/data-sources/evm-rpc-services/index.mjs.map +1 -1
  22. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs +27 -32
  23. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs.map +1 -1
  24. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts +5 -12
  25. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts.map +1 -1
  26. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts +5 -12
  27. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts.map +1 -1
  28. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs +27 -32
  29. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs.map +1 -1
  30. package/dist/data-sources/evm-rpc-services/services/TokenDetector.cjs +12 -23
  31. package/dist/data-sources/evm-rpc-services/services/TokenDetector.cjs.map +1 -1
  32. package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.cts +3 -8
  33. package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.cts.map +1 -1
  34. package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.mts +3 -8
  35. package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.mts.map +1 -1
  36. package/dist/data-sources/evm-rpc-services/services/TokenDetector.mjs +12 -23
  37. package/dist/data-sources/evm-rpc-services/services/TokenDetector.mjs.map +1 -1
  38. package/dist/data-sources/evm-rpc-services/services/index.cjs.map +1 -1
  39. package/dist/data-sources/evm-rpc-services/services/index.d.cts +2 -2
  40. package/dist/data-sources/evm-rpc-services/services/index.d.cts.map +1 -1
  41. package/dist/data-sources/evm-rpc-services/services/index.d.mts +2 -2
  42. package/dist/data-sources/evm-rpc-services/services/index.d.mts.map +1 -1
  43. package/dist/data-sources/evm-rpc-services/services/index.mjs.map +1 -1
  44. package/dist/data-sources/evm-rpc-services/types/index.cjs.map +1 -1
  45. package/dist/data-sources/evm-rpc-services/types/index.d.cts +1 -1
  46. package/dist/data-sources/evm-rpc-services/types/index.d.cts.map +1 -1
  47. package/dist/data-sources/evm-rpc-services/types/index.d.mts +1 -1
  48. package/dist/data-sources/evm-rpc-services/types/index.d.mts.map +1 -1
  49. package/dist/data-sources/evm-rpc-services/types/index.mjs.map +1 -1
  50. package/dist/data-sources/evm-rpc-services/types/state.cjs.map +1 -1
  51. package/dist/data-sources/evm-rpc-services/types/state.d.cts +24 -9
  52. package/dist/data-sources/evm-rpc-services/types/state.d.cts.map +1 -1
  53. package/dist/data-sources/evm-rpc-services/types/state.d.mts +24 -9
  54. package/dist/data-sources/evm-rpc-services/types/state.d.mts.map +1 -1
  55. package/dist/data-sources/evm-rpc-services/types/state.mjs.map +1 -1
  56. package/package.json +1 -1
@@ -10,17 +10,13 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  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");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var __importDefault = (this && this.__importDefault) || function (mod) {
14
- return (mod && mod.__esModule) ? mod : { "default": mod };
15
- };
16
- var _RpcDataSource_instances, _RpcDataSource_timeout, _RpcDataSource_tokenDetectionEnabled, _RpcDataSource_activeChains, _RpcDataSource_chainStatuses, _RpcDataSource_providerCache, _RpcDataSource_activeSubscriptions, _RpcDataSource_multicallClient, _RpcDataSource_balanceFetcher, _RpcDataSource_tokenDetector, _RpcDataSource_convertToHumanReadable, _RpcDataSource_collectMetadataForBalances, _RpcDataSource_handleBalanceUpdate, _RpcDataSource_handleDetectionUpdate, _RpcDataSource_registerActionHandlers, _RpcDataSource_subscribeToNetworkController, _RpcDataSource_initializeFromNetworkController, _RpcDataSource_updateFromNetworkState, _RpcDataSource_getProvider, _RpcDataSource_getMulticallProvider, _RpcDataSource_clearProviderCache, _RpcDataSource_accountSupportsChain, _RpcDataSource_buildNativeAssetId, _RpcDataSource_getExistingAssetsMetadata, _RpcDataSource_getTokenMetadataFromTokenList;
13
+ var _RpcDataSource_instances, _RpcDataSource_timeout, _RpcDataSource_tokenDetectionEnabled, _RpcDataSource_activeChains, _RpcDataSource_chainStatuses, _RpcDataSource_providerCache, _RpcDataSource_activeSubscriptions, _RpcDataSource_multicallClient, _RpcDataSource_balanceFetcher, _RpcDataSource_tokenDetector, _RpcDataSource_handleBalanceUpdate, _RpcDataSource_handleDetectionUpdate, _RpcDataSource_registerActionHandlers, _RpcDataSource_subscribeToNetworkController, _RpcDataSource_initializeFromNetworkController, _RpcDataSource_updateFromNetworkState, _RpcDataSource_getProvider, _RpcDataSource_getMulticallProvider, _RpcDataSource_clearProviderCache, _RpcDataSource_accountSupportsChain, _RpcDataSource_buildNativeAssetId;
17
14
  Object.defineProperty(exports, "__esModule", { value: true });
18
15
  exports.createRpcDataSource = exports.RpcDataSource = exports.caipChainIdToHex = void 0;
19
16
  const providers_1 = require("@ethersproject/providers");
20
17
  const base_controller_1 = require("@metamask/base-controller");
21
18
  const controller_utils_1 = require("@metamask/controller-utils");
22
19
  const utils_1 = require("@metamask/utils");
23
- const bignumber_js_1 = __importDefault(require("bignumber.js"));
24
20
  const evm_rpc_services_1 = require("./evm-rpc-services/index.cjs");
25
21
  const logger_1 = require("../logger.cjs");
26
22
  const CONTROLLER_NAME = 'RpcDataSource';
@@ -98,25 +94,24 @@ class RpcDataSource extends base_controller_1.BaseController {
98
94
  __classPrivateFieldSet(this, _RpcDataSource_multicallClient, new evm_rpc_services_1.MulticallClient((hexChainId) => {
99
95
  return __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_getMulticallProvider).call(this, hexChainId);
100
96
  }), "f");
101
- // Create messenger adapters for BalanceFetcher and TokenDetector
102
- const balanceFetcherMessenger = {
103
- call: (_action) => {
104
- const state = this.messenger.call('AssetsController:getState');
105
- return {
106
- assetsBalance: (state.assetsBalance ?? {}),
107
- };
108
- },
97
+ // Create state getters using messenger
98
+ const getTokenListState = () => {
99
+ return this.messenger.call('TokenListController:getState');
109
100
  };
110
- const tokenDetectorMessenger = {
111
- call: (_action) => {
112
- return this.messenger.call('TokenListController:getState');
113
- },
101
+ const getUserTokensState = () => {
102
+ return this.messenger.call('AssetsController:getState');
114
103
  };
115
104
  // Initialize BalanceFetcher with polling interval
116
- __classPrivateFieldSet(this, _RpcDataSource_balanceFetcher, new evm_rpc_services_1.BalanceFetcher(__classPrivateFieldGet(this, _RpcDataSource_multicallClient, "f"), balanceFetcherMessenger, { pollingInterval: balanceInterval }), "f");
105
+ __classPrivateFieldSet(this, _RpcDataSource_balanceFetcher, new evm_rpc_services_1.BalanceFetcher(__classPrivateFieldGet(this, _RpcDataSource_multicallClient, "f"), {
106
+ pollingInterval: balanceInterval,
107
+ }), "f");
108
+ __classPrivateFieldGet(this, _RpcDataSource_balanceFetcher, "f").setUserTokensStateGetter(getUserTokensState);
117
109
  __classPrivateFieldGet(this, _RpcDataSource_balanceFetcher, "f").setOnBalanceUpdate(__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_handleBalanceUpdate).bind(this));
118
110
  // Initialize TokenDetector with polling interval
119
- __classPrivateFieldSet(this, _RpcDataSource_tokenDetector, new evm_rpc_services_1.TokenDetector(__classPrivateFieldGet(this, _RpcDataSource_multicallClient, "f"), tokenDetectorMessenger, { pollingInterval: detectionInterval }), "f");
111
+ __classPrivateFieldSet(this, _RpcDataSource_tokenDetector, new evm_rpc_services_1.TokenDetector(__classPrivateFieldGet(this, _RpcDataSource_multicallClient, "f"), {
112
+ pollingInterval: detectionInterval,
113
+ }), "f");
114
+ __classPrivateFieldGet(this, _RpcDataSource_tokenDetector, "f").setTokenListStateGetter(getTokenListState);
120
115
  __classPrivateFieldGet(this, _RpcDataSource_tokenDetector, "f").setOnDetectionUpdate(__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_handleDetectionUpdate).bind(this));
121
116
  __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_registerActionHandlers).call(this);
122
117
  __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_subscribeToNetworkController).call(this);
@@ -202,7 +197,6 @@ class RpcDataSource extends base_controller_1.BaseController {
202
197
  return response;
203
198
  }
204
199
  const assetsBalance = {};
205
- const assetsMetadata = {};
206
200
  const failedChains = [];
207
201
  // Fetch balances for each chain using BalanceFetcher
208
202
  for (const chainId of chainsToFetch) {
@@ -219,17 +213,10 @@ class RpcDataSource extends base_controller_1.BaseController {
219
213
  if (!assetsBalance[accountId]) {
220
214
  assetsBalance[accountId] = {};
221
215
  }
222
- // Collect metadata for all balances
223
- const balanceMetadata = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_collectMetadataForBalances).call(this, result.balances, chainId);
224
- Object.assign(assetsMetadata, balanceMetadata);
225
- // Convert balances to human-readable format
216
+ // Convert balances to response format
226
217
  for (const balance of result.balances) {
227
- const metadata = assetsMetadata[balance.assetId];
228
- // Default to 18 decimals (ERC20 standard) for consistent human-readable format
229
- const decimals = metadata?.decimals ?? 18;
230
- const humanReadableAmount = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_convertToHumanReadable).call(this, balance.balance, decimals);
231
218
  assetsBalance[accountId][balance.assetId] = {
232
- amount: humanReadableAmount,
219
+ amount: balance.balance,
233
220
  };
234
221
  }
235
222
  }
@@ -240,16 +227,6 @@ class RpcDataSource extends base_controller_1.BaseController {
240
227
  }
241
228
  const nativeAssetId = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_buildNativeAssetId).call(this, chainId);
242
229
  assetsBalance[accountId][nativeAssetId] = { amount: '0' };
243
- // Even on error, include native token metadata
244
- const chainStatus = __classPrivateFieldGet(this, _RpcDataSource_chainStatuses, "f")[chainId];
245
- if (chainStatus) {
246
- assetsMetadata[nativeAssetId] = {
247
- type: 'native',
248
- symbol: chainStatus.nativeCurrency,
249
- name: chainStatus.nativeCurrency,
250
- decimals: 18,
251
- };
252
- }
253
230
  if (!failedChains.includes(chainId)) {
254
231
  failedChains.push(chainId);
255
232
  }
@@ -273,10 +250,6 @@ class RpcDataSource extends base_controller_1.BaseController {
273
250
  });
274
251
  }
275
252
  response.assetsBalance = assetsBalance;
276
- // Include metadata for native tokens if we have any
277
- if (Object.keys(assetsMetadata).length > 0) {
278
- response.assetsMetadata = assetsMetadata;
279
- }
280
253
  return response;
281
254
  }
282
255
  /**
@@ -306,27 +279,10 @@ class RpcDataSource extends base_controller_1.BaseController {
306
279
  });
307
280
  // Convert detected assets to DataResponse format
308
281
  const balances = {};
309
- const assetsMetadata = {};
310
- // Build metadata from detected assets
311
- for (const asset of result.detectedAssets) {
312
- if (asset.symbol && asset.decimals !== undefined) {
313
- assetsMetadata[asset.assetId] = {
314
- type: 'erc20',
315
- symbol: asset.symbol,
316
- name: asset.name ?? asset.symbol,
317
- decimals: asset.decimals,
318
- image: asset.image,
319
- };
320
- }
321
- }
322
- // Add balances for detected tokens (converted to human-readable format)
282
+ // Add balances for detected tokens
323
283
  for (const balance of result.detectedBalances) {
324
- const detectedAsset = result.detectedAssets.find((asset) => asset.assetId === balance.assetId);
325
- // Default to 18 decimals (ERC20 standard) for consistent human-readable format
326
- const decimals = detectedAsset?.decimals ?? 18;
327
- const humanReadableAmount = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_convertToHumanReadable).call(this, balance.balance, decimals);
328
284
  balances[balance.assetId] = {
329
- amount: humanReadableAmount,
285
+ amount: balance.balance,
330
286
  };
331
287
  }
332
288
  const response = {
@@ -337,10 +293,6 @@ class RpcDataSource extends base_controller_1.BaseController {
337
293
  [accountId]: balances,
338
294
  },
339
295
  };
340
- // Include metadata if we have any
341
- if (Object.keys(assetsMetadata).length > 0) {
342
- response.assetsMetadata = assetsMetadata;
343
- }
344
296
  return response;
345
297
  }
346
298
  catch (error) {
@@ -350,7 +302,7 @@ class RpcDataSource extends base_controller_1.BaseController {
350
302
  }
351
303
  get assetsMiddleware() {
352
304
  return async (context, next) => {
353
- var _a, _b, _c;
305
+ var _a, _b;
354
306
  const { request } = context;
355
307
  const supportedChains = request.chainIds.filter((chainId) => __classPrivateFieldGet(this, _RpcDataSource_activeChains, "f").includes(chainId));
356
308
  if (supportedChains.length === 0) {
@@ -375,13 +327,6 @@ class RpcDataSource extends base_controller_1.BaseController {
375
327
  };
376
328
  }
377
329
  }
378
- if (response.assetsMetadata) {
379
- (_c = context.response).assetsMetadata ?? (_c.assetsMetadata = {});
380
- context.response.assetsMetadata = {
381
- ...context.response.assetsMetadata,
382
- ...response.assetsMetadata,
383
- };
384
- }
385
330
  const failedChains = new Set(Object.keys(response.errors ?? {}));
386
331
  successfullyHandledChains = supportedChains.filter((chainId) => !failedChains.has(chainId));
387
332
  if (successfullyHandledChains.length > 0) {
@@ -416,19 +361,20 @@ class RpcDataSource extends base_controller_1.BaseController {
416
361
  log('No active chains to subscribe');
417
362
  return;
418
363
  }
419
- // Handle subscription update - restart polling for new chains
364
+ // Handle subscription update
420
365
  if (isUpdate) {
421
366
  const existing = __classPrivateFieldGet(this, _RpcDataSource_activeSubscriptions, "f").get(subscriptionId);
422
367
  if (existing) {
423
- log('Updating existing subscription - restarting polling', {
368
+ log('Updating existing subscription', {
424
369
  subscriptionId,
425
- existingChains: existing.chains,
426
- newChains: chainsToSubscribe,
370
+ chainsToSubscribe,
427
371
  });
428
- // Don't return early - continue to unsubscribe and restart polling
372
+ existing.chains = chainsToSubscribe;
373
+ existing.accounts = request.accounts;
374
+ return;
429
375
  }
430
376
  }
431
- // Clean up existing subscription (stops old polling)
377
+ // Clean up existing subscription
432
378
  await this.unsubscribe(subscriptionId);
433
379
  // Start polling through BalanceFetcher and TokenDetector
434
380
  const balancePollingTokens = [];
@@ -509,82 +455,18 @@ class RpcDataSource extends base_controller_1.BaseController {
509
455
  }
510
456
  }
511
457
  exports.RpcDataSource = RpcDataSource;
512
- _RpcDataSource_timeout = new WeakMap(), _RpcDataSource_tokenDetectionEnabled = new WeakMap(), _RpcDataSource_activeChains = new WeakMap(), _RpcDataSource_chainStatuses = new WeakMap(), _RpcDataSource_providerCache = new WeakMap(), _RpcDataSource_activeSubscriptions = new WeakMap(), _RpcDataSource_multicallClient = new WeakMap(), _RpcDataSource_balanceFetcher = new WeakMap(), _RpcDataSource_tokenDetector = new WeakMap(), _RpcDataSource_instances = new WeakSet(), _RpcDataSource_convertToHumanReadable = function _RpcDataSource_convertToHumanReadable(rawBalance, decimals) {
513
- const rawAmount = new bignumber_js_1.default(rawBalance);
514
- const divisor = new bignumber_js_1.default(10).pow(decimals);
515
- return rawAmount.dividedBy(divisor).toString();
516
- }, _RpcDataSource_collectMetadataForBalances = function _RpcDataSource_collectMetadataForBalances(balances, chainId) {
517
- const assetsMetadata = {};
518
- const existingMetadata = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_getExistingAssetsMetadata).call(this);
519
- for (const balance of balances) {
520
- const isNative = balance.assetId.includes('/slip44:');
521
- if (isNative) {
522
- const chainStatus = __classPrivateFieldGet(this, _RpcDataSource_chainStatuses, "f")[chainId];
523
- if (chainStatus) {
524
- assetsMetadata[balance.assetId] = {
525
- type: 'native',
526
- symbol: chainStatus.nativeCurrency,
527
- name: chainStatus.nativeCurrency,
528
- decimals: 18,
529
- };
530
- }
531
- }
532
- else {
533
- // For ERC20 tokens, try existing metadata from state first
534
- const existingMeta = existingMetadata[balance.assetId];
535
- if (existingMeta) {
536
- assetsMetadata[balance.assetId] = existingMeta;
537
- }
538
- else {
539
- // Fallback to token list if not in state
540
- const tokenListMeta = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_getTokenMetadataFromTokenList).call(this, balance.assetId);
541
- if (tokenListMeta) {
542
- assetsMetadata[balance.assetId] = tokenListMeta;
543
- }
544
- else {
545
- // Default metadata for unknown ERC20 tokens.
546
- // Use 18 decimals (the standard for most ERC20 tokens)
547
- // to ensure consistent human-readable balance format.
548
- assetsMetadata[balance.assetId] = {
549
- type: 'erc20',
550
- symbol: '',
551
- name: '',
552
- decimals: 18,
553
- };
554
- }
555
- }
556
- }
557
- }
558
- return assetsMetadata;
559
- }, _RpcDataSource_handleBalanceUpdate = function _RpcDataSource_handleBalanceUpdate(result) {
560
- const newBalances = {};
561
- // Convert hex chain ID to CAIP-2 format
562
- const chainIdDecimal = parseInt(result.chainId, 16);
563
- const caipChainId = `eip155:${chainIdDecimal}`;
564
- // Collect metadata for all balances
565
- const assetsMetadata = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_collectMetadataForBalances).call(this, result.balances, caipChainId);
566
- // Convert balances to human-readable format using metadata
458
+ _RpcDataSource_timeout = new WeakMap(), _RpcDataSource_tokenDetectionEnabled = new WeakMap(), _RpcDataSource_activeChains = new WeakMap(), _RpcDataSource_chainStatuses = new WeakMap(), _RpcDataSource_providerCache = new WeakMap(), _RpcDataSource_activeSubscriptions = new WeakMap(), _RpcDataSource_multicallClient = new WeakMap(), _RpcDataSource_balanceFetcher = new WeakMap(), _RpcDataSource_tokenDetector = new WeakMap(), _RpcDataSource_instances = new WeakSet(), _RpcDataSource_handleBalanceUpdate = function _RpcDataSource_handleBalanceUpdate(result) {
459
+ const accountBalances = {};
567
460
  for (const balance of result.balances) {
568
- const metadata = assetsMetadata[balance.assetId];
569
- // Default to 18 decimals (ERC20 standard) for consistent human-readable format
570
- const decimals = metadata?.decimals ?? 18;
571
- const humanReadableAmount = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_convertToHumanReadable).call(this, balance.balance, decimals);
572
- newBalances[balance.assetId] = {
573
- amount: humanReadableAmount,
461
+ accountBalances[balance.assetId] = {
462
+ amount: balance.balance,
574
463
  };
575
464
  }
576
- // Only send new data to AssetsController - it handles merging atomically
577
- // to avoid race conditions when concurrent updates occur for the same account
578
465
  const response = {
579
466
  assetsBalance: {
580
- [result.accountId]: newBalances,
467
+ [result.accountId]: accountBalances,
581
468
  },
582
- assetsMetadata,
583
469
  };
584
- log('Balance update response', {
585
- accountId: result.accountId,
586
- newBalanceCount: Object.keys(newBalances).length,
587
- });
588
470
  this.messenger
589
471
  .call('AssetsController:assetsUpdate', response, CONTROLLER_NAME)
590
472
  .catch((error) => {
@@ -594,47 +476,22 @@ _RpcDataSource_timeout = new WeakMap(), _RpcDataSource_tokenDetectionEnabled = n
594
476
  log('Detected new tokens', {
595
477
  count: result.detectedAssets.length,
596
478
  });
597
- // Build new metadata from detected assets
598
- const newMetadata = {};
599
- if (result.detectedAssets.length > 0) {
600
- for (const asset of result.detectedAssets) {
601
- // Only include if we have metadata (symbol and decimals at minimum)
602
- if (asset.symbol && asset.decimals !== undefined) {
603
- newMetadata[asset.assetId] = {
604
- type: 'erc20',
605
- symbol: asset.symbol,
606
- name: asset.name ?? asset.symbol,
607
- decimals: asset.decimals,
608
- image: asset.image,
609
- };
610
- }
611
- }
612
- }
613
- // Build new balances from detected tokens
614
- const newBalances = {};
615
- if (result.detectedBalances.length > 0) {
616
- for (const balance of result.detectedBalances) {
617
- // Get decimals from the detected asset metadata
618
- const detectedAsset = result.detectedAssets.find((asset) => asset.assetId === balance.assetId);
619
- // Default to 18 decimals (ERC20 standard) for consistent human-readable format
620
- const decimals = detectedAsset?.decimals ?? 18;
621
- const humanReadableAmount = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_convertToHumanReadable).call(this, balance.balance, decimals);
622
- newBalances[balance.assetId] = {
623
- amount: humanReadableAmount,
624
- };
625
- }
626
- }
627
- // Only send new data to AssetsController - it handles merging atomically
628
- // to avoid race conditions when concurrent updates occur for the same account
629
479
  const response = {
630
480
  detectedAssets: {
631
481
  [result.accountId]: result.detectedAssets.map((asset) => asset.assetId),
632
482
  },
633
- assetsMetadata: newMetadata,
634
- assetsBalance: {
635
- [result.accountId]: newBalances,
636
- },
637
483
  };
484
+ // Add balances for detected tokens
485
+ if (result.detectedBalances.length > 0) {
486
+ response.assetsBalance = {
487
+ [result.accountId]: {},
488
+ };
489
+ for (const balance of result.detectedBalances) {
490
+ response.assetsBalance[result.accountId][balance.assetId] = {
491
+ amount: balance.balance,
492
+ };
493
+ }
494
+ }
638
495
  this.messenger
639
496
  .call('AssetsController:assetsUpdate', response, CONTROLLER_NAME)
640
497
  .catch((error) => {
@@ -774,53 +631,6 @@ _RpcDataSource_timeout = new WeakMap(), _RpcDataSource_tokenDetectionEnabled = n
774
631
  const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
775
632
  return (nativeAssetIdentifiers[chainId] ??
776
633
  `${chainId}/slip44:60`);
777
- }, _RpcDataSource_getExistingAssetsMetadata = function _RpcDataSource_getExistingAssetsMetadata() {
778
- try {
779
- const state = this.messenger.call('AssetsController:getState');
780
- return (state.assetsMetadata ?? {});
781
- }
782
- catch {
783
- // If AssetsController:getState fails, return empty metadata
784
- return {};
785
- }
786
- }, _RpcDataSource_getTokenMetadataFromTokenList = function _RpcDataSource_getTokenMetadataFromTokenList(assetId) {
787
- try {
788
- // Parse asset ID to get chain and token address
789
- // Format: eip155:{chainId}/erc20:{address}
790
- const [chainPart, assetPart] = assetId.split('/');
791
- if (!assetPart?.startsWith('erc20:')) {
792
- return undefined;
793
- }
794
- const tokenAddress = assetPart.slice(6); // Remove 'erc20:' prefix
795
- const chainIdDecimal = chainPart.split(':')[1];
796
- const hexChainId = `0x${parseInt(chainIdDecimal, 10).toString(16)}`;
797
- const tokenListState = this.messenger.call('TokenListController:getState');
798
- const chainCacheEntry = tokenListState.tokensChainsCache[hexChainId];
799
- const chainTokenList = chainCacheEntry?.data;
800
- if (!chainTokenList) {
801
- return undefined;
802
- }
803
- // Look up token by address (case-insensitive)
804
- const lowerAddress = tokenAddress.toLowerCase();
805
- for (const [address, tokenData] of Object.entries(chainTokenList)) {
806
- if (address.toLowerCase() === lowerAddress) {
807
- const token = tokenData;
808
- if (token.symbol && token.decimals !== undefined) {
809
- return {
810
- type: 'erc20',
811
- symbol: token.symbol,
812
- name: token.name ?? token.symbol,
813
- decimals: token.decimals,
814
- image: token.iconUrl,
815
- };
816
- }
817
- }
818
- }
819
- return undefined;
820
- }
821
- catch {
822
- return undefined;
823
- }
824
634
  };
825
635
  function createRpcDataSource(options) {
826
636
  return new RpcDataSource(options);