@metamask-previews/assets-controller 16.1.0-preview-1efee3183 → 16.1.1-preview-c8ffe7b0e

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.
@@ -1,6 +1,6 @@
1
1
  import type { AccountActivityServiceBalanceUpdatedEvent, AccountActivityServiceStatusChangedEvent } from '@metamask/core-backend';
2
2
  import type { AssetsControllerMessenger } from '../AssetsController.js';
3
- import type { ChainId, Caip19AssetId, DataRequest, DataResponse } from '../types.js';
3
+ import type { ChainId, DataRequest, DataResponse } from '../types.js';
4
4
  import { AbstractDataSource } from './AbstractDataSource.js';
5
5
  import type { DataSourceState } from './AbstractDataSource.js';
6
6
  declare const CONTROLLER_NAME = "AccountActivityDataSource";
@@ -12,8 +12,6 @@ export type AccountActivityDataSourceOptions = {
12
12
  messenger: AssetsControllerMessenger;
13
13
  /** Called when active chains are updated. Pass dataSourceName so the controller knows the source. */
14
14
  onActiveChainsUpdated: (dataSourceName: string, chains: ChainId[], previousChains: ChainId[]) => void;
15
- /** Returns the asset type ('native' | 'erc20' | 'spl') for a given CAIP-19 asset ID. */
16
- getAssetType: (assetId: Caip19AssetId) => 'native' | 'erc20' | 'spl';
17
15
  /**
18
16
  * Pushes decoded balance updates to the controller (bound to
19
17
  * `AssetsController.handleAssetsUpdate`). AADS is event-driven and never
@@ -1 +1 @@
1
- {"version":3,"file":"AccountActivityDataSource.d.ts","sourceRoot":"","sources":["../../src/data-sources/AccountActivityDataSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yCAAyC,EACzC,wCAAwC,EAEzC,MAAM,wBAAwB,CAAC;AAKhC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAExE,OAAO,KAAK,EAGV,OAAO,EACP,aAAa,EACb,WAAW,EACX,YAAY,EACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,QAAA,MAAM,eAAe,8BAA8B,CAAC;AAsFpD,mEAAmE;AACnE,MAAM,MAAM,sCAAsC,GAC9C,yCAAyC,GACzC,wCAAwC,CAAC;AAM7C,MAAM,MAAM,8BAA8B,GAAG,eAAe,CAAC;AAU7D,MAAM,MAAM,gCAAgC,GAAG;IAC7C,mEAAmE;IACnE,SAAS,EAAE,yBAAyB,CAAC;IACrC,qGAAqG;IACrG,qBAAqB,EAAE,CACrB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,OAAO,EAAE,EACjB,cAAc,EAAE,OAAO,EAAE,KACtB,IAAI,CAAC;IACV,wFAAwF;IACxF,YAAY,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;IACrE;;;;;OAKG;IACH,cAAc,EAAE,CACd,QAAQ,EAAE,YAAY,EACtB,OAAO,CAAC,EAAE,WAAW,KAClB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;CACjD,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,yBAA0B,SAAQ,kBAAkB,CAC/D,OAAO,eAAe,EACtB,8BAA8B,CAC/B;;IAwBC,YAAY,OAAO,EAAE,gCAAgC,EAapD;IAqBD;;;;;;;OAOG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/B;IAwJD,OAAO,IAAI,IAAI,CAoBd;CACF;AAMD;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,gCAAgC,GACxC,yBAAyB,CAE3B"}
1
+ {"version":3,"file":"AccountActivityDataSource.d.ts","sourceRoot":"","sources":["../../src/data-sources/AccountActivityDataSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yCAAyC,EACzC,wCAAwC,EAEzC,MAAM,wBAAwB,CAAC;AAKhC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAExE,OAAO,KAAK,EAEV,OAAO,EAEP,WAAW,EACX,YAAY,EACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,QAAA,MAAM,eAAe,8BAA8B,CAAC;AAwEpD,mEAAmE;AACnE,MAAM,MAAM,sCAAsC,GAC9C,yCAAyC,GACzC,wCAAwC,CAAC;AAM7C,MAAM,MAAM,8BAA8B,GAAG,eAAe,CAAC;AAU7D,MAAM,MAAM,gCAAgC,GAAG;IAC7C,mEAAmE;IACnE,SAAS,EAAE,yBAAyB,CAAC;IACrC,qGAAqG;IACrG,qBAAqB,EAAE,CACrB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,OAAO,EAAE,EACjB,cAAc,EAAE,OAAO,EAAE,KACtB,IAAI,CAAC;IACV;;;;;OAKG;IACH,cAAc,EAAE,CACd,QAAQ,EAAE,YAAY,EACtB,OAAO,CAAC,EAAE,WAAW,KAClB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;CACjD,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,yBAA0B,SAAQ,kBAAkB,CAC/D,OAAO,eAAe,EACtB,8BAA8B,CAC/B;;IAoBC,YAAY,OAAO,EAAE,gCAAgC,EAYpD;IAqBD;;;;;;;OAOG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/B;IAuJD,OAAO,IAAI,IAAI,CAoBd;CACF;AAMD;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,gCAAgC,GACxC,yBAAyB,CAE3B"}
@@ -17,13 +17,11 @@ const log = createModuleLogger(projectLogger, CONTROLLER_NAME);
17
17
  *
18
18
  * @param updates - Balance updates from account-activity websocket payload.
19
19
  * @param accountId - Internal account UUID.
20
- * @param getAssetType - Resolver for asset metadata type.
21
20
  * @returns DataResponse with merge mode when balances are present.
22
21
  */
23
- function processAccountActivityBalanceUpdates(updates, accountId, getAssetType) {
22
+ function processAccountActivityBalanceUpdates(updates, accountId) {
24
23
  const assetsBalance = Object.create(null);
25
24
  assetsBalance[accountId] = Object.create(null);
26
- const assetsMetadata = Object.create(null);
27
25
  for (const update of updates) {
28
26
  const { asset, postBalance } = update;
29
27
  if (!asset || !postBalance) {
@@ -47,17 +45,10 @@ function processAccountActivityBalanceUpdates(updates, accountId, getAssetType)
47
45
  amount: humanReadableAmount,
48
46
  ...(postBalance.metadata ? { metadata: postBalance.metadata } : {}),
49
47
  };
50
- assetsMetadata[assetId] = {
51
- type: getAssetType(assetId),
52
- symbol: asset.unit,
53
- name: asset.unit,
54
- decimals: asset.decimals,
55
- };
56
48
  }
57
49
  const response = { updateMode: 'merge' };
58
50
  if (Object.keys(assetsBalance[accountId]).length > 0) {
59
51
  response.assetsBalance = assetsBalance;
60
- response.assetsInfo = assetsMetadata;
61
52
  }
62
53
  return response;
63
54
  }
@@ -102,7 +93,6 @@ const defaultState = {
102
93
  export class AccountActivityDataSource extends AbstractDataSource {
103
94
  #messenger;
104
95
  #onActiveChainsUpdated;
105
- #getAssetType;
106
96
  #onAssetsUpdate;
107
97
  #onBalanceUpdatedBound;
108
98
  constructor(options) {
@@ -112,7 +102,6 @@ export class AccountActivityDataSource extends AbstractDataSource {
112
102
  });
113
103
  this.#messenger = options.messenger;
114
104
  this.#onActiveChainsUpdated = options.onActiveChainsUpdated;
115
- this.#getAssetType = options.getAssetType;
116
105
  this.#onAssetsUpdate = options.onAssetsUpdate;
117
106
  this.#onBalanceUpdatedBound = this.#onBalanceUpdated.bind(this);
118
107
  this.#subscribeToEvents();
@@ -151,14 +140,14 @@ export class AccountActivityDataSource extends AbstractDataSource {
151
140
  return;
152
141
  }
153
142
  const chainId = chain;
154
- const response = processAccountActivityBalanceUpdates(updates, account.id, (assetId) => this.#getAssetType(assetId));
143
+ const response = processAccountActivityBalanceUpdates(updates, account.id);
155
144
  if (!response.assetsBalance) {
156
145
  return;
157
146
  }
158
147
  const request = {
159
148
  accountsWithSupportedChains: [{ account, supportedChains: [chainId] }],
160
149
  chainIds: [chainId],
161
- dataTypes: ['balance', 'metadata'],
150
+ dataTypes: ['balance', 'metadata', 'price'],
162
151
  };
163
152
  Promise.resolve(this.#onAssetsUpdate(response, request)).catch((error) => {
164
153
  log('Failed to report balance update', { error });
@@ -1 +1 @@
1
- {"version":3,"file":"AccountActivityDataSource.js","sourceRoot":"","sources":["../../src/data-sources/AccountActivityDataSource.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountActivityServiceBalanceUpdatedEvent,\n AccountActivityServiceStatusChangedEvent,\n BalanceUpdate,\n} from '@metamask/core-backend';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport { isCaipChainId } from '@metamask/utils';\nimport { BigNumber as BigNumberJS } from 'bignumber.js';\n\nimport type { AssetsControllerMessenger } from '../AssetsController.js';\nimport { projectLogger, createModuleLogger } from '../logger.js';\nimport type {\n AssetBalance,\n AssetMetadata,\n ChainId,\n Caip19AssetId,\n DataRequest,\n DataResponse,\n} from '../types.js';\nimport { safeNormalizeAssetId } from '../utils/index.js';\nimport { AbstractDataSource } from './AbstractDataSource.js';\nimport type { DataSourceState } from './AbstractDataSource.js';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst CONTROLLER_NAME = 'AccountActivityDataSource';\n\nconst log = createModuleLogger(projectLogger, CONTROLLER_NAME);\n\n// ============================================================================\n// BALANCE UPDATE PROCESSING\n// ============================================================================\n\n/**\n * Convert AccountActivityMessage balance updates into a {@link DataResponse}\n * for AssetsController.\n *\n * @param updates - Balance updates from account-activity websocket payload.\n * @param accountId - Internal account UUID.\n * @param getAssetType - Resolver for asset metadata type.\n * @returns DataResponse with merge mode when balances are present.\n */\nfunction processAccountActivityBalanceUpdates(\n updates: BalanceUpdate[],\n accountId: string,\n getAssetType: (assetId: Caip19AssetId) => 'native' | 'erc20' | 'spl',\n): DataResponse {\n const assetsBalance = Object.create(null) as Record<\n string,\n Record<Caip19AssetId, AssetBalance>\n >;\n assetsBalance[accountId] = Object.create(null) as Record<\n Caip19AssetId,\n AssetBalance\n >;\n const assetsMetadata = Object.create(null) as Record<\n Caip19AssetId,\n AssetMetadata\n >;\n\n for (const update of updates) {\n const { asset, postBalance } = update;\n\n if (!asset || !postBalance) {\n continue;\n }\n\n // The websocket sends lower-case ERC-20 addresses, while state and the\n // rest of the pipeline key assets by their checksummed ID. Normalizing\n // here keeps middleware comparisons (detection, custom-asset graduation,\n // occurrence filtering) from treating an existing holding as brand new.\n const assetId = safeNormalizeAssetId(asset.type as Caip19AssetId);\n\n if (asset.decimals === undefined) {\n continue;\n }\n\n const rawBalanceStr = postBalance.amount.startsWith('0x')\n ? BigInt(postBalance.amount).toString()\n : postBalance.amount;\n\n const humanReadableAmount = new BigNumberJS(rawBalanceStr)\n .dividedBy(new BigNumberJS(10).pow(asset.decimals))\n .toFixed();\n\n assetsBalance[accountId][assetId] = {\n amount: humanReadableAmount,\n ...(postBalance.metadata ? { metadata: postBalance.metadata } : {}),\n };\n\n assetsMetadata[assetId] = {\n type: getAssetType(assetId),\n symbol: asset.unit,\n name: asset.unit,\n decimals: asset.decimals,\n };\n }\n\n const response: DataResponse = { updateMode: 'merge' };\n if (Object.keys(assetsBalance[accountId]).length > 0) {\n response.assetsBalance = assetsBalance;\n response.assetsInfo = assetsMetadata;\n }\n\n return response;\n}\n\n// ============================================================================\n// MESSENGER TYPES\n// ============================================================================\n\n/** Allowed events that AccountActivityDataSource subscribes to. */\nexport type AccountActivityDataSourceAllowedEvents =\n | AccountActivityServiceBalanceUpdatedEvent\n | AccountActivityServiceStatusChangedEvent;\n\n// ============================================================================\n// STATE\n// ============================================================================\n\nexport type AccountActivityDataSourceState = DataSourceState;\n\nconst defaultState: AccountActivityDataSourceState = {\n activeChains: [],\n};\n\n// ============================================================================\n// OPTIONS\n// ============================================================================\n\nexport type AccountActivityDataSourceOptions = {\n /** The AssetsController messenger (shared by all data sources). */\n messenger: AssetsControllerMessenger;\n /** Called when active chains are updated. Pass dataSourceName so the controller knows the source. */\n onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n /** Returns the asset type ('native' | 'erc20' | 'spl') for a given CAIP-19 asset ID. */\n getAssetType: (assetId: Caip19AssetId) => 'native' | 'erc20' | 'spl';\n /**\n * Pushes decoded balance updates to the controller (bound to\n * `AssetsController.handleAssetsUpdate`). AADS is event-driven and never\n * takes part in the controller's subscribe handoff, so it receives this\n * callback directly instead of via a `SubscriptionRequest`.\n */\n onAssetsUpdate: (\n response: DataResponse,\n request?: DataRequest,\n ) => void | Promise<void>;\n state?: Partial<AccountActivityDataSourceState>;\n};\n\n// ============================================================================\n// ACCOUNT ACTIVITY DATA SOURCE\n// ============================================================================\n\n/**\n * Data source that consumes real-time updates from `AccountActivityService`.\n *\n * `AccountActivityService` owns the WebSocket connection and channel\n * subscriptions; this data source is a thin consumer of the two high-level\n * events that it publishes:\n *\n * - `AccountActivityService:balanceUpdated` — post-transaction balances for the\n * subscribed account(s). The address is resolved against the wallet's\n * selected account group, transformed into a {@link DataResponse} (via\n * {@link processAccountActivityBalanceUpdates}), and pushed to the controller\n * through the injected `onAssetsUpdate` callback.\n * - `AccountActivityService:statusChanged` — per-chain \"up\"/\"down\" notifications.\n * A chain reported \"up\" is claimed as an active chain (WebSocket is providing\n * real-time data); a chain reported \"down\" is released so polling data sources\n * can take over. Each change is applied directly via `updateActiveChains`,\n * which notifies the controller through `onActiveChainsUpdated`.\n *\n * This data source does NOT debounce, jitter, or gate chain updates itself.\n * Coalescing (collapsing bursts) and jitter (staggering the WS-subscribe herd\n * across clients) live in `AssetsController`, where the expensive re-subscribe\n * happens and where updates from all data sources converge. `activeChains` are\n * never seeded from the accounts API; they only ever reflect live\n * `statusChanged` events (the service flushes all tracked chains as \"down\" when\n * the WebSocket disconnects, releasing them).\n *\n * It subscribes to these events in its constructor (the same way\n * `TokenBalancesController` does). Unlike the polling data sources it does not\n * take part in the controller's subscribe/unsubscribe handoff: `subscribe` is a\n * no-op, balance updates are routed by resolving the address against the\n * wallet, and updates are pushed through the injected `onAssetsUpdate` callback.\n */\nexport class AccountActivityDataSource extends AbstractDataSource<\n typeof CONTROLLER_NAME,\n AccountActivityDataSourceState\n> {\n readonly #messenger: AssetsControllerMessenger;\n\n readonly #onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n\n readonly #getAssetType: (\n assetId: Caip19AssetId,\n ) => 'native' | 'erc20' | 'spl';\n\n readonly #onAssetsUpdate: (\n response: DataResponse,\n request?: DataRequest,\n ) => void | Promise<void>;\n\n readonly #onBalanceUpdatedBound: (event: {\n address: string;\n chain: string;\n updates: BalanceUpdate[];\n }) => void;\n\n constructor(options: AccountActivityDataSourceOptions) {\n super(CONTROLLER_NAME, {\n ...defaultState,\n ...options.state,\n });\n\n this.#messenger = options.messenger;\n this.#onActiveChainsUpdated = options.onActiveChainsUpdated;\n this.#getAssetType = options.getAssetType;\n this.#onAssetsUpdate = options.onAssetsUpdate;\n this.#onBalanceUpdatedBound = this.#onBalanceUpdated.bind(this);\n\n this.#subscribeToEvents();\n }\n\n // ============================================================================\n // EVENT SUBSCRIPTIONS\n // ============================================================================\n\n #subscribeToEvents(): void {\n this.#messenger.subscribe(\n 'AccountActivityService:balanceUpdated',\n this.#onBalanceUpdatedBound,\n );\n this.#messenger.subscribe(\n 'AccountActivityService:statusChanged',\n this.#onAccountActivityStatusChanged,\n );\n }\n\n // ============================================================================\n // SUBSCRIBE / UNSUBSCRIBE\n // ============================================================================\n\n /**\n * AADS is event-driven and chain-agnostic: it never participates in the\n * controller's subscribe/unsubscribe handoff. Incoming `balanceUpdated`\n * events are routed by resolving the address against the wallet's accounts\n * (see `#onBalanceUpdated`), and updates are pushed through the injected\n * `#onAssetsUpdate` callback. This override exists only to satisfy the\n * abstract contract and is intentionally a no-op.\n */\n async subscribe(): Promise<void> {\n // Intentionally empty — see method doc.\n }\n\n // ============================================================================\n // BALANCE UPDATES\n // ============================================================================\n\n #onBalanceUpdated({\n address,\n chain,\n updates,\n }: {\n address: string;\n chain: string;\n updates: BalanceUpdate[];\n }): void {\n try {\n if (!address || !chain || !updates || updates.length === 0) {\n return;\n }\n\n const account = this.#findAccountForAddress(address);\n if (!account) {\n return;\n }\n\n const chainId = chain as ChainId;\n\n const response = processAccountActivityBalanceUpdates(\n updates,\n account.id,\n (assetId) => this.#getAssetType(assetId),\n );\n\n if (!response.assetsBalance) {\n return;\n }\n\n const request: DataRequest = {\n accountsWithSupportedChains: [{ account, supportedChains: [chainId] }],\n chainIds: [chainId],\n dataTypes: ['balance', 'metadata'],\n };\n\n Promise.resolve(this.#onAssetsUpdate(response, request)).catch(\n (error) => {\n log('Failed to report balance update', { error });\n },\n );\n } catch (error) {\n log('Error handling balance update', error);\n }\n }\n\n /**\n * Find the wallet account matching the given activity address. EVM addresses\n * are matched case-insensitively; other namespaces are matched exactly.\n *\n * The candidate set is the accounts of the selected account group, resolved\n * from the wallet at event time (rather than from a stored subscription), so\n * AADS does not need to be re-subscribed whenever the account set changes.\n *\n * @param address - The account address from the activity message.\n * @returns The matching account, or null.\n */\n #findAccountForAddress(address: string): InternalAccount | null {\n const isEvm = address.startsWith('0x');\n\n return (\n this.#getWalletAccounts().find((candidate) =>\n isEvm\n ? candidate.address.toLowerCase() === address.toLowerCase()\n : candidate.address === address,\n ) ?? null\n );\n }\n\n /**\n * Resolve the accounts of the selected account group from the wallet,\n * mirroring `AssetsController.#getSelectedAccounts`.\n *\n * @returns The accounts of the selected account group.\n */\n #getWalletAccounts(): InternalAccount[] {\n const accounts = this.#messenger.call(\n 'AccountTreeController:getAccountsFromSelectedAccountGroup',\n );\n if (accounts.length > 0) {\n return accounts;\n }\n\n const selectedAccount = this.#messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n return selectedAccount ? [selectedAccount] : [];\n }\n\n // ============================================================================\n // STATUS CHANGES\n // ============================================================================\n\n /**\n * Handle a `statusChanged` notification. Chains reported \"up\" are claimed as\n * active (WebSocket provides real-time data); chains reported \"down\" are\n * released so polling data sources take over. The change is applied directly;\n * coalescing and jitter are handled by `AssetsController`.\n *\n * @param options - The status change notification.\n * @param options.chainIds - The CAIP-2 chain IDs whose status changed.\n * @param options.status - Whether the chains are `up` or `down`.\n * @param options.timestamp - Optional timestamp of the status change.\n */\n readonly #onAccountActivityStatusChanged = ({\n chainIds,\n status,\n }: {\n chainIds: string[];\n status: 'up' | 'down';\n timestamp?: number;\n }): void => {\n try {\n // Act on every namespace (eip155, solana, etc.); AssetsController is\n // multichain. Only skip identifiers that are not valid CAIP-2 chain IDs.\n const validChains = chainIds.filter((chainId) => isCaipChainId(chainId));\n\n if (validChains.length === 0) {\n return;\n }\n\n const next = new Set(this.state.activeChains);\n if (status === 'up') {\n for (const chainId of validChains) {\n next.add(chainId);\n }\n } else {\n for (const chainId of validChains) {\n next.delete(chainId);\n }\n }\n\n const previous = [...this.state.activeChains];\n this.updateActiveChains(Array.from(next), (updatedChains) =>\n this.#onActiveChainsUpdated(this.getName(), updatedChains, previous),\n );\n } catch (error) {\n log('Error handling status change', error);\n }\n };\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n destroy(): void {\n try {\n this.#messenger.unsubscribe(\n 'AccountActivityService:balanceUpdated',\n this.#onBalanceUpdatedBound,\n );\n } catch (error) {\n log('Failed to unsubscribe from balanceUpdated', { error });\n }\n\n try {\n this.#messenger.unsubscribe(\n 'AccountActivityService:statusChanged',\n this.#onAccountActivityStatusChanged,\n );\n } catch (error) {\n log('Failed to unsubscribe from statusChanged', { error });\n }\n\n super.destroy();\n }\n}\n\n// ============================================================================\n// FACTORY FUNCTION\n// ============================================================================\n\n/**\n * Creates an AccountActivityDataSource instance.\n *\n * @param options - Configuration options for the data source.\n * @returns A new AccountActivityDataSource instance.\n */\nexport function createAccountActivityDataSource(\n options: AccountActivityDataSourceOptions,\n): AccountActivityDataSource {\n return new AccountActivityDataSource(options);\n}\n"]}
1
+ {"version":3,"file":"AccountActivityDataSource.js","sourceRoot":"","sources":["../../src/data-sources/AccountActivityDataSource.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountActivityServiceBalanceUpdatedEvent,\n AccountActivityServiceStatusChangedEvent,\n BalanceUpdate,\n} from '@metamask/core-backend';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport { isCaipChainId } from '@metamask/utils';\nimport { BigNumber as BigNumberJS } from 'bignumber.js';\n\nimport type { AssetsControllerMessenger } from '../AssetsController.js';\nimport { projectLogger, createModuleLogger } from '../logger.js';\nimport type {\n AssetBalance,\n ChainId,\n Caip19AssetId,\n DataRequest,\n DataResponse,\n} from '../types.js';\nimport { safeNormalizeAssetId } from '../utils/index.js';\nimport { AbstractDataSource } from './AbstractDataSource.js';\nimport type { DataSourceState } from './AbstractDataSource.js';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst CONTROLLER_NAME = 'AccountActivityDataSource';\n\nconst log = createModuleLogger(projectLogger, CONTROLLER_NAME);\n\n// ============================================================================\n// BALANCE UPDATE PROCESSING\n// ============================================================================\n\n/**\n * Convert AccountActivityMessage balance updates into a {@link DataResponse}\n * for AssetsController.\n *\n * @param updates - Balance updates from account-activity websocket payload.\n * @param accountId - Internal account UUID.\n * @returns DataResponse with merge mode when balances are present.\n */\nfunction processAccountActivityBalanceUpdates(\n updates: BalanceUpdate[],\n accountId: string,\n): DataResponse {\n const assetsBalance = Object.create(null) as Record<\n string,\n Record<Caip19AssetId, AssetBalance>\n >;\n assetsBalance[accountId] = Object.create(null) as Record<\n Caip19AssetId,\n AssetBalance\n >;\n\n for (const update of updates) {\n const { asset, postBalance } = update;\n\n if (!asset || !postBalance) {\n continue;\n }\n\n // The websocket sends lower-case ERC-20 addresses, while state and the\n // rest of the pipeline key assets by their checksummed ID. Normalizing\n // here keeps middleware comparisons (detection, custom-asset graduation,\n // occurrence filtering) from treating an existing holding as brand new.\n const assetId = safeNormalizeAssetId(asset.type as Caip19AssetId);\n\n if (asset.decimals === undefined) {\n continue;\n }\n\n const rawBalanceStr = postBalance.amount.startsWith('0x')\n ? BigInt(postBalance.amount).toString()\n : postBalance.amount;\n\n const humanReadableAmount = new BigNumberJS(rawBalanceStr)\n .dividedBy(new BigNumberJS(10).pow(asset.decimals))\n .toFixed();\n\n assetsBalance[accountId][assetId] = {\n amount: humanReadableAmount,\n ...(postBalance.metadata ? { metadata: postBalance.metadata } : {}),\n };\n }\n\n const response: DataResponse = { updateMode: 'merge' };\n if (Object.keys(assetsBalance[accountId]).length > 0) {\n response.assetsBalance = assetsBalance;\n }\n\n return response;\n}\n\n// ============================================================================\n// MESSENGER TYPES\n// ============================================================================\n\n/** Allowed events that AccountActivityDataSource subscribes to. */\nexport type AccountActivityDataSourceAllowedEvents =\n | AccountActivityServiceBalanceUpdatedEvent\n | AccountActivityServiceStatusChangedEvent;\n\n// ============================================================================\n// STATE\n// ============================================================================\n\nexport type AccountActivityDataSourceState = DataSourceState;\n\nconst defaultState: AccountActivityDataSourceState = {\n activeChains: [],\n};\n\n// ============================================================================\n// OPTIONS\n// ============================================================================\n\nexport type AccountActivityDataSourceOptions = {\n /** The AssetsController messenger (shared by all data sources). */\n messenger: AssetsControllerMessenger;\n /** Called when active chains are updated. Pass dataSourceName so the controller knows the source. */\n onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n /**\n * Pushes decoded balance updates to the controller (bound to\n * `AssetsController.handleAssetsUpdate`). AADS is event-driven and never\n * takes part in the controller's subscribe handoff, so it receives this\n * callback directly instead of via a `SubscriptionRequest`.\n */\n onAssetsUpdate: (\n response: DataResponse,\n request?: DataRequest,\n ) => void | Promise<void>;\n state?: Partial<AccountActivityDataSourceState>;\n};\n\n// ============================================================================\n// ACCOUNT ACTIVITY DATA SOURCE\n// ============================================================================\n\n/**\n * Data source that consumes real-time updates from `AccountActivityService`.\n *\n * `AccountActivityService` owns the WebSocket connection and channel\n * subscriptions; this data source is a thin consumer of the two high-level\n * events that it publishes:\n *\n * - `AccountActivityService:balanceUpdated` — post-transaction balances for the\n * subscribed account(s). The address is resolved against the wallet's\n * selected account group, transformed into a {@link DataResponse} (via\n * {@link processAccountActivityBalanceUpdates}), and pushed to the controller\n * through the injected `onAssetsUpdate` callback.\n * - `AccountActivityService:statusChanged` — per-chain \"up\"/\"down\" notifications.\n * A chain reported \"up\" is claimed as an active chain (WebSocket is providing\n * real-time data); a chain reported \"down\" is released so polling data sources\n * can take over. Each change is applied directly via `updateActiveChains`,\n * which notifies the controller through `onActiveChainsUpdated`.\n *\n * This data source does NOT debounce, jitter, or gate chain updates itself.\n * Coalescing (collapsing bursts) and jitter (staggering the WS-subscribe herd\n * across clients) live in `AssetsController`, where the expensive re-subscribe\n * happens and where updates from all data sources converge. `activeChains` are\n * never seeded from the accounts API; they only ever reflect live\n * `statusChanged` events (the service flushes all tracked chains as \"down\" when\n * the WebSocket disconnects, releasing them).\n *\n * It subscribes to these events in its constructor (the same way\n * `TokenBalancesController` does). Unlike the polling data sources it does not\n * take part in the controller's subscribe/unsubscribe handoff: `subscribe` is a\n * no-op, balance updates are routed by resolving the address against the\n * wallet, and updates are pushed through the injected `onAssetsUpdate` callback.\n */\nexport class AccountActivityDataSource extends AbstractDataSource<\n typeof CONTROLLER_NAME,\n AccountActivityDataSourceState\n> {\n readonly #messenger: AssetsControllerMessenger;\n\n readonly #onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n\n readonly #onAssetsUpdate: (\n response: DataResponse,\n request?: DataRequest,\n ) => void | Promise<void>;\n\n readonly #onBalanceUpdatedBound: (event: {\n address: string;\n chain: string;\n updates: BalanceUpdate[];\n }) => void;\n\n constructor(options: AccountActivityDataSourceOptions) {\n super(CONTROLLER_NAME, {\n ...defaultState,\n ...options.state,\n });\n\n this.#messenger = options.messenger;\n this.#onActiveChainsUpdated = options.onActiveChainsUpdated;\n this.#onAssetsUpdate = options.onAssetsUpdate;\n this.#onBalanceUpdatedBound = this.#onBalanceUpdated.bind(this);\n\n this.#subscribeToEvents();\n }\n\n // ============================================================================\n // EVENT SUBSCRIPTIONS\n // ============================================================================\n\n #subscribeToEvents(): void {\n this.#messenger.subscribe(\n 'AccountActivityService:balanceUpdated',\n this.#onBalanceUpdatedBound,\n );\n this.#messenger.subscribe(\n 'AccountActivityService:statusChanged',\n this.#onAccountActivityStatusChanged,\n );\n }\n\n // ============================================================================\n // SUBSCRIBE / UNSUBSCRIBE\n // ============================================================================\n\n /**\n * AADS is event-driven and chain-agnostic: it never participates in the\n * controller's subscribe/unsubscribe handoff. Incoming `balanceUpdated`\n * events are routed by resolving the address against the wallet's accounts\n * (see `#onBalanceUpdated`), and updates are pushed through the injected\n * `#onAssetsUpdate` callback. This override exists only to satisfy the\n * abstract contract and is intentionally a no-op.\n */\n async subscribe(): Promise<void> {\n // Intentionally empty — see method doc.\n }\n\n // ============================================================================\n // BALANCE UPDATES\n // ============================================================================\n\n #onBalanceUpdated({\n address,\n chain,\n updates,\n }: {\n address: string;\n chain: string;\n updates: BalanceUpdate[];\n }): void {\n try {\n if (!address || !chain || !updates || updates.length === 0) {\n return;\n }\n\n const account = this.#findAccountForAddress(address);\n if (!account) {\n return;\n }\n\n const chainId = chain as ChainId;\n\n const response = processAccountActivityBalanceUpdates(\n updates,\n account.id,\n );\n\n if (!response.assetsBalance) {\n return;\n }\n\n const request: DataRequest = {\n accountsWithSupportedChains: [{ account, supportedChains: [chainId] }],\n chainIds: [chainId],\n dataTypes: ['balance', 'metadata', 'price'],\n };\n\n Promise.resolve(this.#onAssetsUpdate(response, request)).catch(\n (error) => {\n log('Failed to report balance update', { error });\n },\n );\n } catch (error) {\n log('Error handling balance update', error);\n }\n }\n\n /**\n * Find the wallet account matching the given activity address. EVM addresses\n * are matched case-insensitively; other namespaces are matched exactly.\n *\n * The candidate set is the accounts of the selected account group, resolved\n * from the wallet at event time (rather than from a stored subscription), so\n * AADS does not need to be re-subscribed whenever the account set changes.\n *\n * @param address - The account address from the activity message.\n * @returns The matching account, or null.\n */\n #findAccountForAddress(address: string): InternalAccount | null {\n const isEvm = address.startsWith('0x');\n\n return (\n this.#getWalletAccounts().find((candidate) =>\n isEvm\n ? candidate.address.toLowerCase() === address.toLowerCase()\n : candidate.address === address,\n ) ?? null\n );\n }\n\n /**\n * Resolve the accounts of the selected account group from the wallet,\n * mirroring `AssetsController.#getSelectedAccounts`.\n *\n * @returns The accounts of the selected account group.\n */\n #getWalletAccounts(): InternalAccount[] {\n const accounts = this.#messenger.call(\n 'AccountTreeController:getAccountsFromSelectedAccountGroup',\n );\n if (accounts.length > 0) {\n return accounts;\n }\n\n const selectedAccount = this.#messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n return selectedAccount ? [selectedAccount] : [];\n }\n\n // ============================================================================\n // STATUS CHANGES\n // ============================================================================\n\n /**\n * Handle a `statusChanged` notification. Chains reported \"up\" are claimed as\n * active (WebSocket provides real-time data); chains reported \"down\" are\n * released so polling data sources take over. The change is applied directly;\n * coalescing and jitter are handled by `AssetsController`.\n *\n * @param options - The status change notification.\n * @param options.chainIds - The CAIP-2 chain IDs whose status changed.\n * @param options.status - Whether the chains are `up` or `down`.\n * @param options.timestamp - Optional timestamp of the status change.\n */\n readonly #onAccountActivityStatusChanged = ({\n chainIds,\n status,\n }: {\n chainIds: string[];\n status: 'up' | 'down';\n timestamp?: number;\n }): void => {\n try {\n // Act on every namespace (eip155, solana, etc.); AssetsController is\n // multichain. Only skip identifiers that are not valid CAIP-2 chain IDs.\n const validChains = chainIds.filter((chainId) => isCaipChainId(chainId));\n\n if (validChains.length === 0) {\n return;\n }\n\n const next = new Set(this.state.activeChains);\n if (status === 'up') {\n for (const chainId of validChains) {\n next.add(chainId);\n }\n } else {\n for (const chainId of validChains) {\n next.delete(chainId);\n }\n }\n\n const previous = [...this.state.activeChains];\n this.updateActiveChains(Array.from(next), (updatedChains) =>\n this.#onActiveChainsUpdated(this.getName(), updatedChains, previous),\n );\n } catch (error) {\n log('Error handling status change', error);\n }\n };\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n destroy(): void {\n try {\n this.#messenger.unsubscribe(\n 'AccountActivityService:balanceUpdated',\n this.#onBalanceUpdatedBound,\n );\n } catch (error) {\n log('Failed to unsubscribe from balanceUpdated', { error });\n }\n\n try {\n this.#messenger.unsubscribe(\n 'AccountActivityService:statusChanged',\n this.#onAccountActivityStatusChanged,\n );\n } catch (error) {\n log('Failed to unsubscribe from statusChanged', { error });\n }\n\n super.destroy();\n }\n}\n\n// ============================================================================\n// FACTORY FUNCTION\n// ============================================================================\n\n/**\n * Creates an AccountActivityDataSource instance.\n *\n * @param options - Configuration options for the data source.\n * @returns A new AccountActivityDataSource instance.\n */\nexport function createAccountActivityDataSource(\n options: AccountActivityDataSourceOptions,\n): AccountActivityDataSource {\n return new AccountActivityDataSource(options);\n}\n"]}
@@ -2,10 +2,11 @@ import type { Caip19AssetId, ChainId, FungibleAssetBalance } from '../types.js';
2
2
  /**
3
3
  * Seed native CAIP-19 asset IDs, keyed by CAIP-2 chain ID.
4
4
  *
5
- * Covers Price API v3/spot-prices EVM natives plus the Solana, Stellar and
6
- * Tron natives this controller ingests. chainid.network only fills extra
7
- * `eip155` gaps, so without the non-EVM rows an account holding nothing on
8
- * those networks gets an empty list instead of SOL/XLM/TRX at 0.
5
+ * Covers Price API v3/spot-prices EVM natives plus the Bitcoin, Solana,
6
+ * Stellar and Tron natives this controller ingests. chainid.network only
7
+ * fills extra `eip155` gaps, so without the non-EVM rows an account holding
8
+ * nothing on those networks gets an empty list instead of BTC/SOL/XLM/TRX
9
+ * at 0.
9
10
  *
10
11
  * Price API v3/spot-prices chains only for EVM — verify support before adding:
11
12
  * https://github.com/consensys-vertical-apps/va-mmcx-price-api/blob/main/src/constants/slip44.ts
@@ -1 +1 @@
1
- {"version":3,"file":"native-assets.d.ts","sourceRoot":"","sources":["../../src/utils/native-assets.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAUhF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,CAsGlE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oCAAoC;aAC/C,qBAAqB,EAAE,GAAG;aAC1B,gBAAgB,EAAE,GAAG;CACb,CAAC;AAIX;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,aAAa,GAC3B,oBAAoB,CActB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,CACrD,OAAO,EACP,aAAa,CACd,CAMA;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CACvD,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,CAC/B,CAmCA"}
1
+ {"version":3,"file":"native-assets.d.ts","sourceRoot":"","sources":["../../src/utils/native-assets.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAUhF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,CAwGlE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oCAAoC;aAC/C,qBAAqB,EAAE,GAAG;aAC1B,gBAAgB,EAAE,GAAG;CACb,CAAC;AAIX;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,aAAa,GAC3B,oBAAoB,CActB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,CACrD,OAAO,EACP,aAAa,CACd,CAMA;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CACvD,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,CAC/B,CAmCA"}
@@ -5,10 +5,11 @@ const CHAINID_NETWORK_URL = 'https://chainid.network/chains.json';
5
5
  /**
6
6
  * Seed native CAIP-19 asset IDs, keyed by CAIP-2 chain ID.
7
7
  *
8
- * Covers Price API v3/spot-prices EVM natives plus the Solana, Stellar and
9
- * Tron natives this controller ingests. chainid.network only fills extra
10
- * `eip155` gaps, so without the non-EVM rows an account holding nothing on
11
- * those networks gets an empty list instead of SOL/XLM/TRX at 0.
8
+ * Covers Price API v3/spot-prices EVM natives plus the Bitcoin, Solana,
9
+ * Stellar and Tron natives this controller ingests. chainid.network only
10
+ * fills extra `eip155` gaps, so without the non-EVM rows an account holding
11
+ * nothing on those networks gets an empty list instead of BTC/SOL/XLM/TRX
12
+ * at 0.
12
13
  *
13
14
  * Price API v3/spot-prices chains only for EVM — verify support before adding:
14
15
  * https://github.com/consensys-vertical-apps/va-mmcx-price-api/blob/main/src/constants/slip44.ts
@@ -91,6 +92,7 @@ export const NATIVE_ASSETS = {
91
92
  'eip155:1313161554': 'eip155:1313161554/slip44:60', // Aurora Mainnet (Ethereum L2 on NEAR) - Native symbol: ETH
92
93
  'eip155:1666600000': 'eip155:1666600000/slip44:1023', // Harmony Mainnet Shard 0 - Native symbol: ONE
93
94
  'eip155:16661': 'eip155:16661/slip44:1111116661', // 0G Chain - Native symbol: 0G
95
+ 'bip122:000000000019d6689c085ae165831e93': 'bip122:000000000019d6689c085ae165831e93/slip44:0', // Bitcoin Mainnet - Native symbol: BTC
94
96
  'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501', // Solana Mainnet - Native symbol: SOL
95
97
  'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z': 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z/slip44:501', // Solana Testnet - Native symbol: SOL
96
98
  'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1/slip44:501', // Solana Devnet - Native symbol: SOL
@@ -1 +1 @@
1
- {"version":3,"file":"native-assets.js","sourceRoot":"","sources":["../../src/utils/native-assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,mBAAmB,GAAG,qCAAqC,CAAC;AAOlE;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,aAAa,GAA6C;IACrE,UAAU,EAAE,oBAAoB,EAAE,wCAAwC;IAC1E,WAAW,EAAE,qBAAqB,EAAE,kCAAkC;IACtE,WAAW,EAAE,sBAAsB,EAAE,sCAAsC;IAC3E,WAAW,EAAE,sBAAsB,EAAE,0CAA0C;IAC/E,WAAW,EAAE,4DAA4D,EAAE,6BAA6B;IACxG,WAAW,EAAE,4DAA4D,EAAE,mCAAmC;IAC9G,WAAW,EAAE,sBAAsB,EAAE,+CAA+C;IACpF,WAAW,EAAE,qBAAqB,EAAE,uCAAuC;IAC3E,WAAW,EAAE,wBAAwB,EAAE,qCAAqC;IAC5E,WAAW,EAAE,sBAAsB,EAAE,kCAAkC;IACvE,YAAY,EAAE,6DAA6D,EAAE,qDAAqD;IAClI,YAAY,EAAE,2BAA2B,EAAE,yCAAyC;IACpF,YAAY,EAAE,6DAA6D,EAAE,qCAAqC;IAClH,YAAY,EAAE,wBAAwB,EAAE,8CAA8C;IACtF,YAAY,EAAE,uBAAuB,EAAE,uCAAuC;IAC9E,YAAY,EAAE,6BAA6B,EAAE,qCAAqC;IAClF,YAAY,EAAE,yBAAyB,EAAE,mCAAmC;IAC5E,YAAY,EAAE,6DAA6D,EAAE,uCAAuC;IACpH,YAAY,EAAE,6DAA6D,EAAE,oCAAoC;IACjH,YAAY,EAAE,wBAAwB,EAAE,oCAAoC;IAC5E,YAAY,EAAE,6DAA6D,EAAE,gCAAgC;IAC7G,YAAY,EAAE,sBAAsB,EAAE,kDAAkD;IACxF,YAAY,EAAE,uBAAuB,EAAE,mCAAmC;IAC1E,YAAY,EAAE,sBAAsB,EAAE,wDAAwD;IAC9F,YAAY,EAAE,uBAAuB,EAAE,8BAA8B;IACrE,YAAY,EAAE,uBAAuB,EAAE,uCAAuC;IAC9E,YAAY,EAAE,uBAAuB,EAAE,iCAAiC;IACxE,YAAY,EAAE,6DAA6D,EAAE,gCAAgC;IAC7G,YAAY,EAAE,wBAAwB,EAAE,iCAAiC;IACzE,aAAa,EAAE,8DAA8D,EAAE,+DAA+D;IAC9I,aAAa,EAAE,uBAAuB,EAAE,6CAA6C;IACrF,aAAa,EAAE,yBAAyB,EAAE,iCAAiC;IAC3E,aAAa,EAAE,yBAAyB,EAAE,kCAAkC;IAC5E,aAAa,EAAE,6BAA6B,EAAE,mCAAmC;IACjF,aAAa,EAAE,6BAA6B,EAAE,yCAAyC;IACvF,aAAa,EAAE,8DAA8D,EAAE,+BAA+B;IAC9G,aAAa,EAAE,8DAA8D,EAAE,qCAAqC;IACpH,aAAa,EAAE,8DAA8D,EAAE,gCAAgC;IAC/G,aAAa,EAAE,uBAAuB,EAAE,kCAAkC;IAC1E,aAAa,EAAE,8DAA8D,EAAE,uCAAuC;IACtH,aAAa,EAAE,8DAA8D,EAAE,8BAA8B;IAC7G,aAAa,EAAE,yBAAyB,EAAE,uCAAuC;IACjF,aAAa,EAAE,yBAAyB,EAAE,4BAA4B;IACtE,aAAa,EAAE,yBAAyB,EAAE,kCAAkC;IAC5E,aAAa,EAAE,uBAAuB,EAAE,4BAA4B;IACpE,aAAa,EAAE,uBAAuB,EAAE,uCAAuC;IAC/E,aAAa,EAAE,8DAA8D,EAAE,sCAAsC;IACrH,cAAc,EAAE,yBAAyB,EAAE,0CAA0C;IACrF,cAAc,EACZ,+DAA+D,EAAE,wCAAwC;IAC3G,cAAc,EACZ,+DAA+D,EAAE,iCAAiC;IACpG,cAAc,EAAE,wBAAwB,EAAE,oCAAoC;IAC9E,cAAc,EAAE,2BAA2B,EAAE,qCAAqC;IAClF,cAAc,EAAE,yBAAyB,EAAE,sCAAsC;IACjF,cAAc,EAAE,wBAAwB,EAAE,2CAA2C;IACrF,cAAc,EACZ,+DAA+D,EAAE,4CAA4C;IAC/G,cAAc,EACZ,+DAA+D,EAAE,4BAA4B;IAC/F,cAAc,EAAE,0BAA0B,EAAE,0CAA0C;IACtF,cAAc,EAAE,wBAAwB,EAAE,mCAAmC;IAC7E,cAAc,EAAE,wBAAwB,EAAE,qCAAqC;IAC/E,cAAc,EACZ,+DAA+D,EAAE,2BAA2B;IAC9F,cAAc,EACZ,+DAA+D,EAAE,kCAAkC;IACrG,cAAc,EACZ,+DAA+D,EAAE,oCAAoC;IACvG,cAAc,EACZ,+DAA+D,EAAE,kCAAkC;IACrG,cAAc,EAAE,wBAAwB,EAAE,qCAAqC;IAC/E,cAAc,EACZ,+DAA+D,EAAE,oCAAoC;IACvG,cAAc,EACZ,+DAA+D,EAAE,+CAA+C;IAClH,cAAc,EACZ,+DAA+D,EAAE,uCAAuC;IAC1G,eAAe,EAAE,yBAAyB,EAAE,qCAAqC;IACjF,eAAe,EAAE,2BAA2B,EAAE,uCAAuC;IACrF,eAAe,EAAE,yBAAyB,EAAE,sCAAsC;IAClF,eAAe,EACb,gEAAgE,EAAE,8BAA8B;IAClG,eAAe,EACb,gEAAgE,EAAE,wCAAwC;IAC5G,gBAAgB,EACd,iEAAiE,EAAE,gCAAgC;IACrG,mBAAmB,EAAE,6BAA6B,EAAE,4DAA4D;IAChH,mBAAmB,EAAE,+BAA+B,EAAE,+CAA+C;IACrG,cAAc,EAAE,gCAAgC,EAAE,+BAA+B;IACjF,yCAAyC,EACvC,oDAAoD,EAAE,sCAAsC;IAC9F,yCAAyC,EACvC,oDAAoD,EAAE,sCAAsC;IAC9F,yCAAyC,EACvC,oDAAoD,EAAE,qCAAqC;IAC7F,gBAAgB,EAAE,2BAA2B,EAAE,sCAAsC;IACrF,iBAAiB,EAAE,4BAA4B,EAAE,uCAAuC;IACxF,gBAAgB,EAAE,2BAA2B,EAAE,oCAAoC;IACnF,iBAAiB,EAAE,4BAA4B,EAAE,iCAAiC;IAClF,iBAAiB,EAAE,4BAA4B,EAAE,mCAAmC;CACrF,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG;IAClD,qBAAqB,EAAE,GAAG;IAC1B,gBAAgB,EAAE,GAAG;CACb,CAAC;AAEX,MAAM,mBAAmB,GAAyB,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAElE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,4BAA4B,CAC1C,aAA4B;IAE5B,IAAI,CAAC;QACH,MAAM,EAAE,KAAK,EAAE,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;QACpD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO;gBACL,MAAM,EAAE,GAAG;gBACX,QAAQ,EAAE,EAAE,GAAG,oCAAoC,EAAE;aACtD,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;IAED,OAAO,EAAE,GAAG,mBAAmB,EAAE,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,6BAA6B;IAI3C,MAAM,eAAe,GAAmC,EAAE,CAAC;IAC3D,KAAK,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QACrE,eAAe,CAAC,OAAkB,CAAC,GAAG,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAG5C,MAAM,eAAe,GAAG,6BAA6B,EAAE,CAAC;IAExD,IAAI,CAAC;QACH,MAAM,MAAM,GACV,MAAM,sBAAsB,CAAC;YAC3B,GAAG,EAAE,mBAAmB;YACxB,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QAEL,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IACE,CAAC,KAAK,CAAC,OAAO;oBACd,CAAC,KAAK,CAAC,MAAM;oBACb,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;oBAChC,KAAK,CAAC,OAAO,GAAG,CAAC;oBACjB,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;oBAC/B,KAAK,CAAC,MAAM,GAAG,CAAC,EAChB,CAAC;oBACD,SAAS;gBACX,CAAC;gBAED,MAAM,WAAW,GAAG,UAAU,KAAK,CAAC,OAAO,EAAa,CAAC;gBACzD,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;oBAClC,eAAe,CAAC,WAAW,CAAC;wBAC1B,UAAU,KAAK,CAAC,OAAO,WAAW,KAAK,CAAC,MAAM,EAAmB,CAAC;gBACtE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC","sourcesContent":["import { fetchWithErrorHandling } from '@metamask/controller-utils';\nimport { parseCaipAssetType } from '@metamask/utils';\n\nimport type { Caip19AssetId, ChainId, FungibleAssetBalance } from '../types.js';\nimport { normalizeAssetId } from './normalizeAssetId.js';\n\nconst CHAINID_NETWORK_URL = 'https://chainid.network/chains.json';\n\ntype ChainIdNetworkEntry = {\n chainId: number;\n slip44?: number;\n};\n\n/**\n * Seed native CAIP-19 asset IDs, keyed by CAIP-2 chain ID.\n *\n * Covers Price API v3/spot-prices EVM natives plus the Solana, Stellar and\n * Tron natives this controller ingests. chainid.network only fills extra\n * `eip155` gaps, so without the non-EVM rows an account holding nothing on\n * those networks gets an empty list instead of SOL/XLM/TRX at 0.\n *\n * Price API v3/spot-prices chains only for EVM — verify support before adding:\n * https://github.com/consensys-vertical-apps/va-mmcx-price-api/blob/main/src/constants/slip44.ts\n * Include chain name + native symbol. Keep sorted by chain ID.\n */\nexport const NATIVE_ASSETS: Readonly<Record<ChainId, Caip19AssetId>> = {\n 'eip155:1': 'eip155:1/slip44:60', // Ethereum Mainnet - Native symbol: ETH\n 'eip155:10': 'eip155:10/slip44:60', // OP Mainnet - Native symbol: ETH\n 'eip155:25': 'eip155:25/slip44:394', // Cronos Mainnet - Native symbol: CRO\n 'eip155:30': 'eip155:30/slip44:137', // Rootstock Mainnet - Native symbol: RBTC\n 'eip155:42': 'eip155:42/erc20:0x0000000000000000000000000000000000000000', // Lukso - native symbol: LYX\n 'eip155:50': 'eip155:50/erc20:0x0000000000000000000000000000000000000000', // xdc-network - native symbol: XDC\n 'eip155:56': 'eip155:56/slip44:714', // BNB Smart Chain Mainnet - Native symbol: BNB\n 'eip155:57': 'eip155:57/slip44:57', // Syscoin Mainnet - Native symbol: SYS\n 'eip155:82': 'eip155:82/slip44:18000', // Meter Mainnet - Native symbol: MTR\n 'eip155:88': 'eip155:88/slip44:889', // TomoChain - Native symbol: TOMO\n 'eip155:100': 'eip155:100/erc20:0x0000000000000000000000000000000000000000', // Gnosis (formerly xDAI Chain) - Native symbol: xDAI\n 'eip155:106': 'eip155:106/slip44:5655640', // Velas EVM Mainnet - Native symbol: VLX\n 'eip155:122': 'eip155:122/erc20:0x0000000000000000000000000000000000000000', // Fuse Mainnet - Native symbol: FUSE\n 'eip155:128': 'eip155:128/slip44:1010', // Huobi ECO Chain Mainnet - Native symbol: HT\n 'eip155:137': 'eip155:137/slip44:966', // Polygon Mainnet - Native symbol: POL\n 'eip155:143': 'eip155:143/slip44:268435779', // Monad Mainnet - Native symbol: MON\n 'eip155:146': 'eip155:146/slip44:10007', // Sonic Mainnet - Native symbol: S\n 'eip155:196': 'eip155:196/erc20:0x0000000000000000000000000000000000000000', // X Layer Mainnet - Native symbol: OKB\n 'eip155:232': 'eip155:232/erc20:0x0000000000000000000000000000000000000000', // Lens Mainnet - Native symbol: GHO\n 'eip155:250': 'eip155:250/slip44:1007', // Fantom Opera - Native symbol: FTM\n 'eip155:252': 'eip155:252/erc20:0x0000000000000000000000000000000000000000', // Fraxtal - native symbol: FRAX\n 'eip155:288': 'eip155:288/slip44:60', // Boba Network (Ethereum L2) - Native symbol: ETH\n 'eip155:321': 'eip155:321/slip44:641', // KCC Mainnet - Native symbol: KCS\n 'eip155:324': 'eip155:324/slip44:60', // zkSync Era Mainnet (Ethereum L2) - Native symbol: ETH\n 'eip155:336': 'eip155:336/slip44:809', // Shiden - Native symbol: SDN\n 'eip155:361': 'eip155:361/slip44:589', // Theta Mainnet - Native symbol: TFUEL\n 'eip155:747': 'eip155:747/slip44:539', // Flow evm - Native symbol: Flow\n 'eip155:988': 'eip155:988/erc20:0x0000000000000000000000000000000000000000', // Stable - Native symbol: USDT0\n 'eip155:999': 'eip155:999/slip44:2457', // HyperEVM - Native symbol: HYPE\n 'eip155:1088': 'eip155:1088/erc20:0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000', // Metis Andromeda Mainnet (Ethereum L2) - Native symbol: METIS\n 'eip155:1101': 'eip155:1101/slip44:60', // Polygon zkEVM mainnet - Native symbol: ETH\n 'eip155:1284': 'eip155:1284/slip44:1284', // Moonbeam - Native symbol: GLMR\n 'eip155:1285': 'eip155:1285/slip44:1285', // Moonriver - Native symbol: MOVR\n 'eip155:1329': 'eip155:1329/slip44:19000118', // Sei Mainnet - Native symbol: SEI\n 'eip155:1776': 'eip155:1776/slip44:22000119', // Injective Mainnet - Native symbol: INJ\n 'eip155:1868': 'eip155:1868/erc20:0x0000000000000000000000000000000000000000', // Soneium - Native symbol: ETH\n 'eip155:2525': 'eip155:2525/erc20:0x0000000000000000000000000000000000000000', // inEVM Mainnet - Native symbol: INV\n 'eip155:2741': 'eip155:2741/erc20:0x0000000000000000000000000000000000000000', // Abstract - Native symbol: ETH\n 'eip155:4217': 'eip155:4217/slip44:60', // Tempo Mainnet - No native asset\n 'eip155:4326': 'eip155:4326/erc20:0x0000000000000000000000000000000000000000', // MegaETH Mainnet - Native symbol: ETH\n 'eip155:5000': 'eip155:5000/erc20:0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000', // Mantle - Native symbol: MNT\n 'eip155:5031': 'eip155:5031/slip44:5031', // Somnia Mainnet - Native symbol: SOMI\n 'eip155:5042': 'eip155:5042/slip44:5042', // Arc - Native symbol: USDC\n 'eip155:7000': 'eip155:7000/slip44:7000', // ZetaChain - Native symbol: ZETA\n 'eip155:8453': 'eip155:8453/slip44:60', // Base - Native symbol: ETH\n 'eip155:4663': 'eip155:4663/slip44:60', // Robinhood Chain - Native symbol: ETH\n 'eip155:9745': 'eip155:9745/erc20:0x0000000000000000000000000000000000000000', // Plasma mainnet - native symbol: XPL\n 'eip155:10000': 'eip155:10000/slip44:145', // Smart Bitcoin Cash - Native symbol: BCH\n 'eip155:33139':\n 'eip155:33139/erc20:0x0000000000000000000000000000000000000000', // Apechain Mainnet - Native symbol: APE\n 'eip155:41923':\n 'eip155:41923/erc20:0x0000000000000000000000000000000000000000', // EDU Chain - Native symbol: EDU\n 'eip155:42161': 'eip155:42161/slip44:60', // Arbitrum One - Native symbol: ETH\n 'eip155:42220': 'eip155:42220/slip44:52752', // Celo Mainnet - Native symbol: CELO\n 'eip155:42262': 'eip155:42262/slip44:474', // Oasis Emerald - Native symbol: ROSE\n 'eip155:42431': 'eip155:42431/slip44:60', // Tempo Testnet Moderato - No native asset\n 'eip155:42793':\n 'eip155:42793/erc20:0x0000000000000000000000000000000000000000', // Etherlink - Native symbol: XTZ (Tezos L2)\n 'eip155:43111':\n 'eip155:43111/erc20:0x0000000000000000000000000000000000000000', // Hemi - Native symbol: ETH\n 'eip155:43114': 'eip155:43114/slip44:9005', // Avalanche C-Chain - Native symbol: AVAX\n 'eip155:57073': 'eip155:57073/slip44:60', // Ink Mainnet - Native symbol: ETH\n 'eip155:59144': 'eip155:59144/slip44:60', // Linea Mainnet - Native symbol: ETH\n 'eip155:60808':\n 'eip155:60808/erc20:0x0000000000000000000000000000000000000000', // BOB - Native symbol: ETH\n 'eip155:68414':\n 'eip155:68414/erc20:0x0000000000000000000000000000000000000000', // MapleStory Universe - no slip44\n 'eip155:73115':\n 'eip155:73115/erc20:0x0000000000000000000000000000000000000000', // ICB Network - Native symbol: ICBX\n 'eip155:80094':\n 'eip155:80094/erc20:0x0000000000000000000000000000000000000000', // Berachain - Native symbol: Bera\n 'eip155:81457': 'eip155:81457/slip44:60', // Blast Mainnet - Native symbol: ETH\n 'eip155:88888':\n 'eip155:88888/erc20:0x0000000000000000000000000000000000000000', // Chiliz Chain - Native symbol: CHZ\n 'eip155:97741':\n 'eip155:97741/erc20:0x0000000000000000000000000000000000000000', // Pepe Unchained Mainnet - Native symbol: PEPU\n 'eip155:98866':\n 'eip155:98866/erc20:0x0000000000000000000000000000000000000000', // Plume Mainnet - Native symbol: Plume\n 'eip155:167000': 'eip155:167000/slip44:60', // Taiko Mainnet - Native symbol: ETH\n 'eip155:333999': 'eip155:333999/slip44:1997', // Polis Mainnet - Native symbol: POLIS\n 'eip155:534352': 'eip155:534352/slip44:60', // Scroll Mainnet - Native symbol: ETH\n 'eip155:747474':\n 'eip155:747474/erc20:0x0000000000000000000000000000000000000000', // katana - Native symbol: ETH\n 'eip155:984122':\n 'eip155:984122/erc20:0x0000000000000000000000000000000000000000', // Forma - Native symbol: TIA (Celestia)\n 'eip155:1440000':\n 'eip155:1440000/erc20:0x0000000000000000000000000000000000000000', // xrpl-evm - native symbol: XRP\n 'eip155:1313161554': 'eip155:1313161554/slip44:60', // Aurora Mainnet (Ethereum L2 on NEAR) - Native symbol: ETH\n 'eip155:1666600000': 'eip155:1666600000/slip44:1023', // Harmony Mainnet Shard 0 - Native symbol: ONE\n 'eip155:16661': 'eip155:16661/slip44:1111116661', // 0G Chain - Native symbol: 0G\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp':\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501', // Solana Mainnet - Native symbol: SOL\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z':\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z/slip44:501', // Solana Testnet - Native symbol: SOL\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1':\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1/slip44:501', // Solana Devnet - Native symbol: SOL\n 'stellar:pubnet': 'stellar:pubnet/slip44:148', // Stellar Pubnet - Native symbol: XLM\n 'stellar:testnet': 'stellar:testnet/slip44:148', // Stellar Testnet - Native symbol: XLM\n 'tron:728126428': 'tron:728126428/slip44:195', // Tron Mainnet - Native symbol: TRX\n 'tron:3448148188': 'tron:3448148188/slip44:195', // Tron Nile - Native symbol: TRX\n 'tron:2494104990': 'tron:2494104990/slip44:195', // Tron Shasta - Native symbol: TRX\n};\n\n/**\n * Balance-row metadata the Accounts API attaches to Stellar native XLM.\n * Seeded at zero so an unfunded account still has a well-formed native row\n * instead of a bare `{ amount: '0' }`.\n */\nexport const STELLAR_NATIVE_ZERO_BALANCE_METADATA = {\n minimumReserveBalance: '0',\n spendableBalance: '0',\n} as const;\n\nconst ZERO_NATIVE_BALANCE: FungibleAssetBalance = { amount: '0' };\n\n/**\n * Default native balance to insert when a data source (typically Accounts API)\n * returns no row for the chain's native asset.\n *\n * Stellar natives include `spendableBalance` / `minimumReserveBalance` at 0 so\n * consumers that read those fields on XLM do not have to special-case a missing\n * metadata object. Other natives are a plain zero amount.\n *\n * @param nativeAssetId - The CAIP-19 native asset ID being seeded.\n * @returns A zero-balance entry for that native.\n */\nexport function getDefaultNativeAssetBalance(\n nativeAssetId: Caip19AssetId,\n): FungibleAssetBalance {\n try {\n const { chain } = parseCaipAssetType(nativeAssetId);\n if (chain.namespace === 'stellar') {\n return {\n amount: '0',\n metadata: { ...STELLAR_NATIVE_ZERO_BALANCE_METADATA },\n };\n }\n } catch {\n // Malformed IDs fall through to a plain zero amount.\n }\n\n return { ...ZERO_NATIVE_BALANCE };\n}\n\n/**\n * Builds a native asset map from {@link NATIVE_ASSETS}, normalizing each\n * CAIP-19 ID (ERC-20 addresses become EIP-55 checksummed).\n *\n * @returns A record mapping CAIP-2 chain IDs to their CAIP-19 native asset IDs.\n */\nexport function buildNativeAssetsFromConstant(): Record<\n ChainId,\n Caip19AssetId\n> {\n const nativeAssetsMap: Record<ChainId, Caip19AssetId> = {};\n for (const [chainId, nativeAssetId] of Object.entries(NATIVE_ASSETS)) {\n nativeAssetsMap[chainId as ChainId] = normalizeAssetId(nativeAssetId);\n }\n return nativeAssetsMap;\n}\n\n/**\n * Fetches chain data from chainid.network and merges it with the seed\n * native asset map built from {@link buildNativeAssetsFromConstant}.\n *\n * Remote entries only fill gaps — chains already present in the seed map\n * are never overwritten. Invalid entries (missing/negative chainId or slip44)\n * are silently skipped.\n *\n * @returns The merged native asset map.\n */\nexport async function buildNativeAssetsFromApi(): Promise<\n Record<ChainId, Caip19AssetId>\n> {\n const nativeAssetsMap = buildNativeAssetsFromConstant();\n\n try {\n const chains: ChainIdNetworkEntry[] | undefined =\n await fetchWithErrorHandling({\n url: CHAINID_NETWORK_URL,\n timeout: 10_000,\n });\n\n if (chains && Array.isArray(chains)) {\n for (const chain of chains) {\n if (\n !chain.chainId ||\n !chain.slip44 ||\n !Number.isInteger(chain.chainId) ||\n chain.chainId < 1 ||\n !Number.isInteger(chain.slip44) ||\n chain.slip44 < 1\n ) {\n continue;\n }\n\n const caipChainId = `eip155:${chain.chainId}` as ChainId;\n if (!nativeAssetsMap[caipChainId]) {\n nativeAssetsMap[caipChainId] =\n `eip155:${chain.chainId}/slip44:${chain.slip44}` as Caip19AssetId;\n }\n }\n }\n } catch {\n // Non-fatal: caller should fall back to the seed map.\n }\n\n return nativeAssetsMap;\n}\n"]}
1
+ {"version":3,"file":"native-assets.js","sourceRoot":"","sources":["../../src/utils/native-assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,mBAAmB,GAAG,qCAAqC,CAAC;AAOlE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,aAAa,GAA6C;IACrE,UAAU,EAAE,oBAAoB,EAAE,wCAAwC;IAC1E,WAAW,EAAE,qBAAqB,EAAE,kCAAkC;IACtE,WAAW,EAAE,sBAAsB,EAAE,sCAAsC;IAC3E,WAAW,EAAE,sBAAsB,EAAE,0CAA0C;IAC/E,WAAW,EAAE,4DAA4D,EAAE,6BAA6B;IACxG,WAAW,EAAE,4DAA4D,EAAE,mCAAmC;IAC9G,WAAW,EAAE,sBAAsB,EAAE,+CAA+C;IACpF,WAAW,EAAE,qBAAqB,EAAE,uCAAuC;IAC3E,WAAW,EAAE,wBAAwB,EAAE,qCAAqC;IAC5E,WAAW,EAAE,sBAAsB,EAAE,kCAAkC;IACvE,YAAY,EAAE,6DAA6D,EAAE,qDAAqD;IAClI,YAAY,EAAE,2BAA2B,EAAE,yCAAyC;IACpF,YAAY,EAAE,6DAA6D,EAAE,qCAAqC;IAClH,YAAY,EAAE,wBAAwB,EAAE,8CAA8C;IACtF,YAAY,EAAE,uBAAuB,EAAE,uCAAuC;IAC9E,YAAY,EAAE,6BAA6B,EAAE,qCAAqC;IAClF,YAAY,EAAE,yBAAyB,EAAE,mCAAmC;IAC5E,YAAY,EAAE,6DAA6D,EAAE,uCAAuC;IACpH,YAAY,EAAE,6DAA6D,EAAE,oCAAoC;IACjH,YAAY,EAAE,wBAAwB,EAAE,oCAAoC;IAC5E,YAAY,EAAE,6DAA6D,EAAE,gCAAgC;IAC7G,YAAY,EAAE,sBAAsB,EAAE,kDAAkD;IACxF,YAAY,EAAE,uBAAuB,EAAE,mCAAmC;IAC1E,YAAY,EAAE,sBAAsB,EAAE,wDAAwD;IAC9F,YAAY,EAAE,uBAAuB,EAAE,8BAA8B;IACrE,YAAY,EAAE,uBAAuB,EAAE,uCAAuC;IAC9E,YAAY,EAAE,uBAAuB,EAAE,iCAAiC;IACxE,YAAY,EAAE,6DAA6D,EAAE,gCAAgC;IAC7G,YAAY,EAAE,wBAAwB,EAAE,iCAAiC;IACzE,aAAa,EAAE,8DAA8D,EAAE,+DAA+D;IAC9I,aAAa,EAAE,uBAAuB,EAAE,6CAA6C;IACrF,aAAa,EAAE,yBAAyB,EAAE,iCAAiC;IAC3E,aAAa,EAAE,yBAAyB,EAAE,kCAAkC;IAC5E,aAAa,EAAE,6BAA6B,EAAE,mCAAmC;IACjF,aAAa,EAAE,6BAA6B,EAAE,yCAAyC;IACvF,aAAa,EAAE,8DAA8D,EAAE,+BAA+B;IAC9G,aAAa,EAAE,8DAA8D,EAAE,qCAAqC;IACpH,aAAa,EAAE,8DAA8D,EAAE,gCAAgC;IAC/G,aAAa,EAAE,uBAAuB,EAAE,kCAAkC;IAC1E,aAAa,EAAE,8DAA8D,EAAE,uCAAuC;IACtH,aAAa,EAAE,8DAA8D,EAAE,8BAA8B;IAC7G,aAAa,EAAE,yBAAyB,EAAE,uCAAuC;IACjF,aAAa,EAAE,yBAAyB,EAAE,4BAA4B;IACtE,aAAa,EAAE,yBAAyB,EAAE,kCAAkC;IAC5E,aAAa,EAAE,uBAAuB,EAAE,4BAA4B;IACpE,aAAa,EAAE,uBAAuB,EAAE,uCAAuC;IAC/E,aAAa,EAAE,8DAA8D,EAAE,sCAAsC;IACrH,cAAc,EAAE,yBAAyB,EAAE,0CAA0C;IACrF,cAAc,EACZ,+DAA+D,EAAE,wCAAwC;IAC3G,cAAc,EACZ,+DAA+D,EAAE,iCAAiC;IACpG,cAAc,EAAE,wBAAwB,EAAE,oCAAoC;IAC9E,cAAc,EAAE,2BAA2B,EAAE,qCAAqC;IAClF,cAAc,EAAE,yBAAyB,EAAE,sCAAsC;IACjF,cAAc,EAAE,wBAAwB,EAAE,2CAA2C;IACrF,cAAc,EACZ,+DAA+D,EAAE,4CAA4C;IAC/G,cAAc,EACZ,+DAA+D,EAAE,4BAA4B;IAC/F,cAAc,EAAE,0BAA0B,EAAE,0CAA0C;IACtF,cAAc,EAAE,wBAAwB,EAAE,mCAAmC;IAC7E,cAAc,EAAE,wBAAwB,EAAE,qCAAqC;IAC/E,cAAc,EACZ,+DAA+D,EAAE,2BAA2B;IAC9F,cAAc,EACZ,+DAA+D,EAAE,kCAAkC;IACrG,cAAc,EACZ,+DAA+D,EAAE,oCAAoC;IACvG,cAAc,EACZ,+DAA+D,EAAE,kCAAkC;IACrG,cAAc,EAAE,wBAAwB,EAAE,qCAAqC;IAC/E,cAAc,EACZ,+DAA+D,EAAE,oCAAoC;IACvG,cAAc,EACZ,+DAA+D,EAAE,+CAA+C;IAClH,cAAc,EACZ,+DAA+D,EAAE,uCAAuC;IAC1G,eAAe,EAAE,yBAAyB,EAAE,qCAAqC;IACjF,eAAe,EAAE,2BAA2B,EAAE,uCAAuC;IACrF,eAAe,EAAE,yBAAyB,EAAE,sCAAsC;IAClF,eAAe,EACb,gEAAgE,EAAE,8BAA8B;IAClG,eAAe,EACb,gEAAgE,EAAE,wCAAwC;IAC5G,gBAAgB,EACd,iEAAiE,EAAE,gCAAgC;IACrG,mBAAmB,EAAE,6BAA6B,EAAE,4DAA4D;IAChH,mBAAmB,EAAE,+BAA+B,EAAE,+CAA+C;IACrG,cAAc,EAAE,gCAAgC,EAAE,+BAA+B;IACjF,yCAAyC,EACvC,kDAAkD,EAAE,uCAAuC;IAC7F,yCAAyC,EACvC,oDAAoD,EAAE,sCAAsC;IAC9F,yCAAyC,EACvC,oDAAoD,EAAE,sCAAsC;IAC9F,yCAAyC,EACvC,oDAAoD,EAAE,qCAAqC;IAC7F,gBAAgB,EAAE,2BAA2B,EAAE,sCAAsC;IACrF,iBAAiB,EAAE,4BAA4B,EAAE,uCAAuC;IACxF,gBAAgB,EAAE,2BAA2B,EAAE,oCAAoC;IACnF,iBAAiB,EAAE,4BAA4B,EAAE,iCAAiC;IAClF,iBAAiB,EAAE,4BAA4B,EAAE,mCAAmC;CACrF,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG;IAClD,qBAAqB,EAAE,GAAG;IAC1B,gBAAgB,EAAE,GAAG;CACb,CAAC;AAEX,MAAM,mBAAmB,GAAyB,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAElE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,4BAA4B,CAC1C,aAA4B;IAE5B,IAAI,CAAC;QACH,MAAM,EAAE,KAAK,EAAE,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;QACpD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO;gBACL,MAAM,EAAE,GAAG;gBACX,QAAQ,EAAE,EAAE,GAAG,oCAAoC,EAAE;aACtD,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;IAED,OAAO,EAAE,GAAG,mBAAmB,EAAE,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,6BAA6B;IAI3C,MAAM,eAAe,GAAmC,EAAE,CAAC;IAC3D,KAAK,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QACrE,eAAe,CAAC,OAAkB,CAAC,GAAG,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAG5C,MAAM,eAAe,GAAG,6BAA6B,EAAE,CAAC;IAExD,IAAI,CAAC;QACH,MAAM,MAAM,GACV,MAAM,sBAAsB,CAAC;YAC3B,GAAG,EAAE,mBAAmB;YACxB,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QAEL,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IACE,CAAC,KAAK,CAAC,OAAO;oBACd,CAAC,KAAK,CAAC,MAAM;oBACb,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;oBAChC,KAAK,CAAC,OAAO,GAAG,CAAC;oBACjB,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;oBAC/B,KAAK,CAAC,MAAM,GAAG,CAAC,EAChB,CAAC;oBACD,SAAS;gBACX,CAAC;gBAED,MAAM,WAAW,GAAG,UAAU,KAAK,CAAC,OAAO,EAAa,CAAC;gBACzD,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;oBAClC,eAAe,CAAC,WAAW,CAAC;wBAC1B,UAAU,KAAK,CAAC,OAAO,WAAW,KAAK,CAAC,MAAM,EAAmB,CAAC;gBACtE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC","sourcesContent":["import { fetchWithErrorHandling } from '@metamask/controller-utils';\nimport { parseCaipAssetType } from '@metamask/utils';\n\nimport type { Caip19AssetId, ChainId, FungibleAssetBalance } from '../types.js';\nimport { normalizeAssetId } from './normalizeAssetId.js';\n\nconst CHAINID_NETWORK_URL = 'https://chainid.network/chains.json';\n\ntype ChainIdNetworkEntry = {\n chainId: number;\n slip44?: number;\n};\n\n/**\n * Seed native CAIP-19 asset IDs, keyed by CAIP-2 chain ID.\n *\n * Covers Price API v3/spot-prices EVM natives plus the Bitcoin, Solana,\n * Stellar and Tron natives this controller ingests. chainid.network only\n * fills extra `eip155` gaps, so without the non-EVM rows an account holding\n * nothing on those networks gets an empty list instead of BTC/SOL/XLM/TRX\n * at 0.\n *\n * Price API v3/spot-prices chains only for EVM — verify support before adding:\n * https://github.com/consensys-vertical-apps/va-mmcx-price-api/blob/main/src/constants/slip44.ts\n * Include chain name + native symbol. Keep sorted by chain ID.\n */\nexport const NATIVE_ASSETS: Readonly<Record<ChainId, Caip19AssetId>> = {\n 'eip155:1': 'eip155:1/slip44:60', // Ethereum Mainnet - Native symbol: ETH\n 'eip155:10': 'eip155:10/slip44:60', // OP Mainnet - Native symbol: ETH\n 'eip155:25': 'eip155:25/slip44:394', // Cronos Mainnet - Native symbol: CRO\n 'eip155:30': 'eip155:30/slip44:137', // Rootstock Mainnet - Native symbol: RBTC\n 'eip155:42': 'eip155:42/erc20:0x0000000000000000000000000000000000000000', // Lukso - native symbol: LYX\n 'eip155:50': 'eip155:50/erc20:0x0000000000000000000000000000000000000000', // xdc-network - native symbol: XDC\n 'eip155:56': 'eip155:56/slip44:714', // BNB Smart Chain Mainnet - Native symbol: BNB\n 'eip155:57': 'eip155:57/slip44:57', // Syscoin Mainnet - Native symbol: SYS\n 'eip155:82': 'eip155:82/slip44:18000', // Meter Mainnet - Native symbol: MTR\n 'eip155:88': 'eip155:88/slip44:889', // TomoChain - Native symbol: TOMO\n 'eip155:100': 'eip155:100/erc20:0x0000000000000000000000000000000000000000', // Gnosis (formerly xDAI Chain) - Native symbol: xDAI\n 'eip155:106': 'eip155:106/slip44:5655640', // Velas EVM Mainnet - Native symbol: VLX\n 'eip155:122': 'eip155:122/erc20:0x0000000000000000000000000000000000000000', // Fuse Mainnet - Native symbol: FUSE\n 'eip155:128': 'eip155:128/slip44:1010', // Huobi ECO Chain Mainnet - Native symbol: HT\n 'eip155:137': 'eip155:137/slip44:966', // Polygon Mainnet - Native symbol: POL\n 'eip155:143': 'eip155:143/slip44:268435779', // Monad Mainnet - Native symbol: MON\n 'eip155:146': 'eip155:146/slip44:10007', // Sonic Mainnet - Native symbol: S\n 'eip155:196': 'eip155:196/erc20:0x0000000000000000000000000000000000000000', // X Layer Mainnet - Native symbol: OKB\n 'eip155:232': 'eip155:232/erc20:0x0000000000000000000000000000000000000000', // Lens Mainnet - Native symbol: GHO\n 'eip155:250': 'eip155:250/slip44:1007', // Fantom Opera - Native symbol: FTM\n 'eip155:252': 'eip155:252/erc20:0x0000000000000000000000000000000000000000', // Fraxtal - native symbol: FRAX\n 'eip155:288': 'eip155:288/slip44:60', // Boba Network (Ethereum L2) - Native symbol: ETH\n 'eip155:321': 'eip155:321/slip44:641', // KCC Mainnet - Native symbol: KCS\n 'eip155:324': 'eip155:324/slip44:60', // zkSync Era Mainnet (Ethereum L2) - Native symbol: ETH\n 'eip155:336': 'eip155:336/slip44:809', // Shiden - Native symbol: SDN\n 'eip155:361': 'eip155:361/slip44:589', // Theta Mainnet - Native symbol: TFUEL\n 'eip155:747': 'eip155:747/slip44:539', // Flow evm - Native symbol: Flow\n 'eip155:988': 'eip155:988/erc20:0x0000000000000000000000000000000000000000', // Stable - Native symbol: USDT0\n 'eip155:999': 'eip155:999/slip44:2457', // HyperEVM - Native symbol: HYPE\n 'eip155:1088': 'eip155:1088/erc20:0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000', // Metis Andromeda Mainnet (Ethereum L2) - Native symbol: METIS\n 'eip155:1101': 'eip155:1101/slip44:60', // Polygon zkEVM mainnet - Native symbol: ETH\n 'eip155:1284': 'eip155:1284/slip44:1284', // Moonbeam - Native symbol: GLMR\n 'eip155:1285': 'eip155:1285/slip44:1285', // Moonriver - Native symbol: MOVR\n 'eip155:1329': 'eip155:1329/slip44:19000118', // Sei Mainnet - Native symbol: SEI\n 'eip155:1776': 'eip155:1776/slip44:22000119', // Injective Mainnet - Native symbol: INJ\n 'eip155:1868': 'eip155:1868/erc20:0x0000000000000000000000000000000000000000', // Soneium - Native symbol: ETH\n 'eip155:2525': 'eip155:2525/erc20:0x0000000000000000000000000000000000000000', // inEVM Mainnet - Native symbol: INV\n 'eip155:2741': 'eip155:2741/erc20:0x0000000000000000000000000000000000000000', // Abstract - Native symbol: ETH\n 'eip155:4217': 'eip155:4217/slip44:60', // Tempo Mainnet - No native asset\n 'eip155:4326': 'eip155:4326/erc20:0x0000000000000000000000000000000000000000', // MegaETH Mainnet - Native symbol: ETH\n 'eip155:5000': 'eip155:5000/erc20:0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000', // Mantle - Native symbol: MNT\n 'eip155:5031': 'eip155:5031/slip44:5031', // Somnia Mainnet - Native symbol: SOMI\n 'eip155:5042': 'eip155:5042/slip44:5042', // Arc - Native symbol: USDC\n 'eip155:7000': 'eip155:7000/slip44:7000', // ZetaChain - Native symbol: ZETA\n 'eip155:8453': 'eip155:8453/slip44:60', // Base - Native symbol: ETH\n 'eip155:4663': 'eip155:4663/slip44:60', // Robinhood Chain - Native symbol: ETH\n 'eip155:9745': 'eip155:9745/erc20:0x0000000000000000000000000000000000000000', // Plasma mainnet - native symbol: XPL\n 'eip155:10000': 'eip155:10000/slip44:145', // Smart Bitcoin Cash - Native symbol: BCH\n 'eip155:33139':\n 'eip155:33139/erc20:0x0000000000000000000000000000000000000000', // Apechain Mainnet - Native symbol: APE\n 'eip155:41923':\n 'eip155:41923/erc20:0x0000000000000000000000000000000000000000', // EDU Chain - Native symbol: EDU\n 'eip155:42161': 'eip155:42161/slip44:60', // Arbitrum One - Native symbol: ETH\n 'eip155:42220': 'eip155:42220/slip44:52752', // Celo Mainnet - Native symbol: CELO\n 'eip155:42262': 'eip155:42262/slip44:474', // Oasis Emerald - Native symbol: ROSE\n 'eip155:42431': 'eip155:42431/slip44:60', // Tempo Testnet Moderato - No native asset\n 'eip155:42793':\n 'eip155:42793/erc20:0x0000000000000000000000000000000000000000', // Etherlink - Native symbol: XTZ (Tezos L2)\n 'eip155:43111':\n 'eip155:43111/erc20:0x0000000000000000000000000000000000000000', // Hemi - Native symbol: ETH\n 'eip155:43114': 'eip155:43114/slip44:9005', // Avalanche C-Chain - Native symbol: AVAX\n 'eip155:57073': 'eip155:57073/slip44:60', // Ink Mainnet - Native symbol: ETH\n 'eip155:59144': 'eip155:59144/slip44:60', // Linea Mainnet - Native symbol: ETH\n 'eip155:60808':\n 'eip155:60808/erc20:0x0000000000000000000000000000000000000000', // BOB - Native symbol: ETH\n 'eip155:68414':\n 'eip155:68414/erc20:0x0000000000000000000000000000000000000000', // MapleStory Universe - no slip44\n 'eip155:73115':\n 'eip155:73115/erc20:0x0000000000000000000000000000000000000000', // ICB Network - Native symbol: ICBX\n 'eip155:80094':\n 'eip155:80094/erc20:0x0000000000000000000000000000000000000000', // Berachain - Native symbol: Bera\n 'eip155:81457': 'eip155:81457/slip44:60', // Blast Mainnet - Native symbol: ETH\n 'eip155:88888':\n 'eip155:88888/erc20:0x0000000000000000000000000000000000000000', // Chiliz Chain - Native symbol: CHZ\n 'eip155:97741':\n 'eip155:97741/erc20:0x0000000000000000000000000000000000000000', // Pepe Unchained Mainnet - Native symbol: PEPU\n 'eip155:98866':\n 'eip155:98866/erc20:0x0000000000000000000000000000000000000000', // Plume Mainnet - Native symbol: Plume\n 'eip155:167000': 'eip155:167000/slip44:60', // Taiko Mainnet - Native symbol: ETH\n 'eip155:333999': 'eip155:333999/slip44:1997', // Polis Mainnet - Native symbol: POLIS\n 'eip155:534352': 'eip155:534352/slip44:60', // Scroll Mainnet - Native symbol: ETH\n 'eip155:747474':\n 'eip155:747474/erc20:0x0000000000000000000000000000000000000000', // katana - Native symbol: ETH\n 'eip155:984122':\n 'eip155:984122/erc20:0x0000000000000000000000000000000000000000', // Forma - Native symbol: TIA (Celestia)\n 'eip155:1440000':\n 'eip155:1440000/erc20:0x0000000000000000000000000000000000000000', // xrpl-evm - native symbol: XRP\n 'eip155:1313161554': 'eip155:1313161554/slip44:60', // Aurora Mainnet (Ethereum L2 on NEAR) - Native symbol: ETH\n 'eip155:1666600000': 'eip155:1666600000/slip44:1023', // Harmony Mainnet Shard 0 - Native symbol: ONE\n 'eip155:16661': 'eip155:16661/slip44:1111116661', // 0G Chain - Native symbol: 0G\n 'bip122:000000000019d6689c085ae165831e93':\n 'bip122:000000000019d6689c085ae165831e93/slip44:0', // Bitcoin Mainnet - Native symbol: BTC\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp':\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501', // Solana Mainnet - Native symbol: SOL\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z':\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z/slip44:501', // Solana Testnet - Native symbol: SOL\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1':\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1/slip44:501', // Solana Devnet - Native symbol: SOL\n 'stellar:pubnet': 'stellar:pubnet/slip44:148', // Stellar Pubnet - Native symbol: XLM\n 'stellar:testnet': 'stellar:testnet/slip44:148', // Stellar Testnet - Native symbol: XLM\n 'tron:728126428': 'tron:728126428/slip44:195', // Tron Mainnet - Native symbol: TRX\n 'tron:3448148188': 'tron:3448148188/slip44:195', // Tron Nile - Native symbol: TRX\n 'tron:2494104990': 'tron:2494104990/slip44:195', // Tron Shasta - Native symbol: TRX\n};\n\n/**\n * Balance-row metadata the Accounts API attaches to Stellar native XLM.\n * Seeded at zero so an unfunded account still has a well-formed native row\n * instead of a bare `{ amount: '0' }`.\n */\nexport const STELLAR_NATIVE_ZERO_BALANCE_METADATA = {\n minimumReserveBalance: '0',\n spendableBalance: '0',\n} as const;\n\nconst ZERO_NATIVE_BALANCE: FungibleAssetBalance = { amount: '0' };\n\n/**\n * Default native balance to insert when a data source (typically Accounts API)\n * returns no row for the chain's native asset.\n *\n * Stellar natives include `spendableBalance` / `minimumReserveBalance` at 0 so\n * consumers that read those fields on XLM do not have to special-case a missing\n * metadata object. Other natives are a plain zero amount.\n *\n * @param nativeAssetId - The CAIP-19 native asset ID being seeded.\n * @returns A zero-balance entry for that native.\n */\nexport function getDefaultNativeAssetBalance(\n nativeAssetId: Caip19AssetId,\n): FungibleAssetBalance {\n try {\n const { chain } = parseCaipAssetType(nativeAssetId);\n if (chain.namespace === 'stellar') {\n return {\n amount: '0',\n metadata: { ...STELLAR_NATIVE_ZERO_BALANCE_METADATA },\n };\n }\n } catch {\n // Malformed IDs fall through to a plain zero amount.\n }\n\n return { ...ZERO_NATIVE_BALANCE };\n}\n\n/**\n * Builds a native asset map from {@link NATIVE_ASSETS}, normalizing each\n * CAIP-19 ID (ERC-20 addresses become EIP-55 checksummed).\n *\n * @returns A record mapping CAIP-2 chain IDs to their CAIP-19 native asset IDs.\n */\nexport function buildNativeAssetsFromConstant(): Record<\n ChainId,\n Caip19AssetId\n> {\n const nativeAssetsMap: Record<ChainId, Caip19AssetId> = {};\n for (const [chainId, nativeAssetId] of Object.entries(NATIVE_ASSETS)) {\n nativeAssetsMap[chainId as ChainId] = normalizeAssetId(nativeAssetId);\n }\n return nativeAssetsMap;\n}\n\n/**\n * Fetches chain data from chainid.network and merges it with the seed\n * native asset map built from {@link buildNativeAssetsFromConstant}.\n *\n * Remote entries only fill gaps — chains already present in the seed map\n * are never overwritten. Invalid entries (missing/negative chainId or slip44)\n * are silently skipped.\n *\n * @returns The merged native asset map.\n */\nexport async function buildNativeAssetsFromApi(): Promise<\n Record<ChainId, Caip19AssetId>\n> {\n const nativeAssetsMap = buildNativeAssetsFromConstant();\n\n try {\n const chains: ChainIdNetworkEntry[] | undefined =\n await fetchWithErrorHandling({\n url: CHAINID_NETWORK_URL,\n timeout: 10_000,\n });\n\n if (chains && Array.isArray(chains)) {\n for (const chain of chains) {\n if (\n !chain.chainId ||\n !chain.slip44 ||\n !Number.isInteger(chain.chainId) ||\n chain.chainId < 1 ||\n !Number.isInteger(chain.slip44) ||\n chain.slip44 < 1\n ) {\n continue;\n }\n\n const caipChainId = `eip155:${chain.chainId}` as ChainId;\n if (!nativeAssetsMap[caipChainId]) {\n nativeAssetsMap[caipChainId] =\n `eip155:${chain.chainId}/slip44:${chain.slip44}` as Caip19AssetId;\n }\n }\n }\n } catch {\n // Non-fatal: caller should fall back to the seed map.\n }\n\n return nativeAssetsMap;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/assets-controller",
3
- "version": "16.1.0-preview-1efee3183",
3
+ "version": "16.1.1-preview-c8ffe7b0e",
4
4
  "description": "Tracks assets balances/prices and handles token detection across all digital assets",
5
5
  "keywords": [
6
6
  "Ethereum",
@@ -55,7 +55,7 @@
55
55
  "@ethersproject/providers": "^5.7.0",
56
56
  "@metamask/account-tree-controller": "^10.0.1",
57
57
  "@metamask/accounts-controller": "^40.0.0",
58
- "@metamask/assets-controllers": "^112.0.2",
58
+ "@metamask/assets-controllers": "^112.0.3",
59
59
  "@metamask/base-controller": "^10.0.0",
60
60
  "@metamask/client-controller": "^2.0.0",
61
61
  "@metamask/config-registry-controller": "^4.0.0",
@@ -67,15 +67,15 @@
67
67
  "@metamask/keyring-snap-client": "^10.0.0",
68
68
  "@metamask/messenger": "^3.0.0",
69
69
  "@metamask/network-controller": "^37.0.0",
70
- "@metamask/network-enablement-controller": "^7.0.0",
70
+ "@metamask/network-enablement-controller": "^7.0.1",
71
71
  "@metamask/permission-controller": "^14.0.0",
72
- "@metamask/phishing-controller": "^18.1.0",
72
+ "@metamask/phishing-controller": "^18.1.1",
73
73
  "@metamask/polling-controller": "^17.0.0",
74
74
  "@metamask/preferences-controller": "^24.0.0",
75
75
  "@metamask/remote-feature-flag-controller": "^7.0.0",
76
76
  "@metamask/snaps-controllers": "^19.0.0",
77
77
  "@metamask/snaps-utils": "^12.1.2",
78
- "@metamask/transaction-controller": "^71.0.0",
78
+ "@metamask/transaction-controller": "^72.0.0",
79
79
  "@metamask/utils": "^12.0.0",
80
80
  "async-mutex": "^0.5.0",
81
81
  "bignumber.js": "^9.1.2",