@metamask/assets-controller 2.0.1 → 2.1.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 +5 -0
- package/dist/AssetsController-method-action-types.d.cts.map +1 -1
- package/dist/AssetsController-method-action-types.d.mts +5 -0
- 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 +259 -88
- package/dist/AssetsController.cjs.map +1 -1
- package/dist/AssetsController.d.cts +44 -17
- package/dist/AssetsController.d.cts.map +1 -1
- package/dist/AssetsController.d.mts +44 -17
- package/dist/AssetsController.d.mts.map +1 -1
- package/dist/AssetsController.mjs +259 -88
- 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 +1 -0
- 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 +1 -0
- 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.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.mts.map +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/package.json +9 -8
|
@@ -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,6 +31,7 @@ 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");
|
|
34
|
+
const ParallelMiddleware_1 = require("./middlewares/ParallelMiddleware.cjs");
|
|
33
35
|
const utils_2 = require("./utils.cjs");
|
|
34
36
|
// ============================================================================
|
|
35
37
|
// CONTROLLER CONSTANTS
|
|
@@ -62,6 +64,7 @@ function getDefaultAssetsControllerState() {
|
|
|
62
64
|
assetsPrice: {},
|
|
63
65
|
customAssets: {},
|
|
64
66
|
assetPreferences: {},
|
|
67
|
+
selectedCurrency: 'usd',
|
|
65
68
|
};
|
|
66
69
|
}
|
|
67
70
|
exports.getDefaultAssetsControllerState = getDefaultAssetsControllerState;
|
|
@@ -99,6 +102,12 @@ const stateMetadata = {
|
|
|
99
102
|
includeInDebugSnapshot: false,
|
|
100
103
|
usedInUi: true,
|
|
101
104
|
},
|
|
105
|
+
selectedCurrency: {
|
|
106
|
+
persist: true,
|
|
107
|
+
includeInStateLogs: false,
|
|
108
|
+
includeInDebugSnapshot: false,
|
|
109
|
+
usedInUi: true,
|
|
110
|
+
},
|
|
102
111
|
};
|
|
103
112
|
// ============================================================================
|
|
104
113
|
// HELPER FUNCTIONS
|
|
@@ -152,6 +161,9 @@ function normalizeResponse(response) {
|
|
|
152
161
|
if (response.errors) {
|
|
153
162
|
normalized.errors = { ...response.errors };
|
|
154
163
|
}
|
|
164
|
+
if (response.updateMode) {
|
|
165
|
+
normalized.updateMode = response.updateMode;
|
|
166
|
+
}
|
|
155
167
|
return normalized;
|
|
156
168
|
}
|
|
157
169
|
// ============================================================================
|
|
@@ -173,8 +185,10 @@ function normalizeResponse(response) {
|
|
|
173
185
|
* based on which chains they support. When active chains change, the controller
|
|
174
186
|
* dynamically adjusts subscriptions.
|
|
175
187
|
*
|
|
176
|
-
* 4. **Keyring Lifecycle**:
|
|
177
|
-
*
|
|
188
|
+
* 4. **Client + Keyring Lifecycle**: Starts subscriptions only when both the UI is
|
|
189
|
+
* open (ClientController) and the wallet is unlocked (KeyringController).
|
|
190
|
+
* Stops when either the UI closes or the keyring locks. See client-controller
|
|
191
|
+
* README for the combined pattern.
|
|
178
192
|
*
|
|
179
193
|
* ## Architecture
|
|
180
194
|
*
|
|
@@ -204,6 +218,10 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
204
218
|
_AssetsController_trackMetaMetricsEvent.set(this, void 0);
|
|
205
219
|
/** Whether we have already reported first init fetch for this session (reset on #stop). */
|
|
206
220
|
_AssetsController_firstInitFetchReported.set(this, false);
|
|
221
|
+
/** Whether the client (UI) is open. Combined with #keyringUnlocked for #updateActive. */
|
|
222
|
+
_AssetsController_uiOpen.set(this, false);
|
|
223
|
+
/** Whether the keyring is unlocked. Combined with #uiOpen for #updateActive. */
|
|
224
|
+
_AssetsController_keyringUnlocked.set(this, false);
|
|
207
225
|
_AssetsController_controllerMutex.set(this, new async_mutex_1.Mutex());
|
|
208
226
|
/**
|
|
209
227
|
* Active balance subscriptions keyed by account ID.
|
|
@@ -223,36 +241,37 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
223
241
|
_AssetsController_detectionMiddleware.set(this, void 0);
|
|
224
242
|
_AssetsController_tokenDataSource.set(this, void 0);
|
|
225
243
|
_AssetsController_unsubscribeBasicFunctionality.set(this, null);
|
|
244
|
+
_AssetsController_onActiveChainsUpdated.set(this, void 0);
|
|
226
245
|
__classPrivateFieldSet(this, _AssetsController_isEnabled, isEnabled(), "f");
|
|
227
246
|
__classPrivateFieldSet(this, _AssetsController_isBasicFunctionality, isBasicFunctionality ?? (() => true), "f");
|
|
228
247
|
__classPrivateFieldSet(this, _AssetsController_defaultUpdateInterval, defaultUpdateInterval, "f");
|
|
229
248
|
__classPrivateFieldSet(this, _AssetsController_trackMetaMetricsEvent, trackMetaMetricsEvent, "f");
|
|
230
249
|
const rpcConfig = rpcDataSourceConfig ?? {};
|
|
231
|
-
|
|
232
|
-
this.
|
|
233
|
-
};
|
|
250
|
+
__classPrivateFieldSet(this, _AssetsController_onActiveChainsUpdated, (dataSourceName, chains, previousChains) => {
|
|
251
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleActiveChainsUpdate).call(this, dataSourceName, chains, previousChains);
|
|
252
|
+
}, "f");
|
|
234
253
|
__classPrivateFieldSet(this, _AssetsController_backendWebsocketDataSource, new BackendWebsocketDataSource_1.BackendWebsocketDataSource({
|
|
235
254
|
messenger: this.messenger,
|
|
236
255
|
queryApiClient,
|
|
237
|
-
onActiveChainsUpdated,
|
|
256
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
238
257
|
}), "f");
|
|
239
258
|
__classPrivateFieldSet(this, _AssetsController_accountsApiDataSource, new AccountsApiDataSource_1.AccountsApiDataSource({
|
|
240
259
|
queryApiClient,
|
|
241
|
-
onActiveChainsUpdated,
|
|
260
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
242
261
|
...accountsApiDataSourceConfig,
|
|
243
262
|
}), "f");
|
|
244
263
|
__classPrivateFieldSet(this, _AssetsController_snapDataSource, new SnapDataSource_1.SnapDataSource({
|
|
245
264
|
messenger: this.messenger,
|
|
246
|
-
onActiveChainsUpdated,
|
|
265
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
247
266
|
}), "f");
|
|
248
267
|
__classPrivateFieldSet(this, _AssetsController_rpcDataSource, new RpcDataSource_1.RpcDataSource({
|
|
249
268
|
messenger: this.messenger,
|
|
250
|
-
onActiveChainsUpdated,
|
|
269
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
251
270
|
...rpcConfig,
|
|
252
271
|
}), "f");
|
|
253
272
|
__classPrivateFieldSet(this, _AssetsController_stakedBalanceDataSource, new StakedBalanceDataSource_1.StakedBalanceDataSource({
|
|
254
273
|
messenger: this.messenger,
|
|
255
|
-
onActiveChainsUpdated,
|
|
274
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
256
275
|
...stakedBalanceDataSourceConfig,
|
|
257
276
|
}), "f");
|
|
258
277
|
__classPrivateFieldSet(this, _AssetsController_tokenDataSource, new TokenDataSource_1.TokenDataSource({
|
|
@@ -260,6 +279,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
260
279
|
}), "f");
|
|
261
280
|
__classPrivateFieldSet(this, _AssetsController_priceDataSource, new PriceDataSource_1.PriceDataSource({
|
|
262
281
|
queryApiClient,
|
|
282
|
+
getSelectedCurrency: () => this.state.selectedCurrency,
|
|
263
283
|
...priceDataSourceConfig,
|
|
264
284
|
}), "f");
|
|
265
285
|
__classPrivateFieldSet(this, _AssetsController_detectionMiddleware, new DetectionMiddleware_1.DetectionMiddleware(), "f");
|
|
@@ -273,7 +293,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
273
293
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_initializeState).call(this);
|
|
274
294
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeToEvents).call(this);
|
|
275
295
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_registerActionHandlers).call(this);
|
|
276
|
-
// Subscriptions start only
|
|
296
|
+
// Subscriptions start only when both UI is open and keyring unlocked -> #updateActive().
|
|
277
297
|
// Subscribe to basic-functionality changes after construction so a synchronous
|
|
278
298
|
// onChange during subscribe cannot run before data sources are initialized.
|
|
279
299
|
if (subscribeToBasicFunctionalityChange) {
|
|
@@ -283,52 +303,14 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
283
303
|
}
|
|
284
304
|
}
|
|
285
305
|
}
|
|
286
|
-
// ============================================================================
|
|
287
|
-
// DATA SOURCE CHAIN MANAGEMENT
|
|
288
|
-
// ============================================================================
|
|
289
306
|
/**
|
|
290
|
-
*
|
|
291
|
-
* Used
|
|
307
|
+
* Returns the callback passed to data sources for reporting active chain updates.
|
|
308
|
+
* Used by tests to simulate a data source reporting chain changes.
|
|
292
309
|
*
|
|
293
|
-
*
|
|
294
|
-
* - When chains are added: fetches balances for the new chains (for selected accounts on enabled networks).
|
|
295
|
-
*
|
|
296
|
-
* Controller does not store chains; sources report via this callback. previousChains is required for diff.
|
|
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.
|
|
310
|
+
* @returns The onActiveChainsUpdated callback.
|
|
301
311
|
*/
|
|
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
|
-
}
|
|
312
|
+
getOnActiveChainsUpdated() {
|
|
313
|
+
return __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f");
|
|
332
314
|
}
|
|
333
315
|
// ============================================================================
|
|
334
316
|
// PUBLIC API: QUERY METHODS
|
|
@@ -337,6 +319,9 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
337
319
|
const chainIds = options?.chainIds ?? [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")];
|
|
338
320
|
const assetTypes = options?.assetTypes ?? ['fungible'];
|
|
339
321
|
const dataTypes = options?.dataTypes ?? ['balance', 'metadata', 'price'];
|
|
322
|
+
if (accounts.length === 0 || chainIds.length === 0) {
|
|
323
|
+
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
|
|
324
|
+
}
|
|
340
325
|
// Collect custom assets for all requested accounts
|
|
341
326
|
const customAssets = [];
|
|
342
327
|
for (const account of accounts) {
|
|
@@ -350,16 +335,21 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
350
335
|
dataTypes,
|
|
351
336
|
customAssets: customAssets.length > 0 ? customAssets : undefined,
|
|
352
337
|
forceUpdate: true,
|
|
338
|
+
assetsForPriceUpdate: options?.assetsForPriceUpdate,
|
|
353
339
|
});
|
|
354
340
|
const sources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
355
341
|
? [
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
342
|
+
(0, ParallelMiddleware_1.createParallelBalanceMiddleware)([
|
|
343
|
+
__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
|
|
344
|
+
__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"),
|
|
345
|
+
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
|
|
346
|
+
__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
|
|
347
|
+
]),
|
|
360
348
|
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
361
|
-
|
|
362
|
-
|
|
349
|
+
(0, ParallelMiddleware_1.createParallelMiddleware)([
|
|
350
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
351
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
352
|
+
]),
|
|
363
353
|
]
|
|
364
354
|
: [
|
|
365
355
|
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
|
|
@@ -367,7 +357,12 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
367
357
|
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
368
358
|
];
|
|
369
359
|
const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, sources, request);
|
|
370
|
-
|
|
360
|
+
// Default to 'merge' when fetching a subset of chains so we don't wipe
|
|
361
|
+
// balances from chains that weren't included in this fetch.
|
|
362
|
+
const isPartialChainFetch = options?.chainIds !== undefined &&
|
|
363
|
+
options.chainIds.length < __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size;
|
|
364
|
+
const updateMode = options?.updateMode ?? (isPartialChainFetch ? 'merge' : 'full');
|
|
365
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...response, updateMode });
|
|
371
366
|
if (__classPrivateFieldGet(this, _AssetsController_trackMetaMetricsEvent, "f") && !__classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")) {
|
|
372
367
|
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
|
|
373
368
|
const durationMs = Date.now() - startTime;
|
|
@@ -378,7 +373,8 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
378
373
|
});
|
|
379
374
|
}
|
|
380
375
|
}
|
|
381
|
-
|
|
376
|
+
const result = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
|
|
377
|
+
return result;
|
|
382
378
|
}
|
|
383
379
|
async getAssetsBalance(accounts, options) {
|
|
384
380
|
// Reuse getAssets with dataTypes: ['balance'] only
|
|
@@ -429,10 +425,15 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
429
425
|
* Custom assets are included in subscription and fetch operations.
|
|
430
426
|
* Adding a custom asset also unhides it if it was previously hidden.
|
|
431
427
|
*
|
|
428
|
+
* When `pendingMetadata` is provided (e.g. from the extension's pending-tokens
|
|
429
|
+
* flow), the token metadata is persisted immediately into `assetsInfo` so the
|
|
430
|
+
* UI can render it without waiting for the next pipeline fetch.
|
|
431
|
+
*
|
|
432
432
|
* @param accountId - The account ID to add the custom asset for.
|
|
433
433
|
* @param assetId - The CAIP-19 asset ID to add.
|
|
434
|
+
* @param pendingMetadata - Optional token metadata from the UI (pendingTokens format).
|
|
434
435
|
*/
|
|
435
|
-
async addCustomAsset(accountId, assetId) {
|
|
436
|
+
async addCustomAsset(accountId, assetId, pendingMetadata) {
|
|
436
437
|
const normalizedAssetId = (0, utils_2.normalizeAssetId)(assetId);
|
|
437
438
|
log('Adding custom asset', { accountId, assetId: normalizedAssetId });
|
|
438
439
|
this.update((state) => {
|
|
@@ -452,14 +453,37 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
452
453
|
delete state.assetPreferences[normalizedAssetId];
|
|
453
454
|
}
|
|
454
455
|
}
|
|
456
|
+
// Persist metadata from the UI so the token is immediately renderable
|
|
457
|
+
if (pendingMetadata) {
|
|
458
|
+
const parsed = (0, utils_1.parseCaipAssetType)(normalizedAssetId);
|
|
459
|
+
let tokenType = 'erc20';
|
|
460
|
+
if (parsed.assetNamespace === 'slip44') {
|
|
461
|
+
tokenType = 'native';
|
|
462
|
+
}
|
|
463
|
+
else if (parsed.assetNamespace === 'spl') {
|
|
464
|
+
tokenType = 'spl';
|
|
465
|
+
}
|
|
466
|
+
const assetMetadata = {
|
|
467
|
+
type: tokenType,
|
|
468
|
+
symbol: pendingMetadata.symbol,
|
|
469
|
+
name: pendingMetadata.name,
|
|
470
|
+
decimals: pendingMetadata.decimals,
|
|
471
|
+
image: pendingMetadata.iconUrl,
|
|
472
|
+
aggregators: pendingMetadata.aggregators,
|
|
473
|
+
occurrences: pendingMetadata.occurrences,
|
|
474
|
+
};
|
|
475
|
+
state.assetsInfo[normalizedAssetId] =
|
|
476
|
+
assetMetadata;
|
|
477
|
+
}
|
|
455
478
|
});
|
|
456
|
-
// Fetch data for the newly added custom asset
|
|
479
|
+
// Fetch data for the newly added custom asset (merge to preserve other chains)
|
|
457
480
|
const account = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).find((a) => a.id === accountId);
|
|
458
481
|
if (account) {
|
|
459
482
|
const chainId = extractChainId(normalizedAssetId);
|
|
460
483
|
await this.getAssets([account], {
|
|
461
484
|
chainIds: [chainId],
|
|
462
485
|
forceUpdate: true,
|
|
486
|
+
updateMode: 'merge',
|
|
463
487
|
});
|
|
464
488
|
}
|
|
465
489
|
}
|
|
@@ -530,6 +554,34 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
530
554
|
});
|
|
531
555
|
}
|
|
532
556
|
// ============================================================================
|
|
557
|
+
// CURRENT CURRENCY MANAGEMENT
|
|
558
|
+
// ============================================================================
|
|
559
|
+
/**
|
|
560
|
+
* Set the current currency.
|
|
561
|
+
*
|
|
562
|
+
* @param selectedCurrency - The ISO 4217 currency code to set.
|
|
563
|
+
*/
|
|
564
|
+
setSelectedCurrency(selectedCurrency) {
|
|
565
|
+
const previousCurrency = this.state.selectedCurrency;
|
|
566
|
+
if (previousCurrency === selectedCurrency) {
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
this.update((state) => {
|
|
570
|
+
state.selectedCurrency = selectedCurrency;
|
|
571
|
+
});
|
|
572
|
+
log('Current currency changed', {
|
|
573
|
+
previousCurrency,
|
|
574
|
+
selectedCurrency,
|
|
575
|
+
});
|
|
576
|
+
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
577
|
+
forceUpdate: true,
|
|
578
|
+
dataTypes: ['price'],
|
|
579
|
+
assetsForPriceUpdate: Object.values(this.state.assetsBalance).flatMap((balances) => Object.keys(balances)),
|
|
580
|
+
}).catch((error) => {
|
|
581
|
+
log('Failed to fetch asset prices after current currency change', error);
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
// ============================================================================
|
|
533
585
|
// SUBSCRIPTIONS
|
|
534
586
|
// ============================================================================
|
|
535
587
|
/**
|
|
@@ -607,9 +659,15 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
607
659
|
hasBalance: Boolean(response.assetsBalance),
|
|
608
660
|
hasPrice: Boolean(response.assetsPrice),
|
|
609
661
|
});
|
|
610
|
-
// Run through enrichment middlewares (
|
|
662
|
+
// Run through enrichment middlewares (Detection, then Token + Price in parallel)
|
|
611
663
|
// 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, [
|
|
664
|
+
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
|
|
665
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
666
|
+
(0, ParallelMiddleware_1.createParallelMiddleware)([
|
|
667
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
668
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
669
|
+
]),
|
|
670
|
+
], request ?? {
|
|
613
671
|
accountsWithSupportedChains: [],
|
|
614
672
|
chainIds: [],
|
|
615
673
|
dataTypes: ['balance', 'metadata', 'price'],
|
|
@@ -649,7 +707,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
649
707
|
}
|
|
650
708
|
}
|
|
651
709
|
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() {
|
|
710
|
+
_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
711
|
return this.messenger.call('AccountTreeController:getAccountsFromSelectedAccountGroup');
|
|
654
712
|
}, _AssetsController_allBalanceDataSources_get = function _AssetsController_allBalanceDataSources_get() {
|
|
655
713
|
return [
|
|
@@ -699,11 +757,60 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
699
757
|
this.messenger.subscribe('NetworkEnablementController:stateChange', ({ enabledNetworkMap }) => {
|
|
700
758
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleEnabledNetworksChanged).call(this, enabledNetworkMap).catch(console.error);
|
|
701
759
|
});
|
|
702
|
-
// Keyring lifecycle:
|
|
703
|
-
this.messenger.subscribe('
|
|
704
|
-
|
|
760
|
+
// Client + Keyring lifecycle: only run when UI is open AND keyring is unlocked
|
|
761
|
+
this.messenger.subscribe('ClientController:stateChange', (isUiOpen) => {
|
|
762
|
+
__classPrivateFieldSet(this, _AssetsController_uiOpen, isUiOpen, "f");
|
|
763
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
764
|
+
}, client_controller_1.clientControllerSelectors.selectIsUiOpen);
|
|
765
|
+
this.messenger.subscribe('KeyringController:unlock', () => {
|
|
766
|
+
__classPrivateFieldSet(this, _AssetsController_keyringUnlocked, true, "f");
|
|
767
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
768
|
+
});
|
|
769
|
+
this.messenger.subscribe('KeyringController:lock', () => {
|
|
770
|
+
__classPrivateFieldSet(this, _AssetsController_keyringUnlocked, false, "f");
|
|
771
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
772
|
+
});
|
|
773
|
+
}, _AssetsController_updateActive = function _AssetsController_updateActive() {
|
|
774
|
+
const shouldRun = __classPrivateFieldGet(this, _AssetsController_uiOpen, "f") && __classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f");
|
|
775
|
+
if (shouldRun) {
|
|
776
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_start).call(this);
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_stop).call(this);
|
|
780
|
+
}
|
|
705
781
|
}, _AssetsController_registerActionHandlers = function _AssetsController_registerActionHandlers() {
|
|
706
782
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
783
|
+
}, _AssetsController_handleActiveChainsUpdate = function _AssetsController_handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
|
|
784
|
+
if (!__classPrivateFieldGet(this, _AssetsController_isEnabled, "f")) {
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
log('Data source active chains changed', {
|
|
788
|
+
dataSourceId,
|
|
789
|
+
chainCount: activeChains.length,
|
|
790
|
+
chains: activeChains,
|
|
791
|
+
});
|
|
792
|
+
const previous = previousChains;
|
|
793
|
+
const previousSet = new Set(previous);
|
|
794
|
+
const addedChains = activeChains.filter((ch) => !previousSet.has(ch));
|
|
795
|
+
const removedChains = previous.filter((ch) => !activeChains.includes(ch));
|
|
796
|
+
if (addedChains.length > 0 || removedChains.length > 0) {
|
|
797
|
+
// Refresh subscriptions to use updated data source availability
|
|
798
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
799
|
+
}
|
|
800
|
+
// If chains were added and we have selected accounts, do one-time fetch
|
|
801
|
+
if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
|
|
802
|
+
const addedEnabledChains = addedChains.filter((chain) => __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").has(chain));
|
|
803
|
+
if (addedEnabledChains.length > 0) {
|
|
804
|
+
log('Fetching balances for newly added chains', { addedEnabledChains });
|
|
805
|
+
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
806
|
+
chainIds: addedEnabledChains,
|
|
807
|
+
forceUpdate: true,
|
|
808
|
+
updateMode: 'merge',
|
|
809
|
+
}).catch((error) => {
|
|
810
|
+
log('Failed to fetch balance for added chains', { error });
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
}
|
|
707
814
|
}, _AssetsController_executeMiddlewares =
|
|
708
815
|
// ============================================================================
|
|
709
816
|
// MIDDLEWARE EXECUTION
|
|
@@ -754,13 +861,46 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
754
861
|
}
|
|
755
862
|
}
|
|
756
863
|
return { response: result.response, durationByDataSource };
|
|
757
|
-
},
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
864
|
+
}, _AssetsController_resolveNativeAssetIds = function _AssetsController_resolveNativeAssetIds(chains) {
|
|
865
|
+
const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
|
|
866
|
+
const ids = [];
|
|
867
|
+
for (const chainId of chains) {
|
|
868
|
+
const nativeId = nativeAssetIdentifiers?.[chainId];
|
|
869
|
+
if (nativeId) {
|
|
870
|
+
ids.push(nativeId);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
return ids;
|
|
874
|
+
}, _AssetsController_getNativeAssetIdsForEnabledChains = function _AssetsController_getNativeAssetIdsForEnabledChains() {
|
|
875
|
+
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_enabledChains, "f"));
|
|
876
|
+
}, _AssetsController_getNativeAssetIdsForAccount = function _AssetsController_getNativeAssetIdsForAccount(account) {
|
|
877
|
+
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
|
|
878
|
+
}, _AssetsController_ensureNativeBalancesDefaultZero = function _AssetsController_ensureNativeBalancesDefaultZero() {
|
|
879
|
+
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get);
|
|
880
|
+
if (accounts.length === 0) {
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
this.update((state) => {
|
|
884
|
+
const balances = state.assetsBalance;
|
|
885
|
+
for (const account of accounts) {
|
|
886
|
+
const accountId = account.id;
|
|
887
|
+
const nativeAssetIds = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account);
|
|
888
|
+
if (nativeAssetIds.length === 0) {
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
if (!balances[accountId]) {
|
|
892
|
+
balances[accountId] = {};
|
|
893
|
+
}
|
|
894
|
+
for (const nativeAssetId of nativeAssetIds) {
|
|
895
|
+
if (!(nativeAssetId in balances[accountId])) {
|
|
896
|
+
balances[accountId][nativeAssetId] = { amount: '0' };
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
}, _AssetsController_updateState = async function _AssetsController_updateState(response) {
|
|
763
902
|
const normalizedResponse = normalizeResponse(response);
|
|
903
|
+
const mode = normalizedResponse.updateMode ?? 'merge';
|
|
764
904
|
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_controllerMutex, "f").acquire();
|
|
765
905
|
try {
|
|
766
906
|
const previousState = this.state;
|
|
@@ -786,16 +926,43 @@ async function _AssetsController_updateState(response) {
|
|
|
786
926
|
if (normalizedResponse.assetsBalance) {
|
|
787
927
|
for (const [accountId, accountBalances] of Object.entries(normalizedResponse.assetsBalance)) {
|
|
788
928
|
const previousBalances = previousState.assetsBalance[accountId] ?? {};
|
|
789
|
-
|
|
790
|
-
|
|
929
|
+
const customAssetIds = state.customAssets[accountId] ?? [];
|
|
930
|
+
// Full: response is authoritative; preserve custom assets not in response.
|
|
931
|
+
// Merge: response overlays previous balances.
|
|
932
|
+
// Callers that fetch partial data (e.g. newly added chains) must set updateMode: 'merge'.
|
|
933
|
+
const effective = mode === 'merge'
|
|
934
|
+
? { ...previousBalances, ...accountBalances }
|
|
935
|
+
: (() => {
|
|
936
|
+
const next = {
|
|
937
|
+
...accountBalances,
|
|
938
|
+
};
|
|
939
|
+
for (const customId of customAssetIds) {
|
|
940
|
+
if (!(customId in next)) {
|
|
941
|
+
const prev = previousBalances[customId];
|
|
942
|
+
next[customId] =
|
|
943
|
+
prev ?? { amount: '0' };
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
return next;
|
|
947
|
+
})();
|
|
948
|
+
// Ensure native tokens have an entry (0 if missing) for chains this account supports
|
|
949
|
+
const account = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).find((a) => a.id === accountId);
|
|
950
|
+
const nativeAssetIdsForAccount = account
|
|
951
|
+
? __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account)
|
|
952
|
+
: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForEnabledChains).call(this);
|
|
953
|
+
for (const nativeAssetId of nativeAssetIdsForAccount) {
|
|
954
|
+
if (!(nativeAssetId in effective)) {
|
|
955
|
+
effective[nativeAssetId] = { amount: '0' };
|
|
956
|
+
}
|
|
791
957
|
}
|
|
792
|
-
for (const [assetId, balance] of Object.entries(
|
|
958
|
+
for (const [assetId, balance] of Object.entries(effective)) {
|
|
793
959
|
const previousBalance = previousBalances[assetId];
|
|
794
|
-
const
|
|
795
|
-
const newAmount = balanceData.amount;
|
|
960
|
+
const newAmount = balance.amount;
|
|
796
961
|
const oldAmount = previousBalance?.amount;
|
|
797
|
-
|
|
798
|
-
|
|
962
|
+
const isNewDefaultNativeZero = oldAmount === undefined &&
|
|
963
|
+
newAmount === '0' &&
|
|
964
|
+
nativeAssetIdsForAccount.includes(assetId);
|
|
965
|
+
if (oldAmount !== newAmount && !isNewDefaultNativeZero) {
|
|
799
966
|
changedBalances.push({
|
|
800
967
|
accountId,
|
|
801
968
|
assetId,
|
|
@@ -804,7 +971,7 @@ async function _AssetsController_updateState(response) {
|
|
|
804
971
|
});
|
|
805
972
|
}
|
|
806
973
|
}
|
|
807
|
-
|
|
974
|
+
balances[accountId] = effective;
|
|
808
975
|
}
|
|
809
976
|
}
|
|
810
977
|
// Update prices in state
|
|
@@ -948,6 +1115,7 @@ async function _AssetsController_updateState(response) {
|
|
|
948
1115
|
enabledChainCount: __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size,
|
|
949
1116
|
});
|
|
950
1117
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1118
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
951
1119
|
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
952
1120
|
chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
|
|
953
1121
|
forceUpdate: true,
|
|
@@ -982,7 +1150,7 @@ async function _AssetsController_updateState(response) {
|
|
|
982
1150
|
}
|
|
983
1151
|
__classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").clear();
|
|
984
1152
|
}, _AssetsController_subscribeAssets = function _AssetsController_subscribeAssets() {
|
|
985
|
-
if (__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length === 0) {
|
|
1153
|
+
if (__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length === 0 || __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size === 0) {
|
|
986
1154
|
return;
|
|
987
1155
|
}
|
|
988
1156
|
// Subscribe to balance updates (batched by data source)
|
|
@@ -1071,7 +1239,7 @@ async function _AssetsController_updateState(response) {
|
|
|
1071
1239
|
}),
|
|
1072
1240
|
subscriptionId: subscriptionKey,
|
|
1073
1241
|
isUpdate,
|
|
1074
|
-
onAssetsUpdate: (response) => this.handleAssetsUpdate(response, sourceId),
|
|
1242
|
+
onAssetsUpdate: (response, request) => this.handleAssetsUpdate(response, sourceId, request),
|
|
1075
1243
|
getAssetsState: () => this.state,
|
|
1076
1244
|
};
|
|
1077
1245
|
source.subscribe(subscribeReq).catch((error) => {
|
|
@@ -1155,6 +1323,7 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
1155
1323
|
forceUpdate: true,
|
|
1156
1324
|
});
|
|
1157
1325
|
}
|
|
1326
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1158
1327
|
}, _AssetsController_handleEnabledNetworksChanged = async function _AssetsController_handleEnabledNetworksChanged(enabledNetworkMap) {
|
|
1159
1328
|
const previousChains = __classPrivateFieldGet(this, _AssetsController_enabledChains, "f");
|
|
1160
1329
|
__classPrivateFieldSet(this, _AssetsController_enabledChains, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_extractEnabledChains).call(this, enabledNetworkMap), "f");
|
|
@@ -1183,12 +1352,14 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
1183
1352
|
// The data will simply not be updated until the network is re-enabled.
|
|
1184
1353
|
// Refresh subscriptions for new chain set
|
|
1185
1354
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1186
|
-
// Do one-time fetch for newly enabled chains
|
|
1355
|
+
// Do one-time fetch for newly enabled chains; merge so we keep existing chain balances
|
|
1187
1356
|
if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
|
|
1188
1357
|
await this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
1189
1358
|
chainIds: addedChains,
|
|
1190
1359
|
forceUpdate: true,
|
|
1360
|
+
updateMode: 'merge',
|
|
1191
1361
|
});
|
|
1192
1362
|
}
|
|
1363
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1193
1364
|
};
|
|
1194
1365
|
//# sourceMappingURL=AssetsController.cjs.map
|