@metamask/assets-controller 2.0.2 → 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 +28 -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 +6 -5
|
@@ -9,8 +9,9 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
10
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
11
|
};
|
|
12
|
-
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;
|
|
12
|
+
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;
|
|
13
13
|
import { BaseController } from "@metamask/base-controller";
|
|
14
|
+
import { clientControllerSelectors } from "@metamask/client-controller";
|
|
14
15
|
import { isCaipChainId, isStrictHexString, parseCaipAssetType, parseCaipChainId } from "@metamask/utils";
|
|
15
16
|
import { Mutex } from "async-mutex";
|
|
16
17
|
import BigNumberJS from "bignumber.js";
|
|
@@ -25,6 +26,7 @@ import { StakedBalanceDataSource } from "./data-sources/StakedBalanceDataSource.
|
|
|
25
26
|
import { TokenDataSource } from "./data-sources/TokenDataSource.mjs";
|
|
26
27
|
import { projectLogger, createModuleLogger } from "./logger.mjs";
|
|
27
28
|
import { DetectionMiddleware } from "./middlewares/DetectionMiddleware.mjs";
|
|
29
|
+
import { createParallelBalanceMiddleware, createParallelMiddleware } from "./middlewares/ParallelMiddleware.mjs";
|
|
28
30
|
import { normalizeAssetId } from "./utils.mjs";
|
|
29
31
|
// ============================================================================
|
|
30
32
|
// CONTROLLER CONSTANTS
|
|
@@ -57,6 +59,7 @@ export function getDefaultAssetsControllerState() {
|
|
|
57
59
|
assetsPrice: {},
|
|
58
60
|
customAssets: {},
|
|
59
61
|
assetPreferences: {},
|
|
62
|
+
selectedCurrency: 'usd',
|
|
60
63
|
};
|
|
61
64
|
}
|
|
62
65
|
// ============================================================================
|
|
@@ -93,6 +96,12 @@ const stateMetadata = {
|
|
|
93
96
|
includeInDebugSnapshot: false,
|
|
94
97
|
usedInUi: true,
|
|
95
98
|
},
|
|
99
|
+
selectedCurrency: {
|
|
100
|
+
persist: true,
|
|
101
|
+
includeInStateLogs: false,
|
|
102
|
+
includeInDebugSnapshot: false,
|
|
103
|
+
usedInUi: true,
|
|
104
|
+
},
|
|
96
105
|
};
|
|
97
106
|
// ============================================================================
|
|
98
107
|
// HELPER FUNCTIONS
|
|
@@ -146,6 +155,9 @@ function normalizeResponse(response) {
|
|
|
146
155
|
if (response.errors) {
|
|
147
156
|
normalized.errors = { ...response.errors };
|
|
148
157
|
}
|
|
158
|
+
if (response.updateMode) {
|
|
159
|
+
normalized.updateMode = response.updateMode;
|
|
160
|
+
}
|
|
149
161
|
return normalized;
|
|
150
162
|
}
|
|
151
163
|
// ============================================================================
|
|
@@ -167,8 +179,10 @@ function normalizeResponse(response) {
|
|
|
167
179
|
* based on which chains they support. When active chains change, the controller
|
|
168
180
|
* dynamically adjusts subscriptions.
|
|
169
181
|
*
|
|
170
|
-
* 4. **Keyring Lifecycle**:
|
|
171
|
-
*
|
|
182
|
+
* 4. **Client + Keyring Lifecycle**: Starts subscriptions only when both the UI is
|
|
183
|
+
* open (ClientController) and the wallet is unlocked (KeyringController).
|
|
184
|
+
* Stops when either the UI closes or the keyring locks. See client-controller
|
|
185
|
+
* README for the combined pattern.
|
|
172
186
|
*
|
|
173
187
|
* ## Architecture
|
|
174
188
|
*
|
|
@@ -198,6 +212,10 @@ export class AssetsController extends BaseController {
|
|
|
198
212
|
_AssetsController_trackMetaMetricsEvent.set(this, void 0);
|
|
199
213
|
/** Whether we have already reported first init fetch for this session (reset on #stop). */
|
|
200
214
|
_AssetsController_firstInitFetchReported.set(this, false);
|
|
215
|
+
/** Whether the client (UI) is open. Combined with #keyringUnlocked for #updateActive. */
|
|
216
|
+
_AssetsController_uiOpen.set(this, false);
|
|
217
|
+
/** Whether the keyring is unlocked. Combined with #uiOpen for #updateActive. */
|
|
218
|
+
_AssetsController_keyringUnlocked.set(this, false);
|
|
201
219
|
_AssetsController_controllerMutex.set(this, new Mutex());
|
|
202
220
|
/**
|
|
203
221
|
* Active balance subscriptions keyed by account ID.
|
|
@@ -217,36 +235,37 @@ export class AssetsController extends BaseController {
|
|
|
217
235
|
_AssetsController_detectionMiddleware.set(this, void 0);
|
|
218
236
|
_AssetsController_tokenDataSource.set(this, void 0);
|
|
219
237
|
_AssetsController_unsubscribeBasicFunctionality.set(this, null);
|
|
238
|
+
_AssetsController_onActiveChainsUpdated.set(this, void 0);
|
|
220
239
|
__classPrivateFieldSet(this, _AssetsController_isEnabled, isEnabled(), "f");
|
|
221
240
|
__classPrivateFieldSet(this, _AssetsController_isBasicFunctionality, isBasicFunctionality ?? (() => true), "f");
|
|
222
241
|
__classPrivateFieldSet(this, _AssetsController_defaultUpdateInterval, defaultUpdateInterval, "f");
|
|
223
242
|
__classPrivateFieldSet(this, _AssetsController_trackMetaMetricsEvent, trackMetaMetricsEvent, "f");
|
|
224
243
|
const rpcConfig = rpcDataSourceConfig ?? {};
|
|
225
|
-
|
|
226
|
-
this.
|
|
227
|
-
};
|
|
244
|
+
__classPrivateFieldSet(this, _AssetsController_onActiveChainsUpdated, (dataSourceName, chains, previousChains) => {
|
|
245
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleActiveChainsUpdate).call(this, dataSourceName, chains, previousChains);
|
|
246
|
+
}, "f");
|
|
228
247
|
__classPrivateFieldSet(this, _AssetsController_backendWebsocketDataSource, new BackendWebsocketDataSource({
|
|
229
248
|
messenger: this.messenger,
|
|
230
249
|
queryApiClient,
|
|
231
|
-
onActiveChainsUpdated,
|
|
250
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
232
251
|
}), "f");
|
|
233
252
|
__classPrivateFieldSet(this, _AssetsController_accountsApiDataSource, new AccountsApiDataSource({
|
|
234
253
|
queryApiClient,
|
|
235
|
-
onActiveChainsUpdated,
|
|
254
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
236
255
|
...accountsApiDataSourceConfig,
|
|
237
256
|
}), "f");
|
|
238
257
|
__classPrivateFieldSet(this, _AssetsController_snapDataSource, new SnapDataSource({
|
|
239
258
|
messenger: this.messenger,
|
|
240
|
-
onActiveChainsUpdated,
|
|
259
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
241
260
|
}), "f");
|
|
242
261
|
__classPrivateFieldSet(this, _AssetsController_rpcDataSource, new RpcDataSource({
|
|
243
262
|
messenger: this.messenger,
|
|
244
|
-
onActiveChainsUpdated,
|
|
263
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
245
264
|
...rpcConfig,
|
|
246
265
|
}), "f");
|
|
247
266
|
__classPrivateFieldSet(this, _AssetsController_stakedBalanceDataSource, new StakedBalanceDataSource({
|
|
248
267
|
messenger: this.messenger,
|
|
249
|
-
onActiveChainsUpdated,
|
|
268
|
+
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
250
269
|
...stakedBalanceDataSourceConfig,
|
|
251
270
|
}), "f");
|
|
252
271
|
__classPrivateFieldSet(this, _AssetsController_tokenDataSource, new TokenDataSource({
|
|
@@ -254,6 +273,7 @@ export class AssetsController extends BaseController {
|
|
|
254
273
|
}), "f");
|
|
255
274
|
__classPrivateFieldSet(this, _AssetsController_priceDataSource, new PriceDataSource({
|
|
256
275
|
queryApiClient,
|
|
276
|
+
getSelectedCurrency: () => this.state.selectedCurrency,
|
|
257
277
|
...priceDataSourceConfig,
|
|
258
278
|
}), "f");
|
|
259
279
|
__classPrivateFieldSet(this, _AssetsController_detectionMiddleware, new DetectionMiddleware(), "f");
|
|
@@ -267,7 +287,7 @@ export class AssetsController extends BaseController {
|
|
|
267
287
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_initializeState).call(this);
|
|
268
288
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeToEvents).call(this);
|
|
269
289
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_registerActionHandlers).call(this);
|
|
270
|
-
// Subscriptions start only
|
|
290
|
+
// Subscriptions start only when both UI is open and keyring unlocked -> #updateActive().
|
|
271
291
|
// Subscribe to basic-functionality changes after construction so a synchronous
|
|
272
292
|
// onChange during subscribe cannot run before data sources are initialized.
|
|
273
293
|
if (subscribeToBasicFunctionalityChange) {
|
|
@@ -277,52 +297,14 @@ export class AssetsController extends BaseController {
|
|
|
277
297
|
}
|
|
278
298
|
}
|
|
279
299
|
}
|
|
280
|
-
// ============================================================================
|
|
281
|
-
// DATA SOURCE CHAIN MANAGEMENT
|
|
282
|
-
// ============================================================================
|
|
283
300
|
/**
|
|
284
|
-
*
|
|
285
|
-
* Used
|
|
301
|
+
* Returns the callback passed to data sources for reporting active chain updates.
|
|
302
|
+
* Used by tests to simulate a data source reporting chain changes.
|
|
286
303
|
*
|
|
287
|
-
*
|
|
288
|
-
* - When chains are added: fetches balances for the new chains (for selected accounts on enabled networks).
|
|
289
|
-
*
|
|
290
|
-
* Controller does not store chains; sources report via this callback. previousChains is required for diff.
|
|
291
|
-
*
|
|
292
|
-
* @param dataSourceId - The identifier of the data source reporting the change.
|
|
293
|
-
* @param activeChains - Currently active (supported and available) chain IDs for this source.
|
|
294
|
-
* @param previousChains - Previous chains; used to compute added/removed.
|
|
304
|
+
* @returns The onActiveChainsUpdated callback.
|
|
295
305
|
*/
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
log('Data source active chains changed', {
|
|
301
|
-
dataSourceId,
|
|
302
|
-
chainCount: activeChains.length,
|
|
303
|
-
chains: activeChains,
|
|
304
|
-
});
|
|
305
|
-
const previous = previousChains;
|
|
306
|
-
const previousSet = new Set(previous);
|
|
307
|
-
const addedChains = activeChains.filter((ch) => !previousSet.has(ch));
|
|
308
|
-
const removedChains = previous.filter((ch) => !activeChains.includes(ch));
|
|
309
|
-
if (addedChains.length > 0 || removedChains.length > 0) {
|
|
310
|
-
// Refresh subscriptions to use updated data source availability
|
|
311
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
312
|
-
}
|
|
313
|
-
// If chains were added and we have selected accounts, do one-time fetch
|
|
314
|
-
if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
|
|
315
|
-
const addedEnabledChains = addedChains.filter((chain) => __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").has(chain));
|
|
316
|
-
if (addedEnabledChains.length > 0) {
|
|
317
|
-
log('Fetching balances for newly added chains', { addedEnabledChains });
|
|
318
|
-
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
319
|
-
chainIds: addedEnabledChains,
|
|
320
|
-
forceUpdate: true,
|
|
321
|
-
}).catch((error) => {
|
|
322
|
-
log('Failed to fetch balance for added chains', { error });
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
}
|
|
306
|
+
getOnActiveChainsUpdated() {
|
|
307
|
+
return __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f");
|
|
326
308
|
}
|
|
327
309
|
// ============================================================================
|
|
328
310
|
// PUBLIC API: QUERY METHODS
|
|
@@ -331,6 +313,9 @@ export class AssetsController extends BaseController {
|
|
|
331
313
|
const chainIds = options?.chainIds ?? [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")];
|
|
332
314
|
const assetTypes = options?.assetTypes ?? ['fungible'];
|
|
333
315
|
const dataTypes = options?.dataTypes ?? ['balance', 'metadata', 'price'];
|
|
316
|
+
if (accounts.length === 0 || chainIds.length === 0) {
|
|
317
|
+
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
|
|
318
|
+
}
|
|
334
319
|
// Collect custom assets for all requested accounts
|
|
335
320
|
const customAssets = [];
|
|
336
321
|
for (const account of accounts) {
|
|
@@ -344,16 +329,21 @@ export class AssetsController extends BaseController {
|
|
|
344
329
|
dataTypes,
|
|
345
330
|
customAssets: customAssets.length > 0 ? customAssets : undefined,
|
|
346
331
|
forceUpdate: true,
|
|
332
|
+
assetsForPriceUpdate: options?.assetsForPriceUpdate,
|
|
347
333
|
});
|
|
348
334
|
const sources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
349
335
|
? [
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
336
|
+
createParallelBalanceMiddleware([
|
|
337
|
+
__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
|
|
338
|
+
__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"),
|
|
339
|
+
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
|
|
340
|
+
__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
|
|
341
|
+
]),
|
|
354
342
|
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
355
|
-
|
|
356
|
-
|
|
343
|
+
createParallelMiddleware([
|
|
344
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
345
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
346
|
+
]),
|
|
357
347
|
]
|
|
358
348
|
: [
|
|
359
349
|
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
|
|
@@ -361,7 +351,12 @@ export class AssetsController extends BaseController {
|
|
|
361
351
|
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
362
352
|
];
|
|
363
353
|
const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, sources, request);
|
|
364
|
-
|
|
354
|
+
// Default to 'merge' when fetching a subset of chains so we don't wipe
|
|
355
|
+
// balances from chains that weren't included in this fetch.
|
|
356
|
+
const isPartialChainFetch = options?.chainIds !== undefined &&
|
|
357
|
+
options.chainIds.length < __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size;
|
|
358
|
+
const updateMode = options?.updateMode ?? (isPartialChainFetch ? 'merge' : 'full');
|
|
359
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...response, updateMode });
|
|
365
360
|
if (__classPrivateFieldGet(this, _AssetsController_trackMetaMetricsEvent, "f") && !__classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")) {
|
|
366
361
|
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
|
|
367
362
|
const durationMs = Date.now() - startTime;
|
|
@@ -372,7 +367,8 @@ export class AssetsController extends BaseController {
|
|
|
372
367
|
});
|
|
373
368
|
}
|
|
374
369
|
}
|
|
375
|
-
|
|
370
|
+
const result = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
|
|
371
|
+
return result;
|
|
376
372
|
}
|
|
377
373
|
async getAssetsBalance(accounts, options) {
|
|
378
374
|
// Reuse getAssets with dataTypes: ['balance'] only
|
|
@@ -423,10 +419,15 @@ export class AssetsController extends BaseController {
|
|
|
423
419
|
* Custom assets are included in subscription and fetch operations.
|
|
424
420
|
* Adding a custom asset also unhides it if it was previously hidden.
|
|
425
421
|
*
|
|
422
|
+
* When `pendingMetadata` is provided (e.g. from the extension's pending-tokens
|
|
423
|
+
* flow), the token metadata is persisted immediately into `assetsInfo` so the
|
|
424
|
+
* UI can render it without waiting for the next pipeline fetch.
|
|
425
|
+
*
|
|
426
426
|
* @param accountId - The account ID to add the custom asset for.
|
|
427
427
|
* @param assetId - The CAIP-19 asset ID to add.
|
|
428
|
+
* @param pendingMetadata - Optional token metadata from the UI (pendingTokens format).
|
|
428
429
|
*/
|
|
429
|
-
async addCustomAsset(accountId, assetId) {
|
|
430
|
+
async addCustomAsset(accountId, assetId, pendingMetadata) {
|
|
430
431
|
const normalizedAssetId = normalizeAssetId(assetId);
|
|
431
432
|
log('Adding custom asset', { accountId, assetId: normalizedAssetId });
|
|
432
433
|
this.update((state) => {
|
|
@@ -446,14 +447,37 @@ export class AssetsController extends BaseController {
|
|
|
446
447
|
delete state.assetPreferences[normalizedAssetId];
|
|
447
448
|
}
|
|
448
449
|
}
|
|
450
|
+
// Persist metadata from the UI so the token is immediately renderable
|
|
451
|
+
if (pendingMetadata) {
|
|
452
|
+
const parsed = parseCaipAssetType(normalizedAssetId);
|
|
453
|
+
let tokenType = 'erc20';
|
|
454
|
+
if (parsed.assetNamespace === 'slip44') {
|
|
455
|
+
tokenType = 'native';
|
|
456
|
+
}
|
|
457
|
+
else if (parsed.assetNamespace === 'spl') {
|
|
458
|
+
tokenType = 'spl';
|
|
459
|
+
}
|
|
460
|
+
const assetMetadata = {
|
|
461
|
+
type: tokenType,
|
|
462
|
+
symbol: pendingMetadata.symbol,
|
|
463
|
+
name: pendingMetadata.name,
|
|
464
|
+
decimals: pendingMetadata.decimals,
|
|
465
|
+
image: pendingMetadata.iconUrl,
|
|
466
|
+
aggregators: pendingMetadata.aggregators,
|
|
467
|
+
occurrences: pendingMetadata.occurrences,
|
|
468
|
+
};
|
|
469
|
+
state.assetsInfo[normalizedAssetId] =
|
|
470
|
+
assetMetadata;
|
|
471
|
+
}
|
|
449
472
|
});
|
|
450
|
-
// Fetch data for the newly added custom asset
|
|
473
|
+
// Fetch data for the newly added custom asset (merge to preserve other chains)
|
|
451
474
|
const account = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).find((a) => a.id === accountId);
|
|
452
475
|
if (account) {
|
|
453
476
|
const chainId = extractChainId(normalizedAssetId);
|
|
454
477
|
await this.getAssets([account], {
|
|
455
478
|
chainIds: [chainId],
|
|
456
479
|
forceUpdate: true,
|
|
480
|
+
updateMode: 'merge',
|
|
457
481
|
});
|
|
458
482
|
}
|
|
459
483
|
}
|
|
@@ -524,6 +548,34 @@ export class AssetsController extends BaseController {
|
|
|
524
548
|
});
|
|
525
549
|
}
|
|
526
550
|
// ============================================================================
|
|
551
|
+
// CURRENT CURRENCY MANAGEMENT
|
|
552
|
+
// ============================================================================
|
|
553
|
+
/**
|
|
554
|
+
* Set the current currency.
|
|
555
|
+
*
|
|
556
|
+
* @param selectedCurrency - The ISO 4217 currency code to set.
|
|
557
|
+
*/
|
|
558
|
+
setSelectedCurrency(selectedCurrency) {
|
|
559
|
+
const previousCurrency = this.state.selectedCurrency;
|
|
560
|
+
if (previousCurrency === selectedCurrency) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
this.update((state) => {
|
|
564
|
+
state.selectedCurrency = selectedCurrency;
|
|
565
|
+
});
|
|
566
|
+
log('Current currency changed', {
|
|
567
|
+
previousCurrency,
|
|
568
|
+
selectedCurrency,
|
|
569
|
+
});
|
|
570
|
+
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
571
|
+
forceUpdate: true,
|
|
572
|
+
dataTypes: ['price'],
|
|
573
|
+
assetsForPriceUpdate: Object.values(this.state.assetsBalance).flatMap((balances) => Object.keys(balances)),
|
|
574
|
+
}).catch((error) => {
|
|
575
|
+
log('Failed to fetch asset prices after current currency change', error);
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
// ============================================================================
|
|
527
579
|
// SUBSCRIPTIONS
|
|
528
580
|
// ============================================================================
|
|
529
581
|
/**
|
|
@@ -601,9 +653,15 @@ export class AssetsController extends BaseController {
|
|
|
601
653
|
hasBalance: Boolean(response.assetsBalance),
|
|
602
654
|
hasPrice: Boolean(response.assetsPrice),
|
|
603
655
|
});
|
|
604
|
-
// Run through enrichment middlewares (
|
|
656
|
+
// Run through enrichment middlewares (Detection, then Token + Price in parallel)
|
|
605
657
|
// Include 'metadata' in dataTypes so TokenDataSource runs to enrich detected assets
|
|
606
|
-
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
|
|
658
|
+
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
|
|
659
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
660
|
+
createParallelMiddleware([
|
|
661
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
662
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
663
|
+
]),
|
|
664
|
+
], request ?? {
|
|
607
665
|
accountsWithSupportedChains: [],
|
|
608
666
|
chainIds: [],
|
|
609
667
|
dataTypes: ['balance', 'metadata', 'price'],
|
|
@@ -642,7 +700,7 @@ export class AssetsController extends BaseController {
|
|
|
642
700
|
this.messenger.unregisterActionHandler('AssetsController:unhideAsset');
|
|
643
701
|
}
|
|
644
702
|
}
|
|
645
|
-
_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() {
|
|
703
|
+
_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() {
|
|
646
704
|
return this.messenger.call('AccountTreeController:getAccountsFromSelectedAccountGroup');
|
|
647
705
|
}, _AssetsController_allBalanceDataSources_get = function _AssetsController_allBalanceDataSources_get() {
|
|
648
706
|
return [
|
|
@@ -692,11 +750,60 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
692
750
|
this.messenger.subscribe('NetworkEnablementController:stateChange', ({ enabledNetworkMap }) => {
|
|
693
751
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleEnabledNetworksChanged).call(this, enabledNetworkMap).catch(console.error);
|
|
694
752
|
});
|
|
695
|
-
// Keyring lifecycle:
|
|
696
|
-
this.messenger.subscribe('
|
|
697
|
-
|
|
753
|
+
// Client + Keyring lifecycle: only run when UI is open AND keyring is unlocked
|
|
754
|
+
this.messenger.subscribe('ClientController:stateChange', (isUiOpen) => {
|
|
755
|
+
__classPrivateFieldSet(this, _AssetsController_uiOpen, isUiOpen, "f");
|
|
756
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
757
|
+
}, clientControllerSelectors.selectIsUiOpen);
|
|
758
|
+
this.messenger.subscribe('KeyringController:unlock', () => {
|
|
759
|
+
__classPrivateFieldSet(this, _AssetsController_keyringUnlocked, true, "f");
|
|
760
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
761
|
+
});
|
|
762
|
+
this.messenger.subscribe('KeyringController:lock', () => {
|
|
763
|
+
__classPrivateFieldSet(this, _AssetsController_keyringUnlocked, false, "f");
|
|
764
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
765
|
+
});
|
|
766
|
+
}, _AssetsController_updateActive = function _AssetsController_updateActive() {
|
|
767
|
+
const shouldRun = __classPrivateFieldGet(this, _AssetsController_uiOpen, "f") && __classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f");
|
|
768
|
+
if (shouldRun) {
|
|
769
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_start).call(this);
|
|
770
|
+
}
|
|
771
|
+
else {
|
|
772
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_stop).call(this);
|
|
773
|
+
}
|
|
698
774
|
}, _AssetsController_registerActionHandlers = function _AssetsController_registerActionHandlers() {
|
|
699
775
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
776
|
+
}, _AssetsController_handleActiveChainsUpdate = function _AssetsController_handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
|
|
777
|
+
if (!__classPrivateFieldGet(this, _AssetsController_isEnabled, "f")) {
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
log('Data source active chains changed', {
|
|
781
|
+
dataSourceId,
|
|
782
|
+
chainCount: activeChains.length,
|
|
783
|
+
chains: activeChains,
|
|
784
|
+
});
|
|
785
|
+
const previous = previousChains;
|
|
786
|
+
const previousSet = new Set(previous);
|
|
787
|
+
const addedChains = activeChains.filter((ch) => !previousSet.has(ch));
|
|
788
|
+
const removedChains = previous.filter((ch) => !activeChains.includes(ch));
|
|
789
|
+
if (addedChains.length > 0 || removedChains.length > 0) {
|
|
790
|
+
// Refresh subscriptions to use updated data source availability
|
|
791
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
792
|
+
}
|
|
793
|
+
// If chains were added and we have selected accounts, do one-time fetch
|
|
794
|
+
if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
|
|
795
|
+
const addedEnabledChains = addedChains.filter((chain) => __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").has(chain));
|
|
796
|
+
if (addedEnabledChains.length > 0) {
|
|
797
|
+
log('Fetching balances for newly added chains', { addedEnabledChains });
|
|
798
|
+
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
799
|
+
chainIds: addedEnabledChains,
|
|
800
|
+
forceUpdate: true,
|
|
801
|
+
updateMode: 'merge',
|
|
802
|
+
}).catch((error) => {
|
|
803
|
+
log('Failed to fetch balance for added chains', { error });
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
}
|
|
700
807
|
}, _AssetsController_executeMiddlewares =
|
|
701
808
|
// ============================================================================
|
|
702
809
|
// MIDDLEWARE EXECUTION
|
|
@@ -747,13 +854,46 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
747
854
|
}
|
|
748
855
|
}
|
|
749
856
|
return { response: result.response, durationByDataSource };
|
|
750
|
-
},
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
857
|
+
}, _AssetsController_resolveNativeAssetIds = function _AssetsController_resolveNativeAssetIds(chains) {
|
|
858
|
+
const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
|
|
859
|
+
const ids = [];
|
|
860
|
+
for (const chainId of chains) {
|
|
861
|
+
const nativeId = nativeAssetIdentifiers?.[chainId];
|
|
862
|
+
if (nativeId) {
|
|
863
|
+
ids.push(nativeId);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
return ids;
|
|
867
|
+
}, _AssetsController_getNativeAssetIdsForEnabledChains = function _AssetsController_getNativeAssetIdsForEnabledChains() {
|
|
868
|
+
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_enabledChains, "f"));
|
|
869
|
+
}, _AssetsController_getNativeAssetIdsForAccount = function _AssetsController_getNativeAssetIdsForAccount(account) {
|
|
870
|
+
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
|
|
871
|
+
}, _AssetsController_ensureNativeBalancesDefaultZero = function _AssetsController_ensureNativeBalancesDefaultZero() {
|
|
872
|
+
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get);
|
|
873
|
+
if (accounts.length === 0) {
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
this.update((state) => {
|
|
877
|
+
const balances = state.assetsBalance;
|
|
878
|
+
for (const account of accounts) {
|
|
879
|
+
const accountId = account.id;
|
|
880
|
+
const nativeAssetIds = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account);
|
|
881
|
+
if (nativeAssetIds.length === 0) {
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
884
|
+
if (!balances[accountId]) {
|
|
885
|
+
balances[accountId] = {};
|
|
886
|
+
}
|
|
887
|
+
for (const nativeAssetId of nativeAssetIds) {
|
|
888
|
+
if (!(nativeAssetId in balances[accountId])) {
|
|
889
|
+
balances[accountId][nativeAssetId] = { amount: '0' };
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
}, _AssetsController_updateState = async function _AssetsController_updateState(response) {
|
|
756
895
|
const normalizedResponse = normalizeResponse(response);
|
|
896
|
+
const mode = normalizedResponse.updateMode ?? 'merge';
|
|
757
897
|
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_controllerMutex, "f").acquire();
|
|
758
898
|
try {
|
|
759
899
|
const previousState = this.state;
|
|
@@ -779,16 +919,43 @@ async function _AssetsController_updateState(response) {
|
|
|
779
919
|
if (normalizedResponse.assetsBalance) {
|
|
780
920
|
for (const [accountId, accountBalances] of Object.entries(normalizedResponse.assetsBalance)) {
|
|
781
921
|
const previousBalances = previousState.assetsBalance[accountId] ?? {};
|
|
782
|
-
|
|
783
|
-
|
|
922
|
+
const customAssetIds = state.customAssets[accountId] ?? [];
|
|
923
|
+
// Full: response is authoritative; preserve custom assets not in response.
|
|
924
|
+
// Merge: response overlays previous balances.
|
|
925
|
+
// Callers that fetch partial data (e.g. newly added chains) must set updateMode: 'merge'.
|
|
926
|
+
const effective = mode === 'merge'
|
|
927
|
+
? { ...previousBalances, ...accountBalances }
|
|
928
|
+
: (() => {
|
|
929
|
+
const next = {
|
|
930
|
+
...accountBalances,
|
|
931
|
+
};
|
|
932
|
+
for (const customId of customAssetIds) {
|
|
933
|
+
if (!(customId in next)) {
|
|
934
|
+
const prev = previousBalances[customId];
|
|
935
|
+
next[customId] =
|
|
936
|
+
prev ?? { amount: '0' };
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
return next;
|
|
940
|
+
})();
|
|
941
|
+
// Ensure native tokens have an entry (0 if missing) for chains this account supports
|
|
942
|
+
const account = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).find((a) => a.id === accountId);
|
|
943
|
+
const nativeAssetIdsForAccount = account
|
|
944
|
+
? __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account)
|
|
945
|
+
: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForEnabledChains).call(this);
|
|
946
|
+
for (const nativeAssetId of nativeAssetIdsForAccount) {
|
|
947
|
+
if (!(nativeAssetId in effective)) {
|
|
948
|
+
effective[nativeAssetId] = { amount: '0' };
|
|
949
|
+
}
|
|
784
950
|
}
|
|
785
|
-
for (const [assetId, balance] of Object.entries(
|
|
951
|
+
for (const [assetId, balance] of Object.entries(effective)) {
|
|
786
952
|
const previousBalance = previousBalances[assetId];
|
|
787
|
-
const
|
|
788
|
-
const newAmount = balanceData.amount;
|
|
953
|
+
const newAmount = balance.amount;
|
|
789
954
|
const oldAmount = previousBalance?.amount;
|
|
790
|
-
|
|
791
|
-
|
|
955
|
+
const isNewDefaultNativeZero = oldAmount === undefined &&
|
|
956
|
+
newAmount === '0' &&
|
|
957
|
+
nativeAssetIdsForAccount.includes(assetId);
|
|
958
|
+
if (oldAmount !== newAmount && !isNewDefaultNativeZero) {
|
|
792
959
|
changedBalances.push({
|
|
793
960
|
accountId,
|
|
794
961
|
assetId,
|
|
@@ -797,7 +964,7 @@ async function _AssetsController_updateState(response) {
|
|
|
797
964
|
});
|
|
798
965
|
}
|
|
799
966
|
}
|
|
800
|
-
|
|
967
|
+
balances[accountId] = effective;
|
|
801
968
|
}
|
|
802
969
|
}
|
|
803
970
|
// Update prices in state
|
|
@@ -941,6 +1108,7 @@ async function _AssetsController_updateState(response) {
|
|
|
941
1108
|
enabledChainCount: __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size,
|
|
942
1109
|
});
|
|
943
1110
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1111
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
944
1112
|
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
945
1113
|
chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
|
|
946
1114
|
forceUpdate: true,
|
|
@@ -975,7 +1143,7 @@ async function _AssetsController_updateState(response) {
|
|
|
975
1143
|
}
|
|
976
1144
|
__classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").clear();
|
|
977
1145
|
}, _AssetsController_subscribeAssets = function _AssetsController_subscribeAssets() {
|
|
978
|
-
if (__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length === 0) {
|
|
1146
|
+
if (__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length === 0 || __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size === 0) {
|
|
979
1147
|
return;
|
|
980
1148
|
}
|
|
981
1149
|
// Subscribe to balance updates (batched by data source)
|
|
@@ -1064,7 +1232,7 @@ async function _AssetsController_updateState(response) {
|
|
|
1064
1232
|
}),
|
|
1065
1233
|
subscriptionId: subscriptionKey,
|
|
1066
1234
|
isUpdate,
|
|
1067
|
-
onAssetsUpdate: (response) => this.handleAssetsUpdate(response, sourceId),
|
|
1235
|
+
onAssetsUpdate: (response, request) => this.handleAssetsUpdate(response, sourceId, request),
|
|
1068
1236
|
getAssetsState: () => this.state,
|
|
1069
1237
|
};
|
|
1070
1238
|
source.subscribe(subscribeReq).catch((error) => {
|
|
@@ -1148,6 +1316,7 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
1148
1316
|
forceUpdate: true,
|
|
1149
1317
|
});
|
|
1150
1318
|
}
|
|
1319
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1151
1320
|
}, _AssetsController_handleEnabledNetworksChanged = async function _AssetsController_handleEnabledNetworksChanged(enabledNetworkMap) {
|
|
1152
1321
|
const previousChains = __classPrivateFieldGet(this, _AssetsController_enabledChains, "f");
|
|
1153
1322
|
__classPrivateFieldSet(this, _AssetsController_enabledChains, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_extractEnabledChains).call(this, enabledNetworkMap), "f");
|
|
@@ -1176,12 +1345,14 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
1176
1345
|
// The data will simply not be updated until the network is re-enabled.
|
|
1177
1346
|
// Refresh subscriptions for new chain set
|
|
1178
1347
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1179
|
-
// Do one-time fetch for newly enabled chains
|
|
1348
|
+
// Do one-time fetch for newly enabled chains; merge so we keep existing chain balances
|
|
1180
1349
|
if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
|
|
1181
1350
|
await this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
|
|
1182
1351
|
chainIds: addedChains,
|
|
1183
1352
|
forceUpdate: true,
|
|
1353
|
+
updateMode: 'merge',
|
|
1184
1354
|
});
|
|
1185
1355
|
}
|
|
1356
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1186
1357
|
};
|
|
1187
1358
|
//# sourceMappingURL=AssetsController.mjs.map
|