@metamask/assets-controllers 103.1.0 → 104.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +32 -2
  2. package/dist/AssetsContractController.cjs +1 -1
  3. package/dist/AssetsContractController.cjs.map +1 -1
  4. package/dist/AssetsContractController.d.cts +1 -1
  5. package/dist/AssetsContractController.d.cts.map +1 -1
  6. package/dist/AssetsContractController.d.mts +1 -1
  7. package/dist/AssetsContractController.d.mts.map +1 -1
  8. package/dist/AssetsContractController.mjs +1 -1
  9. package/dist/AssetsContractController.mjs.map +1 -1
  10. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.cjs.map +1 -1
  11. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts +1 -1
  12. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts.map +1 -1
  13. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts +1 -1
  14. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts.map +1 -1
  15. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs.map +1 -1
  16. package/dist/NftController.cjs +49 -39
  17. package/dist/NftController.cjs.map +1 -1
  18. package/dist/NftController.d.cts +12 -7
  19. package/dist/NftController.d.cts.map +1 -1
  20. package/dist/NftController.d.mts +12 -7
  21. package/dist/NftController.d.mts.map +1 -1
  22. package/dist/NftController.mjs +49 -39
  23. package/dist/NftController.mjs.map +1 -1
  24. package/dist/RatesController/RatesController.cjs.map +1 -1
  25. package/dist/RatesController/RatesController.d.cts.map +1 -1
  26. package/dist/RatesController/RatesController.d.mts.map +1 -1
  27. package/dist/RatesController/RatesController.mjs.map +1 -1
  28. package/dist/RatesController/types.cjs.map +1 -1
  29. package/dist/RatesController/types.d.cts +1 -1
  30. package/dist/RatesController/types.d.cts.map +1 -1
  31. package/dist/RatesController/types.d.mts +1 -1
  32. package/dist/RatesController/types.d.mts.map +1 -1
  33. package/dist/RatesController/types.mjs.map +1 -1
  34. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.cjs.map +1 -1
  35. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.cts +1 -1
  36. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.cts.map +1 -1
  37. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.mts +1 -1
  38. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.mts.map +1 -1
  39. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.mjs.map +1 -1
  40. package/dist/multi-chain-accounts-service/api-balance-fetcher.cjs +1 -1
  41. package/dist/multi-chain-accounts-service/api-balance-fetcher.cjs.map +1 -1
  42. package/dist/multi-chain-accounts-service/api-balance-fetcher.mjs +1 -1
  43. package/dist/multi-chain-accounts-service/api-balance-fetcher.mjs.map +1 -1
  44. package/dist/multicall.cjs +220 -1
  45. package/dist/multicall.cjs.map +1 -1
  46. package/dist/multicall.d.cts +22 -0
  47. package/dist/multicall.d.cts.map +1 -1
  48. package/dist/multicall.d.mts +22 -0
  49. package/dist/multicall.d.mts.map +1 -1
  50. package/dist/multicall.mjs +218 -0
  51. package/dist/multicall.mjs.map +1 -1
  52. package/dist/rpc-service/rpc-balance-fetcher.cjs.map +1 -1
  53. package/dist/rpc-service/rpc-balance-fetcher.mjs.map +1 -1
  54. package/dist/selectors/token-selectors.cjs +1 -1
  55. package/dist/selectors/token-selectors.cjs.map +1 -1
  56. package/dist/selectors/token-selectors.d.cts.map +1 -1
  57. package/dist/selectors/token-selectors.d.mts.map +1 -1
  58. package/dist/selectors/token-selectors.mjs +1 -1
  59. package/dist/selectors/token-selectors.mjs.map +1 -1
  60. package/dist/token-prices-service/codefi-v2.cjs.map +1 -1
  61. package/dist/token-prices-service/codefi-v2.d.cts +1 -1
  62. package/dist/token-prices-service/codefi-v2.d.cts.map +1 -1
  63. package/dist/token-prices-service/codefi-v2.d.mts +1 -1
  64. package/dist/token-prices-service/codefi-v2.d.mts.map +1 -1
  65. package/dist/token-prices-service/codefi-v2.mjs.map +1 -1
  66. package/package.json +23 -24
@@ -1 +1 @@
1
- {"version":3,"file":"RatesController.d.cts","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAK3D,OAAO,KAAK,EAEV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACzB,oBAAgB;AAGjB,eAAO,MAAM,IAAI,oBAAoB,CAAC;AAEtC;;;;;GAKG;AACH,oBAAY,cAAc;IACxB,GAAG,QAAQ;IACX,MAAM,QAAQ;CACf;AAwCD,qBAAa,eAAgB,SAAQ,cAAc,CACjD,OAAO,IAAI,EACX,oBAAoB,EACpB,wBAAwB,CACzB;;IAWC;;;;;;;;;OASG;gBACS,EACV,QAA2B,EAC3B,SAAS,EACT,KAAK,EACL,cAAc,EACd,sBAAiD,GAClD,EAAE,sBAAsB;IA8EzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B;;;;OAIG;IACH,qBAAqB,IAAI,cAAc,EAAE;IAKzC;;;;OAIG;IACG,qBAAqB,CACzB,gBAAgB,EAAE,cAAc,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC;IAahB;;;;OAIG;IACG,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB3D"}
1
+ {"version":3,"file":"RatesController.d.cts","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAM3D,OAAO,KAAK,EAEV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACzB,oBAAgB;AAEjB,eAAO,MAAM,IAAI,oBAAoB,CAAC;AAEtC;;;;;GAKG;AACH,oBAAY,cAAc;IACxB,GAAG,QAAQ;IACX,MAAM,QAAQ;CACf;AAwCD,qBAAa,eAAgB,SAAQ,cAAc,CACjD,OAAO,IAAI,EACX,oBAAoB,EACpB,wBAAwB,CACzB;;IAWC;;;;;;;;;OASG;gBACS,EACV,QAA2B,EAC3B,SAAS,EACT,KAAK,EACL,cAAc,EACd,sBAAiD,GAClD,EAAE,sBAAsB;IA8EzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B;;;;OAIG;IACH,qBAAqB,IAAI,cAAc,EAAE;IAKzC;;;;OAIG;IACG,qBAAqB,CACzB,gBAAgB,EAAE,cAAc,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC;IAahB;;;;OAIG;IACG,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"RatesController.d.mts","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAK3D,OAAO,KAAK,EAEV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACzB,oBAAgB;AAGjB,eAAO,MAAM,IAAI,oBAAoB,CAAC;AAEtC;;;;;GAKG;AACH,oBAAY,cAAc;IACxB,GAAG,QAAQ;IACX,MAAM,QAAQ;CACf;AAwCD,qBAAa,eAAgB,SAAQ,cAAc,CACjD,OAAO,IAAI,EACX,oBAAoB,EACpB,wBAAwB,CACzB;;IAWC;;;;;;;;;OASG;gBACS,EACV,QAA2B,EAC3B,SAAS,EACT,KAAK,EACL,cAAc,EACd,sBAAiD,GAClD,EAAE,sBAAsB;IA8EzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B;;;;OAIG;IACH,qBAAqB,IAAI,cAAc,EAAE;IAKzC;;;;OAIG;IACG,qBAAqB,CACzB,gBAAgB,EAAE,cAAc,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC;IAahB;;;;OAIG;IACG,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB3D"}
1
+ {"version":3,"file":"RatesController.d.mts","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAM3D,OAAO,KAAK,EAEV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACzB,oBAAgB;AAEjB,eAAO,MAAM,IAAI,oBAAoB,CAAC;AAEtC;;;;;GAKG;AACH,oBAAY,cAAc;IACxB,GAAG,QAAQ;IACX,MAAM,QAAQ;CACf;AAwCD,qBAAa,eAAgB,SAAQ,cAAc,CACjD,OAAO,IAAI,EACX,oBAAoB,EACpB,wBAAwB,CACzB;;IAWC;;;;;;;;;OASG;gBACS,EACV,QAA2B,EAC3B,SAAS,EACT,KAAK,EACL,cAAc,EACd,sBAAiD,GAClD,EAAE,sBAAsB;IA8EzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B;;;;OAIG;IACH,qBAAqB,IAAI,cAAc,EAAE;IAKzC;;;;OAIG;IACG,qBAAqB,CACzB,gBAAgB,EAAE,cAAc,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC;IAahB;;;;OAIG;IACG,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"RatesController.mjs","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport type {\n ConversionRates,\n RatesControllerState,\n RatesControllerOptions,\n RatesControllerMessenger,\n} from './types';\nimport { fetchMultiExchangeRate as defaultFetchExchangeRate } from '../crypto-compare-service';\n\nexport const name = 'RatesController';\n\n/**\n * Supported cryptocurrencies that can be used as a base currency. The value needs to be compatible\n * with CryptoCompare's API which is the default source for the rates.\n *\n * See: https://min-api.cryptocompare.com/documentation?key=Price&cat=multipleSymbolsPriceEndpoint\n */\nexport enum Cryptocurrency {\n Btc = 'btc',\n Solana = 'sol',\n}\n\nconst DEFAULT_INTERVAL = 180000;\n\nconst metadata: StateMetadata<RatesControllerState> = {\n fiatCurrency: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n rates: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n cryptocurrencies: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: false,\n },\n};\n\nconst defaultState = {\n fiatCurrency: 'usd',\n rates: {\n [Cryptocurrency.Btc]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n [Cryptocurrency.Solana]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n },\n cryptocurrencies: [Cryptocurrency.Btc, Cryptocurrency.Solana],\n};\n\nexport class RatesController extends BaseController<\n typeof name,\n RatesControllerState,\n RatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n readonly #fetchMultiExchangeRate;\n\n readonly #includeUsdRate;\n\n readonly #intervalLength: number;\n\n #intervalId: NodeJS.Timeout | undefined;\n\n /**\n * Creates a RatesController instance.\n *\n * @param options - Constructor options.\n * @param options.includeUsdRate - Keep track of the USD rate in addition to the current currency rate.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.messenger - A reference to the messaging system.\n * @param options.state - Initial state to set on this controller.\n * @param options.fetchMultiExchangeRate - Fetches the exchange rate from an external API. This option is primarily meant for use in unit tests.\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n messenger,\n state,\n includeUsdRate,\n fetchMultiExchangeRate = defaultFetchExchangeRate,\n }: RatesControllerOptions) {\n super({\n name,\n metadata,\n messenger,\n state: { ...defaultState, ...state },\n });\n this.#includeUsdRate = includeUsdRate;\n this.#fetchMultiExchangeRate = fetchMultiExchangeRate;\n this.#intervalLength = interval;\n }\n\n /**\n * Executes a function `callback` within a mutex lock to ensure that only one instance of `callback` runs at a time across all invocations of `#withLock`.\n * This method is useful for synchronizing access to a resource or section of code that should not be executed concurrently.\n *\n * @template R - The return type of the function `callback`.\n * @param callback - A callback to execute once the lock is acquired. This callback can be synchronous or asynchronous.\n * @returns A promise that resolves to the result of the function `callback`. The promise is fulfilled once `callback` has completed execution.\n * @example\n * async function criticalLogic() {\n * // Critical logic code goes here.\n * }\n *\n * // Execute criticalLogic within a lock.\n * const result = await this.#withLock(criticalLogic);\n */\n async #withLock<R>(callback: () => R) {\n const releaseLock = await this.#mutex.acquire();\n try {\n return callback();\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Executes the polling operation to update rates.\n */\n async #executePoll(): Promise<void> {\n await this.#updateRates();\n }\n\n /**\n * Updates the rates by fetching new data.\n */\n async #updateRates(): Promise<void> {\n await this.#withLock(async () => {\n const { fiatCurrency, cryptocurrencies } = this.state;\n const response: Record<\n Cryptocurrency,\n Record<string, number>\n > = await this.#fetchMultiExchangeRate(\n fiatCurrency,\n cryptocurrencies,\n this.#includeUsdRate,\n );\n\n const updatedRates: ConversionRates = {};\n for (const [cryptocurrency, values] of Object.entries(response)) {\n updatedRates[cryptocurrency] = {\n conversionDate: Date.now(),\n conversionRate: values[fiatCurrency],\n ...(this.#includeUsdRate && { usdConversionRate: values.usd }),\n };\n }\n\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n rates: updatedRates,\n };\n },\n );\n });\n }\n\n /**\n * Starts the polling process.\n */\n async start(): Promise<void> {\n if (this.#intervalId) {\n return;\n }\n\n this.messenger.publish(`${name}:pollingStarted`);\n\n await this.#updateRates();\n\n this.#intervalId = setInterval(() => {\n this.#executePoll().catch(console.error);\n }, this.#intervalLength);\n }\n\n /**\n * Stops the polling process.\n */\n async stop(): Promise<void> {\n if (!this.#intervalId) {\n return;\n }\n\n clearInterval(this.#intervalId);\n this.#intervalId = undefined;\n this.messenger.publish(`${name}:pollingStopped`);\n }\n\n /**\n * Returns the current list of cryptocurrency.\n *\n * @returns The cryptocurrency list.\n */\n getCryptocurrencyList(): Cryptocurrency[] {\n const { cryptocurrencies } = this.state;\n return cryptocurrencies;\n }\n\n /**\n * Sets the list of supported cryptocurrencies.\n *\n * @param cryptocurrencies - The list of supported cryptocurrencies.\n */\n async setCryptocurrencyList(\n cryptocurrencies: Cryptocurrency[],\n ): Promise<void> {\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n cryptocurrencies,\n };\n },\n );\n });\n }\n\n /**\n * Sets the internal fiat currency and update rates accordingly.\n *\n * @param fiatCurrency - The fiat currency.\n */\n async setFiatCurrency(fiatCurrency: string): Promise<void> {\n if (fiatCurrency === '') {\n throw new Error('The currency can not be an empty string');\n }\n\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n fiatCurrency,\n };\n },\n );\n });\n await this.#updateRates();\n }\n}\n"]}
1
+ {"version":3,"file":"RatesController.mjs","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport { fetchMultiExchangeRate as defaultFetchExchangeRate } from '../crypto-compare-service';\nimport type {\n ConversionRates,\n RatesControllerState,\n RatesControllerOptions,\n RatesControllerMessenger,\n} from './types';\n\nexport const name = 'RatesController';\n\n/**\n * Supported cryptocurrencies that can be used as a base currency. The value needs to be compatible\n * with CryptoCompare's API which is the default source for the rates.\n *\n * See: https://min-api.cryptocompare.com/documentation?key=Price&cat=multipleSymbolsPriceEndpoint\n */\nexport enum Cryptocurrency {\n Btc = 'btc',\n Solana = 'sol',\n}\n\nconst DEFAULT_INTERVAL = 180000;\n\nconst metadata: StateMetadata<RatesControllerState> = {\n fiatCurrency: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n rates: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n cryptocurrencies: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: false,\n },\n};\n\nconst defaultState = {\n fiatCurrency: 'usd',\n rates: {\n [Cryptocurrency.Btc]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n [Cryptocurrency.Solana]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n },\n cryptocurrencies: [Cryptocurrency.Btc, Cryptocurrency.Solana],\n};\n\nexport class RatesController extends BaseController<\n typeof name,\n RatesControllerState,\n RatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n readonly #fetchMultiExchangeRate;\n\n readonly #includeUsdRate;\n\n readonly #intervalLength: number;\n\n #intervalId: NodeJS.Timeout | undefined;\n\n /**\n * Creates a RatesController instance.\n *\n * @param options - Constructor options.\n * @param options.includeUsdRate - Keep track of the USD rate in addition to the current currency rate.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.messenger - A reference to the messaging system.\n * @param options.state - Initial state to set on this controller.\n * @param options.fetchMultiExchangeRate - Fetches the exchange rate from an external API. This option is primarily meant for use in unit tests.\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n messenger,\n state,\n includeUsdRate,\n fetchMultiExchangeRate = defaultFetchExchangeRate,\n }: RatesControllerOptions) {\n super({\n name,\n metadata,\n messenger,\n state: { ...defaultState, ...state },\n });\n this.#includeUsdRate = includeUsdRate;\n this.#fetchMultiExchangeRate = fetchMultiExchangeRate;\n this.#intervalLength = interval;\n }\n\n /**\n * Executes a function `callback` within a mutex lock to ensure that only one instance of `callback` runs at a time across all invocations of `#withLock`.\n * This method is useful for synchronizing access to a resource or section of code that should not be executed concurrently.\n *\n * @template R - The return type of the function `callback`.\n * @param callback - A callback to execute once the lock is acquired. This callback can be synchronous or asynchronous.\n * @returns A promise that resolves to the result of the function `callback`. The promise is fulfilled once `callback` has completed execution.\n * @example\n * async function criticalLogic() {\n * // Critical logic code goes here.\n * }\n *\n * // Execute criticalLogic within a lock.\n * const result = await this.#withLock(criticalLogic);\n */\n async #withLock<R>(callback: () => R) {\n const releaseLock = await this.#mutex.acquire();\n try {\n return callback();\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Executes the polling operation to update rates.\n */\n async #executePoll(): Promise<void> {\n await this.#updateRates();\n }\n\n /**\n * Updates the rates by fetching new data.\n */\n async #updateRates(): Promise<void> {\n await this.#withLock(async () => {\n const { fiatCurrency, cryptocurrencies } = this.state;\n const response: Record<\n Cryptocurrency,\n Record<string, number>\n > = await this.#fetchMultiExchangeRate(\n fiatCurrency,\n cryptocurrencies,\n this.#includeUsdRate,\n );\n\n const updatedRates: ConversionRates = {};\n for (const [cryptocurrency, values] of Object.entries(response)) {\n updatedRates[cryptocurrency] = {\n conversionDate: Date.now(),\n conversionRate: values[fiatCurrency],\n ...(this.#includeUsdRate && { usdConversionRate: values.usd }),\n };\n }\n\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n rates: updatedRates,\n };\n },\n );\n });\n }\n\n /**\n * Starts the polling process.\n */\n async start(): Promise<void> {\n if (this.#intervalId) {\n return;\n }\n\n this.messenger.publish(`${name}:pollingStarted`);\n\n await this.#updateRates();\n\n this.#intervalId = setInterval(() => {\n this.#executePoll().catch(console.error);\n }, this.#intervalLength);\n }\n\n /**\n * Stops the polling process.\n */\n async stop(): Promise<void> {\n if (!this.#intervalId) {\n return;\n }\n\n clearInterval(this.#intervalId);\n this.#intervalId = undefined;\n this.messenger.publish(`${name}:pollingStopped`);\n }\n\n /**\n * Returns the current list of cryptocurrency.\n *\n * @returns The cryptocurrency list.\n */\n getCryptocurrencyList(): Cryptocurrency[] {\n const { cryptocurrencies } = this.state;\n return cryptocurrencies;\n }\n\n /**\n * Sets the list of supported cryptocurrencies.\n *\n * @param cryptocurrencies - The list of supported cryptocurrencies.\n */\n async setCryptocurrencyList(\n cryptocurrencies: Cryptocurrency[],\n ): Promise<void> {\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n cryptocurrencies,\n };\n },\n );\n });\n }\n\n /**\n * Sets the internal fiat currency and update rates accordingly.\n *\n * @param fiatCurrency - The fiat currency.\n */\n async setFiatCurrency(fiatCurrency: string): Promise<void> {\n if (fiatCurrency === '') {\n throw new Error('The currency can not be an empty string');\n }\n\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n fiatCurrency,\n };\n },\n );\n });\n await this.#updateRates();\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../../src/RatesController/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport type {\n name as ratesControllerName,\n Cryptocurrency,\n} from './RatesController';\nimport type { fetchMultiExchangeRate as defaultFetchExchangeRate } from '../crypto-compare-service';\n\n/**\n * Represents the conversion rates from one currency to others, including the conversion date.\n * The `conversionRate` field is a number that maps a cryptocurrency code (e.g., \"BTC\") to its\n * conversion rate.\n * The `usdConversionRate` provides the conversion rate to USD as a number, or `null` if the\n * conversion rate to USD is not available.\n * The `conversionDate` is a Unix timestamp (number) indicating when the conversion rate was last updated.\n */\nexport type Rate = {\n conversionRate: number;\n conversionDate: number;\n usdConversionRate?: number;\n};\n\n/**\n * Represents the conversion rates for multiple cryptocurrencies.\n * Each key is a string representing the cryptocurrency symbol (e.g., \"BTC\", \"SOL\"),\n * and its value is a `Rate` object containing conversion rates from that cryptocurrency\n * to a fiat currencies and an optional USD rate.\n */\nexport type ConversionRates = Record<string, Rate>;\n\n/**\n * Represents the state structure for the RatesController.\n */\nexport type RatesControllerState = {\n /**\n * The fiat currency in which conversion rates are expressed\n * (i.e., the \"to\" currency).\n */\n fiatCurrency: string;\n /**\n * The conversion rates for multiple cryptocurrencies.\n */\n rates: ConversionRates;\n /**\n * A list of supported cryptocurrency symbols.\n * (i.e., the \"from\" currencies).\n */\n cryptocurrencies: Cryptocurrency[];\n};\n\n/**\n * Type definition for RatesController state change events.\n */\nexport type RatesControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof ratesControllerName,\n RatesControllerState\n>;\n\n/**\n * Type definition for the RatesController polling started event.\n */\nexport type RatesControllerPollingStartedEvent = {\n type: `${typeof ratesControllerName}:pollingStarted`;\n payload: [];\n};\n\n/**\n * Type definition for the RatesController polling stopped event.\n */\nexport type RatesControllerPollingStoppedEvent = {\n type: `${typeof ratesControllerName}:pollingStopped`;\n payload: [];\n};\n\n/**\n * Defines the events that the RatesController can emit.\n */\nexport type RatesControllerEvents =\n | RatesControllerStateChangeEvent\n | RatesControllerPollingStartedEvent\n | RatesControllerPollingStoppedEvent;\n\nexport type RatesControllerGetStateAction = ControllerGetStateAction<\n typeof ratesControllerName,\n RatesControllerState\n>;\n\n/**\n * Defines the actions that can be performed to get the state of the RatesController.\n */\nexport type RatesControllerActions = RatesControllerGetStateAction;\n\n/**\n * Defines the actions that the RatesController can perform.\n */\nexport type RatesControllerMessenger = Messenger<\n typeof ratesControllerName,\n RatesControllerActions,\n RatesControllerEvents\n>;\n\n/**\n * The options required to initialize a RatesController.\n */\nexport type RatesControllerOptions = {\n /**\n * Whether to include USD rates in the conversion rates.\n */\n includeUsdRate: boolean;\n /**\n * The polling interval in milliseconds.\n */\n interval?: number;\n /**\n * The messenger instance for communication.\n */\n messenger: RatesControllerMessenger;\n /**\n * The initial state of the controller.\n */\n state?: Partial<RatesControllerState>;\n /**\n * The function to fetch exchange rates.\n */\n fetchMultiExchangeRate?: typeof defaultFetchExchangeRate;\n};\n"]}
1
+ {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../../src/RatesController/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport type { fetchMultiExchangeRate as defaultFetchExchangeRate } from '../crypto-compare-service';\nimport type {\n name as ratesControllerName,\n Cryptocurrency,\n} from './RatesController';\n\n/**\n * Represents the conversion rates from one currency to others, including the conversion date.\n * The `conversionRate` field is a number that maps a cryptocurrency code (e.g., \"BTC\") to its\n * conversion rate.\n * The `usdConversionRate` provides the conversion rate to USD as a number, or `null` if the\n * conversion rate to USD is not available.\n * The `conversionDate` is a Unix timestamp (number) indicating when the conversion rate was last updated.\n */\nexport type Rate = {\n conversionRate: number;\n conversionDate: number;\n usdConversionRate?: number;\n};\n\n/**\n * Represents the conversion rates for multiple cryptocurrencies.\n * Each key is a string representing the cryptocurrency symbol (e.g., \"BTC\", \"SOL\"),\n * and its value is a `Rate` object containing conversion rates from that cryptocurrency\n * to a fiat currencies and an optional USD rate.\n */\nexport type ConversionRates = Record<string, Rate>;\n\n/**\n * Represents the state structure for the RatesController.\n */\nexport type RatesControllerState = {\n /**\n * The fiat currency in which conversion rates are expressed\n * (i.e., the \"to\" currency).\n */\n fiatCurrency: string;\n /**\n * The conversion rates for multiple cryptocurrencies.\n */\n rates: ConversionRates;\n /**\n * A list of supported cryptocurrency symbols.\n * (i.e., the \"from\" currencies).\n */\n cryptocurrencies: Cryptocurrency[];\n};\n\n/**\n * Type definition for RatesController state change events.\n */\nexport type RatesControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof ratesControllerName,\n RatesControllerState\n>;\n\n/**\n * Type definition for the RatesController polling started event.\n */\nexport type RatesControllerPollingStartedEvent = {\n type: `${typeof ratesControllerName}:pollingStarted`;\n payload: [];\n};\n\n/**\n * Type definition for the RatesController polling stopped event.\n */\nexport type RatesControllerPollingStoppedEvent = {\n type: `${typeof ratesControllerName}:pollingStopped`;\n payload: [];\n};\n\n/**\n * Defines the events that the RatesController can emit.\n */\nexport type RatesControllerEvents =\n | RatesControllerStateChangeEvent\n | RatesControllerPollingStartedEvent\n | RatesControllerPollingStoppedEvent;\n\nexport type RatesControllerGetStateAction = ControllerGetStateAction<\n typeof ratesControllerName,\n RatesControllerState\n>;\n\n/**\n * Defines the actions that can be performed to get the state of the RatesController.\n */\nexport type RatesControllerActions = RatesControllerGetStateAction;\n\n/**\n * Defines the actions that the RatesController can perform.\n */\nexport type RatesControllerMessenger = Messenger<\n typeof ratesControllerName,\n RatesControllerActions,\n RatesControllerEvents\n>;\n\n/**\n * The options required to initialize a RatesController.\n */\nexport type RatesControllerOptions = {\n /**\n * Whether to include USD rates in the conversion rates.\n */\n includeUsdRate: boolean;\n /**\n * The polling interval in milliseconds.\n */\n interval?: number;\n /**\n * The messenger instance for communication.\n */\n messenger: RatesControllerMessenger;\n /**\n * The initial state of the controller.\n */\n state?: Partial<RatesControllerState>;\n /**\n * The function to fetch exchange rates.\n */\n fetchMultiExchangeRate?: typeof defaultFetchExchangeRate;\n};\n"]}
@@ -1,7 +1,7 @@
1
1
  import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
2
2
  import type { Messenger } from "@metamask/messenger";
3
- import type { name as ratesControllerName, Cryptocurrency } from "./RatesController.cjs";
4
3
  import type { fetchMultiExchangeRate as defaultFetchExchangeRate } from "../crypto-compare-service/index.cjs";
4
+ import type { name as ratesControllerName, Cryptocurrency } from "./RatesController.cjs";
5
5
  /**
6
6
  * Represents the conversion rates from one currency to others, including the conversion date.
7
7
  * The `conversionRate` field is a number that maps a cryptocurrency code (e.g., "BTC") to its
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../../src/RatesController/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EACV,IAAI,IAAI,mBAAmB,EAC3B,cAAc,EACf,8BAA0B;AAC3B,OAAO,KAAK,EAAE,sBAAsB,IAAI,wBAAwB,EAAE,4CAAkC;AAEpG;;;;;;;GAOG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,KAAK,EAAE,eAAe,CAAC;IACvB;;;OAGG;IACH,gBAAgB,EAAE,cAAc,EAAE,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GAAG,0BAA0B,CACtE,OAAO,mBAAmB,EAC1B,oBAAoB,CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,GAAG,OAAO,mBAAmB,iBAAiB,CAAC;IACrD,OAAO,EAAE,EAAE,CAAC;CACb,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,GAAG,OAAO,mBAAmB,iBAAiB,CAAC;IACrD,OAAO,EAAE,EAAE,CAAC;CACb,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B,+BAA+B,GAC/B,kCAAkC,GAClC,kCAAkC,CAAC;AAEvC,MAAM,MAAM,6BAA6B,GAAG,wBAAwB,CAClE,OAAO,mBAAmB,EAC1B,oBAAoB,CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,6BAA6B,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,SAAS,CAC9C,OAAO,mBAAmB,EAC1B,sBAAsB,EACtB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,SAAS,EAAE,wBAAwB,CAAC;IACpC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtC;;OAEG;IACH,sBAAsB,CAAC,EAAE,OAAO,wBAAwB,CAAC;CAC1D,CAAC"}
1
+ {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../../src/RatesController/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EAAE,sBAAsB,IAAI,wBAAwB,EAAE,4CAAkC;AACpG,OAAO,KAAK,EACV,IAAI,IAAI,mBAAmB,EAC3B,cAAc,EACf,8BAA0B;AAE3B;;;;;;;GAOG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,KAAK,EAAE,eAAe,CAAC;IACvB;;;OAGG;IACH,gBAAgB,EAAE,cAAc,EAAE,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GAAG,0BAA0B,CACtE,OAAO,mBAAmB,EAC1B,oBAAoB,CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,GAAG,OAAO,mBAAmB,iBAAiB,CAAC;IACrD,OAAO,EAAE,EAAE,CAAC;CACb,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,GAAG,OAAO,mBAAmB,iBAAiB,CAAC;IACrD,OAAO,EAAE,EAAE,CAAC;CACb,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B,+BAA+B,GAC/B,kCAAkC,GAClC,kCAAkC,CAAC;AAEvC,MAAM,MAAM,6BAA6B,GAAG,wBAAwB,CAClE,OAAO,mBAAmB,EAC1B,oBAAoB,CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,6BAA6B,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,SAAS,CAC9C,OAAO,mBAAmB,EAC1B,sBAAsB,EACtB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,SAAS,EAAE,wBAAwB,CAAC;IACpC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtC;;OAEG;IACH,sBAAsB,CAAC,EAAE,OAAO,wBAAwB,CAAC;CAC1D,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
2
2
  import type { Messenger } from "@metamask/messenger";
3
- import type { name as ratesControllerName, Cryptocurrency } from "./RatesController.mjs";
4
3
  import type { fetchMultiExchangeRate as defaultFetchExchangeRate } from "../crypto-compare-service/index.mjs";
4
+ import type { name as ratesControllerName, Cryptocurrency } from "./RatesController.mjs";
5
5
  /**
6
6
  * Represents the conversion rates from one currency to others, including the conversion date.
7
7
  * The `conversionRate` field is a number that maps a cryptocurrency code (e.g., "BTC") to its
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../../src/RatesController/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EACV,IAAI,IAAI,mBAAmB,EAC3B,cAAc,EACf,8BAA0B;AAC3B,OAAO,KAAK,EAAE,sBAAsB,IAAI,wBAAwB,EAAE,4CAAkC;AAEpG;;;;;;;GAOG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,KAAK,EAAE,eAAe,CAAC;IACvB;;;OAGG;IACH,gBAAgB,EAAE,cAAc,EAAE,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GAAG,0BAA0B,CACtE,OAAO,mBAAmB,EAC1B,oBAAoB,CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,GAAG,OAAO,mBAAmB,iBAAiB,CAAC;IACrD,OAAO,EAAE,EAAE,CAAC;CACb,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,GAAG,OAAO,mBAAmB,iBAAiB,CAAC;IACrD,OAAO,EAAE,EAAE,CAAC;CACb,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B,+BAA+B,GAC/B,kCAAkC,GAClC,kCAAkC,CAAC;AAEvC,MAAM,MAAM,6BAA6B,GAAG,wBAAwB,CAClE,OAAO,mBAAmB,EAC1B,oBAAoB,CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,6BAA6B,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,SAAS,CAC9C,OAAO,mBAAmB,EAC1B,sBAAsB,EACtB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,SAAS,EAAE,wBAAwB,CAAC;IACpC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtC;;OAEG;IACH,sBAAsB,CAAC,EAAE,OAAO,wBAAwB,CAAC;CAC1D,CAAC"}
1
+ {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../../src/RatesController/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EAAE,sBAAsB,IAAI,wBAAwB,EAAE,4CAAkC;AACpG,OAAO,KAAK,EACV,IAAI,IAAI,mBAAmB,EAC3B,cAAc,EACf,8BAA0B;AAE3B;;;;;;;GAOG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,KAAK,EAAE,eAAe,CAAC;IACvB;;;OAGG;IACH,gBAAgB,EAAE,cAAc,EAAE,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GAAG,0BAA0B,CACtE,OAAO,mBAAmB,EAC1B,oBAAoB,CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,GAAG,OAAO,mBAAmB,iBAAiB,CAAC;IACrD,OAAO,EAAE,EAAE,CAAC;CACb,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,GAAG,OAAO,mBAAmB,iBAAiB,CAAC;IACrD,OAAO,EAAE,EAAE,CAAC;CACb,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B,+BAA+B,GAC/B,kCAAkC,GAClC,kCAAkC,CAAC;AAEvC,MAAM,MAAM,6BAA6B,GAAG,wBAAwB,CAClE,OAAO,mBAAmB,EAC1B,oBAAoB,CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,6BAA6B,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,SAAS,CAC9C,OAAO,mBAAmB,EAC1B,sBAAsB,EACtB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,SAAS,EAAE,wBAAwB,CAAC;IACpC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtC;;OAEG;IACH,sBAAsB,CAAC,EAAE,OAAO,wBAAwB,CAAC;CAC1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","sourceRoot":"","sources":["../../src/RatesController/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport type {\n name as ratesControllerName,\n Cryptocurrency,\n} from './RatesController';\nimport type { fetchMultiExchangeRate as defaultFetchExchangeRate } from '../crypto-compare-service';\n\n/**\n * Represents the conversion rates from one currency to others, including the conversion date.\n * The `conversionRate` field is a number that maps a cryptocurrency code (e.g., \"BTC\") to its\n * conversion rate.\n * The `usdConversionRate` provides the conversion rate to USD as a number, or `null` if the\n * conversion rate to USD is not available.\n * The `conversionDate` is a Unix timestamp (number) indicating when the conversion rate was last updated.\n */\nexport type Rate = {\n conversionRate: number;\n conversionDate: number;\n usdConversionRate?: number;\n};\n\n/**\n * Represents the conversion rates for multiple cryptocurrencies.\n * Each key is a string representing the cryptocurrency symbol (e.g., \"BTC\", \"SOL\"),\n * and its value is a `Rate` object containing conversion rates from that cryptocurrency\n * to a fiat currencies and an optional USD rate.\n */\nexport type ConversionRates = Record<string, Rate>;\n\n/**\n * Represents the state structure for the RatesController.\n */\nexport type RatesControllerState = {\n /**\n * The fiat currency in which conversion rates are expressed\n * (i.e., the \"to\" currency).\n */\n fiatCurrency: string;\n /**\n * The conversion rates for multiple cryptocurrencies.\n */\n rates: ConversionRates;\n /**\n * A list of supported cryptocurrency symbols.\n * (i.e., the \"from\" currencies).\n */\n cryptocurrencies: Cryptocurrency[];\n};\n\n/**\n * Type definition for RatesController state change events.\n */\nexport type RatesControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof ratesControllerName,\n RatesControllerState\n>;\n\n/**\n * Type definition for the RatesController polling started event.\n */\nexport type RatesControllerPollingStartedEvent = {\n type: `${typeof ratesControllerName}:pollingStarted`;\n payload: [];\n};\n\n/**\n * Type definition for the RatesController polling stopped event.\n */\nexport type RatesControllerPollingStoppedEvent = {\n type: `${typeof ratesControllerName}:pollingStopped`;\n payload: [];\n};\n\n/**\n * Defines the events that the RatesController can emit.\n */\nexport type RatesControllerEvents =\n | RatesControllerStateChangeEvent\n | RatesControllerPollingStartedEvent\n | RatesControllerPollingStoppedEvent;\n\nexport type RatesControllerGetStateAction = ControllerGetStateAction<\n typeof ratesControllerName,\n RatesControllerState\n>;\n\n/**\n * Defines the actions that can be performed to get the state of the RatesController.\n */\nexport type RatesControllerActions = RatesControllerGetStateAction;\n\n/**\n * Defines the actions that the RatesController can perform.\n */\nexport type RatesControllerMessenger = Messenger<\n typeof ratesControllerName,\n RatesControllerActions,\n RatesControllerEvents\n>;\n\n/**\n * The options required to initialize a RatesController.\n */\nexport type RatesControllerOptions = {\n /**\n * Whether to include USD rates in the conversion rates.\n */\n includeUsdRate: boolean;\n /**\n * The polling interval in milliseconds.\n */\n interval?: number;\n /**\n * The messenger instance for communication.\n */\n messenger: RatesControllerMessenger;\n /**\n * The initial state of the controller.\n */\n state?: Partial<RatesControllerState>;\n /**\n * The function to fetch exchange rates.\n */\n fetchMultiExchangeRate?: typeof defaultFetchExchangeRate;\n};\n"]}
1
+ {"version":3,"file":"types.mjs","sourceRoot":"","sources":["../../src/RatesController/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport type { fetchMultiExchangeRate as defaultFetchExchangeRate } from '../crypto-compare-service';\nimport type {\n name as ratesControllerName,\n Cryptocurrency,\n} from './RatesController';\n\n/**\n * Represents the conversion rates from one currency to others, including the conversion date.\n * The `conversionRate` field is a number that maps a cryptocurrency code (e.g., \"BTC\") to its\n * conversion rate.\n * The `usdConversionRate` provides the conversion rate to USD as a number, or `null` if the\n * conversion rate to USD is not available.\n * The `conversionDate` is a Unix timestamp (number) indicating when the conversion rate was last updated.\n */\nexport type Rate = {\n conversionRate: number;\n conversionDate: number;\n usdConversionRate?: number;\n};\n\n/**\n * Represents the conversion rates for multiple cryptocurrencies.\n * Each key is a string representing the cryptocurrency symbol (e.g., \"BTC\", \"SOL\"),\n * and its value is a `Rate` object containing conversion rates from that cryptocurrency\n * to a fiat currencies and an optional USD rate.\n */\nexport type ConversionRates = Record<string, Rate>;\n\n/**\n * Represents the state structure for the RatesController.\n */\nexport type RatesControllerState = {\n /**\n * The fiat currency in which conversion rates are expressed\n * (i.e., the \"to\" currency).\n */\n fiatCurrency: string;\n /**\n * The conversion rates for multiple cryptocurrencies.\n */\n rates: ConversionRates;\n /**\n * A list of supported cryptocurrency symbols.\n * (i.e., the \"from\" currencies).\n */\n cryptocurrencies: Cryptocurrency[];\n};\n\n/**\n * Type definition for RatesController state change events.\n */\nexport type RatesControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof ratesControllerName,\n RatesControllerState\n>;\n\n/**\n * Type definition for the RatesController polling started event.\n */\nexport type RatesControllerPollingStartedEvent = {\n type: `${typeof ratesControllerName}:pollingStarted`;\n payload: [];\n};\n\n/**\n * Type definition for the RatesController polling stopped event.\n */\nexport type RatesControllerPollingStoppedEvent = {\n type: `${typeof ratesControllerName}:pollingStopped`;\n payload: [];\n};\n\n/**\n * Defines the events that the RatesController can emit.\n */\nexport type RatesControllerEvents =\n | RatesControllerStateChangeEvent\n | RatesControllerPollingStartedEvent\n | RatesControllerPollingStoppedEvent;\n\nexport type RatesControllerGetStateAction = ControllerGetStateAction<\n typeof ratesControllerName,\n RatesControllerState\n>;\n\n/**\n * Defines the actions that can be performed to get the state of the RatesController.\n */\nexport type RatesControllerActions = RatesControllerGetStateAction;\n\n/**\n * Defines the actions that the RatesController can perform.\n */\nexport type RatesControllerMessenger = Messenger<\n typeof ratesControllerName,\n RatesControllerActions,\n RatesControllerEvents\n>;\n\n/**\n * The options required to initialize a RatesController.\n */\nexport type RatesControllerOptions = {\n /**\n * Whether to include USD rates in the conversion rates.\n */\n includeUsdRate: boolean;\n /**\n * The polling interval in milliseconds.\n */\n interval?: number;\n /**\n * The messenger instance for communication.\n */\n messenger: RatesControllerMessenger;\n /**\n * The initial state of the controller.\n */\n state?: Partial<RatesControllerState>;\n /**\n * The function to fetch exchange rates.\n */\n fetchMultiExchangeRate?: typeof defaultFetchExchangeRate;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TokenSearchDiscoveryDataController.cjs","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Hex } from '@metamask/utils';\n\nimport type { TokenDisplayData } from './types';\nimport { formatIconUrlWithProxy } from '../assetsUtil';\nimport type { GetCurrencyRateState } from '../CurrencyRateController';\nimport type { AbstractTokenPricesService } from '../token-prices-service';\nimport {\n fetchTokenMetadata,\n TOKEN_METADATA_NO_SUPPORT_ERROR,\n} from '../token-service';\nimport type { TokenListToken } from '../TokenListController';\n\n// === GENERAL ===\n\nexport const controllerName = 'TokenSearchDiscoveryDataController';\n\nexport const MAX_TOKEN_DISPLAY_DATA_LENGTH = 10;\n\n// === STATE ===\n\nexport type TokenSearchDiscoveryDataControllerState = {\n tokenDisplayData: TokenDisplayData[];\n};\n\nconst tokenSearchDiscoveryDataControllerMetadata: StateMetadata<TokenSearchDiscoveryDataControllerState> =\n {\n tokenDisplayData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n } as const;\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} registers, to be\n * called externally.\n */\nexport type TokenSearchDiscoveryDataControllerActions =\n TokenSearchDiscoveryDataControllerGetStateAction;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} calls internally.\n */\nexport type AllowedActions = GetCurrencyRateState;\n\n/**\n * The event that {@link TokenSearchDiscoveryDataController} publishes when updating\n * state.\n */\nexport type TokenSearchDiscoveryDataControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} publishes, to be\n * subscribed to externally.\n */\nexport type TokenSearchDiscoveryDataControllerEvents =\n TokenSearchDiscoveryDataControllerStateChangeEvent;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} subscribes to internally.\n */\nexport type AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerMessenger = Messenger<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerActions | AllowedActions,\n TokenSearchDiscoveryDataControllerEvents | AllowedEvents\n>;\n\n/**\n * Constructs the default {@link TokenSearchDiscoveryDataController} 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 TokenSearchDiscoveryDataController} state.\n */\nexport function getDefaultTokenSearchDiscoveryDataControllerState(): TokenSearchDiscoveryDataControllerState {\n return {\n tokenDisplayData: [],\n };\n}\n\n/**\n * The TokenSearchDiscoveryDataController manages the retrieval of token search results and token discovery.\n * It fetches token metadata from the Token API and token prices from the token prices service.\n */\nexport class TokenSearchDiscoveryDataController extends BaseController<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState,\n TokenSearchDiscoveryDataControllerMessenger\n> {\n readonly #abortController: AbortController;\n\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n constructor({\n state = {},\n messenger,\n tokenPricesService,\n }: {\n state?: Partial<TokenSearchDiscoveryDataControllerState>;\n messenger: TokenSearchDiscoveryDataControllerMessenger;\n tokenPricesService: AbstractTokenPricesService;\n }) {\n super({\n name: controllerName,\n metadata: tokenSearchDiscoveryDataControllerMetadata,\n messenger,\n state: {\n ...getDefaultTokenSearchDiscoveryDataControllerState(),\n ...state,\n },\n });\n\n this.#abortController = new AbortController();\n this.#tokenPricesService = tokenPricesService;\n }\n\n async #fetchPriceData(chainId: Hex, address: string) {\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n try {\n const pricesData = await this.#tokenPricesService.fetchTokenPrices({\n assets: [{ chainId, tokenAddress: address as Hex }],\n currency: currentCurrency,\n });\n\n return pricesData[0] ?? null;\n } catch (error) {\n console.error(error);\n return null;\n }\n }\n\n async fetchTokenDisplayData(chainId: Hex, address: string): Promise<void> {\n let tokenMetadata: TokenListToken | undefined;\n try {\n tokenMetadata = await fetchTokenMetadata<TokenListToken>(\n chainId,\n address,\n this.#abortController.signal,\n );\n } catch (error) {\n if (\n !(error instanceof Error) ||\n !error.message.includes(TOKEN_METADATA_NO_SUPPORT_ERROR)\n ) {\n throw error;\n }\n }\n\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n let tokenDisplayData: TokenDisplayData;\n if (!tokenMetadata) {\n tokenDisplayData = {\n found: false,\n address,\n chainId,\n currency: currentCurrency,\n };\n } else {\n const priceData = await this.#fetchPriceData(chainId, address);\n tokenDisplayData = {\n found: true,\n address,\n chainId,\n currency: currentCurrency,\n token: {\n ...tokenMetadata,\n isERC721: false,\n image: formatIconUrlWithProxy({\n chainId,\n tokenAddress: address,\n }),\n },\n price: priceData,\n };\n }\n\n this.update((state) => {\n state.tokenDisplayData = [\n tokenDisplayData,\n ...state.tokenDisplayData.filter(\n (token) =>\n token.address !== address ||\n token.chainId !== chainId ||\n token.currency !== currentCurrency,\n ),\n ].slice(0, MAX_TOKEN_DISPLAY_DATA_LENGTH);\n });\n }\n}\n"]}
1
+ {"version":3,"file":"TokenSearchDiscoveryDataController.cjs","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Hex } from '@metamask/utils';\n\nimport { formatIconUrlWithProxy } from '../assetsUtil';\nimport type { GetCurrencyRateState } from '../CurrencyRateController';\nimport type { AbstractTokenPricesService } from '../token-prices-service';\nimport {\n fetchTokenMetadata,\n TOKEN_METADATA_NO_SUPPORT_ERROR,\n} from '../token-service';\nimport type { TokenListToken } from '../TokenListController';\nimport type { TokenDisplayData } from './types';\n\n// === GENERAL ===\n\nexport const controllerName = 'TokenSearchDiscoveryDataController';\n\nexport const MAX_TOKEN_DISPLAY_DATA_LENGTH = 10;\n\n// === STATE ===\n\nexport type TokenSearchDiscoveryDataControllerState = {\n tokenDisplayData: TokenDisplayData[];\n};\n\nconst tokenSearchDiscoveryDataControllerMetadata: StateMetadata<TokenSearchDiscoveryDataControllerState> =\n {\n tokenDisplayData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n } as const;\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} registers, to be\n * called externally.\n */\nexport type TokenSearchDiscoveryDataControllerActions =\n TokenSearchDiscoveryDataControllerGetStateAction;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} calls internally.\n */\nexport type AllowedActions = GetCurrencyRateState;\n\n/**\n * The event that {@link TokenSearchDiscoveryDataController} publishes when updating\n * state.\n */\nexport type TokenSearchDiscoveryDataControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} publishes, to be\n * subscribed to externally.\n */\nexport type TokenSearchDiscoveryDataControllerEvents =\n TokenSearchDiscoveryDataControllerStateChangeEvent;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} subscribes to internally.\n */\nexport type AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerMessenger = Messenger<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerActions | AllowedActions,\n TokenSearchDiscoveryDataControllerEvents | AllowedEvents\n>;\n\n/**\n * Constructs the default {@link TokenSearchDiscoveryDataController} 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 TokenSearchDiscoveryDataController} state.\n */\nexport function getDefaultTokenSearchDiscoveryDataControllerState(): TokenSearchDiscoveryDataControllerState {\n return {\n tokenDisplayData: [],\n };\n}\n\n/**\n * The TokenSearchDiscoveryDataController manages the retrieval of token search results and token discovery.\n * It fetches token metadata from the Token API and token prices from the token prices service.\n */\nexport class TokenSearchDiscoveryDataController extends BaseController<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState,\n TokenSearchDiscoveryDataControllerMessenger\n> {\n readonly #abortController: AbortController;\n\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n constructor({\n state = {},\n messenger,\n tokenPricesService,\n }: {\n state?: Partial<TokenSearchDiscoveryDataControllerState>;\n messenger: TokenSearchDiscoveryDataControllerMessenger;\n tokenPricesService: AbstractTokenPricesService;\n }) {\n super({\n name: controllerName,\n metadata: tokenSearchDiscoveryDataControllerMetadata,\n messenger,\n state: {\n ...getDefaultTokenSearchDiscoveryDataControllerState(),\n ...state,\n },\n });\n\n this.#abortController = new AbortController();\n this.#tokenPricesService = tokenPricesService;\n }\n\n async #fetchPriceData(chainId: Hex, address: string) {\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n try {\n const pricesData = await this.#tokenPricesService.fetchTokenPrices({\n assets: [{ chainId, tokenAddress: address as Hex }],\n currency: currentCurrency,\n });\n\n return pricesData[0] ?? null;\n } catch (error) {\n console.error(error);\n return null;\n }\n }\n\n async fetchTokenDisplayData(chainId: Hex, address: string): Promise<void> {\n let tokenMetadata: TokenListToken | undefined;\n try {\n tokenMetadata = await fetchTokenMetadata<TokenListToken>(\n chainId,\n address,\n this.#abortController.signal,\n );\n } catch (error) {\n if (\n !(error instanceof Error) ||\n !error.message.includes(TOKEN_METADATA_NO_SUPPORT_ERROR)\n ) {\n throw error;\n }\n }\n\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n let tokenDisplayData: TokenDisplayData;\n if (!tokenMetadata) {\n tokenDisplayData = {\n found: false,\n address,\n chainId,\n currency: currentCurrency,\n };\n } else {\n const priceData = await this.#fetchPriceData(chainId, address);\n tokenDisplayData = {\n found: true,\n address,\n chainId,\n currency: currentCurrency,\n token: {\n ...tokenMetadata,\n isERC721: false,\n image: formatIconUrlWithProxy({\n chainId,\n tokenAddress: address,\n }),\n },\n price: priceData,\n };\n }\n\n this.update((state) => {\n state.tokenDisplayData = [\n tokenDisplayData,\n ...state.tokenDisplayData.filter(\n (token) =>\n token.address !== address ||\n token.chainId !== chainId ||\n token.currency !== currentCurrency,\n ),\n ].slice(0, MAX_TOKEN_DISPLAY_DATA_LENGTH);\n });\n }\n}\n"]}
@@ -2,9 +2,9 @@ import { BaseController } from "@metamask/base-controller";
2
2
  import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
3
3
  import type { Messenger } from "@metamask/messenger";
4
4
  import type { Hex } from "@metamask/utils";
5
- import type { TokenDisplayData } from "./types.cjs";
6
5
  import type { GetCurrencyRateState } from "../CurrencyRateController.cjs";
7
6
  import type { AbstractTokenPricesService } from "../token-prices-service/index.cjs";
7
+ import type { TokenDisplayData } from "./types.cjs";
8
8
  export declare const controllerName = "TokenSearchDiscoveryDataController";
9
9
  export declare const MAX_TOKEN_DISPLAY_DATA_LENGTH = 10;
10
10
  export type TokenSearchDiscoveryDataControllerState = {
@@ -1 +1 @@
1
- {"version":3,"file":"TokenSearchDiscoveryDataController.d.cts","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAgB;AAEhD,OAAO,KAAK,EAAE,oBAAoB,EAAE,sCAAkC;AACtE,OAAO,KAAK,EAAE,0BAA0B,EAAE,0CAAgC;AAS1E,eAAO,MAAM,cAAc,uCAAuC,CAAC;AAEnE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAIhD,MAAM,MAAM,uCAAuC,GAAG;IACpD,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;CACtC,CAAC;AAcF;;;GAGG;AACH,MAAM,MAAM,gDAAgD,GAC1D,wBAAwB,CACtB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,yCAAyC,GACnD,gDAAgD,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,kDAAkD,GAC5D,0BAA0B,CACxB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,wCAAwC,GAClD,kDAAkD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,2CAA2C,GAAG,SAAS,CACjE,OAAO,cAAc,EACrB,yCAAyC,GAAG,cAAc,EAC1D,wCAAwC,GAAG,aAAa,CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iDAAiD,IAAI,uCAAuC,CAI3G;AAED;;;GAGG;AACH,qBAAa,kCAAmC,SAAQ,cAAc,CACpE,OAAO,cAAc,EACrB,uCAAuC,EACvC,2CAA2C,CAC5C;;gBAKa,EACV,KAAU,EACV,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,KAAK,CAAC,EAAE,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACzD,SAAS,EAAE,2CAA2C,CAAC;QACvD,kBAAkB,EAAE,0BAA0B,CAAC;KAChD;IAiCK,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4D1E"}
1
+ {"version":3,"file":"TokenSearchDiscoveryDataController.d.cts","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,sCAAkC;AACtE,OAAO,KAAK,EAAE,0BAA0B,EAAE,0CAAgC;AAM1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAgB;AAIhD,eAAO,MAAM,cAAc,uCAAuC,CAAC;AAEnE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAIhD,MAAM,MAAM,uCAAuC,GAAG;IACpD,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;CACtC,CAAC;AAcF;;;GAGG;AACH,MAAM,MAAM,gDAAgD,GAC1D,wBAAwB,CACtB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,yCAAyC,GACnD,gDAAgD,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,kDAAkD,GAC5D,0BAA0B,CACxB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,wCAAwC,GAClD,kDAAkD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,2CAA2C,GAAG,SAAS,CACjE,OAAO,cAAc,EACrB,yCAAyC,GAAG,cAAc,EAC1D,wCAAwC,GAAG,aAAa,CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iDAAiD,IAAI,uCAAuC,CAI3G;AAED;;;GAGG;AACH,qBAAa,kCAAmC,SAAQ,cAAc,CACpE,OAAO,cAAc,EACrB,uCAAuC,EACvC,2CAA2C,CAC5C;;gBAKa,EACV,KAAU,EACV,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,KAAK,CAAC,EAAE,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACzD,SAAS,EAAE,2CAA2C,CAAC;QACvD,kBAAkB,EAAE,0BAA0B,CAAC;KAChD;IAiCK,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4D1E"}
@@ -2,9 +2,9 @@ import { BaseController } from "@metamask/base-controller";
2
2
  import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
3
3
  import type { Messenger } from "@metamask/messenger";
4
4
  import type { Hex } from "@metamask/utils";
5
- import type { TokenDisplayData } from "./types.mjs";
6
5
  import type { GetCurrencyRateState } from "../CurrencyRateController.mjs";
7
6
  import type { AbstractTokenPricesService } from "../token-prices-service/index.mjs";
7
+ import type { TokenDisplayData } from "./types.mjs";
8
8
  export declare const controllerName = "TokenSearchDiscoveryDataController";
9
9
  export declare const MAX_TOKEN_DISPLAY_DATA_LENGTH = 10;
10
10
  export type TokenSearchDiscoveryDataControllerState = {
@@ -1 +1 @@
1
- {"version":3,"file":"TokenSearchDiscoveryDataController.d.mts","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAgB;AAEhD,OAAO,KAAK,EAAE,oBAAoB,EAAE,sCAAkC;AACtE,OAAO,KAAK,EAAE,0BAA0B,EAAE,0CAAgC;AAS1E,eAAO,MAAM,cAAc,uCAAuC,CAAC;AAEnE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAIhD,MAAM,MAAM,uCAAuC,GAAG;IACpD,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;CACtC,CAAC;AAcF;;;GAGG;AACH,MAAM,MAAM,gDAAgD,GAC1D,wBAAwB,CACtB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,yCAAyC,GACnD,gDAAgD,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,kDAAkD,GAC5D,0BAA0B,CACxB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,wCAAwC,GAClD,kDAAkD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,2CAA2C,GAAG,SAAS,CACjE,OAAO,cAAc,EACrB,yCAAyC,GAAG,cAAc,EAC1D,wCAAwC,GAAG,aAAa,CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iDAAiD,IAAI,uCAAuC,CAI3G;AAED;;;GAGG;AACH,qBAAa,kCAAmC,SAAQ,cAAc,CACpE,OAAO,cAAc,EACrB,uCAAuC,EACvC,2CAA2C,CAC5C;;gBAKa,EACV,KAAU,EACV,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,KAAK,CAAC,EAAE,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACzD,SAAS,EAAE,2CAA2C,CAAC;QACvD,kBAAkB,EAAE,0BAA0B,CAAC;KAChD;IAiCK,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4D1E"}
1
+ {"version":3,"file":"TokenSearchDiscoveryDataController.d.mts","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,sCAAkC;AACtE,OAAO,KAAK,EAAE,0BAA0B,EAAE,0CAAgC;AAM1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAgB;AAIhD,eAAO,MAAM,cAAc,uCAAuC,CAAC;AAEnE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAIhD,MAAM,MAAM,uCAAuC,GAAG;IACpD,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;CACtC,CAAC;AAcF;;;GAGG;AACH,MAAM,MAAM,gDAAgD,GAC1D,wBAAwB,CACtB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,yCAAyC,GACnD,gDAAgD,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,kDAAkD,GAC5D,0BAA0B,CACxB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,wCAAwC,GAClD,kDAAkD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,2CAA2C,GAAG,SAAS,CACjE,OAAO,cAAc,EACrB,yCAAyC,GAAG,cAAc,EAC1D,wCAAwC,GAAG,aAAa,CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iDAAiD,IAAI,uCAAuC,CAI3G;AAED;;;GAGG;AACH,qBAAa,kCAAmC,SAAQ,cAAc,CACpE,OAAO,cAAc,EACrB,uCAAuC,EACvC,2CAA2C,CAC5C;;gBAKa,EACV,KAAU,EACV,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,KAAK,CAAC,EAAE,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACzD,SAAS,EAAE,2CAA2C,CAAC;QACvD,kBAAkB,EAAE,0BAA0B,CAAC;KAChD;IAiCK,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4D1E"}
@@ -1 +1 @@
1
- {"version":3,"file":"TokenSearchDiscoveryDataController.mjs","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Hex } from '@metamask/utils';\n\nimport type { TokenDisplayData } from './types';\nimport { formatIconUrlWithProxy } from '../assetsUtil';\nimport type { GetCurrencyRateState } from '../CurrencyRateController';\nimport type { AbstractTokenPricesService } from '../token-prices-service';\nimport {\n fetchTokenMetadata,\n TOKEN_METADATA_NO_SUPPORT_ERROR,\n} from '../token-service';\nimport type { TokenListToken } from '../TokenListController';\n\n// === GENERAL ===\n\nexport const controllerName = 'TokenSearchDiscoveryDataController';\n\nexport const MAX_TOKEN_DISPLAY_DATA_LENGTH = 10;\n\n// === STATE ===\n\nexport type TokenSearchDiscoveryDataControllerState = {\n tokenDisplayData: TokenDisplayData[];\n};\n\nconst tokenSearchDiscoveryDataControllerMetadata: StateMetadata<TokenSearchDiscoveryDataControllerState> =\n {\n tokenDisplayData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n } as const;\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} registers, to be\n * called externally.\n */\nexport type TokenSearchDiscoveryDataControllerActions =\n TokenSearchDiscoveryDataControllerGetStateAction;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} calls internally.\n */\nexport type AllowedActions = GetCurrencyRateState;\n\n/**\n * The event that {@link TokenSearchDiscoveryDataController} publishes when updating\n * state.\n */\nexport type TokenSearchDiscoveryDataControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} publishes, to be\n * subscribed to externally.\n */\nexport type TokenSearchDiscoveryDataControllerEvents =\n TokenSearchDiscoveryDataControllerStateChangeEvent;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} subscribes to internally.\n */\nexport type AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerMessenger = Messenger<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerActions | AllowedActions,\n TokenSearchDiscoveryDataControllerEvents | AllowedEvents\n>;\n\n/**\n * Constructs the default {@link TokenSearchDiscoveryDataController} 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 TokenSearchDiscoveryDataController} state.\n */\nexport function getDefaultTokenSearchDiscoveryDataControllerState(): TokenSearchDiscoveryDataControllerState {\n return {\n tokenDisplayData: [],\n };\n}\n\n/**\n * The TokenSearchDiscoveryDataController manages the retrieval of token search results and token discovery.\n * It fetches token metadata from the Token API and token prices from the token prices service.\n */\nexport class TokenSearchDiscoveryDataController extends BaseController<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState,\n TokenSearchDiscoveryDataControllerMessenger\n> {\n readonly #abortController: AbortController;\n\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n constructor({\n state = {},\n messenger,\n tokenPricesService,\n }: {\n state?: Partial<TokenSearchDiscoveryDataControllerState>;\n messenger: TokenSearchDiscoveryDataControllerMessenger;\n tokenPricesService: AbstractTokenPricesService;\n }) {\n super({\n name: controllerName,\n metadata: tokenSearchDiscoveryDataControllerMetadata,\n messenger,\n state: {\n ...getDefaultTokenSearchDiscoveryDataControllerState(),\n ...state,\n },\n });\n\n this.#abortController = new AbortController();\n this.#tokenPricesService = tokenPricesService;\n }\n\n async #fetchPriceData(chainId: Hex, address: string) {\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n try {\n const pricesData = await this.#tokenPricesService.fetchTokenPrices({\n assets: [{ chainId, tokenAddress: address as Hex }],\n currency: currentCurrency,\n });\n\n return pricesData[0] ?? null;\n } catch (error) {\n console.error(error);\n return null;\n }\n }\n\n async fetchTokenDisplayData(chainId: Hex, address: string): Promise<void> {\n let tokenMetadata: TokenListToken | undefined;\n try {\n tokenMetadata = await fetchTokenMetadata<TokenListToken>(\n chainId,\n address,\n this.#abortController.signal,\n );\n } catch (error) {\n if (\n !(error instanceof Error) ||\n !error.message.includes(TOKEN_METADATA_NO_SUPPORT_ERROR)\n ) {\n throw error;\n }\n }\n\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n let tokenDisplayData: TokenDisplayData;\n if (!tokenMetadata) {\n tokenDisplayData = {\n found: false,\n address,\n chainId,\n currency: currentCurrency,\n };\n } else {\n const priceData = await this.#fetchPriceData(chainId, address);\n tokenDisplayData = {\n found: true,\n address,\n chainId,\n currency: currentCurrency,\n token: {\n ...tokenMetadata,\n isERC721: false,\n image: formatIconUrlWithProxy({\n chainId,\n tokenAddress: address,\n }),\n },\n price: priceData,\n };\n }\n\n this.update((state) => {\n state.tokenDisplayData = [\n tokenDisplayData,\n ...state.tokenDisplayData.filter(\n (token) =>\n token.address !== address ||\n token.chainId !== chainId ||\n token.currency !== currentCurrency,\n ),\n ].slice(0, MAX_TOKEN_DISPLAY_DATA_LENGTH);\n });\n }\n}\n"]}
1
+ {"version":3,"file":"TokenSearchDiscoveryDataController.mjs","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Hex } from '@metamask/utils';\n\nimport { formatIconUrlWithProxy } from '../assetsUtil';\nimport type { GetCurrencyRateState } from '../CurrencyRateController';\nimport type { AbstractTokenPricesService } from '../token-prices-service';\nimport {\n fetchTokenMetadata,\n TOKEN_METADATA_NO_SUPPORT_ERROR,\n} from '../token-service';\nimport type { TokenListToken } from '../TokenListController';\nimport type { TokenDisplayData } from './types';\n\n// === GENERAL ===\n\nexport const controllerName = 'TokenSearchDiscoveryDataController';\n\nexport const MAX_TOKEN_DISPLAY_DATA_LENGTH = 10;\n\n// === STATE ===\n\nexport type TokenSearchDiscoveryDataControllerState = {\n tokenDisplayData: TokenDisplayData[];\n};\n\nconst tokenSearchDiscoveryDataControllerMetadata: StateMetadata<TokenSearchDiscoveryDataControllerState> =\n {\n tokenDisplayData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n } as const;\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} registers, to be\n * called externally.\n */\nexport type TokenSearchDiscoveryDataControllerActions =\n TokenSearchDiscoveryDataControllerGetStateAction;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} calls internally.\n */\nexport type AllowedActions = GetCurrencyRateState;\n\n/**\n * The event that {@link TokenSearchDiscoveryDataController} publishes when updating\n * state.\n */\nexport type TokenSearchDiscoveryDataControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} publishes, to be\n * subscribed to externally.\n */\nexport type TokenSearchDiscoveryDataControllerEvents =\n TokenSearchDiscoveryDataControllerStateChangeEvent;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} subscribes to internally.\n */\nexport type AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerMessenger = Messenger<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerActions | AllowedActions,\n TokenSearchDiscoveryDataControllerEvents | AllowedEvents\n>;\n\n/**\n * Constructs the default {@link TokenSearchDiscoveryDataController} 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 TokenSearchDiscoveryDataController} state.\n */\nexport function getDefaultTokenSearchDiscoveryDataControllerState(): TokenSearchDiscoveryDataControllerState {\n return {\n tokenDisplayData: [],\n };\n}\n\n/**\n * The TokenSearchDiscoveryDataController manages the retrieval of token search results and token discovery.\n * It fetches token metadata from the Token API and token prices from the token prices service.\n */\nexport class TokenSearchDiscoveryDataController extends BaseController<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState,\n TokenSearchDiscoveryDataControllerMessenger\n> {\n readonly #abortController: AbortController;\n\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n constructor({\n state = {},\n messenger,\n tokenPricesService,\n }: {\n state?: Partial<TokenSearchDiscoveryDataControllerState>;\n messenger: TokenSearchDiscoveryDataControllerMessenger;\n tokenPricesService: AbstractTokenPricesService;\n }) {\n super({\n name: controllerName,\n metadata: tokenSearchDiscoveryDataControllerMetadata,\n messenger,\n state: {\n ...getDefaultTokenSearchDiscoveryDataControllerState(),\n ...state,\n },\n });\n\n this.#abortController = new AbortController();\n this.#tokenPricesService = tokenPricesService;\n }\n\n async #fetchPriceData(chainId: Hex, address: string) {\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n try {\n const pricesData = await this.#tokenPricesService.fetchTokenPrices({\n assets: [{ chainId, tokenAddress: address as Hex }],\n currency: currentCurrency,\n });\n\n return pricesData[0] ?? null;\n } catch (error) {\n console.error(error);\n return null;\n }\n }\n\n async fetchTokenDisplayData(chainId: Hex, address: string): Promise<void> {\n let tokenMetadata: TokenListToken | undefined;\n try {\n tokenMetadata = await fetchTokenMetadata<TokenListToken>(\n chainId,\n address,\n this.#abortController.signal,\n );\n } catch (error) {\n if (\n !(error instanceof Error) ||\n !error.message.includes(TOKEN_METADATA_NO_SUPPORT_ERROR)\n ) {\n throw error;\n }\n }\n\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n let tokenDisplayData: TokenDisplayData;\n if (!tokenMetadata) {\n tokenDisplayData = {\n found: false,\n address,\n chainId,\n currency: currentCurrency,\n };\n } else {\n const priceData = await this.#fetchPriceData(chainId, address);\n tokenDisplayData = {\n found: true,\n address,\n chainId,\n currency: currentCurrency,\n token: {\n ...tokenMetadata,\n isERC721: false,\n image: formatIconUrlWithProxy({\n chainId,\n tokenAddress: address,\n }),\n },\n price: priceData,\n };\n }\n\n this.update((state) => {\n state.tokenDisplayData = [\n tokenDisplayData,\n ...state.tokenDisplayData.filter(\n (token) =>\n token.address !== address ||\n token.chainId !== chainId ||\n token.currency !== currentCurrency,\n ),\n ].slice(0, MAX_TOKEN_DISPLAY_DATA_LENGTH);\n });\n }\n}\n"]}
@@ -20,10 +20,10 @@ const contracts_1 = require("@ethersproject/contracts");
20
20
  const controller_utils_1 = require("@metamask/controller-utils");
21
21
  const utils_1 = require("@metamask/utils");
22
22
  const bn_js_1 = __importDefault(require("bn.js"));
23
- const multi_chain_accounts_1 = require("./multi-chain-accounts.cjs");
24
23
  const AssetsContractController_1 = require("../AssetsContractController.cjs");
25
24
  const assetsUtil_1 = require("../assetsUtil.cjs");
26
25
  const constants_1 = require("../constants.cjs");
26
+ const multi_chain_accounts_1 = require("./multi-chain-accounts.cjs");
27
27
  // Maximum number of account addresses that can be sent to the accounts API in a single request
28
28
  const ACCOUNTS_API_BATCH_SIZE = 20;
29
29
  // Timeout for accounts API requests (10 seconds)
@@ -1 +1 @@
1
- {"version":3,"file":"api-balance-fetcher.cjs","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/api-balance-fetcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AACA,wDAAoD;AAEpD,iEAKoC;AAGpC,2CAAmD;AACnD,kDAAuB;AAEvB,qEAAmE;AAEnE,8EAAkF;AAClF,kDAIuB;AACvB,gDAAkE;AAElE,+FAA+F;AAC/F,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAEnC,iDAAiD;AACjD,MAAM,uBAAuB,GAAG,KAAM,CAAC;AAwCvC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAmB,EAAE,CACjD,IAAA,uCAAoB,EAAC,IAAI,CAAoB,CAAC;AAEhD,MAAM,aAAa,GAAG,CACpB,OAAmB,EACnB,OAAwB,EACJ,EAAE,CAAC,IAAA,0CAA6B,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAIzE,MAAa,yBAAyB;IAWpC,YACE,WAAmC,WAAW,EAC9C,WAAiC,EACjC,aAIC;;QAjBM,8CAAoC,WAAW,EAAC;QAEhD,yDAAmC;QAEnC,2DAIP;QAWA,uBAAA,IAAI,uCAAa,QAAQ,MAAA,CAAC;QAC1B,uBAAA,IAAI,0CAAgB,WAAW,MAAA,CAAC;QAChC,uBAAA,IAAI,4CAAkB,aAAa,MAAA,CAAC;IACtC,CAAC;IAED,QAAQ,CAAC,OAAmB;QAC1B,OAAO,8CAAkC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;IAqLD,KAAK,CAAC,KAAK,CAAC,EACV,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,QAAQ,GAC+B;QACvC,MAAM,SAAS,GAAyB,EAAE,CAAC;QAE3C,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACvE,IAAI,gBAAgB,EAAE,CAAC;gBACrB,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACxB,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,OAA0B,CAAC,CAAC,CACrE,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YACtB,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC1B,CAAC;QAED,mEAAmE;QACnE,wDAAwD;QACxD,MAAM,WAAW,GAAG,MAAM,IAAA,2CAAwB,EAChD,GAAG,EAAE,CAAC,uBAAA,IAAI,sFAAe,MAAnB,IAAI,EAAgB,SAAS,EAAE,QAAQ,CAAC,EAC9C,KAAK,EAAE,yCAAyC;QAChD,uBAAuB,CACxB,CAAC;QAEF,uEAAuE;QACvE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QAED,4DAA4D;QAC5D,uEAAuE;QACvE,oDAAoD;QACpD,MAAM,mBAAmB,GAA6B,WAAW;aAC9D,mBAAmB,EAAE,MAAM;YAC5B,CAAC,CAAC,WAAW,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC9C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;oBAChC,sCAAsC;oBACtC,OAAO,IAAA,wBAAK,EAAC,IAAA,wBAAgB,EAAC,OAAsB,CAAC,CAAC,SAAS,CAAC,CAAC;gBACnE,CAAC;gBACD,wBAAwB;gBACxB,OAAO,IAAA,wBAAK,EAAC,OAAO,CAAC,CAAC;YACxB,CAAC,CAAC;YACJ,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,cAAc,GAAG,MAAM,uBAAA,IAAI,4FAAqB,MAAzB,IAAI,EAAsB,SAAS,CAAC,CAAC;QAElE,MAAM,OAAO,GAAuB,EAAE,CAAC;QAEvC,kEAAkE;QAClE,MAAM,eAAe,GAAG,IAAI,GAAG,EAA2B,CAAC;QAC3D,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC7B,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,IAAA,wBAAK,EAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;YAC9C,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;YAE1C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC1C,eAAe,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;YAClD,CAAC;YACD,eAAe,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,8EAA8E;QAC9E,MAAM,YAAY,GAChB,4CAA+D,CAAC;QAClE,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAc,CAAC,CAAC,sCAAsC;QAC3F,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAc,CAAC,CAAC,sDAAsD;QAE9G,+BAA+B;QAC/B,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,CAC9C,CAAC,CAA0C,EAAE,EAAE;gBAC7C,MAAM,WAAW,GAAG,CAAC,CAAC,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,OAAO,EAAE,CAAC;gBACZ,CAAC;gBACD,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;gBACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBAClC,uEAAuE;gBACvE,qFAAqF;gBACrF,4DAA4D;gBAC5D,MAAM,YAAY,GAChB,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC;gBACjD,MAAM,OAAO,GAAG,IAAA,wBAAK,EAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBAEjC,IAAI,KAAqB,CAAC;gBAC1B,IAAI,CAAC;oBACH,wEAAwE;oBACxE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;oBAE5C,0DAA0D;oBAC1D,MAAM,CAAC,WAAW,GAAG,GAAG,EAAE,WAAW,GAAG,EAAE,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAEpE,uDAAuD;oBACvD,MAAM,iBAAiB,GAAG,WAAW;yBAClC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC;yBACrB,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;oBAEtB,wBAAwB;oBACxB,MAAM,cAAc,GAAG,WAAW,GAAG,iBAAiB,CAAC;oBACvD,KAAK,GAAG,IAAI,eAAE,CAAC,cAAc,CAAC,CAAC;gBACjC,CAAC;gBAAC,MAAM,CAAC;oBACP,KAAK,GAAG,SAAS,CAAC;gBACpB,CAAC;gBAED,kCAAkC;gBAClC,IAAI,KAAK,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBAClD,qBAAqB,CAAC,GAAG,CAAC,GAAG,YAAY,IAAI,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;gBACjE,CAAC;gBAED,IAAI,KAAK,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBAClD,wBAAwB,CAAC,GAAG,CAC1B,GAAG,YAAY,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,OAAO,EAAE,EACjE,KAAK,CACN,CAAC;gBACJ,CAAC;gBAED,OAAO;oBACL;wBACE,OAAO,EAAE,KAAK,KAAK,SAAS;wBAC5B,KAAK;wBACL,OAAO,EAAE,YAAY;wBACrB,KAAK;wBACL,OAAO;qBACR;iBACF,CAAC;YACJ,CAAC,CACF,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;QAC/B,CAAC;QAED,MAAM,0BAA0B,GAAG,CAAC,OAAe,EAAW,EAAE,CAC9D,gBAAgB;YACd,CAAC,CAAC,WAAW,CAAC,IAAI,CACd,CAAC,cAAc,EAAE,EAAE,CACjB,cAAc,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CACjE;YACH,CAAC,CAAC,eAAe,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC;QAE9D,MAAM,iBAAiB,GAAsB,EAAE,CAAC;QAEhD,MAAM,mBAAmB,GAAG,CAC1B,OAAe,EACf,OAAmB,EACnB,YAAoB,EACd,EAAE;YACR,iBAAiB,CAAC,OAAO,MAAzB,iBAAiB,CAAC,OAAO,IAAM,EAAE,EAAC;YAClC,MAAM,+BAA+B,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;YACnE,+BAA+B,CAAC,OAAO,MAAvC,+BAA+B,CAAC,OAAO,IAAM,EAAE,EAAC;YAChD,MAAM,wBAAwB,GAAG,+BAA+B,CAAC,OAAO,CAAC,CAAC;YAC1E,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBACrD,wBAAwB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC,CAAC;QAEF,uEAAuE;QACvE,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;YAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBACzB,MAAM,GAAG,GAAG,GAAG,OAAO,IAAI,OAAO,EAAE,CAAC;gBACpC,MAAM,eAAe,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACvD,MAAM,wBAAwB,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAChD,MAAM,iBAAiB,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;gBAC9D,MAAM,oBAAoB,GACxB,CAAC,eAAe;oBAChB,wBAAwB;oBACxB,gBAAgB;oBAChB,iBAAiB,CAAC;gBAEpB,IAAI,oBAAoB,EAAE,CAAC;oBACzB,uEAAuE;oBACvE,OAAO,CAAC,IAAI,CAAC;wBACX,OAAO,EAAE,IAAI;wBACb,KAAK,EAAE,IAAI,eAAE,CAAC,GAAG,CAAC;wBAClB,OAAO,EAAE,OAA0B;wBACnC,KAAK,EAAE,YAAY;wBACnB,OAAO;qBACR,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,gEAAgE;QAChE,gEAAgE;QAChE,2DAA2D;QAC3D,IAAI,uBAAA,IAAI,gDAAe,EAAE,CAAC;YACxB,MAAM,UAAU,GAAG,uBAAA,IAAI,gDAAe,MAAnB,IAAI,CAAiB,CAAC;YACzC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE;gBACvD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE;oBACnD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,EAAE;wBAChD,MAAM,cAAc,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;wBAClD,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,cAAc,IAAI,OAAO,EAAE,CAAC;wBACpE,MAAM,KAAK,GAAG,YAAY,KAAK,YAAY,CAAC;wBAC5C,MAAM,eAAe,GAAG,wBAAwB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;wBAC1D,MAAM,wBAAwB,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAc,CAAC,CAAC;wBACnE,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAc,CAAC,CAAC;wBACvD,MAAM,iBAAiB,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;wBAC9D,MAAM,oBAAoB,GACxB,CAAC,eAAe;4BAChB,wBAAwB;4BACxB,gBAAgB;4BAChB,iBAAiB,CAAC;wBAEpB,IAAI,KAAK,IAAI,oBAAoB,EAAE,CAAC;4BAClC,mBAAmB,CACjB,OAAO,CAAC,WAAW,EAAE,EACrB,OAAqB,EACrB,cAAc,CACf,CAAC;wBACJ,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QAED,sBAAsB;QACtB,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;QAEhC,OAAO;YACL,QAAQ,EAAE,OAAO;YACjB,mBAAmB;YACnB,iBAAiB,EACf,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC;gBACvC,CAAC,CAAC,iBAAiB;gBACnB,CAAC,CAAC,SAAS;SAChB,CAAC;IACJ,CAAC;CACF;AAzbD,8DAybC;8QA5ZC,KAAK,yDACH,KAA2B;IAE3B,sEAAsE;IACtE,IAAI,CAAC,uBAAA,IAAI,8CAAa,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAuB,EAAE,CAAC;IAEvC,8BAA8B;IAC9B,MAAM,gBAAgB,GAA0C,EAAE,CAAC;IAEnE,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;QAC7B,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,IAAA,wBAAK,EAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;QAC9C,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QAE1C,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjC,CAAC;QACD,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAClD,CAAC;IAED,+BAA+B;IAC/B,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpE,MAAM,UAAU,GAAG,OAAqB,CAAC;QAEzC,sEAAsE;QACtE,IACE,CAAC;YACC,2CAA8B,CAAC,OAAO;YACtC,2CAA8B,CAAC,KAAK;SACrC,CAAC,QAAQ,CAAC,UAA4C,CAAC,EACxD,CAAC;YACD,SAAS;QACX,CAAC;QAED,uDAAuD;QACvD,IAAI,CAAC,CAAC,UAAU,IAAI,8DAAmC,CAAC,EAAE,CAAC;YACzD,SAAS;QACX,CAAC;QAED,MAAM,eAAe,GAAG,8DAAmC,CAAC,UAAU,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,uBAAA,IAAI,8CAAa,MAAjB,IAAI,EAAc,UAAU,CAAC,CAAC;QAE/C,MAAM,GAAG,GAAG;YACV;gBACE,MAAM,EAAE;oBACN,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;iBAC9D;gBACD,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;gBACjE,eAAe,EAAE,MAAM;gBACvB,IAAI,EAAE,UAAU;aACjB;YACD;gBACE,MAAM,EAAE;oBACN,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;iBAC7D;gBACD,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE;oBACP,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;iBAC7D;gBACD,eAAe,EAAE,MAAM;gBACvB,IAAI,EAAE,UAAU;aACjB;SACF,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,oBAAQ,CAAC,eAAe,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;YAE9D,8BAA8B;YAC9B,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,IAAA,gCAAa,EAAC,GAAG,EAAE,CACtC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAC5B,CAAC;oBAEF,IAAI,MAAM,IAAK,MAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC1C,sDAAsD;wBACtD,MAAM,MAAM,GAAG,MAAM,IAAA,gCAAa,EAAC,GAAG,EAAE,CACtC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CACjC,CAAC;wBAEF,IAAI,MAAM,EAAE,CAAC;4BACX,OAAO,CAAC,IAAI,CAAC;gCACX,OAAO,EAAE,IAAI;gCACb,KAAK,EAAE,IAAI,eAAE,CAAE,MAAoB,CAAC,QAAQ,EAAE,CAAC;gCAC/C,OAAO,EAAE,OAAO;gCAChB,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC;gCAChC,OAAO,EAAE,UAAU;6BACpB,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,yDAAyD;wBACzD,OAAO,CAAC,IAAI,CAAC;4BACX,OAAO,EAAE,IAAI;4BACb,KAAK,EAAE,IAAI,eAAE,CAAC,GAAG,CAAC;4BAClB,OAAO,EAAE,OAAO;4BAChB,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC;4BAChC,OAAO,EAAE,UAAU;yBACpB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,2CAA2C;oBAC3C,OAAO,CAAC,KAAK,CACX,qCAAqC,OAAO,GAAG,EAC/C,KAAK,CACN,CAAC;oBACF,OAAO,CAAC,IAAI,CAAC;wBACX,OAAO,EAAE,KAAK;wBACd,OAAO,EAAE,OAAO;wBAChB,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC;wBAChC,OAAO,EAAE,UAAU;qBACpB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,+CAA+C,OAAO,GAAG,EACzD,KAAK,CACN,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,6CAED,KAAK,mDACH,KAA2B,EAC3B,QAAiB;IAEjB,0EAA0E;IAC1E,IAAI,KAAK,CAAC,MAAM,IAAI,uBAAuB,EAAE,CAAC;QAC5C,OAAO,MAAM,IAAA,gDAAyB,EACpC,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAC3B,uBAAA,IAAI,2CAAU,EACd,QAAQ,CACT,CAAC;IACJ,CAAC;IASD,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC1D,MAAM,WAAW,GAAG,MAAM,IAAA,oCAAuB,EAG/C;QACA,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,uBAAuB;QAClC,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE;YACxC,MAAM,QAAQ,GAAG,MAAM,IAAA,gDAAyB,EAC9C,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAC3B,uBAAA,IAAI,2CAAU,EACd,QAAQ,CACT,CAAC;YACF,+CAA+C;YAC/C,IAAI,QAAQ,CAAC,mBAAmB,EAAE,CAAC;gBACjC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC/C,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,CACpC,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1D,CAAC;QACD,aAAa,EAAE,EAAE;KAClB,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ,EAAE,WAAW;QACrB,mBAAmB,EAAE,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC;KACxC,CAAC;AACpB,CAAC","sourcesContent":["import type { BigNumber } from '@ethersproject/bignumber';\nimport { Contract } from '@ethersproject/contracts';\nimport type { Web3Provider } from '@ethersproject/providers';\nimport {\n safelyExecute,\n safelyExecuteWithTimeout,\n toHex,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { CaipAccountAddress, CaipChainId, Hex } from '@metamask/utils';\nimport { parseCaipChainId } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { fetchMultiChainBalancesV4 } from './multi-chain-accounts';\nimport type { GetBalancesResponse } from './types';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from '../AssetsContractController';\nimport {\n accountAddressToCaipReference,\n reduceInBatchesSerially,\n SupportedStakedBalanceNetworks,\n} from '../assetsUtil';\nimport { SUPPORTED_NETWORKS_ACCOUNTS_API_V4 } from '../constants';\n\n// Maximum number of account addresses that can be sent to the accounts API in a single request\nconst ACCOUNTS_API_BATCH_SIZE = 20;\n\n// Timeout for accounts API requests (10 seconds)\nconst ACCOUNTS_API_TIMEOUT_MS = 10_000;\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nexport type ProcessedBalance = {\n success: boolean;\n value?: BN;\n account: ChecksumAddress | string;\n token: ChecksumAddress;\n chainId: ChainIdHex;\n};\n\n/**\n * Account -> ChainId -> TokenAddress[]\n */\nexport type UnprocessedTokens = {\n [account: string]: {\n [chainId: ChainIdHex]: string[];\n };\n};\n\nexport type BalanceFetchResult = {\n balances: ProcessedBalance[];\n unprocessedChainIds?: ChainIdHex[];\n unprocessedTokens?: UnprocessedTokens;\n};\n\nexport type BalanceFetcher = {\n supports(chainId: ChainIdHex): boolean;\n fetch(input: {\n chainIds: ChainIdHex[];\n queryAllAccounts: boolean;\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n jwtToken?: string;\n unprocessedTokens?: UnprocessedTokens; // API Balance Fetcher does not process unprocessed tokens\n }): Promise<BalanceFetchResult>;\n};\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\nconst toCaipAccount = (\n chainId: ChainIdHex,\n account: ChecksumAddress,\n): CaipAccountAddress => accountAddressToCaipReference(chainId, account);\n\nexport type GetProviderFunction = (chainId: ChainIdHex) => Web3Provider;\n\nexport class AccountsApiBalanceFetcher implements BalanceFetcher {\n readonly #platform: 'extension' | 'mobile' = 'extension';\n\n readonly #getProvider?: GetProviderFunction;\n\n readonly #getUserTokens?: () => {\n [accountId: ChecksumAddress]: {\n [chainId: ChainIdHex]: { [tokenAddress: ChecksumAddress]: unknown };\n };\n };\n\n constructor(\n platform: 'extension' | 'mobile' = 'extension',\n getProvider?: GetProviderFunction,\n getUserTokens?: () => {\n [account: ChecksumAddress]: {\n [chainId: ChainIdHex]: { [tokenAddress: ChecksumAddress]: unknown };\n };\n },\n ) {\n this.#platform = platform;\n this.#getProvider = getProvider;\n this.#getUserTokens = getUserTokens;\n }\n\n supports(chainId: ChainIdHex): boolean {\n return SUPPORTED_NETWORKS_ACCOUNTS_API_V4.includes(chainId);\n }\n\n async #fetchStakedBalances(\n addrs: CaipAccountAddress[],\n ): Promise<ProcessedBalance[]> {\n // Return empty array if no provider is available for blockchain calls\n if (!this.#getProvider) {\n return [];\n }\n\n const results: ProcessedBalance[] = [];\n\n // Group addresses by chain ID\n const addressesByChain: Record<ChainIdHex, ChecksumAddress[]> = {};\n\n for (const caipAddr of addrs) {\n const [, chainRef, address] = caipAddr.split(':');\n const chainId = toHex(parseInt(chainRef, 10));\n const checksumAddress = checksum(address);\n\n if (!addressesByChain[chainId]) {\n addressesByChain[chainId] = [];\n }\n addressesByChain[chainId].push(checksumAddress);\n }\n\n // Process each supported chain\n for (const [chainId, addresses] of Object.entries(addressesByChain)) {\n const chainIdHex = chainId as ChainIdHex;\n\n // Only fetch staked balance on supported networks (mainnet and hoodi)\n if (\n ![\n SupportedStakedBalanceNetworks.Mainnet,\n SupportedStakedBalanceNetworks.Hoodi,\n ].includes(chainIdHex as SupportedStakedBalanceNetworks)\n ) {\n continue;\n }\n\n // Only fetch staked balance if contract address exists\n if (!(chainIdHex in STAKING_CONTRACT_ADDRESS_BY_CHAINID)) {\n continue;\n }\n\n const contractAddress = STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainIdHex];\n const provider = this.#getProvider(chainIdHex);\n\n const abi = [\n {\n inputs: [\n { internalType: 'address', name: 'account', type: 'address' },\n ],\n name: 'getShares',\n outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'uint256', name: 'shares', type: 'uint256' },\n ],\n name: 'convertToAssets',\n outputs: [\n { internalType: 'uint256', name: 'assets', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n ];\n\n try {\n const contract = new Contract(contractAddress, abi, provider);\n\n // Get shares for each address\n for (const address of addresses) {\n try {\n const shares = await safelyExecute(() =>\n contract.getShares(address),\n );\n\n if (shares && (shares as BigNumber).gt(0)) {\n // Convert shares to assets (actual staked ETH amount)\n const assets = await safelyExecute(() =>\n contract.convertToAssets(shares),\n );\n\n if (assets) {\n results.push({\n success: true,\n value: new BN((assets as BigNumber).toString()),\n account: address,\n token: checksum(contractAddress),\n chainId: chainIdHex,\n });\n }\n } else {\n // Return zero balance for accounts with no staked assets\n results.push({\n success: true,\n value: new BN('0'),\n account: address,\n token: checksum(contractAddress),\n chainId: chainIdHex,\n });\n }\n } catch (error) {\n // Log error and continue with next address\n console.error(\n `Error fetching staked balance for ${address}:`,\n error,\n );\n results.push({\n success: false,\n account: address,\n token: checksum(contractAddress),\n chainId: chainIdHex,\n });\n }\n }\n } catch (error) {\n console.error(\n `Error setting up staking contract for chain ${chainId}:`,\n error,\n );\n }\n }\n\n return results;\n }\n\n async #fetchBalances(\n addrs: CaipAccountAddress[],\n jwtToken?: string,\n ): Promise<GetBalancesResponse> {\n // If we have fewer than or equal to the batch size, make a single request\n if (addrs.length <= ACCOUNTS_API_BATCH_SIZE) {\n return await fetchMultiChainBalancesV4(\n { accountAddresses: addrs },\n this.#platform,\n jwtToken,\n );\n }\n\n // Otherwise, batch the requests to respect the 50-element limit\n type BalanceData = Awaited<\n ReturnType<typeof fetchMultiChainBalancesV4>\n >['balances'][number];\n\n type ResponseData = Awaited<ReturnType<typeof fetchMultiChainBalancesV4>>;\n\n const allUnprocessedNetworks = new Set<number | string>();\n const allBalances = await reduceInBatchesSerially<\n CaipAccountAddress,\n BalanceData[]\n >({\n values: addrs,\n batchSize: ACCOUNTS_API_BATCH_SIZE,\n eachBatch: async (workingResult, batch) => {\n const response = await fetchMultiChainBalancesV4(\n { accountAddresses: batch },\n this.#platform,\n jwtToken,\n );\n // Collect unprocessed networks from each batch\n if (response.unprocessedNetworks) {\n response.unprocessedNetworks.forEach((network) =>\n allUnprocessedNetworks.add(network),\n );\n }\n return [...(workingResult || []), ...response.balances];\n },\n initialResult: [],\n });\n\n return {\n balances: allBalances,\n unprocessedNetworks: Array.from(allUnprocessedNetworks),\n } as ResponseData;\n }\n\n async fetch({\n chainIds,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n jwtToken,\n }: Parameters<BalanceFetcher['fetch']>[0]): Promise<BalanceFetchResult> {\n const caipAddrs: CaipAccountAddress[] = [];\n\n for (const chainId of chainIds.filter((chain) => this.supports(chain))) {\n if (queryAllAccounts) {\n allAccounts.forEach((a) =>\n caipAddrs.push(toCaipAccount(chainId, a.address as ChecksumAddress)),\n );\n } else {\n caipAddrs.push(toCaipAccount(chainId, selectedAccount));\n }\n }\n\n if (!caipAddrs.length) {\n return { balances: [] };\n }\n\n // Let errors propagate to TokenBalancesController for RPC fallback\n // Use timeout to prevent hanging API calls (30 seconds)\n const apiResponse = await safelyExecuteWithTimeout(\n () => this.#fetchBalances(caipAddrs, jwtToken),\n false, // don't log error here, let it propagate\n ACCOUNTS_API_TIMEOUT_MS,\n );\n\n // If API call timed out or failed, throw error to trigger RPC fallback\n if (!apiResponse) {\n throw new Error('Accounts API request timed out or failed');\n }\n\n // Extract unprocessed networks and convert to hex chain IDs\n // V4 API returns CAIP chain IDs like 'eip155:1329', need to parse them\n // V2 API returns decimal numbers, handle both cases\n const unprocessedChainIds: ChainIdHex[] | undefined = apiResponse\n .unprocessedNetworks?.length\n ? apiResponse.unprocessedNetworks.map((network) => {\n if (typeof network === 'string') {\n // CAIP chain ID format: 'eip155:1329'\n return toHex(parseCaipChainId(network as CaipChainId).reference);\n }\n // Decimal number format\n return toHex(network);\n })\n : undefined;\n\n const stakedBalances = await this.#fetchStakedBalances(caipAddrs);\n\n const results: ProcessedBalance[] = [];\n\n // Collect all unique addresses and chains from the CAIP addresses\n const addressChainMap = new Map<string, Set<ChainIdHex>>();\n caipAddrs.forEach((caipAddr) => {\n const [, chainRef, address] = caipAddr.split(':');\n const chainId = toHex(parseInt(chainRef, 10));\n const checksumAddress = checksum(address);\n\n if (!addressChainMap.has(checksumAddress)) {\n addressChainMap.set(checksumAddress, new Set());\n }\n addressChainMap.get(checksumAddress)?.add(chainId);\n });\n\n // Ensure native token entries exist for all addresses on all requested chains\n const ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n const nativeBalancesFromAPI = new Map<string, BN>(); // key: `${accountAddress}-${chainId}`\n const nonNativeBalancesFromAPI = new Map<string, BN>(); // key: `${accountAddress}-${tokenAddress}-${chainId}`\n\n // Process regular API balances\n if (apiResponse.balances) {\n const apiBalances = apiResponse.balances.flatMap(\n (b: GetBalancesResponse['balances'][number]) => {\n const addressPart = b.accountAddress?.split(':')[2];\n if (!addressPart) {\n return [];\n }\n const account = checksum(addressPart);\n const token = checksum(b.address);\n // Use original address for zero address tokens, checksummed for others\n // TODO: this is a hack to get the correct account address type but needs to be fixed\n // by mgrating tokenBalancesController to checksum addresses\n const finalAccount: ChecksumAddress | string =\n token === ZERO_ADDRESS ? account : addressPart;\n const chainId = toHex(b.chainId);\n\n let value: BN | undefined;\n try {\n // Convert string balance to BN avoiding floating point precision issues\n const { balance: balanceStr, decimals } = b;\n\n // Split the balance string into integer and decimal parts\n const [integerPart = '0', decimalPart = ''] = balanceStr.split('.');\n\n // Pad or truncate decimal part to match token decimals\n const paddedDecimalPart = decimalPart\n .padEnd(decimals, '0')\n .slice(0, decimals);\n\n // Combine and create BN\n const fullIntegerStr = integerPart + paddedDecimalPart;\n value = new BN(fullIntegerStr);\n } catch {\n value = undefined;\n }\n\n // Track native balances for later\n if (token === ZERO_ADDRESS && value !== undefined) {\n nativeBalancesFromAPI.set(`${finalAccount}-${chainId}`, value);\n }\n\n if (token !== ZERO_ADDRESS && value !== undefined) {\n nonNativeBalancesFromAPI.set(\n `${finalAccount.toLowerCase()}-${token.toLowerCase()}-${chainId}`,\n value,\n );\n }\n\n return [\n {\n success: value !== undefined,\n value,\n account: finalAccount,\n token,\n chainId,\n },\n ];\n },\n );\n results.push(...apiBalances);\n }\n\n const isAccountIncludedInRequest = (address: string): boolean =>\n queryAllAccounts\n ? allAccounts.some(\n (currentAccount) =>\n currentAccount.address.toLowerCase() === address.toLowerCase(),\n )\n : selectedAccount.toLowerCase() === address.toLowerCase();\n\n const unprocessedTokens: UnprocessedTokens = {};\n\n const addUnprocessedToken = (\n account: string,\n chainId: ChainIdHex,\n tokenAddress: string,\n ): void => {\n unprocessedTokens[account] ??= {};\n const accountUnprocessedTokensByChain = unprocessedTokens[account];\n accountUnprocessedTokensByChain[chainId] ??= [];\n const accountUnprocessedTokens = accountUnprocessedTokensByChain[chainId];\n if (!accountUnprocessedTokens.includes(tokenAddress)) {\n accountUnprocessedTokens.push(tokenAddress);\n }\n };\n\n // Add zero native balance entries for addresses that API didn't return\n addressChainMap.forEach((chains, address) => {\n chains.forEach((chainId) => {\n const key = `${address}-${chainId}`;\n const existingBalance = nativeBalancesFromAPI.get(key);\n const isChainIncludedInRequest = chainIds.includes(chainId);\n const isChainSupported = this.supports(chainId);\n const isAccountIncluded = isAccountIncludedInRequest(address);\n const shouldZeroOutBalance =\n !existingBalance &&\n isChainIncludedInRequest &&\n isChainSupported &&\n isAccountIncluded;\n\n if (shouldZeroOutBalance) {\n // Add zero native balance entry if API succeeded but didn't return one\n results.push({\n success: true,\n value: new BN('0'),\n account: address as ChecksumAddress,\n token: ZERO_ADDRESS,\n chainId,\n });\n }\n });\n });\n\n // Track ERC-20 balances that were not returned by Accounts API.\n // These can then be fetched by a fallback fetcher (RPC) without\n // overwriting potentially stale balances with zero values.\n if (this.#getUserTokens) {\n const userTokens = this.#getUserTokens();\n Object.entries(userTokens).forEach(([account, chains]) => {\n Object.entries(chains).forEach(([chainId, tokens]) => {\n Object.entries(tokens).forEach(([tokenAddress]) => {\n const tokenLowerCase = tokenAddress.toLowerCase();\n const key = `${account.toLowerCase()}-${tokenLowerCase}-${chainId}`;\n const isERC = tokenAddress !== ZERO_ADDRESS;\n const existingBalance = nonNativeBalancesFromAPI.get(key);\n const isChainIncludedInRequest = chainIds.includes(chainId as Hex);\n const isChainSupported = this.supports(chainId as Hex);\n const isAccountIncluded = isAccountIncludedInRequest(account);\n const shouldZeroOutBalance =\n !existingBalance &&\n isChainIncludedInRequest &&\n isChainSupported &&\n isAccountIncluded;\n\n if (isERC && shouldZeroOutBalance) {\n addUnprocessedToken(\n account.toLowerCase(),\n chainId as ChainIdHex,\n tokenLowerCase,\n );\n }\n });\n });\n });\n }\n\n // Add staked balances\n results.push(...stakedBalances);\n\n return {\n balances: results,\n unprocessedChainIds,\n unprocessedTokens:\n Object.keys(unprocessedTokens).length > 0\n ? unprocessedTokens\n : undefined,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"api-balance-fetcher.cjs","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/api-balance-fetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BigNumber } from '@ethersproject/bignumber';\nimport { Contract } from '@ethersproject/contracts';\nimport type { Web3Provider } from '@ethersproject/providers';\nimport {\n safelyExecute,\n safelyExecuteWithTimeout,\n toHex,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { CaipAccountAddress, CaipChainId, Hex } from '@metamask/utils';\nimport { parseCaipChainId } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from '../AssetsContractController';\nimport {\n accountAddressToCaipReference,\n reduceInBatchesSerially,\n SupportedStakedBalanceNetworks,\n} from '../assetsUtil';\nimport { SUPPORTED_NETWORKS_ACCOUNTS_API_V4 } from '../constants';\nimport { fetchMultiChainBalancesV4 } from './multi-chain-accounts';\nimport type { GetBalancesResponse } from './types';\n\n// Maximum number of account addresses that can be sent to the accounts API in a single request\nconst ACCOUNTS_API_BATCH_SIZE = 20;\n\n// Timeout for accounts API requests (10 seconds)\nconst ACCOUNTS_API_TIMEOUT_MS = 10_000;\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nexport type ProcessedBalance = {\n success: boolean;\n value?: BN;\n account: ChecksumAddress | string;\n token: ChecksumAddress;\n chainId: ChainIdHex;\n};\n\n/**\n * Account -> ChainId -> TokenAddress[]\n */\nexport type UnprocessedTokens = {\n [account: string]: {\n [chainId: ChainIdHex]: string[];\n };\n};\n\nexport type BalanceFetchResult = {\n balances: ProcessedBalance[];\n unprocessedChainIds?: ChainIdHex[];\n unprocessedTokens?: UnprocessedTokens;\n};\n\nexport type BalanceFetcher = {\n supports(chainId: ChainIdHex): boolean;\n fetch(input: {\n chainIds: ChainIdHex[];\n queryAllAccounts: boolean;\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n jwtToken?: string;\n unprocessedTokens?: UnprocessedTokens; // API Balance Fetcher does not process unprocessed tokens\n }): Promise<BalanceFetchResult>;\n};\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\nconst toCaipAccount = (\n chainId: ChainIdHex,\n account: ChecksumAddress,\n): CaipAccountAddress => accountAddressToCaipReference(chainId, account);\n\nexport type GetProviderFunction = (chainId: ChainIdHex) => Web3Provider;\n\nexport class AccountsApiBalanceFetcher implements BalanceFetcher {\n readonly #platform: 'extension' | 'mobile' = 'extension';\n\n readonly #getProvider?: GetProviderFunction;\n\n readonly #getUserTokens?: () => {\n [accountId: ChecksumAddress]: {\n [chainId: ChainIdHex]: { [tokenAddress: ChecksumAddress]: unknown };\n };\n };\n\n constructor(\n platform: 'extension' | 'mobile' = 'extension',\n getProvider?: GetProviderFunction,\n getUserTokens?: () => {\n [account: ChecksumAddress]: {\n [chainId: ChainIdHex]: { [tokenAddress: ChecksumAddress]: unknown };\n };\n },\n ) {\n this.#platform = platform;\n this.#getProvider = getProvider;\n this.#getUserTokens = getUserTokens;\n }\n\n supports(chainId: ChainIdHex): boolean {\n return SUPPORTED_NETWORKS_ACCOUNTS_API_V4.includes(chainId);\n }\n\n async #fetchStakedBalances(\n addrs: CaipAccountAddress[],\n ): Promise<ProcessedBalance[]> {\n // Return empty array if no provider is available for blockchain calls\n if (!this.#getProvider) {\n return [];\n }\n\n const results: ProcessedBalance[] = [];\n\n // Group addresses by chain ID\n const addressesByChain: Record<ChainIdHex, ChecksumAddress[]> = {};\n\n for (const caipAddr of addrs) {\n const [, chainRef, address] = caipAddr.split(':');\n const chainId = toHex(parseInt(chainRef, 10));\n const checksumAddress = checksum(address);\n\n if (!addressesByChain[chainId]) {\n addressesByChain[chainId] = [];\n }\n addressesByChain[chainId].push(checksumAddress);\n }\n\n // Process each supported chain\n for (const [chainId, addresses] of Object.entries(addressesByChain)) {\n const chainIdHex = chainId as ChainIdHex;\n\n // Only fetch staked balance on supported networks (mainnet and hoodi)\n if (\n ![\n SupportedStakedBalanceNetworks.Mainnet,\n SupportedStakedBalanceNetworks.Hoodi,\n ].includes(chainIdHex as SupportedStakedBalanceNetworks)\n ) {\n continue;\n }\n\n // Only fetch staked balance if contract address exists\n if (!(chainIdHex in STAKING_CONTRACT_ADDRESS_BY_CHAINID)) {\n continue;\n }\n\n const contractAddress = STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainIdHex];\n const provider = this.#getProvider(chainIdHex);\n\n const abi = [\n {\n inputs: [\n { internalType: 'address', name: 'account', type: 'address' },\n ],\n name: 'getShares',\n outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'uint256', name: 'shares', type: 'uint256' },\n ],\n name: 'convertToAssets',\n outputs: [\n { internalType: 'uint256', name: 'assets', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n ];\n\n try {\n const contract = new Contract(contractAddress, abi, provider);\n\n // Get shares for each address\n for (const address of addresses) {\n try {\n const shares = await safelyExecute(() =>\n contract.getShares(address),\n );\n\n if (shares && (shares as BigNumber).gt(0)) {\n // Convert shares to assets (actual staked ETH amount)\n const assets = await safelyExecute(() =>\n contract.convertToAssets(shares),\n );\n\n if (assets) {\n results.push({\n success: true,\n value: new BN((assets as BigNumber).toString()),\n account: address,\n token: checksum(contractAddress),\n chainId: chainIdHex,\n });\n }\n } else {\n // Return zero balance for accounts with no staked assets\n results.push({\n success: true,\n value: new BN('0'),\n account: address,\n token: checksum(contractAddress),\n chainId: chainIdHex,\n });\n }\n } catch (error) {\n // Log error and continue with next address\n console.error(\n `Error fetching staked balance for ${address}:`,\n error,\n );\n results.push({\n success: false,\n account: address,\n token: checksum(contractAddress),\n chainId: chainIdHex,\n });\n }\n }\n } catch (error) {\n console.error(\n `Error setting up staking contract for chain ${chainId}:`,\n error,\n );\n }\n }\n\n return results;\n }\n\n async #fetchBalances(\n addrs: CaipAccountAddress[],\n jwtToken?: string,\n ): Promise<GetBalancesResponse> {\n // If we have fewer than or equal to the batch size, make a single request\n if (addrs.length <= ACCOUNTS_API_BATCH_SIZE) {\n return await fetchMultiChainBalancesV4(\n { accountAddresses: addrs },\n this.#platform,\n jwtToken,\n );\n }\n\n // Otherwise, batch the requests to respect the 50-element limit\n type BalanceData = Awaited<\n ReturnType<typeof fetchMultiChainBalancesV4>\n >['balances'][number];\n\n type ResponseData = Awaited<ReturnType<typeof fetchMultiChainBalancesV4>>;\n\n const allUnprocessedNetworks = new Set<number | string>();\n const allBalances = await reduceInBatchesSerially<\n CaipAccountAddress,\n BalanceData[]\n >({\n values: addrs,\n batchSize: ACCOUNTS_API_BATCH_SIZE,\n eachBatch: async (workingResult, batch) => {\n const response = await fetchMultiChainBalancesV4(\n { accountAddresses: batch },\n this.#platform,\n jwtToken,\n );\n // Collect unprocessed networks from each batch\n if (response.unprocessedNetworks) {\n response.unprocessedNetworks.forEach((network) =>\n allUnprocessedNetworks.add(network),\n );\n }\n return [...(workingResult || []), ...response.balances];\n },\n initialResult: [],\n });\n\n return {\n balances: allBalances,\n unprocessedNetworks: Array.from(allUnprocessedNetworks),\n } as ResponseData;\n }\n\n async fetch({\n chainIds,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n jwtToken,\n }: Parameters<BalanceFetcher['fetch']>[0]): Promise<BalanceFetchResult> {\n const caipAddrs: CaipAccountAddress[] = [];\n\n for (const chainId of chainIds.filter((chain) => this.supports(chain))) {\n if (queryAllAccounts) {\n allAccounts.forEach((a) =>\n caipAddrs.push(toCaipAccount(chainId, a.address as ChecksumAddress)),\n );\n } else {\n caipAddrs.push(toCaipAccount(chainId, selectedAccount));\n }\n }\n\n if (!caipAddrs.length) {\n return { balances: [] };\n }\n\n // Let errors propagate to TokenBalancesController for RPC fallback\n // Use timeout to prevent hanging API calls (30 seconds)\n const apiResponse = await safelyExecuteWithTimeout(\n () => this.#fetchBalances(caipAddrs, jwtToken),\n false, // don't log error here, let it propagate\n ACCOUNTS_API_TIMEOUT_MS,\n );\n\n // If API call timed out or failed, throw error to trigger RPC fallback\n if (!apiResponse) {\n throw new Error('Accounts API request timed out or failed');\n }\n\n // Extract unprocessed networks and convert to hex chain IDs\n // V4 API returns CAIP chain IDs like 'eip155:1329', need to parse them\n // V2 API returns decimal numbers, handle both cases\n const unprocessedChainIds: ChainIdHex[] | undefined = apiResponse\n .unprocessedNetworks?.length\n ? apiResponse.unprocessedNetworks.map((network) => {\n if (typeof network === 'string') {\n // CAIP chain ID format: 'eip155:1329'\n return toHex(parseCaipChainId(network as CaipChainId).reference);\n }\n // Decimal number format\n return toHex(network);\n })\n : undefined;\n\n const stakedBalances = await this.#fetchStakedBalances(caipAddrs);\n\n const results: ProcessedBalance[] = [];\n\n // Collect all unique addresses and chains from the CAIP addresses\n const addressChainMap = new Map<string, Set<ChainIdHex>>();\n caipAddrs.forEach((caipAddr) => {\n const [, chainRef, address] = caipAddr.split(':');\n const chainId = toHex(parseInt(chainRef, 10));\n const checksumAddress = checksum(address);\n\n if (!addressChainMap.has(checksumAddress)) {\n addressChainMap.set(checksumAddress, new Set());\n }\n addressChainMap.get(checksumAddress)?.add(chainId);\n });\n\n // Ensure native token entries exist for all addresses on all requested chains\n const ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n const nativeBalancesFromAPI = new Map<string, BN>(); // key: `${accountAddress}-${chainId}`\n const nonNativeBalancesFromAPI = new Map<string, BN>(); // key: `${accountAddress}-${tokenAddress}-${chainId}`\n\n // Process regular API balances\n if (apiResponse.balances) {\n const apiBalances = apiResponse.balances.flatMap(\n (b: GetBalancesResponse['balances'][number]) => {\n const addressPart = b.accountAddress?.split(':')[2];\n if (!addressPart) {\n return [];\n }\n const account = checksum(addressPart);\n const token = checksum(b.address);\n // Use original address for zero address tokens, checksummed for others\n // TODO: this is a hack to get the correct account address type but needs to be fixed\n // by mgrating tokenBalancesController to checksum addresses\n const finalAccount: ChecksumAddress | string =\n token === ZERO_ADDRESS ? account : addressPart;\n const chainId = toHex(b.chainId);\n\n let value: BN | undefined;\n try {\n // Convert string balance to BN avoiding floating point precision issues\n const { balance: balanceStr, decimals } = b;\n\n // Split the balance string into integer and decimal parts\n const [integerPart = '0', decimalPart = ''] = balanceStr.split('.');\n\n // Pad or truncate decimal part to match token decimals\n const paddedDecimalPart = decimalPart\n .padEnd(decimals, '0')\n .slice(0, decimals);\n\n // Combine and create BN\n const fullIntegerStr = integerPart + paddedDecimalPart;\n value = new BN(fullIntegerStr);\n } catch {\n value = undefined;\n }\n\n // Track native balances for later\n if (token === ZERO_ADDRESS && value !== undefined) {\n nativeBalancesFromAPI.set(`${finalAccount}-${chainId}`, value);\n }\n\n if (token !== ZERO_ADDRESS && value !== undefined) {\n nonNativeBalancesFromAPI.set(\n `${finalAccount.toLowerCase()}-${token.toLowerCase()}-${chainId}`,\n value,\n );\n }\n\n return [\n {\n success: value !== undefined,\n value,\n account: finalAccount,\n token,\n chainId,\n },\n ];\n },\n );\n results.push(...apiBalances);\n }\n\n const isAccountIncludedInRequest = (address: string): boolean =>\n queryAllAccounts\n ? allAccounts.some(\n (currentAccount) =>\n currentAccount.address.toLowerCase() === address.toLowerCase(),\n )\n : selectedAccount.toLowerCase() === address.toLowerCase();\n\n const unprocessedTokens: UnprocessedTokens = {};\n\n const addUnprocessedToken = (\n account: string,\n chainId: ChainIdHex,\n tokenAddress: string,\n ): void => {\n unprocessedTokens[account] ??= {};\n const accountUnprocessedTokensByChain = unprocessedTokens[account];\n accountUnprocessedTokensByChain[chainId] ??= [];\n const accountUnprocessedTokens = accountUnprocessedTokensByChain[chainId];\n if (!accountUnprocessedTokens.includes(tokenAddress)) {\n accountUnprocessedTokens.push(tokenAddress);\n }\n };\n\n // Add zero native balance entries for addresses that API didn't return\n addressChainMap.forEach((chains, address) => {\n chains.forEach((chainId) => {\n const key = `${address}-${chainId}`;\n const existingBalance = nativeBalancesFromAPI.get(key);\n const isChainIncludedInRequest = chainIds.includes(chainId);\n const isChainSupported = this.supports(chainId);\n const isAccountIncluded = isAccountIncludedInRequest(address);\n const shouldZeroOutBalance =\n !existingBalance &&\n isChainIncludedInRequest &&\n isChainSupported &&\n isAccountIncluded;\n\n if (shouldZeroOutBalance) {\n // Add zero native balance entry if API succeeded but didn't return one\n results.push({\n success: true,\n value: new BN('0'),\n account: address as ChecksumAddress,\n token: ZERO_ADDRESS,\n chainId,\n });\n }\n });\n });\n\n // Track ERC-20 balances that were not returned by Accounts API.\n // These can then be fetched by a fallback fetcher (RPC) without\n // overwriting potentially stale balances with zero values.\n if (this.#getUserTokens) {\n const userTokens = this.#getUserTokens();\n Object.entries(userTokens).forEach(([account, chains]) => {\n Object.entries(chains).forEach(([chainId, tokens]) => {\n Object.entries(tokens).forEach(([tokenAddress]) => {\n const tokenLowerCase = tokenAddress.toLowerCase();\n const key = `${account.toLowerCase()}-${tokenLowerCase}-${chainId}`;\n const isERC = tokenAddress !== ZERO_ADDRESS;\n const existingBalance = nonNativeBalancesFromAPI.get(key);\n const isChainIncludedInRequest = chainIds.includes(chainId as Hex);\n const isChainSupported = this.supports(chainId as Hex);\n const isAccountIncluded = isAccountIncludedInRequest(account);\n const shouldZeroOutBalance =\n !existingBalance &&\n isChainIncludedInRequest &&\n isChainSupported &&\n isAccountIncluded;\n\n if (isERC && shouldZeroOutBalance) {\n addUnprocessedToken(\n account.toLowerCase(),\n chainId as ChainIdHex,\n tokenLowerCase,\n );\n }\n });\n });\n });\n }\n\n // Add staked balances\n results.push(...stakedBalances);\n\n return {\n balances: results,\n unprocessedChainIds,\n unprocessedTokens:\n Object.keys(unprocessedTokens).length > 0\n ? unprocessedTokens\n : undefined,\n };\n }\n}\n"]}
@@ -21,10 +21,10 @@ import { safelyExecute, safelyExecuteWithTimeout, toHex, toChecksumHexAddress }
21
21
  import { parseCaipChainId } from "@metamask/utils";
22
22
  import $BN from "bn.js";
23
23
  const BN = $importDefault($BN);
24
- import { fetchMultiChainBalancesV4 } from "./multi-chain-accounts.mjs";
25
24
  import { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from "../AssetsContractController.mjs";
26
25
  import { accountAddressToCaipReference, reduceInBatchesSerially, SupportedStakedBalanceNetworks } from "../assetsUtil.mjs";
27
26
  import { SUPPORTED_NETWORKS_ACCOUNTS_API_V4 } from "../constants.mjs";
27
+ import { fetchMultiChainBalancesV4 } from "./multi-chain-accounts.mjs";
28
28
  // Maximum number of account addresses that can be sent to the accounts API in a single request
29
29
  const ACCOUNTS_API_BATCH_SIZE = 20;
30
30
  // Timeout for accounts API requests (10 seconds)