@metamask-previews/assets-controller 9.1.0-preview-50e82f088 → 9.1.0-preview-773e4e83d
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 +6 -0
- package/dist/AssetsController.cjs +113 -25
- package/dist/AssetsController.cjs.map +1 -1
- package/dist/AssetsController.d.cts.map +1 -1
- package/dist/AssetsController.d.mts.map +1 -1
- package/dist/AssetsController.mjs +113 -25
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.cjs +4 -1
- package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.mjs +4 -1
- package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.cjs +214 -103
- package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.cts +7 -0
- package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.mts +7 -0
- package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.mjs +214 -103
- package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +7 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +7 -0
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
- Bump `@metamask/transaction-controller` from `^68.1.1` to `^68.2.0` ([#9253](https://github.com/MetaMask/core/pull/9253))
|
|
13
13
|
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Fix stale token balances after transactions when switching accounts or when websocket subscriptions reconnect; `AssetsController` now fetches before re-subscribing on account switch, serializes overlapping refresh work, treats `getAssets({ forceUpdate: true })` as authoritative over recent websocket freshness guards, and prevents passive polling from overwriting websocket balances for 120 seconds ([#9265](https://github.com/MetaMask/core/pull/9265))
|
|
17
|
+
- `AccountsApiDataSource` bypasses the TanStack Query balance cache when `forceUpdate` is true so forced refreshes return up-to-date balances instead of 60-second cached values ([#9265](https://github.com/MetaMask/core/pull/9265))
|
|
18
|
+
- `BackendWebsocketDataSource` re-subscribes when subscribed accounts change (case-insensitive EVM address matching), serializes subscribe/unsubscribe to prevent races on account switch, and registers optional channel callbacks for more reliable notification delivery ([#9265](https://github.com/MetaMask/core/pull/9265))
|
|
19
|
+
|
|
14
20
|
## [9.1.0]
|
|
15
21
|
|
|
16
22
|
### Added
|
|
@@ -13,7 +13,7 @@ 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_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitTrace, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_lastKnownAccountIds, _AssetsController_getSelectedAccounts, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_customAssetGraduationMiddleware, _AssetsController_rpcFallbackMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_queryApiClient, _AssetsController_onActiveChainsUpdated, _AssetsController_initializeNativeAssetsMap, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_onUnapprovedTransactionAdded, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_ensureDefaultTrackedAssetsSeeded, _AssetsController_updateState, _AssetsController_getAssetsFromState, _AssetsController_shouldHideNativeToken, _AssetsController_tokenStandardToAssetType, _AssetsController_start, _AssetsController_stop, _AssetsController_subscribeAssets, _AssetsController_subscribeAssetsBalance, _AssetsController_subscribeRpcCustomAssetsSupplement, _AssetsController_unsubscribeBySubscriptionKey, _AssetsController_subscribeStakedBalance, _AssetsController_buildChainToAccountsMap, _AssetsController_subscribeDataSource, _AssetsController_unsubscribeDataSource, _AssetsController_buildDataRequest, _AssetsController_getEnabledChainsForAccount, _AssetsController_handleAccountGroupChanged, _AssetsController_handleEnabledNetworksChanged, _AssetsController_handleNetworkAdded, _AssetsController_refreshAssetsAfterNetworkChange;
|
|
16
|
+
var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitTrace, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_accountRefreshMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_lastKnownAccountIds, _AssetsController_wsBalanceFreshUntil, _AssetsController_getSelectedAccounts, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_customAssetGraduationMiddleware, _AssetsController_rpcFallbackMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_queryApiClient, _AssetsController_onActiveChainsUpdated, _AssetsController_initializeNativeAssetsMap, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_onUnapprovedTransactionAdded, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_runAccountTreeRefresh, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_ensureDefaultTrackedAssetsSeeded, _AssetsController_filterBalancesRespectingWsFreshness, _AssetsController_markWsBalancesFresh, _AssetsController_clearWsBalanceFreshness, _AssetsController_updateState, _AssetsController_getAssetsFromState, _AssetsController_shouldHideNativeToken, _AssetsController_tokenStandardToAssetType, _AssetsController_start, _AssetsController_stop, _AssetsController_subscribeAssets, _AssetsController_subscribeAssetsBalance, _AssetsController_subscribeRpcCustomAssetsSupplement, _AssetsController_unsubscribeBySubscriptionKey, _AssetsController_subscribeStakedBalance, _AssetsController_buildChainToAccountsMap, _AssetsController_subscribeDataSource, _AssetsController_unsubscribeDataSource, _AssetsController_buildDataRequest, _AssetsController_getEnabledChainsForAccount, _AssetsController_handleAccountGroupChanged, _AssetsController_handleEnabledNetworksChanged, _AssetsController_handleNetworkAdded, _AssetsController_refreshAssetsAfterNetworkChange;
|
|
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");
|
|
@@ -62,6 +62,15 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
62
62
|
];
|
|
63
63
|
/** Default polling interval hint for data sources (30 seconds) */
|
|
64
64
|
const DEFAULT_POLLING_INTERVAL_MS = 30000;
|
|
65
|
+
/** Sources whose passive polling must not overwrite recent websocket balances. */
|
|
66
|
+
const POLLING_BALANCE_SOURCES = new Set([
|
|
67
|
+
'AccountsApiDataSource',
|
|
68
|
+
'RpcDataSource',
|
|
69
|
+
'SnapDataSource',
|
|
70
|
+
'StakedBalanceDataSource',
|
|
71
|
+
]);
|
|
72
|
+
/** How long websocket balance updates block stale polling overwrites. */
|
|
73
|
+
const WS_BALANCE_FRESHNESS_MS = 120000;
|
|
65
74
|
// ============================================================================
|
|
66
75
|
// TRACE NAMES — used in Sentry spans (search these strings in Discover)
|
|
67
76
|
// ============================================================================
|
|
@@ -192,6 +201,9 @@ function normalizeResponse(response) {
|
|
|
192
201
|
if (response.updateMode) {
|
|
193
202
|
normalized.updateMode = response.updateMode;
|
|
194
203
|
}
|
|
204
|
+
if (response.sourceId) {
|
|
205
|
+
normalized.sourceId = response.sourceId;
|
|
206
|
+
}
|
|
195
207
|
return normalized;
|
|
196
208
|
}
|
|
197
209
|
// ============================================================================
|
|
@@ -255,6 +267,8 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
255
267
|
/** Whether the keyring is unlocked. Combined with #uiOpen for #updateActive. */
|
|
256
268
|
_AssetsController_keyringUnlocked.set(this, false);
|
|
257
269
|
_AssetsController_controllerMutex.set(this, new async_mutex_1.Mutex());
|
|
270
|
+
/** Serializes account-switch fetch + subscribe to prevent overlapping races. */
|
|
271
|
+
_AssetsController_accountRefreshMutex.set(this, new async_mutex_1.Mutex());
|
|
258
272
|
/**
|
|
259
273
|
* Active balance subscriptions keyed by account ID.
|
|
260
274
|
* Each account has one logical subscription that may span multiple data sources.
|
|
@@ -270,6 +284,11 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
270
284
|
* re-subscriptions when the account set hasn't actually changed.
|
|
271
285
|
*/
|
|
272
286
|
_AssetsController_lastKnownAccountIds.set(this, new Set());
|
|
287
|
+
/**
|
|
288
|
+
* Per `accountId:assetId`, timestamp until which websocket balance updates
|
|
289
|
+
* should not be overwritten by polling/API fetches.
|
|
290
|
+
*/
|
|
291
|
+
_AssetsController_wsBalanceFreshUntil.set(this, new Map());
|
|
273
292
|
_AssetsController_backendWebsocketDataSource.set(this, void 0);
|
|
274
293
|
_AssetsController_accountsApiDataSource.set(this, void 0);
|
|
275
294
|
_AssetsController_snapDataSource.set(this, void 0);
|
|
@@ -443,7 +462,11 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
443
462
|
// The fast pipeline only contains a subset of data sources (AccountsApi +
|
|
444
463
|
// StakedBalance), so it must always merge to avoid wiping Snap/RPC
|
|
445
464
|
// balances that the background pipeline hasn't yet replaced.
|
|
446
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
465
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
466
|
+
...response,
|
|
467
|
+
updateMode: 'merge',
|
|
468
|
+
sourceId: 'getAssets:forceUpdate',
|
|
469
|
+
});
|
|
447
470
|
// Background pipeline: snap and RPC run in parallel after the fast path
|
|
448
471
|
// commits to state. Their balances are merged together before detection.
|
|
449
472
|
// Token + price enrichment matches the pre-split behavior: only when basic
|
|
@@ -463,7 +486,11 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
463
486
|
]
|
|
464
487
|
: []),
|
|
465
488
|
], request)
|
|
466
|
-
.then(({ response: slowResponse }) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
489
|
+
.then(({ response: slowResponse }) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
490
|
+
...slowResponse,
|
|
491
|
+
updateMode: 'merge',
|
|
492
|
+
sourceId: 'getAssets:forceUpdate',
|
|
493
|
+
}))
|
|
467
494
|
.catch((error) => log('Background pipeline failed', { error }));
|
|
468
495
|
const durationMs = performance.now() - startTime;
|
|
469
496
|
// Emit trace for every full fetch (Assets Health dashboard)
|
|
@@ -870,7 +897,11 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
870
897
|
]));
|
|
871
898
|
}
|
|
872
899
|
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, enrichmentSources, pipelineRequest, response);
|
|
873
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, enrichedResponse);
|
|
900
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...enrichedResponse, sourceId });
|
|
901
|
+
if (sourceId === 'BackendWebsocketDataSource' &&
|
|
902
|
+
enrichedResponse.assetsBalance) {
|
|
903
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_markWsBalancesFresh).call(this, enrichedResponse.assetsBalance);
|
|
904
|
+
}
|
|
874
905
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_UPDATE_PIPELINE, {
|
|
875
906
|
source: sourceId,
|
|
876
907
|
duration_ms: performance.now() - updateStart,
|
|
@@ -918,7 +949,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
918
949
|
}
|
|
919
950
|
}
|
|
920
951
|
exports.AssetsController = AssetsController;
|
|
921
|
-
_AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trace = new WeakMap(), _AssetsController_captureException = new WeakMap(), _AssetsController_firstInitFetchReported = new WeakMap(), _AssetsController_stateSizeReported = new WeakMap(), _AssetsController_uiOpen = new WeakMap(), _AssetsController_keyringUnlocked = new WeakMap(), _AssetsController_controllerMutex = new WeakMap(), _AssetsController_activeSubscriptions = new WeakMap(), _AssetsController_enabledChains = new WeakMap(), _AssetsController_lastKnownAccountIds = 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_customAssetGraduationMiddleware = new WeakMap(), _AssetsController_rpcFallbackMiddleware = new WeakMap(), _AssetsController_tokenDataSource = new WeakMap(), _AssetsController_unsubscribeBasicFunctionality = new WeakMap(), _AssetsController_queryApiClient = new WeakMap(), _AssetsController_onActiveChainsUpdated = new WeakMap(), _AssetsController_instances = new WeakSet(), _AssetsController_emitTrace = function _AssetsController_emitTrace(name, data, tags = {
|
|
952
|
+
_AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trace = new WeakMap(), _AssetsController_captureException = new WeakMap(), _AssetsController_firstInitFetchReported = new WeakMap(), _AssetsController_stateSizeReported = new WeakMap(), _AssetsController_uiOpen = new WeakMap(), _AssetsController_keyringUnlocked = new WeakMap(), _AssetsController_controllerMutex = new WeakMap(), _AssetsController_accountRefreshMutex = new WeakMap(), _AssetsController_activeSubscriptions = new WeakMap(), _AssetsController_enabledChains = new WeakMap(), _AssetsController_lastKnownAccountIds = new WeakMap(), _AssetsController_wsBalanceFreshUntil = 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_customAssetGraduationMiddleware = new WeakMap(), _AssetsController_rpcFallbackMiddleware = new WeakMap(), _AssetsController_tokenDataSource = new WeakMap(), _AssetsController_unsubscribeBasicFunctionality = new WeakMap(), _AssetsController_queryApiClient = new WeakMap(), _AssetsController_onActiveChainsUpdated = new WeakMap(), _AssetsController_instances = new WeakSet(), _AssetsController_emitTrace = function _AssetsController_emitTrace(name, data, tags = {
|
|
922
953
|
controller: 'AssetsController',
|
|
923
954
|
}) {
|
|
924
955
|
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f")) {
|
|
@@ -1125,24 +1156,40 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1125
1156
|
if (!accountsChanged) {
|
|
1126
1157
|
return;
|
|
1127
1158
|
}
|
|
1159
|
+
const hasOverlap = [...currentIds].some((id) => __classPrivateFieldGet(this, _AssetsController_lastKnownAccountIds, "f").has(id));
|
|
1160
|
+
if (!hasOverlap && __classPrivateFieldGet(this, _AssetsController_lastKnownAccountIds, "f").size > 0) {
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1128
1163
|
log('Account tree changed with new accounts, re-subscribing', {
|
|
1129
1164
|
previousCount: __classPrivateFieldGet(this, _AssetsController_lastKnownAccountIds, "f").size,
|
|
1130
1165
|
currentCount: currentIds.size,
|
|
1131
1166
|
});
|
|
1132
1167
|
__classPrivateFieldSet(this, _AssetsController_lastKnownAccountIds, currentIds, "f");
|
|
1133
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1134
1168
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1135
1169
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1136
|
-
this.
|
|
1137
|
-
|
|
1138
|
-
forceUpdate: true,
|
|
1139
|
-
}).catch((error) => {
|
|
1140
|
-
log('Failed to fetch assets after tree change', error);
|
|
1170
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runAccountTreeRefresh).call(this, accounts).catch((error) => {
|
|
1171
|
+
log('Failed to refresh assets after tree change', error);
|
|
1141
1172
|
});
|
|
1142
1173
|
}
|
|
1143
1174
|
else {
|
|
1144
1175
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_start).call(this);
|
|
1145
1176
|
}
|
|
1177
|
+
}, _AssetsController_runAccountTreeRefresh = async function _AssetsController_runAccountTreeRefresh(accounts) {
|
|
1178
|
+
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_accountRefreshMutex, "f").acquire();
|
|
1179
|
+
try {
|
|
1180
|
+
await this.getAssets(accounts, {
|
|
1181
|
+
chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
|
|
1182
|
+
forceUpdate: true,
|
|
1183
|
+
});
|
|
1184
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1185
|
+
}
|
|
1186
|
+
catch (error) {
|
|
1187
|
+
log('Failed to fetch assets after tree change', error);
|
|
1188
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1189
|
+
}
|
|
1190
|
+
finally {
|
|
1191
|
+
releaseLock();
|
|
1192
|
+
}
|
|
1146
1193
|
}, _AssetsController_registerActionHandlers = function _AssetsController_registerActionHandlers() {
|
|
1147
1194
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
1148
1195
|
}, _AssetsController_handleActiveChainsUpdate = function _AssetsController_handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
|
|
@@ -1364,9 +1411,37 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1364
1411
|
}
|
|
1365
1412
|
}
|
|
1366
1413
|
});
|
|
1414
|
+
}, _AssetsController_filterBalancesRespectingWsFreshness = function _AssetsController_filterBalancesRespectingWsFreshness(accountId, accountBalances, sourceId) {
|
|
1415
|
+
if (!sourceId || !POLLING_BALANCE_SOURCES.has(sourceId)) {
|
|
1416
|
+
return accountBalances;
|
|
1417
|
+
}
|
|
1418
|
+
const now = Date.now();
|
|
1419
|
+
const filtered = {};
|
|
1420
|
+
for (const [assetId, balance] of Object.entries(accountBalances)) {
|
|
1421
|
+
const freshUntil = __classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").get(`${accountId}:${assetId}`);
|
|
1422
|
+
if (freshUntil !== undefined && now < freshUntil) {
|
|
1423
|
+
continue;
|
|
1424
|
+
}
|
|
1425
|
+
filtered[assetId] = balance;
|
|
1426
|
+
}
|
|
1427
|
+
return filtered;
|
|
1428
|
+
}, _AssetsController_markWsBalancesFresh = function _AssetsController_markWsBalancesFresh(assetsBalance) {
|
|
1429
|
+
const freshUntil = Date.now() + WS_BALANCE_FRESHNESS_MS;
|
|
1430
|
+
for (const [accountId, balances] of Object.entries(assetsBalance)) {
|
|
1431
|
+
for (const assetId of Object.keys(balances)) {
|
|
1432
|
+
__classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").set(`${accountId}:${assetId}`, freshUntil);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
}, _AssetsController_clearWsBalanceFreshness = function _AssetsController_clearWsBalanceFreshness(assetsBalance) {
|
|
1436
|
+
for (const [accountId, balances] of Object.entries(assetsBalance)) {
|
|
1437
|
+
for (const assetId of Object.keys(balances)) {
|
|
1438
|
+
__classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").delete(`${accountId}:${assetId}`);
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1367
1441
|
}, _AssetsController_updateState = async function _AssetsController_updateState(response) {
|
|
1368
1442
|
const normalizedResponse = normalizeResponse(response);
|
|
1369
1443
|
const mode = normalizedResponse.updateMode ?? 'merge';
|
|
1444
|
+
const assetsBalanceToApply = normalizedResponse.assetsBalance;
|
|
1370
1445
|
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_controllerMutex, "f").acquire();
|
|
1371
1446
|
try {
|
|
1372
1447
|
const previousState = this.state;
|
|
@@ -1427,8 +1502,9 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1427
1502
|
}
|
|
1428
1503
|
}
|
|
1429
1504
|
}
|
|
1430
|
-
if (
|
|
1431
|
-
for (const [accountId, accountBalances] of Object.entries(
|
|
1505
|
+
if (assetsBalanceToApply) {
|
|
1506
|
+
for (const [accountId, accountBalances] of Object.entries(assetsBalanceToApply)) {
|
|
1507
|
+
const filteredAccountBalances = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_filterBalancesRespectingWsFreshness).call(this, accountId, accountBalances, normalizedResponse.sourceId);
|
|
1432
1508
|
const previousBalances = previousState.assetsBalance[accountId] ?? {};
|
|
1433
1509
|
const customAssetIds = state.customAssets[accountId] ?? [];
|
|
1434
1510
|
// Full: response is authoritative for the chains it covered;
|
|
@@ -1437,10 +1513,10 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1437
1513
|
// are never inadvertently reset to zero.
|
|
1438
1514
|
// Merge: response overlays previous balances.
|
|
1439
1515
|
const effective = mode === 'merge'
|
|
1440
|
-
? { ...previousBalances, ...
|
|
1516
|
+
? { ...previousBalances, ...filteredAccountBalances }
|
|
1441
1517
|
: (() => {
|
|
1442
1518
|
// Determine which chain namespaces this response covers.
|
|
1443
|
-
const coveredChains = new Set(Object.keys(
|
|
1519
|
+
const coveredChains = new Set(Object.keys(filteredAccountBalances).map((assetId) => assetId.split('/')[0]));
|
|
1444
1520
|
// Start from previous balances, dropping only entries for
|
|
1445
1521
|
// chains this response is authoritative over.
|
|
1446
1522
|
const next = {};
|
|
@@ -1450,7 +1526,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1450
1526
|
}
|
|
1451
1527
|
}
|
|
1452
1528
|
// Apply the response (authoritative for covered chains).
|
|
1453
|
-
Object.assign(next,
|
|
1529
|
+
Object.assign(next, filteredAccountBalances);
|
|
1454
1530
|
// Preserve custom assets that the response omitted.
|
|
1455
1531
|
for (const customId of customAssetIds) {
|
|
1456
1532
|
if (!(customId in next)) {
|
|
@@ -1562,6 +1638,12 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1562
1638
|
});
|
|
1563
1639
|
}
|
|
1564
1640
|
}
|
|
1641
|
+
// Authoritative fetch on account switch — drop WS freshness locks so API
|
|
1642
|
+
// balances (e.g. receiver +1 USDC) replace stale values from a prior send.
|
|
1643
|
+
if (normalizedResponse.sourceId === 'getAssets:forceUpdate' &&
|
|
1644
|
+
assetsBalanceToApply) {
|
|
1645
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_clearWsBalanceFreshness).call(this, assetsBalanceToApply);
|
|
1646
|
+
}
|
|
1565
1647
|
}
|
|
1566
1648
|
finally {
|
|
1567
1649
|
releaseLock();
|
|
@@ -1932,16 +2014,22 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
1932
2014
|
accountIds: accounts.map((a) => a.id),
|
|
1933
2015
|
});
|
|
1934
2016
|
__classPrivateFieldSet(this, _AssetsController_lastKnownAccountIds, new Set(accounts.map((a) => a.id)), "f");
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
2017
|
+
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_accountRefreshMutex, "f").acquire();
|
|
2018
|
+
try {
|
|
2019
|
+
if (accounts.length > 0) {
|
|
2020
|
+
await this.getAssets(accounts, {
|
|
2021
|
+
chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
|
|
2022
|
+
forceUpdate: true,
|
|
2023
|
+
});
|
|
2024
|
+
}
|
|
2025
|
+
// Subscribe after fetch so WS notifications can recover state
|
|
2026
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
2027
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
2028
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
2029
|
+
}
|
|
2030
|
+
finally {
|
|
2031
|
+
releaseLock();
|
|
1942
2032
|
}
|
|
1943
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1944
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1945
2033
|
}, _AssetsController_handleEnabledNetworksChanged = async function _AssetsController_handleEnabledNetworksChanged(enabledNetworkMap) {
|
|
1946
2034
|
const previousChains = __classPrivateFieldGet(this, _AssetsController_enabledChains, "f");
|
|
1947
2035
|
__classPrivateFieldSet(this, _AssetsController_enabledChains, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_extractEnabledChains).call(this, enabledNetworkMap), "f");
|