@metamask-previews/assets-controllers 94.1.0-preview-2f42013a → 94.1.0-preview-9462ebb8

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 (80) hide show
  1. package/CHANGELOG.md +0 -11
  2. package/dist/AccountTrackerController.d.cts +2 -2
  3. package/dist/AccountTrackerController.d.mts +2 -2
  4. package/dist/CurrencyRateController.d.cts +2 -2
  5. package/dist/CurrencyRateController.d.mts +2 -2
  6. package/dist/DeFiPositionsController/DeFiPositionsController.d.cts +2 -2
  7. package/dist/DeFiPositionsController/DeFiPositionsController.d.mts +2 -2
  8. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.cjs +2 -8
  9. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.cjs.map +1 -1
  10. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts +2 -2
  11. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts.map +1 -1
  12. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts +2 -2
  13. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts.map +1 -1
  14. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs +2 -8
  15. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs.map +1 -1
  16. package/dist/TokenBalancesController.d.cts +2 -2
  17. package/dist/TokenBalancesController.d.mts +2 -2
  18. package/dist/TokenDetectionController.cjs +3 -6
  19. package/dist/TokenDetectionController.cjs.map +1 -1
  20. package/dist/TokenDetectionController.d.cts +2 -2
  21. package/dist/TokenDetectionController.d.cts.map +1 -1
  22. package/dist/TokenDetectionController.d.mts +2 -2
  23. package/dist/TokenDetectionController.d.mts.map +1 -1
  24. package/dist/TokenDetectionController.mjs +3 -6
  25. package/dist/TokenDetectionController.mjs.map +1 -1
  26. package/dist/TokenListController.cjs.map +1 -1
  27. package/dist/TokenListController.d.cts +2 -14
  28. package/dist/TokenListController.d.cts.map +1 -1
  29. package/dist/TokenListController.d.mts +2 -14
  30. package/dist/TokenListController.d.mts.map +1 -1
  31. package/dist/TokenListController.mjs.map +1 -1
  32. package/dist/TokenRatesController.cjs.map +1 -1
  33. package/dist/TokenRatesController.d.cts +2 -14
  34. package/dist/TokenRatesController.d.cts.map +1 -1
  35. package/dist/TokenRatesController.d.mts +2 -14
  36. package/dist/TokenRatesController.d.mts.map +1 -1
  37. package/dist/TokenRatesController.mjs.map +1 -1
  38. package/dist/TokensController.cjs +2 -5
  39. package/dist/TokensController.cjs.map +1 -1
  40. package/dist/TokensController.d.cts +0 -12
  41. package/dist/TokensController.d.cts.map +1 -1
  42. package/dist/TokensController.d.mts +0 -12
  43. package/dist/TokensController.d.mts.map +1 -1
  44. package/dist/TokensController.mjs +2 -5
  45. package/dist/TokensController.mjs.map +1 -1
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.cts +1 -1
  48. package/dist/index.d.cts.map +1 -1
  49. package/dist/index.d.mts +1 -1
  50. package/dist/index.d.mts.map +1 -1
  51. package/dist/index.mjs.map +1 -1
  52. package/dist/multicall.cjs +0 -5
  53. package/dist/multicall.cjs.map +1 -1
  54. package/dist/multicall.d.cts.map +1 -1
  55. package/dist/multicall.d.mts.map +1 -1
  56. package/dist/multicall.mjs +0 -5
  57. package/dist/multicall.mjs.map +1 -1
  58. package/dist/selectors/token-selectors.cjs.map +1 -1
  59. package/dist/selectors/token-selectors.d.cts +0 -2
  60. package/dist/selectors/token-selectors.d.cts.map +1 -1
  61. package/dist/selectors/token-selectors.d.mts +0 -2
  62. package/dist/selectors/token-selectors.d.mts.map +1 -1
  63. package/dist/selectors/token-selectors.mjs.map +1 -1
  64. package/dist/token-prices-service/codefi-v2.cjs +0 -2
  65. package/dist/token-prices-service/codefi-v2.cjs.map +1 -1
  66. package/dist/token-prices-service/codefi-v2.d.cts +1 -3
  67. package/dist/token-prices-service/codefi-v2.d.cts.map +1 -1
  68. package/dist/token-prices-service/codefi-v2.d.mts +1 -3
  69. package/dist/token-prices-service/codefi-v2.d.mts.map +1 -1
  70. package/dist/token-prices-service/codefi-v2.mjs +0 -2
  71. package/dist/token-prices-service/codefi-v2.mjs.map +1 -1
  72. package/dist/token-service.cjs +16 -129
  73. package/dist/token-service.cjs.map +1 -1
  74. package/dist/token-service.d.cts +10 -37
  75. package/dist/token-service.d.cts.map +1 -1
  76. package/dist/token-service.d.mts +10 -37
  77. package/dist/token-service.d.mts.map +1 -1
  78. package/dist/token-service.mjs +16 -129
  79. package/dist/token-service.mjs.map +1 -1
  80. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -9,23 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Added
11
11
 
12
- - Add RWA (Real World Assets) data support to token service ([#7560](https://github.com/MetaMask/core/pull/7560))
13
- - Add `includeRwaData` optional parameter to `getTrendingTokens` function to include RWA data in results
14
- - Add `TokenRwaData` type for RWA token metadata (market hours, pause times, ticker, instrument type)
15
- - Add `TokenSearchItem` type with optional `rwaData` field for token search results
16
- - Add `rwaData` optional field to `TrendingAsset` type
17
12
  - Update spot-prices endpoint list of supported chains and assets ([#7543](https://github.com/MetaMask/core/pull/7543))
18
13
  - Export `selectAllAssets` ([#7496](https://github.com/MetaMask/core/pull/7496))
19
- - Add multicall address for `MSU (MapleStory Universe)` ([#7453](https://github.com/MetaMask/core/pull/7453))
20
- - Add MSU (MapleStory Universe) and Etherlink in Spot Prices support ([#7453](https://github.com/MetaMask/core/pull/7453))
21
14
 
22
15
  ### Changed
23
16
 
24
- - Bump `@metamask/snaps-controllers` from `^14.0.1` to `^17.2.0` ([#7550](https://github.com/MetaMask/core/pull/7550))
25
- - Bump `@metamask/snaps-sdk` from `^9.0.0` to `^10.3.0` ([#7550](https://github.com/MetaMask/core/pull/7550))
26
- - Bump `@metamask/snaps-utils` from `^11.0.0` to `^11.7.0` ([#7550](https://github.com/MetaMask/core/pull/7550))
27
17
  - Upgrade `@metamask/utils` from `^11.8.1` to `^11.9.0` ([#7511](https://github.com/MetaMask/core/pull/7511))
28
- - Bump `@metamask/permission-controller` from `^12.1.1` to `^12.2.0` ([#7559](https://github.com/MetaMask/core/pull/7559))
29
18
  - **BREAKING:** `AccountTrackerController` now requires `KeyringController:getState` action and `KeyringController:lock` event in addition to existing allowed actions and events ([#7492](https://github.com/MetaMask/core/pull/7492))
30
19
  - Added `#isLocked` property to track keyring lock state, initialized from `KeyringController:getState`
31
20
  - Added `isActive` getter that returns `true` when keyring is unlocked and user is onboarded
@@ -90,8 +90,8 @@ type AccountTrackerPollingInput = {
90
90
  queryAllAccounts?: boolean;
91
91
  };
92
92
  declare const AccountTrackerController_base: (abstract new (...args: any[]) => {
93
- readonly "__#14@#intervalIds": Record<string, NodeJS.Timeout>;
94
- "__#14@#intervalLength": number | undefined;
93
+ readonly "__#15@#intervalIds": Record<string, NodeJS.Timeout>;
94
+ "__#15@#intervalLength": number | undefined;
95
95
  setIntervalLength(intervalLength: number): void;
96
96
  getIntervalLength(): number | undefined;
97
97
  _startPolling(input: AccountTrackerPollingInput): void;
@@ -90,8 +90,8 @@ type AccountTrackerPollingInput = {
90
90
  queryAllAccounts?: boolean;
91
91
  };
92
92
  declare const AccountTrackerController_base: (abstract new (...args: any[]) => {
93
- readonly "__#14@#intervalIds": Record<string, NodeJS.Timeout>;
94
- "__#14@#intervalLength": number | undefined;
93
+ readonly "__#15@#intervalIds": Record<string, NodeJS.Timeout>;
94
+ "__#15@#intervalLength": number | undefined;
95
95
  setIntervalLength(intervalLength: number): void;
96
96
  getIntervalLength(): number | undefined;
97
97
  _startPolling(input: AccountTrackerPollingInput): void;
@@ -33,8 +33,8 @@ type CurrencyRatePollingInput = {
33
33
  nativeCurrencies: string[];
34
34
  };
35
35
  declare const CurrencyRateController_base: (abstract new (...args: any[]) => {
36
- readonly "__#14@#intervalIds": Record<string, NodeJS.Timeout>;
37
- "__#14@#intervalLength": number | undefined;
36
+ readonly "__#15@#intervalIds": Record<string, NodeJS.Timeout>;
37
+ "__#15@#intervalLength": number | undefined;
38
38
  setIntervalLength(intervalLength: number): void;
39
39
  getIntervalLength(): number | undefined;
40
40
  _startPolling(input: CurrencyRatePollingInput): void;
@@ -33,8 +33,8 @@ type CurrencyRatePollingInput = {
33
33
  nativeCurrencies: string[];
34
34
  };
35
35
  declare const CurrencyRateController_base: (abstract new (...args: any[]) => {
36
- readonly "__#14@#intervalIds": Record<string, NodeJS.Timeout>;
37
- "__#14@#intervalLength": number | undefined;
36
+ readonly "__#15@#intervalIds": Record<string, NodeJS.Timeout>;
37
+ "__#15@#intervalLength": number | undefined;
38
38
  setIntervalLength(intervalLength: number): void;
39
39
  getIntervalLength(): number | undefined;
40
40
  _startPolling(input: CurrencyRatePollingInput): void;
@@ -57,8 +57,8 @@ export type AllowedEvents = KeyringControllerLockEvent | TransactionControllerTr
57
57
  */
58
58
  export type DeFiPositionsControllerMessenger = Messenger<typeof controllerName, DeFiPositionsControllerActions | AllowedActions, DeFiPositionsControllerEvents | AllowedEvents>;
59
59
  declare const DeFiPositionsController_base: (abstract new (...args: any[]) => {
60
- readonly "__#14@#intervalIds": Record<string, NodeJS.Timeout>;
61
- "__#14@#intervalLength": number | undefined;
60
+ readonly "__#15@#intervalIds": Record<string, NodeJS.Timeout>;
61
+ "__#15@#intervalLength": number | undefined;
62
62
  setIntervalLength(intervalLength: number): void;
63
63
  getIntervalLength(): number | undefined;
64
64
  _startPolling(input: import("@metamask/utils").Json): void;
@@ -57,8 +57,8 @@ export type AllowedEvents = KeyringControllerLockEvent | TransactionControllerTr
57
57
  */
58
58
  export type DeFiPositionsControllerMessenger = Messenger<typeof controllerName, DeFiPositionsControllerActions | AllowedActions, DeFiPositionsControllerEvents | AllowedEvents>;
59
59
  declare const DeFiPositionsController_base: (abstract new (...args: any[]) => {
60
- readonly "__#14@#intervalIds": Record<string, NodeJS.Timeout>;
61
- "__#14@#intervalLength": number | undefined;
60
+ readonly "__#15@#intervalIds": Record<string, NodeJS.Timeout>;
61
+ "__#15@#intervalLength": number | undefined;
62
62
  setIntervalLength(intervalLength: number): void;
63
63
  getIntervalLength(): number | undefined;
64
64
  _startPolling(input: import("@metamask/utils").Json): void;
@@ -291,14 +291,8 @@ async function _MultichainAssetsRatesController_getMarketData(snapId, assets, cu
291
291
  }
292
292
  const assetToMarketData = {};
293
293
  for (const asset of assets) {
294
- const assetMarketData = response.marketData?.[asset]?.[currency];
295
- // We do not consider NFTs here, so `fungible` must be `true`.
296
- if (assetMarketData?.fungible) {
297
- assetToMarketData[asset] = assetMarketData;
298
- }
299
- else {
300
- assetToMarketData[asset] = undefined;
301
- }
294
+ assetToMarketData[asset] =
295
+ response.marketData?.[asset]?.[currency] ?? undefined;
302
296
  }
303
297
  return assetToMarketData;
304
298
  }, _MultichainAssetsRatesController_getUpdatedRatesFor =
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAssetsRatesController.cjs","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerListMultichainAccountsAction,\n AccountsControllerAccountAddedEvent,\n AccountsControllerGetSelectedMultichainAccountAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { CaipAssetType } from '@metamask/keyring-api';\nimport type {\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type {\n SnapId,\n AssetConversion,\n OnAssetsConversionArguments,\n OnAssetHistoricalPriceArguments,\n OnAssetHistoricalPriceResponse,\n HistoricalPriceIntervals,\n OnAssetsMarketDataArguments,\n OnAssetsMarketDataResponse,\n FungibleAssetMarketData,\n OnAssetsConversionResponse,\n} from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport { MAP_CAIP_CURRENCIES } from './constant';\nimport type {\n CurrencyRateState,\n CurrencyRateStateChange,\n GetCurrencyRateState,\n} from '../CurrencyRateController';\nimport type {\n MultichainAssetsControllerGetStateAction,\n MultichainAssetsControllerAccountAssetListUpdatedEvent,\n} from '../MultichainAssetsController';\n\n/**\n * The name of the MultichainAssetsRatesController.\n */\nconst controllerName = 'MultichainAssetsRatesController';\n\n// This is temporary until its exported from snap\ntype HistoricalPrice = {\n intervals: HistoricalPriceIntervals;\n // The UNIX timestamp of when the historical price was last updated.\n updateTime: number;\n // The UNIX timestamp of when the historical price will expire.\n expirationTime?: number;\n};\n\n/**\n * State used by the MultichainAssetsRatesController to cache token conversion rates.\n */\nexport type MultichainAssetsRatesControllerState = {\n conversionRates: Record<CaipAssetType, UnifiedAssetConversion>;\n historicalPrices: Record<CaipAssetType, Record<string, HistoricalPrice>>; // string being the current currency we fetched historical prices for\n};\n\n/**\n * Returns the state of the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\n/**\n * Action to update the rates of all supported tokens.\n */\nexport type MultichainAssetsRatesControllerUpdateRatesAction = {\n type: `${typeof controllerName}:updateAssetsRates`;\n handler: MultichainAssetsRatesController['updateAssetsRates'];\n};\n\ntype UnifiedAssetConversion = AssetConversion & {\n marketData?: FungibleAssetMarketData;\n};\n\n/**\n * Constructs the default {@link MultichainAssetsRatesController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link MultichainAssetsRatesController} state.\n */\nexport function getDefaultMultichainAssetsRatesControllerState(): MultichainAssetsRatesControllerState {\n return { conversionRates: {}, historicalPrices: {} };\n}\n\n/**\n * Event emitted when the state of the MultichainAssetsRatesController changes.\n */\nexport type MultichainAssetsRatesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\n/**\n * Actions exposed by the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerActions =\n | MultichainAssetsRatesControllerGetStateAction\n | MultichainAssetsRatesControllerUpdateRatesAction;\n\n/**\n * Events emitted by MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerEvents =\n MultichainAssetsRatesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction\n | GetCurrencyRateState\n | MultichainAssetsControllerGetStateAction\n | AccountsControllerGetSelectedMultichainAccountAction;\n\n/**\n * Events that this controller is allowed to subscribe to.\n */\nexport type AllowedEvents =\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | AccountsControllerAccountAddedEvent\n | CurrencyRateStateChange\n | MultichainAssetsControllerAccountAssetListUpdatedEvent;\n/**\n * Messenger type for the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerMessenger = Messenger<\n typeof controllerName,\n MultichainAssetsRatesControllerActions | AllowedActions,\n MultichainAssetsRatesControllerEvents | AllowedEvents\n>;\n\n/**\n * The input for starting polling in MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesPollingInput = {\n accountId: string;\n};\n\nconst metadata: StateMetadata<MultichainAssetsRatesControllerState> = {\n conversionRates: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n historicalPrices: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n};\n\nexport type ConversionRatesWithMarketData = {\n conversionRates: Record<\n CaipAssetType,\n Record<CaipAssetType, UnifiedAssetConversion | null>\n >;\n};\n\n/**\n * Arguments for a Snap request.\n */\ntype SnapRequestArgs<T> = {\n snapId: SnapId;\n handler: HandlerType;\n params: T;\n};\n\n/**\n * Controller that manages multichain token conversion rates.\n *\n * This controller polls for token conversion rates and updates its state.\n */\nexport class MultichainAssetsRatesController extends StaticIntervalPollingController<MultichainAssetsRatesPollingInput>()<\n typeof controllerName,\n MultichainAssetsRatesControllerState,\n MultichainAssetsRatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n #currentCurrency: CurrencyRateState['currentCurrency'];\n\n #isUnlocked = true;\n\n /**\n * Creates an instance of MultichainAssetsRatesController.\n *\n * @param options - Constructor options.\n * @param options.interval - The polling interval in milliseconds.\n * @param options.state - The initial state.\n * @param options.messenger - A reference to the messenger.\n */\n constructor({\n interval = 18000,\n state = {},\n messenger,\n }: {\n interval?: number;\n state?: Partial<MultichainAssetsRatesControllerState>;\n messenger: MultichainAssetsRatesControllerMessenger;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {\n ...getDefaultMultichainAssetsRatesControllerState(),\n ...state,\n },\n metadata,\n });\n\n this.setIntervalLength(interval);\n\n // Subscribe to keyring lock/unlock events.\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n ({ currentCurrency: this.#currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n ));\n\n this.messenger.subscribe(\n 'CurrencyRateController:stateChange',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (currentCurrency: string) => {\n this.#currentCurrency = currentCurrency;\n await this.updateAssetsRates();\n },\n (currencyRateControllerState) =>\n currencyRateControllerState.currentCurrency,\n );\n\n this.messenger.subscribe(\n 'MultichainAssetsController:accountAssetListUpdated',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async ({ assets }) => {\n const newAccountAssets = Object.entries(assets).map(\n ([accountId, { added }]) => ({\n accountId,\n assets: [...added],\n }),\n );\n // TODO; removed can be used in future for further cleanup\n await this.#updateAssetsRatesForNewAssets(newAccountAssets);\n },\n );\n }\n\n /**\n * Executes a poll by updating token conversion rates for the current account.\n *\n * @returns A promise that resolves when the polling completes.\n */\n async _executePoll(): Promise<void> {\n await this.updateAssetsRates();\n }\n\n /**\n * Determines whether the controller is active.\n *\n * @returns True if the keyring is unlocked; otherwise, false.\n */\n get isActive(): boolean {\n return this.#isUnlocked;\n }\n\n /**\n * Checks if an account is a non-EVM account with a Snap.\n *\n * @param account - The account to check.\n * @returns True if the account is non-EVM and has Snap metadata; otherwise, false.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) && account.metadata.snap !== undefined\n );\n }\n\n /**\n * Retrieves all multichain accounts from the AccountsController.\n *\n * @returns An array of internal accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messenger.call('AccountsController:listMultichainAccounts');\n }\n\n /**\n * Filters and returns non-EVM accounts that should have balances.\n *\n * @returns An array of non-EVM internal accounts.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Adds the assets to a map of Snap ID to assets.\n *\n * @param snapIdToAssets - The map of Snap ID to assets.\n * @param account - The account to add the assets for.\n * @param assets - The assets to add.\n */\n #addAssetsToSnapIdMap(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n account: InternalAccount,\n assets: CaipAssetType[],\n ): void {\n // Prevent creating a new set if there are no assets to add.\n if (assets.length === 0) {\n return;\n }\n\n // FIXME: Instead of using the Snap ID from the account, we should\n // select the Snap based on the supported scopes defined in the Snaps'\n // manifest.\n const snapId = account.metadata.snap?.id as SnapId | undefined;\n if (!snapId) {\n return;\n }\n\n let snapAssets = snapIdToAssets.get(snapId);\n if (!snapAssets) {\n snapAssets = new Set();\n snapIdToAssets.set(snapId, snapAssets);\n }\n\n for (const asset of assets) {\n snapAssets.add(asset);\n }\n }\n\n /**\n * Updates token conversion rates for each non-EVM account.\n *\n * @returns A promise that resolves when the rates are updated.\n */\n async updateAssetsRates(): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n return (async (): Promise<void> => {\n if (!this.isActive) {\n return;\n }\n\n // Compute the set of unique assets from all accounts. It's important to\n // deduplicate assets here to avoid duplicate requests to the Snap.\n const accounts = this.#listAccounts();\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n for (const account of accounts) {\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n account,\n this.#getAssetsForAccount(account.id),\n );\n }\n\n this.#applyUpdatedRates(await this.#getUpdatedRatesFor(snapIdToAssets));\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Returns the CAIP-19 asset type for the current selected currency. Defaults\n * to USD if the current selected currency is not supported.\n *\n * @returns The CAIP-19 asset type for the current selected currency.\n */\n #getCaipCurrentCurrency(): CaipAssetType {\n return (\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd\n );\n }\n\n /**\n * Fetches the conversion rates for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the conversion rates for.\n * @param currency - The currency to fetch the conversion rates for.\n * @returns A record of CAIP-19 asset types to conversion rates.\n */\n async #getConversionRates(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, AssetConversion | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsConversion,\n params: {\n conversions: Array.from(assets).map((asset) => ({\n from: asset,\n to: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToConversionRate: Record<\n CaipAssetType,\n AssetConversion | undefined\n > = {};\n\n for (const asset of assets) {\n assetToConversionRate[asset] =\n response.conversionRates?.[asset]?.[currency] ?? undefined;\n }\n\n return assetToConversionRate;\n }\n\n /**\n * Fetches the market data for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the market data for.\n * @param currency - The currency to fetch the market data for.\n * @returns A record of CAIP-19 asset types to market data.\n */\n async #getMarketData(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, FungibleAssetMarketData | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsMarketData,\n params: {\n assets: Array.from(assets).map((asset) => ({\n asset,\n unit: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToMarketData: Record<\n CaipAssetType,\n FungibleAssetMarketData | undefined\n > = {};\n\n for (const asset of assets) {\n const assetMarketData = response.marketData?.[asset]?.[currency];\n\n // We do not consider NFTs here, so `fungible` must be `true`.\n if (assetMarketData?.fungible) {\n assetToMarketData[asset] = assetMarketData;\n } else {\n assetToMarketData[asset] = undefined;\n }\n }\n\n return assetToMarketData;\n }\n\n /**\n * Fetches the updated rates for the given assets from the given Snaps.\n *\n * @param snapIdToAssets - A map of Snap ID to CAIP-19 asset types.\n * @returns A record of CAIP-19 asset types to unified asset conversions.\n */\n async #getUpdatedRatesFor(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n ): Promise<\n Record<CaipAssetType, UnifiedAssetConversion & { currency: CaipAssetType }>\n > {\n const updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n > = {};\n\n // Keep a local copy to ensure that the currency is always the same for the\n // entire loop.\n const currency = this.#getCaipCurrentCurrency();\n\n // Note: Since the assets come from a 1-to-1 mapping with Snap IDs, we know\n // that a given asset will not appear under multiple Snap IDs.\n for (const [snapId, assets] of snapIdToAssets.entries()) {\n const [rates, marketData] = await Promise.all([\n this.#getConversionRates(snapId, assets, currency),\n this.#getMarketData(snapId, assets, currency),\n ]);\n\n for (const asset of assets) {\n const assetRate = rates[asset];\n const assetMarketData = marketData[asset];\n\n // Rates are mandatory, so skip the asset if not available.\n if (!assetRate) {\n continue;\n }\n\n updatedRates[asset] = {\n currency,\n ...assetRate,\n ...(assetMarketData && { marketData: assetMarketData }),\n };\n }\n }\n\n return updatedRates;\n }\n\n /**\n * Fetches historical prices for the current account\n *\n * @param asset - The asset to fetch historical prices for.\n * @param account - optional account to fetch historical prices for\n * @returns The historical prices.\n */\n async fetchHistoricalPricesForAsset(\n asset: CaipAssetType,\n account?: InternalAccount,\n ): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n return (async () => {\n const currentCaipCurrency =\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd;\n // Check if we already have historical prices for this asset and currency\n const historicalPriceExpirationTime =\n this.state.historicalPrices[asset]?.[this.#currentCurrency]\n ?.expirationTime;\n\n const historicalPriceHasExpired =\n historicalPriceExpirationTime &&\n historicalPriceExpirationTime < Date.now();\n\n if (historicalPriceHasExpired === false) {\n return;\n }\n\n const selectedAccount =\n account ??\n this.messenger.call('AccountsController:getSelectedMultichainAccount');\n try {\n const historicalPricesResponse = await this.messenger.call(\n 'SnapController:handleRequest',\n {\n snapId: selectedAccount?.metadata.snap?.id as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnAssetHistoricalPrice,\n request: {\n jsonrpc: '2.0',\n method: HandlerType.OnAssetHistoricalPrice,\n params: {\n from: asset,\n to: currentCaipCurrency,\n },\n },\n },\n );\n\n // skip state update if no historical prices are returned\n if (!historicalPricesResponse) {\n return;\n }\n\n this.update((state) => {\n state.historicalPrices = {\n ...state.historicalPrices,\n [asset]: {\n ...state.historicalPrices[asset],\n [this.#currentCurrency]: (\n historicalPricesResponse as OnAssetHistoricalPriceResponse\n )?.historicalPrice,\n },\n };\n });\n } catch {\n throw new Error(\n `Failed to fetch historical prices for asset: ${asset}`,\n );\n }\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Updates the conversion rates for new assets.\n *\n * @param accounts - The accounts to update the conversion rates for.\n * @returns A promise that resolves when the rates are updated.\n */\n async #updateAssetsRatesForNewAssets(\n accounts: {\n accountId: string;\n assets: CaipAssetType[];\n }[],\n ): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n return (async () => {\n if (!this.isActive) {\n return;\n }\n\n // First build a map containing all assets that need to be updated per\n // Snap ID, this will be used to batch the requests.\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n\n for (const { accountId, assets } of accounts) {\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n this.#getAccount(accountId),\n assets,\n );\n }\n\n this.#applyUpdatedRates(await this.#getUpdatedRatesFor(snapIdToAssets));\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined = this.#listAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n\n return account;\n }\n\n /**\n * Returns the array of CAIP-19 assets for the given account ID.\n * If none are found, returns an empty array.\n *\n * @param accountId - The account ID to get the assets for.\n * @returns An array of CAIP-19 assets.\n */\n #getAssetsForAccount(accountId: string): CaipAssetType[] {\n // Always fetch fresh state - MultichainAssetsController uses Immer which creates\n // new object references on every update, so caching would become stale.\n const { accountsAssets } = this.messenger.call(\n 'MultichainAssetsController:getState',\n );\n return accountsAssets?.[accountId] ?? [];\n }\n\n /**\n * Merges the new rates into the controller's state.\n *\n * @param updatedRates - The new rates to merge.\n */\n #applyUpdatedRates(\n updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n >,\n ): void {\n if (Object.keys(updatedRates).length === 0) {\n return;\n }\n this.update((state: Draft<MultichainAssetsRatesControllerState>) => {\n state.conversionRates = {\n ...state.conversionRates,\n ...updatedRates,\n };\n });\n }\n\n /**\n * Forwards a Snap request to the SnapController.\n *\n * @param args - The request parameters.\n * @param args.snapId - The ID of the Snap.\n * @param args.handler - The handler type.\n * @param args.params - The asset conversions.\n * @returns A promise that resolves with the account rates.\n */\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsConversionArguments>,\n ): Promise<OnAssetsConversionResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetHistoricalPriceArguments>,\n ): Promise<OnAssetHistoricalPriceResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsMarketDataArguments>,\n ): Promise<OnAssetsMarketDataResponse | undefined>;\n\n async #handleSnapRequest(args: SnapRequestArgs<unknown>): Promise<unknown> {\n const { snapId, handler, params } = args;\n try {\n return await this.messenger.call('SnapController:handleRequest', {\n snapId,\n origin: 'metamask',\n handler,\n request: {\n jsonrpc: '2.0',\n method: handler,\n params,\n },\n });\n } catch (error) {\n console.error(`Snap request failed for ${handler}:`, {\n snapId,\n handler,\n message: (error as Error).message,\n params,\n });\n return undefined;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"MultichainAssetsRatesController.cjs","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerListMultichainAccountsAction,\n AccountsControllerAccountAddedEvent,\n AccountsControllerGetSelectedMultichainAccountAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { CaipAssetType } from '@metamask/keyring-api';\nimport type {\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type {\n SnapId,\n AssetConversion,\n OnAssetsConversionArguments,\n OnAssetHistoricalPriceArguments,\n OnAssetHistoricalPriceResponse,\n HistoricalPriceIntervals,\n OnAssetsMarketDataArguments,\n OnAssetsMarketDataResponse,\n FungibleAssetMarketData,\n OnAssetsConversionResponse,\n} from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport { MAP_CAIP_CURRENCIES } from './constant';\nimport type {\n CurrencyRateState,\n CurrencyRateStateChange,\n GetCurrencyRateState,\n} from '../CurrencyRateController';\nimport type {\n MultichainAssetsControllerGetStateAction,\n MultichainAssetsControllerAccountAssetListUpdatedEvent,\n} from '../MultichainAssetsController';\n\n/**\n * The name of the MultichainAssetsRatesController.\n */\nconst controllerName = 'MultichainAssetsRatesController';\n\n// This is temporary until its exported from snap\ntype HistoricalPrice = {\n intervals: HistoricalPriceIntervals;\n // The UNIX timestamp of when the historical price was last updated.\n updateTime: number;\n // The UNIX timestamp of when the historical price will expire.\n expirationTime?: number;\n};\n\n/**\n * State used by the MultichainAssetsRatesController to cache token conversion rates.\n */\nexport type MultichainAssetsRatesControllerState = {\n conversionRates: Record<CaipAssetType, UnifiedAssetConversion>;\n historicalPrices: Record<CaipAssetType, Record<string, HistoricalPrice>>; // string being the current currency we fetched historical prices for\n};\n\n/**\n * Returns the state of the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\n/**\n * Action to update the rates of all supported tokens.\n */\nexport type MultichainAssetsRatesControllerUpdateRatesAction = {\n type: `${typeof controllerName}:updateAssetsRates`;\n handler: MultichainAssetsRatesController['updateAssetsRates'];\n};\n\ntype UnifiedAssetConversion = AssetConversion & {\n marketData?: FungibleAssetMarketData;\n};\n\n/**\n * Constructs the default {@link MultichainAssetsRatesController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link MultichainAssetsRatesController} state.\n */\nexport function getDefaultMultichainAssetsRatesControllerState(): MultichainAssetsRatesControllerState {\n return { conversionRates: {}, historicalPrices: {} };\n}\n\n/**\n * Event emitted when the state of the MultichainAssetsRatesController changes.\n */\nexport type MultichainAssetsRatesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\n/**\n * Actions exposed by the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerActions =\n | MultichainAssetsRatesControllerGetStateAction\n | MultichainAssetsRatesControllerUpdateRatesAction;\n\n/**\n * Events emitted by MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerEvents =\n MultichainAssetsRatesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction\n | GetCurrencyRateState\n | MultichainAssetsControllerGetStateAction\n | AccountsControllerGetSelectedMultichainAccountAction;\n\n/**\n * Events that this controller is allowed to subscribe to.\n */\nexport type AllowedEvents =\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | AccountsControllerAccountAddedEvent\n | CurrencyRateStateChange\n | MultichainAssetsControllerAccountAssetListUpdatedEvent;\n/**\n * Messenger type for the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerMessenger = Messenger<\n typeof controllerName,\n MultichainAssetsRatesControllerActions | AllowedActions,\n MultichainAssetsRatesControllerEvents | AllowedEvents\n>;\n\n/**\n * The input for starting polling in MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesPollingInput = {\n accountId: string;\n};\n\nconst metadata: StateMetadata<MultichainAssetsRatesControllerState> = {\n conversionRates: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n historicalPrices: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n};\n\nexport type ConversionRatesWithMarketData = {\n conversionRates: Record<\n CaipAssetType,\n Record<CaipAssetType, UnifiedAssetConversion | null>\n >;\n};\n\n/**\n * Arguments for a Snap request.\n */\ntype SnapRequestArgs<T> = {\n snapId: SnapId;\n handler: HandlerType;\n params: T;\n};\n\n/**\n * Controller that manages multichain token conversion rates.\n *\n * This controller polls for token conversion rates and updates its state.\n */\nexport class MultichainAssetsRatesController extends StaticIntervalPollingController<MultichainAssetsRatesPollingInput>()<\n typeof controllerName,\n MultichainAssetsRatesControllerState,\n MultichainAssetsRatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n #currentCurrency: CurrencyRateState['currentCurrency'];\n\n #isUnlocked = true;\n\n /**\n * Creates an instance of MultichainAssetsRatesController.\n *\n * @param options - Constructor options.\n * @param options.interval - The polling interval in milliseconds.\n * @param options.state - The initial state.\n * @param options.messenger - A reference to the messenger.\n */\n constructor({\n interval = 18000,\n state = {},\n messenger,\n }: {\n interval?: number;\n state?: Partial<MultichainAssetsRatesControllerState>;\n messenger: MultichainAssetsRatesControllerMessenger;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {\n ...getDefaultMultichainAssetsRatesControllerState(),\n ...state,\n },\n metadata,\n });\n\n this.setIntervalLength(interval);\n\n // Subscribe to keyring lock/unlock events.\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n ({ currentCurrency: this.#currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n ));\n\n this.messenger.subscribe(\n 'CurrencyRateController:stateChange',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (currentCurrency: string) => {\n this.#currentCurrency = currentCurrency;\n await this.updateAssetsRates();\n },\n (currencyRateControllerState) =>\n currencyRateControllerState.currentCurrency,\n );\n\n this.messenger.subscribe(\n 'MultichainAssetsController:accountAssetListUpdated',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async ({ assets }) => {\n const newAccountAssets = Object.entries(assets).map(\n ([accountId, { added }]) => ({\n accountId,\n assets: [...added],\n }),\n );\n // TODO; removed can be used in future for further cleanup\n await this.#updateAssetsRatesForNewAssets(newAccountAssets);\n },\n );\n }\n\n /**\n * Executes a poll by updating token conversion rates for the current account.\n *\n * @returns A promise that resolves when the polling completes.\n */\n async _executePoll(): Promise<void> {\n await this.updateAssetsRates();\n }\n\n /**\n * Determines whether the controller is active.\n *\n * @returns True if the keyring is unlocked; otherwise, false.\n */\n get isActive(): boolean {\n return this.#isUnlocked;\n }\n\n /**\n * Checks if an account is a non-EVM account with a Snap.\n *\n * @param account - The account to check.\n * @returns True if the account is non-EVM and has Snap metadata; otherwise, false.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) && account.metadata.snap !== undefined\n );\n }\n\n /**\n * Retrieves all multichain accounts from the AccountsController.\n *\n * @returns An array of internal accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messenger.call('AccountsController:listMultichainAccounts');\n }\n\n /**\n * Filters and returns non-EVM accounts that should have balances.\n *\n * @returns An array of non-EVM internal accounts.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Adds the assets to a map of Snap ID to assets.\n *\n * @param snapIdToAssets - The map of Snap ID to assets.\n * @param account - The account to add the assets for.\n * @param assets - The assets to add.\n */\n #addAssetsToSnapIdMap(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n account: InternalAccount,\n assets: CaipAssetType[],\n ): void {\n // Prevent creating a new set if there are no assets to add.\n if (assets.length === 0) {\n return;\n }\n\n // FIXME: Instead of using the Snap ID from the account, we should\n // select the Snap based on the supported scopes defined in the Snaps'\n // manifest.\n const snapId = account.metadata.snap?.id as SnapId | undefined;\n if (!snapId) {\n return;\n }\n\n let snapAssets = snapIdToAssets.get(snapId);\n if (!snapAssets) {\n snapAssets = new Set();\n snapIdToAssets.set(snapId, snapAssets);\n }\n\n for (const asset of assets) {\n snapAssets.add(asset);\n }\n }\n\n /**\n * Updates token conversion rates for each non-EVM account.\n *\n * @returns A promise that resolves when the rates are updated.\n */\n async updateAssetsRates(): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n return (async (): Promise<void> => {\n if (!this.isActive) {\n return;\n }\n\n // Compute the set of unique assets from all accounts. It's important to\n // deduplicate assets here to avoid duplicate requests to the Snap.\n const accounts = this.#listAccounts();\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n for (const account of accounts) {\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n account,\n this.#getAssetsForAccount(account.id),\n );\n }\n\n this.#applyUpdatedRates(await this.#getUpdatedRatesFor(snapIdToAssets));\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Returns the CAIP-19 asset type for the current selected currency. Defaults\n * to USD if the current selected currency is not supported.\n *\n * @returns The CAIP-19 asset type for the current selected currency.\n */\n #getCaipCurrentCurrency(): CaipAssetType {\n return (\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd\n );\n }\n\n /**\n * Fetches the conversion rates for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the conversion rates for.\n * @param currency - The currency to fetch the conversion rates for.\n * @returns A record of CAIP-19 asset types to conversion rates.\n */\n async #getConversionRates(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, AssetConversion | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsConversion,\n params: {\n conversions: Array.from(assets).map((asset) => ({\n from: asset,\n to: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToConversionRate: Record<\n CaipAssetType,\n AssetConversion | undefined\n > = {};\n\n for (const asset of assets) {\n assetToConversionRate[asset] =\n response.conversionRates?.[asset]?.[currency] ?? undefined;\n }\n\n return assetToConversionRate;\n }\n\n /**\n * Fetches the market data for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the market data for.\n * @param currency - The currency to fetch the market data for.\n * @returns A record of CAIP-19 asset types to market data.\n */\n async #getMarketData(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, FungibleAssetMarketData | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsMarketData,\n params: {\n assets: Array.from(assets).map((asset) => ({\n asset,\n unit: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToMarketData: Record<\n CaipAssetType,\n FungibleAssetMarketData | undefined\n > = {};\n\n for (const asset of assets) {\n assetToMarketData[asset] =\n response.marketData?.[asset]?.[currency] ?? undefined;\n }\n\n return assetToMarketData;\n }\n\n /**\n * Fetches the updated rates for the given assets from the given Snaps.\n *\n * @param snapIdToAssets - A map of Snap ID to CAIP-19 asset types.\n * @returns A record of CAIP-19 asset types to unified asset conversions.\n */\n async #getUpdatedRatesFor(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n ): Promise<\n Record<CaipAssetType, UnifiedAssetConversion & { currency: CaipAssetType }>\n > {\n const updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n > = {};\n\n // Keep a local copy to ensure that the currency is always the same for the\n // entire loop.\n const currency = this.#getCaipCurrentCurrency();\n\n // Note: Since the assets come from a 1-to-1 mapping with Snap IDs, we know\n // that a given asset will not appear under multiple Snap IDs.\n for (const [snapId, assets] of snapIdToAssets.entries()) {\n const [rates, marketData] = await Promise.all([\n this.#getConversionRates(snapId, assets, currency),\n this.#getMarketData(snapId, assets, currency),\n ]);\n\n for (const asset of assets) {\n const assetRate = rates[asset];\n const assetMarketData = marketData[asset];\n\n // Rates are mandatory, so skip the asset if not available.\n if (!assetRate) {\n continue;\n }\n\n updatedRates[asset] = {\n currency,\n ...assetRate,\n ...(assetMarketData && { marketData: assetMarketData }),\n };\n }\n }\n\n return updatedRates;\n }\n\n /**\n * Fetches historical prices for the current account\n *\n * @param asset - The asset to fetch historical prices for.\n * @param account - optional account to fetch historical prices for\n * @returns The historical prices.\n */\n async fetchHistoricalPricesForAsset(\n asset: CaipAssetType,\n account?: InternalAccount,\n ): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n return (async () => {\n const currentCaipCurrency =\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd;\n // Check if we already have historical prices for this asset and currency\n const historicalPriceExpirationTime =\n this.state.historicalPrices[asset]?.[this.#currentCurrency]\n ?.expirationTime;\n\n const historicalPriceHasExpired =\n historicalPriceExpirationTime &&\n historicalPriceExpirationTime < Date.now();\n\n if (historicalPriceHasExpired === false) {\n return;\n }\n\n const selectedAccount =\n account ??\n this.messenger.call('AccountsController:getSelectedMultichainAccount');\n try {\n const historicalPricesResponse = await this.messenger.call(\n 'SnapController:handleRequest',\n {\n snapId: selectedAccount?.metadata.snap?.id as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnAssetHistoricalPrice,\n request: {\n jsonrpc: '2.0',\n method: HandlerType.OnAssetHistoricalPrice,\n params: {\n from: asset,\n to: currentCaipCurrency,\n },\n },\n },\n );\n\n // skip state update if no historical prices are returned\n if (!historicalPricesResponse) {\n return;\n }\n\n this.update((state) => {\n state.historicalPrices = {\n ...state.historicalPrices,\n [asset]: {\n ...state.historicalPrices[asset],\n [this.#currentCurrency]: (\n historicalPricesResponse as OnAssetHistoricalPriceResponse\n )?.historicalPrice,\n },\n };\n });\n } catch {\n throw new Error(\n `Failed to fetch historical prices for asset: ${asset}`,\n );\n }\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Updates the conversion rates for new assets.\n *\n * @param accounts - The accounts to update the conversion rates for.\n * @returns A promise that resolves when the rates are updated.\n */\n async #updateAssetsRatesForNewAssets(\n accounts: {\n accountId: string;\n assets: CaipAssetType[];\n }[],\n ): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n return (async () => {\n if (!this.isActive) {\n return;\n }\n\n // First build a map containing all assets that need to be updated per\n // Snap ID, this will be used to batch the requests.\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n\n for (const { accountId, assets } of accounts) {\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n this.#getAccount(accountId),\n assets,\n );\n }\n\n this.#applyUpdatedRates(await this.#getUpdatedRatesFor(snapIdToAssets));\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined = this.#listAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n\n return account;\n }\n\n /**\n * Returns the array of CAIP-19 assets for the given account ID.\n * If none are found, returns an empty array.\n *\n * @param accountId - The account ID to get the assets for.\n * @returns An array of CAIP-19 assets.\n */\n #getAssetsForAccount(accountId: string): CaipAssetType[] {\n // Always fetch fresh state - MultichainAssetsController uses Immer which creates\n // new object references on every update, so caching would become stale.\n const { accountsAssets } = this.messenger.call(\n 'MultichainAssetsController:getState',\n );\n return accountsAssets?.[accountId] ?? [];\n }\n\n /**\n * Merges the new rates into the controller's state.\n *\n * @param updatedRates - The new rates to merge.\n */\n #applyUpdatedRates(\n updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n >,\n ): void {\n if (Object.keys(updatedRates).length === 0) {\n return;\n }\n this.update((state: Draft<MultichainAssetsRatesControllerState>) => {\n state.conversionRates = {\n ...state.conversionRates,\n ...updatedRates,\n };\n });\n }\n\n /**\n * Forwards a Snap request to the SnapController.\n *\n * @param args - The request parameters.\n * @param args.snapId - The ID of the Snap.\n * @param args.handler - The handler type.\n * @param args.params - The asset conversions.\n * @returns A promise that resolves with the account rates.\n */\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsConversionArguments>,\n ): Promise<OnAssetsConversionResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetHistoricalPriceArguments>,\n ): Promise<OnAssetHistoricalPriceResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsMarketDataArguments>,\n ): Promise<OnAssetsMarketDataResponse | undefined>;\n\n async #handleSnapRequest(args: SnapRequestArgs<unknown>): Promise<unknown> {\n const { snapId, handler, params } = args;\n try {\n return await this.messenger.call('SnapController:handleRequest', {\n snapId,\n origin: 'metamask',\n handler,\n request: {\n jsonrpc: '2.0',\n method: handler,\n params,\n },\n });\n } catch (error) {\n console.error(`Snap request failed for ${handler}:`, {\n snapId,\n handler,\n message: (error as Error).message,\n params,\n });\n return undefined;\n }\n }\n}\n"]}
@@ -81,8 +81,8 @@ export type ConversionRatesWithMarketData = {
81
81
  conversionRates: Record<CaipAssetType, Record<CaipAssetType, UnifiedAssetConversion | null>>;
82
82
  };
83
83
  declare const MultichainAssetsRatesController_base: (abstract new (...args: any[]) => {
84
- readonly "__#14@#intervalIds": Record<string, NodeJS.Timeout>;
85
- "__#14@#intervalLength": number | undefined;
84
+ readonly "__#15@#intervalIds": Record<string, NodeJS.Timeout>;
85
+ "__#15@#intervalLength": number | undefined;
86
86
  setIntervalLength(intervalLength: number): void;
87
87
  getIntervalLength(): number | undefined;
88
88
  _startPolling(input: MultichainAssetsRatesPollingInput): void;
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAssetsRatesController.d.cts","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MultichainAssetsRatesController.d.cts","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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"}
@@ -81,8 +81,8 @@ export type ConversionRatesWithMarketData = {
81
81
  conversionRates: Record<CaipAssetType, Record<CaipAssetType, UnifiedAssetConversion | null>>;
82
82
  };
83
83
  declare const MultichainAssetsRatesController_base: (abstract new (...args: any[]) => {
84
- readonly "__#14@#intervalIds": Record<string, NodeJS.Timeout>;
85
- "__#14@#intervalLength": number | undefined;
84
+ readonly "__#15@#intervalIds": Record<string, NodeJS.Timeout>;
85
+ "__#15@#intervalLength": number | undefined;
86
86
  setIntervalLength(intervalLength: number): void;
87
87
  getIntervalLength(): number | undefined;
88
88
  _startPolling(input: MultichainAssetsRatesPollingInput): void;
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAssetsRatesController.d.mts","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MultichainAssetsRatesController.d.mts","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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"}
@@ -286,14 +286,8 @@ async function _MultichainAssetsRatesController_getMarketData(snapId, assets, cu
286
286
  }
287
287
  const assetToMarketData = {};
288
288
  for (const asset of assets) {
289
- const assetMarketData = response.marketData?.[asset]?.[currency];
290
- // We do not consider NFTs here, so `fungible` must be `true`.
291
- if (assetMarketData?.fungible) {
292
- assetToMarketData[asset] = assetMarketData;
293
- }
294
- else {
295
- assetToMarketData[asset] = undefined;
296
- }
289
+ assetToMarketData[asset] =
290
+ response.marketData?.[asset]?.[currency] ?? undefined;
297
291
  }
298
292
  return assetToMarketData;
299
293
  }, _MultichainAssetsRatesController_getUpdatedRatesFor =
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAssetsRatesController.mjs","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerListMultichainAccountsAction,\n AccountsControllerAccountAddedEvent,\n AccountsControllerGetSelectedMultichainAccountAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { CaipAssetType } from '@metamask/keyring-api';\nimport type {\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type {\n SnapId,\n AssetConversion,\n OnAssetsConversionArguments,\n OnAssetHistoricalPriceArguments,\n OnAssetHistoricalPriceResponse,\n HistoricalPriceIntervals,\n OnAssetsMarketDataArguments,\n OnAssetsMarketDataResponse,\n FungibleAssetMarketData,\n OnAssetsConversionResponse,\n} from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport { MAP_CAIP_CURRENCIES } from './constant';\nimport type {\n CurrencyRateState,\n CurrencyRateStateChange,\n GetCurrencyRateState,\n} from '../CurrencyRateController';\nimport type {\n MultichainAssetsControllerGetStateAction,\n MultichainAssetsControllerAccountAssetListUpdatedEvent,\n} from '../MultichainAssetsController';\n\n/**\n * The name of the MultichainAssetsRatesController.\n */\nconst controllerName = 'MultichainAssetsRatesController';\n\n// This is temporary until its exported from snap\ntype HistoricalPrice = {\n intervals: HistoricalPriceIntervals;\n // The UNIX timestamp of when the historical price was last updated.\n updateTime: number;\n // The UNIX timestamp of when the historical price will expire.\n expirationTime?: number;\n};\n\n/**\n * State used by the MultichainAssetsRatesController to cache token conversion rates.\n */\nexport type MultichainAssetsRatesControllerState = {\n conversionRates: Record<CaipAssetType, UnifiedAssetConversion>;\n historicalPrices: Record<CaipAssetType, Record<string, HistoricalPrice>>; // string being the current currency we fetched historical prices for\n};\n\n/**\n * Returns the state of the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\n/**\n * Action to update the rates of all supported tokens.\n */\nexport type MultichainAssetsRatesControllerUpdateRatesAction = {\n type: `${typeof controllerName}:updateAssetsRates`;\n handler: MultichainAssetsRatesController['updateAssetsRates'];\n};\n\ntype UnifiedAssetConversion = AssetConversion & {\n marketData?: FungibleAssetMarketData;\n};\n\n/**\n * Constructs the default {@link MultichainAssetsRatesController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link MultichainAssetsRatesController} state.\n */\nexport function getDefaultMultichainAssetsRatesControllerState(): MultichainAssetsRatesControllerState {\n return { conversionRates: {}, historicalPrices: {} };\n}\n\n/**\n * Event emitted when the state of the MultichainAssetsRatesController changes.\n */\nexport type MultichainAssetsRatesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\n/**\n * Actions exposed by the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerActions =\n | MultichainAssetsRatesControllerGetStateAction\n | MultichainAssetsRatesControllerUpdateRatesAction;\n\n/**\n * Events emitted by MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerEvents =\n MultichainAssetsRatesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction\n | GetCurrencyRateState\n | MultichainAssetsControllerGetStateAction\n | AccountsControllerGetSelectedMultichainAccountAction;\n\n/**\n * Events that this controller is allowed to subscribe to.\n */\nexport type AllowedEvents =\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | AccountsControllerAccountAddedEvent\n | CurrencyRateStateChange\n | MultichainAssetsControllerAccountAssetListUpdatedEvent;\n/**\n * Messenger type for the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerMessenger = Messenger<\n typeof controllerName,\n MultichainAssetsRatesControllerActions | AllowedActions,\n MultichainAssetsRatesControllerEvents | AllowedEvents\n>;\n\n/**\n * The input for starting polling in MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesPollingInput = {\n accountId: string;\n};\n\nconst metadata: StateMetadata<MultichainAssetsRatesControllerState> = {\n conversionRates: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n historicalPrices: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n};\n\nexport type ConversionRatesWithMarketData = {\n conversionRates: Record<\n CaipAssetType,\n Record<CaipAssetType, UnifiedAssetConversion | null>\n >;\n};\n\n/**\n * Arguments for a Snap request.\n */\ntype SnapRequestArgs<T> = {\n snapId: SnapId;\n handler: HandlerType;\n params: T;\n};\n\n/**\n * Controller that manages multichain token conversion rates.\n *\n * This controller polls for token conversion rates and updates its state.\n */\nexport class MultichainAssetsRatesController extends StaticIntervalPollingController<MultichainAssetsRatesPollingInput>()<\n typeof controllerName,\n MultichainAssetsRatesControllerState,\n MultichainAssetsRatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n #currentCurrency: CurrencyRateState['currentCurrency'];\n\n #isUnlocked = true;\n\n /**\n * Creates an instance of MultichainAssetsRatesController.\n *\n * @param options - Constructor options.\n * @param options.interval - The polling interval in milliseconds.\n * @param options.state - The initial state.\n * @param options.messenger - A reference to the messenger.\n */\n constructor({\n interval = 18000,\n state = {},\n messenger,\n }: {\n interval?: number;\n state?: Partial<MultichainAssetsRatesControllerState>;\n messenger: MultichainAssetsRatesControllerMessenger;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {\n ...getDefaultMultichainAssetsRatesControllerState(),\n ...state,\n },\n metadata,\n });\n\n this.setIntervalLength(interval);\n\n // Subscribe to keyring lock/unlock events.\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n ({ currentCurrency: this.#currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n ));\n\n this.messenger.subscribe(\n 'CurrencyRateController:stateChange',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (currentCurrency: string) => {\n this.#currentCurrency = currentCurrency;\n await this.updateAssetsRates();\n },\n (currencyRateControllerState) =>\n currencyRateControllerState.currentCurrency,\n );\n\n this.messenger.subscribe(\n 'MultichainAssetsController:accountAssetListUpdated',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async ({ assets }) => {\n const newAccountAssets = Object.entries(assets).map(\n ([accountId, { added }]) => ({\n accountId,\n assets: [...added],\n }),\n );\n // TODO; removed can be used in future for further cleanup\n await this.#updateAssetsRatesForNewAssets(newAccountAssets);\n },\n );\n }\n\n /**\n * Executes a poll by updating token conversion rates for the current account.\n *\n * @returns A promise that resolves when the polling completes.\n */\n async _executePoll(): Promise<void> {\n await this.updateAssetsRates();\n }\n\n /**\n * Determines whether the controller is active.\n *\n * @returns True if the keyring is unlocked; otherwise, false.\n */\n get isActive(): boolean {\n return this.#isUnlocked;\n }\n\n /**\n * Checks if an account is a non-EVM account with a Snap.\n *\n * @param account - The account to check.\n * @returns True if the account is non-EVM and has Snap metadata; otherwise, false.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) && account.metadata.snap !== undefined\n );\n }\n\n /**\n * Retrieves all multichain accounts from the AccountsController.\n *\n * @returns An array of internal accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messenger.call('AccountsController:listMultichainAccounts');\n }\n\n /**\n * Filters and returns non-EVM accounts that should have balances.\n *\n * @returns An array of non-EVM internal accounts.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Adds the assets to a map of Snap ID to assets.\n *\n * @param snapIdToAssets - The map of Snap ID to assets.\n * @param account - The account to add the assets for.\n * @param assets - The assets to add.\n */\n #addAssetsToSnapIdMap(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n account: InternalAccount,\n assets: CaipAssetType[],\n ): void {\n // Prevent creating a new set if there are no assets to add.\n if (assets.length === 0) {\n return;\n }\n\n // FIXME: Instead of using the Snap ID from the account, we should\n // select the Snap based on the supported scopes defined in the Snaps'\n // manifest.\n const snapId = account.metadata.snap?.id as SnapId | undefined;\n if (!snapId) {\n return;\n }\n\n let snapAssets = snapIdToAssets.get(snapId);\n if (!snapAssets) {\n snapAssets = new Set();\n snapIdToAssets.set(snapId, snapAssets);\n }\n\n for (const asset of assets) {\n snapAssets.add(asset);\n }\n }\n\n /**\n * Updates token conversion rates for each non-EVM account.\n *\n * @returns A promise that resolves when the rates are updated.\n */\n async updateAssetsRates(): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n return (async (): Promise<void> => {\n if (!this.isActive) {\n return;\n }\n\n // Compute the set of unique assets from all accounts. It's important to\n // deduplicate assets here to avoid duplicate requests to the Snap.\n const accounts = this.#listAccounts();\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n for (const account of accounts) {\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n account,\n this.#getAssetsForAccount(account.id),\n );\n }\n\n this.#applyUpdatedRates(await this.#getUpdatedRatesFor(snapIdToAssets));\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Returns the CAIP-19 asset type for the current selected currency. Defaults\n * to USD if the current selected currency is not supported.\n *\n * @returns The CAIP-19 asset type for the current selected currency.\n */\n #getCaipCurrentCurrency(): CaipAssetType {\n return (\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd\n );\n }\n\n /**\n * Fetches the conversion rates for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the conversion rates for.\n * @param currency - The currency to fetch the conversion rates for.\n * @returns A record of CAIP-19 asset types to conversion rates.\n */\n async #getConversionRates(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, AssetConversion | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsConversion,\n params: {\n conversions: Array.from(assets).map((asset) => ({\n from: asset,\n to: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToConversionRate: Record<\n CaipAssetType,\n AssetConversion | undefined\n > = {};\n\n for (const asset of assets) {\n assetToConversionRate[asset] =\n response.conversionRates?.[asset]?.[currency] ?? undefined;\n }\n\n return assetToConversionRate;\n }\n\n /**\n * Fetches the market data for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the market data for.\n * @param currency - The currency to fetch the market data for.\n * @returns A record of CAIP-19 asset types to market data.\n */\n async #getMarketData(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, FungibleAssetMarketData | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsMarketData,\n params: {\n assets: Array.from(assets).map((asset) => ({\n asset,\n unit: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToMarketData: Record<\n CaipAssetType,\n FungibleAssetMarketData | undefined\n > = {};\n\n for (const asset of assets) {\n const assetMarketData = response.marketData?.[asset]?.[currency];\n\n // We do not consider NFTs here, so `fungible` must be `true`.\n if (assetMarketData?.fungible) {\n assetToMarketData[asset] = assetMarketData;\n } else {\n assetToMarketData[asset] = undefined;\n }\n }\n\n return assetToMarketData;\n }\n\n /**\n * Fetches the updated rates for the given assets from the given Snaps.\n *\n * @param snapIdToAssets - A map of Snap ID to CAIP-19 asset types.\n * @returns A record of CAIP-19 asset types to unified asset conversions.\n */\n async #getUpdatedRatesFor(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n ): Promise<\n Record<CaipAssetType, UnifiedAssetConversion & { currency: CaipAssetType }>\n > {\n const updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n > = {};\n\n // Keep a local copy to ensure that the currency is always the same for the\n // entire loop.\n const currency = this.#getCaipCurrentCurrency();\n\n // Note: Since the assets come from a 1-to-1 mapping with Snap IDs, we know\n // that a given asset will not appear under multiple Snap IDs.\n for (const [snapId, assets] of snapIdToAssets.entries()) {\n const [rates, marketData] = await Promise.all([\n this.#getConversionRates(snapId, assets, currency),\n this.#getMarketData(snapId, assets, currency),\n ]);\n\n for (const asset of assets) {\n const assetRate = rates[asset];\n const assetMarketData = marketData[asset];\n\n // Rates are mandatory, so skip the asset if not available.\n if (!assetRate) {\n continue;\n }\n\n updatedRates[asset] = {\n currency,\n ...assetRate,\n ...(assetMarketData && { marketData: assetMarketData }),\n };\n }\n }\n\n return updatedRates;\n }\n\n /**\n * Fetches historical prices for the current account\n *\n * @param asset - The asset to fetch historical prices for.\n * @param account - optional account to fetch historical prices for\n * @returns The historical prices.\n */\n async fetchHistoricalPricesForAsset(\n asset: CaipAssetType,\n account?: InternalAccount,\n ): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n return (async () => {\n const currentCaipCurrency =\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd;\n // Check if we already have historical prices for this asset and currency\n const historicalPriceExpirationTime =\n this.state.historicalPrices[asset]?.[this.#currentCurrency]\n ?.expirationTime;\n\n const historicalPriceHasExpired =\n historicalPriceExpirationTime &&\n historicalPriceExpirationTime < Date.now();\n\n if (historicalPriceHasExpired === false) {\n return;\n }\n\n const selectedAccount =\n account ??\n this.messenger.call('AccountsController:getSelectedMultichainAccount');\n try {\n const historicalPricesResponse = await this.messenger.call(\n 'SnapController:handleRequest',\n {\n snapId: selectedAccount?.metadata.snap?.id as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnAssetHistoricalPrice,\n request: {\n jsonrpc: '2.0',\n method: HandlerType.OnAssetHistoricalPrice,\n params: {\n from: asset,\n to: currentCaipCurrency,\n },\n },\n },\n );\n\n // skip state update if no historical prices are returned\n if (!historicalPricesResponse) {\n return;\n }\n\n this.update((state) => {\n state.historicalPrices = {\n ...state.historicalPrices,\n [asset]: {\n ...state.historicalPrices[asset],\n [this.#currentCurrency]: (\n historicalPricesResponse as OnAssetHistoricalPriceResponse\n )?.historicalPrice,\n },\n };\n });\n } catch {\n throw new Error(\n `Failed to fetch historical prices for asset: ${asset}`,\n );\n }\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Updates the conversion rates for new assets.\n *\n * @param accounts - The accounts to update the conversion rates for.\n * @returns A promise that resolves when the rates are updated.\n */\n async #updateAssetsRatesForNewAssets(\n accounts: {\n accountId: string;\n assets: CaipAssetType[];\n }[],\n ): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n return (async () => {\n if (!this.isActive) {\n return;\n }\n\n // First build a map containing all assets that need to be updated per\n // Snap ID, this will be used to batch the requests.\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n\n for (const { accountId, assets } of accounts) {\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n this.#getAccount(accountId),\n assets,\n );\n }\n\n this.#applyUpdatedRates(await this.#getUpdatedRatesFor(snapIdToAssets));\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined = this.#listAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n\n return account;\n }\n\n /**\n * Returns the array of CAIP-19 assets for the given account ID.\n * If none are found, returns an empty array.\n *\n * @param accountId - The account ID to get the assets for.\n * @returns An array of CAIP-19 assets.\n */\n #getAssetsForAccount(accountId: string): CaipAssetType[] {\n // Always fetch fresh state - MultichainAssetsController uses Immer which creates\n // new object references on every update, so caching would become stale.\n const { accountsAssets } = this.messenger.call(\n 'MultichainAssetsController:getState',\n );\n return accountsAssets?.[accountId] ?? [];\n }\n\n /**\n * Merges the new rates into the controller's state.\n *\n * @param updatedRates - The new rates to merge.\n */\n #applyUpdatedRates(\n updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n >,\n ): void {\n if (Object.keys(updatedRates).length === 0) {\n return;\n }\n this.update((state: Draft<MultichainAssetsRatesControllerState>) => {\n state.conversionRates = {\n ...state.conversionRates,\n ...updatedRates,\n };\n });\n }\n\n /**\n * Forwards a Snap request to the SnapController.\n *\n * @param args - The request parameters.\n * @param args.snapId - The ID of the Snap.\n * @param args.handler - The handler type.\n * @param args.params - The asset conversions.\n * @returns A promise that resolves with the account rates.\n */\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsConversionArguments>,\n ): Promise<OnAssetsConversionResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetHistoricalPriceArguments>,\n ): Promise<OnAssetHistoricalPriceResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsMarketDataArguments>,\n ): Promise<OnAssetsMarketDataResponse | undefined>;\n\n async #handleSnapRequest(args: SnapRequestArgs<unknown>): Promise<unknown> {\n const { snapId, handler, params } = args;\n try {\n return await this.messenger.call('SnapController:handleRequest', {\n snapId,\n origin: 'metamask',\n handler,\n request: {\n jsonrpc: '2.0',\n method: handler,\n params,\n },\n });\n } catch (error) {\n console.error(`Snap request failed for ${handler}:`, {\n snapId,\n handler,\n message: (error as Error).message,\n params,\n });\n return undefined;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"MultichainAssetsRatesController.mjs","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAUA,OAAO,EAAE,gBAAgB,EAAE,8BAA8B;AAQzD,OAAO,EAAE,+BAA+B,EAAE,qCAAqC;AAc/E,OAAO,EAAE,WAAW,EAAE,8BAA8B;AACpD,OAAO,EAAE,KAAK,EAAE,oBAAoB;AAGpC,OAAO,EAAE,mBAAmB,EAAE,uBAAmB;AAWjD;;GAEG;AACH,MAAM,cAAc,GAAG,iCAAiC,CAAC;AAwCzD;;;;;;;GAOG;AACH,MAAM,UAAU,8CAA8C;IAC5D,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC;AACvD,CAAC;AA2DD,MAAM,QAAQ,GAAwD;IACpE,eAAe,EAAE;QACf,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,QAAQ,EAAE,IAAI;KACf;IACD,gBAAgB,EAAE;QAChB,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,sBAAsB,EAAE,IAAI;QAC5B,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAkBF;;;;GAIG;AACH,MAAM,OAAO,+BAAgC,SAAQ,+BAA+B,EAInF;IAOC;;;;;;;OAOG;IACH,YAAY,EACV,QAAQ,GAAG,KAAK,EAChB,KAAK,GAAG,EAAE,EACV,SAAS,GAKV;;QACC,KAAK,CAAC;YACJ,IAAI,EAAE,cAAc;YACpB,SAAS;YACT,KAAK,EAAE;gBACL,GAAG,8CAA8C,EAAE;gBACnD,GAAG,KAAK;aACT;YACD,QAAQ;SACT,CAAC,CAAC;;QA/BI,iDAAS,IAAI,KAAK,EAAE,EAAC;QAE9B,mEAAuD;QAEvD,sDAAc,IAAI,EAAC;QA6BjB,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAEjC,2CAA2C;QAC3C,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,wBAAwB,EAAE,GAAG,EAAE;YACtD,uBAAA,IAAI,+CAAe,KAAK,MAAA,CAAC;QAC3B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,0BAA0B,EAAE,GAAG,EAAE;YACxD,uBAAA,IAAI,+CAAe,IAAI,MAAA,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,MAAoB,IAAI,EAAvB,EAAE,eAAe,sHAAuB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC/D,iCAAiC,CAClC,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,oCAAoC;QACpC,kEAAkE;QAClE,KAAK,EAAE,eAAuB,EAAE,EAAE;YAChC,uBAAA,IAAI,oDAAoB,eAAe,MAAA,CAAC;YACxC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACjC,CAAC,EACD,CAAC,2BAA2B,EAAE,EAAE,CAC9B,2BAA2B,CAAC,eAAe,CAC9C,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,oDAAoD;QACpD,kEAAkE;QAClE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;YACnB,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CACjD,CAAC,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC3B,SAAS;gBACT,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC;aACnB,CAAC,CACH,CAAC;YACF,0DAA0D;YAC1D,MAAM,uBAAA,IAAI,kHAA+B,MAAnC,IAAI,EAAgC,gBAAgB,CAAC,CAAC;QAC9D,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ;QACV,OAAO,uBAAA,IAAI,mDAAY,CAAC;IAC1B,CAAC;IAqED;;;;OAIG;IACH,KAAK,CAAC,iBAAiB;QACrB,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,8CAAO,CAAC,OAAO,EAAE,CAAC;QAEhD,OAAO,CAAC,KAAK,IAAmB,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,wEAAwE;YACxE,mEAAmE;YACnE,MAAM,QAAQ,GAAG,uBAAA,IAAI,iGAAc,MAAlB,IAAI,CAAgB,CAAC;YACtC,MAAM,cAAc,GAAG,IAAI,GAAG,EAA8B,CAAC;YAC7D,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,uBAAA,IAAI,yGAAsB,MAA1B,IAAI,EACF,cAAc,EACd,OAAO,EACP,uBAAA,IAAI,wGAAqB,MAAzB,IAAI,EAAsB,OAAO,CAAC,EAAE,CAAC,CACtC,CAAC;YACJ,CAAC;YAED,uBAAA,IAAI,sGAAmB,MAAvB,IAAI,EAAoB,MAAM,uBAAA,IAAI,uGAAoB,MAAxB,IAAI,EAAqB,cAAc,CAAC,CAAC,CAAC;QAC1E,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAChB,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;IA0JD;;;;;;OAMG;IACH,KAAK,CAAC,6BAA6B,CACjC,KAAoB,EACpB,OAAyB;QAEzB,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,8CAAO,CAAC,OAAO,EAAE,CAAC;QAChD,OAAO,CAAC,KAAK,IAAI,EAAE;YACjB,MAAM,mBAAmB,GACvB,mBAAmB,CAAC,uBAAA,IAAI,wDAAiB,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC;YACxE,yEAAyE;YACzE,MAAM,6BAA6B,GACjC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,uBAAA,IAAI,wDAAiB,CAAC;gBACzD,EAAE,cAAc,CAAC;YAErB,MAAM,yBAAyB,GAC7B,6BAA6B;gBAC7B,6BAA6B,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE7C,IAAI,yBAAyB,KAAK,KAAK,EAAE,CAAC;gBACxC,OAAO;YACT,CAAC;YAED,MAAM,eAAe,GACnB,OAAO;gBACP,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;YACzE,IAAI,CAAC;gBACH,MAAM,wBAAwB,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACxD,8BAA8B,EAC9B;oBACE,MAAM,EAAE,eAAe,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAY;oBACpD,MAAM,EAAE,UAAU;oBAClB,OAAO,EAAE,WAAW,CAAC,sBAAsB;oBAC3C,OAAO,EAAE;wBACP,OAAO,EAAE,KAAK;wBACd,MAAM,EAAE,WAAW,CAAC,sBAAsB;wBAC1C,MAAM,EAAE;4BACN,IAAI,EAAE,KAAK;4BACX,EAAE,EAAE,mBAAmB;yBACxB;qBACF;iBACF,CACF,CAAC;gBAEF,yDAAyD;gBACzD,IAAI,CAAC,wBAAwB,EAAE,CAAC;oBAC9B,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBACpB,KAAK,CAAC,gBAAgB,GAAG;wBACvB,GAAG,KAAK,CAAC,gBAAgB;wBACzB,CAAC,KAAK,CAAC,EAAE;4BACP,GAAG,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC;4BAChC,CAAC,uBAAA,IAAI,wDAAiB,CAAC,EACrB,wBACD,EAAE,eAAe;yBACnB;qBACF,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CACb,gDAAgD,KAAK,EAAE,CACxD,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAChB,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;CA2IF;gWAxckB,OAAwB;IACvC,OAAO,CACL,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,CACvE,CAAC;AACJ,CAAC;IAQC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;AAC1E,CAAC;IAQC,MAAM,QAAQ,GAAG,uBAAA,IAAI,2GAAwB,MAA5B,IAAI,CAA0B,CAAC;IAChD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAA,IAAI,oGAAiB,MAArB,IAAI,EAAkB,OAAO,CAAC,CAAC,CAAC;AACtE,CAAC,yHAUC,cAA+C,EAC/C,OAAwB,EACxB,MAAuB;IAEvB,4DAA4D;IAC5D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IAED,kEAAkE;IAClE,sEAAsE;IACtE,YAAY;IACZ,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAwB,CAAC;IAC/D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,IAAI,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,UAAU,GAAG,IAAI,GAAG,EAAE,CAAC;QACvB,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;IAwCC,OAAO,CACL,mBAAmB,CAAC,uBAAA,IAAI,wDAAiB,CAAC,IAAI,mBAAmB,CAAC,GAAG,CACtE,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,8DACH,MAAc,EACd,MAA0B,EAC1B,QAAuB;IAEvB,8DAA8D;IAC9D,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,uBAAA,IAAI,sGAAmB,MAAvB,IAAI,EAAoB;QAC7C,MAAM;QACN,OAAO,EAAE,WAAW,CAAC,kBAAkB;QACvC,MAAM,EAAE;YACN,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC9C,IAAI,EAAE,KAAK;gBACX,EAAE,EAAE,QAAQ;aACb,CAAC,CAAC;SACJ;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,qBAAqB,GAGvB,EAAE,CAAC;IAEP,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,qBAAqB,CAAC,KAAK,CAAC;YAC1B,QAAQ,CAAC,eAAe,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;IAC/D,CAAC;IAED,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,yDACH,MAAc,EACd,MAA0B,EAC1B,QAAuB;IAEvB,8DAA8D;IAC9D,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,uBAAA,IAAI,sGAAmB,MAAvB,IAAI,EAAoB;QAC7C,MAAM;QACN,OAAO,EAAE,WAAW,CAAC,kBAAkB;QACvC,MAAM,EAAE;YACN,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACzC,KAAK;gBACL,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;SACJ;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,iBAAiB,GAGnB,EAAE,CAAC;IAEP,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,iBAAiB,CAAC,KAAK,CAAC;YACtB,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;IAC1D,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,KAAK,8DACH,cAA+C;IAI/C,MAAM,YAAY,GAGd,EAAE,CAAC;IAEP,2EAA2E;IAC3E,eAAe;IACf,MAAM,QAAQ,GAAG,uBAAA,IAAI,2GAAwB,MAA5B,IAAI,CAA0B,CAAC;IAEhD,2EAA2E;IAC3E,8DAA8D;IAC9D,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC;QACxD,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC5C,uBAAA,IAAI,uGAAoB,MAAxB,IAAI,EAAqB,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC;YAClD,uBAAA,IAAI,kGAAe,MAAnB,IAAI,EAAgB,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC;SAC9C,CAAC,CAAC;QAEH,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/B,MAAM,eAAe,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YAE1C,2DAA2D;YAC3D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,SAAS;YACX,CAAC;YAED,YAAY,CAAC,KAAK,CAAC,GAAG;gBACpB,QAAQ;gBACR,GAAG,SAAS;gBACZ,GAAG,CAAC,eAAe,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;aACxD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AA6ED;;;;;GAKG;AACH,KAAK,yEACH,QAGG;IAEH,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,8CAAO,CAAC,OAAO,EAAE,CAAC;IAEhD,OAAO,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,sEAAsE;QACtE,oDAAoD;QACpD,MAAM,cAAc,GAAG,IAAI,GAAG,EAA8B,CAAC;QAE7D,KAAK,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC7C,uBAAA,IAAI,yGAAsB,MAA1B,IAAI,EACF,cAAc,EACd,uBAAA,IAAI,+FAAY,MAAhB,IAAI,EAAa,SAAS,CAAC,EAC3B,MAAM,CACP,CAAC;QACJ,CAAC;QAED,uBAAA,IAAI,sGAAmB,MAAvB,IAAI,EAAoB,MAAM,uBAAA,IAAI,uGAAoB,MAAxB,IAAI,EAAqB,cAAc,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;QAChB,WAAW,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,qGAQW,SAAiB;IAC3B,MAAM,OAAO,GAAgC,uBAAA,IAAI,iGAAc,MAAlB,IAAI,CAAgB,CAAC,IAAI,CACpE,CAAC,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,KAAK,SAAS,CAC1D,CAAC;IAEF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,uHASoB,SAAiB;IACpC,iFAAiF;IACjF,wEAAwE;IACxE,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC5C,qCAAqC,CACtC,CAAC;IACF,OAAO,cAAc,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AAC3C,CAAC,mHAQC,YAGC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3C,OAAO;IACT,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAkD,EAAE,EAAE;QACjE,KAAK,CAAC,eAAe,GAAG;YACtB,GAAG,KAAK,CAAC,eAAe;YACxB,GAAG,YAAY;SAChB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,uDAuBD,KAAK,6DAAoB,IAA8B;IACrD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACzC,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,8BAA8B,EAAE;YAC/D,MAAM;YACN,MAAM,EAAE,UAAU;YAClB,OAAO;YACP,OAAO,EAAE;gBACP,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,OAAO;gBACf,MAAM;aACP;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,OAAO,GAAG,EAAE;YACnD,MAAM;YACN,OAAO;YACP,OAAO,EAAG,KAAe,CAAC,OAAO;YACjC,MAAM;SACP,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC","sourcesContent":["import type {\n AccountsControllerListMultichainAccountsAction,\n AccountsControllerAccountAddedEvent,\n AccountsControllerGetSelectedMultichainAccountAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { CaipAssetType } from '@metamask/keyring-api';\nimport type {\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type {\n SnapId,\n AssetConversion,\n OnAssetsConversionArguments,\n OnAssetHistoricalPriceArguments,\n OnAssetHistoricalPriceResponse,\n HistoricalPriceIntervals,\n OnAssetsMarketDataArguments,\n OnAssetsMarketDataResponse,\n FungibleAssetMarketData,\n OnAssetsConversionResponse,\n} from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport { MAP_CAIP_CURRENCIES } from './constant';\nimport type {\n CurrencyRateState,\n CurrencyRateStateChange,\n GetCurrencyRateState,\n} from '../CurrencyRateController';\nimport type {\n MultichainAssetsControllerGetStateAction,\n MultichainAssetsControllerAccountAssetListUpdatedEvent,\n} from '../MultichainAssetsController';\n\n/**\n * The name of the MultichainAssetsRatesController.\n */\nconst controllerName = 'MultichainAssetsRatesController';\n\n// This is temporary until its exported from snap\ntype HistoricalPrice = {\n intervals: HistoricalPriceIntervals;\n // The UNIX timestamp of when the historical price was last updated.\n updateTime: number;\n // The UNIX timestamp of when the historical price will expire.\n expirationTime?: number;\n};\n\n/**\n * State used by the MultichainAssetsRatesController to cache token conversion rates.\n */\nexport type MultichainAssetsRatesControllerState = {\n conversionRates: Record<CaipAssetType, UnifiedAssetConversion>;\n historicalPrices: Record<CaipAssetType, Record<string, HistoricalPrice>>; // string being the current currency we fetched historical prices for\n};\n\n/**\n * Returns the state of the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\n/**\n * Action to update the rates of all supported tokens.\n */\nexport type MultichainAssetsRatesControllerUpdateRatesAction = {\n type: `${typeof controllerName}:updateAssetsRates`;\n handler: MultichainAssetsRatesController['updateAssetsRates'];\n};\n\ntype UnifiedAssetConversion = AssetConversion & {\n marketData?: FungibleAssetMarketData;\n};\n\n/**\n * Constructs the default {@link MultichainAssetsRatesController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link MultichainAssetsRatesController} state.\n */\nexport function getDefaultMultichainAssetsRatesControllerState(): MultichainAssetsRatesControllerState {\n return { conversionRates: {}, historicalPrices: {} };\n}\n\n/**\n * Event emitted when the state of the MultichainAssetsRatesController changes.\n */\nexport type MultichainAssetsRatesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\n/**\n * Actions exposed by the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerActions =\n | MultichainAssetsRatesControllerGetStateAction\n | MultichainAssetsRatesControllerUpdateRatesAction;\n\n/**\n * Events emitted by MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerEvents =\n MultichainAssetsRatesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction\n | GetCurrencyRateState\n | MultichainAssetsControllerGetStateAction\n | AccountsControllerGetSelectedMultichainAccountAction;\n\n/**\n * Events that this controller is allowed to subscribe to.\n */\nexport type AllowedEvents =\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | AccountsControllerAccountAddedEvent\n | CurrencyRateStateChange\n | MultichainAssetsControllerAccountAssetListUpdatedEvent;\n/**\n * Messenger type for the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerMessenger = Messenger<\n typeof controllerName,\n MultichainAssetsRatesControllerActions | AllowedActions,\n MultichainAssetsRatesControllerEvents | AllowedEvents\n>;\n\n/**\n * The input for starting polling in MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesPollingInput = {\n accountId: string;\n};\n\nconst metadata: StateMetadata<MultichainAssetsRatesControllerState> = {\n conversionRates: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n historicalPrices: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n};\n\nexport type ConversionRatesWithMarketData = {\n conversionRates: Record<\n CaipAssetType,\n Record<CaipAssetType, UnifiedAssetConversion | null>\n >;\n};\n\n/**\n * Arguments for a Snap request.\n */\ntype SnapRequestArgs<T> = {\n snapId: SnapId;\n handler: HandlerType;\n params: T;\n};\n\n/**\n * Controller that manages multichain token conversion rates.\n *\n * This controller polls for token conversion rates and updates its state.\n */\nexport class MultichainAssetsRatesController extends StaticIntervalPollingController<MultichainAssetsRatesPollingInput>()<\n typeof controllerName,\n MultichainAssetsRatesControllerState,\n MultichainAssetsRatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n #currentCurrency: CurrencyRateState['currentCurrency'];\n\n #isUnlocked = true;\n\n /**\n * Creates an instance of MultichainAssetsRatesController.\n *\n * @param options - Constructor options.\n * @param options.interval - The polling interval in milliseconds.\n * @param options.state - The initial state.\n * @param options.messenger - A reference to the messenger.\n */\n constructor({\n interval = 18000,\n state = {},\n messenger,\n }: {\n interval?: number;\n state?: Partial<MultichainAssetsRatesControllerState>;\n messenger: MultichainAssetsRatesControllerMessenger;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {\n ...getDefaultMultichainAssetsRatesControllerState(),\n ...state,\n },\n metadata,\n });\n\n this.setIntervalLength(interval);\n\n // Subscribe to keyring lock/unlock events.\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n ({ currentCurrency: this.#currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n ));\n\n this.messenger.subscribe(\n 'CurrencyRateController:stateChange',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (currentCurrency: string) => {\n this.#currentCurrency = currentCurrency;\n await this.updateAssetsRates();\n },\n (currencyRateControllerState) =>\n currencyRateControllerState.currentCurrency,\n );\n\n this.messenger.subscribe(\n 'MultichainAssetsController:accountAssetListUpdated',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async ({ assets }) => {\n const newAccountAssets = Object.entries(assets).map(\n ([accountId, { added }]) => ({\n accountId,\n assets: [...added],\n }),\n );\n // TODO; removed can be used in future for further cleanup\n await this.#updateAssetsRatesForNewAssets(newAccountAssets);\n },\n );\n }\n\n /**\n * Executes a poll by updating token conversion rates for the current account.\n *\n * @returns A promise that resolves when the polling completes.\n */\n async _executePoll(): Promise<void> {\n await this.updateAssetsRates();\n }\n\n /**\n * Determines whether the controller is active.\n *\n * @returns True if the keyring is unlocked; otherwise, false.\n */\n get isActive(): boolean {\n return this.#isUnlocked;\n }\n\n /**\n * Checks if an account is a non-EVM account with a Snap.\n *\n * @param account - The account to check.\n * @returns True if the account is non-EVM and has Snap metadata; otherwise, false.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) && account.metadata.snap !== undefined\n );\n }\n\n /**\n * Retrieves all multichain accounts from the AccountsController.\n *\n * @returns An array of internal accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messenger.call('AccountsController:listMultichainAccounts');\n }\n\n /**\n * Filters and returns non-EVM accounts that should have balances.\n *\n * @returns An array of non-EVM internal accounts.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Adds the assets to a map of Snap ID to assets.\n *\n * @param snapIdToAssets - The map of Snap ID to assets.\n * @param account - The account to add the assets for.\n * @param assets - The assets to add.\n */\n #addAssetsToSnapIdMap(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n account: InternalAccount,\n assets: CaipAssetType[],\n ): void {\n // Prevent creating a new set if there are no assets to add.\n if (assets.length === 0) {\n return;\n }\n\n // FIXME: Instead of using the Snap ID from the account, we should\n // select the Snap based on the supported scopes defined in the Snaps'\n // manifest.\n const snapId = account.metadata.snap?.id as SnapId | undefined;\n if (!snapId) {\n return;\n }\n\n let snapAssets = snapIdToAssets.get(snapId);\n if (!snapAssets) {\n snapAssets = new Set();\n snapIdToAssets.set(snapId, snapAssets);\n }\n\n for (const asset of assets) {\n snapAssets.add(asset);\n }\n }\n\n /**\n * Updates token conversion rates for each non-EVM account.\n *\n * @returns A promise that resolves when the rates are updated.\n */\n async updateAssetsRates(): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n return (async (): Promise<void> => {\n if (!this.isActive) {\n return;\n }\n\n // Compute the set of unique assets from all accounts. It's important to\n // deduplicate assets here to avoid duplicate requests to the Snap.\n const accounts = this.#listAccounts();\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n for (const account of accounts) {\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n account,\n this.#getAssetsForAccount(account.id),\n );\n }\n\n this.#applyUpdatedRates(await this.#getUpdatedRatesFor(snapIdToAssets));\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Returns the CAIP-19 asset type for the current selected currency. Defaults\n * to USD if the current selected currency is not supported.\n *\n * @returns The CAIP-19 asset type for the current selected currency.\n */\n #getCaipCurrentCurrency(): CaipAssetType {\n return (\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd\n );\n }\n\n /**\n * Fetches the conversion rates for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the conversion rates for.\n * @param currency - The currency to fetch the conversion rates for.\n * @returns A record of CAIP-19 asset types to conversion rates.\n */\n async #getConversionRates(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, AssetConversion | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsConversion,\n params: {\n conversions: Array.from(assets).map((asset) => ({\n from: asset,\n to: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToConversionRate: Record<\n CaipAssetType,\n AssetConversion | undefined\n > = {};\n\n for (const asset of assets) {\n assetToConversionRate[asset] =\n response.conversionRates?.[asset]?.[currency] ?? undefined;\n }\n\n return assetToConversionRate;\n }\n\n /**\n * Fetches the market data for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the market data for.\n * @param currency - The currency to fetch the market data for.\n * @returns A record of CAIP-19 asset types to market data.\n */\n async #getMarketData(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, FungibleAssetMarketData | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsMarketData,\n params: {\n assets: Array.from(assets).map((asset) => ({\n asset,\n unit: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToMarketData: Record<\n CaipAssetType,\n FungibleAssetMarketData | undefined\n > = {};\n\n for (const asset of assets) {\n assetToMarketData[asset] =\n response.marketData?.[asset]?.[currency] ?? undefined;\n }\n\n return assetToMarketData;\n }\n\n /**\n * Fetches the updated rates for the given assets from the given Snaps.\n *\n * @param snapIdToAssets - A map of Snap ID to CAIP-19 asset types.\n * @returns A record of CAIP-19 asset types to unified asset conversions.\n */\n async #getUpdatedRatesFor(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n ): Promise<\n Record<CaipAssetType, UnifiedAssetConversion & { currency: CaipAssetType }>\n > {\n const updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n > = {};\n\n // Keep a local copy to ensure that the currency is always the same for the\n // entire loop.\n const currency = this.#getCaipCurrentCurrency();\n\n // Note: Since the assets come from a 1-to-1 mapping with Snap IDs, we know\n // that a given asset will not appear under multiple Snap IDs.\n for (const [snapId, assets] of snapIdToAssets.entries()) {\n const [rates, marketData] = await Promise.all([\n this.#getConversionRates(snapId, assets, currency),\n this.#getMarketData(snapId, assets, currency),\n ]);\n\n for (const asset of assets) {\n const assetRate = rates[asset];\n const assetMarketData = marketData[asset];\n\n // Rates are mandatory, so skip the asset if not available.\n if (!assetRate) {\n continue;\n }\n\n updatedRates[asset] = {\n currency,\n ...assetRate,\n ...(assetMarketData && { marketData: assetMarketData }),\n };\n }\n }\n\n return updatedRates;\n }\n\n /**\n * Fetches historical prices for the current account\n *\n * @param asset - The asset to fetch historical prices for.\n * @param account - optional account to fetch historical prices for\n * @returns The historical prices.\n */\n async fetchHistoricalPricesForAsset(\n asset: CaipAssetType,\n account?: InternalAccount,\n ): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n return (async () => {\n const currentCaipCurrency =\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd;\n // Check if we already have historical prices for this asset and currency\n const historicalPriceExpirationTime =\n this.state.historicalPrices[asset]?.[this.#currentCurrency]\n ?.expirationTime;\n\n const historicalPriceHasExpired =\n historicalPriceExpirationTime &&\n historicalPriceExpirationTime < Date.now();\n\n if (historicalPriceHasExpired === false) {\n return;\n }\n\n const selectedAccount =\n account ??\n this.messenger.call('AccountsController:getSelectedMultichainAccount');\n try {\n const historicalPricesResponse = await this.messenger.call(\n 'SnapController:handleRequest',\n {\n snapId: selectedAccount?.metadata.snap?.id as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnAssetHistoricalPrice,\n request: {\n jsonrpc: '2.0',\n method: HandlerType.OnAssetHistoricalPrice,\n params: {\n from: asset,\n to: currentCaipCurrency,\n },\n },\n },\n );\n\n // skip state update if no historical prices are returned\n if (!historicalPricesResponse) {\n return;\n }\n\n this.update((state) => {\n state.historicalPrices = {\n ...state.historicalPrices,\n [asset]: {\n ...state.historicalPrices[asset],\n [this.#currentCurrency]: (\n historicalPricesResponse as OnAssetHistoricalPriceResponse\n )?.historicalPrice,\n },\n };\n });\n } catch {\n throw new Error(\n `Failed to fetch historical prices for asset: ${asset}`,\n );\n }\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Updates the conversion rates for new assets.\n *\n * @param accounts - The accounts to update the conversion rates for.\n * @returns A promise that resolves when the rates are updated.\n */\n async #updateAssetsRatesForNewAssets(\n accounts: {\n accountId: string;\n assets: CaipAssetType[];\n }[],\n ): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n return (async () => {\n if (!this.isActive) {\n return;\n }\n\n // First build a map containing all assets that need to be updated per\n // Snap ID, this will be used to batch the requests.\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n\n for (const { accountId, assets } of accounts) {\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n this.#getAccount(accountId),\n assets,\n );\n }\n\n this.#applyUpdatedRates(await this.#getUpdatedRatesFor(snapIdToAssets));\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined = this.#listAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n\n return account;\n }\n\n /**\n * Returns the array of CAIP-19 assets for the given account ID.\n * If none are found, returns an empty array.\n *\n * @param accountId - The account ID to get the assets for.\n * @returns An array of CAIP-19 assets.\n */\n #getAssetsForAccount(accountId: string): CaipAssetType[] {\n // Always fetch fresh state - MultichainAssetsController uses Immer which creates\n // new object references on every update, so caching would become stale.\n const { accountsAssets } = this.messenger.call(\n 'MultichainAssetsController:getState',\n );\n return accountsAssets?.[accountId] ?? [];\n }\n\n /**\n * Merges the new rates into the controller's state.\n *\n * @param updatedRates - The new rates to merge.\n */\n #applyUpdatedRates(\n updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n >,\n ): void {\n if (Object.keys(updatedRates).length === 0) {\n return;\n }\n this.update((state: Draft<MultichainAssetsRatesControllerState>) => {\n state.conversionRates = {\n ...state.conversionRates,\n ...updatedRates,\n };\n });\n }\n\n /**\n * Forwards a Snap request to the SnapController.\n *\n * @param args - The request parameters.\n * @param args.snapId - The ID of the Snap.\n * @param args.handler - The handler type.\n * @param args.params - The asset conversions.\n * @returns A promise that resolves with the account rates.\n */\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsConversionArguments>,\n ): Promise<OnAssetsConversionResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetHistoricalPriceArguments>,\n ): Promise<OnAssetHistoricalPriceResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsMarketDataArguments>,\n ): Promise<OnAssetsMarketDataResponse | undefined>;\n\n async #handleSnapRequest(args: SnapRequestArgs<unknown>): Promise<unknown> {\n const { snapId, handler, params } = args;\n try {\n return await this.messenger.call('SnapController:handleRequest', {\n snapId,\n origin: 'metamask',\n handler,\n request: {\n jsonrpc: '2.0',\n method: handler,\n params,\n },\n });\n } catch (error) {\n console.error(`Snap request failed for ${handler}:`, {\n snapId,\n handler,\n message: (error as Error).message,\n params,\n });\n return undefined;\n }\n }\n}\n"]}
@@ -84,8 +84,8 @@ export declare const parseAssetType: (assetType: string) => [
84
84
  boolean
85
85
  ] | null;
86
86
  declare const TokenBalancesController_base: (abstract new (...args: any[]) => {
87
- readonly "__#14@#intervalIds": Record<string, NodeJS.Timeout>;
88
- "__#14@#intervalLength": number | undefined;
87
+ readonly "__#15@#intervalIds": Record<string, NodeJS.Timeout>;
88
+ "__#15@#intervalLength": number | undefined;
89
89
  setIntervalLength(intervalLength: number): void;
90
90
  getIntervalLength(): number | undefined;
91
91
  _startPolling(input: {
@@ -84,8 +84,8 @@ export declare const parseAssetType: (assetType: string) => [
84
84
  boolean
85
85
  ] | null;
86
86
  declare const TokenBalancesController_base: (abstract new (...args: any[]) => {
87
- readonly "__#14@#intervalIds": Record<string, NodeJS.Timeout>;
88
- "__#14@#intervalLength": number | undefined;
87
+ readonly "__#15@#intervalIds": Record<string, NodeJS.Timeout>;
88
+ "__#15@#intervalLength": number | undefined;
89
89
  setIntervalLength(intervalLength: number): void;
90
90
  getIntervalLength(): number | undefined;
91
91
  _startPolling(input: {
@@ -233,7 +233,7 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
233
233
  console.warn(`Token metadata not found in cache for ${tokenAddress} on chain ${chainId}`);
234
234
  continue;
235
235
  }
236
- const { decimals, symbol, aggregators, iconUrl, name, rwaData } = tokenData;
236
+ const { decimals, symbol, aggregators, iconUrl, name } = tokenData;
237
237
  // Push to lists with checksummed address (for allTokens storage)
238
238
  eventTokensDetails.push(`${symbol} - ${checksummedTokenAddress}`);
239
239
  tokensWithBalance.push({
@@ -244,7 +244,6 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
244
244
  image: iconUrl,
245
245
  isERC721: false,
246
246
  name,
247
- ...(rwaData && { rwaData }),
248
247
  });
249
248
  }
250
249
  // Perform addition
@@ -313,7 +312,7 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
313
312
  console.warn(`Token metadata not found in cache for ${tokenAddress} on chain ${chainId}`);
314
313
  continue;
315
314
  }
316
- const { decimals, symbol, aggregators, iconUrl, name, rwaData } = tokenData;
315
+ const { decimals, symbol, aggregators, iconUrl, name } = tokenData;
317
316
  eventTokensDetails.push(`${symbol} - ${checksummedTokenAddress}`);
318
317
  tokensWithBalance.push({
319
318
  address: checksummedTokenAddress,
@@ -323,7 +322,6 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
323
322
  image: iconUrl,
324
323
  isERC721: false,
325
324
  name,
326
- ...(rwaData && { rwaData }),
327
325
  });
328
326
  }
329
327
  // Perform addition
@@ -533,7 +531,7 @@ async function _TokenDetectionController_restartTokenDetection({ selectedAddress
533
531
  const tokensWithBalance = [];
534
532
  const eventTokensDetails = [];
535
533
  for (const nonZeroTokenAddress of Object.keys(balances)) {
536
- const { decimals, symbol, aggregators, iconUrl, name, rwaData } = __classPrivateFieldGet(this, _TokenDetectionController_tokensChainsCache, "f")[chainId].data[nonZeroTokenAddress];
534
+ const { decimals, symbol, aggregators, iconUrl, name } = __classPrivateFieldGet(this, _TokenDetectionController_tokensChainsCache, "f")[chainId].data[nonZeroTokenAddress];
537
535
  eventTokensDetails.push(`${symbol} - ${nonZeroTokenAddress}`);
538
536
  tokensWithBalance.push({
539
537
  address: nonZeroTokenAddress,
@@ -543,7 +541,6 @@ async function _TokenDetectionController_restartTokenDetection({ selectedAddress
543
541
  image: iconUrl,
544
542
  isERC721: false,
545
543
  name,
546
- ...(rwaData && { rwaData }),
547
544
  });
548
545
  }
549
546
  if (tokensWithBalance.length) {