Skip to content

feat(wallet): wire PreferencesController into default initialization#9232

Open
sirtimid wants to merge 4 commits into
mainfrom
sirtimid/wire-preferences-controller
Open

feat(wallet): wire PreferencesController into default initialization#9232
sirtimid wants to merge 4 commits into
mainfrom
sirtimid/wire-preferences-controller

Conversation

@sirtimid

@sirtimid sirtimid commented Jun 23, 2026

Copy link
Copy Markdown
Member

Explanation

Wires the @metamask/preferences-controller package into @metamask/wallet's default initialization. The default Wallet now constructs a PreferencesController and exposes its PreferencesController:* messenger actions (getState/stateChange plus the preference setters).

References

Client construction sites (live main):

Jira: N/A

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed, highlighting breaking changes as necessary
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes (extension + mobile adoption PRs are follow-ups)

🤖 Generated with Claude Code


Note

Medium Risk
Breaking messenger registration affects extension/mobile upgrade paths, though override-by-name is supported and behavior is covered by tests.

Overview
The default Wallet now bootstraps PreferencesController from @metamask/preferences-controller, exposing PreferencesController:* messenger actions (state and preference setters) on the wallet messenger and PreferencesController on wallet state.

This is a breaking change for apps that already register their own PreferencesController on a shared messenger—they must drop duplicate wiring or face action registration collisions. Clients with a superset controller can still replace the default via initializationConfigurations with the same name.

The package also exports InitializationConfiguration, InitFunctionArguments, and InstanceState so consumers can type custom init overrides. Dependency graph, TS project references, CODEOWNERS, and tests cover the new default and override path.

Reviewed by Cursor Bugbot for commit 55f1664. Bugbot is set up for automated code reviews on this repo. Configure here.

sirtimid added a commit that referenced this pull request Jun 23, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sirtimid sirtimid marked this pull request as ready for review June 23, 2026 11:46
@sirtimid sirtimid requested a review from a team as a code owner June 23, 2026 11:46
@sirtimid sirtimid temporarily deployed to default-branch June 23, 2026 11:46 — with GitHub Actions Inactive
@sirtimid sirtimid requested a review from FrederikBolding June 23, 2026 11:46
sirtimid and others added 2 commits June 23, 2026 15:26
Add `PreferencesController` to the default wallet initialization set. It
has no cross-controller messenger dependencies and its only constructor
inputs are `messenger` and `state`, so it wires with a plain namespaced
child messenger and no `instanceOptions` slot — per-client values are
supplied through the existing `state.PreferencesController` initial state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sirtimid sirtimid force-pushed the sirtimid/wire-preferences-controller branch from e951604 to a8fd340 Compare June 23, 2026 13:28

@FrederikBolding FrederikBolding left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before we can do this, we will need metamask-extension and metamask-mobile to both be using PreferencesController from core.

Today they have diverged unfortunately.

EDIT: In theory, we may be able to wire in PreferencesController to wallet and override the initialization on extension to use the diverging version. But will depend on whether their state overlaps enough.

@sirtimid

sirtimid commented Jun 23, 2026

Copy link
Copy Markdown
Member Author

Before we can do this, we will need metamask-extension and metamask-mobile to both be using PreferencesController from core.

Today they have diverged unfortunately.

EDIT: In theory, we may be able to wire in PreferencesController to wallet and override the initialization on extension to use the diverging version. But will depend on whether their state overlaps enough.

@FrederikBolding Mobile is already on vanilla core @metamask/preferences-controller@23.1.0 (no patch/subclass) its adoption is a one-PR swap. Extension's superset can't realistically converge to core soon (26 extra fields, nested preferences, 34 extra actions, ~107+ UI refs), but it doesn't need to: it adopts via an initializationConfigurations override that supplies its existing controller under the PreferencesController name (delegating its two AccountsController actions), which the wallet library supports for exactly this case. Nothing in the wallet's wired set reads PreferencesController state yet, so the shape divergence is safe today and gets reconciled per-field only when a wallet-wired consumer needs it. So the gate isn't "both on core first", it's "extension ships the override in the same step it bumps the wallet release." Happy to prototype that override config to de-risk if you want.

@sirtimid

Copy link
Copy Markdown
Member Author

@metamaskbot publish-previews

@FrederikBolding

FrederikBolding commented Jun 23, 2026

Copy link
Copy Markdown
Member

@FrederikBolding Mobile is already on vanilla core @metamask/preferences-controller@23.1.0 (no patch/subclass) its adoption is a one-PR swap. Extension's superset can't realistically converge to core soon (26 extra fields, nested preferences, 34 extra actions, ~107+ UI refs), but it doesn't need to: it adopts via an initializationConfigurations override that supplies its existing controller under the PreferencesController name (delegating its two AccountsController actions), which the wallet library supports for exactly this case. Nothing in the wallet's wired set reads PreferencesController state yet, so the shape divergence is safe today and gets reconciled per-field only when a wallet-wired consumer needs it. So the gate isn't "both on core first", it's "extension ships the override in the same step it bumps the wallet release." Happy to prototype that override config to de-risk if you want.

Yeah, I realized that and added my EDIT.

Have you verified that the controller state on extension is a superset of the core PreferencesController state? That is what I was unsure of.

We should de-risk by creating integration PRs regardless!

@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.3-preview-a8fd340
@metamask-previews/accounts-controller@39.0.3-preview-a8fd340
@metamask-previews/address-book-controller@7.1.2-preview-a8fd340
@metamask-previews/ai-controllers@0.7.0-preview-a8fd340
@metamask-previews/analytics-controller@1.1.1-preview-a8fd340
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-a8fd340
@metamask-previews/announcement-controller@8.1.0-preview-a8fd340
@metamask-previews/app-metadata-controller@2.0.1-preview-a8fd340
@metamask-previews/approval-controller@9.0.2-preview-a8fd340
@metamask-previews/assets-controller@9.0.2-preview-a8fd340
@metamask-previews/assets-controllers@109.2.2-preview-a8fd340
@metamask-previews/authenticated-user-storage@2.1.0-preview-a8fd340
@metamask-previews/base-controller@9.1.0-preview-a8fd340
@metamask-previews/base-data-service@0.1.3-preview-a8fd340
@metamask-previews/bitcoin-regtest-up@0.0.0-preview-a8fd340
@metamask-previews/bridge-controller@76.0.0-preview-a8fd340
@metamask-previews/bridge-status-controller@72.2.0-preview-a8fd340
@metamask-previews/build-utils@3.0.4-preview-a8fd340
@metamask-previews/chain-agnostic-permission@1.6.2-preview-a8fd340
@metamask-previews/chomp-api-service@3.1.0-preview-a8fd340
@metamask-previews/claims-controller@0.5.3-preview-a8fd340
@metamask-previews/client-controller@1.0.1-preview-a8fd340
@metamask-previews/compliance-controller@2.1.0-preview-a8fd340
@metamask-previews/composable-controller@12.0.1-preview-a8fd340
@metamask-previews/config-registry-controller@0.4.1-preview-a8fd340
@metamask-previews/connectivity-controller@0.2.0-preview-a8fd340
@metamask-previews/controller-utils@12.3.0-preview-a8fd340
@metamask-previews/core-backend@6.3.3-preview-a8fd340
@metamask-previews/delegation-controller@3.0.2-preview-a8fd340
@metamask-previews/earn-controller@12.2.1-preview-a8fd340
@metamask-previews/eip-5792-middleware@3.0.4-preview-a8fd340
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-a8fd340
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-a8fd340
@metamask-previews/ens-controller@19.1.4-preview-a8fd340
@metamask-previews/eth-block-tracker@15.0.1-preview-a8fd340
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-a8fd340
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-a8fd340
@metamask-previews/foundryup@1.0.1-preview-a8fd340
@metamask-previews/gas-fee-controller@26.2.3-preview-a8fd340
@metamask-previews/gator-permissions-controller@4.2.1-preview-a8fd340
@metamask-previews/geolocation-controller@0.1.3-preview-a8fd340
@metamask-previews/java-tron-up@0.0.0-preview-a8fd340
@metamask-previews/json-rpc-engine@10.5.0-preview-a8fd340
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-a8fd340
@metamask-previews/keyring-controller@27.1.0-preview-a8fd340
@metamask-previews/local-node-utils@0.0.0-preview-a8fd340
@metamask-previews/logging-controller@8.0.2-preview-a8fd340
@metamask-previews/message-manager@14.1.2-preview-a8fd340
@metamask-previews/messenger@1.2.0-preview-a8fd340
@metamask-previews/messenger-cli@0.2.0-preview-a8fd340
@metamask-previews/money-account-balance-service@2.1.1-preview-a8fd340
@metamask-previews/money-account-controller@0.3.3-preview-a8fd340
@metamask-previews/money-account-upgrade-controller@2.1.0-preview-a8fd340
@metamask-previews/multichain-account-service@11.0.0-preview-a8fd340
@metamask-previews/multichain-api-middleware@3.1.5-preview-a8fd340
@metamask-previews/multichain-network-controller@3.1.4-preview-a8fd340
@metamask-previews/multichain-transactions-controller@7.1.1-preview-a8fd340
@metamask-previews/name-controller@9.1.2-preview-a8fd340
@metamask-previews/network-controller@33.0.0-preview-a8fd340
@metamask-previews/network-enablement-controller@5.4.0-preview-a8fd340
@metamask-previews/notification-services-controller@24.2.0-preview-a8fd340
@metamask-previews/passkey-controller@2.0.1-preview-a8fd340
@metamask-previews/permission-controller@13.1.1-preview-a8fd340
@metamask-previews/permission-log-controller@5.1.0-preview-a8fd340
@metamask-previews/perps-controller@8.3.0-preview-a8fd340
@metamask-previews/phishing-controller@17.2.0-preview-a8fd340
@metamask-previews/polling-controller@16.0.7-preview-a8fd340
@metamask-previews/preferences-controller@23.1.0-preview-a8fd340
@metamask-previews/profile-metrics-controller@4.0.0-preview-a8fd340
@metamask-previews/profile-sync-controller@28.2.0-preview-a8fd340
@metamask-previews/ramps-controller@14.3.0-preview-a8fd340
@metamask-previews/rate-limit-controller@7.0.1-preview-a8fd340
@metamask-previews/react-data-query@0.2.1-preview-a8fd340
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-a8fd340
@metamask-previews/sample-controllers@5.0.2-preview-a8fd340
@metamask-previews/seedless-onboarding-controller@10.0.2-preview-a8fd340
@metamask-previews/selected-network-controller@26.1.4-preview-a8fd340
@metamask-previews/shield-controller@5.1.2-preview-a8fd340
@metamask-previews/signature-controller@39.2.6-preview-a8fd340
@metamask-previews/smart-transactions-controller@24.2.3-preview-a8fd340
@metamask-previews/snap-account-service@1.0.0-preview-a8fd340
@metamask-previews/social-controllers@2.3.1-preview-a8fd340
@metamask-previews/solana-test-validator-up@0.0.0-preview-a8fd340
@metamask-previews/storage-service@1.0.2-preview-a8fd340
@metamask-previews/subscription-controller@6.2.0-preview-a8fd340
@metamask-previews/transaction-controller@68.1.1-preview-a8fd340
@metamask-previews/transaction-pay-controller@23.14.0-preview-a8fd340
@metamask-previews/user-operation-controller@41.2.5-preview-a8fd340
@metamask-previews/wallet@4.0.0-preview-a8fd340
@metamask-previews/wallet-cli@0.0.0-preview-a8fd340

sirtimid and others added 2 commits June 23, 2026 18:28
Prove a consumer can keep a diverging superset PreferencesController by
supplying its own initialization configuration under the same name, which
overrides the package default — the adoption path for clients (e.g. the
extension) that cannot converge to the package controller's state shape.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Re-export `InitializationConfiguration`, `InitFunctionArguments`, and
`InstanceState` from the package root so consumers can annotate their own
initialization configurations that override a default controller (e.g. the
extension overriding the default `PreferencesController`).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sirtimid

Copy link
Copy Markdown
Member Author

@metamaskbot publish-previews

@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.3-preview-55f166437
@metamask-previews/accounts-controller@39.0.3-preview-55f166437
@metamask-previews/address-book-controller@7.1.2-preview-55f166437
@metamask-previews/ai-controllers@0.7.0-preview-55f166437
@metamask-previews/analytics-controller@1.1.1-preview-55f166437
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-55f166437
@metamask-previews/announcement-controller@8.1.0-preview-55f166437
@metamask-previews/app-metadata-controller@2.0.1-preview-55f166437
@metamask-previews/approval-controller@9.0.2-preview-55f166437
@metamask-previews/assets-controller@9.0.2-preview-55f166437
@metamask-previews/assets-controllers@109.2.2-preview-55f166437
@metamask-previews/authenticated-user-storage@2.1.0-preview-55f166437
@metamask-previews/base-controller@9.1.0-preview-55f166437
@metamask-previews/base-data-service@0.1.3-preview-55f166437
@metamask-previews/bitcoin-regtest-up@0.0.0-preview-55f166437
@metamask-previews/bridge-controller@76.0.0-preview-55f166437
@metamask-previews/bridge-status-controller@72.2.0-preview-55f166437
@metamask-previews/build-utils@3.0.4-preview-55f166437
@metamask-previews/chain-agnostic-permission@1.6.2-preview-55f166437
@metamask-previews/chomp-api-service@3.1.0-preview-55f166437
@metamask-previews/claims-controller@0.5.3-preview-55f166437
@metamask-previews/client-controller@1.0.1-preview-55f166437
@metamask-previews/compliance-controller@2.1.0-preview-55f166437
@metamask-previews/composable-controller@12.0.1-preview-55f166437
@metamask-previews/config-registry-controller@0.4.1-preview-55f166437
@metamask-previews/connectivity-controller@0.2.0-preview-55f166437
@metamask-previews/controller-utils@12.3.0-preview-55f166437
@metamask-previews/core-backend@6.3.3-preview-55f166437
@metamask-previews/delegation-controller@3.0.2-preview-55f166437
@metamask-previews/earn-controller@12.2.1-preview-55f166437
@metamask-previews/eip-5792-middleware@3.0.4-preview-55f166437
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-55f166437
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-55f166437
@metamask-previews/ens-controller@19.1.4-preview-55f166437
@metamask-previews/eth-block-tracker@15.0.1-preview-55f166437
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-55f166437
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-55f166437
@metamask-previews/foundryup@1.0.1-preview-55f166437
@metamask-previews/gas-fee-controller@26.2.3-preview-55f166437
@metamask-previews/gator-permissions-controller@4.2.1-preview-55f166437
@metamask-previews/geolocation-controller@0.1.3-preview-55f166437
@metamask-previews/java-tron-up@0.0.0-preview-55f166437
@metamask-previews/json-rpc-engine@10.5.0-preview-55f166437
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-55f166437
@metamask-previews/keyring-controller@27.1.0-preview-55f166437
@metamask-previews/local-node-utils@0.0.0-preview-55f166437
@metamask-previews/logging-controller@8.0.2-preview-55f166437
@metamask-previews/message-manager@14.1.2-preview-55f166437
@metamask-previews/messenger@1.2.0-preview-55f166437
@metamask-previews/messenger-cli@0.2.0-preview-55f166437
@metamask-previews/money-account-balance-service@2.1.1-preview-55f166437
@metamask-previews/money-account-controller@0.3.3-preview-55f166437
@metamask-previews/money-account-upgrade-controller@2.1.0-preview-55f166437
@metamask-previews/multichain-account-service@11.0.0-preview-55f166437
@metamask-previews/multichain-api-middleware@3.1.5-preview-55f166437
@metamask-previews/multichain-network-controller@3.1.4-preview-55f166437
@metamask-previews/multichain-transactions-controller@7.1.1-preview-55f166437
@metamask-previews/name-controller@9.1.2-preview-55f166437
@metamask-previews/network-controller@33.0.0-preview-55f166437
@metamask-previews/network-enablement-controller@5.4.0-preview-55f166437
@metamask-previews/notification-services-controller@24.2.0-preview-55f166437
@metamask-previews/passkey-controller@2.0.1-preview-55f166437
@metamask-previews/permission-controller@13.1.1-preview-55f166437
@metamask-previews/permission-log-controller@5.1.0-preview-55f166437
@metamask-previews/perps-controller@8.3.0-preview-55f166437
@metamask-previews/phishing-controller@17.2.0-preview-55f166437
@metamask-previews/polling-controller@16.0.7-preview-55f166437
@metamask-previews/preferences-controller@23.1.0-preview-55f166437
@metamask-previews/profile-metrics-controller@4.0.0-preview-55f166437
@metamask-previews/profile-sync-controller@28.2.0-preview-55f166437
@metamask-previews/ramps-controller@14.3.0-preview-55f166437
@metamask-previews/rate-limit-controller@7.0.1-preview-55f166437
@metamask-previews/react-data-query@0.2.1-preview-55f166437
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-55f166437
@metamask-previews/sample-controllers@5.0.2-preview-55f166437
@metamask-previews/seedless-onboarding-controller@10.0.2-preview-55f166437
@metamask-previews/selected-network-controller@26.1.4-preview-55f166437
@metamask-previews/shield-controller@5.1.2-preview-55f166437
@metamask-previews/signature-controller@39.2.6-preview-55f166437
@metamask-previews/smart-transactions-controller@24.2.3-preview-55f166437
@metamask-previews/snap-account-service@1.0.0-preview-55f166437
@metamask-previews/social-controllers@2.3.1-preview-55f166437
@metamask-previews/solana-test-validator-up@0.0.0-preview-55f166437
@metamask-previews/storage-service@1.0.2-preview-55f166437
@metamask-previews/subscription-controller@6.2.0-preview-55f166437
@metamask-previews/transaction-controller@68.1.1-preview-55f166437
@metamask-previews/transaction-pay-controller@23.14.0-preview-55f166437
@metamask-previews/user-operation-controller@41.2.5-preview-55f166437
@metamask-previews/wallet@4.0.0-preview-55f166437
@metamask-previews/wallet-cli@0.0.0-preview-55f166437

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants