@metamask/assets-controller 2.0.2 → 2.2.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.map +1 -1
- package/dist/AssetsController-method-action-types.d.cts +21 -1
- package/dist/AssetsController-method-action-types.d.cts.map +1 -1
- package/dist/AssetsController-method-action-types.d.mts +21 -1
- package/dist/AssetsController-method-action-types.d.mts.map +1 -1
- package/dist/AssetsController-method-action-types.mjs.map +1 -1
- package/dist/AssetsController.cjs +284 -89
- package/dist/AssetsController.cjs.map +1 -1
- package/dist/AssetsController.d.cts +59 -17
- package/dist/AssetsController.d.cts.map +1 -1
- package/dist/AssetsController.d.mts +59 -17
- package/dist/AssetsController.d.mts.map +1 -1
- package/dist/AssetsController.mjs +284 -89
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/AbstractDataSource.cjs.map +1 -1
- package/dist/data-sources/AbstractDataSource.d.cts +3 -3
- package/dist/data-sources/AbstractDataSource.d.cts.map +1 -1
- package/dist/data-sources/AbstractDataSource.d.mts +3 -3
- package/dist/data-sources/AbstractDataSource.d.mts.map +1 -1
- package/dist/data-sources/AbstractDataSource.mjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.cjs +2 -1
- package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.mjs +2 -1
- package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.cjs +18 -6
- package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.cts +2 -2
- package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.mts +2 -2
- package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.mjs +15 -6
- package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
- package/dist/data-sources/PriceDataSource.cjs +20 -14
- package/dist/data-sources/PriceDataSource.cjs.map +1 -1
- package/dist/data-sources/PriceDataSource.d.cts +2 -2
- package/dist/data-sources/PriceDataSource.d.cts.map +1 -1
- package/dist/data-sources/PriceDataSource.d.mts +2 -2
- package/dist/data-sources/PriceDataSource.d.mts.map +1 -1
- package/dist/data-sources/PriceDataSource.mjs +20 -14
- package/dist/data-sources/PriceDataSource.mjs.map +1 -1
- package/dist/data-sources/RpcDataSource.cjs +23 -4
- package/dist/data-sources/RpcDataSource.cjs.map +1 -1
- package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
- package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
- package/dist/data-sources/RpcDataSource.mjs +23 -4
- package/dist/data-sources/RpcDataSource.mjs.map +1 -1
- package/dist/data-sources/SnapDataSource.cjs +3 -2
- package/dist/data-sources/SnapDataSource.cjs.map +1 -1
- package/dist/data-sources/SnapDataSource.d.cts.map +1 -1
- package/dist/data-sources/SnapDataSource.d.mts.map +1 -1
- package/dist/data-sources/SnapDataSource.mjs +3 -2
- package/dist/data-sources/SnapDataSource.mjs.map +1 -1
- package/dist/data-sources/StakedBalanceDataSource.cjs +41 -3
- package/dist/data-sources/StakedBalanceDataSource.cjs.map +1 -1
- package/dist/data-sources/StakedBalanceDataSource.d.cts.map +1 -1
- package/dist/data-sources/StakedBalanceDataSource.d.mts.map +1 -1
- package/dist/data-sources/StakedBalanceDataSource.mjs +41 -3
- package/dist/data-sources/StakedBalanceDataSource.mjs.map +1 -1
- package/dist/data-sources/TokenDataSource.cjs +1 -0
- package/dist/data-sources/TokenDataSource.cjs.map +1 -1
- package/dist/data-sources/TokenDataSource.d.cts.map +1 -1
- package/dist/data-sources/TokenDataSource.d.mts.map +1 -1
- package/dist/data-sources/TokenDataSource.mjs +1 -0
- package/dist/data-sources/TokenDataSource.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.cjs.map +1 -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.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.mjs.map +1 -1
- package/dist/index.cjs +3 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +5 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/middlewares/DetectionMiddleware.cjs +44 -27
- package/dist/middlewares/DetectionMiddleware.cjs.map +1 -1
- package/dist/middlewares/DetectionMiddleware.d.cts +15 -9
- package/dist/middlewares/DetectionMiddleware.d.cts.map +1 -1
- package/dist/middlewares/DetectionMiddleware.d.mts +15 -9
- package/dist/middlewares/DetectionMiddleware.d.mts.map +1 -1
- package/dist/middlewares/DetectionMiddleware.mjs +44 -27
- package/dist/middlewares/DetectionMiddleware.mjs.map +1 -1
- package/dist/middlewares/ParallelMiddleware.cjs +216 -0
- package/dist/middlewares/ParallelMiddleware.cjs.map +1 -0
- package/dist/middlewares/ParallelMiddleware.d.cts +45 -0
- package/dist/middlewares/ParallelMiddleware.d.cts.map +1 -0
- package/dist/middlewares/ParallelMiddleware.d.mts +45 -0
- package/dist/middlewares/ParallelMiddleware.d.mts.map +1 -0
- package/dist/middlewares/ParallelMiddleware.mjs +214 -0
- package/dist/middlewares/ParallelMiddleware.mjs.map +1 -0
- package/dist/middlewares/index.cjs +5 -1
- package/dist/middlewares/index.cjs.map +1 -1
- package/dist/middlewares/index.d.cts +2 -0
- package/dist/middlewares/index.d.cts.map +1 -1
- package/dist/middlewares/index.d.mts +2 -0
- package/dist/middlewares/index.d.mts.map +1 -1
- package/dist/middlewares/index.mjs +1 -0
- package/dist/middlewares/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +16 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +16 -0
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/formatExchangeRatesForBridge.cjs +123 -0
- package/dist/utils/formatExchangeRatesForBridge.cjs.map +1 -0
- package/dist/utils/formatExchangeRatesForBridge.d.cts +65 -0
- package/dist/utils/formatExchangeRatesForBridge.d.cts.map +1 -0
- package/dist/utils/formatExchangeRatesForBridge.d.mts +65 -0
- package/dist/utils/formatExchangeRatesForBridge.d.mts.map +1 -0
- package/dist/utils/formatExchangeRatesForBridge.mjs +119 -0
- package/dist/utils/formatExchangeRatesForBridge.mjs.map +1 -0
- package/dist/utils/index.cjs +8 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +4 -0
- package/dist/utils/index.d.cts.map +1 -0
- package/dist/utils/index.d.mts +4 -0
- package/dist/utils/index.d.mts.map +1 -0
- package/dist/utils/index.mjs +3 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/{utils.cjs → utils/normalizeAssetId.cjs} +1 -1
- package/dist/utils/normalizeAssetId.cjs.map +1 -0
- package/dist/{utils.d.mts → utils/normalizeAssetId.d.cts} +2 -2
- package/dist/utils/normalizeAssetId.d.cts.map +1 -0
- package/dist/{utils.d.cts → utils/normalizeAssetId.d.mts} +2 -2
- package/dist/utils/normalizeAssetId.d.mts.map +1 -0
- package/dist/{utils.mjs → utils/normalizeAssetId.mjs} +1 -1
- package/dist/utils/normalizeAssetId.mjs.map +1 -0
- package/package.json +6 -5
- package/dist/utils.cjs.map +0 -1
- package/dist/utils.d.cts.map +0 -1
- package/dist/utils.d.mts.map +0 -1
- package/dist/utils.mjs.map +0 -1
|
@@ -13,10 +13,11 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
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_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;
|
|
16
|
+
var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trackMetaMetricsEvent, _AssetsController_firstInitFetchReported, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _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_onActiveChainsUpdated, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_updateActive, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_ensureNativeBalancesDefaultZero, _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");
|
|
20
|
+
const client_controller_1 = require("@metamask/client-controller");
|
|
20
21
|
const utils_1 = require("@metamask/utils");
|
|
21
22
|
const async_mutex_1 = require("async-mutex");
|
|
22
23
|
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
@@ -30,7 +31,8 @@ const StakedBalanceDataSource_1 = require("./data-sources/StakedBalanceDataSourc
|
|
|
30
31
|
const TokenDataSource_1 = require("./data-sources/TokenDataSource.cjs");
|
|
31
32
|
const logger_1 = require("./logger.cjs");
|
|
32
33
|
const DetectionMiddleware_1 = require("./middlewares/DetectionMiddleware.cjs");
|
|
33
|
-
const
|
|
34
|
+
const ParallelMiddleware_1 = require("./middlewares/ParallelMiddleware.cjs");
|
|
35
|
+
const utils_2 = require("./utils/index.cjs");
|
|
34
36
|
// ============================================================================
|
|
35
37
|
// CONTROLLER CONSTANTS
|
|
36
38
|
// ============================================================================
|
|
@@ -41,6 +43,7 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
41
43
|
'getAssetsBalance',
|
|
42
44
|
'getAssetMetadata',
|
|
43
45
|
'getAssetsPrice',
|
|
46
|
+
'getExchangeRatesForBridge',
|
|
44
47
|
'addCustomAsset',
|
|
45
48
|
'removeCustomAsset',
|
|
46
49
|
'getCustomAssets',
|
|
@@ -62,6 +65,7 @@ function getDefaultAssetsControllerState() {
|
|
|
62
65
|
assetsPrice: {},
|
|
63
66
|
customAssets: {},
|
|
64
67
|
assetPreferences: {},
|
|
68
|
+
selectedCurrency: 'usd',
|
|
65
69
|
};
|
|
66
70
|
}
|
|
67
71
|
exports.getDefaultAssetsControllerState = getDefaultAssetsControllerState;
|
|
@@ -99,6 +103,12 @@ const stateMetadata = {
|
|
|
99
103
|
includeInDebugSnapshot: false,
|
|
100
104
|
usedInUi: true,
|
|
101
105
|
},
|
|
106
|
+
selectedCurrency: {
|
|
107
|
+
persist: true,
|
|
108
|
+
includeInStateLogs: false,
|
|
109
|
+
includeInDebugSnapshot: false,
|
|
110
|
+
usedInUi: true,
|
|
111
|
+
},
|
|
102
112
|
};
|
|
103
113
|
// ============================================================================
|
|
104
114
|
// HELPER FUNCTIONS
|
|
@@ -152,6 +162,9 @@ function normalizeResponse(response) {
|
|
|
152
162
|
if (response.errors) {
|
|
153
163
|
normalized.errors = { ...response.errors };
|
|
154
164
|
}
|
|
165
|
+
if (response.updateMode) {
|
|
166
|
+
normalized.updateMode = response.updateMode;
|
|
167
|
+
}
|
|
155
168
|
return normalized;
|
|
156
169
|
}
|
|
157
170
|
// ============================================================================
|
|
@@ -173,8 +186,10 @@ function normalizeResponse(response) {
|
|
|
173
186
|
* based on which chains they support. When active chains change, the controller
|
|
174
187
|
* dynamically adjusts subscriptions.
|
|
175
188
|
*
|
|
176
|
-
* 4. **Keyring Lifecycle**:
|
|
177
|
-
*
|
|
189
|
+
* 4. **Client + Keyring Lifecycle**: Starts subscriptions only when both the UI is
|
|
190
|
+
* open (ClientController) and the wallet is unlocked (KeyringController).
|
|
191
|
+
* Stops when either the UI closes or the keyring locks. See client-controller
|
|
192
|
+
* README for the combined pattern.
|
|
178
193
|
*
|
|
179
194
|
* ## Architecture
|
|
180
195
|
*
|
|
@@ -204,6 +219,10 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
204
219
|
_AssetsController_trackMetaMetricsEvent.set(this, void 0);
|
|
205
220
|
/** Whether we have already reported first init fetch for this session (reset on #stop). */
|
|
206
221
|
_AssetsController_firstInitFetchReported.set(this, false);
|
|
222
|
+
/** Whether the client (UI) is open. Combined with #keyringUnlocked for #updateActive. */
|
|
223
|
+
_AssetsController_uiOpen.set(this, false);
|
|
224
|
+
/** Whether the keyring is unlocked. Combined with #uiOpen for #updateActive. */
|
|
225
|
+
_AssetsController_keyringUnlocked.set(this, false);
|
|
207
226
|
_AssetsController_controllerMutex.set(this, new async_mutex_1.Mutex());
|
|
208
227
|
/**
|
|
209
228
|
* Active balance subscriptions keyed by account ID.
|
|
@@ -223,36 +242,37 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
223
242
|
_AssetsController_detectionMiddleware.set(this, void 0);
|
|
224
243
|
_AssetsController_tokenDataSource.set(this, void 0);
|
|
225
244
|
_AssetsController_unsubscribeBasicFunctionality.set(this, null);
|
|
245
|
+
_AssetsController_onActiveChainsUpdated.set(this, void 0);
|
|
226
246
|
__classPrivateFieldSet(this, _AssetsController_isEnabled, isEnabled(), "f");
|
|
227
247
|
__classPrivateFieldSet(this, _AssetsController_isBasicFunctionality, isBasicFunctionality ?? (() => true), "f");
|
|
228
248
|
__classPrivateFieldSet(this, _AssetsController_defaultUpdateInterval, defaultUpdateInterval, "f");
|
|
229
249
|
__classPrivateFieldSet(this, _AssetsController_trackMetaMetricsEvent, trackMetaMetricsEvent, "f");
|
|
230
250
|
const rpcConfig = rpcDataSourceConfig ?? {};
|
|
231
|
-
|
|
232
|
-
this.
|
|
233
|
-
};
|
|
251
|
+
__classPrivateFieldSet(this, _AssetsController_onActiveChainsUpdated, (dataSourceName, chains, previousChains) => {
|
|
252
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleActiveChainsUpdate).call(this, dataSourceName, chains, previousChains);
|
|
253
|
+
}, "f");
|
|
234
254
|
__classPrivateFieldSet(this, _AssetsController_backendWebsocketDataSource, new BackendWebsocketDataSource_1.BackendWebsocketDataSource({
|
|
235
255
|
messenger: this.messenger,
|
|
236
256
|
queryApiClient,
|
|
237
|
-
onActiveChainsUpdated,
|
|
257
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
238
258
|
}), "f");
|
|
239
259
|
__classPrivateFieldSet(this, _AssetsController_accountsApiDataSource, new AccountsApiDataSource_1.AccountsApiDataSource({
|
|
240
260
|
queryApiClient,
|
|
241
|
-
onActiveChainsUpdated,
|
|
261
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
242
262
|
...accountsApiDataSourceConfig,
|
|
243
263
|
}), "f");
|
|
244
264
|
__classPrivateFieldSet(this, _AssetsController_snapDataSource, new SnapDataSource_1.SnapDataSource({
|
|
245
265
|
messenger: this.messenger,
|
|
246
|
-
onActiveChainsUpdated,
|
|
266
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
247
267
|
}), "f");
|
|
248
268
|
__classPrivateFieldSet(this, _AssetsController_rpcDataSource, new RpcDataSource_1.RpcDataSource({
|
|
249
269
|
messenger: this.messenger,
|
|
250
|
-
onActiveChainsUpdated,
|
|
270
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
251
271
|
...rpcConfig,
|
|
252
272
|
}), "f");
|
|
253
273
|
__classPrivateFieldSet(this, _AssetsController_stakedBalanceDataSource, new StakedBalanceDataSource_1.StakedBalanceDataSource({
|
|
254
274
|
messenger: this.messenger,
|
|
255
|
-
onActiveChainsUpdated,
|
|
275
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
256
276
|
...stakedBalanceDataSourceConfig,
|
|
257
277
|
}), "f");
|
|
258
278
|
__classPrivateFieldSet(this, _AssetsController_tokenDataSource, new TokenDataSource_1.TokenDataSource({
|
|
@@ -260,6 +280,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
260
280
|
}), "f");
|
|
261
281
|
__classPrivateFieldSet(this, _AssetsController_priceDataSource, new PriceDataSource_1.PriceDataSource({
|
|
262
282
|
queryApiClient,
|
|
283
|
+
getSelectedCurrency: () => this.state.selectedCurrency,
|
|
263
284
|
...priceDataSourceConfig,
|
|
264
285
|
}), "f");
|
|
265
286
|
__classPrivateFieldSet(this, _AssetsController_detectionMiddleware, new DetectionMiddleware_1.DetectionMiddleware(), "f");
|
|
@@ -273,7 +294,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
273
294
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_initializeState).call(this);
|
|
274
295
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeToEvents).call(this);
|
|
275
296
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_registerActionHandlers).call(this);
|
|
276
|
-
// Subscriptions start only
|
|
297
|
+
// Subscriptions start only when both UI is open and keyring unlocked -> #updateActive().
|
|
277
298
|
// Subscribe to basic-functionality changes after construction so a synchronous
|
|
278
299
|
// onChange during subscribe cannot run before data sources are initialized.
|
|
279
300
|
if (subscribeToBasicFunctionalityChange) {
|
|
@@ -283,52 +304,14 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
283
304
|
}
|
|
284
305
|
}
|
|
285
306
|
}
|
|
286
|
-
// ============================================================================
|
|
287
|
-
// DATA SOURCE CHAIN MANAGEMENT
|
|
288
|
-
// ============================================================================
|
|
289
307
|
/**
|
|
290
|
-
*
|
|
291
|
-
* Used
|
|
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).
|
|
308
|
+
* Returns the callback passed to data sources for reporting active chain updates.
|
|
309
|
+
* Used by tests to simulate a data source reporting chain changes.
|
|
295
310
|
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
* @param dataSourceId - The identifier of the data source reporting the change.
|
|
299
|
-
* @param activeChains - Currently active (supported and available) chain IDs for this source.
|
|
300
|
-
* @param previousChains - Previous chains; used to compute added/removed.
|
|
311
|
+
* @returns The onActiveChainsUpdated callback.
|
|
301
312
|
*/
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
log('Data source active chains changed', {
|
|
307
|
-
dataSourceId,
|
|
308
|
-
chainCount: activeChains.length,
|
|
309
|
-
chains: activeChains,
|
|
310
|
-
});
|
|
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));
|
|
315
|
-
if (addedChains.length > 0 || removedChains.length > 0) {
|
|
316
|
-
// Refresh subscriptions to use updated data source availability
|
|
317
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
318
|
-
}
|
|
319
|
-
// If chains were added and we have selected accounts, do one-time fetch
|
|
320
|
-
if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
|
|
321
|
-
const addedEnabledChains = addedChains.filter((chain) => __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").has(chain));
|
|
322
|
-
if (addedEnabledChains.length > 0) {
|
|
323
|
-
log('Fetching balances for newly added chains', { addedEnabledChains });
|
|
324
|
-
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
325
|
-
chainIds: addedEnabledChains,
|
|
326
|
-
forceUpdate: true,
|
|
327
|
-
}).catch((error) => {
|
|
328
|
-
log('Failed to fetch balance for added chains', { error });
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
}
|
|
313
|
+
getOnActiveChainsUpdated() {
|
|
314
|
+
return __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f");
|
|
332
315
|
}
|
|
333
316
|
// ============================================================================
|
|
334
317
|
// PUBLIC API: QUERY METHODS
|
|
@@ -337,6 +320,9 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
337
320
|
const chainIds = options?.chainIds ?? [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")];
|
|
338
321
|
const assetTypes = options?.assetTypes ?? ['fungible'];
|
|
339
322
|
const dataTypes = options?.dataTypes ?? ['balance', 'metadata', 'price'];
|
|
323
|
+
if (accounts.length === 0 || chainIds.length === 0) {
|
|
324
|
+
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
|
|
325
|
+
}
|
|
340
326
|
// Collect custom assets for all requested accounts
|
|
341
327
|
const customAssets = [];
|
|
342
328
|
for (const account of accounts) {
|
|
@@ -350,16 +336,21 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
350
336
|
dataTypes,
|
|
351
337
|
customAssets: customAssets.length > 0 ? customAssets : undefined,
|
|
352
338
|
forceUpdate: true,
|
|
339
|
+
assetsForPriceUpdate: options?.assetsForPriceUpdate,
|
|
353
340
|
});
|
|
354
341
|
const sources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
355
342
|
? [
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
343
|
+
(0, ParallelMiddleware_1.createParallelBalanceMiddleware)([
|
|
344
|
+
__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
|
|
345
|
+
__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"),
|
|
346
|
+
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
|
|
347
|
+
__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
|
|
348
|
+
]),
|
|
360
349
|
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
361
|
-
|
|
362
|
-
|
|
350
|
+
(0, ParallelMiddleware_1.createParallelMiddleware)([
|
|
351
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
352
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
353
|
+
]),
|
|
363
354
|
]
|
|
364
355
|
: [
|
|
365
356
|
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
|
|
@@ -367,7 +358,12 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
367
358
|
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
368
359
|
];
|
|
369
360
|
const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, sources, request);
|
|
370
|
-
|
|
361
|
+
// Default to 'merge' when fetching a subset of chains so we don't wipe
|
|
362
|
+
// balances from chains that weren't included in this fetch.
|
|
363
|
+
const isPartialChainFetch = options?.chainIds !== undefined &&
|
|
364
|
+
options.chainIds.length < __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size;
|
|
365
|
+
const updateMode = options?.updateMode ?? (isPartialChainFetch ? 'merge' : 'full');
|
|
366
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...response, updateMode });
|
|
371
367
|
if (__classPrivateFieldGet(this, _AssetsController_trackMetaMetricsEvent, "f") && !__classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")) {
|
|
372
368
|
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
|
|
373
369
|
const durationMs = Date.now() - startTime;
|
|
@@ -378,7 +374,8 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
378
374
|
});
|
|
379
375
|
}
|
|
380
376
|
}
|
|
381
|
-
|
|
377
|
+
const result = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
|
|
378
|
+
return result;
|
|
382
379
|
}
|
|
383
380
|
async getAssetsBalance(accounts, options) {
|
|
384
381
|
// Reuse getAssets with dataTypes: ['balance'] only
|
|
@@ -421,6 +418,28 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
421
418
|
}
|
|
422
419
|
return result;
|
|
423
420
|
}
|
|
421
|
+
/**
|
|
422
|
+
* Returns exchange rates in the format expected by the bridge controller
|
|
423
|
+
* (conversionRates, currencyRates, marketData, currentCurrency) so that
|
|
424
|
+
* when useAssetsControllerForRates is true the bridge can use a single
|
|
425
|
+
* action instead of MultichainAssetsRatesController, TokenRatesController,
|
|
426
|
+
* and CurrencyRateController.
|
|
427
|
+
*
|
|
428
|
+
* @param options - Optional options for bridge rate conversion.
|
|
429
|
+
* @param options.usdToSelectedCurrencyRate - When selectedCurrency is not 'usd', pass 1 USD = this many units of selected currency so that currencyRates and conversionRates use correct user-currency vs USD values; otherwise the bridge USD conversion will be wrong for non-USD currencies.
|
|
430
|
+
* @returns Bridge-compatible exchange rate state derived from assetsPrice and selectedCurrency.
|
|
431
|
+
*/
|
|
432
|
+
getExchangeRatesForBridge(options) {
|
|
433
|
+
const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
|
|
434
|
+
const { networkConfigurationsByChainId } = this.messenger.call('NetworkController:getState');
|
|
435
|
+
return (0, utils_2.formatExchangeRatesForBridge)({
|
|
436
|
+
assetsPrice: this.state.assetsPrice,
|
|
437
|
+
selectedCurrency: this.state.selectedCurrency,
|
|
438
|
+
nativeAssetIdentifiers,
|
|
439
|
+
networkConfigurationsByChainId,
|
|
440
|
+
usdToSelectedCurrencyRate: options?.usdToSelectedCurrencyRate,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
424
443
|
// ============================================================================
|
|
425
444
|
// CUSTOM ASSETS MANAGEMENT
|
|
426
445
|
// ============================================================================
|
|
@@ -429,10 +448,15 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
429
448
|
* Custom assets are included in subscription and fetch operations.
|
|
430
449
|
* Adding a custom asset also unhides it if it was previously hidden.
|
|
431
450
|
*
|
|
451
|
+
* When `pendingMetadata` is provided (e.g. from the extension's pending-tokens
|
|
452
|
+
* flow), the token metadata is persisted immediately into `assetsInfo` so the
|
|
453
|
+
* UI can render it without waiting for the next pipeline fetch.
|
|
454
|
+
*
|
|
432
455
|
* @param accountId - The account ID to add the custom asset for.
|
|
433
456
|
* @param assetId - The CAIP-19 asset ID to add.
|
|
457
|
+
* @param pendingMetadata - Optional token metadata from the UI (pendingTokens format).
|
|
434
458
|
*/
|
|
435
|
-
async addCustomAsset(accountId, assetId) {
|
|
459
|
+
async addCustomAsset(accountId, assetId, pendingMetadata) {
|
|
436
460
|
const normalizedAssetId = (0, utils_2.normalizeAssetId)(assetId);
|
|
437
461
|
log('Adding custom asset', { accountId, assetId: normalizedAssetId });
|
|
438
462
|
this.update((state) => {
|
|
@@ -452,14 +476,37 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
452
476
|
delete state.assetPreferences[normalizedAssetId];
|
|
453
477
|
}
|
|
454
478
|
}
|
|
479
|
+
// Persist metadata from the UI so the token is immediately renderable
|
|
480
|
+
if (pendingMetadata) {
|
|
481
|
+
const parsed = (0, utils_1.parseCaipAssetType)(normalizedAssetId);
|
|
482
|
+
let tokenType = 'erc20';
|
|
483
|
+
if (parsed.assetNamespace === 'slip44') {
|
|
484
|
+
tokenType = 'native';
|
|
485
|
+
}
|
|
486
|
+
else if (parsed.assetNamespace === 'spl') {
|
|
487
|
+
tokenType = 'spl';
|
|
488
|
+
}
|
|
489
|
+
const assetMetadata = {
|
|
490
|
+
type: tokenType,
|
|
491
|
+
symbol: pendingMetadata.symbol,
|
|
492
|
+
name: pendingMetadata.name,
|
|
493
|
+
decimals: pendingMetadata.decimals,
|
|
494
|
+
image: pendingMetadata.iconUrl,
|
|
495
|
+
aggregators: pendingMetadata.aggregators,
|
|
496
|
+
occurrences: pendingMetadata.occurrences,
|
|
497
|
+
};
|
|
498
|
+
state.assetsInfo[normalizedAssetId] =
|
|
499
|
+
assetMetadata;
|
|
500
|
+
}
|
|
455
501
|
});
|
|
456
|
-
// Fetch data for the newly added custom asset
|
|
502
|
+
// Fetch data for the newly added custom asset (merge to preserve other chains)
|
|
457
503
|
const account = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).find((a) => a.id === accountId);
|
|
458
504
|
if (account) {
|
|
459
505
|
const chainId = extractChainId(normalizedAssetId);
|
|
460
506
|
await this.getAssets([account], {
|
|
461
507
|
chainIds: [chainId],
|
|
462
508
|
forceUpdate: true,
|
|
509
|
+
updateMode: 'merge',
|
|
463
510
|
});
|
|
464
511
|
}
|
|
465
512
|
}
|
|
@@ -530,6 +577,34 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
530
577
|
});
|
|
531
578
|
}
|
|
532
579
|
// ============================================================================
|
|
580
|
+
// CURRENT CURRENCY MANAGEMENT
|
|
581
|
+
// ============================================================================
|
|
582
|
+
/**
|
|
583
|
+
* Set the current currency.
|
|
584
|
+
*
|
|
585
|
+
* @param selectedCurrency - The ISO 4217 currency code to set.
|
|
586
|
+
*/
|
|
587
|
+
setSelectedCurrency(selectedCurrency) {
|
|
588
|
+
const previousCurrency = this.state.selectedCurrency;
|
|
589
|
+
if (previousCurrency === selectedCurrency) {
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
this.update((state) => {
|
|
593
|
+
state.selectedCurrency = selectedCurrency;
|
|
594
|
+
});
|
|
595
|
+
log('Current currency changed', {
|
|
596
|
+
previousCurrency,
|
|
597
|
+
selectedCurrency,
|
|
598
|
+
});
|
|
599
|
+
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
600
|
+
forceUpdate: true,
|
|
601
|
+
dataTypes: ['price'],
|
|
602
|
+
assetsForPriceUpdate: Object.values(this.state.assetsBalance).flatMap((balances) => Object.keys(balances)),
|
|
603
|
+
}).catch((error) => {
|
|
604
|
+
log('Failed to fetch asset prices after current currency change', error);
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
// ============================================================================
|
|
533
608
|
// SUBSCRIPTIONS
|
|
534
609
|
// ============================================================================
|
|
535
610
|
/**
|
|
@@ -607,9 +682,15 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
607
682
|
hasBalance: Boolean(response.assetsBalance),
|
|
608
683
|
hasPrice: Boolean(response.assetsPrice),
|
|
609
684
|
});
|
|
610
|
-
// Run through enrichment middlewares (
|
|
685
|
+
// Run through enrichment middlewares (Detection, then Token + Price in parallel)
|
|
611
686
|
// 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, [
|
|
687
|
+
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
|
|
688
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
689
|
+
(0, ParallelMiddleware_1.createParallelMiddleware)([
|
|
690
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
691
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
692
|
+
]),
|
|
693
|
+
], request ?? {
|
|
613
694
|
accountsWithSupportedChains: [],
|
|
614
695
|
chainIds: [],
|
|
615
696
|
dataTypes: ['balance', 'metadata', 'price'],
|
|
@@ -641,6 +722,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
641
722
|
this.messenger.unregisterActionHandler('AssetsController:getAssetsBalance');
|
|
642
723
|
this.messenger.unregisterActionHandler('AssetsController:getAssetMetadata');
|
|
643
724
|
this.messenger.unregisterActionHandler('AssetsController:getAssetsPrice');
|
|
725
|
+
this.messenger.unregisterActionHandler('AssetsController:getExchangeRatesForBridge');
|
|
644
726
|
this.messenger.unregisterActionHandler('AssetsController:addCustomAsset');
|
|
645
727
|
this.messenger.unregisterActionHandler('AssetsController:removeCustomAsset');
|
|
646
728
|
this.messenger.unregisterActionHandler('AssetsController:getCustomAssets');
|
|
@@ -649,7 +731,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
649
731
|
}
|
|
650
732
|
}
|
|
651
733
|
exports.AssetsController = AssetsController;
|
|
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() {
|
|
734
|
+
_AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trackMetaMetricsEvent = new WeakMap(), _AssetsController_firstInitFetchReported = new WeakMap(), _AssetsController_uiOpen = new WeakMap(), _AssetsController_keyringUnlocked = 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_onActiveChainsUpdated = new WeakMap(), _AssetsController_instances = new WeakSet(), _AssetsController_selectedAccounts_get = function _AssetsController_selectedAccounts_get() {
|
|
653
735
|
return this.messenger.call('AccountTreeController:getAccountsFromSelectedAccountGroup');
|
|
654
736
|
}, _AssetsController_allBalanceDataSources_get = function _AssetsController_allBalanceDataSources_get() {
|
|
655
737
|
return [
|
|
@@ -699,11 +781,60 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
699
781
|
this.messenger.subscribe('NetworkEnablementController:stateChange', ({ enabledNetworkMap }) => {
|
|
700
782
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleEnabledNetworksChanged).call(this, enabledNetworkMap).catch(console.error);
|
|
701
783
|
});
|
|
702
|
-
// Keyring lifecycle:
|
|
703
|
-
this.messenger.subscribe('
|
|
704
|
-
|
|
784
|
+
// Client + Keyring lifecycle: only run when UI is open AND keyring is unlocked
|
|
785
|
+
this.messenger.subscribe('ClientController:stateChange', (isUiOpen) => {
|
|
786
|
+
__classPrivateFieldSet(this, _AssetsController_uiOpen, isUiOpen, "f");
|
|
787
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
788
|
+
}, client_controller_1.clientControllerSelectors.selectIsUiOpen);
|
|
789
|
+
this.messenger.subscribe('KeyringController:unlock', () => {
|
|
790
|
+
__classPrivateFieldSet(this, _AssetsController_keyringUnlocked, true, "f");
|
|
791
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
792
|
+
});
|
|
793
|
+
this.messenger.subscribe('KeyringController:lock', () => {
|
|
794
|
+
__classPrivateFieldSet(this, _AssetsController_keyringUnlocked, false, "f");
|
|
795
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
796
|
+
});
|
|
797
|
+
}, _AssetsController_updateActive = function _AssetsController_updateActive() {
|
|
798
|
+
const shouldRun = __classPrivateFieldGet(this, _AssetsController_uiOpen, "f") && __classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f");
|
|
799
|
+
if (shouldRun) {
|
|
800
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_start).call(this);
|
|
801
|
+
}
|
|
802
|
+
else {
|
|
803
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_stop).call(this);
|
|
804
|
+
}
|
|
705
805
|
}, _AssetsController_registerActionHandlers = function _AssetsController_registerActionHandlers() {
|
|
706
806
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
807
|
+
}, _AssetsController_handleActiveChainsUpdate = function _AssetsController_handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
|
|
808
|
+
if (!__classPrivateFieldGet(this, _AssetsController_isEnabled, "f")) {
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
log('Data source active chains changed', {
|
|
812
|
+
dataSourceId,
|
|
813
|
+
chainCount: activeChains.length,
|
|
814
|
+
chains: activeChains,
|
|
815
|
+
});
|
|
816
|
+
const previous = previousChains;
|
|
817
|
+
const previousSet = new Set(previous);
|
|
818
|
+
const addedChains = activeChains.filter((ch) => !previousSet.has(ch));
|
|
819
|
+
const removedChains = previous.filter((ch) => !activeChains.includes(ch));
|
|
820
|
+
if (addedChains.length > 0 || removedChains.length > 0) {
|
|
821
|
+
// Refresh subscriptions to use updated data source availability
|
|
822
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
823
|
+
}
|
|
824
|
+
// If chains were added and we have selected accounts, do one-time fetch
|
|
825
|
+
if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
|
|
826
|
+
const addedEnabledChains = addedChains.filter((chain) => __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").has(chain));
|
|
827
|
+
if (addedEnabledChains.length > 0) {
|
|
828
|
+
log('Fetching balances for newly added chains', { addedEnabledChains });
|
|
829
|
+
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
830
|
+
chainIds: addedEnabledChains,
|
|
831
|
+
forceUpdate: true,
|
|
832
|
+
updateMode: 'merge',
|
|
833
|
+
}).catch((error) => {
|
|
834
|
+
log('Failed to fetch balance for added chains', { error });
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
}
|
|
707
838
|
}, _AssetsController_executeMiddlewares =
|
|
708
839
|
// ============================================================================
|
|
709
840
|
// MIDDLEWARE EXECUTION
|
|
@@ -754,13 +885,46 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
754
885
|
}
|
|
755
886
|
}
|
|
756
887
|
return { response: result.response, durationByDataSource };
|
|
757
|
-
},
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
888
|
+
}, _AssetsController_resolveNativeAssetIds = function _AssetsController_resolveNativeAssetIds(chains) {
|
|
889
|
+
const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
|
|
890
|
+
const ids = [];
|
|
891
|
+
for (const chainId of chains) {
|
|
892
|
+
const nativeId = nativeAssetIdentifiers?.[chainId];
|
|
893
|
+
if (nativeId) {
|
|
894
|
+
ids.push(nativeId);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
return ids;
|
|
898
|
+
}, _AssetsController_getNativeAssetIdsForEnabledChains = function _AssetsController_getNativeAssetIdsForEnabledChains() {
|
|
899
|
+
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_enabledChains, "f"));
|
|
900
|
+
}, _AssetsController_getNativeAssetIdsForAccount = function _AssetsController_getNativeAssetIdsForAccount(account) {
|
|
901
|
+
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
|
|
902
|
+
}, _AssetsController_ensureNativeBalancesDefaultZero = function _AssetsController_ensureNativeBalancesDefaultZero() {
|
|
903
|
+
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get);
|
|
904
|
+
if (accounts.length === 0) {
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
this.update((state) => {
|
|
908
|
+
const balances = state.assetsBalance;
|
|
909
|
+
for (const account of accounts) {
|
|
910
|
+
const accountId = account.id;
|
|
911
|
+
const nativeAssetIds = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account);
|
|
912
|
+
if (nativeAssetIds.length === 0) {
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
if (!balances[accountId]) {
|
|
916
|
+
balances[accountId] = {};
|
|
917
|
+
}
|
|
918
|
+
for (const nativeAssetId of nativeAssetIds) {
|
|
919
|
+
if (!(nativeAssetId in balances[accountId])) {
|
|
920
|
+
balances[accountId][nativeAssetId] = { amount: '0' };
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
}, _AssetsController_updateState = async function _AssetsController_updateState(response) {
|
|
763
926
|
const normalizedResponse = normalizeResponse(response);
|
|
927
|
+
const mode = normalizedResponse.updateMode ?? 'merge';
|
|
764
928
|
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_controllerMutex, "f").acquire();
|
|
765
929
|
try {
|
|
766
930
|
const previousState = this.state;
|
|
@@ -786,16 +950,43 @@ async function _AssetsController_updateState(response) {
|
|
|
786
950
|
if (normalizedResponse.assetsBalance) {
|
|
787
951
|
for (const [accountId, accountBalances] of Object.entries(normalizedResponse.assetsBalance)) {
|
|
788
952
|
const previousBalances = previousState.assetsBalance[accountId] ?? {};
|
|
789
|
-
|
|
790
|
-
|
|
953
|
+
const customAssetIds = state.customAssets[accountId] ?? [];
|
|
954
|
+
// Full: response is authoritative; preserve custom assets not in response.
|
|
955
|
+
// Merge: response overlays previous balances.
|
|
956
|
+
// Callers that fetch partial data (e.g. newly added chains) must set updateMode: 'merge'.
|
|
957
|
+
const effective = mode === 'merge'
|
|
958
|
+
? { ...previousBalances, ...accountBalances }
|
|
959
|
+
: (() => {
|
|
960
|
+
const next = {
|
|
961
|
+
...accountBalances,
|
|
962
|
+
};
|
|
963
|
+
for (const customId of customAssetIds) {
|
|
964
|
+
if (!(customId in next)) {
|
|
965
|
+
const prev = previousBalances[customId];
|
|
966
|
+
next[customId] =
|
|
967
|
+
prev ?? { amount: '0' };
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
return next;
|
|
971
|
+
})();
|
|
972
|
+
// Ensure native tokens have an entry (0 if missing) for chains this account supports
|
|
973
|
+
const account = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).find((a) => a.id === accountId);
|
|
974
|
+
const nativeAssetIdsForAccount = account
|
|
975
|
+
? __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account)
|
|
976
|
+
: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForEnabledChains).call(this);
|
|
977
|
+
for (const nativeAssetId of nativeAssetIdsForAccount) {
|
|
978
|
+
if (!(nativeAssetId in effective)) {
|
|
979
|
+
effective[nativeAssetId] = { amount: '0' };
|
|
980
|
+
}
|
|
791
981
|
}
|
|
792
|
-
for (const [assetId, balance] of Object.entries(
|
|
982
|
+
for (const [assetId, balance] of Object.entries(effective)) {
|
|
793
983
|
const previousBalance = previousBalances[assetId];
|
|
794
|
-
const
|
|
795
|
-
const newAmount = balanceData.amount;
|
|
984
|
+
const newAmount = balance.amount;
|
|
796
985
|
const oldAmount = previousBalance?.amount;
|
|
797
|
-
|
|
798
|
-
|
|
986
|
+
const isNewDefaultNativeZero = oldAmount === undefined &&
|
|
987
|
+
newAmount === '0' &&
|
|
988
|
+
nativeAssetIdsForAccount.includes(assetId);
|
|
989
|
+
if (oldAmount !== newAmount && !isNewDefaultNativeZero) {
|
|
799
990
|
changedBalances.push({
|
|
800
991
|
accountId,
|
|
801
992
|
assetId,
|
|
@@ -804,7 +995,7 @@ async function _AssetsController_updateState(response) {
|
|
|
804
995
|
});
|
|
805
996
|
}
|
|
806
997
|
}
|
|
807
|
-
|
|
998
|
+
balances[accountId] = effective;
|
|
808
999
|
}
|
|
809
1000
|
}
|
|
810
1001
|
// Update prices in state
|
|
@@ -948,6 +1139,7 @@ async function _AssetsController_updateState(response) {
|
|
|
948
1139
|
enabledChainCount: __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size,
|
|
949
1140
|
});
|
|
950
1141
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1142
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
951
1143
|
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
952
1144
|
chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
|
|
953
1145
|
forceUpdate: true,
|
|
@@ -982,7 +1174,7 @@ async function _AssetsController_updateState(response) {
|
|
|
982
1174
|
}
|
|
983
1175
|
__classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").clear();
|
|
984
1176
|
}, _AssetsController_subscribeAssets = function _AssetsController_subscribeAssets() {
|
|
985
|
-
if (__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length === 0) {
|
|
1177
|
+
if (__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length === 0 || __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size === 0) {
|
|
986
1178
|
return;
|
|
987
1179
|
}
|
|
988
1180
|
// Subscribe to balance updates (batched by data source)
|
|
@@ -1071,7 +1263,7 @@ async function _AssetsController_updateState(response) {
|
|
|
1071
1263
|
}),
|
|
1072
1264
|
subscriptionId: subscriptionKey,
|
|
1073
1265
|
isUpdate,
|
|
1074
|
-
onAssetsUpdate: (response) => this.handleAssetsUpdate(response, sourceId),
|
|
1266
|
+
onAssetsUpdate: (response, request) => this.handleAssetsUpdate(response, sourceId, request),
|
|
1075
1267
|
getAssetsState: () => this.state,
|
|
1076
1268
|
};
|
|
1077
1269
|
source.subscribe(subscribeReq).catch((error) => {
|
|
@@ -1155,6 +1347,7 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
1155
1347
|
forceUpdate: true,
|
|
1156
1348
|
});
|
|
1157
1349
|
}
|
|
1350
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1158
1351
|
}, _AssetsController_handleEnabledNetworksChanged = async function _AssetsController_handleEnabledNetworksChanged(enabledNetworkMap) {
|
|
1159
1352
|
const previousChains = __classPrivateFieldGet(this, _AssetsController_enabledChains, "f");
|
|
1160
1353
|
__classPrivateFieldSet(this, _AssetsController_enabledChains, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_extractEnabledChains).call(this, enabledNetworkMap), "f");
|
|
@@ -1183,12 +1376,14 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
1183
1376
|
// The data will simply not be updated until the network is re-enabled.
|
|
1184
1377
|
// Refresh subscriptions for new chain set
|
|
1185
1378
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1186
|
-
// Do one-time fetch for newly enabled chains
|
|
1379
|
+
// Do one-time fetch for newly enabled chains; merge so we keep existing chain balances
|
|
1187
1380
|
if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
|
|
1188
1381
|
await this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
1189
1382
|
chainIds: addedChains,
|
|
1190
1383
|
forceUpdate: true,
|
|
1384
|
+
updateMode: 'merge',
|
|
1191
1385
|
});
|
|
1192
1386
|
}
|
|
1387
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1193
1388
|
};
|
|
1194
1389
|
//# sourceMappingURL=AssetsController.cjs.map
|