@metamask-previews/assets-controllers 109.1.0-preview-e4b456ca8 → 109.1.0-preview-0bd5566
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 +10 -0
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.cjs +48 -3
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.cjs.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts +9 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts +9 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs +48 -3
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.cjs +57 -8
- package/dist/MultichainBalancesController/MultichainBalancesController.cjs.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.cts +15 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.cts.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.mts +15 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.mts.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.mjs +57 -8
- package/dist/MultichainBalancesController/MultichainBalancesController.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Add `isDeprecated` option to `MultichainAssetsRatesController` constructor ([#9044](https://github.com/MetaMask/core/pull/9044))
|
|
13
|
+
- When `isDeprecated()` returns `true`, no Snap requests are sent and `conversionRates` and `historicalPrices` are reset to `{}` at construction and at every entry point (`updateAssetsRates`, `fetchHistoricalPricesForAsset`, `_executePoll`, `CurrencyRateController:stateChange`, and `MultichainAssetsController:accountAssetListUpdated`), so no stale rates remain in state.
|
|
14
|
+
- The function is re-evaluated on each entry point so it can be toggled at runtime without reconstructing the controller.
|
|
15
|
+
- Add `isDeprecated` option to `MultichainBalancesController` constructor ([#9044](https://github.com/MetaMask/core/pull/9044))
|
|
16
|
+
- When `isDeprecated()` returns `true`, no Snap requests are sent and `balances` is reset to `{}` at construction and at every entry point (`updateBalance`, `MultichainAssetsController:accountAssetListUpdated`, `AccountsController:accountBalancesUpdated`, and `AccountsController:accountRemoved`), so no stale balances remain in state.
|
|
17
|
+
- The function is re-evaluated on each entry point so it can be toggled at runtime without reconstructing the controller.
|
|
18
|
+
|
|
10
19
|
### Changed
|
|
11
20
|
|
|
12
21
|
- Bump `@metamask/profile-sync-controller` from `^28.1.1` to `^28.2.0` ([#9119](https://github.com/MetaMask/core/pull/9119))
|
|
13
22
|
- Bump `@metamask/keyring-controller` from `^27.0.0` to `^27.1.0` ([#9129](https://github.com/MetaMask/core/pull/9129))
|
|
23
|
+
- Bump `@metamask/transaction-controller` from `^68.0.0` to `^68.0.1` ([#9177](https://github.com/MetaMask/core/pull/9177))
|
|
14
24
|
|
|
15
25
|
## [109.1.0]
|
|
16
26
|
|
|
@@ -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 _MultichainAssetsRatesController_instances, _MultichainAssetsRatesController_mutex, _MultichainAssetsRatesController_currentCurrency, _MultichainAssetsRatesController_isUnlocked, _MultichainAssetsRatesController_isNonEvmAccount, _MultichainAssetsRatesController_listMultichainAccounts, _MultichainAssetsRatesController_listAccounts, _MultichainAssetsRatesController_addAssetsToSnapIdMap, _MultichainAssetsRatesController_getCaipCurrentCurrency, _MultichainAssetsRatesController_getConversionRates, _MultichainAssetsRatesController_getMarketData, _MultichainAssetsRatesController_getUpdatedRatesFor, _MultichainAssetsRatesController_updateAssetsRatesForNewAssets, _MultichainAssetsRatesController_getAccount, _MultichainAssetsRatesController_getAssetsForAccount, _MultichainAssetsRatesController_applyUpdatedRates, _MultichainAssetsRatesController_isAssetTracked, _MultichainAssetsRatesController_handleSnapRequest;
|
|
13
|
+
var _MultichainAssetsRatesController_instances, _MultichainAssetsRatesController_mutex, _MultichainAssetsRatesController_currentCurrency, _MultichainAssetsRatesController_isUnlocked, _MultichainAssetsRatesController_isDeprecated, _MultichainAssetsRatesController_enforceDisabledState, _MultichainAssetsRatesController_isNonEvmAccount, _MultichainAssetsRatesController_listMultichainAccounts, _MultichainAssetsRatesController_listAccounts, _MultichainAssetsRatesController_addAssetsToSnapIdMap, _MultichainAssetsRatesController_getCaipCurrentCurrency, _MultichainAssetsRatesController_getConversionRates, _MultichainAssetsRatesController_getMarketData, _MultichainAssetsRatesController_getUpdatedRatesFor, _MultichainAssetsRatesController_updateAssetsRatesForNewAssets, _MultichainAssetsRatesController_getAccount, _MultichainAssetsRatesController_getAssetsForAccount, _MultichainAssetsRatesController_applyUpdatedRates, _MultichainAssetsRatesController_isAssetTracked, _MultichainAssetsRatesController_handleSnapRequest;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.MultichainAssetsRatesController = exports.getDefaultMultichainAssetsRatesControllerState = void 0;
|
|
16
16
|
const keyring_api_1 = require("@metamask/keyring-api");
|
|
@@ -65,8 +65,15 @@ class MultichainAssetsRatesController extends (0, polling_controller_1.StaticInt
|
|
|
65
65
|
* @param options.interval - The polling interval in milliseconds.
|
|
66
66
|
* @param options.state - The initial state.
|
|
67
67
|
* @param options.messenger - A reference to the messenger.
|
|
68
|
+
* @param options.isDeprecated - Optional function that returns true to completely
|
|
69
|
+
* disable this controller (no requests, no state updates). When it returns
|
|
70
|
+
* `true`, `conversionRates` and `historicalPrices` are reset to `{}` at
|
|
71
|
+
* construction and at every polling entry point, so no stale rates remain in
|
|
72
|
+
* state. The function is evaluated dynamically on each entry point so it can
|
|
73
|
+
* be toggled at runtime. Intended for use when a higher-level controller
|
|
74
|
+
* (e.g. AssetsController) supersedes this one.
|
|
68
75
|
*/
|
|
69
|
-
constructor({ interval = 18000, state = {}, messenger, }) {
|
|
76
|
+
constructor({ interval = 18000, state = {}, messenger, isDeprecated = () => false, }) {
|
|
70
77
|
var _a;
|
|
71
78
|
super({
|
|
72
79
|
name: controllerName,
|
|
@@ -81,7 +88,12 @@ class MultichainAssetsRatesController extends (0, polling_controller_1.StaticInt
|
|
|
81
88
|
_MultichainAssetsRatesController_mutex.set(this, new async_mutex_1.Mutex());
|
|
82
89
|
_MultichainAssetsRatesController_currentCurrency.set(this, void 0);
|
|
83
90
|
_MultichainAssetsRatesController_isUnlocked.set(this, true);
|
|
91
|
+
_MultichainAssetsRatesController_isDeprecated.set(this, void 0);
|
|
84
92
|
this.setIntervalLength(interval);
|
|
93
|
+
__classPrivateFieldSet(this, _MultichainAssetsRatesController_isDeprecated, isDeprecated, "f");
|
|
94
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
95
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
96
|
+
}
|
|
85
97
|
messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
86
98
|
// Subscribe to keyring lock/unlock events.
|
|
87
99
|
this.messenger.subscribe('KeyringController:lock', () => {
|
|
@@ -94,12 +106,20 @@ class MultichainAssetsRatesController extends (0, polling_controller_1.StaticInt
|
|
|
94
106
|
this.messenger.subscribe('CurrencyRateController:stateChange',
|
|
95
107
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
96
108
|
async (currentCurrency) => {
|
|
109
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
110
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
97
113
|
__classPrivateFieldSet(this, _MultichainAssetsRatesController_currentCurrency, currentCurrency, "f");
|
|
98
114
|
await this.updateAssetsRates();
|
|
99
115
|
}, (currencyRateControllerState) => currencyRateControllerState.currentCurrency);
|
|
100
116
|
this.messenger.subscribe('MultichainAssetsController:accountAssetListUpdated',
|
|
101
117
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
102
118
|
async ({ assets }) => {
|
|
119
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
120
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
103
123
|
// Treat the event payload as a per-account delta so we can fetch only
|
|
104
124
|
// newly added assets and independently clean up removed ones.
|
|
105
125
|
const updatedAccountAssets = Object.entries(assets).map(([accountId, { added, removed }]) => ({
|
|
@@ -116,6 +136,10 @@ class MultichainAssetsRatesController extends (0, polling_controller_1.StaticInt
|
|
|
116
136
|
* @returns A promise that resolves when the polling completes.
|
|
117
137
|
*/
|
|
118
138
|
async _executePoll() {
|
|
139
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
140
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
119
143
|
await this.updateAssetsRates();
|
|
120
144
|
}
|
|
121
145
|
/**
|
|
@@ -132,6 +156,10 @@ class MultichainAssetsRatesController extends (0, polling_controller_1.StaticInt
|
|
|
132
156
|
* @returns A promise that resolves when the rates are updated.
|
|
133
157
|
*/
|
|
134
158
|
async updateAssetsRates() {
|
|
159
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
160
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
161
|
+
return Promise.resolve();
|
|
162
|
+
}
|
|
135
163
|
const releaseLock = await __classPrivateFieldGet(this, _MultichainAssetsRatesController_mutex, "f").acquire();
|
|
136
164
|
return (async () => {
|
|
137
165
|
if (!this.isActive) {
|
|
@@ -157,6 +185,10 @@ class MultichainAssetsRatesController extends (0, polling_controller_1.StaticInt
|
|
|
157
185
|
* @returns The historical prices.
|
|
158
186
|
*/
|
|
159
187
|
async fetchHistoricalPricesForAsset(asset, account) {
|
|
188
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
189
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
190
|
+
return Promise.resolve();
|
|
191
|
+
}
|
|
160
192
|
const releaseLock = await __classPrivateFieldGet(this, _MultichainAssetsRatesController_mutex, "f").acquire();
|
|
161
193
|
return (async () => {
|
|
162
194
|
const currentCaipCurrency = constant_1.MAP_CAIP_CURRENCIES[__classPrivateFieldGet(this, _MultichainAssetsRatesController_currentCurrency, "f")] ?? constant_1.MAP_CAIP_CURRENCIES.usd;
|
|
@@ -207,7 +239,16 @@ class MultichainAssetsRatesController extends (0, polling_controller_1.StaticInt
|
|
|
207
239
|
}
|
|
208
240
|
}
|
|
209
241
|
exports.MultichainAssetsRatesController = MultichainAssetsRatesController;
|
|
210
|
-
_MultichainAssetsRatesController_mutex = new WeakMap(), _MultichainAssetsRatesController_currentCurrency = new WeakMap(), _MultichainAssetsRatesController_isUnlocked = new WeakMap(), _MultichainAssetsRatesController_instances = new WeakSet(),
|
|
242
|
+
_MultichainAssetsRatesController_mutex = new WeakMap(), _MultichainAssetsRatesController_currentCurrency = new WeakMap(), _MultichainAssetsRatesController_isUnlocked = new WeakMap(), _MultichainAssetsRatesController_isDeprecated = new WeakMap(), _MultichainAssetsRatesController_instances = new WeakSet(), _MultichainAssetsRatesController_enforceDisabledState = function _MultichainAssetsRatesController_enforceDisabledState() {
|
|
243
|
+
if (Object.keys(this.state.conversionRates).length === 0 &&
|
|
244
|
+
Object.keys(this.state.historicalPrices).length === 0) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
this.update((state) => {
|
|
248
|
+
state.conversionRates = {};
|
|
249
|
+
state.historicalPrices = {};
|
|
250
|
+
});
|
|
251
|
+
}, _MultichainAssetsRatesController_isNonEvmAccount = function _MultichainAssetsRatesController_isNonEvmAccount(account) {
|
|
211
252
|
return (!(0, keyring_api_1.isEvmAccountType)(account.type) && account.metadata.snap !== undefined);
|
|
212
253
|
}, _MultichainAssetsRatesController_listMultichainAccounts = function _MultichainAssetsRatesController_listMultichainAccounts() {
|
|
213
254
|
return this.messenger.call('AccountsController:listMultichainAccounts');
|
|
@@ -357,6 +398,10 @@ async function _MultichainAssetsRatesController_getUpdatedRatesFor(snapIdToAsset
|
|
|
357
398
|
* @returns A promise that resolves when the rates are updated.
|
|
358
399
|
*/
|
|
359
400
|
async function _MultichainAssetsRatesController_updateAssetsRatesForNewAssets(accounts) {
|
|
401
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
402
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
403
|
+
return Promise.resolve();
|
|
404
|
+
}
|
|
360
405
|
const releaseLock = await __classPrivateFieldGet(this, _MultichainAssetsRatesController_mutex, "f").acquire();
|
|
361
406
|
return (async () => {
|
|
362
407
|
if (!this.isActive) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAssetsRatesController.cjs","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerListMultichainAccountsAction,\n AccountsControllerAccountAddedEvent,\n AccountsControllerGetSelectedMultichainAccountAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { CaipAssetType } from '@metamask/keyring-api';\nimport type {\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { SnapControllerHandleRequestAction } from '@metamask/snaps-controllers';\nimport type {\n SnapId,\n AssetConversion,\n OnAssetsConversionArguments,\n OnAssetHistoricalPriceArguments,\n OnAssetHistoricalPriceResponse,\n HistoricalPriceIntervals,\n OnAssetsMarketDataArguments,\n OnAssetsMarketDataResponse,\n FungibleAssetMarketData,\n OnAssetsConversionResponse,\n} from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport type {\n CurrencyRateState,\n CurrencyRateStateChange,\n CurrencyRateControllerGetStateAction,\n} from '../CurrencyRateController';\nimport type {\n MultichainAssetsControllerGetStateAction,\n MultichainAssetsControllerAccountAssetListUpdatedEvent,\n} from '../MultichainAssetsController';\nimport { MAP_CAIP_CURRENCIES } from './constant';\nimport type { MultichainAssetsRatesControllerMethodActions } from './MultichainAssetsRatesController-method-action-types';\n\n/**\n * The name of the MultichainAssetsRatesController.\n */\nconst controllerName = 'MultichainAssetsRatesController';\n\n// This is temporary until its exported from snap\ntype HistoricalPrice = {\n intervals: HistoricalPriceIntervals;\n // The UNIX timestamp of when the historical price was last updated.\n updateTime: number;\n // The UNIX timestamp of when the historical price will expire.\n expirationTime?: number;\n};\n\n/**\n * State used by the MultichainAssetsRatesController to cache token conversion rates.\n */\nexport type MultichainAssetsRatesControllerState = {\n conversionRates: Record<CaipAssetType, UnifiedAssetConversion>;\n historicalPrices: Record<CaipAssetType, Record<string, HistoricalPrice>>; // string being the current currency we fetched historical prices for\n};\n\n/**\n * Returns the state of the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\ntype UnifiedAssetConversion = AssetConversion & {\n marketData?: FungibleAssetMarketData;\n};\n\n/**\n * Constructs the default {@link MultichainAssetsRatesController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link MultichainAssetsRatesController} state.\n */\nexport function getDefaultMultichainAssetsRatesControllerState(): MultichainAssetsRatesControllerState {\n return { conversionRates: {}, historicalPrices: {} };\n}\n\n/**\n * Event emitted when the state of the MultichainAssetsRatesController changes.\n */\nexport type MultichainAssetsRatesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\n/**\n * Actions exposed by the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerActions =\n | MultichainAssetsRatesControllerGetStateAction\n | MultichainAssetsRatesControllerMethodActions;\n\n/**\n * Events emitted by MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerEvents =\n MultichainAssetsRatesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | SnapControllerHandleRequestAction\n | AccountsControllerListMultichainAccountsAction\n | CurrencyRateControllerGetStateAction\n | MultichainAssetsControllerGetStateAction\n | AccountsControllerGetSelectedMultichainAccountAction;\n\n/**\n * Events that this controller is allowed to subscribe to.\n */\nexport type AllowedEvents =\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | AccountsControllerAccountAddedEvent\n | CurrencyRateStateChange\n | MultichainAssetsControllerAccountAssetListUpdatedEvent;\n/**\n * Messenger type for the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerMessenger = Messenger<\n typeof controllerName,\n MultichainAssetsRatesControllerActions | AllowedActions,\n MultichainAssetsRatesControllerEvents | AllowedEvents\n>;\n\n/**\n * The input for starting polling in MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesPollingInput = {\n accountId: string;\n};\n\nconst metadata: StateMetadata<MultichainAssetsRatesControllerState> = {\n conversionRates: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n historicalPrices: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n};\n\nexport type ConversionRatesWithMarketData = {\n conversionRates: Record<\n CaipAssetType,\n Record<CaipAssetType, UnifiedAssetConversion | null>\n >;\n};\n\n/**\n * Arguments for a Snap request.\n */\ntype SnapRequestArgs<T> = {\n snapId: SnapId;\n handler: HandlerType;\n params: T;\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'updateAssetsRates',\n 'fetchHistoricalPricesForAsset',\n] as const;\n\n/**\n * Controller that manages multichain token conversion rates.\n *\n * This controller polls for token conversion rates and updates its state.\n */\nexport class MultichainAssetsRatesController extends StaticIntervalPollingController<MultichainAssetsRatesPollingInput>()<\n typeof controllerName,\n MultichainAssetsRatesControllerState,\n MultichainAssetsRatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n #currentCurrency: CurrencyRateState['currentCurrency'];\n\n #isUnlocked = true;\n\n /**\n * Creates an instance of MultichainAssetsRatesController.\n *\n * @param options - Constructor options.\n * @param options.interval - The polling interval in milliseconds.\n * @param options.state - The initial state.\n * @param options.messenger - A reference to the messenger.\n */\n constructor({\n interval = 18000,\n state = {},\n messenger,\n }: {\n interval?: number;\n state?: Partial<MultichainAssetsRatesControllerState>;\n messenger: MultichainAssetsRatesControllerMessenger;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {\n ...getDefaultMultichainAssetsRatesControllerState(),\n ...state,\n },\n metadata,\n });\n\n this.setIntervalLength(interval);\n\n messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);\n\n // Subscribe to keyring lock/unlock events.\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n ({ currentCurrency: this.#currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n ));\n\n this.messenger.subscribe(\n 'CurrencyRateController:stateChange',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (currentCurrency: string) => {\n this.#currentCurrency = currentCurrency;\n await this.updateAssetsRates();\n },\n (currencyRateControllerState) =>\n currencyRateControllerState.currentCurrency,\n );\n\n this.messenger.subscribe(\n 'MultichainAssetsController:accountAssetListUpdated',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async ({ assets }) => {\n // Treat the event payload as a per-account delta so we can fetch only\n // newly added assets and independently clean up removed ones.\n const updatedAccountAssets = Object.entries(assets).map(\n ([accountId, { added, removed }]) => ({\n accountId,\n added: [...added],\n removed: [...removed],\n }),\n );\n await this.#updateAssetsRatesForNewAssets(updatedAccountAssets);\n },\n );\n }\n\n /**\n * Executes a poll by updating token conversion rates for the current account.\n *\n * @returns A promise that resolves when the polling completes.\n */\n async _executePoll(): Promise<void> {\n await this.updateAssetsRates();\n }\n\n /**\n * Determines whether the controller is active.\n *\n * @returns True if the keyring is unlocked; otherwise, false.\n */\n get isActive(): boolean {\n return this.#isUnlocked;\n }\n\n /**\n * Checks if an account is a non-EVM account with a Snap.\n *\n * @param account - The account to check.\n * @returns True if the account is non-EVM and has Snap metadata; otherwise, false.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) && account.metadata.snap !== undefined\n );\n }\n\n /**\n * Retrieves all multichain accounts from the AccountsController.\n *\n * @returns An array of internal accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messenger.call('AccountsController:listMultichainAccounts');\n }\n\n /**\n * Filters and returns non-EVM accounts that should have balances.\n *\n * @returns An array of non-EVM internal accounts.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Adds the assets to a map of Snap ID to assets.\n *\n * @param snapIdToAssets - The map of Snap ID to assets.\n * @param account - The account to add the assets for.\n * @param assets - The assets to add.\n */\n #addAssetsToSnapIdMap(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n account: InternalAccount,\n assets: CaipAssetType[],\n ): void {\n // Prevent creating a new set if there are no assets to add.\n if (assets.length === 0) {\n return;\n }\n\n // FIXME: Instead of using the Snap ID from the account, we should\n // select the Snap based on the supported scopes defined in the Snaps'\n // manifest.\n const snapId = account.metadata.snap?.id as SnapId | undefined;\n if (!snapId) {\n return;\n }\n\n let snapAssets = snapIdToAssets.get(snapId);\n if (!snapAssets) {\n snapAssets = new Set();\n snapIdToAssets.set(snapId, snapAssets);\n }\n\n for (const asset of assets) {\n snapAssets.add(asset);\n }\n }\n\n /**\n * Updates token conversion rates for each non-EVM account.\n *\n * @returns A promise that resolves when the rates are updated.\n */\n async updateAssetsRates(): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n return (async (): Promise<void> => {\n if (!this.isActive) {\n return;\n }\n\n // Compute the set of unique assets from all accounts. It's important to\n // deduplicate assets here to avoid duplicate requests to the Snap.\n const accounts = this.#listAccounts();\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n for (const account of accounts) {\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n account,\n this.#getAssetsForAccount(account.id),\n );\n }\n\n this.#applyUpdatedRates(await this.#getUpdatedRatesFor(snapIdToAssets));\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Returns the CAIP-19 asset type for the current selected currency. Defaults\n * to USD if the current selected currency is not supported.\n *\n * @returns The CAIP-19 asset type for the current selected currency.\n */\n #getCaipCurrentCurrency(): CaipAssetType {\n return (\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd\n );\n }\n\n /**\n * Fetches the conversion rates for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the conversion rates for.\n * @param currency - The currency to fetch the conversion rates for.\n * @returns A record of CAIP-19 asset types to conversion rates.\n */\n async #getConversionRates(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, AssetConversion | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsConversion,\n params: {\n conversions: Array.from(assets).map((asset) => ({\n from: asset,\n to: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToConversionRate: Record<\n CaipAssetType,\n AssetConversion | undefined\n > = {};\n\n for (const asset of assets) {\n assetToConversionRate[asset] =\n response.conversionRates?.[asset]?.[currency] ?? undefined;\n }\n\n return assetToConversionRate;\n }\n\n /**\n * Fetches the market data for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the market data for.\n * @param currency - The currency to fetch the market data for.\n * @returns A record of CAIP-19 asset types to market data.\n */\n async #getMarketData(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, FungibleAssetMarketData | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsMarketData,\n params: {\n assets: Array.from(assets).map((asset) => ({\n asset,\n unit: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToMarketData: Record<\n CaipAssetType,\n FungibleAssetMarketData | undefined\n > = {};\n\n for (const asset of assets) {\n const assetMarketData = response.marketData?.[asset]?.[currency];\n\n // We do not consider NFTs here, so `fungible` must be `true`.\n if (assetMarketData?.fungible) {\n assetToMarketData[asset] = assetMarketData;\n } else {\n assetToMarketData[asset] = undefined;\n }\n }\n\n return assetToMarketData;\n }\n\n /**\n * Fetches the updated rates for the given assets from the given Snaps.\n *\n * @param snapIdToAssets - A map of Snap ID to CAIP-19 asset types.\n * @returns A record of CAIP-19 asset types to unified asset conversions.\n */\n async #getUpdatedRatesFor(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n ): Promise<\n Record<CaipAssetType, UnifiedAssetConversion & { currency: CaipAssetType }>\n > {\n const updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n > = {};\n\n // Keep a local copy to ensure that the currency is always the same for the\n // entire loop.\n const currency = this.#getCaipCurrentCurrency();\n\n // Note: Since the assets come from a 1-to-1 mapping with Snap IDs, we know\n // that a given asset will not appear under multiple Snap IDs.\n for (const [snapId, assets] of snapIdToAssets.entries()) {\n const [rates, marketData] = await Promise.all([\n this.#getConversionRates(snapId, assets, currency),\n this.#getMarketData(snapId, assets, currency),\n ]);\n\n for (const asset of assets) {\n const assetRate = rates[asset];\n const assetMarketData = marketData[asset];\n\n // Rates are mandatory, so skip the asset if not available.\n if (!assetRate) {\n continue;\n }\n\n updatedRates[asset] = {\n currency,\n ...assetRate,\n ...(assetMarketData && { marketData: assetMarketData }),\n };\n }\n }\n\n return updatedRates;\n }\n\n /**\n * Fetches historical prices for the current account\n *\n * @param asset - The asset to fetch historical prices for.\n * @param account - optional account to fetch historical prices for\n * @returns The historical prices.\n */\n async fetchHistoricalPricesForAsset(\n asset: CaipAssetType,\n account?: InternalAccount,\n ): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n return (async () => {\n const currentCaipCurrency =\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd;\n // Check if we already have historical prices for this asset and currency\n const historicalPriceExpirationTime =\n this.state.historicalPrices[asset]?.[this.#currentCurrency]\n ?.expirationTime;\n\n const historicalPriceHasExpired =\n historicalPriceExpirationTime &&\n historicalPriceExpirationTime < Date.now();\n\n if (historicalPriceHasExpired === false) {\n return;\n }\n\n const selectedAccount =\n account ??\n this.messenger.call('AccountsController:getSelectedMultichainAccount');\n try {\n const historicalPricesResponse = await this.messenger.call(\n 'SnapController:handleRequest',\n {\n snapId: selectedAccount?.metadata.snap?.id as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnAssetHistoricalPrice,\n request: {\n jsonrpc: '2.0',\n method: HandlerType.OnAssetHistoricalPrice,\n params: {\n from: asset,\n to: currentCaipCurrency,\n },\n },\n },\n );\n\n // skip state update if no historical prices are returned\n if (!historicalPricesResponse) {\n return;\n }\n\n this.update((state) => {\n state.historicalPrices = {\n ...state.historicalPrices,\n [asset]: {\n ...state.historicalPrices[asset],\n [this.#currentCurrency]: (\n historicalPricesResponse as OnAssetHistoricalPriceResponse\n )?.historicalPrice,\n },\n };\n });\n } catch {\n throw new Error(\n `Failed to fetch historical prices for asset: ${asset}`,\n );\n }\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Reconciles cached rates after an account asset-list update event.\n *\n * The event payload is treated as a delta:\n * - `added` assets are batched by Snap and fetched for fresh rates\n * - `removed` assets are deleted from cached state only if they are no longer tracked by any account\n *\n * This global check is required because rate state is keyed by asset rather\n * than by account, so the same asset may still be shared by another account.\n *\n * @param accounts - The per-account asset deltas from the asset-list update event.\n * @returns A promise that resolves when the rates are updated.\n */\n async #updateAssetsRatesForNewAssets(\n accounts: {\n accountId: string;\n added: CaipAssetType[];\n removed: CaipAssetType[];\n }[],\n ): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n return (async () => {\n if (!this.isActive) {\n return;\n }\n\n // First build a map containing all assets that need to be updated per\n // Snap ID, this will be used to batch the requests.\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n const removedAssets = new Set<CaipAssetType>();\n\n for (const { accountId, added, removed } of accounts) {\n if (added.length !== 0) {\n // Only newly added assets need fresh rate requests.\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n this.#getAccount(accountId),\n added,\n );\n }\n\n // Collect removed assets separately so we can decide later whether they\n // are truly stale or still referenced by another account.\n for (const asset of removed) {\n removedAssets.add(asset);\n }\n }\n\n const updatedRates = await this.#getUpdatedRatesFor(snapIdToAssets);\n // Rates are stored globally by asset, so delete only assets that no\n // longer exist in any account asset list.\n const assetsToDelete = Array.from(removedAssets).filter(\n (asset) => !this.#isAssetTracked(asset),\n );\n\n this.#applyUpdatedRates(updatedRates, assetsToDelete);\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined = this.#listAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n\n return account;\n }\n\n /**\n * Returns the array of CAIP-19 assets for the given account ID.\n * If none are found, returns an empty array.\n *\n * @param accountId - The account ID to get the assets for.\n * @returns An array of CAIP-19 assets.\n */\n #getAssetsForAccount(accountId: string): CaipAssetType[] {\n // Always fetch fresh state - MultichainAssetsController uses Immer which creates\n // new object references on every update, so caching would become stale.\n const { accountsAssets } = this.messenger.call(\n 'MultichainAssetsController:getState',\n );\n return accountsAssets?.[accountId] ?? [];\n }\n\n /**\n * Applies fresh rates and removes stale asset-rate state in one update.\n *\n * @param updatedRates - The latest conversion rates fetched for added assets.\n * @param removedAssets - Assets that should be purged because they are no longer tracked by any account.\n */\n #applyUpdatedRates(\n updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n >,\n removedAssets: CaipAssetType[] = [],\n ): void {\n if (Object.keys(updatedRates).length === 0 && removedAssets.length === 0) {\n return;\n }\n this.update((state: Draft<MultichainAssetsRatesControllerState>) => {\n // Drop both current rates and historical prices for assets that are no\n // longer referenced anywhere in MultichainAssetsController state.\n for (const asset of removedAssets) {\n delete state.conversionRates[asset];\n delete state.historicalPrices[asset];\n }\n\n // Merge the freshly fetched rates after cleanup.\n state.conversionRates = {\n ...state.conversionRates,\n ...updatedRates,\n };\n });\n }\n\n /**\n * Checks whether an asset is still tracked by any account in\n * MultichainAssetsController state.\n *\n * @param asset - The asset to check.\n * @returns True if the asset still exists in any account asset list.\n */\n #isAssetTracked(asset: CaipAssetType): boolean {\n const { accountsAssets } = this.messenger.call(\n 'MultichainAssetsController:getState',\n );\n\n // Rate state is global per asset, so inspect all account asset lists before\n // deciding whether a removed asset should be purged from cache.\n return Object.values(accountsAssets ?? {}).some((accountAssets) =>\n accountAssets.includes(asset),\n );\n }\n\n /**\n * Forwards a Snap request to the SnapController.\n *\n * @param args - The request parameters.\n * @param args.snapId - The ID of the Snap.\n * @param args.handler - The handler type.\n * @param args.params - The asset conversions.\n * @returns A promise that resolves with the account rates.\n */\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsConversionArguments>,\n ): Promise<OnAssetsConversionResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetHistoricalPriceArguments>,\n ): Promise<OnAssetHistoricalPriceResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsMarketDataArguments>,\n ): Promise<OnAssetsMarketDataResponse | undefined>;\n\n async #handleSnapRequest(args: SnapRequestArgs<unknown>): Promise<unknown> {\n const { snapId, handler, params } = args;\n try {\n return await this.messenger.call('SnapController:handleRequest', {\n snapId,\n origin: 'metamask',\n handler,\n request: {\n jsonrpc: '2.0',\n method: handler,\n params,\n },\n });\n } catch (error) {\n console.error(`Snap request failed for ${handler}:`, {\n snapId,\n handler,\n message: (error as Error).message,\n params,\n });\n return undefined;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainAssetsRatesController.cjs","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerListMultichainAccountsAction,\n AccountsControllerAccountAddedEvent,\n AccountsControllerGetSelectedMultichainAccountAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { CaipAssetType } from '@metamask/keyring-api';\nimport type {\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { SnapControllerHandleRequestAction } from '@metamask/snaps-controllers';\nimport type {\n SnapId,\n AssetConversion,\n OnAssetsConversionArguments,\n OnAssetHistoricalPriceArguments,\n OnAssetHistoricalPriceResponse,\n HistoricalPriceIntervals,\n OnAssetsMarketDataArguments,\n OnAssetsMarketDataResponse,\n FungibleAssetMarketData,\n OnAssetsConversionResponse,\n} from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport type {\n CurrencyRateState,\n CurrencyRateStateChange,\n CurrencyRateControllerGetStateAction,\n} from '../CurrencyRateController';\nimport type {\n MultichainAssetsControllerGetStateAction,\n MultichainAssetsControllerAccountAssetListUpdatedEvent,\n} from '../MultichainAssetsController';\nimport { MAP_CAIP_CURRENCIES } from './constant';\nimport type { MultichainAssetsRatesControllerMethodActions } from './MultichainAssetsRatesController-method-action-types';\n\n/**\n * The name of the MultichainAssetsRatesController.\n */\nconst controllerName = 'MultichainAssetsRatesController';\n\n// This is temporary until its exported from snap\ntype HistoricalPrice = {\n intervals: HistoricalPriceIntervals;\n // The UNIX timestamp of when the historical price was last updated.\n updateTime: number;\n // The UNIX timestamp of when the historical price will expire.\n expirationTime?: number;\n};\n\n/**\n * State used by the MultichainAssetsRatesController to cache token conversion rates.\n */\nexport type MultichainAssetsRatesControllerState = {\n conversionRates: Record<CaipAssetType, UnifiedAssetConversion>;\n historicalPrices: Record<CaipAssetType, Record<string, HistoricalPrice>>; // string being the current currency we fetched historical prices for\n};\n\n/**\n * Returns the state of the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\ntype UnifiedAssetConversion = AssetConversion & {\n marketData?: FungibleAssetMarketData;\n};\n\n/**\n * Constructs the default {@link MultichainAssetsRatesController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link MultichainAssetsRatesController} state.\n */\nexport function getDefaultMultichainAssetsRatesControllerState(): MultichainAssetsRatesControllerState {\n return { conversionRates: {}, historicalPrices: {} };\n}\n\n/**\n * Event emitted when the state of the MultichainAssetsRatesController changes.\n */\nexport type MultichainAssetsRatesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainAssetsRatesControllerState\n >;\n\n/**\n * Actions exposed by the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerActions =\n | MultichainAssetsRatesControllerGetStateAction\n | MultichainAssetsRatesControllerMethodActions;\n\n/**\n * Events emitted by MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerEvents =\n MultichainAssetsRatesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | SnapControllerHandleRequestAction\n | AccountsControllerListMultichainAccountsAction\n | CurrencyRateControllerGetStateAction\n | MultichainAssetsControllerGetStateAction\n | AccountsControllerGetSelectedMultichainAccountAction;\n\n/**\n * Events that this controller is allowed to subscribe to.\n */\nexport type AllowedEvents =\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | AccountsControllerAccountAddedEvent\n | CurrencyRateStateChange\n | MultichainAssetsControllerAccountAssetListUpdatedEvent;\n/**\n * Messenger type for the MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesControllerMessenger = Messenger<\n typeof controllerName,\n MultichainAssetsRatesControllerActions | AllowedActions,\n MultichainAssetsRatesControllerEvents | AllowedEvents\n>;\n\n/**\n * The input for starting polling in MultichainAssetsRatesController.\n */\nexport type MultichainAssetsRatesPollingInput = {\n accountId: string;\n};\n\nconst metadata: StateMetadata<MultichainAssetsRatesControllerState> = {\n conversionRates: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n historicalPrices: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n};\n\nexport type ConversionRatesWithMarketData = {\n conversionRates: Record<\n CaipAssetType,\n Record<CaipAssetType, UnifiedAssetConversion | null>\n >;\n};\n\n/**\n * Arguments for a Snap request.\n */\ntype SnapRequestArgs<T> = {\n snapId: SnapId;\n handler: HandlerType;\n params: T;\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'updateAssetsRates',\n 'fetchHistoricalPricesForAsset',\n] as const;\n\n/**\n * Controller that manages multichain token conversion rates.\n *\n * This controller polls for token conversion rates and updates its state.\n */\nexport class MultichainAssetsRatesController extends StaticIntervalPollingController<MultichainAssetsRatesPollingInput>()<\n typeof controllerName,\n MultichainAssetsRatesControllerState,\n MultichainAssetsRatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n #currentCurrency: CurrencyRateState['currentCurrency'];\n\n #isUnlocked = true;\n\n readonly #isDeprecated: () => boolean;\n\n /**\n * Creates an instance of MultichainAssetsRatesController.\n *\n * @param options - Constructor options.\n * @param options.interval - The polling interval in milliseconds.\n * @param options.state - The initial state.\n * @param options.messenger - A reference to the messenger.\n * @param options.isDeprecated - Optional function that returns true to completely\n * disable this controller (no requests, no state updates). When it returns\n * `true`, `conversionRates` and `historicalPrices` are reset to `{}` at\n * construction and at every polling entry point, so no stale rates remain in\n * state. The function is evaluated dynamically on each entry point so it can\n * be toggled at runtime. Intended for use when a higher-level controller\n * (e.g. AssetsController) supersedes this one.\n */\n constructor({\n interval = 18000,\n state = {},\n messenger,\n isDeprecated = (): boolean => false,\n }: {\n interval?: number;\n state?: Partial<MultichainAssetsRatesControllerState>;\n messenger: MultichainAssetsRatesControllerMessenger;\n isDeprecated?: () => boolean;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {\n ...getDefaultMultichainAssetsRatesControllerState(),\n ...state,\n },\n metadata,\n });\n\n this.setIntervalLength(interval);\n this.#isDeprecated = isDeprecated;\n\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n }\n\n messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);\n\n // Subscribe to keyring lock/unlock events.\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n ({ currentCurrency: this.#currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n ));\n\n this.messenger.subscribe(\n 'CurrencyRateController:stateChange',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (currentCurrency: string) => {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n this.#currentCurrency = currentCurrency;\n await this.updateAssetsRates();\n },\n (currencyRateControllerState) =>\n currencyRateControllerState.currentCurrency,\n );\n\n this.messenger.subscribe(\n 'MultichainAssetsController:accountAssetListUpdated',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async ({ assets }) => {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n // Treat the event payload as a per-account delta so we can fetch only\n // newly added assets and independently clean up removed ones.\n const updatedAccountAssets = Object.entries(assets).map(\n ([accountId, { added, removed }]) => ({\n accountId,\n added: [...added],\n removed: [...removed],\n }),\n );\n await this.#updateAssetsRatesForNewAssets(updatedAccountAssets);\n },\n );\n }\n\n /**\n * Clears all persisted `conversionRates` and `historicalPrices` so that no\n * stale rates remain in state.\n *\n * Called from every entry point when `isDeprecated()` is true so that a\n * runtime toggle propagates to state immediately, even if the controller was\n * originally constructed while it was enabled. The update is skipped when\n * both fields are already empty to avoid emitting redundant state changes.\n */\n #enforceDisabledState(): void {\n if (\n Object.keys(this.state.conversionRates).length === 0 &&\n Object.keys(this.state.historicalPrices).length === 0\n ) {\n return;\n }\n this.update((state) => {\n state.conversionRates = {};\n state.historicalPrices = {};\n });\n }\n\n /**\n * Executes a poll by updating token conversion rates for the current account.\n *\n * @returns A promise that resolves when the polling completes.\n */\n async _executePoll(): Promise<void> {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n await this.updateAssetsRates();\n }\n\n /**\n * Determines whether the controller is active.\n *\n * @returns True if the keyring is unlocked; otherwise, false.\n */\n get isActive(): boolean {\n return this.#isUnlocked;\n }\n\n /**\n * Checks if an account is a non-EVM account with a Snap.\n *\n * @param account - The account to check.\n * @returns True if the account is non-EVM and has Snap metadata; otherwise, false.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) && account.metadata.snap !== undefined\n );\n }\n\n /**\n * Retrieves all multichain accounts from the AccountsController.\n *\n * @returns An array of internal accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messenger.call('AccountsController:listMultichainAccounts');\n }\n\n /**\n * Filters and returns non-EVM accounts that should have balances.\n *\n * @returns An array of non-EVM internal accounts.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Adds the assets to a map of Snap ID to assets.\n *\n * @param snapIdToAssets - The map of Snap ID to assets.\n * @param account - The account to add the assets for.\n * @param assets - The assets to add.\n */\n #addAssetsToSnapIdMap(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n account: InternalAccount,\n assets: CaipAssetType[],\n ): void {\n // Prevent creating a new set if there are no assets to add.\n if (assets.length === 0) {\n return;\n }\n\n // FIXME: Instead of using the Snap ID from the account, we should\n // select the Snap based on the supported scopes defined in the Snaps'\n // manifest.\n const snapId = account.metadata.snap?.id as SnapId | undefined;\n if (!snapId) {\n return;\n }\n\n let snapAssets = snapIdToAssets.get(snapId);\n if (!snapAssets) {\n snapAssets = new Set();\n snapIdToAssets.set(snapId, snapAssets);\n }\n\n for (const asset of assets) {\n snapAssets.add(asset);\n }\n }\n\n /**\n * Updates token conversion rates for each non-EVM account.\n *\n * @returns A promise that resolves when the rates are updated.\n */\n async updateAssetsRates(): Promise<void> {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return Promise.resolve();\n }\n\n const releaseLock = await this.#mutex.acquire();\n\n return (async (): Promise<void> => {\n if (!this.isActive) {\n return;\n }\n\n // Compute the set of unique assets from all accounts. It's important to\n // deduplicate assets here to avoid duplicate requests to the Snap.\n const accounts = this.#listAccounts();\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n for (const account of accounts) {\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n account,\n this.#getAssetsForAccount(account.id),\n );\n }\n\n this.#applyUpdatedRates(await this.#getUpdatedRatesFor(snapIdToAssets));\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Returns the CAIP-19 asset type for the current selected currency. Defaults\n * to USD if the current selected currency is not supported.\n *\n * @returns The CAIP-19 asset type for the current selected currency.\n */\n #getCaipCurrentCurrency(): CaipAssetType {\n return (\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd\n );\n }\n\n /**\n * Fetches the conversion rates for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the conversion rates for.\n * @param currency - The currency to fetch the conversion rates for.\n * @returns A record of CAIP-19 asset types to conversion rates.\n */\n async #getConversionRates(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, AssetConversion | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsConversion,\n params: {\n conversions: Array.from(assets).map((asset) => ({\n from: asset,\n to: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToConversionRate: Record<\n CaipAssetType,\n AssetConversion | undefined\n > = {};\n\n for (const asset of assets) {\n assetToConversionRate[asset] =\n response.conversionRates?.[asset]?.[currency] ?? undefined;\n }\n\n return assetToConversionRate;\n }\n\n /**\n * Fetches the market data for the given assets from the given Snap.\n *\n * @param snapId - The ID of the Snap.\n * @param assets - The assets to fetch the market data for.\n * @param currency - The currency to fetch the market data for.\n * @returns A record of CAIP-19 asset types to market data.\n */\n async #getMarketData(\n snapId: SnapId,\n assets: Set<CaipAssetType>,\n currency: CaipAssetType,\n ): Promise<Record<CaipAssetType, FungibleAssetMarketData | undefined>> {\n // Prevent making a Snap call if there are no assets to fetch.\n if (assets.size === 0) {\n return {};\n }\n\n const response = await this.#handleSnapRequest({\n snapId,\n handler: HandlerType.OnAssetsMarketData,\n params: {\n assets: Array.from(assets).map((asset) => ({\n asset,\n unit: currency,\n })),\n },\n });\n\n if (!response) {\n return {};\n }\n\n const assetToMarketData: Record<\n CaipAssetType,\n FungibleAssetMarketData | undefined\n > = {};\n\n for (const asset of assets) {\n const assetMarketData = response.marketData?.[asset]?.[currency];\n\n // We do not consider NFTs here, so `fungible` must be `true`.\n if (assetMarketData?.fungible) {\n assetToMarketData[asset] = assetMarketData;\n } else {\n assetToMarketData[asset] = undefined;\n }\n }\n\n return assetToMarketData;\n }\n\n /**\n * Fetches the updated rates for the given assets from the given Snaps.\n *\n * @param snapIdToAssets - A map of Snap ID to CAIP-19 asset types.\n * @returns A record of CAIP-19 asset types to unified asset conversions.\n */\n async #getUpdatedRatesFor(\n snapIdToAssets: Map<SnapId, Set<CaipAssetType>>,\n ): Promise<\n Record<CaipAssetType, UnifiedAssetConversion & { currency: CaipAssetType }>\n > {\n const updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n > = {};\n\n // Keep a local copy to ensure that the currency is always the same for the\n // entire loop.\n const currency = this.#getCaipCurrentCurrency();\n\n // Note: Since the assets come from a 1-to-1 mapping with Snap IDs, we know\n // that a given asset will not appear under multiple Snap IDs.\n for (const [snapId, assets] of snapIdToAssets.entries()) {\n const [rates, marketData] = await Promise.all([\n this.#getConversionRates(snapId, assets, currency),\n this.#getMarketData(snapId, assets, currency),\n ]);\n\n for (const asset of assets) {\n const assetRate = rates[asset];\n const assetMarketData = marketData[asset];\n\n // Rates are mandatory, so skip the asset if not available.\n if (!assetRate) {\n continue;\n }\n\n updatedRates[asset] = {\n currency,\n ...assetRate,\n ...(assetMarketData && { marketData: assetMarketData }),\n };\n }\n }\n\n return updatedRates;\n }\n\n /**\n * Fetches historical prices for the current account\n *\n * @param asset - The asset to fetch historical prices for.\n * @param account - optional account to fetch historical prices for\n * @returns The historical prices.\n */\n async fetchHistoricalPricesForAsset(\n asset: CaipAssetType,\n account?: InternalAccount,\n ): Promise<void> {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return Promise.resolve();\n }\n\n const releaseLock = await this.#mutex.acquire();\n return (async () => {\n const currentCaipCurrency =\n MAP_CAIP_CURRENCIES[this.#currentCurrency] ?? MAP_CAIP_CURRENCIES.usd;\n // Check if we already have historical prices for this asset and currency\n const historicalPriceExpirationTime =\n this.state.historicalPrices[asset]?.[this.#currentCurrency]\n ?.expirationTime;\n\n const historicalPriceHasExpired =\n historicalPriceExpirationTime &&\n historicalPriceExpirationTime < Date.now();\n\n if (historicalPriceHasExpired === false) {\n return;\n }\n\n const selectedAccount =\n account ??\n this.messenger.call('AccountsController:getSelectedMultichainAccount');\n try {\n const historicalPricesResponse = await this.messenger.call(\n 'SnapController:handleRequest',\n {\n snapId: selectedAccount?.metadata.snap?.id as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnAssetHistoricalPrice,\n request: {\n jsonrpc: '2.0',\n method: HandlerType.OnAssetHistoricalPrice,\n params: {\n from: asset,\n to: currentCaipCurrency,\n },\n },\n },\n );\n\n // skip state update if no historical prices are returned\n if (!historicalPricesResponse) {\n return;\n }\n\n this.update((state) => {\n state.historicalPrices = {\n ...state.historicalPrices,\n [asset]: {\n ...state.historicalPrices[asset],\n [this.#currentCurrency]: (\n historicalPricesResponse as OnAssetHistoricalPriceResponse\n )?.historicalPrice,\n },\n };\n });\n } catch {\n throw new Error(\n `Failed to fetch historical prices for asset: ${asset}`,\n );\n }\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Reconciles cached rates after an account asset-list update event.\n *\n * The event payload is treated as a delta:\n * - `added` assets are batched by Snap and fetched for fresh rates\n * - `removed` assets are deleted from cached state only if they are no longer tracked by any account\n *\n * This global check is required because rate state is keyed by asset rather\n * than by account, so the same asset may still be shared by another account.\n *\n * @param accounts - The per-account asset deltas from the asset-list update event.\n * @returns A promise that resolves when the rates are updated.\n */\n async #updateAssetsRatesForNewAssets(\n accounts: {\n accountId: string;\n added: CaipAssetType[];\n removed: CaipAssetType[];\n }[],\n ): Promise<void> {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return Promise.resolve();\n }\n\n const releaseLock = await this.#mutex.acquire();\n\n return (async () => {\n if (!this.isActive) {\n return;\n }\n\n // First build a map containing all assets that need to be updated per\n // Snap ID, this will be used to batch the requests.\n const snapIdToAssets = new Map<SnapId, Set<CaipAssetType>>();\n const removedAssets = new Set<CaipAssetType>();\n\n for (const { accountId, added, removed } of accounts) {\n if (added.length !== 0) {\n // Only newly added assets need fresh rate requests.\n this.#addAssetsToSnapIdMap(\n snapIdToAssets,\n this.#getAccount(accountId),\n added,\n );\n }\n\n // Collect removed assets separately so we can decide later whether they\n // are truly stale or still referenced by another account.\n for (const asset of removed) {\n removedAssets.add(asset);\n }\n }\n\n const updatedRates = await this.#getUpdatedRatesFor(snapIdToAssets);\n // Rates are stored globally by asset, so delete only assets that no\n // longer exist in any account asset list.\n const assetsToDelete = Array.from(removedAssets).filter(\n (asset) => !this.#isAssetTracked(asset),\n );\n\n this.#applyUpdatedRates(updatedRates, assetsToDelete);\n })().finally(() => {\n releaseLock();\n });\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined = this.#listAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n\n return account;\n }\n\n /**\n * Returns the array of CAIP-19 assets for the given account ID.\n * If none are found, returns an empty array.\n *\n * @param accountId - The account ID to get the assets for.\n * @returns An array of CAIP-19 assets.\n */\n #getAssetsForAccount(accountId: string): CaipAssetType[] {\n // Always fetch fresh state - MultichainAssetsController uses Immer which creates\n // new object references on every update, so caching would become stale.\n const { accountsAssets } = this.messenger.call(\n 'MultichainAssetsController:getState',\n );\n return accountsAssets?.[accountId] ?? [];\n }\n\n /**\n * Applies fresh rates and removes stale asset-rate state in one update.\n *\n * @param updatedRates - The latest conversion rates fetched for added assets.\n * @param removedAssets - Assets that should be purged because they are no longer tracked by any account.\n */\n #applyUpdatedRates(\n updatedRates: Record<\n CaipAssetType,\n UnifiedAssetConversion & { currency: CaipAssetType }\n >,\n removedAssets: CaipAssetType[] = [],\n ): void {\n if (Object.keys(updatedRates).length === 0 && removedAssets.length === 0) {\n return;\n }\n this.update((state: Draft<MultichainAssetsRatesControllerState>) => {\n // Drop both current rates and historical prices for assets that are no\n // longer referenced anywhere in MultichainAssetsController state.\n for (const asset of removedAssets) {\n delete state.conversionRates[asset];\n delete state.historicalPrices[asset];\n }\n\n // Merge the freshly fetched rates after cleanup.\n state.conversionRates = {\n ...state.conversionRates,\n ...updatedRates,\n };\n });\n }\n\n /**\n * Checks whether an asset is still tracked by any account in\n * MultichainAssetsController state.\n *\n * @param asset - The asset to check.\n * @returns True if the asset still exists in any account asset list.\n */\n #isAssetTracked(asset: CaipAssetType): boolean {\n const { accountsAssets } = this.messenger.call(\n 'MultichainAssetsController:getState',\n );\n\n // Rate state is global per asset, so inspect all account asset lists before\n // deciding whether a removed asset should be purged from cache.\n return Object.values(accountsAssets ?? {}).some((accountAssets) =>\n accountAssets.includes(asset),\n );\n }\n\n /**\n * Forwards a Snap request to the SnapController.\n *\n * @param args - The request parameters.\n * @param args.snapId - The ID of the Snap.\n * @param args.handler - The handler type.\n * @param args.params - The asset conversions.\n * @returns A promise that resolves with the account rates.\n */\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsConversionArguments>,\n ): Promise<OnAssetsConversionResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetHistoricalPriceArguments>,\n ): Promise<OnAssetHistoricalPriceResponse | undefined>;\n\n async #handleSnapRequest(\n args: SnapRequestArgs<OnAssetsMarketDataArguments>,\n ): Promise<OnAssetsMarketDataResponse | undefined>;\n\n async #handleSnapRequest(args: SnapRequestArgs<unknown>): Promise<unknown> {\n const { snapId, handler, params } = args;\n try {\n return await this.messenger.call('SnapController:handleRequest', {\n snapId,\n origin: 'metamask',\n handler,\n request: {\n jsonrpc: '2.0',\n method: handler,\n params,\n },\n });\n } catch (error) {\n console.error(`Snap request failed for ${handler}:`, {\n snapId,\n handler,\n message: (error as Error).message,\n params,\n });\n return undefined;\n }\n }\n}\n"]}
|
|
@@ -103,11 +103,19 @@ export declare class MultichainAssetsRatesController extends MultichainAssetsRat
|
|
|
103
103
|
* @param options.interval - The polling interval in milliseconds.
|
|
104
104
|
* @param options.state - The initial state.
|
|
105
105
|
* @param options.messenger - A reference to the messenger.
|
|
106
|
+
* @param options.isDeprecated - Optional function that returns true to completely
|
|
107
|
+
* disable this controller (no requests, no state updates). When it returns
|
|
108
|
+
* `true`, `conversionRates` and `historicalPrices` are reset to `{}` at
|
|
109
|
+
* construction and at every polling entry point, so no stale rates remain in
|
|
110
|
+
* state. The function is evaluated dynamically on each entry point so it can
|
|
111
|
+
* be toggled at runtime. Intended for use when a higher-level controller
|
|
112
|
+
* (e.g. AssetsController) supersedes this one.
|
|
106
113
|
*/
|
|
107
|
-
constructor({ interval, state, messenger, }: {
|
|
114
|
+
constructor({ interval, state, messenger, isDeprecated, }: {
|
|
108
115
|
interval?: number;
|
|
109
116
|
state?: Partial<MultichainAssetsRatesControllerState>;
|
|
110
117
|
messenger: MultichainAssetsRatesControllerMessenger;
|
|
118
|
+
isDeprecated?: () => boolean;
|
|
111
119
|
});
|
|
112
120
|
/**
|
|
113
121
|
* Executes a poll by updating token conversion rates for the current account.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAssetsRatesController.d.cts","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8CAA8C,EAC9C,mCAAmC,EACnC,oDAAoD,EACrD,sCAAsC;AACvC,OAAO,KAAK,EACV,0BAA0B,EAC1B,wBAAwB,EAEzB,kCAAkC;AAEnC,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA8B;AAC3D,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,qCAAqC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EAAE,iCAAiC,EAAE,oCAAoC;AACrF,OAAO,KAAK,EAEV,eAAe,EAIf,wBAAwB,EAGxB,uBAAuB,EAExB,4BAA4B;AAK7B,OAAO,KAAK,EAEV,uBAAuB,EACvB,oCAAoC,EACrC,sCAAkC;AACnC,OAAO,KAAK,EACV,wCAAwC,EACxC,sDAAsD,EACvD,gDAAsC;AAEvC,OAAO,KAAK,EAAE,4CAA4C,EAAE,kEAA8D;AAE1H;;GAEG;AACH,QAAA,MAAM,cAAc,oCAAoC,CAAC;AAGzD,KAAK,eAAe,GAAG;IACrB,SAAS,EAAE,wBAAwB,CAAC;IAEpC,UAAU,EAAE,MAAM,CAAC;IAEnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oCAAoC,GAAG;IACjD,eAAe,EAAE,MAAM,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAC;IAC/D,gBAAgB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;CAC1E,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6CAA6C,GACvD,wBAAwB,CACtB,OAAO,cAAc,EACrB,oCAAoC,CACrC,CAAC;AAEJ,KAAK,sBAAsB,GAAG,eAAe,GAAG;IAC9C,UAAU,CAAC,EAAE,uBAAuB,CAAC;CACtC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,8CAA8C,IAAI,oCAAoC,CAErG;AAED;;GAEG;AACH,MAAM,MAAM,0CAA0C,GACpD,0BAA0B,CACxB,OAAO,cAAc,EACrB,oCAAoC,CACrC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,sCAAsC,GAC9C,6CAA6C,GAC7C,4CAA4C,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,qCAAqC,GAC/C,0CAA0C,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,iCAAiC,GACjC,8CAA8C,GAC9C,oCAAoC,GACpC,wCAAwC,GACxC,oDAAoD,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,0BAA0B,GAC1B,4BAA4B,GAC5B,mCAAmC,GACnC,uBAAuB,GACvB,sDAAsD,CAAC;AAC3D;;GAEG;AACH,MAAM,MAAM,wCAAwC,GAAG,SAAS,CAC9D,OAAO,cAAc,EACrB,sCAAsC,GAAG,cAAc,EACvD,qCAAqC,GAAG,aAAa,CACtD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAiBF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,eAAe,EAAE,MAAM,CACrB,aAAa,EACb,MAAM,CAAC,aAAa,EAAE,sBAAsB,GAAG,IAAI,CAAC,CACrD,CAAC;CACH,CAAC;;;;;;;;;;;;;;;;AAgBF;;;;GAIG;AACH,qBAAa,+BAAgC,SAAQ,qCACnD,OAAO,cAAc,EACrB,oCAAoC,EACpC,wCAAwC,CACzC;;
|
|
1
|
+
{"version":3,"file":"MultichainAssetsRatesController.d.cts","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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"}
|
|
@@ -103,11 +103,19 @@ export declare class MultichainAssetsRatesController extends MultichainAssetsRat
|
|
|
103
103
|
* @param options.interval - The polling interval in milliseconds.
|
|
104
104
|
* @param options.state - The initial state.
|
|
105
105
|
* @param options.messenger - A reference to the messenger.
|
|
106
|
+
* @param options.isDeprecated - Optional function that returns true to completely
|
|
107
|
+
* disable this controller (no requests, no state updates). When it returns
|
|
108
|
+
* `true`, `conversionRates` and `historicalPrices` are reset to `{}` at
|
|
109
|
+
* construction and at every polling entry point, so no stale rates remain in
|
|
110
|
+
* state. The function is evaluated dynamically on each entry point so it can
|
|
111
|
+
* be toggled at runtime. Intended for use when a higher-level controller
|
|
112
|
+
* (e.g. AssetsController) supersedes this one.
|
|
106
113
|
*/
|
|
107
|
-
constructor({ interval, state, messenger, }: {
|
|
114
|
+
constructor({ interval, state, messenger, isDeprecated, }: {
|
|
108
115
|
interval?: number;
|
|
109
116
|
state?: Partial<MultichainAssetsRatesControllerState>;
|
|
110
117
|
messenger: MultichainAssetsRatesControllerMessenger;
|
|
118
|
+
isDeprecated?: () => boolean;
|
|
111
119
|
});
|
|
112
120
|
/**
|
|
113
121
|
* Executes a poll by updating token conversion rates for the current account.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAssetsRatesController.d.mts","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8CAA8C,EAC9C,mCAAmC,EACnC,oDAAoD,EACrD,sCAAsC;AACvC,OAAO,KAAK,EACV,0BAA0B,EAC1B,wBAAwB,EAEzB,kCAAkC;AAEnC,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA8B;AAC3D,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,qCAAqC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EAAE,iCAAiC,EAAE,oCAAoC;AACrF,OAAO,KAAK,EAEV,eAAe,EAIf,wBAAwB,EAGxB,uBAAuB,EAExB,4BAA4B;AAK7B,OAAO,KAAK,EAEV,uBAAuB,EACvB,oCAAoC,EACrC,sCAAkC;AACnC,OAAO,KAAK,EACV,wCAAwC,EACxC,sDAAsD,EACvD,gDAAsC;AAEvC,OAAO,KAAK,EAAE,4CAA4C,EAAE,kEAA8D;AAE1H;;GAEG;AACH,QAAA,MAAM,cAAc,oCAAoC,CAAC;AAGzD,KAAK,eAAe,GAAG;IACrB,SAAS,EAAE,wBAAwB,CAAC;IAEpC,UAAU,EAAE,MAAM,CAAC;IAEnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oCAAoC,GAAG;IACjD,eAAe,EAAE,MAAM,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAC;IAC/D,gBAAgB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;CAC1E,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6CAA6C,GACvD,wBAAwB,CACtB,OAAO,cAAc,EACrB,oCAAoC,CACrC,CAAC;AAEJ,KAAK,sBAAsB,GAAG,eAAe,GAAG;IAC9C,UAAU,CAAC,EAAE,uBAAuB,CAAC;CACtC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,8CAA8C,IAAI,oCAAoC,CAErG;AAED;;GAEG;AACH,MAAM,MAAM,0CAA0C,GACpD,0BAA0B,CACxB,OAAO,cAAc,EACrB,oCAAoC,CACrC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,sCAAsC,GAC9C,6CAA6C,GAC7C,4CAA4C,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,qCAAqC,GAC/C,0CAA0C,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,iCAAiC,GACjC,8CAA8C,GAC9C,oCAAoC,GACpC,wCAAwC,GACxC,oDAAoD,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,0BAA0B,GAC1B,4BAA4B,GAC5B,mCAAmC,GACnC,uBAAuB,GACvB,sDAAsD,CAAC;AAC3D;;GAEG;AACH,MAAM,MAAM,wCAAwC,GAAG,SAAS,CAC9D,OAAO,cAAc,EACrB,sCAAsC,GAAG,cAAc,EACvD,qCAAqC,GAAG,aAAa,CACtD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAiBF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,eAAe,EAAE,MAAM,CACrB,aAAa,EACb,MAAM,CAAC,aAAa,EAAE,sBAAsB,GAAG,IAAI,CAAC,CACrD,CAAC;CACH,CAAC;;;;;;;;;;;;;;;;AAgBF;;;;GAIG;AACH,qBAAa,+BAAgC,SAAQ,qCACnD,OAAO,cAAc,EACrB,oCAAoC,EACpC,wCAAwC,CACzC;;
|
|
1
|
+
{"version":3,"file":"MultichainAssetsRatesController.d.mts","sourceRoot":"","sources":["../../src/MultichainAssetsRatesController/MultichainAssetsRatesController.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
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");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _MultichainAssetsRatesController_instances, _MultichainAssetsRatesController_mutex, _MultichainAssetsRatesController_currentCurrency, _MultichainAssetsRatesController_isUnlocked, _MultichainAssetsRatesController_isNonEvmAccount, _MultichainAssetsRatesController_listMultichainAccounts, _MultichainAssetsRatesController_listAccounts, _MultichainAssetsRatesController_addAssetsToSnapIdMap, _MultichainAssetsRatesController_getCaipCurrentCurrency, _MultichainAssetsRatesController_getConversionRates, _MultichainAssetsRatesController_getMarketData, _MultichainAssetsRatesController_getUpdatedRatesFor, _MultichainAssetsRatesController_updateAssetsRatesForNewAssets, _MultichainAssetsRatesController_getAccount, _MultichainAssetsRatesController_getAssetsForAccount, _MultichainAssetsRatesController_applyUpdatedRates, _MultichainAssetsRatesController_isAssetTracked, _MultichainAssetsRatesController_handleSnapRequest;
|
|
12
|
+
var _MultichainAssetsRatesController_instances, _MultichainAssetsRatesController_mutex, _MultichainAssetsRatesController_currentCurrency, _MultichainAssetsRatesController_isUnlocked, _MultichainAssetsRatesController_isDeprecated, _MultichainAssetsRatesController_enforceDisabledState, _MultichainAssetsRatesController_isNonEvmAccount, _MultichainAssetsRatesController_listMultichainAccounts, _MultichainAssetsRatesController_listAccounts, _MultichainAssetsRatesController_addAssetsToSnapIdMap, _MultichainAssetsRatesController_getCaipCurrentCurrency, _MultichainAssetsRatesController_getConversionRates, _MultichainAssetsRatesController_getMarketData, _MultichainAssetsRatesController_getUpdatedRatesFor, _MultichainAssetsRatesController_updateAssetsRatesForNewAssets, _MultichainAssetsRatesController_getAccount, _MultichainAssetsRatesController_getAssetsForAccount, _MultichainAssetsRatesController_applyUpdatedRates, _MultichainAssetsRatesController_isAssetTracked, _MultichainAssetsRatesController_handleSnapRequest;
|
|
13
13
|
import { isEvmAccountType } from "@metamask/keyring-api";
|
|
14
14
|
import { StaticIntervalPollingController } from "@metamask/polling-controller";
|
|
15
15
|
import { HandlerType } from "@metamask/snaps-utils";
|
|
@@ -61,8 +61,15 @@ export class MultichainAssetsRatesController extends StaticIntervalPollingContro
|
|
|
61
61
|
* @param options.interval - The polling interval in milliseconds.
|
|
62
62
|
* @param options.state - The initial state.
|
|
63
63
|
* @param options.messenger - A reference to the messenger.
|
|
64
|
+
* @param options.isDeprecated - Optional function that returns true to completely
|
|
65
|
+
* disable this controller (no requests, no state updates). When it returns
|
|
66
|
+
* `true`, `conversionRates` and `historicalPrices` are reset to `{}` at
|
|
67
|
+
* construction and at every polling entry point, so no stale rates remain in
|
|
68
|
+
* state. The function is evaluated dynamically on each entry point so it can
|
|
69
|
+
* be toggled at runtime. Intended for use when a higher-level controller
|
|
70
|
+
* (e.g. AssetsController) supersedes this one.
|
|
64
71
|
*/
|
|
65
|
-
constructor({ interval = 18000, state = {}, messenger, }) {
|
|
72
|
+
constructor({ interval = 18000, state = {}, messenger, isDeprecated = () => false, }) {
|
|
66
73
|
var _a;
|
|
67
74
|
super({
|
|
68
75
|
name: controllerName,
|
|
@@ -77,7 +84,12 @@ export class MultichainAssetsRatesController extends StaticIntervalPollingContro
|
|
|
77
84
|
_MultichainAssetsRatesController_mutex.set(this, new Mutex());
|
|
78
85
|
_MultichainAssetsRatesController_currentCurrency.set(this, void 0);
|
|
79
86
|
_MultichainAssetsRatesController_isUnlocked.set(this, true);
|
|
87
|
+
_MultichainAssetsRatesController_isDeprecated.set(this, void 0);
|
|
80
88
|
this.setIntervalLength(interval);
|
|
89
|
+
__classPrivateFieldSet(this, _MultichainAssetsRatesController_isDeprecated, isDeprecated, "f");
|
|
90
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
91
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
92
|
+
}
|
|
81
93
|
messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
82
94
|
// Subscribe to keyring lock/unlock events.
|
|
83
95
|
this.messenger.subscribe('KeyringController:lock', () => {
|
|
@@ -90,12 +102,20 @@ export class MultichainAssetsRatesController extends StaticIntervalPollingContro
|
|
|
90
102
|
this.messenger.subscribe('CurrencyRateController:stateChange',
|
|
91
103
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
92
104
|
async (currentCurrency) => {
|
|
105
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
106
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
93
109
|
__classPrivateFieldSet(this, _MultichainAssetsRatesController_currentCurrency, currentCurrency, "f");
|
|
94
110
|
await this.updateAssetsRates();
|
|
95
111
|
}, (currencyRateControllerState) => currencyRateControllerState.currentCurrency);
|
|
96
112
|
this.messenger.subscribe('MultichainAssetsController:accountAssetListUpdated',
|
|
97
113
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
98
114
|
async ({ assets }) => {
|
|
115
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
116
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
99
119
|
// Treat the event payload as a per-account delta so we can fetch only
|
|
100
120
|
// newly added assets and independently clean up removed ones.
|
|
101
121
|
const updatedAccountAssets = Object.entries(assets).map(([accountId, { added, removed }]) => ({
|
|
@@ -112,6 +132,10 @@ export class MultichainAssetsRatesController extends StaticIntervalPollingContro
|
|
|
112
132
|
* @returns A promise that resolves when the polling completes.
|
|
113
133
|
*/
|
|
114
134
|
async _executePoll() {
|
|
135
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
136
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
115
139
|
await this.updateAssetsRates();
|
|
116
140
|
}
|
|
117
141
|
/**
|
|
@@ -128,6 +152,10 @@ export class MultichainAssetsRatesController extends StaticIntervalPollingContro
|
|
|
128
152
|
* @returns A promise that resolves when the rates are updated.
|
|
129
153
|
*/
|
|
130
154
|
async updateAssetsRates() {
|
|
155
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
156
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
157
|
+
return Promise.resolve();
|
|
158
|
+
}
|
|
131
159
|
const releaseLock = await __classPrivateFieldGet(this, _MultichainAssetsRatesController_mutex, "f").acquire();
|
|
132
160
|
return (async () => {
|
|
133
161
|
if (!this.isActive) {
|
|
@@ -153,6 +181,10 @@ export class MultichainAssetsRatesController extends StaticIntervalPollingContro
|
|
|
153
181
|
* @returns The historical prices.
|
|
154
182
|
*/
|
|
155
183
|
async fetchHistoricalPricesForAsset(asset, account) {
|
|
184
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
185
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
186
|
+
return Promise.resolve();
|
|
187
|
+
}
|
|
156
188
|
const releaseLock = await __classPrivateFieldGet(this, _MultichainAssetsRatesController_mutex, "f").acquire();
|
|
157
189
|
return (async () => {
|
|
158
190
|
const currentCaipCurrency = MAP_CAIP_CURRENCIES[__classPrivateFieldGet(this, _MultichainAssetsRatesController_currentCurrency, "f")] ?? MAP_CAIP_CURRENCIES.usd;
|
|
@@ -202,7 +234,16 @@ export class MultichainAssetsRatesController extends StaticIntervalPollingContro
|
|
|
202
234
|
});
|
|
203
235
|
}
|
|
204
236
|
}
|
|
205
|
-
_MultichainAssetsRatesController_mutex = new WeakMap(), _MultichainAssetsRatesController_currentCurrency = new WeakMap(), _MultichainAssetsRatesController_isUnlocked = new WeakMap(), _MultichainAssetsRatesController_instances = new WeakSet(),
|
|
237
|
+
_MultichainAssetsRatesController_mutex = new WeakMap(), _MultichainAssetsRatesController_currentCurrency = new WeakMap(), _MultichainAssetsRatesController_isUnlocked = new WeakMap(), _MultichainAssetsRatesController_isDeprecated = new WeakMap(), _MultichainAssetsRatesController_instances = new WeakSet(), _MultichainAssetsRatesController_enforceDisabledState = function _MultichainAssetsRatesController_enforceDisabledState() {
|
|
238
|
+
if (Object.keys(this.state.conversionRates).length === 0 &&
|
|
239
|
+
Object.keys(this.state.historicalPrices).length === 0) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
this.update((state) => {
|
|
243
|
+
state.conversionRates = {};
|
|
244
|
+
state.historicalPrices = {};
|
|
245
|
+
});
|
|
246
|
+
}, _MultichainAssetsRatesController_isNonEvmAccount = function _MultichainAssetsRatesController_isNonEvmAccount(account) {
|
|
206
247
|
return (!isEvmAccountType(account.type) && account.metadata.snap !== undefined);
|
|
207
248
|
}, _MultichainAssetsRatesController_listMultichainAccounts = function _MultichainAssetsRatesController_listMultichainAccounts() {
|
|
208
249
|
return this.messenger.call('AccountsController:listMultichainAccounts');
|
|
@@ -352,6 +393,10 @@ async function _MultichainAssetsRatesController_getUpdatedRatesFor(snapIdToAsset
|
|
|
352
393
|
* @returns A promise that resolves when the rates are updated.
|
|
353
394
|
*/
|
|
354
395
|
async function _MultichainAssetsRatesController_updateAssetsRatesForNewAssets(accounts) {
|
|
396
|
+
if (__classPrivateFieldGet(this, _MultichainAssetsRatesController_isDeprecated, "f").call(this)) {
|
|
397
|
+
__classPrivateFieldGet(this, _MultichainAssetsRatesController_instances, "m", _MultichainAssetsRatesController_enforceDisabledState).call(this);
|
|
398
|
+
return Promise.resolve();
|
|
399
|
+
}
|
|
355
400
|
const releaseLock = await __classPrivateFieldGet(this, _MultichainAssetsRatesController_mutex, "f").acquire();
|
|
356
401
|
return (async () => {
|
|
357
402
|
if (!this.isActive) {
|