@metamask/assets-controllers 83.1.0 → 85.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.
- package/CHANGELOG.md +39 -2
- package/dist/AccountTrackerController.cjs +20 -21
- package/dist/AccountTrackerController.cjs.map +1 -1
- package/dist/AccountTrackerController.d.cts +4 -3
- package/dist/AccountTrackerController.d.cts.map +1 -1
- package/dist/AccountTrackerController.d.mts +4 -3
- package/dist/AccountTrackerController.d.mts.map +1 -1
- package/dist/AccountTrackerController.mjs +20 -21
- package/dist/AccountTrackerController.mjs.map +1 -1
- package/dist/AssetsContractController.cjs +10 -10
- package/dist/AssetsContractController.cjs.map +1 -1
- package/dist/AssetsContractController.d.cts +3 -3
- package/dist/AssetsContractController.d.cts.map +1 -1
- package/dist/AssetsContractController.d.mts +3 -3
- package/dist/AssetsContractController.d.mts.map +1 -1
- package/dist/AssetsContractController.mjs +10 -10
- package/dist/AssetsContractController.mjs.map +1 -1
- package/dist/CurrencyRateController.cjs +68 -15
- package/dist/CurrencyRateController.cjs.map +1 -1
- package/dist/CurrencyRateController.d.cts +18 -10
- package/dist/CurrencyRateController.d.cts.map +1 -1
- package/dist/CurrencyRateController.d.mts +18 -10
- package/dist/CurrencyRateController.d.mts.map +1 -1
- package/dist/CurrencyRateController.mjs +68 -15
- package/dist/CurrencyRateController.mjs.map +1 -1
- package/dist/DeFiPositionsController/DeFiPositionsController.cjs +7 -7
- package/dist/DeFiPositionsController/DeFiPositionsController.cjs.map +1 -1
- package/dist/DeFiPositionsController/DeFiPositionsController.d.cts +3 -2
- package/dist/DeFiPositionsController/DeFiPositionsController.d.cts.map +1 -1
- package/dist/DeFiPositionsController/DeFiPositionsController.d.mts +3 -2
- package/dist/DeFiPositionsController/DeFiPositionsController.d.mts.map +1 -1
- package/dist/DeFiPositionsController/DeFiPositionsController.mjs +7 -7
- package/dist/DeFiPositionsController/DeFiPositionsController.mjs.map +1 -1
- package/dist/MultichainAssetsController/MultichainAssetsController.cjs +54 -22
- package/dist/MultichainAssetsController/MultichainAssetsController.cjs.map +1 -1
- package/dist/MultichainAssetsController/MultichainAssetsController.d.cts +18 -3
- package/dist/MultichainAssetsController/MultichainAssetsController.d.cts.map +1 -1
- package/dist/MultichainAssetsController/MultichainAssetsController.d.mts +18 -3
- package/dist/MultichainAssetsController/MultichainAssetsController.d.mts.map +1 -1
- package/dist/MultichainAssetsController/MultichainAssetsController.mjs +54 -22
- package/dist/MultichainAssetsController/MultichainAssetsController.mjs.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.cjs +13 -13
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.cjs.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts +4 -3
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts +4 -3
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs +13 -13
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.cjs +9 -9
- package/dist/MultichainBalancesController/MultichainBalancesController.cjs.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.cts +3 -2
- package/dist/MultichainBalancesController/MultichainBalancesController.d.cts.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.mts +3 -2
- package/dist/MultichainBalancesController/MultichainBalancesController.d.mts.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.mjs +9 -9
- package/dist/MultichainBalancesController/MultichainBalancesController.mjs.map +1 -1
- package/dist/NftController.cjs +25 -25
- package/dist/NftController.cjs.map +1 -1
- package/dist/NftController.d.cts +3 -3
- package/dist/NftController.d.cts.map +1 -1
- package/dist/NftController.d.mts +3 -3
- package/dist/NftController.d.mts.map +1 -1
- package/dist/NftController.mjs +25 -25
- package/dist/NftController.mjs.map +1 -1
- package/dist/NftDetectionController.cjs +5 -6
- package/dist/NftDetectionController.cjs.map +1 -1
- package/dist/NftDetectionController.d.cts +5 -5
- package/dist/NftDetectionController.d.cts.map +1 -1
- package/dist/NftDetectionController.d.mts +5 -5
- package/dist/NftDetectionController.d.mts.map +1 -1
- package/dist/NftDetectionController.mjs +5 -6
- package/dist/NftDetectionController.mjs.map +1 -1
- package/dist/RatesController/RatesController.cjs +5 -5
- package/dist/RatesController/RatesController.cjs.map +1 -1
- package/dist/RatesController/RatesController.d.cts.map +1 -1
- package/dist/RatesController/RatesController.d.mts.map +1 -1
- package/dist/RatesController/RatesController.mjs +5 -5
- package/dist/RatesController/RatesController.mjs.map +1 -1
- package/dist/RatesController/types.cjs.map +1 -1
- package/dist/RatesController/types.d.cts +3 -2
- package/dist/RatesController/types.d.cts.map +1 -1
- package/dist/RatesController/types.d.mts +3 -2
- package/dist/RatesController/types.d.mts.map +1 -1
- package/dist/RatesController/types.mjs.map +1 -1
- package/dist/TokenBalancesController.cjs +22 -22
- package/dist/TokenBalancesController.cjs.map +1 -1
- package/dist/TokenBalancesController.d.cts +3 -2
- package/dist/TokenBalancesController.d.cts.map +1 -1
- package/dist/TokenBalancesController.d.mts +3 -2
- package/dist/TokenBalancesController.d.mts.map +1 -1
- package/dist/TokenBalancesController.mjs +22 -22
- package/dist/TokenBalancesController.mjs.map +1 -1
- package/dist/TokenDetectionController.cjs +24 -24
- package/dist/TokenDetectionController.cjs.map +1 -1
- package/dist/TokenDetectionController.d.cts +4 -3
- package/dist/TokenDetectionController.d.cts.map +1 -1
- package/dist/TokenDetectionController.d.mts +4 -3
- package/dist/TokenDetectionController.d.mts.map +1 -1
- package/dist/TokenDetectionController.mjs +24 -24
- package/dist/TokenDetectionController.mjs.map +1 -1
- package/dist/TokenListController.cjs +4 -4
- package/dist/TokenListController.cjs.map +1 -1
- package/dist/TokenListController.d.cts +3 -2
- package/dist/TokenListController.d.cts.map +1 -1
- package/dist/TokenListController.d.mts +3 -2
- package/dist/TokenListController.d.mts.map +1 -1
- package/dist/TokenListController.mjs +4 -4
- package/dist/TokenListController.mjs.map +1 -1
- package/dist/TokenRatesController.cjs +6 -6
- package/dist/TokenRatesController.cjs.map +1 -1
- package/dist/TokenRatesController.d.cts +3 -2
- package/dist/TokenRatesController.d.cts.map +1 -1
- package/dist/TokenRatesController.d.mts +3 -2
- package/dist/TokenRatesController.d.mts.map +1 -1
- package/dist/TokenRatesController.mjs +6 -6
- package/dist/TokenRatesController.mjs.map +1 -1
- package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.cjs +4 -4
- package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.cjs.map +1 -1
- package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.cts +3 -2
- package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.cts.map +1 -1
- package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.mts +3 -2
- package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.mts.map +1 -1
- package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.mjs +4 -4
- package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.mjs.map +1 -1
- package/dist/TokensController.cjs +17 -17
- package/dist/TokensController.cjs.map +1 -1
- package/dist/TokensController.d.cts +3 -2
- package/dist/TokensController.d.cts.map +1 -1
- package/dist/TokensController.d.mts +3 -2
- package/dist/TokensController.d.mts.map +1 -1
- package/dist/TokensController.mjs +17 -17
- package/dist/TokensController.mjs.map +1 -1
- package/dist/balances.cjs +20 -12
- package/dist/balances.cjs.map +1 -1
- package/dist/balances.d.cts +7 -3
- package/dist/balances.d.cts.map +1 -1
- package/dist/balances.d.mts +7 -3
- package/dist/balances.d.mts.map +1 -1
- package/dist/balances.mjs +20 -12
- package/dist/balances.mjs.map +1 -1
- package/dist/selectors/token-selectors.cjs +5 -1
- package/dist/selectors/token-selectors.cjs.map +1 -1
- package/dist/selectors/token-selectors.d.cts +21 -14
- package/dist/selectors/token-selectors.d.cts.map +1 -1
- package/dist/selectors/token-selectors.d.mts +21 -14
- package/dist/selectors/token-selectors.d.mts.map +1 -1
- package/dist/selectors/token-selectors.mjs +5 -1
- package/dist/selectors/token-selectors.mjs.map +1 -1
- package/dist/token-prices-service/abstract-token-prices-service.cjs.map +1 -1
- package/dist/token-prices-service/abstract-token-prices-service.d.cts +30 -0
- package/dist/token-prices-service/abstract-token-prices-service.d.cts.map +1 -1
- package/dist/token-prices-service/abstract-token-prices-service.d.mts +30 -0
- package/dist/token-prices-service/abstract-token-prices-service.d.mts.map +1 -1
- package/dist/token-prices-service/abstract-token-prices-service.mjs.map +1 -1
- package/dist/token-prices-service/codefi-v2.cjs +75 -0
- package/dist/token-prices-service/codefi-v2.cjs.map +1 -1
- package/dist/token-prices-service/codefi-v2.d.cts +15 -1
- package/dist/token-prices-service/codefi-v2.d.cts.map +1 -1
- package/dist/token-prices-service/codefi-v2.d.mts +15 -1
- package/dist/token-prices-service/codefi-v2.d.mts.map +1 -1
- package/dist/token-prices-service/codefi-v2.mjs +75 -0
- package/dist/token-prices-service/codefi-v2.mjs.map +1 -1
- package/package.json +26 -25
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeFiPositionsController.mjs","sourceRoot":"","sources":["../../src/DeFiPositionsController/DeFiPositionsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerListAccountsAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n StateMetadata,\n} from '@metamask/base-controller';\nimport type { KeyringControllerUnlockEvent } from '@metamask/keyring-controller';\nimport type { KeyringControllerLockEvent } from '@metamask/keyring-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { TransactionControllerTransactionConfirmedEvent } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport { calculateDeFiPositionMetrics } from './calculate-defi-metrics';\nimport type { DefiPositionResponse } from './fetch-positions';\nimport { buildPositionFetcher } from './fetch-positions';\nimport {\n groupDeFiPositions,\n type GroupedDeFiPositions,\n} from './group-defi-positions';\nimport { reduceInBatchesSerially } from '../assetsUtil';\n\nconst TEN_MINUTES_IN_MS = 600_000;\n\nconst FETCH_POSITIONS_BATCH_SIZE = 10;\n\nconst controllerName = 'DeFiPositionsController';\n\nexport type GroupedDeFiPositionsPerChain = {\n [chain: Hex]: GroupedDeFiPositions;\n};\n\nexport type TrackingEventPayload = {\n event: string;\n category: string;\n properties: {\n totalPositions: number;\n totalMarketValueUSD: number;\n breakdown?: {\n protocolId: string;\n marketValueUSD: number;\n chainId: Hex;\n count: number;\n }[];\n };\n};\n\ntype TrackEventHook = (event: TrackingEventPayload) => void;\n\nexport type DeFiPositionsControllerState = {\n /**\n * Object containing DeFi positions per account and network\n */\n allDeFiPositions: {\n [accountAddress: string]: GroupedDeFiPositionsPerChain | null;\n };\n\n /**\n * Object containing DeFi positions count per account\n */\n allDeFiPositionsCount: {\n [accountAddress: string]: number;\n };\n};\n\nconst controllerMetadata: StateMetadata<DeFiPositionsControllerState> = {\n allDeFiPositions: {\n includeInStateLogs: false,\n persist: false,\n anonymous: false,\n usedInUi: true,\n },\n allDeFiPositionsCount: {\n includeInStateLogs: false,\n persist: false,\n anonymous: false,\n usedInUi: false,\n },\n};\n\nexport const getDefaultDefiPositionsControllerState =\n (): DeFiPositionsControllerState => {\n return {\n allDeFiPositions: {},\n allDeFiPositionsCount: {},\n };\n };\n\nexport type DeFiPositionsControllerActions =\n DeFiPositionsControllerGetStateAction;\n\nexport type DeFiPositionsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n DeFiPositionsControllerState\n>;\n\nexport type DeFiPositionsControllerEvents =\n DeFiPositionsControllerStateChangeEvent;\n\nexport type DeFiPositionsControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n DeFiPositionsControllerState\n >;\n\n/**\n * The external actions available to the {@link DeFiPositionsController}.\n */\nexport type AllowedActions = AccountsControllerListAccountsAction;\n\n/**\n * The external events available to the {@link DeFiPositionsController}.\n */\nexport type AllowedEvents =\n | KeyringControllerUnlockEvent\n | KeyringControllerLockEvent\n | TransactionControllerTransactionConfirmedEvent\n | AccountsControllerAccountAddedEvent;\n\n/**\n * The messenger of the {@link DeFiPositionsController}.\n */\nexport type DeFiPositionsControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n DeFiPositionsControllerActions | AllowedActions,\n DeFiPositionsControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Controller that stores assets and exposes convenience methods\n */\nexport class DeFiPositionsController extends StaticIntervalPollingController()<\n typeof controllerName,\n DeFiPositionsControllerState,\n DeFiPositionsControllerMessenger\n> {\n readonly #fetchPositions: (\n accountAddress: string,\n ) => Promise<DefiPositionResponse[]>;\n\n readonly #isEnabled: () => boolean;\n\n readonly #trackEvent?: TrackEventHook;\n\n /**\n * DeFiPositionsController constuctor\n *\n * @param options - Constructor options.\n * @param options.messenger - The controller messenger.\n * @param options.isEnabled - Function that returns whether the controller is enabled. (default: () => true)\n * @param options.trackEvent - Function to track events. (default: undefined)\n */\n constructor({\n messenger,\n isEnabled = () => true,\n trackEvent,\n }: {\n messenger: DeFiPositionsControllerMessenger;\n isEnabled?: () => boolean;\n trackEvent?: TrackEventHook;\n }) {\n super({\n name: controllerName,\n metadata: controllerMetadata,\n messenger,\n state: getDefaultDefiPositionsControllerState(),\n });\n\n this.setIntervalLength(TEN_MINUTES_IN_MS);\n\n this.#fetchPositions = buildPositionFetcher();\n this.#isEnabled = isEnabled;\n\n this.messagingSystem.subscribe('KeyringController:unlock', () => {\n this.startPolling(null);\n });\n\n this.messagingSystem.subscribe('KeyringController:lock', () => {\n this.stopAllPolling();\n });\n\n this.messagingSystem.subscribe(\n 'TransactionController:transactionConfirmed',\n async (transactionMeta) => {\n if (!this.#isEnabled()) {\n return;\n }\n\n await this.#updateAccountPositions(transactionMeta.txParams.from);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n async (account) => {\n if (!this.#isEnabled() || !account.type.startsWith('eip155:')) {\n return;\n }\n\n await this.#updateAccountPositions(account.address);\n },\n );\n\n this.#trackEvent = trackEvent;\n }\n\n async _executePoll(): Promise<void> {\n if (!this.#isEnabled()) {\n return;\n }\n\n const accounts = this.messagingSystem.call(\n 'AccountsController:listAccounts',\n );\n\n const initialResult: {\n accountAddress: string;\n positions: GroupedDeFiPositionsPerChain | null;\n }[] = [];\n\n const results = await reduceInBatchesSerially({\n initialResult,\n values: accounts,\n batchSize: FETCH_POSITIONS_BATCH_SIZE,\n eachBatch: async (workingResult, batch) => {\n const batchResults = (\n await Promise.all(\n batch.map(async ({ address: accountAddress, type }) => {\n if (type.startsWith('eip155:')) {\n const positions =\n await this.#fetchAccountPositions(accountAddress);\n\n return {\n accountAddress,\n positions,\n };\n }\n\n return undefined;\n }),\n )\n ).filter(Boolean) as {\n accountAddress: string;\n positions: GroupedDeFiPositionsPerChain | null;\n }[];\n\n return [...workingResult, ...batchResults];\n },\n });\n\n const allDefiPositions = results.reduce(\n (acc, { accountAddress, positions }) => {\n acc[accountAddress] = positions;\n return acc;\n },\n {} as DeFiPositionsControllerState['allDeFiPositions'],\n );\n\n this.update((state) => {\n state.allDeFiPositions = allDefiPositions;\n });\n }\n\n async #updateAccountPositions(accountAddress: string): Promise<void> {\n const accountPositionsPerChain =\n await this.#fetchAccountPositions(accountAddress);\n\n this.update((state) => {\n state.allDeFiPositions[accountAddress] = accountPositionsPerChain;\n });\n }\n\n async #fetchAccountPositions(\n accountAddress: string,\n ): Promise<GroupedDeFiPositionsPerChain | null> {\n try {\n const defiPositionsResponse = await this.#fetchPositions(accountAddress);\n\n const groupedDeFiPositions = groupDeFiPositions(defiPositionsResponse);\n\n try {\n this.#updatePositionsCountMetrics(groupedDeFiPositions, accountAddress);\n } catch (error) {\n console.error(\n `Failed to update positions count for account ${accountAddress}:`,\n error,\n );\n }\n\n return groupedDeFiPositions;\n } catch {\n return null;\n }\n }\n\n #updatePositionsCountMetrics(\n groupedDeFiPositions: GroupedDeFiPositionsPerChain,\n accountAddress: string,\n ) {\n // If no track event passed then skip the metrics update\n if (!this.#trackEvent) {\n return;\n }\n\n const defiMetrics = calculateDeFiPositionMetrics(groupedDeFiPositions);\n const { totalPositions } = defiMetrics.properties;\n\n if (totalPositions !== this.state.allDeFiPositionsCount[accountAddress]) {\n this.update((state) => {\n state.allDeFiPositionsCount[accountAddress] = totalPositions;\n });\n\n this.#trackEvent?.(defiMetrics);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DeFiPositionsController.mjs","sourceRoot":"","sources":["../../src/DeFiPositionsController/DeFiPositionsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerListAccountsAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport type { KeyringControllerUnlockEvent } from '@metamask/keyring-controller';\nimport type { KeyringControllerLockEvent } from '@metamask/keyring-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { TransactionControllerTransactionConfirmedEvent } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport { calculateDeFiPositionMetrics } from './calculate-defi-metrics';\nimport type { DefiPositionResponse } from './fetch-positions';\nimport { buildPositionFetcher } from './fetch-positions';\nimport {\n groupDeFiPositions,\n type GroupedDeFiPositions,\n} from './group-defi-positions';\nimport { reduceInBatchesSerially } from '../assetsUtil';\n\nconst TEN_MINUTES_IN_MS = 600_000;\n\nconst FETCH_POSITIONS_BATCH_SIZE = 10;\n\nconst controllerName = 'DeFiPositionsController';\n\nexport type GroupedDeFiPositionsPerChain = {\n [chain: Hex]: GroupedDeFiPositions;\n};\n\nexport type TrackingEventPayload = {\n event: string;\n category: string;\n properties: {\n totalPositions: number;\n totalMarketValueUSD: number;\n breakdown?: {\n protocolId: string;\n marketValueUSD: number;\n chainId: Hex;\n count: number;\n }[];\n };\n};\n\ntype TrackEventHook = (event: TrackingEventPayload) => void;\n\nexport type DeFiPositionsControllerState = {\n /**\n * Object containing DeFi positions per account and network\n */\n allDeFiPositions: {\n [accountAddress: string]: GroupedDeFiPositionsPerChain | null;\n };\n\n /**\n * Object containing DeFi positions count per account\n */\n allDeFiPositionsCount: {\n [accountAddress: string]: number;\n };\n};\n\nconst controllerMetadata: StateMetadata<DeFiPositionsControllerState> = {\n allDeFiPositions: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n allDeFiPositionsCount: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: false,\n },\n};\n\nexport const getDefaultDefiPositionsControllerState =\n (): DeFiPositionsControllerState => {\n return {\n allDeFiPositions: {},\n allDeFiPositionsCount: {},\n };\n };\n\nexport type DeFiPositionsControllerActions =\n DeFiPositionsControllerGetStateAction;\n\nexport type DeFiPositionsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n DeFiPositionsControllerState\n>;\n\nexport type DeFiPositionsControllerEvents =\n DeFiPositionsControllerStateChangeEvent;\n\nexport type DeFiPositionsControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n DeFiPositionsControllerState\n >;\n\n/**\n * The external actions available to the {@link DeFiPositionsController}.\n */\nexport type AllowedActions = AccountsControllerListAccountsAction;\n\n/**\n * The external events available to the {@link DeFiPositionsController}.\n */\nexport type AllowedEvents =\n | KeyringControllerUnlockEvent\n | KeyringControllerLockEvent\n | TransactionControllerTransactionConfirmedEvent\n | AccountsControllerAccountAddedEvent;\n\n/**\n * The messenger of the {@link DeFiPositionsController}.\n */\nexport type DeFiPositionsControllerMessenger = Messenger<\n typeof controllerName,\n DeFiPositionsControllerActions | AllowedActions,\n DeFiPositionsControllerEvents | AllowedEvents\n>;\n\n/**\n * Controller that stores assets and exposes convenience methods\n */\nexport class DeFiPositionsController extends StaticIntervalPollingController()<\n typeof controllerName,\n DeFiPositionsControllerState,\n DeFiPositionsControllerMessenger\n> {\n readonly #fetchPositions: (\n accountAddress: string,\n ) => Promise<DefiPositionResponse[]>;\n\n readonly #isEnabled: () => boolean;\n\n readonly #trackEvent?: TrackEventHook;\n\n /**\n * DeFiPositionsController constuctor\n *\n * @param options - Constructor options.\n * @param options.messenger - The controller messenger.\n * @param options.isEnabled - Function that returns whether the controller is enabled. (default: () => true)\n * @param options.trackEvent - Function to track events. (default: undefined)\n */\n constructor({\n messenger,\n isEnabled = () => true,\n trackEvent,\n }: {\n messenger: DeFiPositionsControllerMessenger;\n isEnabled?: () => boolean;\n trackEvent?: TrackEventHook;\n }) {\n super({\n name: controllerName,\n metadata: controllerMetadata,\n messenger,\n state: getDefaultDefiPositionsControllerState(),\n });\n\n this.setIntervalLength(TEN_MINUTES_IN_MS);\n\n this.#fetchPositions = buildPositionFetcher();\n this.#isEnabled = isEnabled;\n\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.startPolling(null);\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.stopAllPolling();\n });\n\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n async (transactionMeta) => {\n if (!this.#isEnabled()) {\n return;\n }\n\n await this.#updateAccountPositions(transactionMeta.txParams.from);\n },\n );\n\n this.messenger.subscribe(\n 'AccountsController:accountAdded',\n async (account) => {\n if (!this.#isEnabled() || !account.type.startsWith('eip155:')) {\n return;\n }\n\n await this.#updateAccountPositions(account.address);\n },\n );\n\n this.#trackEvent = trackEvent;\n }\n\n async _executePoll(): Promise<void> {\n if (!this.#isEnabled()) {\n return;\n }\n\n const accounts = this.messenger.call('AccountsController:listAccounts');\n\n const initialResult: {\n accountAddress: string;\n positions: GroupedDeFiPositionsPerChain | null;\n }[] = [];\n\n const results = await reduceInBatchesSerially({\n initialResult,\n values: accounts,\n batchSize: FETCH_POSITIONS_BATCH_SIZE,\n eachBatch: async (workingResult, batch) => {\n const batchResults = (\n await Promise.all(\n batch.map(async ({ address: accountAddress, type }) => {\n if (type.startsWith('eip155:')) {\n const positions =\n await this.#fetchAccountPositions(accountAddress);\n\n return {\n accountAddress,\n positions,\n };\n }\n\n return undefined;\n }),\n )\n ).filter(Boolean) as {\n accountAddress: string;\n positions: GroupedDeFiPositionsPerChain | null;\n }[];\n\n return [...workingResult, ...batchResults];\n },\n });\n\n const allDefiPositions = results.reduce(\n (acc, { accountAddress, positions }) => {\n acc[accountAddress] = positions;\n return acc;\n },\n {} as DeFiPositionsControllerState['allDeFiPositions'],\n );\n\n this.update((state) => {\n state.allDeFiPositions = allDefiPositions;\n });\n }\n\n async #updateAccountPositions(accountAddress: string): Promise<void> {\n const accountPositionsPerChain =\n await this.#fetchAccountPositions(accountAddress);\n\n this.update((state) => {\n state.allDeFiPositions[accountAddress] = accountPositionsPerChain;\n });\n }\n\n async #fetchAccountPositions(\n accountAddress: string,\n ): Promise<GroupedDeFiPositionsPerChain | null> {\n try {\n const defiPositionsResponse = await this.#fetchPositions(accountAddress);\n\n const groupedDeFiPositions = groupDeFiPositions(defiPositionsResponse);\n\n try {\n this.#updatePositionsCountMetrics(groupedDeFiPositions, accountAddress);\n } catch (error) {\n console.error(\n `Failed to update positions count for account ${accountAddress}:`,\n error,\n );\n }\n\n return groupedDeFiPositions;\n } catch {\n return null;\n }\n }\n\n #updatePositionsCountMetrics(\n groupedDeFiPositions: GroupedDeFiPositionsPerChain,\n accountAddress: string,\n ) {\n // If no track event passed then skip the metrics update\n if (!this.#trackEvent) {\n return;\n }\n\n const defiMetrics = calculateDeFiPositionMetrics(groupedDeFiPositions);\n const { totalPositions } = defiMetrics.properties;\n\n if (totalPositions !== this.state.allDeFiPositionsCount[accountAddress]) {\n this.update((state) => {\n state.allDeFiPositionsCount[accountAddress] = totalPositions;\n });\n\n this.#trackEvent?.(defiMetrics);\n }\n }\n}\n"]}
|
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _MultichainAssetsController_instances, _MultichainAssetsController_snaps, _MultichainAssetsController_controllerOperationMutex, _MultichainAssetsController_handleAccountAssetListUpdatedEvent, _MultichainAssetsController_handleOnAccountAddedEvent, _MultichainAssetsController_registerMessageHandlers, _MultichainAssetsController_handleAccountAssetListUpdated, _MultichainAssetsController_isNonEvmAccount, _MultichainAssetsController_handleOnAccountAdded, _MultichainAssetsController_handleOnAccountRemovedEvent, _MultichainAssetsController_refreshAssetsMetadata, _MultichainAssetsController_updateAssetsMetadata, _MultichainAssetsController_getAssetSnaps, _MultichainAssetsController_getAssetSnapFor, _MultichainAssetsController_getAllSnaps, _MultichainAssetsController_getSnapsPermissions, _MultichainAssetsController_getAssetsMetadataFrom, _MultichainAssetsController_getAssetsList, _MultichainAssetsController_getClient, _MultichainAssetsController_assertControllerMutexIsLocked, _MultichainAssetsController_withControllerLock;
|
|
13
|
+
var _MultichainAssetsController_instances, _MultichainAssetsController_snaps, _MultichainAssetsController_controllerOperationMutex, _MultichainAssetsController_handleAccountAssetListUpdatedEvent, _MultichainAssetsController_handleOnAccountAddedEvent, _MultichainAssetsController_registerMessageHandlers, _MultichainAssetsController_isAssetIgnored, _MultichainAssetsController_handleAccountAssetListUpdated, _MultichainAssetsController_isNonEvmAccount, _MultichainAssetsController_handleOnAccountAdded, _MultichainAssetsController_handleOnAccountRemovedEvent, _MultichainAssetsController_refreshAssetsMetadata, _MultichainAssetsController_updateAssetsMetadata, _MultichainAssetsController_getAssetSnaps, _MultichainAssetsController_getAssetSnapFor, _MultichainAssetsController_getAllSnaps, _MultichainAssetsController_getSnapsPermissions, _MultichainAssetsController_getAssetsMetadataFrom, _MultichainAssetsController_getAssetsList, _MultichainAssetsController_getClient, _MultichainAssetsController_assertControllerMutexIsLocked, _MultichainAssetsController_withControllerLock;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.MultichainAssetsController = exports.getDefaultMultichainAssetsControllerState = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
@@ -30,7 +30,7 @@ const controllerName = 'MultichainAssetsController';
|
|
|
30
30
|
* @returns The default {@link MultichainAssetsController} state.
|
|
31
31
|
*/
|
|
32
32
|
function getDefaultMultichainAssetsControllerState() {
|
|
33
|
-
return { accountsAssets: {}, assetsMetadata: {} };
|
|
33
|
+
return { accountsAssets: {}, assetsMetadata: {}, allIgnoredAssets: {} };
|
|
34
34
|
}
|
|
35
35
|
exports.getDefaultMultichainAssetsControllerState = getDefaultMultichainAssetsControllerState;
|
|
36
36
|
/**
|
|
@@ -44,13 +44,19 @@ const assetsControllerMetadata = {
|
|
|
44
44
|
assetsMetadata: {
|
|
45
45
|
includeInStateLogs: false,
|
|
46
46
|
persist: true,
|
|
47
|
-
|
|
47
|
+
includeInDebugSnapshot: false,
|
|
48
48
|
usedInUi: true,
|
|
49
49
|
},
|
|
50
50
|
accountsAssets: {
|
|
51
51
|
includeInStateLogs: false,
|
|
52
52
|
persist: true,
|
|
53
|
-
|
|
53
|
+
includeInDebugSnapshot: false,
|
|
54
|
+
usedInUi: true,
|
|
55
|
+
},
|
|
56
|
+
allIgnoredAssets: {
|
|
57
|
+
includeInStateLogs: false,
|
|
58
|
+
persist: true,
|
|
59
|
+
includeInDebugSnapshot: false,
|
|
54
60
|
usedInUi: true,
|
|
55
61
|
},
|
|
56
62
|
};
|
|
@@ -71,9 +77,9 @@ class MultichainAssetsController extends base_controller_1.BaseController {
|
|
|
71
77
|
_MultichainAssetsController_snaps.set(this, void 0);
|
|
72
78
|
_MultichainAssetsController_controllerOperationMutex.set(this, new async_mutex_1.Mutex());
|
|
73
79
|
__classPrivateFieldSet(this, _MultichainAssetsController_snaps, {}, "f");
|
|
74
|
-
this.
|
|
75
|
-
this.
|
|
76
|
-
this.
|
|
80
|
+
this.messenger.subscribe('AccountsController:accountAdded', async (account) => await __classPrivateFieldGet(this, _MultichainAssetsController_instances, "m", _MultichainAssetsController_handleOnAccountAddedEvent).call(this, account));
|
|
81
|
+
this.messenger.subscribe('AccountsController:accountRemoved', async (account) => await __classPrivateFieldGet(this, _MultichainAssetsController_instances, "m", _MultichainAssetsController_handleOnAccountRemovedEvent).call(this, account));
|
|
82
|
+
this.messenger.subscribe('AccountsController:accountAssetListUpdated', async (event) => await __classPrivateFieldGet(this, _MultichainAssetsController_instances, "m", _MultichainAssetsController_handleAccountAssetListUpdatedEvent).call(this, event));
|
|
77
83
|
__classPrivateFieldGet(this, _MultichainAssetsController_instances, "m", _MultichainAssetsController_registerMessageHandlers).call(this);
|
|
78
84
|
}
|
|
79
85
|
/**
|
|
@@ -85,6 +91,24 @@ class MultichainAssetsController extends base_controller_1.BaseController {
|
|
|
85
91
|
getAssetMetadata(asset) {
|
|
86
92
|
return this.state.assetsMetadata[asset];
|
|
87
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Ignores a batch of assets for a specific account.
|
|
96
|
+
*
|
|
97
|
+
* @param assetsToIgnore - Array of asset IDs to ignore.
|
|
98
|
+
* @param accountId - The account ID to ignore assets for.
|
|
99
|
+
*/
|
|
100
|
+
ignoreAssets(assetsToIgnore, accountId) {
|
|
101
|
+
this.update((state) => {
|
|
102
|
+
if (state.accountsAssets[accountId]) {
|
|
103
|
+
state.accountsAssets[accountId] = state.accountsAssets[accountId].filter((asset) => !assetsToIgnore.includes(asset));
|
|
104
|
+
}
|
|
105
|
+
if (!state.allIgnoredAssets[accountId]) {
|
|
106
|
+
state.allIgnoredAssets[accountId] = [];
|
|
107
|
+
}
|
|
108
|
+
const newIgnoredAssets = assetsToIgnore.filter((asset) => !state.allIgnoredAssets[accountId].includes(asset));
|
|
109
|
+
state.allIgnoredAssets[accountId].push(...newIgnoredAssets);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
88
112
|
}
|
|
89
113
|
exports.MultichainAssetsController = MultichainAssetsController;
|
|
90
114
|
_MultichainAssetsController_snaps = new WeakMap(), _MultichainAssetsController_controllerOperationMutex = new WeakMap(), _MultichainAssetsController_instances = new WeakSet(), _MultichainAssetsController_handleAccountAssetListUpdatedEvent = async function _MultichainAssetsController_handleAccountAssetListUpdatedEvent(event) {
|
|
@@ -92,7 +116,10 @@ _MultichainAssetsController_snaps = new WeakMap(), _MultichainAssetsController_c
|
|
|
92
116
|
}, _MultichainAssetsController_handleOnAccountAddedEvent = async function _MultichainAssetsController_handleOnAccountAddedEvent(account) {
|
|
93
117
|
return __classPrivateFieldGet(this, _MultichainAssetsController_instances, "m", _MultichainAssetsController_withControllerLock).call(this, async () => __classPrivateFieldGet(this, _MultichainAssetsController_instances, "m", _MultichainAssetsController_handleOnAccountAdded).call(this, account));
|
|
94
118
|
}, _MultichainAssetsController_registerMessageHandlers = function _MultichainAssetsController_registerMessageHandlers() {
|
|
95
|
-
this.
|
|
119
|
+
this.messenger.registerActionHandler('MultichainAssetsController:getAssetMetadata', this.getAssetMetadata.bind(this));
|
|
120
|
+
this.messenger.registerActionHandler('MultichainAssetsController:ignoreAssets', this.ignoreAssets.bind(this));
|
|
121
|
+
}, _MultichainAssetsController_isAssetIgnored = function _MultichainAssetsController_isAssetIgnored(asset, accountId) {
|
|
122
|
+
return this.state.allIgnoredAssets[accountId]?.includes(asset) ?? false;
|
|
96
123
|
}, _MultichainAssetsController_handleAccountAssetListUpdated =
|
|
97
124
|
/**
|
|
98
125
|
* Function to update the assets list for an account
|
|
@@ -107,7 +134,10 @@ async function _MultichainAssetsController_handleAccountAssetListUpdated(event)
|
|
|
107
134
|
if (added.length > 0 || removed.length > 0) {
|
|
108
135
|
const existing = this.state.accountsAssets[accountId] || [];
|
|
109
136
|
// In case accountsAndAssetsToUpdate event is fired with "added" assets that already exist, we don't want to add them again
|
|
110
|
-
|
|
137
|
+
// Also filter out ignored assets
|
|
138
|
+
const filteredToBeAddedAssets = added.filter((asset) => !existing.includes(asset) &&
|
|
139
|
+
(0, utils_1.isCaipAssetType)(asset) &&
|
|
140
|
+
!__classPrivateFieldGet(this, _MultichainAssetsController_instances, "m", _MultichainAssetsController_isAssetIgnored).call(this, asset, accountId));
|
|
111
141
|
// In case accountsAndAssetsToUpdate event is fired with "removed" assets that don't exist, we don't want to remove them
|
|
112
142
|
const filteredToBeRemovedAssets = removed.filter((asset) => existing.includes(asset) && (0, utils_1.isCaipAssetType)(asset));
|
|
113
143
|
if (filteredToBeAddedAssets.length > 0 ||
|
|
@@ -142,7 +172,7 @@ async function _MultichainAssetsController_handleAccountAssetListUpdated(event)
|
|
|
142
172
|
});
|
|
143
173
|
// Trigger fetching metadata for new assets
|
|
144
174
|
await __classPrivateFieldGet(this, _MultichainAssetsController_instances, "m", _MultichainAssetsController_refreshAssetsMetadata).call(this, Array.from(assetsForMetadataRefresh));
|
|
145
|
-
this.
|
|
175
|
+
this.messenger.publish(`${controllerName}:accountAssetListUpdated`, {
|
|
146
176
|
assets: accountsAndAssetsToUpdate,
|
|
147
177
|
});
|
|
148
178
|
}, _MultichainAssetsController_isNonEvmAccount = function _MultichainAssetsController_isNonEvmAccount(account) {
|
|
@@ -168,7 +198,7 @@ async function _MultichainAssetsController_handleOnAccountAdded(account) {
|
|
|
168
198
|
this.update((state) => {
|
|
169
199
|
state.accountsAssets[account.id] = assets;
|
|
170
200
|
});
|
|
171
|
-
this.
|
|
201
|
+
this.messenger.publish(`${controllerName}:accountAssetListUpdated`, {
|
|
172
202
|
assets: {
|
|
173
203
|
[account.id]: {
|
|
174
204
|
added: assets,
|
|
@@ -184,14 +214,16 @@ async function _MultichainAssetsController_handleOnAccountAdded(account) {
|
|
|
184
214
|
* @param accountId - The new account id being removed.
|
|
185
215
|
*/
|
|
186
216
|
async function _MultichainAssetsController_handleOnAccountRemovedEvent(accountId) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
this.update((state) => {
|
|
190
|
-
// TODO: We are not deleting the assetsMetadata because we will soon make this controller extends StaticIntervalPollingController
|
|
191
|
-
// and update all assetsMetadata once a day.
|
|
217
|
+
this.update((state) => {
|
|
218
|
+
if (state.accountsAssets[accountId]) {
|
|
192
219
|
delete state.accountsAssets[accountId];
|
|
193
|
-
}
|
|
194
|
-
|
|
220
|
+
}
|
|
221
|
+
if (state.allIgnoredAssets[accountId]) {
|
|
222
|
+
delete state.allIgnoredAssets[accountId];
|
|
223
|
+
}
|
|
224
|
+
// TODO: We are not deleting the assetsMetadata because we will soon make this controller extends StaticIntervalPollingController
|
|
225
|
+
// and update all assetsMetadata once a day.
|
|
226
|
+
});
|
|
195
227
|
}, _MultichainAssetsController_refreshAssetsMetadata =
|
|
196
228
|
/**
|
|
197
229
|
* Refreshes the assets snaps and metadata for the given list of assets
|
|
@@ -273,11 +305,11 @@ async function _MultichainAssetsController_updateAssetsMetadata(assets) {
|
|
|
273
305
|
return allSnaps?.[0]; // Will be undefined if there's no Snaps candidate for this scope.
|
|
274
306
|
}, _MultichainAssetsController_getAllSnaps = function _MultichainAssetsController_getAllSnaps() {
|
|
275
307
|
// TODO: Use dedicated SnapController's action once available for this:
|
|
276
|
-
return this.
|
|
308
|
+
return this.messenger
|
|
277
309
|
.call('SnapController:getAll')
|
|
278
310
|
.filter((snap) => snap.enabled && !snap.blocked);
|
|
279
311
|
}, _MultichainAssetsController_getSnapsPermissions = function _MultichainAssetsController_getSnapsPermissions(origin) {
|
|
280
|
-
return this.
|
|
312
|
+
return this.messenger.call('PermissionController:getPermissions', origin);
|
|
281
313
|
}, _MultichainAssetsController_getAssetsMetadataFrom =
|
|
282
314
|
/**
|
|
283
315
|
* Returns the metadata for the given assets
|
|
@@ -288,7 +320,7 @@ async function _MultichainAssetsController_updateAssetsMetadata(assets) {
|
|
|
288
320
|
*/
|
|
289
321
|
async function _MultichainAssetsController_getAssetsMetadataFrom(assets, snapId) {
|
|
290
322
|
try {
|
|
291
|
-
return (await this.
|
|
323
|
+
return (await this.messenger.call('SnapController:handleRequest', {
|
|
292
324
|
snapId: snapId,
|
|
293
325
|
origin: 'metamask',
|
|
294
326
|
handler: snaps_utils_1.HandlerType.OnAssetsLookup,
|
|
@@ -318,7 +350,7 @@ async function _MultichainAssetsController_getAssetsList(accountId, snapId) {
|
|
|
318
350
|
return await __classPrivateFieldGet(this, _MultichainAssetsController_instances, "m", _MultichainAssetsController_getClient).call(this, snapId).listAccountAssets(accountId);
|
|
319
351
|
}, _MultichainAssetsController_getClient = function _MultichainAssetsController_getClient(snapId) {
|
|
320
352
|
return new keyring_snap_client_1.KeyringClient({
|
|
321
|
-
send: async (request) => (await this.
|
|
353
|
+
send: async (request) => (await this.messenger.call('SnapController:handleRequest', {
|
|
322
354
|
snapId: snapId,
|
|
323
355
|
origin: 'metamask',
|
|
324
356
|
handler: snaps_utils_1.HandlerType.OnKeyringRequest,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAssetsController.cjs","sourceRoot":"","sources":["../../src/MultichainAssetsController/MultichainAssetsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountAssetListUpdatedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedMessenger,\n} from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type {\n AccountAssetListUpdatedEventPayload,\n CaipAssetType,\n CaipAssetTypeOrId,\n} from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport { KeyringClient } from '@metamask/keyring-snap-client';\nimport type {\n GetPermissions,\n PermissionConstraint,\n SubjectPermissions,\n} from '@metamask/permission-controller';\nimport type {\n GetAllSnaps,\n HandleSnapRequest,\n} from '@metamask/snaps-controllers';\nimport type { FungibleAssetMetadata, Snap, SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport {\n isCaipAssetType,\n parseCaipAssetType,\n type CaipChainId,\n} from '@metamask/utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\nimport type { MutexInterface } from 'async-mutex';\nimport { Mutex } from 'async-mutex';\n\nimport { getChainIdsCaveat } from './utils';\n\nconst controllerName = 'MultichainAssetsController';\n\nexport type MultichainAssetsControllerState = {\n assetsMetadata: {\n [asset: CaipAssetType]: FungibleAssetMetadata;\n };\n accountsAssets: { [account: string]: CaipAssetType[] };\n};\n\n// Represents the response of the asset snap's onAssetLookup handler\nexport type AssetMetadataResponse = {\n assets: {\n [asset: CaipAssetType]: FungibleAssetMetadata;\n };\n};\n\nexport type MultichainAssetsControllerAccountAssetListUpdatedEvent = {\n type: `${typeof controllerName}:accountAssetListUpdated`;\n payload: AccountsControllerAccountAssetListUpdatedEvent['payload'];\n};\n\n/**\n * Constructs the default {@link MultichainAssetsController} 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 MultichainAssetsController} state.\n */\nexport function getDefaultMultichainAssetsControllerState(): MultichainAssetsControllerState {\n return { accountsAssets: {}, assetsMetadata: {} };\n}\n\nexport type MultichainAssetsControllerGetAssetMetadataAction = {\n type: `${typeof controllerName}:getAssetMetadata`;\n handler: MultichainAssetsController['getAssetMetadata'];\n};\n\n/**\n * Returns the state of the {@link MultichainAssetsController}.\n */\nexport type MultichainAssetsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n MultichainAssetsControllerState\n>;\n\n/**\n * Event emitted when the state of the {@link MultichainAssetsController} changes.\n */\nexport type MultichainAssetsControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainAssetsControllerState\n >;\n\n/**\n * Actions exposed by the {@link MultichainAssetsController}.\n */\nexport type MultichainAssetsControllerActions =\n | MultichainAssetsControllerGetStateAction\n | MultichainAssetsControllerGetAssetMetadataAction;\n\n/**\n * Events emitted by {@link MultichainAssetsController}.\n */\nexport type MultichainAssetsControllerEvents =\n | MultichainAssetsControllerStateChangeEvent\n | MultichainAssetsControllerAccountAssetListUpdatedEvent;\n\n/**\n * A function executed within a mutually exclusive lock, with\n * a mutex releaser in its option bag.\n *\n * @param releaseLock - A function to release the lock.\n */\ntype MutuallyExclusiveCallback<Result> = ({\n releaseLock,\n}: {\n releaseLock: MutexInterface.Releaser;\n}) => Promise<Result>;\n\n/**\n * Actions that this controller is allowed to call.\n */\ntype AllowedActions =\n | HandleSnapRequest\n | GetAllSnaps\n | GetPermissions\n | AccountsControllerListMultichainAccountsAction;\n\n/**\n * Events that this controller is allowed to subscribe.\n */\ntype AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent\n | AccountsControllerAccountAssetListUpdatedEvent;\n\n/**\n * Messenger type for the MultichainAssetsController.\n */\nexport type MultichainAssetsControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n MultichainAssetsControllerActions | AllowedActions,\n MultichainAssetsControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * {@link MultichainAssetsController}'s metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst assetsControllerMetadata = {\n assetsMetadata: {\n includeInStateLogs: false,\n persist: true,\n anonymous: false,\n usedInUi: true,\n },\n accountsAssets: {\n includeInStateLogs: false,\n persist: true,\n anonymous: false,\n usedInUi: true,\n },\n};\n\n// TODO: make this controller extends StaticIntervalPollingController and update all assetsMetadata once a day.\n\nexport class MultichainAssetsController extends BaseController<\n typeof controllerName,\n MultichainAssetsControllerState,\n MultichainAssetsControllerMessenger\n> {\n // Mapping of CAIP-2 Chain ID to Asset Snaps.\n #snaps: Record<CaipChainId, Snap[]>;\n\n readonly #controllerOperationMutex = new Mutex();\n\n constructor({\n messenger,\n state = {},\n }: {\n messenger: MultichainAssetsControllerMessenger;\n state?: Partial<MultichainAssetsControllerState>;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: assetsControllerMetadata,\n state: {\n ...getDefaultMultichainAssetsControllerState(),\n ...state,\n },\n });\n\n this.#snaps = {};\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n async (account) => await this.#handleOnAccountAddedEvent(account),\n );\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n async (account) => await this.#handleOnAccountRemovedEvent(account),\n );\n this.messagingSystem.subscribe(\n 'AccountsController:accountAssetListUpdated',\n async (event) => await this.#handleAccountAssetListUpdatedEvent(event),\n );\n\n this.#registerMessageHandlers();\n }\n\n async #handleAccountAssetListUpdatedEvent(\n event: AccountAssetListUpdatedEventPayload,\n ) {\n return this.#withControllerLock(async () =>\n this.#handleAccountAssetListUpdated(event),\n );\n }\n\n async #handleOnAccountAddedEvent(account: InternalAccount) {\n return this.#withControllerLock(async () =>\n this.#handleOnAccountAdded(account),\n );\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n 'MultichainAssetsController:getAssetMetadata',\n this.getAssetMetadata.bind(this),\n );\n }\n\n /**\n * Returns the metadata for the given asset\n *\n * @param asset - The asset to get metadata for\n * @returns The metadata for the asset or undefined if not found.\n */\n getAssetMetadata(asset: CaipAssetType): FungibleAssetMetadata | undefined {\n return this.state.assetsMetadata[asset];\n }\n\n /**\n * Function to update the assets list for an account\n *\n * @param event - The list of assets to update\n */\n async #handleAccountAssetListUpdated(\n event: AccountAssetListUpdatedEventPayload,\n ) {\n this.#assertControllerMutexIsLocked();\n\n const assetsForMetadataRefresh = new Set<CaipAssetType>([]);\n const accountsAndAssetsToUpdate: AccountAssetListUpdatedEventPayload['assets'] =\n {};\n for (const [accountId, { added, removed }] of Object.entries(\n event.assets,\n )) {\n if (added.length > 0 || removed.length > 0) {\n const existing = this.state.accountsAssets[accountId] || [];\n\n // In case accountsAndAssetsToUpdate event is fired with \"added\" assets that already exist, we don't want to add them again\n const filteredToBeAddedAssets = added.filter(\n (asset) => !existing.includes(asset) && isCaipAssetType(asset),\n );\n\n // In case accountsAndAssetsToUpdate event is fired with \"removed\" assets that don't exist, we don't want to remove them\n const filteredToBeRemovedAssets = removed.filter(\n (asset) => existing.includes(asset) && isCaipAssetType(asset),\n );\n\n if (\n filteredToBeAddedAssets.length > 0 ||\n filteredToBeRemovedAssets.length > 0\n ) {\n accountsAndAssetsToUpdate[accountId] = {\n added: filteredToBeAddedAssets,\n removed: filteredToBeRemovedAssets,\n };\n }\n\n for (const asset of existing) {\n assetsForMetadataRefresh.add(asset);\n }\n for (const asset of filteredToBeAddedAssets) {\n assetsForMetadataRefresh.add(asset);\n }\n for (const asset of filteredToBeRemovedAssets) {\n assetsForMetadataRefresh.delete(asset);\n }\n }\n }\n\n this.update((state) => {\n for (const [accountId, { added, removed }] of Object.entries(\n accountsAndAssetsToUpdate,\n )) {\n const assets = new Set([\n ...(state.accountsAssets[accountId] || []),\n ...added,\n ]);\n for (const asset of removed) {\n assets.delete(asset);\n }\n\n state.accountsAssets[accountId] = Array.from(assets);\n }\n });\n\n // Trigger fetching metadata for new assets\n await this.#refreshAssetsMetadata(Array.from(assetsForMetadataRefresh));\n\n this.messagingSystem.publish(`${controllerName}:accountAssetListUpdated`, {\n assets: accountsAndAssetsToUpdate,\n });\n }\n\n /**\n * Checks for non-EVM accounts.\n *\n * @param account - The new account to be checked.\n * @returns True if the account is a non-EVM account, false otherwise.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) &&\n // Non-EVM accounts are backed by a Snap for now\n account.metadata.snap !== undefined\n );\n }\n\n /**\n * Handles changes when a new account has been added.\n *\n * @param account - The new account being added.\n */\n async #handleOnAccountAdded(account: InternalAccount): Promise<void> {\n if (!this.#isNonEvmAccount(account)) {\n // Nothing to do here for EVM accounts\n return;\n }\n this.#assertControllerMutexIsLocked();\n\n // Get assets list\n if (account.metadata.snap) {\n const assets = await this.#getAssetsList(\n account.id,\n account.metadata.snap.id,\n );\n await this.#refreshAssetsMetadata(assets);\n this.update((state) => {\n state.accountsAssets[account.id] = assets;\n });\n this.messagingSystem.publish(\n `${controllerName}:accountAssetListUpdated`,\n {\n assets: {\n [account.id]: {\n added: assets,\n removed: [],\n },\n },\n },\n );\n }\n }\n\n /**\n * Handles changes when a new account has been removed.\n *\n * @param accountId - The new account id being removed.\n */\n async #handleOnAccountRemovedEvent(accountId: string): Promise<void> {\n // Check if accountId is in accountsAssets and if it is, remove it\n if (this.state.accountsAssets[accountId]) {\n this.update((state) => {\n // TODO: We are not deleting the assetsMetadata because we will soon make this controller extends StaticIntervalPollingController\n // and update all assetsMetadata once a day.\n delete state.accountsAssets[accountId];\n });\n }\n }\n\n /**\n * Refreshes the assets snaps and metadata for the given list of assets\n *\n * @param assets - The assets to refresh\n */\n async #refreshAssetsMetadata(assets: CaipAssetType[]) {\n this.#assertControllerMutexIsLocked();\n\n const assetsWithoutMetadata: CaipAssetType[] = assets.filter(\n (asset) => !this.state.assetsMetadata[asset],\n );\n\n // Call the snap to get the metadata\n if (assetsWithoutMetadata.length > 0) {\n // Check if for every asset in assetsWithoutMetadata there is a snap in snaps by chainId else call getAssetSnaps\n if (\n !assetsWithoutMetadata.every((asset: CaipAssetType) => {\n const { chainId } = parseCaipAssetType(asset);\n return Boolean(this.#getAssetSnapFor(chainId));\n })\n ) {\n this.#snaps = this.#getAssetSnaps();\n }\n await this.#updateAssetsMetadata(assetsWithoutMetadata);\n }\n }\n\n /**\n * Updates the assets metadata for the given list of assets\n *\n * @param assets - The assets to update\n */\n async #updateAssetsMetadata(assets: CaipAssetType[]) {\n // Creates a mapping of scope to their respective assets list.\n const assetsByScope: Record<CaipChainId, CaipAssetType[]> = {};\n for (const asset of assets) {\n const { chainId } = parseCaipAssetType(asset);\n if (!assetsByScope[chainId]) {\n assetsByScope[chainId] = [];\n }\n assetsByScope[chainId].push(asset);\n }\n\n let newMetadata: Record<CaipAssetType, FungibleAssetMetadata> = {};\n for (const chainId of Object.keys(assetsByScope) as CaipChainId[]) {\n const assetsForChain = assetsByScope[chainId];\n // Now fetch metadata from the associated asset Snaps:\n const snap = this.#getAssetSnapFor(chainId);\n if (snap) {\n const metadata = await this.#getAssetsMetadataFrom(\n assetsForChain,\n snap.id,\n );\n newMetadata = {\n ...newMetadata,\n ...(metadata?.assets ?? {}),\n };\n }\n }\n this.update((state) => {\n state.assetsMetadata = {\n ...this.state.assetsMetadata,\n ...newMetadata,\n };\n });\n }\n\n /**\n * Creates a mapping of CAIP-2 Chain ID to Asset Snaps.\n *\n * @returns A mapping of CAIP-2 Chain ID to Asset Snaps.\n */\n #getAssetSnaps(): Record<CaipChainId, Snap[]> {\n const snaps: Record<CaipChainId, Snap[]> = {};\n const allSnaps = this.#getAllSnaps();\n const allPermissions = allSnaps.map((snap) =>\n this.#getSnapsPermissions(snap.id),\n );\n\n for (const [index, permission] of allPermissions.entries()) {\n let scopes;\n for (const singlePermissionConstraint of Object.values(permission)) {\n scopes = getChainIdsCaveat(singlePermissionConstraint);\n if (!scopes) {\n continue;\n }\n for (const scope of scopes as CaipChainId[]) {\n if (!snaps[scope]) {\n snaps[scope] = [];\n }\n snaps[scope].push(allSnaps[index]);\n }\n }\n }\n return snaps;\n }\n\n /**\n * Returns the first asset snap for the given scope\n *\n * @param scope - The scope to get the asset snap for\n * @returns The asset snap for the given scope\n */\n #getAssetSnapFor(scope: CaipChainId): Snap | undefined {\n const allSnaps = this.#snaps[scope];\n // Pick only the first one, we ignore the other Snaps if there are multiple candidates for now.\n return allSnaps?.[0]; // Will be undefined if there's no Snaps candidate for this scope.\n }\n\n /**\n * Returns all the asset snaps\n *\n * @returns All the asset snaps\n */\n #getAllSnaps(): Snap[] {\n // TODO: Use dedicated SnapController's action once available for this:\n return this.messagingSystem\n .call('SnapController:getAll')\n .filter((snap) => snap.enabled && !snap.blocked);\n }\n\n /**\n * Returns the permissions for the given origin\n *\n * @param origin - The origin to get the permissions for\n * @returns The permissions for the given origin\n */\n #getSnapsPermissions(\n origin: string,\n ): SubjectPermissions<PermissionConstraint> {\n return this.messagingSystem.call(\n 'PermissionController:getPermissions',\n origin,\n ) as SubjectPermissions<PermissionConstraint>;\n }\n\n /**\n * Returns the metadata for the given assets\n *\n * @param assets - The assets to get metadata for\n * @param snapId - The snap ID to get metadata from\n * @returns The metadata for the assets\n */\n async #getAssetsMetadataFrom(\n assets: CaipAssetType[],\n snapId: string,\n ): Promise<AssetMetadataResponse | undefined> {\n try {\n return (await this.messagingSystem.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnAssetsLookup,\n request: {\n jsonrpc: '2.0',\n method: 'onAssetLookup',\n params: {\n assets,\n },\n },\n })) as Promise<AssetMetadataResponse>;\n } catch (error) {\n // Ignore\n console.error(error);\n return undefined;\n }\n }\n\n /**\n * Get assets list for an account\n *\n * @param accountId - AccountId to get assets for\n * @param snapId - Snap ID for the account\n * @returns list of assets\n */\n async #getAssetsList(\n accountId: string,\n snapId: string,\n ): Promise<CaipAssetTypeOrId[]> {\n return await this.#getClient(snapId).listAccountAssets(accountId);\n }\n\n /**\n * Gets a `KeyringClient` for a Snap.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getClient(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) =>\n (await this.messagingSystem.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n })) as Promise<Json>,\n });\n }\n\n /**\n * Assert that the controller mutex is locked.\n *\n * @throws If the controller mutex is not locked.\n */\n #assertControllerMutexIsLocked() {\n if (!this.#controllerOperationMutex.isLocked()) {\n throw new Error(\n 'MultichainAssetsControllerError - Attempt to update state',\n );\n }\n }\n\n /**\n * Lock the controller mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This wrapper ensures that each mutable operation that interacts with the\n * controller and that changes its state is executed in a mutually exclusive way,\n * preventing unsafe concurrent access that could lead to unpredictable behavior.\n *\n * @param callback - The function to execute while the controller mutex is locked.\n * @returns The result of the function.\n */\n async #withControllerLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return withLock(this.#controllerOperationMutex, callback);\n }\n}\n\n/**\n * Lock the given mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * @param mutex - The mutex to lock.\n * @param callback - The function to execute while the mutex is locked.\n * @returns The result of the function.\n */\nasync function withLock<Result>(\n mutex: Mutex,\n callback: MutuallyExclusiveCallback<Result>,\n): Promise<Result> {\n const releaseLock = await mutex.acquire();\n\n try {\n return await callback({ releaseLock });\n } finally {\n releaseLock();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainAssetsController.cjs","sourceRoot":"","sources":["../../src/MultichainAssetsController/MultichainAssetsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountAssetListUpdatedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type StateMetadata,\n} from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type {\n AccountAssetListUpdatedEventPayload,\n CaipAssetType,\n CaipAssetTypeOrId,\n} from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport { KeyringClient } from '@metamask/keyring-snap-client';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n GetPermissions,\n PermissionConstraint,\n SubjectPermissions,\n} from '@metamask/permission-controller';\nimport type {\n GetAllSnaps,\n HandleSnapRequest,\n} from '@metamask/snaps-controllers';\nimport type { FungibleAssetMetadata, Snap, SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport {\n isCaipAssetType,\n parseCaipAssetType,\n type CaipChainId,\n} from '@metamask/utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\nimport type { MutexInterface } from 'async-mutex';\nimport { Mutex } from 'async-mutex';\n\nimport { getChainIdsCaveat } from './utils';\n\nconst controllerName = 'MultichainAssetsController';\n\nexport type MultichainAssetsControllerState = {\n assetsMetadata: {\n [asset: CaipAssetType]: FungibleAssetMetadata;\n };\n accountsAssets: { [account: string]: CaipAssetType[] };\n allIgnoredAssets: { [account: string]: CaipAssetType[] };\n};\n\n// Represents the response of the asset snap's onAssetLookup handler\nexport type AssetMetadataResponse = {\n assets: {\n [asset: CaipAssetType]: FungibleAssetMetadata;\n };\n};\n\nexport type MultichainAssetsControllerAccountAssetListUpdatedEvent = {\n type: `${typeof controllerName}:accountAssetListUpdated`;\n payload: AccountsControllerAccountAssetListUpdatedEvent['payload'];\n};\n\n/**\n * Constructs the default {@link MultichainAssetsController} 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 MultichainAssetsController} state.\n */\nexport function getDefaultMultichainAssetsControllerState(): MultichainAssetsControllerState {\n return { accountsAssets: {}, assetsMetadata: {}, allIgnoredAssets: {} };\n}\n\nexport type MultichainAssetsControllerGetAssetMetadataAction = {\n type: `${typeof controllerName}:getAssetMetadata`;\n handler: MultichainAssetsController['getAssetMetadata'];\n};\n\nexport type MultichainAssetsControllerIgnoreAssetsAction = {\n type: `${typeof controllerName}:ignoreAssets`;\n handler: MultichainAssetsController['ignoreAssets'];\n};\n\n/**\n * Returns the state of the {@link MultichainAssetsController}.\n */\nexport type MultichainAssetsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n MultichainAssetsControllerState\n>;\n\n/**\n * Event emitted when the state of the {@link MultichainAssetsController} changes.\n */\nexport type MultichainAssetsControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainAssetsControllerState\n >;\n\n/**\n * Actions exposed by the {@link MultichainAssetsController}.\n */\nexport type MultichainAssetsControllerActions =\n | MultichainAssetsControllerGetStateAction\n | MultichainAssetsControllerGetAssetMetadataAction\n | MultichainAssetsControllerIgnoreAssetsAction;\n\n/**\n * Events emitted by {@link MultichainAssetsController}.\n */\nexport type MultichainAssetsControllerEvents =\n | MultichainAssetsControllerStateChangeEvent\n | MultichainAssetsControllerAccountAssetListUpdatedEvent;\n\n/**\n * A function executed within a mutually exclusive lock, with\n * a mutex releaser in its option bag.\n *\n * @param releaseLock - A function to release the lock.\n */\ntype MutuallyExclusiveCallback<Result> = ({\n releaseLock,\n}: {\n releaseLock: MutexInterface.Releaser;\n}) => Promise<Result>;\n\n/**\n * Actions that this controller is allowed to call.\n */\ntype AllowedActions =\n | HandleSnapRequest\n | GetAllSnaps\n | GetPermissions\n | AccountsControllerListMultichainAccountsAction;\n\n/**\n * Events that this controller is allowed to subscribe.\n */\ntype AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent\n | AccountsControllerAccountAssetListUpdatedEvent;\n\n/**\n * Messenger type for the MultichainAssetsController.\n */\nexport type MultichainAssetsControllerMessenger = Messenger<\n typeof controllerName,\n MultichainAssetsControllerActions | AllowedActions,\n MultichainAssetsControllerEvents | AllowedEvents\n>;\n\n/**\n * {@link MultichainAssetsController}'s metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst assetsControllerMetadata: StateMetadata<MultichainAssetsControllerState> =\n {\n assetsMetadata: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n accountsAssets: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n allIgnoredAssets: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n };\n\n// TODO: make this controller extends StaticIntervalPollingController and update all assetsMetadata once a day.\n\nexport class MultichainAssetsController extends BaseController<\n typeof controllerName,\n MultichainAssetsControllerState,\n MultichainAssetsControllerMessenger\n> {\n // Mapping of CAIP-2 Chain ID to Asset Snaps.\n #snaps: Record<CaipChainId, Snap[]>;\n\n readonly #controllerOperationMutex = new Mutex();\n\n constructor({\n messenger,\n state = {},\n }: {\n messenger: MultichainAssetsControllerMessenger;\n state?: Partial<MultichainAssetsControllerState>;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: assetsControllerMetadata,\n state: {\n ...getDefaultMultichainAssetsControllerState(),\n ...state,\n },\n });\n\n this.#snaps = {};\n\n this.messenger.subscribe(\n 'AccountsController:accountAdded',\n async (account) => await this.#handleOnAccountAddedEvent(account),\n );\n this.messenger.subscribe(\n 'AccountsController:accountRemoved',\n async (account) => await this.#handleOnAccountRemovedEvent(account),\n );\n this.messenger.subscribe(\n 'AccountsController:accountAssetListUpdated',\n async (event) => await this.#handleAccountAssetListUpdatedEvent(event),\n );\n\n this.#registerMessageHandlers();\n }\n\n async #handleAccountAssetListUpdatedEvent(\n event: AccountAssetListUpdatedEventPayload,\n ) {\n return this.#withControllerLock(async () =>\n this.#handleAccountAssetListUpdated(event),\n );\n }\n\n async #handleOnAccountAddedEvent(account: InternalAccount) {\n return this.#withControllerLock(async () =>\n this.#handleOnAccountAdded(account),\n );\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n #registerMessageHandlers() {\n this.messenger.registerActionHandler(\n 'MultichainAssetsController:getAssetMetadata',\n this.getAssetMetadata.bind(this),\n );\n\n this.messenger.registerActionHandler(\n 'MultichainAssetsController:ignoreAssets',\n this.ignoreAssets.bind(this),\n );\n }\n\n /**\n * Returns the metadata for the given asset\n *\n * @param asset - The asset to get metadata for\n * @returns The metadata for the asset or undefined if not found.\n */\n getAssetMetadata(asset: CaipAssetType): FungibleAssetMetadata | undefined {\n return this.state.assetsMetadata[asset];\n }\n\n /**\n * Ignores a batch of assets for a specific account.\n *\n * @param assetsToIgnore - Array of asset IDs to ignore.\n * @param accountId - The account ID to ignore assets for.\n */\n ignoreAssets(assetsToIgnore: CaipAssetType[], accountId: string): void {\n this.update((state) => {\n if (state.accountsAssets[accountId]) {\n state.accountsAssets[accountId] = state.accountsAssets[\n accountId\n ].filter((asset) => !assetsToIgnore.includes(asset));\n }\n\n if (!state.allIgnoredAssets[accountId]) {\n state.allIgnoredAssets[accountId] = [];\n }\n\n const newIgnoredAssets = assetsToIgnore.filter(\n (asset) => !state.allIgnoredAssets[accountId].includes(asset),\n );\n state.allIgnoredAssets[accountId].push(...newIgnoredAssets);\n });\n }\n\n /**\n * Checks if an asset is ignored for a specific account.\n *\n * @param asset - The asset ID to check.\n * @param accountId - The account ID to check for.\n * @returns True if the asset is ignored, false otherwise.\n */\n #isAssetIgnored(asset: CaipAssetType, accountId: string): boolean {\n return this.state.allIgnoredAssets[accountId]?.includes(asset) ?? false;\n }\n\n /**\n * Function to update the assets list for an account\n *\n * @param event - The list of assets to update\n */\n async #handleAccountAssetListUpdated(\n event: AccountAssetListUpdatedEventPayload,\n ) {\n this.#assertControllerMutexIsLocked();\n\n const assetsForMetadataRefresh = new Set<CaipAssetType>([]);\n const accountsAndAssetsToUpdate: AccountAssetListUpdatedEventPayload['assets'] =\n {};\n for (const [accountId, { added, removed }] of Object.entries(\n event.assets,\n )) {\n if (added.length > 0 || removed.length > 0) {\n const existing = this.state.accountsAssets[accountId] || [];\n\n // In case accountsAndAssetsToUpdate event is fired with \"added\" assets that already exist, we don't want to add them again\n // Also filter out ignored assets\n const filteredToBeAddedAssets = added.filter(\n (asset) =>\n !existing.includes(asset) &&\n isCaipAssetType(asset) &&\n !this.#isAssetIgnored(asset, accountId),\n );\n\n // In case accountsAndAssetsToUpdate event is fired with \"removed\" assets that don't exist, we don't want to remove them\n const filteredToBeRemovedAssets = removed.filter(\n (asset) => existing.includes(asset) && isCaipAssetType(asset),\n );\n\n if (\n filteredToBeAddedAssets.length > 0 ||\n filteredToBeRemovedAssets.length > 0\n ) {\n accountsAndAssetsToUpdate[accountId] = {\n added: filteredToBeAddedAssets,\n removed: filteredToBeRemovedAssets,\n };\n }\n\n for (const asset of existing) {\n assetsForMetadataRefresh.add(asset);\n }\n for (const asset of filteredToBeAddedAssets) {\n assetsForMetadataRefresh.add(asset);\n }\n for (const asset of filteredToBeRemovedAssets) {\n assetsForMetadataRefresh.delete(asset);\n }\n }\n }\n\n this.update((state) => {\n for (const [accountId, { added, removed }] of Object.entries(\n accountsAndAssetsToUpdate,\n )) {\n const assets = new Set([\n ...(state.accountsAssets[accountId] || []),\n ...added,\n ]);\n for (const asset of removed) {\n assets.delete(asset);\n }\n\n state.accountsAssets[accountId] = Array.from(assets);\n }\n });\n\n // Trigger fetching metadata for new assets\n await this.#refreshAssetsMetadata(Array.from(assetsForMetadataRefresh));\n\n this.messenger.publish(`${controllerName}:accountAssetListUpdated`, {\n assets: accountsAndAssetsToUpdate,\n });\n }\n\n /**\n * Checks for non-EVM accounts.\n *\n * @param account - The new account to be checked.\n * @returns True if the account is a non-EVM account, false otherwise.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) &&\n // Non-EVM accounts are backed by a Snap for now\n account.metadata.snap !== undefined\n );\n }\n\n /**\n * Handles changes when a new account has been added.\n *\n * @param account - The new account being added.\n */\n async #handleOnAccountAdded(account: InternalAccount): Promise<void> {\n if (!this.#isNonEvmAccount(account)) {\n // Nothing to do here for EVM accounts\n return;\n }\n this.#assertControllerMutexIsLocked();\n\n // Get assets list\n if (account.metadata.snap) {\n const assets = await this.#getAssetsList(\n account.id,\n account.metadata.snap.id,\n );\n await this.#refreshAssetsMetadata(assets);\n this.update((state) => {\n state.accountsAssets[account.id] = assets;\n });\n this.messenger.publish(`${controllerName}:accountAssetListUpdated`, {\n assets: {\n [account.id]: {\n added: assets,\n removed: [],\n },\n },\n });\n }\n }\n\n /**\n * Handles changes when a new account has been removed.\n *\n * @param accountId - The new account id being removed.\n */\n async #handleOnAccountRemovedEvent(accountId: string): Promise<void> {\n this.update((state) => {\n if (state.accountsAssets[accountId]) {\n delete state.accountsAssets[accountId];\n }\n if (state.allIgnoredAssets[accountId]) {\n delete state.allIgnoredAssets[accountId];\n }\n // TODO: We are not deleting the assetsMetadata because we will soon make this controller extends StaticIntervalPollingController\n // and update all assetsMetadata once a day.\n });\n }\n\n /**\n * Refreshes the assets snaps and metadata for the given list of assets\n *\n * @param assets - The assets to refresh\n */\n async #refreshAssetsMetadata(assets: CaipAssetType[]) {\n this.#assertControllerMutexIsLocked();\n\n const assetsWithoutMetadata: CaipAssetType[] = assets.filter(\n (asset) => !this.state.assetsMetadata[asset],\n );\n\n // Call the snap to get the metadata\n if (assetsWithoutMetadata.length > 0) {\n // Check if for every asset in assetsWithoutMetadata there is a snap in snaps by chainId else call getAssetSnaps\n if (\n !assetsWithoutMetadata.every((asset: CaipAssetType) => {\n const { chainId } = parseCaipAssetType(asset);\n return Boolean(this.#getAssetSnapFor(chainId));\n })\n ) {\n this.#snaps = this.#getAssetSnaps();\n }\n await this.#updateAssetsMetadata(assetsWithoutMetadata);\n }\n }\n\n /**\n * Updates the assets metadata for the given list of assets\n *\n * @param assets - The assets to update\n */\n async #updateAssetsMetadata(assets: CaipAssetType[]) {\n // Creates a mapping of scope to their respective assets list.\n const assetsByScope: Record<CaipChainId, CaipAssetType[]> = {};\n for (const asset of assets) {\n const { chainId } = parseCaipAssetType(asset);\n if (!assetsByScope[chainId]) {\n assetsByScope[chainId] = [];\n }\n assetsByScope[chainId].push(asset);\n }\n\n let newMetadata: Record<CaipAssetType, FungibleAssetMetadata> = {};\n for (const chainId of Object.keys(assetsByScope) as CaipChainId[]) {\n const assetsForChain = assetsByScope[chainId];\n // Now fetch metadata from the associated asset Snaps:\n const snap = this.#getAssetSnapFor(chainId);\n if (snap) {\n const metadata = await this.#getAssetsMetadataFrom(\n assetsForChain,\n snap.id,\n );\n newMetadata = {\n ...newMetadata,\n ...(metadata?.assets ?? {}),\n };\n }\n }\n this.update((state) => {\n state.assetsMetadata = {\n ...this.state.assetsMetadata,\n ...newMetadata,\n };\n });\n }\n\n /**\n * Creates a mapping of CAIP-2 Chain ID to Asset Snaps.\n *\n * @returns A mapping of CAIP-2 Chain ID to Asset Snaps.\n */\n #getAssetSnaps(): Record<CaipChainId, Snap[]> {\n const snaps: Record<CaipChainId, Snap[]> = {};\n const allSnaps = this.#getAllSnaps();\n const allPermissions = allSnaps.map((snap) =>\n this.#getSnapsPermissions(snap.id),\n );\n\n for (const [index, permission] of allPermissions.entries()) {\n let scopes;\n for (const singlePermissionConstraint of Object.values(permission)) {\n scopes = getChainIdsCaveat(singlePermissionConstraint);\n if (!scopes) {\n continue;\n }\n for (const scope of scopes as CaipChainId[]) {\n if (!snaps[scope]) {\n snaps[scope] = [];\n }\n snaps[scope].push(allSnaps[index]);\n }\n }\n }\n return snaps;\n }\n\n /**\n * Returns the first asset snap for the given scope\n *\n * @param scope - The scope to get the asset snap for\n * @returns The asset snap for the given scope\n */\n #getAssetSnapFor(scope: CaipChainId): Snap | undefined {\n const allSnaps = this.#snaps[scope];\n // Pick only the first one, we ignore the other Snaps if there are multiple candidates for now.\n return allSnaps?.[0]; // Will be undefined if there's no Snaps candidate for this scope.\n }\n\n /**\n * Returns all the asset snaps\n *\n * @returns All the asset snaps\n */\n #getAllSnaps(): Snap[] {\n // TODO: Use dedicated SnapController's action once available for this:\n return this.messenger\n .call('SnapController:getAll')\n .filter((snap) => snap.enabled && !snap.blocked);\n }\n\n /**\n * Returns the permissions for the given origin\n *\n * @param origin - The origin to get the permissions for\n * @returns The permissions for the given origin\n */\n #getSnapsPermissions(\n origin: string,\n ): SubjectPermissions<PermissionConstraint> {\n return this.messenger.call(\n 'PermissionController:getPermissions',\n origin,\n ) as SubjectPermissions<PermissionConstraint>;\n }\n\n /**\n * Returns the metadata for the given assets\n *\n * @param assets - The assets to get metadata for\n * @param snapId - The snap ID to get metadata from\n * @returns The metadata for the assets\n */\n async #getAssetsMetadataFrom(\n assets: CaipAssetType[],\n snapId: string,\n ): Promise<AssetMetadataResponse | undefined> {\n try {\n return (await this.messenger.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnAssetsLookup,\n request: {\n jsonrpc: '2.0',\n method: 'onAssetLookup',\n params: {\n assets,\n },\n },\n })) as Promise<AssetMetadataResponse>;\n } catch (error) {\n // Ignore\n console.error(error);\n return undefined;\n }\n }\n\n /**\n * Get assets list for an account\n *\n * @param accountId - AccountId to get assets for\n * @param snapId - Snap ID for the account\n * @returns list of assets\n */\n async #getAssetsList(\n accountId: string,\n snapId: string,\n ): Promise<CaipAssetTypeOrId[]> {\n return await this.#getClient(snapId).listAccountAssets(accountId);\n }\n\n /**\n * Gets a `KeyringClient` for a Snap.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getClient(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) =>\n (await this.messenger.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n })) as Promise<Json>,\n });\n }\n\n /**\n * Assert that the controller mutex is locked.\n *\n * @throws If the controller mutex is not locked.\n */\n #assertControllerMutexIsLocked() {\n if (!this.#controllerOperationMutex.isLocked()) {\n throw new Error(\n 'MultichainAssetsControllerError - Attempt to update state',\n );\n }\n }\n\n /**\n * Lock the controller mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This wrapper ensures that each mutable operation that interacts with the\n * controller and that changes its state is executed in a mutually exclusive way,\n * preventing unsafe concurrent access that could lead to unpredictable behavior.\n *\n * @param callback - The function to execute while the controller mutex is locked.\n * @returns The result of the function.\n */\n async #withControllerLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return withLock(this.#controllerOperationMutex, callback);\n }\n}\n\n/**\n * Lock the given mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * @param mutex - The mutex to lock.\n * @param callback - The function to execute while the mutex is locked.\n * @returns The result of the function.\n */\nasync function withLock<Result>(\n mutex: Mutex,\n callback: MutuallyExclusiveCallback<Result>,\n): Promise<Result> {\n const releaseLock = await mutex.acquire();\n\n try {\n return await callback({ releaseLock });\n } finally {\n releaseLock();\n }\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AccountsControllerAccountAddedEvent, AccountsControllerAccountAssetListUpdatedEvent, AccountsControllerAccountRemovedEvent, AccountsControllerListMultichainAccountsAction } from "@metamask/accounts-controller";
|
|
2
|
-
import { BaseController, type ControllerGetStateAction, type ControllerStateChangeEvent
|
|
2
|
+
import { BaseController, type ControllerGetStateAction, type ControllerStateChangeEvent } from "@metamask/base-controller";
|
|
3
3
|
import type { CaipAssetType } from "@metamask/keyring-api";
|
|
4
|
+
import type { Messenger } from "@metamask/messenger";
|
|
4
5
|
import type { GetPermissions } from "@metamask/permission-controller";
|
|
5
6
|
import type { GetAllSnaps, HandleSnapRequest } from "@metamask/snaps-controllers";
|
|
6
7
|
import type { FungibleAssetMetadata } from "@metamask/snaps-sdk";
|
|
@@ -12,6 +13,9 @@ export type MultichainAssetsControllerState = {
|
|
|
12
13
|
accountsAssets: {
|
|
13
14
|
[account: string]: CaipAssetType[];
|
|
14
15
|
};
|
|
16
|
+
allIgnoredAssets: {
|
|
17
|
+
[account: string]: CaipAssetType[];
|
|
18
|
+
};
|
|
15
19
|
};
|
|
16
20
|
export type AssetMetadataResponse = {
|
|
17
21
|
assets: {
|
|
@@ -35,6 +39,10 @@ export type MultichainAssetsControllerGetAssetMetadataAction = {
|
|
|
35
39
|
type: `${typeof controllerName}:getAssetMetadata`;
|
|
36
40
|
handler: MultichainAssetsController['getAssetMetadata'];
|
|
37
41
|
};
|
|
42
|
+
export type MultichainAssetsControllerIgnoreAssetsAction = {
|
|
43
|
+
type: `${typeof controllerName}:ignoreAssets`;
|
|
44
|
+
handler: MultichainAssetsController['ignoreAssets'];
|
|
45
|
+
};
|
|
38
46
|
/**
|
|
39
47
|
* Returns the state of the {@link MultichainAssetsController}.
|
|
40
48
|
*/
|
|
@@ -46,7 +54,7 @@ export type MultichainAssetsControllerStateChangeEvent = ControllerStateChangeEv
|
|
|
46
54
|
/**
|
|
47
55
|
* Actions exposed by the {@link MultichainAssetsController}.
|
|
48
56
|
*/
|
|
49
|
-
export type MultichainAssetsControllerActions = MultichainAssetsControllerGetStateAction | MultichainAssetsControllerGetAssetMetadataAction;
|
|
57
|
+
export type MultichainAssetsControllerActions = MultichainAssetsControllerGetStateAction | MultichainAssetsControllerGetAssetMetadataAction | MultichainAssetsControllerIgnoreAssetsAction;
|
|
50
58
|
/**
|
|
51
59
|
* Events emitted by {@link MultichainAssetsController}.
|
|
52
60
|
*/
|
|
@@ -62,7 +70,7 @@ type AllowedEvents = AccountsControllerAccountAddedEvent | AccountsControllerAcc
|
|
|
62
70
|
/**
|
|
63
71
|
* Messenger type for the MultichainAssetsController.
|
|
64
72
|
*/
|
|
65
|
-
export type MultichainAssetsControllerMessenger =
|
|
73
|
+
export type MultichainAssetsControllerMessenger = Messenger<typeof controllerName, MultichainAssetsControllerActions | AllowedActions, MultichainAssetsControllerEvents | AllowedEvents>;
|
|
66
74
|
export declare class MultichainAssetsController extends BaseController<typeof controllerName, MultichainAssetsControllerState, MultichainAssetsControllerMessenger> {
|
|
67
75
|
#private;
|
|
68
76
|
constructor({ messenger, state, }: {
|
|
@@ -76,6 +84,13 @@ export declare class MultichainAssetsController extends BaseController<typeof co
|
|
|
76
84
|
* @returns The metadata for the asset or undefined if not found.
|
|
77
85
|
*/
|
|
78
86
|
getAssetMetadata(asset: CaipAssetType): FungibleAssetMetadata | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Ignores a batch of assets for a specific account.
|
|
89
|
+
*
|
|
90
|
+
* @param assetsToIgnore - Array of asset IDs to ignore.
|
|
91
|
+
* @param accountId - The account ID to ignore assets for.
|
|
92
|
+
*/
|
|
93
|
+
ignoreAssets(assetsToIgnore: CaipAssetType[], accountId: string): void;
|
|
79
94
|
}
|
|
80
95
|
export {};
|
|
81
96
|
//# sourceMappingURL=MultichainAssetsController.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAssetsController.d.cts","sourceRoot":"","sources":["../../src/MultichainAssetsController/MultichainAssetsController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,8CAA8C,EAC9C,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,
|
|
1
|
+
{"version":3,"file":"MultichainAssetsController.d.cts","sourceRoot":"","sources":["../../src/MultichainAssetsController/MultichainAssetsController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AccountsControllerAccountAddedEvent, AccountsControllerAccountAssetListUpdatedEvent, AccountsControllerAccountRemovedEvent, AccountsControllerListMultichainAccountsAction } from "@metamask/accounts-controller";
|
|
2
|
-
import { BaseController, type ControllerGetStateAction, type ControllerStateChangeEvent
|
|
2
|
+
import { BaseController, type ControllerGetStateAction, type ControllerStateChangeEvent } from "@metamask/base-controller";
|
|
3
3
|
import type { CaipAssetType } from "@metamask/keyring-api";
|
|
4
|
+
import type { Messenger } from "@metamask/messenger";
|
|
4
5
|
import type { GetPermissions } from "@metamask/permission-controller";
|
|
5
6
|
import type { GetAllSnaps, HandleSnapRequest } from "@metamask/snaps-controllers";
|
|
6
7
|
import type { FungibleAssetMetadata } from "@metamask/snaps-sdk";
|
|
@@ -12,6 +13,9 @@ export type MultichainAssetsControllerState = {
|
|
|
12
13
|
accountsAssets: {
|
|
13
14
|
[account: string]: CaipAssetType[];
|
|
14
15
|
};
|
|
16
|
+
allIgnoredAssets: {
|
|
17
|
+
[account: string]: CaipAssetType[];
|
|
18
|
+
};
|
|
15
19
|
};
|
|
16
20
|
export type AssetMetadataResponse = {
|
|
17
21
|
assets: {
|
|
@@ -35,6 +39,10 @@ export type MultichainAssetsControllerGetAssetMetadataAction = {
|
|
|
35
39
|
type: `${typeof controllerName}:getAssetMetadata`;
|
|
36
40
|
handler: MultichainAssetsController['getAssetMetadata'];
|
|
37
41
|
};
|
|
42
|
+
export type MultichainAssetsControllerIgnoreAssetsAction = {
|
|
43
|
+
type: `${typeof controllerName}:ignoreAssets`;
|
|
44
|
+
handler: MultichainAssetsController['ignoreAssets'];
|
|
45
|
+
};
|
|
38
46
|
/**
|
|
39
47
|
* Returns the state of the {@link MultichainAssetsController}.
|
|
40
48
|
*/
|
|
@@ -46,7 +54,7 @@ export type MultichainAssetsControllerStateChangeEvent = ControllerStateChangeEv
|
|
|
46
54
|
/**
|
|
47
55
|
* Actions exposed by the {@link MultichainAssetsController}.
|
|
48
56
|
*/
|
|
49
|
-
export type MultichainAssetsControllerActions = MultichainAssetsControllerGetStateAction | MultichainAssetsControllerGetAssetMetadataAction;
|
|
57
|
+
export type MultichainAssetsControllerActions = MultichainAssetsControllerGetStateAction | MultichainAssetsControllerGetAssetMetadataAction | MultichainAssetsControllerIgnoreAssetsAction;
|
|
50
58
|
/**
|
|
51
59
|
* Events emitted by {@link MultichainAssetsController}.
|
|
52
60
|
*/
|
|
@@ -62,7 +70,7 @@ type AllowedEvents = AccountsControllerAccountAddedEvent | AccountsControllerAcc
|
|
|
62
70
|
/**
|
|
63
71
|
* Messenger type for the MultichainAssetsController.
|
|
64
72
|
*/
|
|
65
|
-
export type MultichainAssetsControllerMessenger =
|
|
73
|
+
export type MultichainAssetsControllerMessenger = Messenger<typeof controllerName, MultichainAssetsControllerActions | AllowedActions, MultichainAssetsControllerEvents | AllowedEvents>;
|
|
66
74
|
export declare class MultichainAssetsController extends BaseController<typeof controllerName, MultichainAssetsControllerState, MultichainAssetsControllerMessenger> {
|
|
67
75
|
#private;
|
|
68
76
|
constructor({ messenger, state, }: {
|
|
@@ -76,6 +84,13 @@ export declare class MultichainAssetsController extends BaseController<typeof co
|
|
|
76
84
|
* @returns The metadata for the asset or undefined if not found.
|
|
77
85
|
*/
|
|
78
86
|
getAssetMetadata(asset: CaipAssetType): FungibleAssetMetadata | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Ignores a batch of assets for a specific account.
|
|
89
|
+
*
|
|
90
|
+
* @param assetsToIgnore - Array of asset IDs to ignore.
|
|
91
|
+
* @param accountId - The account ID to ignore assets for.
|
|
92
|
+
*/
|
|
93
|
+
ignoreAssets(assetsToIgnore: CaipAssetType[], accountId: string): void;
|
|
79
94
|
}
|
|
80
95
|
export {};
|
|
81
96
|
//# sourceMappingURL=MultichainAssetsController.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAssetsController.d.mts","sourceRoot":"","sources":["../../src/MultichainAssetsController/MultichainAssetsController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,8CAA8C,EAC9C,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,
|
|
1
|
+
{"version":3,"file":"MultichainAssetsController.d.mts","sourceRoot":"","sources":["../../src/MultichainAssetsController/MultichainAssetsController.ts"],"names":[],"mappings":"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"}
|