Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
0548318
feat(wallet): add opt-in AssetsController initialization
dawnseeker8 Oct 19, 2026
3ef01a9
docs(wallet): link AssetsController changelog entries to the PR
dawnseeker8 Oct 19, 2026
d687d3a
Merge branch 'main' into feat/assets-3641-wallet-assets-controller
dawnseeker8 Oct 20, 2026
0833a6b
Merge remote-tracking branch 'origin/main' into feat/assets-3641-wall…
dawnseeker8 Oct 22, 2026
55fcf3e
Merge remote-tracking branch 'origin/feat/assets-3641-wallet-assets-c…
dawnseeker8 Oct 22, 2026
9da565b
Merge remote-tracking branch 'origin/main' into feat/assets-3641-wall…
dawnseeker8 Oct 28, 2026
3b6272a
feat(assets-controller): read enabled chains after construction
dawnseeker8 Oct 28, 2026
38267f0
Merge branch 'main' into feat/assets-3641-wallet-assets-controller
dawnseeker8 Oct 28, 2026
cd3925c
test(assets-controller): fix the enabled-chain fixture types
dawnseeker8 Oct 28, 2026
5669a8a
test(assets-controller): satisfy oxlint in the enabled-chain tests
dawnseeker8 Oct 28, 2026
91ce192
fix(assets-controller): keep the init note under Unreleased
dawnseeker8 Oct 28, 2026
bbbbbb9
Merge branch 'main' into feat/assets-3641-wallet-assets-controller
dawnseeker8 Oct 28, 2026
8a848b7
Merge branch 'main' into feat/assets-3641-wallet-assets-controller
dawnseeker8 Oct 29, 2026
4fa64d5
fix(wallet): require @metamask/assets-controller ^20.0.2
dawnseeker8 Oct 29, 2026
32caec8
Merge branch 'main' into feat/assets-3641-wallet-assets-controller
dawnseeker8 Oct 29, 2026
4060903
fix(assets-controller): refresh data source active chains in init()
dawnseeker8 Oct 29, 2026
a8d1c7b
fix(assets-controller): read enabled chains in init instead of the co…
cursoragent Oct 29, 2026
c606824
Merge branch 'main' into feat/assets-3641-wallet-assets-controller
dawnseeker8 Oct 29, 2026
6204d60
Merge remote-tracking branch 'origin/main' into feat/assets-3641-wall…
cursoragent Nov 2, 2026
1246f7d
Merge branch 'main' into feat/assets-3641-wallet-assets-controller
dawnseeker8 Nov 2, 2026
3a7ec4a
feat(wallet): initialize AssetsController by default
cursoragent Nov 2, 2026
4025d6d
Removed the anti pattern code and fix the test file.
dawnseeker8 Nov 2, 2026
aad2df5
chore: remove local cursor hook state file
cursoragent Nov 2, 2026
67efa4c
fix(assets-controller): refresh assets on account switch without acco…
cursoragent Nov 2, 2026
460aec8
Merge branch 'feat/assets-3641-wallet-assets-controller' of https://g…
cursoragent Nov 2, 2026
472c8e8
fix(assets-controller): correct deferred-init test types
cursoragent Nov 2, 2026
fc535b2
fix(assets-controller): refresh account switches during startup
cursoragent Nov 2, 2026
f9a30b8
Merge branch 'main' into feat/assets-3641-wallet-assets-controller
dawnseeker8 Nov 2, 2026
15449e1
Merge remote-tracking branch 'origin/main' into feat/assets-3641-wall…
cursoragent Nov 3, 2026
c8db489
Merge remote-tracking branch 'origin/main' into feat/assets-3641-wall…
dawnseeker8 Nov 3, 2026
e753bce
Merge origin/main into feat/assets-3641-wallet-assets-controller
cursoragent Nov 3, 2026
a895268
Update packages/assets-controller/src/data-sources/AccountsApiDataSou…
dawnseeker8 Nov 3, 2026
5abb39b
fix: make Accounts API data source init idempotent
cursoragent Nov 3, 2026
3862d52
Merge remote-tracking branch 'origin/main' into feat/assets-3641-wall…
dawnseeker8 Nov 3, 2026
7bbff7d
fix: align wallet assets controller dependency
cursoragent Nov 3, 2026
b0700d9
Merge remote-tracking branch 'origin/feat/assets-3641-wallet-assets-c…
cursoragent Nov 3, 2026
f864c38
fix(wallet): drop stale assets-controller lockfile descriptor
dawnseeker8 Nov 3, 2026
3c38435
Merge branch 'main' into feat/assets-3641-wallet-assets-controller
dawnseeker8 Nov 3, 2026
fbb3766
fix(wallet): drop redundant AssetsController queryApiClient guard
cursoragent Nov 3, 2026
e5624fd
Merge remote-tracking branch 'origin/main' into feat/assets-3641-wall…
cursoragent Nov 4, 2026
30efc6b
Merge branch 'main' into feat/assets-3641-wallet-assets-controller
dawnseeker8 Nov 4, 2026
636b56d
refactor(assets-controller): create data sources in start() instead o…
dawnseeker8 Nov 4, 2026
8093c7c
fix(assets-controller): wait for Accounts API chains before the first…
cursoragent Nov 4, 2026
8b8e85c
Revert "fix(assets-controller): wait for Accounts API chains before t…
cursoragent Nov 4, 2026
713f7d7
fix(assets-controller): wait for Accounts API chains before the first…
dawnseeker8 Nov 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,7 @@
/packages/wallet/src/initialization/instances/accounts-controller/ @MetaMask/accounts-engineers
/packages/wallet/src/initialization/instances/address-book-controller/ @MetaMask/confirmations
/packages/wallet/src/initialization/instances/approval-controller/ @MetaMask/confirmations
/packages/wallet/src/initialization/instances/assets-controller/ @MetaMask/metamask-assets
/packages/wallet/src/initialization/instances/claims-controller/ @MetaMask/web3auth
/packages/wallet/src/initialization/instances/claims-service/ @MetaMask/web3auth
/packages/wallet/src/initialization/instances/client-controller/ @MetaMask/core-platform @MetaMask/extension-platform @MetaMask/mobile-platform
Expand Down
1 change: 1 addition & 0 deletions codeowners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const config = {
},
'assets-controller': {
teams: ['@MetaMask/metamask-assets'],
initializationPath: 'assets-controller',
},
'assets-controllers': {
teams: ['@MetaMask/metamask-assets'],
Expand Down
14 changes: 14 additions & 0 deletions packages/assets-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add `start()` and the `AssetsController:start` messenger action ([#10885](https://github.com/MetaMask/core/pull/10885))
- `start()` reads enabled networks from `NetworkEnablementController:getState`, creates the data sources, subscribes to external events and to `subscribeToBasicFunctionalityChange`, waits for the Accounts API supported networks, runs the unlock cleanups when the keyring is already unlocked, and starts asset tracking when the UI is open, the keyring is unlocked and the account tree is initialized.
- Call it once the client has constructed and initialized the controllers `AssetsController` depends on, such as `AccountTreeController` and `SnapController`. Repeated calls return the same promise; calls after `destroy()` do nothing.
- Export the `AssetsControllerStartAction` type ([#10885](https://github.com/MetaMask/core/pull/10885))

### Changed

- **BREAKING:** The `AssetsController` constructor no longer calls messenger actions, creates data sources or subscribes to external events; asset tracking does not run until `start()` is called ([#10885](https://github.com/MetaMask/core/pull/10885))
- Call `start()` (or the `AssetsController:start` action) after the controllers `AssetsController` depends on are registered. Data sources are created in `start()`, so their constructors still read `NetworkController`, `NetworkEnablementController`, `SnapController`, `PermissionController` and `RemoteFeatureFlagController` as before, only later.
- `subscribeToBasicFunctionalityChange` is invoked by `start()` instead of the constructor.
- Before `start()`, `getAssets` (and the methods built on it) with `forceUpdate: true` return what is already in state without fetching and without changing `assetsLoadingStatus`; `handleAssetsUpdate`, `syncAssetsPrices`, `subscribeAssetsPrice` and `handleBasicFunctionalityChange` do nothing; `setSelectedCurrency` updates state without refreshing prices.

### Fixed

- Stop removing launchpad tokens as spam: EVM ERC-20s below the occurrence floor are now kept when Token API `/v2/assets` identifies them as launchpad tokens and their security data does not classify them as malicious ([#11251](https://github.com/MetaMask/core/pull/11251))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,47 @@

import type { AssetsController } from './AssetsController.js';

/**
* Start the controller once every controller it depends on is registered.
*
* The constructor does not touch other controllers. `start()` reads enabled
* networks, creates the data sources (whose constructors read network, snap
* and feature-flag state), subscribes to external events and to
* basic-functionality changes, and begins asset tracking when the UI is
* open, the keyring is unlocked and the account tree is initialized.
*
* Call it after the client has constructed and initialized its own
* controllers, such as `AccountTreeController` and `SnapController`.
* Until then, asset tracking does not run: forced fetches return what is
* already in state, and pushed updates are ignored.
*
* Repeated calls return the same promise. Calls after `destroy()` do
* nothing.
*
* @returns A promise that resolves once the controller has started.
*/
export type AssetsControllerStartAction = {
type: `AssetsController:start`;
handler: AssetsController['start'];
};

/**
* Get assets for the given accounts, optionally force-fetching them first.
*
* Before `start()` there are no data sources, so a forced fetch is skipped
* and the assets already in state are returned. The loading status of the
* accounts is left untouched, so the first fetch after `start()` still
* reports them as loading.
*
* @param accounts - Accounts to get assets for.
* @param options - Fetch options.
* @param options.chainIds - Chains to include. Defaults to the enabled chains.
* @param options.assetTypes - Asset types to include. Defaults to fungible.
* @param options.forceUpdate - Fetch from the data sources before reading state.
* @param options.bypassServerCache - Also bypass server-side HTTP caches.
* @param options.dataTypes - Data types to fetch.
* @returns Assets keyed by account ID and asset ID.
*/
export type AssetsControllerGetAssetsAction = {
type: `AssetsController:getAssets`;
handler: AssetsController['getAssets'];
Expand Down Expand Up @@ -217,6 +258,7 @@ export type AssetsControllerSetSelectedCurrencyAction = {
* Union of all AssetsController action types.
*/
export type AssetsControllerMethodActions =
| AssetsControllerStartAction
| AssetsControllerGetAssetsAction
| AssetsControllerSyncAssetsPricesAction
| AssetsControllerGetAssetsBalanceAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ async function withController<ReturnValue>(
queryApiClient,
isBasicFunctionality: (): boolean => true,
});
await controller.start();

try {
return await fn({ controller, messenger: rootMessenger });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ async function withController<ReturnValue>(
queryApiClient,
isBasicFunctionality: (): boolean => true,
});
await controller.start();

try {
return await fn({ controller, messenger: rootMessenger });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ async function withController<ReturnValue>(
queryApiClient,
isBasicFunctionality: (): boolean => true,
});
await controller.start();

try {
return await fn({ controller, messenger: rootMessenger });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ async function withController<ReturnValue>(
isBasicFunctionality,
captureException,
});
await controller.start();

try {
return await fn({ controller, messenger: rootMessenger });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ async function withController<ReturnValue>(
isBasicFunctionality,
captureException,
});
await controller.start();

try {
return await fn({ controller, messenger: rootMessenger });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ async function withStaleBalanceController<ReturnValue>(
queryApiClient,
isBasicFunctionality: (): boolean => true,
});
await controller.start();

try {
// `AccountsApiDataSource` loads `/v2/supportedNetworks` asynchronously
Expand Down
Loading
Loading