Skip to content

Conversation

@ccharly
Copy link
Contributor

@ccharly ccharly commented Nov 19, 2025

Description

This will automatically fix corrupted states if users have desync'd accounts.

This should mitigate some errors that were spotted with the rewards system where some Solana address could not be registered.

Open in GitHub Codespaces

Changelog

CHANGELOG entry: Automatically re-sync accounts between Snaps and MetaMask

Related issues

Fix for users that already encountered this bug (their "not found" accounts will automatically be re-created now, acting as a migration):

Manual testing steps

Difficult to manually test this since it implies to "hack" the non-EVM Snaps to trigger state-inconsistencies

Screenshots/Recordings

Before

After

Pre-merge author checklist

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.

Note

On unlock, asynchronously resync Snap and MetaMask accounts, then align wallets; adds tests to verify both are invoked.

  • Controller:
    • In app/scripts/metamask-controller.js submitPasswordOrEncryptionKey, after init and account-tree refresh, if multichain state2 is enabled, run multichainAccountService.resyncAccounts() then alignWallets() asynchronously via a helper.
  • Tests:
    • Add waitForAllPromises utility.
    • New test in app/scripts/metamask-controller.test.js asserts resyncAccounts and alignWallets are called asynchronously after submitPasswordOrEncryptionKey.

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

@github-actions
Copy link
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.

@metamaskbot metamaskbot added the team-accounts-framework Accounts Framework team label Nov 19, 2025
@metamaskbot
Copy link
Collaborator

Builds ready [02a6c2a]
UI Startup Metrics (1200 ± 85 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup1200105215938512611323
load102487913828410871141
domContentLoaded101687613748310811135
domInteractive2314156201868
firstPaint70584138140510471136
backgroundConnect21218826812217240
firstReactRender271978102947
getState291680103251
initialActions106113
loadScripts812683115781874925
setupStore1063341216
numNetworkReqs1267116657
BrowserifyPower User HomeuiStartup18231517245120019772187
load981867147511310121266
domContentLoaded96685814641119861252
domInteractive2815135222868
firstPaint5768714733859351195
backgroundConnect22119726114227251
firstReactRender7846138148697
getState17813437040197264
initialActions104112
loadScripts76266312391087801045
setupStore20956102639
numNetworkReqs91651582399152
WebpackStandard HomeuiStartup8406781264968691006
load58252692064592749
domContentLoaded57452089562585739
domInteractive171169121552
firstPaint20557904214179734
backgroundConnect271395153062
firstReactRender3519281293947
getState19116372129
initialActions104112
loadScripts57151888760583730
setupStore145287281417
numNetworkReqs1366917865
WebpackPower User HomeuiStartup13161145192220014281859
load63656592990665885
domContentLoaded61655289778627844
domInteractive2413146222055
firstPaint31760907277594850
backgroundConnect46121583561132
firstReactRender7748102118296
getState15413221016162190
initialActions102011
loadScripts61355088877625836
setupStore17679132938
numNetworkReqs1277223945173220
FirefoxBrowserifyStandard HomeuiStartup12371057166911113171421
load104391412278111201188
domContentLoaded104290912278111171182
domInteractive59292203782133
firstPaint------
backgroundConnect352175114161
firstReactRender23185362334
getState96304919
initialActions103112
loadScripts102189912047810961163
setupStore1144791035
numNetworkReqs1266415857
BrowserifyPower User HomeuiStartup24401868295724526112888
load1083892151714911771398
domContentLoaded1082888151714911771398
domInteractive1132950091144273
firstPaint------
backgroundConnect13322589126191438
firstReactRender81381802187121
getState24777854247211810
initialActions2029327
loadScripts1041872146813810931355
setupStore1236778184116708
numNetworkReqs946219833119168
WebpackStandard HomeuiStartup14401218187412514791709
load1229105915069312951385
domContentLoaded1228105815069212951384
domInteractive66282303883129
firstPaint------
backgroundConnect42161312443101
firstReactRender29197193138
getState12662101145
initialActions102012
loadScripts1204104514868812701342
setupStore165219241249
numNetworkReqs1366716863
WebpackPower User HomeuiStartup27612087349327729583279
load13261073173215414141655
domContentLoaded13261073173215414141655
domInteractive872825246120167
firstPaint------
backgroundConnect13729610133168497
firstReactRender89442252398123
getState26682926273206885
initialActions3036528
loadScripts12881053171314913601610
setupStore112680618685645
numNetworkReqs96562394398201
📊 Page Load Benchmark Results

Current Commit: 02a6c2a | Date: 11/19/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.04s (±54ms) 🟡 | historical mean value: 1.05s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 724ms (±51ms) 🟢 | historical mean value: 730ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 76ms (±11ms) 🟢 | historical mean value: 77ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.04s 54ms 1.01s 1.32s 1.06s 1.32s
domContentLoaded 724ms 51ms 698ms 1.00s 748ms 1.00s
firstPaint 76ms 11ms 60ms 168ms 88ms 168ms
firstContentfulPaint 76ms 11ms 60ms 168ms 88ms 168ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 758 Bytes (0.02%)
  • ui: 1.6 KiB (0.02%)
  • common: 359 Bytes (0%)

@ccharly ccharly self-assigned this Nov 21, 2025
@ccharly ccharly marked this pull request as ready for review November 21, 2025 08:35
@ccharly ccharly changed the title fix: add resync mechanism to sync Snap accounts states with client accounts fix: add resync mechanism to sync Snap accounts states with client accounts cp-13.11.0 Nov 21, 2025
// There is is/was a bug with Snap accounts that can be desynchronized (Solana). To
// automatically "fix" this corrupted state, we run this method which will re-sync
// MetaMask accounts and Snap accounts upon login.
await this.multichainAccountService.resyncAccounts();
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to init the AccountTreeController before syncing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, let me rework this PR and see if we can do the same than on mobile (which is running all this "async"/non-awaited)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I made it async now, so this will happen after all initialization!

///: BEGIN:ONLY_INCLUDE_IF(multichain)
// Init multichain accounts after creating internal accounts.
await this.multichainAccountService.init();
// READ THIS CAREFULLY:
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a reference to the bug in the comments

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did add the reference now, even if this PR is more like a "mitigation" rather than a true fix, but still worth IMO!


expect(mockResyncAccounts).toHaveBeenCalled();
expect(mockAlignWallets).toHaveBeenCalled();
});
Copy link

Choose a reason for hiding this comment

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

Bug: Race condition in async test verification

The test uses waitForAllPromises() which only waits for one process.nextTick, but the resyncAndAlignAccounts function contains two sequential await statements. This creates a race condition where the test assertions may execute before both resyncAccounts and alignWallets complete, causing intermittent test failures. The fire-and-forget pattern with void means the function execution isn't guaranteed to finish before the assertions run.

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's ok for now, I'll keep this simple.

// NOTE: We run this asynchronously on purpose, see FIXME^.
// eslint-disable-next-line no-void
void this.multichainAccountService.alignWallets();
void resyncAndAlignAccounts();
Copy link

Choose a reason for hiding this comment

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

Bug: Unconditional multichain service calls cause runtime errors

The conditional compilation directives around multichainAccountService.init() were removed, but multichainAccountService is only defined in builds with the multichain flag enabled. This causes the code to attempt calling methods on undefined in non-multichain builds, resulting in runtime errors. The same issue affects the resyncAndAlignAccounts function which calls resyncAccounts() and alignWallets() on the potentially undefined service.

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually removed it cause we were already using the service without the codefence. Anyway, this code fence should be entirely remove at some point.

@metamaskbot
Copy link
Collaborator

Builds ready [6771234]
UI Startup Metrics (1234 ± 100 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup12341068159810012701415
load105391413518510931208
domContentLoaded104690913448510871199
domInteractive241492172180
firstPaint54398136741410421168
backgroundConnect21820130515221247
firstReactRender27194773142
getState301768103553
initialActions103112
loadScripts836696111985880984
setupStore1063441115
numNetworkReqs1257720573
BrowserifyPower User HomeuiStartup18641547270422620632214
load993883180115610051433
domContentLoaded97787217871559771420
domInteractive36152504030143
firstPaint5309918394049121417
backgroundConnect22120126915231252
firstReactRender7743122138398
getState17312836741183264
initialActions104112
loadScripts77467615651537711218
setupStore19759112542
numNetworkReqs1316428351168219
WebpackStandard HomeuiStartup803732104874830991
load61256082763616790
domContentLoaded60755781962612785
domInteractive2314105172171
firstPaint23382810176210770
backgroundConnect1153971426
firstReactRender2920109103238
getState291451103646
initialActions103112
loadScripts60455481160610775
setupStore1244761425
numNetworkReqs1257620571
WebpackPower User HomeuiStartup13861069197919115621715
load6545771239116660946
domContentLoaded6445701227115646938
domInteractive32151713127118
firstPaint25784986195244699
backgroundConnect1374061724
firstReactRender7843102128494
getState14812221320160190
initialActions103011
loadScripts6425681216113644929
setupStore21971133153
numNetworkReqs1446531154178288
FirefoxBrowserifyStandard HomeuiStartup12891070167712113671558
load107791512938711311242
domContentLoaded107791512938711301242
domInteractive65312714283140
firstPaint------
backgroundConnect4321126224593
firstReactRender22193942332
getState11694131019
initialActions113012
loadScripts105089912708310971217
setupStore166163241062
numNetworkReqs1156515652
BrowserifyPower User HomeuiStartup25761979315725727563004
load1199994182417712151582
domContentLoaded1198994182317712151582
domInteractive15035632139152548
firstPaint------
backgroundConnect14830736136194414
firstReactRender88541621896120
getState22471846227186836
initialActions30405310
loadScripts1162977167116611791553
setupStore987724126107469
numNetworkReqs90522194485208
WebpackStandard HomeuiStartup14411292195411914741709
load1222106014798212761378
domContentLoaded1222106014798212761378
domInteractive62281603283130
firstPaint------
backgroundConnect44222122844105
firstReactRender27204053039
getState1266091143
initialActions103122
loadScripts1197104613837412401337
setupStore13587141145
numNetworkReqs1156616662
WebpackPower User HomeuiStartup28211972366632930443359
load14211144185518614461823
domContentLoaded14211144185518614461822
domInteractive12530553111128418
firstPaint------
backgroundConnect13825827111201307
firstReactRender87381842498130
getState279751559304216910
initialActions506111629
loadScripts13851113182518714151797
setupStore1086803173101748
numNetworkReqs90602224482207
📊 Page Load Benchmark Results

Current Commit: 6771234 | Date: 11/21/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.04s (±45ms) 🟡 | historical mean value: 1.04s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 726ms (±41ms) 🟢 | historical mean value: 727ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 78ms (±16ms) 🟢 | historical mean value: 79ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.04s 45ms 1.00s 1.36s 1.07s 1.36s
domContentLoaded 726ms 41ms 695ms 1.02s 755ms 1.02s
firstPaint 78ms 16ms 60ms 228ms 88ms 228ms
firstContentfulPaint 78ms 16ms 60ms 228ms 88ms 228ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 6.7 KiB (0.14%)
  • ui: 51.09 KiB (0.73%)
  • common: 12.84 KiB (0.15%)

montelaidev
montelaidev previously approved these changes Nov 21, 2025
@ccharly ccharly enabled auto-merge November 21, 2025 16:07
Co-authored-by: Mathieu Artu <mathieu.artu@consensys.net>
@metamaskbot
Copy link
Collaborator

Builds ready [cfec6a9]
UI Startup Metrics (1205 ± 105 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup12051009150410512621391
load102185712639210761199
domContentLoaded101685412579210721192
domInteractive26141142420101
firstPaint52985118139210061118
backgroundConnect2101952459213228
firstReactRender26185882645
getState30177493446
initialActions104111
loadScripts813651105691864985
setupStore1063941119
numNetworkReqs1257720573
BrowserifyPower User HomeuiStartup18071489266423719842286
load95883814871649681426
domContentLoaded94582814791629531403
domInteractive36162974331150
firstPaint6078714413839181394
backgroundConnect20318225112208227
firstReactRender82401491689103
getState17514031833187247
initialActions104112
loadScripts75564012921627481210
setupStore17954102341
numNetworkReqs90652073397185
WebpackStandard HomeuiStartup8147041071858301037
load63456588274662822
domContentLoaded63056187473658817
domInteractive27151132521101
firstPaint19674845133187576
backgroundConnect106315922
firstReactRender27194363138
getState271375123451
initialActions102112
loadScripts62755986571656808
setupStore136215211319
numNetworkReqs1257720574
WebpackPower User HomeuiStartup14081094210817615481705
load6485691276124656948
domContentLoaded6395611256124644942
domInteractive35161663926156
firstPaint291871111199331664
backgroundConnect1463361726
firstReactRender82471061489103
getState15913723419166207
initialActions1011112
loadScripts6365591248122641933
setupStore19665132246
numNetworkReqs1466430557183282
FirefoxBrowserifyStandard HomeuiStartup12021051155310812651428
load100989612077210621142
domContentLoaded100889612077210571138
domInteractive54301873081119
firstPaint------
backgroundConnect3618152213674
firstReactRender21174452134
getState1168113918
initialActions102112
loadScripts98887811876910331120
setupStore12516317934
numNetworkReqs1156215653
BrowserifyPower User HomeuiStartup25171867316329127073037
load1167912166917812011574
domContentLoaded1166911166917812011574
domInteractive14132652131153478
firstPaint------
backgroundConnect14127870141170476
firstReactRender903916621100130
getState22463892229186836
initialActions218126
loadScripts1135893164817611571520
setupStore1086808166105657
numNetworkReqs91592254582212
WebpackStandard HomeuiStartup13911205175811014491623
load1183103914439512421371
domContentLoaded1183103914439512411370
domInteractive56261753678131
firstPaint------
backgroundConnect4020121204090
firstReactRender25203742732
getState106557921
initialActions103112
loadScripts1160102414218712181327
setupStore1167291233
numNetworkReqs1156515661
WebpackPower User HomeuiStartup26052069338823627702948
load13281089169814814151610
domContentLoaded13281089169814814151610
domInteractive1143141891127373
firstPaint------
backgroundConnect1062450378157212
firstReactRender84391792293121
getState21059860220176802
initialActions3039537
loadScripts12921074167414313721575
setupStore104774416093513
numNetworkReqs91602224581207
📊 Page Load Benchmark Results

Current Commit: cfec6a9 | Date: 11/24/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.06s (±38ms) 🟡 | historical mean value: 1.05s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 738ms (±35ms) 🟢 | historical mean value: 732ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 79ms (±11ms) 🟢 | historical mean value: 79ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.06s 38ms 1.02s 1.33s 1.10s 1.33s
domContentLoaded 738ms 35ms 705ms 989ms 763ms 989ms
firstPaint 79ms 11ms 64ms 176ms 88ms 176ms
firstContentfulPaint 79ms 11ms 64ms 176ms 88ms 176ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 6.7 KiB (0.14%)
  • ui: 53.83 KiB (0.77%)
  • common: 13.06 KiB (0.15%)

@ccharly ccharly added this pull request to the merge queue Nov 24, 2025
Merged via the queue into main with commit 29ed016 Nov 24, 2025
332 of 334 checks passed
@ccharly ccharly deleted the MUL-1271-extension-integrate-resync-feature branch November 24, 2025 11:28
@github-actions github-actions bot locked and limited conversation to collaborators Nov 24, 2025
@metamaskbot metamaskbot added the release-13.12.0 Issue or pull request that will be included in release 13.12.0 label Nov 24, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-13.12.0 Issue or pull request that will be included in release 13.12.0 size-S team-accounts-framework Accounts Framework team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants