…e id management (MetaMask#8504)
## 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?
-->
## References
- https://consensyssoftware.atlassian.net/browse/MUL-1722
### Client PRs
- [Extension](MetaMask/metamask-extension#42120)
- [Mobile](MetaMask/metamask-mobile#29357)
## 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)
- [ ] 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
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches authentication and user-storage request scoping, adding new
network calls and state fields (`canonicalProfileId`) that can affect
login/session validity and storage partitioning if incorrect or
mismatched with backend behavior.
>
> **Overview**
> Adds SRP *profile pairing* support by calling `POST
/api/v2/profile/pair` after `performSignIn` when 2+ SRPs exist,
propagating a new `canonicalProfileId` across cached SRP sessions and
emitting a new `AuthenticationController:profileSignIn` event when
aliases are returned or the canonical changes.
>
> Extends the SRP auth flow to request pairing
(`X-MetaMask-Profile-Pairing: enabled` on `/srp/login`), parse and
surface `profile_aliases`, and resolve the original per-SRP `profileId`
from aliases (via new `computeIdentifierId`) while storing
`canonicalProfileId` separately; sessions missing `canonicalProfileId`
now force re-login.
>
> Updates `UserStorage` to optionally scope requests by sending
`x-profile-id` when `profileId !== canonicalProfileId` (with an escape
hatch `useCanonicalScope`), adds `refreshCanonicalProfileId` to force a
fresh canonical fetch, and introduces validation/utilities
(`validatePairResponse`) plus expanded fixtures/tests for the new
pairing behavior.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
abc619c. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Description
Introduced changes:
@metamask/profile-sync-controllerto version28.1.0Changelog
CHANGELOG entry: null
Related issues
Fixes: https://consensyssoftware.atlassian.net/browse/MUL-1737
Manual testing steps
Check epic for test cases: https://consensyssoftware.atlassian.net/browse/MUL-1408
Screenshots/Recordings
Not applicable
Pre-merge author checklist
Performance checks (if applicable)
trace()for usage andaddTokenfor an exampleFor performance guidelines and tooling, see the Performance Guide.
Pre-merge reviewer checklist
Note
Medium Risk
Touches authentication auto-sign-in/pairing logic and controller initialization, which can affect login/pairing behavior across upgrades. Dependency bump to
@metamask/profile-sync-controller@28.1.0also changes underlying auth/controller behavior and API mocks.Overview
Upgrades
@metamask/profile-sync-controllerto28.1.0and updates test/mocking fixtures to include the new auth pairing endpoint andneedsProfilePairingstate (including defaulting initial background state totrue).Adds
requestProfilePairing()identity action plus a newselectNeedsProfilePairingselector (defaulting totruewhen absent) and extendsuseAutoSignInto trigger pairing on keyring changes and to forcesignIn(true)when pairing is needed even if already signed in.Extends auth controller initialization to provide
metametrics.getAppVersionviareact-native-device-infogetVersion(), and updates related tests; also updates card email verification tests to includecanonicalProfileIdin the mocked session profile.Reviewed by Cursor Bugbot for commit d41351c. Bugbot is set up for automated code reviews on this repo. Configure here.