Skip to content

Commit b6342a9

Browse files
committed
release(runway): cherry-pick fix: force account alignment on unlock cp-13.9.0 (#37762)
## **Description** Force account alignment on unlock to cover new account providers being added. > [!NOTE] > Normally, we should run discovery + alignment asynchronously for a better UX, but this involves a lot more work. For now, this will cover new account providers being added to the extension. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/37762?quickstart=1) ## **Changelog** CHANGELOG entry: Automatically create new account types on wallet unlock ## **Related issues** N/A ## **Manual testing steps** - Go to branch `v13.7.0` * Build the extension with: `yarn build --build-type main dist` - Go to this branch * Build the extension with: `yarn build --build-type main dist` - Make a folder `_local` and `cd` into it - Run `cp ../builds/metamask-chrome-13.7.0.zip . && unzip *.zip` - Load and start the extension - Create a new SRP - Import another SRP - Create some accounts on both SRP - Stop the extension - Run `cp ../builds/metamask-chrome-13.10.0.zip . && unzip *.zip` (build for this branch) - Reload the extension - You should see some `Running ... migration` message - Check all your multichain accounts, you should now see Bitcoin accounts for all of them. ## **Screenshots/Recordings** ### **Before** ### **After** https://github.com/user-attachments/assets/29ab83b2-520a-4331-8e8f-0f5b92490b69 https://github.com/user-attachments/assets/788b3518-9826-45a8-a3d5-62cd239e733f ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is generating a summary for commit 38d98a2. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 9ae1878 commit b6342a9

File tree

5 files changed

+53
-8
lines changed

5 files changed

+53
-8
lines changed

app/scripts/controller-init/messengers/accounts/snap-keyring-builder-messenger.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export function getSnapKeyringBuilderMessenger(
4949
'SnapController:get',
5050
'SnapController:isMinimumPlatformVersion',
5151
'PreferencesController:getState',
52+
'RemoteFeatureFlagController:getState',
5253
],
5354
});
5455
return keyringMessenger;

app/scripts/lib/snap-keyring/snap-keyring.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
} from '@metamask/keyring-api';
77
import { InternalAccount } from '@metamask/keyring-internal-api';
88
import { SnapId } from '@metamask/snaps-sdk';
9+
import { RemoteFeatureFlagControllerState } from '@metamask/remote-feature-flag-controller';
910
import { getRootMessenger } from '../messenger';
1011
import { SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES } from '../../../../shared/constants/app';
1112
import {
@@ -43,6 +44,7 @@ const mockLocale = 'en';
4344
const mockPreferencesControllerGetState = jest.fn();
4445
const mockSnapControllerGet = jest.fn();
4546
const mockSnapControllerHandleRequest = jest.fn();
47+
const mockRemoteFeatureFlagsGetStateRequest = jest.fn();
4648

4749
const mockFlowId = '123';
4850
const address = '0x2a4d4b667D5f12C3F9Bf8F14a7B9f8D8d9b8c8fA';
@@ -114,6 +116,7 @@ const createControllerMessenger = ({
114116
'PreferencesController:getState',
115117
'SnapController:get',
116118
'SnapController:handleRequest',
119+
'RemoteFeatureFlagController:getState',
117120
],
118121
});
119122

@@ -171,6 +174,9 @@ const createControllerMessenger = ({
171174
case 'SnapController:handleRequest':
172175
return mockSnapControllerHandleRequest(params);
173176

177+
case 'RemoteFeatureFlagController:getState':
178+
return mockRemoteFeatureFlagsGetStateRequest(params);
179+
174180
default:
175181
throw new Error(
176182
`MOCK_FAIL - unsupported messenger call: ${actionType}`,
@@ -191,6 +197,11 @@ const createSnapKeyringBuilder = ({
191197
jest.mocked(isSnapPreinstalled).mockReturnValue(snapPreinstalled);
192198
jest.mocked(getSnapName).mockReturnValue(snapName);
193199

200+
// Needed now to know if state 2 is enabled or not.
201+
mockRemoteFeatureFlagsGetStateRequest.mockReturnValue({
202+
remoteFeatureFlags: {},
203+
} as RemoteFeatureFlagControllerState);
204+
194205
return snapKeyringBuilder(createControllerMessenger(), {
195206
persistKeyringHelper: mockPersistKeyringHelper,
196207
removeAccountHelper: mockRemoveAccountHelper,

app/scripts/lib/snap-keyring/snap-keyring.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ import MetaMetricsController from '../../controllers/metametrics-controller';
2121
import { getUniqueAccountName } from '../../../../shared/lib/accounts';
2222
import { isSnapPreinstalled } from '../../../../shared/lib/snaps/snaps';
2323
import { getSnapName } from '../../../../shared/lib/accounts/snaps';
24+
import {
25+
FEATURE_VERSION_2,
26+
isMultichainAccountsFeatureEnabled,
27+
MultichainAccountsFeatureFlag,
28+
} from '../../../../shared/lib/multichain-accounts/remote-feature-flag';
2429
import { SnapKeyringBuilderMessenger } from './types';
2530
import { isBlockedUrl } from './utils/isBlockedUrl';
2631
import { showError, showSuccess } from './utils/showResult';
@@ -299,14 +304,24 @@ class SnapKeyringImpl implements SnapKeyringCallbacks {
299304
});
300305
}
301306

307+
#isMultichainAccountsFeatureState2Enabled() {
308+
const state = this.#messenger.call('RemoteFeatureFlagController:getState');
309+
310+
const featureFlag = state?.remoteFeatureFlags
311+
?.enableMultichainAccountsState2 as
312+
| MultichainAccountsFeatureFlag
313+
| undefined;
314+
return isMultichainAccountsFeatureEnabled(featureFlag, FEATURE_VERSION_2);
315+
}
316+
302317
async #addAccountFinalize({
303318
address,
304319
snapId,
305320
skipConfirmationDialog,
306321
skipSetSelectedAccountStep,
307322
skipApprovalFlow,
308-
accountName,
309323
onceSaved,
324+
accountName,
310325
defaultAccountNameChosen,
311326
}: {
312327
address: string;
@@ -364,12 +379,19 @@ class SnapKeyringImpl implements SnapKeyringCallbacks {
364379
);
365380
}
366381

367-
if (accountName) {
368-
this.#messenger.call(
369-
'AccountsController:setAccountName',
370-
accountId,
371-
accountName,
372-
);
382+
// HACK: In state 2, account creations can run in parallel, thus, `accountName`
383+
// sometimes conflict with other concurrent renaming. Since we don't rely on those
384+
// account names anymore, we just omit this part and make this race-free.
385+
// FIXME: We still rely on the old behavior in some e2e, so we cannot remove this
386+
// entirely.
387+
if (!this.#isMultichainAccountsFeatureState2Enabled()) {
388+
if (accountName) {
389+
this.#messenger.call(
390+
'AccountsController:setAccountName',
391+
accountId,
392+
accountName,
393+
);
394+
}
373395
}
374396

375397
if (!skipConfirmationDialog) {

app/scripts/lib/snap-keyring/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
IsMinimumPlatformVersion,
2424
} from '@metamask/snaps-controllers';
2525
import { SnapKeyring } from '@metamask/eth-snap-keyring';
26+
import { RemoteFeatureFlagControllerGetStateAction } from '@metamask/remote-feature-flag-controller';
2627
import { PreferencesControllerGetStateAction } from '../../controllers/preferences-controller';
2728

2829
export type SnapKeyringBuilderAllowActions =
@@ -44,7 +45,8 @@ export type SnapKeyringBuilderAllowActions =
4445
| HandleSnapRequest
4546
| GetSnap
4647
| PreferencesControllerGetStateAction
47-
| IsMinimumPlatformVersion;
48+
| IsMinimumPlatformVersion
49+
| RemoteFeatureFlagControllerGetStateAction;
4850

4951
export type SnapKeyringBuilderMessenger = Messenger<
5052
'SnapKeyring',

app/scripts/metamask-controller.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5110,6 +5110,15 @@ export default class MetamaskController extends EventEmitter {
51105110
await this.getSnapKeyring(),
51115111
this.accountTreeController.getSelectedAccountGroup(),
51125112
);
5113+
5114+
if (this.isMultichainAccountsFeatureState2Enabled()) {
5115+
// This allows to create missing accounts if new account providers have been added.
5116+
// FIXME: We might wanna run discovery + alignment asynchronously here, like we do
5117+
// for mobile, but for now, this easy fix should cover new provider accounts.
5118+
// NOTE: We run this asynchronously on purpose, see FIXME^.
5119+
// eslint-disable-next-line no-void
5120+
void this.multichainAccountService.alignWallets();
5121+
}
51135122
}
51145123

51155124
async _loginUser(password) {

0 commit comments

Comments
 (0)