@metamask/assets-controller 0.2.0 → 2.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 -1
- package/dist/AssetsController-method-action-types.cjs +7 -0
- package/dist/AssetsController-method-action-types.cjs.map +1 -0
- package/dist/AssetsController-method-action-types.d.cts +78 -0
- package/dist/AssetsController-method-action-types.d.cts.map +1 -0
- package/dist/AssetsController-method-action-types.d.mts +78 -0
- package/dist/AssetsController-method-action-types.d.mts.map +1 -0
- package/dist/AssetsController-method-action-types.mjs +6 -0
- package/dist/AssetsController-method-action-types.mjs.map +1 -0
- package/dist/AssetsController.cjs +346 -271
- package/dist/AssetsController.cjs.map +1 -1
- package/dist/AssetsController.d.cts +92 -96
- package/dist/AssetsController.d.cts.map +1 -1
- package/dist/AssetsController.d.mts +92 -96
- package/dist/AssetsController.d.mts.map +1 -1
- package/dist/AssetsController.mjs +347 -272
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/AbstractDataSource.cjs +8 -0
- package/dist/data-sources/AbstractDataSource.cjs.map +1 -1
- package/dist/data-sources/AbstractDataSource.d.cts +16 -1
- package/dist/data-sources/AbstractDataSource.d.cts.map +1 -1
- package/dist/data-sources/AbstractDataSource.d.mts +16 -1
- package/dist/data-sources/AbstractDataSource.d.mts.map +1 -1
- package/dist/data-sources/AbstractDataSource.mjs +8 -0
- package/dist/data-sources/AbstractDataSource.mjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.cjs +92 -111
- package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.cts +27 -70
- package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.mts +27 -70
- package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.mjs +88 -107
- package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.cjs +141 -46
- package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.cts +19 -66
- package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.mts +19 -66
- package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.mjs +141 -46
- package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
- package/dist/data-sources/PriceDataSource.cjs +39 -48
- package/dist/data-sources/PriceDataSource.cjs.map +1 -1
- package/dist/data-sources/PriceDataSource.d.cts +13 -92
- package/dist/data-sources/PriceDataSource.d.cts.map +1 -1
- package/dist/data-sources/PriceDataSource.d.mts +13 -92
- package/dist/data-sources/PriceDataSource.d.mts.map +1 -1
- package/dist/data-sources/PriceDataSource.mjs +39 -48
- package/dist/data-sources/PriceDataSource.mjs.map +1 -1
- package/dist/data-sources/RpcDataSource.cjs +184 -142
- package/dist/data-sources/RpcDataSource.cjs.map +1 -1
- package/dist/data-sources/RpcDataSource.d.cts +29 -114
- package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
- package/dist/data-sources/RpcDataSource.d.mts +29 -114
- package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
- package/dist/data-sources/RpcDataSource.mjs +185 -143
- package/dist/data-sources/RpcDataSource.mjs.map +1 -1
- package/dist/data-sources/SnapDataSource.cjs +53 -39
- package/dist/data-sources/SnapDataSource.cjs.map +1 -1
- package/dist/data-sources/SnapDataSource.d.cts +9 -45
- package/dist/data-sources/SnapDataSource.d.cts.map +1 -1
- package/dist/data-sources/SnapDataSource.d.mts +9 -45
- package/dist/data-sources/SnapDataSource.d.mts.map +1 -1
- package/dist/data-sources/SnapDataSource.mjs +53 -39
- package/dist/data-sources/SnapDataSource.mjs.map +1 -1
- package/dist/data-sources/StakedBalanceDataSource.cjs +609 -0
- package/dist/data-sources/StakedBalanceDataSource.cjs.map +1 -0
- package/dist/data-sources/StakedBalanceDataSource.d.cts +72 -0
- package/dist/data-sources/StakedBalanceDataSource.d.cts.map +1 -0
- package/dist/data-sources/StakedBalanceDataSource.d.mts +72 -0
- package/dist/data-sources/StakedBalanceDataSource.d.mts.map +1 -0
- package/dist/data-sources/StakedBalanceDataSource.mjs +605 -0
- package/dist/data-sources/StakedBalanceDataSource.mjs.map +1 -0
- package/dist/data-sources/TokenDataSource.cjs +15 -21
- package/dist/data-sources/TokenDataSource.cjs.map +1 -1
- package/dist/data-sources/TokenDataSource.d.cts +3 -25
- package/dist/data-sources/TokenDataSource.d.cts.map +1 -1
- package/dist/data-sources/TokenDataSource.d.mts +3 -25
- package/dist/data-sources/TokenDataSource.d.mts.map +1 -1
- package/dist/data-sources/TokenDataSource.mjs +15 -21
- package/dist/data-sources/TokenDataSource.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/index.cjs +5 -1
- package/dist/data-sources/evm-rpc-services/index.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/index.d.cts +1 -1
- package/dist/data-sources/evm-rpc-services/index.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/index.d.mts +1 -1
- package/dist/data-sources/evm-rpc-services/index.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/index.mjs +1 -1
- package/dist/data-sources/evm-rpc-services/index.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.cjs +132 -0
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.d.cts +78 -0
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.d.mts +78 -0
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.mjs +126 -0
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.cjs +16 -0
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.cts +5 -1
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.mts +5 -1
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.mjs +16 -0
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/index.cjs +6 -1
- package/dist/data-sources/evm-rpc-services/services/index.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/index.d.cts +1 -0
- package/dist/data-sources/evm-rpc-services/services/index.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/index.d.mts +1 -0
- package/dist/data-sources/evm-rpc-services/services/index.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/index.mjs +1 -0
- package/dist/data-sources/evm-rpc-services/services/index.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/services.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/services.d.cts +4 -0
- package/dist/data-sources/evm-rpc-services/types/services.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/services.d.mts +4 -0
- package/dist/data-sources/evm-rpc-services/types/services.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/services.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/state.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/state.d.cts +3 -3
- package/dist/data-sources/evm-rpc-services/types/state.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/state.d.mts +3 -3
- package/dist/data-sources/evm-rpc-services/types/state.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/state.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/utils/index.cjs +9 -1
- package/dist/data-sources/evm-rpc-services/utils/index.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/utils/index.d.cts +2 -0
- package/dist/data-sources/evm-rpc-services/utils/index.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/utils/index.d.mts +2 -0
- package/dist/data-sources/evm-rpc-services/utils/index.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/utils/index.mjs +2 -0
- package/dist/data-sources/evm-rpc-services/utils/index.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/utils/parsing.cjs +47 -0
- package/dist/data-sources/evm-rpc-services/utils/parsing.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/parsing.d.cts +25 -0
- package/dist/data-sources/evm-rpc-services/utils/parsing.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/parsing.d.mts +25 -0
- package/dist/data-sources/evm-rpc-services/utils/parsing.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/parsing.mjs +39 -0
- package/dist/data-sources/evm-rpc-services/utils/parsing.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/staking-contracts.cjs +68 -0
- package/dist/data-sources/evm-rpc-services/utils/staking-contracts.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/staking-contracts.d.cts +25 -0
- package/dist/data-sources/evm-rpc-services/utils/staking-contracts.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/staking-contracts.d.mts +25 -0
- package/dist/data-sources/evm-rpc-services/utils/staking-contracts.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/staking-contracts.mjs +62 -0
- package/dist/data-sources/evm-rpc-services/utils/staking-contracts.mjs.map +1 -0
- package/dist/data-sources/index.cjs +3 -6
- package/dist/data-sources/index.cjs.map +1 -1
- package/dist/data-sources/index.d.cts +7 -7
- package/dist/data-sources/index.d.cts.map +1 -1
- package/dist/data-sources/index.d.mts +7 -7
- package/dist/data-sources/index.d.mts.map +1 -1
- package/dist/data-sources/index.mjs +2 -3
- package/dist/data-sources/index.mjs.map +1 -1
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -11
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +11 -11
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/dist/middlewares/DetectionMiddleware.cjs +8 -28
- package/dist/middlewares/DetectionMiddleware.cjs.map +1 -1
- package/dist/middlewares/DetectionMiddleware.d.cts +4 -26
- package/dist/middlewares/DetectionMiddleware.d.cts.map +1 -1
- package/dist/middlewares/DetectionMiddleware.d.mts +4 -26
- package/dist/middlewares/DetectionMiddleware.d.mts.map +1 -1
- package/dist/middlewares/DetectionMiddleware.mjs +8 -28
- package/dist/middlewares/DetectionMiddleware.mjs.map +1 -1
- package/dist/middlewares/index.cjs.map +1 -1
- package/dist/middlewares/index.d.cts +1 -1
- package/dist/middlewares/index.d.cts.map +1 -1
- package/dist/middlewares/index.d.mts +1 -1
- package/dist/middlewares/index.d.mts.map +1 -1
- package/dist/middlewares/index.mjs.map +1 -1
- package/dist/selectors/balance.cjs +306 -0
- package/dist/selectors/balance.cjs.map +1 -0
- package/dist/selectors/balance.d.cts +22 -0
- package/dist/selectors/balance.d.cts.map +1 -0
- package/dist/selectors/balance.d.mts +22 -0
- package/dist/selectors/balance.d.mts.map +1 -0
- package/dist/selectors/balance.mjs +297 -0
- package/dist/selectors/balance.mjs.map +1 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +56 -21
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +56 -21
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +13 -10
- package/dist/data-sources/initDataSources.cjs +0 -215
- package/dist/data-sources/initDataSources.cjs.map +0 -1
- package/dist/data-sources/initDataSources.d.cts +0 -140
- package/dist/data-sources/initDataSources.d.cts.map +0 -1
- package/dist/data-sources/initDataSources.d.mts +0 -140
- package/dist/data-sources/initDataSources.d.mts.map +0 -1
- package/dist/data-sources/initDataSources.mjs +0 -210
- package/dist/data-sources/initDataSources.mjs.map +0 -1
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
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");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
2
7
|
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
8
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
9
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
11
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
12
|
};
|
|
8
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
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
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
-
};
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_defaultUpdateInterval, _AssetsController_controllerMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_selectedAccounts_get,
|
|
16
|
+
var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trackMetaMetricsEvent, _AssetsController_firstInitFetchReported, _AssetsController_controllerMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_selectedAccounts_get, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_registerActionHandlers, _AssetsController_executeMiddlewares, _AssetsController_updateState, _AssetsController_getAssetsFromState, _AssetsController_tokenStandardToAssetType, _AssetsController_start, _AssetsController_stop, _AssetsController_subscribeAssets, _AssetsController_subscribeAssetsBalance, _AssetsController_subscribeStakedBalance, _AssetsController_buildChainToAccountsMap, _AssetsController_subscribeDataSource, _AssetsController_unsubscribeDataSource, _AssetsController_buildDataRequest, _AssetsController_getEnabledChainsForAccount, _AssetsController_handleAccountGroupChanged, _AssetsController_handleEnabledNetworksChanged;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.AssetsController = exports.getDefaultAssetsControllerState = void 0;
|
|
19
19
|
const base_controller_1 = require("@metamask/base-controller");
|
|
@@ -21,12 +21,32 @@ const utils_1 = require("@metamask/utils");
|
|
|
21
21
|
const async_mutex_1 = require("async-mutex");
|
|
22
22
|
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
23
23
|
const lodash_1 = require("lodash");
|
|
24
|
+
const AccountsApiDataSource_1 = require("./data-sources/AccountsApiDataSource.cjs");
|
|
25
|
+
const BackendWebsocketDataSource_1 = require("./data-sources/BackendWebsocketDataSource.cjs");
|
|
26
|
+
const PriceDataSource_1 = require("./data-sources/PriceDataSource.cjs");
|
|
27
|
+
const RpcDataSource_1 = require("./data-sources/RpcDataSource.cjs");
|
|
28
|
+
const SnapDataSource_1 = require("./data-sources/SnapDataSource.cjs");
|
|
29
|
+
const StakedBalanceDataSource_1 = require("./data-sources/StakedBalanceDataSource.cjs");
|
|
30
|
+
const TokenDataSource_1 = require("./data-sources/TokenDataSource.cjs");
|
|
24
31
|
const logger_1 = require("./logger.cjs");
|
|
32
|
+
const DetectionMiddleware_1 = require("./middlewares/DetectionMiddleware.cjs");
|
|
25
33
|
const utils_2 = require("./utils.cjs");
|
|
26
34
|
// ============================================================================
|
|
27
35
|
// CONTROLLER CONSTANTS
|
|
28
36
|
// ============================================================================
|
|
29
37
|
const CONTROLLER_NAME = 'AssetsController';
|
|
38
|
+
/** Method names exposed as messenger actions (AssetsController:getAssets, etc.) */
|
|
39
|
+
const MESSENGER_EXPOSED_METHODS = [
|
|
40
|
+
'getAssets',
|
|
41
|
+
'getAssetsBalance',
|
|
42
|
+
'getAssetMetadata',
|
|
43
|
+
'getAssetsPrice',
|
|
44
|
+
'addCustomAsset',
|
|
45
|
+
'removeCustomAsset',
|
|
46
|
+
'getCustomAssets',
|
|
47
|
+
'hideAsset',
|
|
48
|
+
'unhideAsset',
|
|
49
|
+
];
|
|
30
50
|
/** Default polling interval hint for data sources (30 seconds) */
|
|
31
51
|
const DEFAULT_POLLING_INTERVAL_MS = 30000;
|
|
32
52
|
const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, CONTROLLER_NAME);
|
|
@@ -37,7 +57,7 @@ const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, CONTROLLER_
|
|
|
37
57
|
*/
|
|
38
58
|
function getDefaultAssetsControllerState() {
|
|
39
59
|
return {
|
|
40
|
-
|
|
60
|
+
assetsInfo: {},
|
|
41
61
|
assetsBalance: {},
|
|
42
62
|
assetsPrice: {},
|
|
43
63
|
customAssets: {},
|
|
@@ -49,7 +69,7 @@ exports.getDefaultAssetsControllerState = getDefaultAssetsControllerState;
|
|
|
49
69
|
// STATE METADATA
|
|
50
70
|
// ============================================================================
|
|
51
71
|
const stateMetadata = {
|
|
52
|
-
|
|
72
|
+
assetsInfo: {
|
|
53
73
|
persist: true,
|
|
54
74
|
includeInStateLogs: false,
|
|
55
75
|
includeInDebugSnapshot: false,
|
|
@@ -97,11 +117,11 @@ function extractChainId(assetId) {
|
|
|
97
117
|
*/
|
|
98
118
|
function normalizeResponse(response) {
|
|
99
119
|
const normalized = {};
|
|
100
|
-
if (response.
|
|
101
|
-
normalized.
|
|
102
|
-
for (const [assetId, metadata] of Object.entries(response.
|
|
120
|
+
if (response.assetsInfo) {
|
|
121
|
+
normalized.assetsInfo = {};
|
|
122
|
+
for (const [assetId, metadata] of Object.entries(response.assetsInfo)) {
|
|
103
123
|
const normalizedId = (0, utils_2.normalizeAssetId)(assetId);
|
|
104
|
-
normalized.
|
|
124
|
+
normalized.assetsInfo[normalizedId] = metadata;
|
|
105
125
|
}
|
|
106
126
|
}
|
|
107
127
|
if (response.assetsPrice) {
|
|
@@ -153,13 +173,8 @@ function normalizeResponse(response) {
|
|
|
153
173
|
* based on which chains they support. When active chains change, the controller
|
|
154
174
|
* dynamically adjusts subscriptions.
|
|
155
175
|
*
|
|
156
|
-
* 4. **
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* ## App Lifecycle
|
|
160
|
-
*
|
|
161
|
-
* - **App Opened** (`AppStateController:appOpened`): Starts subscriptions, fetches initial data
|
|
162
|
-
* - **App Closed** (`AppStateController:appClosed`): Stops all subscriptions to conserve resources
|
|
176
|
+
* 4. **Keyring Lifecycle**: Listens to KeyringController unlock/lock events to
|
|
177
|
+
* start/stop subscriptions when the wallet is unlocked or locked.
|
|
163
178
|
*
|
|
164
179
|
* ## Architecture
|
|
165
180
|
*
|
|
@@ -168,7 +183,7 @@ function normalizeResponse(response) {
|
|
|
168
183
|
* - The controller does NOT manage polling - it simply receives pushed updates
|
|
169
184
|
*/
|
|
170
185
|
class AssetsController extends base_controller_1.BaseController {
|
|
171
|
-
constructor({ messenger, state = {}, defaultUpdateInterval = DEFAULT_POLLING_INTERVAL_MS, isEnabled = () => true, }) {
|
|
186
|
+
constructor({ messenger, state = {}, defaultUpdateInterval = DEFAULT_POLLING_INTERVAL_MS, isEnabled = () => true, isBasicFunctionality, subscribeToBasicFunctionalityChange, queryApiClient, rpcDataSourceConfig, trackMetaMetricsEvent, accountsApiDataSourceConfig, priceDataSourceConfig, stakedBalanceDataSourceConfig, }) {
|
|
172
187
|
super({
|
|
173
188
|
name: CONTROLLER_NAME,
|
|
174
189
|
messenger,
|
|
@@ -181,8 +196,14 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
181
196
|
_AssetsController_instances.add(this);
|
|
182
197
|
/** Whether the controller is enabled */
|
|
183
198
|
_AssetsController_isEnabled.set(this, void 0);
|
|
199
|
+
/** Getter for basic functionality (only balance fetch/subscribe use RPC; token/price API not used). No attribute stored. */
|
|
200
|
+
_AssetsController_isBasicFunctionality.set(this, void 0);
|
|
184
201
|
/** Default update interval hint passed to data sources */
|
|
185
202
|
_AssetsController_defaultUpdateInterval.set(this, void 0);
|
|
203
|
+
/** Optional callback for first init/fetch MetaMetrics (duration). */
|
|
204
|
+
_AssetsController_trackMetaMetricsEvent.set(this, void 0);
|
|
205
|
+
/** Whether we have already reported first init fetch for this session (reset on #stop). */
|
|
206
|
+
_AssetsController_firstInitFetchReported.set(this, false);
|
|
186
207
|
_AssetsController_controllerMutex.set(this, new async_mutex_1.Mutex());
|
|
187
208
|
/**
|
|
188
209
|
* Active balance subscriptions keyed by account ID.
|
|
@@ -193,79 +214,107 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
193
214
|
_AssetsController_activeSubscriptions.set(this, new Map());
|
|
194
215
|
/** Currently enabled chains from NetworkEnablementController */
|
|
195
216
|
_AssetsController_enabledChains.set(this, new Set());
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
217
|
+
_AssetsController_backendWebsocketDataSource.set(this, void 0);
|
|
218
|
+
_AssetsController_accountsApiDataSource.set(this, void 0);
|
|
219
|
+
_AssetsController_snapDataSource.set(this, void 0);
|
|
220
|
+
_AssetsController_rpcDataSource.set(this, void 0);
|
|
221
|
+
_AssetsController_stakedBalanceDataSource.set(this, void 0);
|
|
222
|
+
_AssetsController_priceDataSource.set(this, void 0);
|
|
223
|
+
_AssetsController_detectionMiddleware.set(this, void 0);
|
|
224
|
+
_AssetsController_tokenDataSource.set(this, void 0);
|
|
225
|
+
_AssetsController_unsubscribeBasicFunctionality.set(this, null);
|
|
202
226
|
__classPrivateFieldSet(this, _AssetsController_isEnabled, isEnabled(), "f");
|
|
227
|
+
__classPrivateFieldSet(this, _AssetsController_isBasicFunctionality, isBasicFunctionality ?? (() => true), "f");
|
|
203
228
|
__classPrivateFieldSet(this, _AssetsController_defaultUpdateInterval, defaultUpdateInterval, "f");
|
|
229
|
+
__classPrivateFieldSet(this, _AssetsController_trackMetaMetricsEvent, trackMetaMetricsEvent, "f");
|
|
230
|
+
const rpcConfig = rpcDataSourceConfig ?? {};
|
|
231
|
+
const onActiveChainsUpdated = (dataSourceName, chains, previousChains) => {
|
|
232
|
+
this.handleActiveChainsUpdate(dataSourceName, chains, previousChains);
|
|
233
|
+
};
|
|
234
|
+
__classPrivateFieldSet(this, _AssetsController_backendWebsocketDataSource, new BackendWebsocketDataSource_1.BackendWebsocketDataSource({
|
|
235
|
+
messenger: this.messenger,
|
|
236
|
+
queryApiClient,
|
|
237
|
+
onActiveChainsUpdated,
|
|
238
|
+
}), "f");
|
|
239
|
+
__classPrivateFieldSet(this, _AssetsController_accountsApiDataSource, new AccountsApiDataSource_1.AccountsApiDataSource({
|
|
240
|
+
queryApiClient,
|
|
241
|
+
onActiveChainsUpdated,
|
|
242
|
+
...accountsApiDataSourceConfig,
|
|
243
|
+
}), "f");
|
|
244
|
+
__classPrivateFieldSet(this, _AssetsController_snapDataSource, new SnapDataSource_1.SnapDataSource({
|
|
245
|
+
messenger: this.messenger,
|
|
246
|
+
onActiveChainsUpdated,
|
|
247
|
+
}), "f");
|
|
248
|
+
__classPrivateFieldSet(this, _AssetsController_rpcDataSource, new RpcDataSource_1.RpcDataSource({
|
|
249
|
+
messenger: this.messenger,
|
|
250
|
+
onActiveChainsUpdated,
|
|
251
|
+
...rpcConfig,
|
|
252
|
+
}), "f");
|
|
253
|
+
__classPrivateFieldSet(this, _AssetsController_stakedBalanceDataSource, new StakedBalanceDataSource_1.StakedBalanceDataSource({
|
|
254
|
+
messenger: this.messenger,
|
|
255
|
+
onActiveChainsUpdated,
|
|
256
|
+
...stakedBalanceDataSourceConfig,
|
|
257
|
+
}), "f");
|
|
258
|
+
__classPrivateFieldSet(this, _AssetsController_tokenDataSource, new TokenDataSource_1.TokenDataSource({
|
|
259
|
+
queryApiClient,
|
|
260
|
+
}), "f");
|
|
261
|
+
__classPrivateFieldSet(this, _AssetsController_priceDataSource, new PriceDataSource_1.PriceDataSource({
|
|
262
|
+
queryApiClient,
|
|
263
|
+
...priceDataSourceConfig,
|
|
264
|
+
}), "f");
|
|
265
|
+
__classPrivateFieldSet(this, _AssetsController_detectionMiddleware, new DetectionMiddleware_1.DetectionMiddleware(), "f");
|
|
204
266
|
if (!__classPrivateFieldGet(this, _AssetsController_isEnabled, "f")) {
|
|
205
267
|
log('AssetsController is disabled, skipping initialization');
|
|
206
268
|
return;
|
|
207
269
|
}
|
|
208
270
|
log('Initializing AssetsController', {
|
|
209
|
-
defaultUpdateInterval,
|
|
271
|
+
defaultUpdateInterval: __classPrivateFieldGet(this, _AssetsController_defaultUpdateInterval, "f"),
|
|
210
272
|
});
|
|
211
273
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_initializeState).call(this);
|
|
212
274
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeToEvents).call(this);
|
|
213
275
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_registerActionHandlers).call(this);
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
// ============================================================================
|
|
223
|
-
// DATA SOURCE MANAGEMENT
|
|
224
|
-
// ============================================================================
|
|
225
|
-
/**
|
|
226
|
-
* Register data sources with the controller.
|
|
227
|
-
* Order of the array determines subscription order.
|
|
228
|
-
*
|
|
229
|
-
* Data sources report chain changes by calling `AssetsController:activeChainsUpdate` action.
|
|
230
|
-
*
|
|
231
|
-
* @param dataSourceIds - Array of data source identifiers to register.
|
|
232
|
-
*/
|
|
233
|
-
registerDataSources(dataSourceIds) {
|
|
234
|
-
for (const id of dataSourceIds) {
|
|
235
|
-
log('Registering data source', { id });
|
|
236
|
-
// Initialize available chains tracking for this source
|
|
237
|
-
__classPrivateFieldGet(this, _AssetsController_dataSources, "f").set(id, new Set());
|
|
276
|
+
// Subscriptions start only on KeyringController:unlock -> #start(), not here.
|
|
277
|
+
// Subscribe to basic-functionality changes after construction so a synchronous
|
|
278
|
+
// onChange during subscribe cannot run before data sources are initialized.
|
|
279
|
+
if (subscribeToBasicFunctionalityChange) {
|
|
280
|
+
const unsubscribe = subscribeToBasicFunctionalityChange((isBasic) => this.handleBasicFunctionalityChange(isBasic));
|
|
281
|
+
if (typeof unsubscribe === 'function') {
|
|
282
|
+
__classPrivateFieldSet(this, _AssetsController_unsubscribeBasicFunctionality, unsubscribe, "f");
|
|
283
|
+
}
|
|
238
284
|
}
|
|
239
285
|
}
|
|
240
286
|
// ============================================================================
|
|
241
287
|
// DATA SOURCE CHAIN MANAGEMENT
|
|
242
288
|
// ============================================================================
|
|
243
289
|
/**
|
|
244
|
-
* Handle when a data source's
|
|
245
|
-
*
|
|
246
|
-
*
|
|
290
|
+
* Handle when a data source's supported chains change.
|
|
291
|
+
* Used to refresh balance subscriptions and run a one-time fetch when a new chain is supported.
|
|
292
|
+
*
|
|
293
|
+
* - On any add/remove: re-subscribes to data sources so chain assignment stays correct.
|
|
294
|
+
* - When chains are added: fetches balances for the new chains (for selected accounts on enabled networks).
|
|
247
295
|
*
|
|
248
|
-
*
|
|
296
|
+
* Controller does not store chains; sources report via this callback. previousChains is required for diff.
|
|
249
297
|
*
|
|
250
298
|
* @param dataSourceId - The identifier of the data source reporting the change.
|
|
251
|
-
* @param activeChains -
|
|
299
|
+
* @param activeChains - Currently active (supported and available) chain IDs for this source.
|
|
300
|
+
* @param previousChains - Previous chains; used to compute added/removed.
|
|
252
301
|
*/
|
|
253
|
-
handleActiveChainsUpdate(dataSourceId, activeChains) {
|
|
302
|
+
handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
|
|
303
|
+
if (!__classPrivateFieldGet(this, _AssetsController_isEnabled, "f")) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
254
306
|
log('Data source active chains changed', {
|
|
255
307
|
dataSourceId,
|
|
256
308
|
chainCount: activeChains.length,
|
|
257
309
|
chains: activeChains,
|
|
258
310
|
});
|
|
259
|
-
const
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
// Check for changes
|
|
264
|
-
const addedChains = activeChains.filter((chain) => !previousChains.has(chain));
|
|
265
|
-
const removedChains = Array.from(previousChains).filter((chain) => !newChains.has(chain));
|
|
311
|
+
const previous = previousChains;
|
|
312
|
+
const previousSet = new Set(previous);
|
|
313
|
+
const addedChains = activeChains.filter((ch) => !previousSet.has(ch));
|
|
314
|
+
const removedChains = previous.filter((ch) => !activeChains.includes(ch));
|
|
266
315
|
if (addedChains.length > 0 || removedChains.length > 0) {
|
|
267
316
|
// Refresh subscriptions to use updated data source availability
|
|
268
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m",
|
|
317
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
269
318
|
}
|
|
270
319
|
// If chains were added and we have selected accounts, do one-time fetch
|
|
271
320
|
if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
|
|
@@ -295,22 +344,39 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
295
344
|
customAssets.push(...accountCustomAssets);
|
|
296
345
|
}
|
|
297
346
|
if (options?.forceUpdate) {
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
this.messenger.call('SnapDataSource:getAssetsMiddleware'),
|
|
301
|
-
this.messenger.call('RpcDataSource:getAssetsMiddleware'),
|
|
302
|
-
this.messenger.call('DetectionMiddleware:getAssetsMiddleware'),
|
|
303
|
-
this.messenger.call('TokenDataSource:getAssetsMiddleware'),
|
|
304
|
-
this.messenger.call('PriceDataSource:getAssetsMiddleware'),
|
|
305
|
-
], {
|
|
306
|
-
accounts,
|
|
307
|
-
chainIds,
|
|
347
|
+
const startTime = Date.now();
|
|
348
|
+
const request = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
|
|
308
349
|
assetTypes,
|
|
309
350
|
dataTypes,
|
|
310
351
|
customAssets: customAssets.length > 0 ? customAssets : undefined,
|
|
311
352
|
forceUpdate: true,
|
|
312
353
|
});
|
|
354
|
+
const sources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
355
|
+
? [
|
|
356
|
+
__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
|
|
357
|
+
__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"),
|
|
358
|
+
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
|
|
359
|
+
__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
|
|
360
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
361
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
362
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
363
|
+
]
|
|
364
|
+
: [
|
|
365
|
+
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
|
|
366
|
+
__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
|
|
367
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
368
|
+
];
|
|
369
|
+
const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, sources, request);
|
|
313
370
|
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, response);
|
|
371
|
+
if (__classPrivateFieldGet(this, _AssetsController_trackMetaMetricsEvent, "f") && !__classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")) {
|
|
372
|
+
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
|
|
373
|
+
const durationMs = Date.now() - startTime;
|
|
374
|
+
__classPrivateFieldGet(this, _AssetsController_trackMetaMetricsEvent, "f").call(this, {
|
|
375
|
+
durationMs,
|
|
376
|
+
chainIds,
|
|
377
|
+
durationByDataSource,
|
|
378
|
+
});
|
|
379
|
+
}
|
|
314
380
|
}
|
|
315
381
|
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
|
|
316
382
|
}
|
|
@@ -335,7 +401,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
335
401
|
return result;
|
|
336
402
|
}
|
|
337
403
|
getAssetMetadata(assetId) {
|
|
338
|
-
return this.state.
|
|
404
|
+
return this.state.assetsInfo[assetId];
|
|
339
405
|
}
|
|
340
406
|
async getAssetsPrice(accounts, options) {
|
|
341
407
|
const assets = await this.getAssets(accounts, {
|
|
@@ -463,33 +529,33 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
463
529
|
}
|
|
464
530
|
});
|
|
465
531
|
}
|
|
532
|
+
// ============================================================================
|
|
533
|
+
// SUBSCRIPTIONS
|
|
534
|
+
// ============================================================================
|
|
466
535
|
/**
|
|
467
536
|
* Subscribe to price updates for all assets held by the given accounts.
|
|
468
537
|
* Polls PriceDataSource which fetches prices from balance state.
|
|
469
538
|
*
|
|
470
539
|
* @param accounts - Accounts to subscribe price updates for.
|
|
471
540
|
* @param chainIds - Chain IDs to filter prices for.
|
|
472
|
-
* @param options - Subscription options.
|
|
473
|
-
* @param options.updateInterval - Polling interval in ms.
|
|
474
541
|
*/
|
|
475
|
-
subscribeAssetsPrice(accounts, chainIds
|
|
476
|
-
|
|
542
|
+
subscribeAssetsPrice(accounts, chainIds) {
|
|
543
|
+
if (!__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
477
546
|
const subscriptionKey = 'ds:PriceDataSource';
|
|
478
547
|
const existingSubscription = __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").get(subscriptionKey);
|
|
479
548
|
const isUpdate = existingSubscription !== undefined;
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
.call('PriceDataSource:subscribe', {
|
|
483
|
-
request: {
|
|
484
|
-
accounts,
|
|
485
|
-
chainIds,
|
|
549
|
+
const subscribeReq = {
|
|
550
|
+
request: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
|
|
486
551
|
dataTypes: ['price'],
|
|
487
|
-
|
|
488
|
-
},
|
|
552
|
+
}),
|
|
489
553
|
subscriptionId: subscriptionKey,
|
|
490
554
|
isUpdate,
|
|
491
|
-
|
|
492
|
-
|
|
555
|
+
onAssetsUpdate: (response) => this.handleAssetsUpdate(response, 'PriceDataSource'),
|
|
556
|
+
getAssetsState: () => this.state,
|
|
557
|
+
};
|
|
558
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f").subscribe(subscribeReq).catch(console.error);
|
|
493
559
|
// Track subscription
|
|
494
560
|
const subscription = {
|
|
495
561
|
chains: chainIds,
|
|
@@ -511,46 +577,70 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
511
577
|
if (!existingSubscription) {
|
|
512
578
|
return;
|
|
513
579
|
}
|
|
514
|
-
|
|
515
|
-
this.messenger
|
|
516
|
-
.call('PriceDataSource:unsubscribe', subscriptionKey)
|
|
517
|
-
.catch(console.error);
|
|
580
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f").unsubscribe(subscriptionKey).catch(console.error);
|
|
518
581
|
existingSubscription.unsubscribe();
|
|
519
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* Handle basic functionality toggle change. Call this from the consumer (extension or mobile)
|
|
585
|
+
* when the user changes the "Basic functionality" setting. Refreshes subscriptions so the
|
|
586
|
+
* current {@link AssetsControllerOptions.isBasicFunctionality} getter is used (true = APIs on,
|
|
587
|
+
* false = RPC only).
|
|
588
|
+
*
|
|
589
|
+
* @param _isBasic - The new value (for call-site clarity; the getter is the source of truth).
|
|
590
|
+
*/
|
|
591
|
+
handleBasicFunctionalityChange(_isBasic) {
|
|
592
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_stop).call(this);
|
|
593
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
594
|
+
}
|
|
520
595
|
/**
|
|
521
596
|
* Handle assets updated from a data source.
|
|
522
|
-
* Called via
|
|
597
|
+
* Called via the onAssetsUpdate callback passed in SubscriptionRequest when the controller subscribes to a data source.
|
|
598
|
+
* Enriches the response with token metadata (via middlewares) before updating state.
|
|
523
599
|
*
|
|
524
600
|
* @param response - The data response with updated assets
|
|
525
601
|
* @param sourceId - The data source ID reporting the update
|
|
602
|
+
* @param request - Optional original request for context when enriching
|
|
526
603
|
*/
|
|
527
|
-
async handleAssetsUpdate(response, sourceId) {
|
|
604
|
+
async handleAssetsUpdate(response, sourceId, request) {
|
|
528
605
|
log('Assets updated from data source', {
|
|
529
606
|
sourceId,
|
|
530
607
|
hasBalance: Boolean(response.assetsBalance),
|
|
531
608
|
hasPrice: Boolean(response.assetsPrice),
|
|
532
609
|
});
|
|
533
|
-
|
|
610
|
+
// Run through enrichment middlewares (Event Stack: Detection → Token → Price)
|
|
611
|
+
// Include 'metadata' in dataTypes so TokenDataSource runs to enrich detected assets
|
|
612
|
+
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"), __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f")], request ?? {
|
|
613
|
+
accountsWithSupportedChains: [],
|
|
614
|
+
chainIds: [],
|
|
615
|
+
dataTypes: ['balance', 'metadata', 'price'],
|
|
616
|
+
}, response);
|
|
617
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, enrichedResponse);
|
|
534
618
|
}
|
|
535
619
|
// ============================================================================
|
|
536
620
|
// CLEANUP
|
|
537
621
|
// ============================================================================
|
|
538
622
|
destroy() {
|
|
539
623
|
log('Destroying AssetsController', {
|
|
540
|
-
dataSourceCount: __classPrivateFieldGet(this,
|
|
624
|
+
dataSourceCount: __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_allBalanceDataSources_get).length,
|
|
541
625
|
subscriptionCount: __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").size,
|
|
542
626
|
});
|
|
543
|
-
//
|
|
544
|
-
__classPrivateFieldGet(this,
|
|
627
|
+
// Destroy instantiated data sources
|
|
628
|
+
__classPrivateFieldGet(this, _AssetsController_backendWebsocketDataSource, "f")?.destroy?.();
|
|
629
|
+
__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f")?.destroy?.();
|
|
630
|
+
__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f")?.destroy?.();
|
|
631
|
+
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")?.destroy?.();
|
|
632
|
+
__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f")?.destroy?.();
|
|
545
633
|
// Stop all active subscriptions
|
|
546
634
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_stop).call(this);
|
|
635
|
+
if (__classPrivateFieldGet(this, _AssetsController_unsubscribeBasicFunctionality, "f")) {
|
|
636
|
+
__classPrivateFieldGet(this, _AssetsController_unsubscribeBasicFunctionality, "f").call(this);
|
|
637
|
+
__classPrivateFieldSet(this, _AssetsController_unsubscribeBasicFunctionality, null, "f");
|
|
638
|
+
}
|
|
547
639
|
// Unregister action handlers
|
|
548
640
|
this.messenger.unregisterActionHandler('AssetsController:getAssets');
|
|
549
641
|
this.messenger.unregisterActionHandler('AssetsController:getAssetsBalance');
|
|
550
642
|
this.messenger.unregisterActionHandler('AssetsController:getAssetMetadata');
|
|
551
643
|
this.messenger.unregisterActionHandler('AssetsController:getAssetsPrice');
|
|
552
|
-
this.messenger.unregisterActionHandler('AssetsController:activeChainsUpdate');
|
|
553
|
-
this.messenger.unregisterActionHandler('AssetsController:assetsUpdate');
|
|
554
644
|
this.messenger.unregisterActionHandler('AssetsController:addCustomAsset');
|
|
555
645
|
this.messenger.unregisterActionHandler('AssetsController:removeCustomAsset');
|
|
556
646
|
this.messenger.unregisterActionHandler('AssetsController:getCustomAssets');
|
|
@@ -559,8 +649,15 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
559
649
|
}
|
|
560
650
|
}
|
|
561
651
|
exports.AssetsController = AssetsController;
|
|
562
|
-
_AssetsController_isEnabled = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_controllerMutex = new WeakMap(), _AssetsController_activeSubscriptions = new WeakMap(), _AssetsController_enabledChains = new WeakMap(),
|
|
652
|
+
_AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trackMetaMetricsEvent = new WeakMap(), _AssetsController_firstInitFetchReported = new WeakMap(), _AssetsController_controllerMutex = new WeakMap(), _AssetsController_activeSubscriptions = new WeakMap(), _AssetsController_enabledChains = new WeakMap(), _AssetsController_backendWebsocketDataSource = new WeakMap(), _AssetsController_accountsApiDataSource = new WeakMap(), _AssetsController_snapDataSource = new WeakMap(), _AssetsController_rpcDataSource = new WeakMap(), _AssetsController_stakedBalanceDataSource = new WeakMap(), _AssetsController_priceDataSource = new WeakMap(), _AssetsController_detectionMiddleware = new WeakMap(), _AssetsController_tokenDataSource = new WeakMap(), _AssetsController_unsubscribeBasicFunctionality = new WeakMap(), _AssetsController_instances = new WeakSet(), _AssetsController_selectedAccounts_get = function _AssetsController_selectedAccounts_get() {
|
|
563
653
|
return this.messenger.call('AccountTreeController:getAccountsFromSelectedAccountGroup');
|
|
654
|
+
}, _AssetsController_allBalanceDataSources_get = function _AssetsController_allBalanceDataSources_get() {
|
|
655
|
+
return [
|
|
656
|
+
__classPrivateFieldGet(this, _AssetsController_backendWebsocketDataSource, "f"),
|
|
657
|
+
__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
|
|
658
|
+
__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"),
|
|
659
|
+
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
|
|
660
|
+
];
|
|
564
661
|
}, _AssetsController_initializeState = function _AssetsController_initializeState() {
|
|
565
662
|
const { enabledNetworkMap } = this.messenger.call('NetworkEnablementController:getState');
|
|
566
663
|
__classPrivateFieldSet(this, _AssetsController_enabledChains, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_extractEnabledChains).call(this, enabledNetworkMap), "f");
|
|
@@ -588,7 +685,7 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_defaultUpdateInte
|
|
|
588
685
|
}
|
|
589
686
|
return chains;
|
|
590
687
|
}, _AssetsController_normalizeChainReference = function _AssetsController_normalizeChainReference(namespace, reference) {
|
|
591
|
-
if (namespace === 'eip155' &&
|
|
688
|
+
if (namespace === 'eip155' && (0, utils_1.isStrictHexString)(reference)) {
|
|
592
689
|
// Convert hex to decimal for EIP155 chains
|
|
593
690
|
return parseInt(reference, 16).toString();
|
|
594
691
|
}
|
|
@@ -602,38 +699,38 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_defaultUpdateInte
|
|
|
602
699
|
this.messenger.subscribe('NetworkEnablementController:stateChange', ({ enabledNetworkMap }) => {
|
|
603
700
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleEnabledNetworksChanged).call(this, enabledNetworkMap).catch(console.error);
|
|
604
701
|
});
|
|
605
|
-
// App lifecycle: start when opened, stop when closed
|
|
606
|
-
this.messenger.subscribe('AppStateController:appOpened', () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_start).call(this));
|
|
607
|
-
this.messenger.subscribe('AppStateController:appClosed', () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_stop).call(this));
|
|
608
702
|
// Keyring lifecycle: start when unlocked, stop when locked
|
|
609
703
|
this.messenger.subscribe('KeyringController:unlock', () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_start).call(this));
|
|
610
704
|
this.messenger.subscribe('KeyringController:lock', () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_stop).call(this));
|
|
611
705
|
}, _AssetsController_registerActionHandlers = function _AssetsController_registerActionHandlers() {
|
|
612
|
-
this.messenger.
|
|
613
|
-
this.messenger.registerActionHandler('AssetsController:getAssetsBalance', this.getAssetsBalance.bind(this));
|
|
614
|
-
this.messenger.registerActionHandler('AssetsController:getAssetMetadata', this.getAssetMetadata.bind(this));
|
|
615
|
-
this.messenger.registerActionHandler('AssetsController:getAssetsPrice', this.getAssetsPrice.bind(this));
|
|
616
|
-
this.messenger.registerActionHandler('AssetsController:activeChainsUpdate', this.handleActiveChainsUpdate.bind(this));
|
|
617
|
-
this.messenger.registerActionHandler('AssetsController:assetsUpdate', this.handleAssetsUpdate.bind(this));
|
|
618
|
-
this.messenger.registerActionHandler('AssetsController:addCustomAsset', this.addCustomAsset.bind(this));
|
|
619
|
-
this.messenger.registerActionHandler('AssetsController:removeCustomAsset', this.removeCustomAsset.bind(this));
|
|
620
|
-
this.messenger.registerActionHandler('AssetsController:getCustomAssets', this.getCustomAssets.bind(this));
|
|
621
|
-
this.messenger.registerActionHandler('AssetsController:hideAsset', this.hideAsset.bind(this));
|
|
622
|
-
this.messenger.registerActionHandler('AssetsController:unhideAsset', this.unhideAsset.bind(this));
|
|
706
|
+
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
623
707
|
}, _AssetsController_executeMiddlewares =
|
|
624
708
|
// ============================================================================
|
|
625
709
|
// MIDDLEWARE EXECUTION
|
|
626
710
|
// ============================================================================
|
|
627
711
|
/**
|
|
628
712
|
* Execute middlewares with request/response context.
|
|
713
|
+
* Returns response and exclusive duration per source (sum ≈ wall time).
|
|
629
714
|
*
|
|
630
|
-
* @param
|
|
715
|
+
* @param sources - Data sources or middlewares with getName() and assetsMiddleware (executed in order).
|
|
631
716
|
* @param request - The data request.
|
|
632
717
|
* @param initialResponse - Optional initial response (for enriching existing data).
|
|
633
|
-
* @returns
|
|
718
|
+
* @returns Response and durationByDataSource (exclusive ms per source name).
|
|
634
719
|
*/
|
|
635
|
-
async function _AssetsController_executeMiddlewares(
|
|
636
|
-
const
|
|
720
|
+
async function _AssetsController_executeMiddlewares(sources, request, initialResponse = {}) {
|
|
721
|
+
const names = sources.map((source) => source.getName());
|
|
722
|
+
const middlewares = sources.map((source) => source.assetsMiddleware);
|
|
723
|
+
const inclusive = [];
|
|
724
|
+
const wrapped = middlewares.map((middleware, i) => (async (ctx, next) => {
|
|
725
|
+
const start = Date.now();
|
|
726
|
+
try {
|
|
727
|
+
return await middleware(ctx, next);
|
|
728
|
+
}
|
|
729
|
+
finally {
|
|
730
|
+
inclusive[i] = Date.now() - start;
|
|
731
|
+
}
|
|
732
|
+
}));
|
|
733
|
+
const chain = wrapped.reduceRight((next, middleware) => async (ctx) => {
|
|
637
734
|
try {
|
|
638
735
|
return await middleware(ctx, next);
|
|
639
736
|
}
|
|
@@ -647,33 +744,16 @@ async function _AssetsController_executeMiddlewares(middlewares, request, initia
|
|
|
647
744
|
response: initialResponse,
|
|
648
745
|
getAssetsState: () => this.state,
|
|
649
746
|
});
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
if (!availableChains || availableChains.size === 0) {
|
|
658
|
-
continue;
|
|
659
|
-
}
|
|
660
|
-
const chainsForThisSource = [];
|
|
661
|
-
for (const chainId of remainingChains) {
|
|
662
|
-
// Check if this chain is available on this source
|
|
663
|
-
if (availableChains.has(chainId)) {
|
|
664
|
-
chainsForThisSource.push(chainId);
|
|
665
|
-
remainingChains.delete(chainId);
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
if (chainsForThisSource.length > 0) {
|
|
669
|
-
assignment.set(sourceId, chainsForThisSource);
|
|
670
|
-
log('Assigned chains to data source', {
|
|
671
|
-
sourceId,
|
|
672
|
-
chains: chainsForThisSource,
|
|
673
|
-
});
|
|
747
|
+
const durationByDataSource = {};
|
|
748
|
+
for (let i = 0; i < inclusive.length; i++) {
|
|
749
|
+
const nextInc = i + 1 < inclusive.length ? (inclusive[i + 1] ?? 0) : 0;
|
|
750
|
+
const exclusive = Math.max(0, (inclusive[i] ?? 0) - nextInc);
|
|
751
|
+
const name = names[i];
|
|
752
|
+
if (name !== undefined) {
|
|
753
|
+
durationByDataSource[name] = exclusive;
|
|
674
754
|
}
|
|
675
755
|
}
|
|
676
|
-
return
|
|
756
|
+
return { response: result.response, durationByDataSource };
|
|
677
757
|
}, _AssetsController_updateState =
|
|
678
758
|
// ============================================================================
|
|
679
759
|
// STATE MANAGEMENT
|
|
@@ -692,12 +772,12 @@ async function _AssetsController_updateState(response) {
|
|
|
692
772
|
const changedMetadata = [];
|
|
693
773
|
this.update((state) => {
|
|
694
774
|
// Use type assertions to avoid deep type instantiation issues with Immer Draft types
|
|
695
|
-
const metadata = state.
|
|
775
|
+
const metadata = state.assetsInfo;
|
|
696
776
|
const balances = state.assetsBalance;
|
|
697
777
|
const prices = state.assetsPrice;
|
|
698
|
-
if (normalizedResponse.
|
|
699
|
-
for (const [key, value] of Object.entries(normalizedResponse.
|
|
700
|
-
if (!(0, lodash_1.isEqual)(previousState.
|
|
778
|
+
if (normalizedResponse.assetsInfo) {
|
|
779
|
+
for (const [key, value] of Object.entries(normalizedResponse.assetsInfo)) {
|
|
780
|
+
if (!(0, lodash_1.isEqual)(previousState.assetsInfo[key], value)) {
|
|
701
781
|
changedMetadata.push(key);
|
|
702
782
|
}
|
|
703
783
|
metadata[key] = value;
|
|
@@ -802,7 +882,7 @@ async function _AssetsController_updateState(response) {
|
|
|
802
882
|
const accountBalances = this.state.assetsBalance[account.id] ?? {};
|
|
803
883
|
for (const [assetId, balance] of Object.entries(accountBalances)) {
|
|
804
884
|
const typedAssetId = assetId;
|
|
805
|
-
const metadataRaw = this.state.
|
|
885
|
+
const metadataRaw = this.state.assetsInfo[typedAssetId];
|
|
806
886
|
// Skip assets without metadata
|
|
807
887
|
if (!metadataRaw) {
|
|
808
888
|
continue;
|
|
@@ -867,98 +947,112 @@ async function _AssetsController_updateState(response) {
|
|
|
867
947
|
selectedAccountCount: __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length,
|
|
868
948
|
enabledChainCount: __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size,
|
|
869
949
|
});
|
|
870
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m",
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
});
|
|
878
|
-
}
|
|
950
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
951
|
+
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
952
|
+
chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
|
|
953
|
+
forceUpdate: true,
|
|
954
|
+
}).catch((error) => {
|
|
955
|
+
log('Failed to fetch assets', error);
|
|
956
|
+
});
|
|
879
957
|
}, _AssetsController_stop = function _AssetsController_stop() {
|
|
880
958
|
log('Stopping asset tracking', {
|
|
881
959
|
activeSubscriptionCount: __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").size,
|
|
882
960
|
hasPriceSubscription: __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").has('ds:PriceDataSource'),
|
|
883
961
|
});
|
|
962
|
+
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, false, "f");
|
|
884
963
|
// Stop price subscription first (uses direct messenger call)
|
|
885
964
|
this.unsubscribeAssetsPrice();
|
|
886
965
|
// Stop balance subscriptions by properly notifying data sources via messenger
|
|
887
|
-
// This ensures data sources stop their polling timers
|
|
888
|
-
//
|
|
966
|
+
// This ensures data sources stop their polling timers.
|
|
967
|
+
// Use #allBalanceDataSources + staked balance source so we unsubscribe from
|
|
968
|
+
// every source that may have been subscribed.
|
|
969
|
+
const allSources = [
|
|
970
|
+
...__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_allBalanceDataSources_get),
|
|
971
|
+
__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
|
|
972
|
+
];
|
|
889
973
|
const subscriptionKeys = [...__classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").keys()];
|
|
890
974
|
for (const subscriptionKey of subscriptionKeys) {
|
|
891
|
-
// Extract sourceId from subscription key (format: "ds:${sourceId}")
|
|
892
975
|
if (subscriptionKey.startsWith('ds:')) {
|
|
893
976
|
const sourceId = subscriptionKey.slice(3);
|
|
894
|
-
|
|
977
|
+
const source = allSources.find((ds) => ds.getName() === sourceId);
|
|
978
|
+
if (source) {
|
|
979
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_unsubscribeDataSource).call(this, source);
|
|
980
|
+
}
|
|
895
981
|
}
|
|
896
982
|
}
|
|
897
983
|
__classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").clear();
|
|
898
|
-
},
|
|
984
|
+
}, _AssetsController_subscribeAssets = function _AssetsController_subscribeAssets() {
|
|
899
985
|
if (__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length === 0) {
|
|
900
986
|
return;
|
|
901
987
|
}
|
|
902
988
|
// Subscribe to balance updates (batched by data source)
|
|
903
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssetsBalance).call(this)
|
|
989
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssetsBalance).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), [
|
|
990
|
+
...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f"),
|
|
991
|
+
]);
|
|
992
|
+
// Subscribe to staked balance updates (separate from regular balance chain-claiming)
|
|
993
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeStakedBalance).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), [
|
|
994
|
+
...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f"),
|
|
995
|
+
]);
|
|
904
996
|
// Subscribe to price updates for all assets held by selected accounts
|
|
905
997
|
this.subscribeAssetsPrice(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")]);
|
|
906
|
-
}, _AssetsController_subscribeAssetsBalance = function _AssetsController_subscribeAssetsBalance() {
|
|
907
|
-
|
|
908
|
-
const chainToAccounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildChainToAccountsMap).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), __classPrivateFieldGet(this, _AssetsController_enabledChains, "f"));
|
|
909
|
-
// Step 2: Split by data source active chains (ordered by priority)
|
|
910
|
-
// Get all chains that need to be subscribed
|
|
998
|
+
}, _AssetsController_subscribeAssetsBalance = function _AssetsController_subscribeAssetsBalance(accounts, chainIds) {
|
|
999
|
+
const chainToAccounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildChainToAccountsMap).call(this, accounts, new Set(chainIds));
|
|
911
1000
|
const remainingChains = new Set(chainToAccounts.keys());
|
|
912
|
-
//
|
|
913
|
-
const
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
continue;
|
|
1001
|
+
// When basic functionality is on (getter true), use all balance data sources; when off (getter false), RPC only.
|
|
1002
|
+
const balanceDataSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
1003
|
+
? __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_allBalanceDataSources_get)
|
|
1004
|
+
: [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
|
|
1005
|
+
for (const source of balanceDataSources) {
|
|
1006
|
+
const availableChains = new Set(source.getActiveChainsSync());
|
|
1007
|
+
const assignedChains = [];
|
|
1008
|
+
for (const chainId of remainingChains) {
|
|
1009
|
+
if (availableChains.has(chainId)) {
|
|
1010
|
+
assignedChains.push(chainId);
|
|
1011
|
+
remainingChains.delete(chainId);
|
|
1012
|
+
}
|
|
925
1013
|
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
if (accountsForSource.length === 0) {
|
|
1014
|
+
if (assignedChains.length === 0) {
|
|
1015
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_unsubscribeDataSource).call(this, source);
|
|
929
1016
|
continue;
|
|
930
1017
|
}
|
|
931
|
-
|
|
932
|
-
|
|
1018
|
+
const seenIds = new Set();
|
|
1019
|
+
const accountsForSource = assignedChains
|
|
1020
|
+
.flatMap((chainId) => chainToAccounts.get(chainId) ?? [])
|
|
1021
|
+
.filter((account) => !seenIds.has(account.id) && (seenIds.add(account.id), true));
|
|
1022
|
+
if (accountsForSource.length > 0) {
|
|
1023
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeDataSource).call(this, source, accountsForSource, assignedChains);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
}, _AssetsController_subscribeStakedBalance = function _AssetsController_subscribeStakedBalance(accounts, chainIds) {
|
|
1027
|
+
const source = __classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f");
|
|
1028
|
+
if (!source) {
|
|
1029
|
+
return;
|
|
933
1030
|
}
|
|
1031
|
+
const availableChains = new Set(source.getActiveChainsSync());
|
|
1032
|
+
const assignedChains = chainIds.filter((chainId) => availableChains.has(chainId));
|
|
1033
|
+
if (assignedChains.length === 0) {
|
|
1034
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_unsubscribeDataSource).call(this, source);
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeDataSource).call(this, source, accounts, assignedChains);
|
|
934
1038
|
}, _AssetsController_buildChainToAccountsMap = function _AssetsController_buildChainToAccountsMap(accounts, chainsToSubscribe) {
|
|
935
1039
|
const chainToAccounts = new Map();
|
|
936
1040
|
for (const account of accounts) {
|
|
937
|
-
const
|
|
938
|
-
for (const chainId of accountChains) {
|
|
1041
|
+
for (const chainId of __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account)) {
|
|
939
1042
|
if (!chainsToSubscribe.has(chainId)) {
|
|
940
1043
|
continue;
|
|
941
1044
|
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
}
|
|
947
|
-
return chainToAccounts;
|
|
948
|
-
}, _AssetsController_getAccountsForChains = function _AssetsController_getAccountsForChains(chains, chainToAccounts) {
|
|
949
|
-
const accountIds = new Set();
|
|
950
|
-
const accounts = [];
|
|
951
|
-
for (const chainId of chains) {
|
|
952
|
-
const chainAccounts = chainToAccounts.get(chainId) ?? [];
|
|
953
|
-
for (const account of chainAccounts) {
|
|
954
|
-
if (!accountIds.has(account.id)) {
|
|
955
|
-
accountIds.add(account.id);
|
|
956
|
-
accounts.push(account);
|
|
1045
|
+
let list = chainToAccounts.get(chainId);
|
|
1046
|
+
if (!list) {
|
|
1047
|
+
list = [];
|
|
1048
|
+
chainToAccounts.set(chainId, list);
|
|
957
1049
|
}
|
|
1050
|
+
list.push(account);
|
|
958
1051
|
}
|
|
959
1052
|
}
|
|
960
|
-
return
|
|
961
|
-
},
|
|
1053
|
+
return chainToAccounts;
|
|
1054
|
+
}, _AssetsController_subscribeDataSource = function _AssetsController_subscribeDataSource(source, accounts, chains) {
|
|
1055
|
+
const sourceId = source.getName();
|
|
962
1056
|
const subscriptionKey = `ds:${sourceId}`;
|
|
963
1057
|
const existingSubscription = __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").get(subscriptionKey);
|
|
964
1058
|
const isUpdate = existingSubscription !== undefined;
|
|
@@ -969,68 +1063,72 @@ async function _AssetsController_updateState(response) {
|
|
|
969
1063
|
accountCount: accounts.length,
|
|
970
1064
|
chainCount: chains.length,
|
|
971
1065
|
});
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
}
|
|
987
|
-
catch (error) {
|
|
988
|
-
console.error(`[AssetsController] Failed to subscribe to '${sourceId}':`, error);
|
|
989
|
-
}
|
|
990
|
-
})().catch(console.error);
|
|
1066
|
+
const subscribeReq = {
|
|
1067
|
+
request: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chains, {
|
|
1068
|
+
assetTypes: ['fungible'],
|
|
1069
|
+
dataTypes: ['balance'],
|
|
1070
|
+
updateInterval: __classPrivateFieldGet(this, _AssetsController_defaultUpdateInterval, "f"),
|
|
1071
|
+
}),
|
|
1072
|
+
subscriptionId: subscriptionKey,
|
|
1073
|
+
isUpdate,
|
|
1074
|
+
onAssetsUpdate: (response) => this.handleAssetsUpdate(response, sourceId),
|
|
1075
|
+
getAssetsState: () => this.state,
|
|
1076
|
+
};
|
|
1077
|
+
source.subscribe(subscribeReq).catch((error) => {
|
|
1078
|
+
console.error(`[AssetsController] Failed to subscribe to '${sourceId}':`, error);
|
|
1079
|
+
});
|
|
991
1080
|
// Track subscription
|
|
992
1081
|
const subscription = {
|
|
993
1082
|
chains,
|
|
994
1083
|
accountId: subscriptionKey,
|
|
995
1084
|
assetTypes: ['fungible'],
|
|
996
|
-
dataTypes: ['balance'
|
|
1085
|
+
dataTypes: ['balance'],
|
|
997
1086
|
unsubscribe: () => {
|
|
998
1087
|
__classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").delete(subscriptionKey);
|
|
999
1088
|
},
|
|
1000
1089
|
};
|
|
1001
1090
|
__classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").set(subscriptionKey, subscription);
|
|
1002
|
-
}, _AssetsController_unsubscribeDataSource = function _AssetsController_unsubscribeDataSource(
|
|
1003
|
-
const subscriptionKey = `ds:${
|
|
1091
|
+
}, _AssetsController_unsubscribeDataSource = function _AssetsController_unsubscribeDataSource(source) {
|
|
1092
|
+
const subscriptionKey = `ds:${source.getName()}`;
|
|
1004
1093
|
const existingSubscription = __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").get(subscriptionKey);
|
|
1005
1094
|
if (existingSubscription) {
|
|
1006
|
-
|
|
1007
|
-
(async () => {
|
|
1008
|
-
try {
|
|
1009
|
-
await this.messenger.call(`${sourceId}:unsubscribe`, subscriptionKey);
|
|
1010
|
-
}
|
|
1011
|
-
catch {
|
|
1012
|
-
// Ignore errors - source may not have been subscribed
|
|
1013
|
-
}
|
|
1014
|
-
})().catch(() => {
|
|
1015
|
-
// Ignore errors - source may not have been subscribed
|
|
1016
|
-
});
|
|
1095
|
+
source.unsubscribe(subscriptionKey).catch(() => undefined);
|
|
1017
1096
|
existingSubscription.unsubscribe();
|
|
1018
1097
|
}
|
|
1098
|
+
}, _AssetsController_buildDataRequest = function _AssetsController_buildDataRequest(accounts, chainIds, partial = {}) {
|
|
1099
|
+
const chainIdSet = new Set(chainIds);
|
|
1100
|
+
const accountsWithSupportedChains = accounts.map((account) => ({
|
|
1101
|
+
account,
|
|
1102
|
+
supportedChains: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account).filter((chain) => chainIdSet.has(chain)),
|
|
1103
|
+
}));
|
|
1104
|
+
return {
|
|
1105
|
+
accountsWithSupportedChains,
|
|
1106
|
+
chainIds,
|
|
1107
|
+
...partial,
|
|
1108
|
+
};
|
|
1019
1109
|
}, _AssetsController_getEnabledChainsForAccount = function _AssetsController_getEnabledChainsForAccount(account) {
|
|
1020
1110
|
// Account scopes are CAIP-2 chain IDs like "eip155:1", "solana:mainnet", "bip122:..."
|
|
1021
1111
|
const scopes = account.scopes ?? [];
|
|
1022
1112
|
const result = [];
|
|
1023
1113
|
for (const scope of scopes) {
|
|
1024
|
-
const
|
|
1114
|
+
const scopeStr = scope;
|
|
1115
|
+
if (!(0, utils_1.isCaipChainId)(scopeStr)) {
|
|
1116
|
+
result.push(scope);
|
|
1117
|
+
continue;
|
|
1118
|
+
}
|
|
1119
|
+
const { namespace, reference } = (0, utils_1.parseCaipChainId)(scopeStr);
|
|
1025
1120
|
// Wildcard scope (e.g., "eip155:0" means all enabled chains in that namespace)
|
|
1026
1121
|
if (reference === '0') {
|
|
1027
1122
|
for (const chain of __classPrivateFieldGet(this, _AssetsController_enabledChains, "f")) {
|
|
1028
|
-
if (
|
|
1029
|
-
|
|
1123
|
+
if ((0, utils_1.isCaipChainId)(chain)) {
|
|
1124
|
+
const chainParsed = (0, utils_1.parseCaipChainId)(chain);
|
|
1125
|
+
if (chainParsed.namespace === namespace) {
|
|
1126
|
+
result.push(chain);
|
|
1127
|
+
}
|
|
1030
1128
|
}
|
|
1031
1129
|
}
|
|
1032
1130
|
}
|
|
1033
|
-
else if (namespace === 'eip155' &&
|
|
1131
|
+
else if (namespace === 'eip155' && (0, utils_1.isStrictHexString)(reference)) {
|
|
1034
1132
|
// Normalize hex to decimal for EIP155
|
|
1035
1133
|
result.push(`eip155:${parseInt(reference, 16)}`);
|
|
1036
1134
|
}
|
|
@@ -1050,7 +1148,7 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
1050
1148
|
accountIds: accounts.map((a) => a.id),
|
|
1051
1149
|
});
|
|
1052
1150
|
// Subscribe and fetch for the new account group
|
|
1053
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m",
|
|
1151
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1054
1152
|
if (accounts.length > 0) {
|
|
1055
1153
|
await this.getAssets(accounts, {
|
|
1056
1154
|
chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
|
|
@@ -1084,7 +1182,7 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
1084
1182
|
// Users may want to see historical balances even if the network is currently disabled.
|
|
1085
1183
|
// The data will simply not be updated until the network is re-enabled.
|
|
1086
1184
|
// Refresh subscriptions for new chain set
|
|
1087
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m",
|
|
1185
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1088
1186
|
// Do one-time fetch for newly enabled chains
|
|
1089
1187
|
if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
|
|
1090
1188
|
await this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
@@ -1092,28 +1190,5 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
1092
1190
|
forceUpdate: true,
|
|
1093
1191
|
});
|
|
1094
1192
|
}
|
|
1095
|
-
}, _AssetsController_handleSubscriptionUpdate =
|
|
1096
|
-
/**
|
|
1097
|
-
* Handle an async update from a data source subscription.
|
|
1098
|
-
* Enriches response with token metadata before updating state.
|
|
1099
|
-
*
|
|
1100
|
-
* @param response - The data response from the data source.
|
|
1101
|
-
* @param _sourceId - The source ID (unused but kept for logging context).
|
|
1102
|
-
* @param request - Optional original request for context.
|
|
1103
|
-
*/
|
|
1104
|
-
async function _AssetsController_handleSubscriptionUpdate(response, _sourceId, request) {
|
|
1105
|
-
// Run through enrichment middlewares (Event Stack: Detection → Token → Price)
|
|
1106
|
-
// Include 'metadata' in dataTypes so TokenDataSource runs to enrich detected assets
|
|
1107
|
-
const enrichedResponse = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
|
|
1108
|
-
this.messenger.call('DetectionMiddleware:getAssetsMiddleware'),
|
|
1109
|
-
this.messenger.call('TokenDataSource:getAssetsMiddleware'),
|
|
1110
|
-
this.messenger.call('PriceDataSource:getAssetsMiddleware'),
|
|
1111
|
-
], request ?? {
|
|
1112
|
-
accounts: [],
|
|
1113
|
-
chainIds: [],
|
|
1114
|
-
dataTypes: ['balance', 'metadata', 'price'],
|
|
1115
|
-
}, response);
|
|
1116
|
-
// Update state
|
|
1117
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, enrichedResponse);
|
|
1118
1193
|
};
|
|
1119
1194
|
//# sourceMappingURL=AssetsController.cjs.map
|