@metamask-previews/assets-controller 9.1.0-preview-18dd0df9c → 9.1.0-preview-bd7b53f49
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 +1 -0
- package/dist/AssetsController.cjs +74 -41
- 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 +74 -41
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/middlewares/ParallelMiddleware.cjs +3 -0
- package/dist/middlewares/ParallelMiddleware.cjs.map +1 -1
- package/dist/middlewares/ParallelMiddleware.d.cts.map +1 -1
- package/dist/middlewares/ParallelMiddleware.d.mts.map +1 -1
- package/dist/middlewares/ParallelMiddleware.mjs +3 -0
- package/dist/middlewares/ParallelMiddleware.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +12 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +12 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
21
21
|
- `BackendWebsocketDataSource` registers subscription handlers before the subscribe handshake so in-flight account-activity notifications are not dropped, cleans up subscription state on subscribe failure, and resolves balance updates from stored subscription state when notifications arrive with stale subscription IDs ([#9273](https://github.com/MetaMask/core/pull/9273))
|
|
22
22
|
- `AssetsController` refreshes data-source `activeChains`, re-subscribes, and force-fetches balances for the newly selected EVM chain when the user switches networks via `NetworkController:networkDidChange`
|
|
23
23
|
- `AssetsController` bypasses the price deduper cache and fetches spot prices for assets on a newly selected or added EVM network only when those assets have no entry in `assetsPrice` yet; `DetectionMiddleware` queues newly detected assets for the same pipeline price fetch so RPC-detected tokens are priced without waiting for the poll interval
|
|
24
|
+
- `AssetsController` merge updates from `getAssets({ forceUpdate: true })` now replace balances on API-covered chains so unlock/startup reflects the fresh Accounts API snapshot instead of preserving stale pre-lock tokens; subscription-driven merges are unchanged
|
|
24
25
|
|
|
25
26
|
## [9.1.0]
|
|
26
27
|
|
|
@@ -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_accountRefreshMutex, _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_onTransactionConfirmed, _AssetsController_onAccountActivityBalanceUpdated, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_runAccountTreeRefresh, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_fetchMissingPricesWithoutCache, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_getSlowPipelineChainIds, _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_refreshActiveChainsOnNetworkSwitch, _AssetsController_getSelectedEvmChainIdFromNetworkState, _AssetsController_handleNetworkDidChange, _AssetsController_refreshAssetsAfterNetworkChange, _AssetsController_refreshAssetsAfterNetworkAdded;
|
|
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_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_onTransactionConfirmed, _AssetsController_onAccountActivityBalanceUpdated, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_runAccountTreeRefresh, _AssetsController_runStartupRefresh, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_fetchMissingPricesWithoutCache, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_getSlowPipelineChainIds, _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_refreshActiveChainsOnNetworkSwitch, _AssetsController_getSelectedEvmChainIdFromNetworkState, _AssetsController_handleNetworkDidChange, _AssetsController_refreshAssetsAfterNetworkChange, _AssetsController_refreshAssetsAfterNetworkAdded;
|
|
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");
|
|
@@ -193,8 +193,41 @@ function normalizeResponse(response) {
|
|
|
193
193
|
if (response.updateMode) {
|
|
194
194
|
normalized.updateMode = response.updateMode;
|
|
195
195
|
}
|
|
196
|
+
if (response.replaceCoveredChainBalances) {
|
|
197
|
+
normalized.replaceCoveredChainBalances = true;
|
|
198
|
+
}
|
|
196
199
|
return normalized;
|
|
197
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Merge account balances from a data-source response into prior state.
|
|
203
|
+
*
|
|
204
|
+
* @param previousBalances - Balances already in state for this account.
|
|
205
|
+
* @param accountBalances - Balances from the incoming response.
|
|
206
|
+
* @param customAssetIds - Custom assets to preserve when replacing covered chains.
|
|
207
|
+
* @param replaceCoveredChains - When true, drop prior balances on chains present
|
|
208
|
+
* in the response before applying it (authoritative chain slice).
|
|
209
|
+
* @returns The merged balance map for the account.
|
|
210
|
+
*/
|
|
211
|
+
function mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains) {
|
|
212
|
+
if (!replaceCoveredChains) {
|
|
213
|
+
return { ...previousBalances, ...accountBalances };
|
|
214
|
+
}
|
|
215
|
+
const coveredChains = new Set(Object.keys(accountBalances).map((assetId) => assetId.split('/')[0]));
|
|
216
|
+
const next = {};
|
|
217
|
+
for (const [assetId, balance] of Object.entries(previousBalances)) {
|
|
218
|
+
if (!coveredChains.has(assetId.split('/')[0])) {
|
|
219
|
+
next[assetId] = balance;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
Object.assign(next, accountBalances);
|
|
223
|
+
for (const customId of customAssetIds) {
|
|
224
|
+
if (!Object.prototype.hasOwnProperty.call(next, customId)) {
|
|
225
|
+
const prev = previousBalances[customId];
|
|
226
|
+
next[customId] = prev ?? { amount: '0' };
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return next;
|
|
230
|
+
}
|
|
198
231
|
// ============================================================================
|
|
199
232
|
// CONTROLLER IMPLEMENTATION
|
|
200
233
|
// ============================================================================
|
|
@@ -443,7 +476,11 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
443
476
|
]
|
|
444
477
|
: [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
|
|
445
478
|
const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, fastSources, request);
|
|
446
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
479
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
480
|
+
...response,
|
|
481
|
+
updateMode: 'merge',
|
|
482
|
+
replaceCoveredChainBalances: true,
|
|
483
|
+
});
|
|
447
484
|
// Background pipeline: snap and RPC run in parallel after the fast path
|
|
448
485
|
// commits to state. Their balances are merged together before detection.
|
|
449
486
|
// Token + price enrichment matches the pre-split behavior: only when basic
|
|
@@ -875,7 +912,10 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
875
912
|
]));
|
|
876
913
|
}
|
|
877
914
|
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, enrichmentSources, pipelineRequest, response);
|
|
878
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this,
|
|
915
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
916
|
+
...enrichedResponse,
|
|
917
|
+
replaceCoveredChainBalances: response.replaceCoveredChainBalances,
|
|
918
|
+
});
|
|
879
919
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_UPDATE_PIPELINE, {
|
|
880
920
|
source: sourceId,
|
|
881
921
|
duration_ms: performance.now() - updateStart,
|
|
@@ -1223,6 +1263,32 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1223
1263
|
finally {
|
|
1224
1264
|
releaseLock();
|
|
1225
1265
|
}
|
|
1266
|
+
}, _AssetsController_runStartupRefresh =
|
|
1267
|
+
/**
|
|
1268
|
+
* Force-fetch balances then subscribe. Used on unlock / first startup.
|
|
1269
|
+
*
|
|
1270
|
+
* @param accounts - Selected accounts to refresh.
|
|
1271
|
+
*/
|
|
1272
|
+
async function _AssetsController_runStartupRefresh(accounts) {
|
|
1273
|
+
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_accountRefreshMutex, "f").acquire();
|
|
1274
|
+
try {
|
|
1275
|
+
await this.getAssets(accounts, {
|
|
1276
|
+
chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
|
|
1277
|
+
forceUpdate: true,
|
|
1278
|
+
});
|
|
1279
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1280
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1281
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1282
|
+
}
|
|
1283
|
+
catch (error) {
|
|
1284
|
+
log('Failed to fetch assets on startup', error);
|
|
1285
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1286
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1287
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1288
|
+
}
|
|
1289
|
+
finally {
|
|
1290
|
+
releaseLock();
|
|
1291
|
+
}
|
|
1226
1292
|
}, _AssetsController_registerActionHandlers = function _AssetsController_registerActionHandlers() {
|
|
1227
1293
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
1228
1294
|
}, _AssetsController_handleActiveChainsUpdate = function _AssetsController_handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
|
|
@@ -1557,36 +1623,9 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1557
1623
|
for (const [accountId, accountBalances] of Object.entries(normalizedResponse.assetsBalance)) {
|
|
1558
1624
|
const previousBalances = previousState.assetsBalance[accountId] ?? {};
|
|
1559
1625
|
const customAssetIds = state.customAssets[accountId] ?? [];
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
// are never inadvertently reset to zero.
|
|
1564
|
-
// Merge: response overlays previous balances.
|
|
1565
|
-
const effective = mode === 'merge'
|
|
1566
|
-
? { ...previousBalances, ...accountBalances }
|
|
1567
|
-
: (() => {
|
|
1568
|
-
// Determine which chain namespaces this response covers.
|
|
1569
|
-
const coveredChains = new Set(Object.keys(accountBalances).map((assetId) => assetId.split('/')[0]));
|
|
1570
|
-
// Start from previous balances, dropping only entries for
|
|
1571
|
-
// chains this response is authoritative over.
|
|
1572
|
-
const next = {};
|
|
1573
|
-
for (const [assetId, balance] of Object.entries(previousBalances)) {
|
|
1574
|
-
if (!coveredChains.has(assetId.split('/')[0])) {
|
|
1575
|
-
next[assetId] = balance;
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
// Apply the response (authoritative for covered chains).
|
|
1579
|
-
Object.assign(next, accountBalances);
|
|
1580
|
-
// Preserve custom assets that the response omitted.
|
|
1581
|
-
for (const customId of customAssetIds) {
|
|
1582
|
-
if (!Object.prototype.hasOwnProperty.call(next, customId)) {
|
|
1583
|
-
const prev = previousBalances[customId];
|
|
1584
|
-
next[customId] =
|
|
1585
|
-
prev ?? { amount: '0' };
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
|
-
return next;
|
|
1589
|
-
})();
|
|
1626
|
+
const replaceCoveredChains = mode === 'full' ||
|
|
1627
|
+
normalizedResponse.replaceCoveredChainBalances === true;
|
|
1628
|
+
const effective = mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains);
|
|
1590
1629
|
// Ensure native tokens have an entry (0 if missing) for chains this account supports
|
|
1591
1630
|
const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
|
|
1592
1631
|
const nativeAssetIdsForAccount = account
|
|
@@ -1785,14 +1824,8 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1785
1824
|
enabledChainCount: chainIds.length,
|
|
1786
1825
|
});
|
|
1787
1826
|
__classPrivateFieldSet(this, _AssetsController_lastKnownAccountIds, new Set(accounts.map((a) => a.id)), "f");
|
|
1788
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m",
|
|
1789
|
-
|
|
1790
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1791
|
-
this.getAssets(accounts, {
|
|
1792
|
-
chainIds,
|
|
1793
|
-
forceUpdate: true,
|
|
1794
|
-
}).catch((error) => {
|
|
1795
|
-
log('Failed to fetch assets', error);
|
|
1827
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runStartupRefresh).call(this, accounts).catch((error) => {
|
|
1828
|
+
log('Failed to start asset tracking', error);
|
|
1796
1829
|
});
|
|
1797
1830
|
}, _AssetsController_stop = function _AssetsController_stop() {
|
|
1798
1831
|
log('Stopping asset tracking', {
|