Skip to content

feat(account-tree-controller): re-introduce lastSelected metadata#8261

Open
ccharly wants to merge 1 commit intomainfrom
cc/fix/group-last-selected-metadata
Open

feat(account-tree-controller): re-introduce lastSelected metadata#8261
ccharly wants to merge 1 commit intomainfrom
cc/fix/group-last-selected-metadata

Conversation

@ccharly
Copy link
Contributor

@ccharly ccharly commented Mar 20, 2026

Explanation

Some logic still relies on this metadata on accounts. Since we want to deprecate the AccountsController at some point, we need to reintroduce this concept, but at the group level this time.

References

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
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Medium risk because it changes how the controller persists/derives the default selectedAccountGroup, which can affect account selection after removals or restarts if timestamps or metadata restoration behave unexpectedly.

Overview
Adds a lastSelected timestamp to account-group metadata, persisting it in accountGroupsMetadata (local-only) and restoring it during tree initialization.

Updates selection flows (setSelectedAccountGroup and AccountsController:selectedAccountChange) to stamp Date.now() into both persisted metadata and the in-tree group node, and changes default-group fallback logic to prefer the most recently selected non-empty group (with an EVM-account tiebreaker). Tests and rule-generated defaults are updated to include lastSelected: 0 and to cover the new fallback/restore behavior.

Written by Cursor Bugbot for commit cc3d9fe. This will update automatically on new commits. Configure here.

@ccharly ccharly force-pushed the cc/fix/group-last-selected-metadata branch 2 times, most recently from aa318fb to ba6d99f Compare March 20, 2026 14:47
@ccharly ccharly force-pushed the cc/fix/group-last-selected-metadata branch from ba6d99f to cc3d9fe Compare March 20, 2026 14:58
@ccharly
Copy link
Contributor Author

ccharly commented Mar 20, 2026

@metamaskbot publish-preview

@github-actions
Copy link
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@5.0.1-preview-cc3d9fe8e
@metamask-previews/accounts-controller@37.0.0-preview-cc3d9fe8e
@metamask-previews/address-book-controller@7.1.0-preview-cc3d9fe8e
@metamask-previews/ai-controllers@0.4.0-preview-cc3d9fe8e
@metamask-previews/analytics-controller@1.0.0-preview-cc3d9fe8e
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-cc3d9fe8e
@metamask-previews/announcement-controller@8.0.0-preview-cc3d9fe8e
@metamask-previews/app-metadata-controller@2.0.0-preview-cc3d9fe8e
@metamask-previews/approval-controller@9.0.0-preview-cc3d9fe8e
@metamask-previews/assets-controller@3.0.0-preview-cc3d9fe8e
@metamask-previews/assets-controllers@101.0.1-preview-cc3d9fe8e
@metamask-previews/base-controller@9.0.0-preview-cc3d9fe8e
@metamask-previews/base-data-service@0.0.0-preview-cc3d9fe8e
@metamask-previews/bridge-controller@69.1.1-preview-cc3d9fe8e
@metamask-previews/bridge-status-controller@70.0.0-preview-cc3d9fe8e
@metamask-previews/build-utils@3.0.4-preview-cc3d9fe8e
@metamask-previews/chain-agnostic-permission@1.4.0-preview-cc3d9fe8e
@metamask-previews/claims-controller@0.4.3-preview-cc3d9fe8e
@metamask-previews/client-controller@1.0.0-preview-cc3d9fe8e
@metamask-previews/compliance-controller@1.0.1-preview-cc3d9fe8e
@metamask-previews/composable-controller@12.0.0-preview-cc3d9fe8e
@metamask-previews/config-registry-controller@0.1.1-preview-cc3d9fe8e
@metamask-previews/connectivity-controller@0.1.0-preview-cc3d9fe8e
@metamask-previews/controller-utils@11.19.0-preview-cc3d9fe8e
@metamask-previews/core-backend@6.2.0-preview-cc3d9fe8e
@metamask-previews/delegation-controller@2.0.2-preview-cc3d9fe8e
@metamask-previews/earn-controller@11.1.2-preview-cc3d9fe8e
@metamask-previews/eip-5792-middleware@3.0.1-preview-cc3d9fe8e
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.0-preview-cc3d9fe8e
@metamask-previews/eip1193-permission-middleware@1.0.3-preview-cc3d9fe8e
@metamask-previews/ens-controller@19.1.0-preview-cc3d9fe8e
@metamask-previews/error-reporting-service@3.0.1-preview-cc3d9fe8e
@metamask-previews/eth-block-tracker@15.0.1-preview-cc3d9fe8e
@metamask-previews/eth-json-rpc-middleware@23.1.0-preview-cc3d9fe8e
@metamask-previews/eth-json-rpc-provider@6.0.0-preview-cc3d9fe8e
@metamask-previews/foundryup@1.0.1-preview-cc3d9fe8e
@metamask-previews/gas-fee-controller@26.1.0-preview-cc3d9fe8e
@metamask-previews/gator-permissions-controller@2.1.1-preview-cc3d9fe8e
@metamask-previews/geolocation-controller@0.1.1-preview-cc3d9fe8e
@metamask-previews/json-rpc-engine@10.2.3-preview-cc3d9fe8e
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-cc3d9fe8e
@metamask-previews/keyring-controller@25.1.0-preview-cc3d9fe8e
@metamask-previews/logging-controller@8.0.0-preview-cc3d9fe8e
@metamask-previews/message-manager@14.1.0-preview-cc3d9fe8e
@metamask-previews/messenger@0.3.0-preview-cc3d9fe8e
@metamask-previews/multichain-account-service@7.1.0-preview-cc3d9fe8e
@metamask-previews/multichain-api-middleware@1.2.7-preview-cc3d9fe8e
@metamask-previews/multichain-network-controller@3.0.5-preview-cc3d9fe8e
@metamask-previews/multichain-transactions-controller@7.0.2-preview-cc3d9fe8e
@metamask-previews/name-controller@9.1.0-preview-cc3d9fe8e
@metamask-previews/network-controller@30.0.0-preview-cc3d9fe8e
@metamask-previews/network-enablement-controller@5.0.0-preview-cc3d9fe8e
@metamask-previews/notification-services-controller@23.0.0-preview-cc3d9fe8e
@metamask-previews/permission-controller@12.2.1-preview-cc3d9fe8e
@metamask-previews/permission-log-controller@5.0.0-preview-cc3d9fe8e
@metamask-previews/perps-controller@1.3.0-preview-cc3d9fe8e
@metamask-previews/phishing-controller@17.0.0-preview-cc3d9fe8e
@metamask-previews/polling-controller@16.0.3-preview-cc3d9fe8e
@metamask-previews/preferences-controller@23.0.0-preview-cc3d9fe8e
@metamask-previews/profile-metrics-controller@3.1.1-preview-cc3d9fe8e
@metamask-previews/profile-sync-controller@28.0.0-preview-cc3d9fe8e
@metamask-previews/ramps-controller@12.0.0-preview-cc3d9fe8e
@metamask-previews/rate-limit-controller@7.0.0-preview-cc3d9fe8e
@metamask-previews/react-data-query@0.0.0-preview-cc3d9fe8e
@metamask-previews/remote-feature-flag-controller@4.1.0-preview-cc3d9fe8e
@metamask-previews/sample-controllers@4.0.3-preview-cc3d9fe8e
@metamask-previews/seedless-onboarding-controller@9.0.0-preview-cc3d9fe8e
@metamask-previews/selected-network-controller@26.0.3-preview-cc3d9fe8e
@metamask-previews/shield-controller@5.0.2-preview-cc3d9fe8e
@metamask-previews/signature-controller@39.1.0-preview-cc3d9fe8e
@metamask-previews/storage-service@1.0.0-preview-cc3d9fe8e
@metamask-previews/subscription-controller@6.0.2-preview-cc3d9fe8e
@metamask-previews/transaction-controller@63.0.0-preview-cc3d9fe8e
@metamask-previews/transaction-pay-controller@18.0.0-preview-cc3d9fe8e
@metamask-previews/user-operation-controller@41.1.0-preview-cc3d9fe8e

@ccharly ccharly marked this pull request as ready for review March 20, 2026 16:02
@ccharly ccharly requested review from a team as code owners March 20, 2026 16:02
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

}
}
}
return candidate?.id ?? '';
Copy link

Choose a reason for hiding this comment

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

Persisted lastSelected ignored during init fallback path

Low Severity

In init(), #getDefaultSelectedAccountGroup(wallets) receives the original wallets object rather than state.accountTree.wallets (the Immer draft). Since #applyAccountGroupMetadata writes persisted lastSelected values through the draft (copy-on-write), these updates are not reflected in the original wallets reference. If #getDefaultAccountGroupId is reached as a fallback, all groups appear to have lastSelected: 0, making the new lastSelected-based ranking ineffective during init and falling back to the EVM tiebreaker instead.

Additional Locations (1)
Fix in Cursor Fix in Web

state.accountTree.wallets[walletId].groups[
groupId
].metadata.lastSelected = now;
}
Copy link

Choose a reason for hiding this comment

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

Duplicated lastSelected update logic across two methods

Low Severity

The block that guards accountGroupsMetadata[groupId], captures Date.now(), and writes lastSelected to both persisted metadata and the tree is copy-pasted identically in setSelectedAccountGroup and #handleSelectedAccountChange. Extracting this into a shared private helper would reduce the risk of future inconsistent updates between the two call sites.

Additional Locations (1)
Fix in Cursor Fix in Web

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.

1 participant