Skip to content

chore: bump assets-controller - #36604

Closed
Kriys94 wants to merge 8 commits into
mainfrom
chore/bumpAssetsController4
Closed

Kriys94 wants to merge 8 commits into
mainfrom
chore/bumpAssetsController4

Conversation

@Kriys94

@Kriys94 Kriys94 commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Description

Resolves @metamask/assets-controller to the preview package @metamask-previews/assets-controller@16.1.0-preview-b1e33e9f1 so mobile can pick up the latest AssetsController changes before a published core release.

Changelog

CHANGELOG entry: null

Related issues

Fixes: N/A

Manual testing steps

N/A — dependency resolution bump only. Confirm @metamask/assets-controller resolves to 16.1.0-preview-b1e33e9f1 after install, then spot-check the wallet asset list and balances.

Screenshots/Recordings

N/A — no UI change in this bump.

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
  • I've tested with a power user scenario
  • I've instrumented key operations with Sentry traces for production performance metrics

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamask-ci

metamask-ci Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

PR template — items to address before "Ready for review"

Warnings — informational, address before merging:

See docs/readme/ready-for-review.md for the full Definition of Ready for Review.

@socket-security

socket-security Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​tanstack/​query-core@​5.103.2961007698100
Addednpm/​@​metamask-previews/​assets-controller@​16.1.1-preview-33429d645821007998100
Updatednpm/​@​metamask/​assets-controllers@​112.0.2 ⏵ 112.0.398 +110091100100

View full report

@Kriys94 Kriys94 added the no-changelog no-changelog Indicates no external facing user changes, therefore no changelog documentation needed label Sep 21, 2026
@sonarqubecloud

Copy link
Copy Markdown

@github-actions github-actions Bot added size-L and removed size-XS labels Sep 23, 2026
@github-actions

github-actions Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Smart E2E Test Selection

Selected E2E tags: ALL

Selected Performance tags

@PerformanceAssetLoading
@PerformanceLaunch

AI Confidence: 100

E2E reasoning

Expand to read

This PR has critical-level changes across multiple core areas:

  1. @metamask/assets-controller preview version update (package.json): A preview version of the assets-controller is being used (16.1.1-preview-33429d645). This is a core controller that drives asset display, balances, and token management across the entire app. Any behavioral changes in this controller could break asset loading in Wallet, Bridge, Confirmations, Perps, Stake, and more.

  2. Migration 153 (new state migration): Strips Arc ERC-20 USDC from AssetsController state (customAssets, assetsBalance, assetMetadata, assetPreferences). State migrations are critical — they run on app startup for existing users and can corrupt state if incorrect.

  3. AssetPollingProvider deleted: This component was removed from Wallet home view, TokensFullView, confirm-component, and Perps routes. This changes how assets are polled/loaded in these views. The Arc default token bootstrap effect (useArcDefaultTokens) was also removed. This affects SmokeWalletPlatform, SmokeConfirmations, SmokePerps, SmokeStake, SmokeSwap.

  4. ConfirmationAssetPollingProvider deleted: Removed from confirmation flows and Perps confirmation screen. Affects SmokeConfirmations and SmokePerps.

  5. useAssetVisibility async change: handleHideToken is now async, awaiting AssetsController.unhideAsset and MultichainAssetsController.addAssets. This affects token hide/unhide flows in TokenDetails.

  6. SearchTokenAutocomplete guard: Added isCaipAssetType validation — affects token search/add flows (SmokeWalletPlatform, SmokeNetworkAbstractions).

  7. Arc constants moved: ARC_NATIVE_ASSET_ID, ARC_USDC_ASSET_ID moved from useArcDefaultTokens hook to enablement/assets/arc.ts — affects Bridge token selector and useTokensWithBalances (SmokeSwap).

The combination of a preview controller version, a new state migration, and removal of asset polling infrastructure across Wallet, Confirmations, and Perps warrants running ALL E2E tests. The hard rule seed also mandates ALL due to the controller version update. The blast radius spans virtually every user-facing flow: wallet home, confirmations, bridge/swap, perps, stake, token management, and network management.

Performance reasoning

Expand to read

Two performance areas are potentially impacted: 1) @PerformanceAssetLoading - The removal of AssetPollingProvider from Wallet home and TokensFullView changes how assets are loaded. The assets-controller preview version update could affect balance fetching and token list rendering performance. 2) @PerformanceLaunch - Migration 153 runs on app startup for existing users, and the assets-controller version change could affect cold start time. The removal of polling infrastructure could either improve or degrade asset loading performance on launch.

View run

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Performance Test Results

ℹ️ Performance test results are currently non-blocking and will not block this PR.

❌ 1 test failed · 6 tests · 1 device

📱 Devices tested (1)

Android: Google Pixel 8 Pro (v14.0)

❌ Failed Tests (1)

🔬 App profiling vs main is included under each failed scenario that has a prior baseline.

@metamask-mobile-platform

Measure Warm Start: Warm Start to Login Screen

Platform Device Reason Recording
Android Google Pixel 8 Pro (v14.0) no_performance_metrics 📹 Watch

🔬 App profiling check · Current run 36105983861 · Baseline (last green on main) run 35635949154 @ 7bdb9cb

Summary: ⚠️ 4 metrics over +10%: CPU avg (+1.56 (+22.7%)), Memory avg (+71.78 (+12.8%)), Slow frames (+47.9 (+383.2%)), Critical issues (+1 (+100%))

ℹ️ API calls unavailable: Network logs API error: Bad Request

Full metric table (+10% variance rules)

Disclaimer — allowed variance: a +10% margin over the baseline is permitted.

  • If Current <= Baseline + 10%, treated as acceptable noise.
  • If Current > Baseline + 10%, Current and variance % are highlighted with ⚠️.
Metric Baseline Current Δ
CPU avg 6.88% 8.44% +1.56 (+22.7%) ⚠️
CPU max 21.63% 20.31% -1.32 (-6.1%)
Memory avg 560.41 MB 632.19 MB +71.78 (+12.8%) ⚠️
Memory max 712.95 MB 749.79 MB +36.84 (+5.2%)
Slow frames 12.5% 60.4% +47.9 (+383.2%) ⚠️
Frozen frames 0% 0% 0 (0%)
ANRs 0 0 0 (0%)
Issues 2 2 0 (0%)
Critical issues 1 2 +1 (+100%) ⚠️
App size 396.81 MB 398.7 MB +1.89 (+0.5%)
✅ Passed Tests (5)
Test Platform Device Duration Team Recording
Aggregated Balance Loading Time, SRP 1 + SRP 2 + SRP 3 Android Google Pixel 8 Pro (v14.0) 8.65s @assets-dev-team 📹 Watch
Asset View, SRP 1 + SRP 2 + SRP 3 Android Google Pixel 8 Pro (v14.0) 1.82s @assets-dev-team 📹 Watch
Cold Start: Measure ColdStart To Login Screen Android Google Pixel 8 Pro (v14.0) 0.00s @metamask-mobile-platform 📹 Watch
Measure Warm Start: Login To Wallet Screen Android Google Pixel 8 Pro (v14.0) 0.00s @metamask-mobile-platform 📹 Watch
Measure Cold Start To Onboarding Screen Android Google Pixel 8 Pro (v14.0) 0.45s @metamask-mobile-platform 📹 Watch

Branch: chore/bumpAssetsController4 · Build: E2E · Commit: 0dc54aa · View full run

pull Bot pushed a commit to Reality2byte/core that referenced this pull request Sep 25, 2026
## Explanation

<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

Mobile preview: MetaMask/metamask-mobile#36604
Extension preview:
MetaMask/metamask-extension#46451

Architecture walkthrough:
[`packages/assets-controller/docs/architecture/v1/CHANGES.md`](packages/assets-controller/docs/architecture/v1/CHANGES.md)

**Onboarding**
- Current logic + v5:
https://www.loom.com/share/c55eed16333749e29d99cbda87ca4d9e
- After PR + v6:
https://www.loom.com/share/6f443eda5f344d7aa1733c3b5bf7ea4e

**Start / basic flows (change account, network, add/remove custom
tokens, add non-supported network)**
- Current logic + v5:
https://www.loom.com/share/d5fdd69c1f384c0a97574729773d578f
- After PR + v6:
https://www.loom.com/share/4753a4fd68c54a58abed48e728836760

**Transactions**
- Current logic + v5:
https://www.loom.com/share/fbc0e58acc9e435694dc6f2f2dfb6d6f
- After PR + v6:
https://www.loom.com/share/5b3b1cf5f58f4e6fa31de34f30cc01a9

**Fallback**
- Current logic + v5:
https://www.loom.com/share/16f95d2b237e4b63ab0f68e5d2d18cb1
- After PR + v6:
https://www.loom.com/share/d34beee512d041b19ccb1869cef5c327
- After PR + v6 + custom tokens:
https://www.loom.com/share/11f342e1ac1e4644a695403a536b9780

### Why

Accounts API **v6** can take pinned custom tokens (`includeAssetIds`)
and return them in the balance snapshot even at zero balance, and can
drop hidden tokens (`excludeAssetIds`). Once the API owns that, the
client does not need a parallel custom-token path on the v6 flow.

v5 stays intact. Which path runs is decided only in
`AssetsController.#isBalanceV6Enabled()` (`assetsAccountsApiV6 ===
true`).

### What v6 does

- Subscribe and force refresh assign **accounts + chains only**. Pins
and hides are **not** copied onto `DataRequest`.
- `AccountsApiDataSource` reads controller state via a required
`getAssetsState` getter:
  - visible pins on fetched chains → `includeAssetIds`
  - hidden assets on fetched chains → `excludeAssetIds`
  - a hide wins over a pin
- `request.customAssets` is only a **scoped override** (`getAssets({
customAssets })`, `addCustomAsset`, RPC fallback).
- Accounts API reports `updateMode: 'full'`. `mergeAccountBalancesV6`
replaces the covered chain slice, keeps `unprocessedCustomAssets` and
staked vault balances, and re-asserts default tracked assets (mUSD) when
the snapshot omits a zero balance.
- RPC fallback recovers errored chains and pins listed in
`unprocessedCustomAssets`.
- Account Activity ignores pins/hides.
- Token-detection filtering is **not** applied; the v6 snapshot is kept
in full.
- `CustomAssetGraduationMiddleware` does **not** run on this path. There
is **no** `customAssetsOnly` RPC supplement.

### What v5 still does (flag off)

Unchanged from production:

- Force update attaches every pin (including hidden) on
`DataRequest.customAssets`.
- Extra RPC poll (`customAssetsOnly`) for pins on chains another source
already owns.
- `updateMode: 'merge'` with `replaceCoveredChainBalances`.
- `CustomAssetGraduationMiddleware` on Accounts API and Account Activity
updates.

### Breaking

- Remove `excludeAssetIds` from `DataRequest`. v6 builds the query param
from `assetPreferences`.
- `AccountsApiDataSource` now requires `getAssetsState`.
`AssetsController` injects `() => this.state`.

`CustomAssetGraduationMiddleware`, `customAssetsOnly`, and
`replaceCoveredChainBalances` stay on the v5 path and are **not**
removed from the public API.

## References

<!--
Are there any issues that this pull request is tied to?
Are there other links that reviewers should consult to understand these
changes better?
Are there client or consumer pull requests to adopt any breaking
changes?

For example:

* Fixes #12345
* Related to #67890
-->

- [APIPLAT-2499](https://consensys.atlassian.net/browse/APIPLAT-2499) —
v6 `includeAssetIds` for pinned / zero-balance custom tokens
- Architecture:
[`packages/assets-controller/docs/architecture/v1/CHANGES.md`](packages/assets-controller/docs/architecture/v1/CHANGES.md)
- Clients:
[metamask-mobile#36604](MetaMask/metamask-mobile#36604),
[metamask-extension#46451](MetaMask/metamask-extension#46451)

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [x] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them


[APIPLAT-2499]:
https://consensyssoftware.atlassian.net/browse/APIPLAT-2499?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **High Risk**
> This is a breaking, flag-gated rewrite of how wallet balances are
fetched, merged, and pruned—core UI/send/swap state—with many edge cases
around full replaces, hidden/pinned tokens, and RPC/API fallbacks.
> 
> **Overview**
> **Breaking:** `@metamask/assets-controller` now runs two separate
balance pipelines behind `assetsAccountsApiV6`. With the flag on, the
client declares the visible set (`includeAssetIds` / `excludeAssetIds`
from shared `getAssetVisibility`), Accounts API / Snap / RPC stamp
**`full`** snapshots, and state merges via `effectiveAccountBalancesV6`
(pins, natives, default tracked assets, and staking survive omission;
detected/hidden tokens can drop). With the flag off, the existing **v5**
merge + `replaceCoveredChainBalances` path is unchanged, including
custom-asset graduation and the supplemental `customAssetsOnly` RPC
poll.
> 
> **API / wiring changes:** `'update'` is removed from
`AssetsUpdateMode`; `getAssets` no longer accepts `updateMode` (sources
set it on responses). `getAssetsState` / `getAssetVisibility` are
required on Accounts API, Snap, and RPC constructors (removed from
pipeline `Context` / subscriptions). `unhideAsset` is **async** and
force-fetches the chain like `addCustomAsset`; hide/unhide re-run
subscriptions. New zero-balance helpers (`getZeroAssetBalance`, Stellar
trustline metadata) replace plain `{ amount: '0' }` in several paths.
The flag is treated as enabled when `assetsAccountsApiV6 === true` (not
a nested `{ value }` object).
> 
> Adds an ADR, changelog entries, broad unit/integration tests (v6
visibility, RPC fallback on failed chains, full vs merge behavior), and
a BSC spam case where user-imported custom tokens are kept under v6.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d273088. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
FrederikBolding pushed a commit to MetaMask/core that referenced this pull request Sep 28, 2026
## Explanation

<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

Mobile preview: MetaMask/metamask-mobile#36604
Extension preview:
MetaMask/metamask-extension#46451

Architecture walkthrough:
[`packages/assets-controller/docs/architecture/v1/CHANGES.md`](packages/assets-controller/docs/architecture/v1/CHANGES.md)

**Onboarding**
- Current logic + v5:
https://www.loom.com/share/c55eed16333749e29d99cbda87ca4d9e
- After PR + v6:
https://www.loom.com/share/6f443eda5f344d7aa1733c3b5bf7ea4e

**Start / basic flows (change account, network, add/remove custom
tokens, add non-supported network)**
- Current logic + v5:
https://www.loom.com/share/d5fdd69c1f384c0a97574729773d578f
- After PR + v6:
https://www.loom.com/share/4753a4fd68c54a58abed48e728836760

**Transactions**
- Current logic + v5:
https://www.loom.com/share/fbc0e58acc9e435694dc6f2f2dfb6d6f
- After PR + v6:
https://www.loom.com/share/5b3b1cf5f58f4e6fa31de34f30cc01a9

**Fallback**
- Current logic + v5:
https://www.loom.com/share/16f95d2b237e4b63ab0f68e5d2d18cb1
- After PR + v6:
https://www.loom.com/share/d34beee512d041b19ccb1869cef5c327
- After PR + v6 + custom tokens:
https://www.loom.com/share/11f342e1ac1e4644a695403a536b9780

### Why

Accounts API **v6** can take pinned custom tokens (`includeAssetIds`)
and return them in the balance snapshot even at zero balance, and can
drop hidden tokens (`excludeAssetIds`). Once the API owns that, the
client does not need a parallel custom-token path on the v6 flow.

v5 stays intact. Which path runs is decided only in
`AssetsController.#isBalanceV6Enabled()` (`assetsAccountsApiV6 ===
true`).

### What v6 does

- Subscribe and force refresh assign **accounts + chains only**. Pins
and hides are **not** copied onto `DataRequest`.
- `AccountsApiDataSource` reads controller state via a required
`getAssetsState` getter:
  - visible pins on fetched chains → `includeAssetIds`
  - hidden assets on fetched chains → `excludeAssetIds`
  - a hide wins over a pin
- `request.customAssets` is only a **scoped override** (`getAssets({
customAssets })`, `addCustomAsset`, RPC fallback).
- Accounts API reports `updateMode: 'full'`. `mergeAccountBalancesV6`
replaces the covered chain slice, keeps `unprocessedCustomAssets` and
staked vault balances, and re-asserts default tracked assets (mUSD) when
the snapshot omits a zero balance.
- RPC fallback recovers errored chains and pins listed in
`unprocessedCustomAssets`.
- Account Activity ignores pins/hides.
- Token-detection filtering is **not** applied; the v6 snapshot is kept
in full.
- `CustomAssetGraduationMiddleware` does **not** run on this path. There
is **no** `customAssetsOnly` RPC supplement.

### What v5 still does (flag off)

Unchanged from production:

- Force update attaches every pin (including hidden) on
`DataRequest.customAssets`.
- Extra RPC poll (`customAssetsOnly`) for pins on chains another source
already owns.
- `updateMode: 'merge'` with `replaceCoveredChainBalances`.
- `CustomAssetGraduationMiddleware` on Accounts API and Account Activity
updates.

### Breaking

- Remove `excludeAssetIds` from `DataRequest`. v6 builds the query param
from `assetPreferences`.
- `AccountsApiDataSource` now requires `getAssetsState`.
`AssetsController` injects `() => this.state`.

`CustomAssetGraduationMiddleware`, `customAssetsOnly`, and
`replaceCoveredChainBalances` stay on the v5 path and are **not**
removed from the public API.

## References

<!--
Are there any issues that this pull request is tied to?
Are there other links that reviewers should consult to understand these
changes better?
Are there client or consumer pull requests to adopt any breaking
changes?

For example:

* Fixes #12345
* Related to #67890
-->

- [APIPLAT-2499](https://consensys.atlassian.net/browse/APIPLAT-2499) —
v6 `includeAssetIds` for pinned / zero-balance custom tokens
- Architecture:
[`packages/assets-controller/docs/architecture/v1/CHANGES.md`](packages/assets-controller/docs/architecture/v1/CHANGES.md)
- Clients:
[metamask-mobile#36604](MetaMask/metamask-mobile#36604),
[metamask-extension#46451](MetaMask/metamask-extension#46451)

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [x] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them


[APIPLAT-2499]:
https://consensyssoftware.atlassian.net/browse/APIPLAT-2499?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **High Risk**
> This is a breaking, flag-gated rewrite of how wallet balances are
fetched, merged, and pruned—core UI/send/swap state—with many edge cases
around full replaces, hidden/pinned tokens, and RPC/API fallbacks.
> 
> **Overview**
> **Breaking:** `@metamask/assets-controller` now runs two separate
balance pipelines behind `assetsAccountsApiV6`. With the flag on, the
client declares the visible set (`includeAssetIds` / `excludeAssetIds`
from shared `getAssetVisibility`), Accounts API / Snap / RPC stamp
**`full`** snapshots, and state merges via `effectiveAccountBalancesV6`
(pins, natives, default tracked assets, and staking survive omission;
detected/hidden tokens can drop). With the flag off, the existing **v5**
merge + `replaceCoveredChainBalances` path is unchanged, including
custom-asset graduation and the supplemental `customAssetsOnly` RPC
poll.
> 
> **API / wiring changes:** `'update'` is removed from
`AssetsUpdateMode`; `getAssets` no longer accepts `updateMode` (sources
set it on responses). `getAssetsState` / `getAssetVisibility` are
required on Accounts API, Snap, and RPC constructors (removed from
pipeline `Context` / subscriptions). `unhideAsset` is **async** and
force-fetches the chain like `addCustomAsset`; hide/unhide re-run
subscriptions. New zero-balance helpers (`getZeroAssetBalance`, Stellar
trustline metadata) replace plain `{ amount: '0' }` in several paths.
The flag is treated as enabled when `assetsAccountsApiV6 === true` (not
a nested `{ value }` object).
> 
> Adds an ADR, changelog entries, broad unit/integration tests (v6
visibility, RPC fallback on failed chains, full vs merge behavior), and
a BSC spam case where user-imported custom tokens are kept under v6.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d273088. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@Kriys94 Kriys94 closed this Sep 29, 2026
@Kriys94
Kriys94 deleted the chore/bumpAssetsController4 branch September 29, 2026 12:14
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 29, 2026

This branch was successfully deployed

1 active deployment
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

no-changelog no-changelog Indicates no external facing user changes, therefore no changelog documentation needed size-XL team-assets

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant