Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
1ae4362
fix: apply controller fix for the invalid-access-token error
lwin-kyaw Jul 21, 2025
82a9f67
test: reset app
lwin-kyaw Aug 12, 2025
7b89e75
Merge remote-tracking branch 'origin/main' into feat/reset-wallet
lwin-kyaw Sep 20, 2025
473e7e2
Merge remote-tracking branch 'origin/main' into feat/reset-wallet
lwin-kyaw Sep 23, 2025
320c5bc
feat: reset app and background controllers state
lwin-kyaw Sep 23, 2025
536af4b
Merge remote-tracking branch 'origin/main' into feat/reset-wallet
lwin-kyaw Sep 23, 2025
add53d3
chore: removed dupes
lwin-kyaw Sep 23, 2025
ca12fe0
Merge remote-tracking branch 'origin/main' into feat/reset-wallet
lwin-kyaw Sep 24, 2025
e881551
added new state to App Controller for wallet reset progress
lwin-kyaw Sep 24, 2025
35a2834
feat: add LoginError modal for unlock page
lwin-kyaw Sep 24, 2025
0e56c01
feat: update locales for Unlock Error Modal description
lwin-kyaw Sep 24, 2025
ff3082c
chore: rename vars
lwin-kyaw Sep 24, 2025
69bf490
removed logs
lwin-kyaw Sep 24, 2025
dae5707
Merge remote-tracking branch 'origin/main' into feat/reset-wallet
lwin-kyaw Sep 27, 2025
f28f5f0
test: added e2e tests for the reset-wallet flow
lwin-kyaw Sep 29, 2025
674e10e
fix: fixed CI
lwin-kyaw Sep 29, 2025
22e8081
fix :fixed unit tests
lwin-kyaw Sep 29, 2025
1ce8cd5
Merge remote-tracking branch 'origin/main' into feat/reset-wallet
lwin-kyaw Sep 29, 2025
155a976
fix: fixed e2e
lwin-kyaw Sep 29, 2025
e8eb9a2
fix: fixed tests for firefox
lwin-kyaw Sep 29, 2025
2a3bf3c
Merge remote-tracking branch 'origin/main' into feat/reset-wallet
lwin-kyaw Sep 29, 2025
36775c1
fix: fixed bridge.specs
lwin-kyaw Sep 29, 2025
6570184
feat: updated AppStateController state metadata
lwin-kyaw Sep 29, 2025
785b077
fix: fixed unit tests
lwin-kyaw Sep 29, 2025
508bae0
fix: fixed e2e again
lwin-kyaw Sep 30, 2025
67e3c0a
fix: fixed pwd outdated check cron job
lwin-kyaw Sep 30, 2025
cdae71c
try moving snap clearstate to keyring overrides
lwin-kyaw Sep 30, 2025
8b5ae1d
feat: seedless controller update
lwin-kyaw Oct 30, 2025
6126602
feat: validate SeedlessOnboarding Authenticated state in create-passw…
lwin-kyaw Oct 30, 2025
0262278
test: added unit tests
lwin-kyaw Oct 30, 2025
763ebd4
Merge remote-tracking branch 'origin/main' into fix/invalid-access-token
lwin-kyaw Oct 30, 2025
70a9c7f
Merge remote-tracking branch 'origin/fix/invalid-access-token' into f…
lwin-kyaw Oct 30, 2025
a5119af
resolved conflicts
lwin-kyaw Oct 30, 2025
30201d1
Update LavaMoat policies
metamaskbot Oct 30, 2025
07649b9
Merge remote-tracking branch 'origin/main' into fix/invalid-access-token
lwin-kyaw Oct 30, 2025
fd09f0b
feat: update seedless-onboarding-controller to 6.0.0
lwin-kyaw Oct 30, 2025
7a93b4a
Merge remote-tracking branch 'origin/fix/invalid-access-token' into f…
lwin-kyaw Oct 30, 2025
56da278
chore: resolved conflicts
lwin-kyaw Oct 31, 2025
25d72d7
fix: fixed lint and unit tests
lwin-kyaw Oct 31, 2025
6360060
fix: fixed lint
lwin-kyaw Oct 31, 2025
ddfa8da
fix: fixed e2e
lwin-kyaw Oct 31, 2025
f2c0982
test: added more tests
lwin-kyaw Oct 31, 2025
5c759c7
Merge branch 'main' into feat/reset-wallet
lwin-kyaw Oct 31, 2025
a6841a2
fix: ignore snap error in reset-wallet test
lwin-kyaw Oct 31, 2025
698f77f
chore: merged wih feat/reset-wallet branch
lwin-kyaw Oct 31, 2025
aa5fa6c
test: updated e2e tests
lwin-kyaw Oct 31, 2025
d73c564
feat: updated syncPasswordAndUnlockWallet in metamask-controller
lwin-kyaw Oct 31, 2025
d895088
fix: ignore snap error in reset-wallet test
lwin-kyaw Oct 31, 2025
1f1e735
test: update ignoredConsoleErrors in reset-wallet e2e
lwin-kyaw Oct 31, 2025
4a63f0a
chore: resolved conflicts
lwin-kyaw Nov 1, 2025
50c9965
fix: reset pwd outdated cache after wallet reset
lwin-kyaw Nov 1, 2025
0a4a04e
Merge branch 'main' into feat/reset-wallet
lwin-kyaw Nov 1, 2025
a451dd9
feat: removed 'ConnectionRemovedModal' from the home page
lwin-kyaw Nov 1, 2025
61c39bc
Merge remote-tracking branch 'origin/feat/reset-wallet' into fix/inva…
lwin-kyaw Nov 1, 2025
7b22c46
fix: errors.spec
lwin-kyaw Nov 1, 2025
2d07c71
Merge remote-tracking branch 'origin/feat/reset-wallet' into fix/inva…
lwin-kyaw Nov 1, 2025
856a42c
fix: fixed unit tests
lwin-kyaw Nov 1, 2025
fc9143f
fix: fixed firefox e2e and added unit tests
lwin-kyaw Nov 1, 2025
b73be1f
Merge remote-tracking branch 'origin/feat/reset-wallet' into fix/inva…
lwin-kyaw Nov 1, 2025
3f83de9
fix: fixed firefox e2e and added unit tests
lwin-kyaw Nov 1, 2025
8e8ea8d
fix: fixed errors.spec.ts
lwin-kyaw Nov 3, 2025
601ae29
fixing tests
lwin-kyaw Nov 3, 2025
8c94f3e
test: updated reset-wallet.spec
lwin-kyaw Nov 3, 2025
91eca11
fix tests maybe?
lwin-kyaw Nov 3, 2025
c322a0c
Merge branch 'main' into feat/reset-wallet
lwin-kyaw Nov 3, 2025
370334a
updated 'createNewVaultAndKeychain' method with isWalletResetInProgress
lwin-kyaw Nov 3, 2025
fd90a14
Merge branch 'main' into feat/reset-wallet
lwin-kyaw Nov 3, 2025
8b05e9c
chore: resolved conflicts
lwin-kyaw Nov 3, 2025
4fa1f04
try removing ignoredError in reset-wallet.spec
lwin-kyaw Nov 3, 2025
6bea8f7
revert setState in unlock.page
lwin-kyaw Nov 4, 2025
2b5d2c0
Merge remote-tracking branch 'origin/feat/reset-wallet' into fix/inva…
lwin-kyaw Nov 4, 2025
3c86839
feat: renamed 'getIsSeedlessOnboardingUserAuthenticated' method
lwin-kyaw Nov 4, 2025
26a6e80
update controller
lwin-kyaw Nov 4, 2025
d9e19bb
fix: fixed unlock-wallet connection removal spec
lwin-kyaw Nov 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions app/_locales/en_GB/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/scripts/constants/sentry-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export const SENTRY_BACKGROUND_STATE = {
lastUpdatedAt: true,
shieldEndingToastLastClickedOrClosed: true,
shieldPausedToastLastClickedOrClosed: true,
isWalletResetInProgress: false,
},
MultichainBalancesController: {
balances: false,
Expand Down
4 changes: 4 additions & 0 deletions app/scripts/controllers/app-state-controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ describe('AppStateController', () => {
"hasShownMultichainAccountsIntroModal": false,
"isRampCardClosed": false,
"isUpdateAvailable": false,
"isWalletResetInProgress": false,
"lastInteractedConfirmationInfo": {
"chainId": "0x1",
"id": "123",
Expand Down Expand Up @@ -860,6 +861,7 @@ describe('AppStateController', () => {
"hasShownMultichainAccountsIntroModal": false,
"isRampCardClosed": false,
"isUpdateAvailable": false,
"isWalletResetInProgress": false,
"lastInteractedConfirmationInfo": {
"chainId": "0x1",
"id": "123",
Expand Down Expand Up @@ -939,6 +941,7 @@ describe('AppStateController', () => {
"hadAdvancedGasFeesSetPriorToMigration92_3": false,
"hasShownMultichainAccountsIntroModal": false,
"isRampCardClosed": false,
"isWalletResetInProgress": false,
"lastInteractedConfirmationInfo": {
"chainId": "0x1",
"id": "123",
Expand Down Expand Up @@ -1020,6 +1023,7 @@ describe('AppStateController', () => {
"hasShownMultichainAccountsIntroModal": false,
"isRampCardClosed": false,
"isUpdateAvailable": false,
"isWalletResetInProgress": false,
"lastInteractedConfirmationInfo": {
"chainId": "0x1",
"id": "123",
Expand Down
23 changes: 23 additions & 0 deletions app/scripts/controllers/app-state-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ export type AppStateControllerState = {
updateModalLastDismissedAt: number | null;
hasShownMultichainAccountsIntroModal: boolean;
showShieldEntryModalOnce: boolean | null;

/**
* Whether the wallet reset is in progress.
*/
isWalletResetInProgress: boolean;
};

const controllerName = 'AppStateController';
Expand Down Expand Up @@ -268,6 +273,8 @@ const getDefaultAppStateControllerState = (): AppStateControllerState => ({
updateModalLastDismissedAt: null,
hasShownMultichainAccountsIntroModal: false,
showShieldEntryModalOnce: null,
isWalletResetInProgress: false,

...getInitialStateOverrides(),
});

Expand Down Expand Up @@ -599,6 +606,12 @@ const controllerMetadata: StateMetadata<AppStateControllerState> = {
includeInDebugSnapshot: true,
usedInUi: true,
},
isWalletResetInProgress: {
persist: true,
includeInDebugSnapshot: true,
usedInUi: true,
includeInStateLogs: true,
},
};

export class AppStateController extends BaseController<
Expand Down Expand Up @@ -1502,4 +1515,14 @@ export class AppStateController extends BaseController<
state.canTrackWalletFundsObtained = enabled;
});
}

setIsWalletResetInProgress(isResetting: boolean): void {
this.update((state) => {
state.isWalletResetInProgress = isResetting;
});
}

getIsWalletResetInProgress(): boolean {
return this.state.isWalletResetInProgress;
}
}
12 changes: 12 additions & 0 deletions app/scripts/controllers/onboarding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,16 @@ export default class OnboardingController extends BaseController<
firstTimeFlowType === FirstTimeFlowType.socialImport
);
}

/**
* Reset the onboarding controller state.
*/
resetOnboarding(): void {
this.update((state) => {
state.completedOnboarding = false;
state.firstTimeFlowType = null;
state.seedPhraseBackedUp = null;
state.onboardingTabs = {};
});
}
}
4 changes: 1 addition & 3 deletions app/scripts/metamask-controller.actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -835,10 +835,8 @@ describe('MetaMaskController', function () {
// We now need the Snap keyring after unlocking the wallet.
jest.spyOn(metamaskController, 'getSnapKeyring').mockReturnValue({});

const syncAndUnlockResult =
await metamaskController.syncPasswordAndUnlockWallet(password);
await metamaskController.syncPasswordAndUnlockWallet(password);

expect(syncAndUnlockResult).toBe(true);
expect(keyringSubmitPwdSpy).toHaveBeenCalled();
expect(seedlessSubmitPwdSpy).toHaveBeenCalled();
});
Expand Down
76 changes: 47 additions & 29 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -2784,6 +2784,10 @@ export default class MetamaskController extends EventEmitter {
this.restoreSocialBackupAndGetSeedPhrase.bind(this),
syncSeedPhrases: this.syncSeedPhrases.bind(this),
changePassword: this.changePassword.bind(this),
getIsSeedlessOnboardingUserAuthenticated:
this.seedlessOnboardingController.getIsUserAuthenticated.bind(
this.seedlessOnboardingController,
),

// GatorPermissionsController
fetchAndUpdateGatorPermissions:
Expand Down Expand Up @@ -3377,6 +3381,7 @@ export default class MetamaskController extends EventEmitter {
),
}),
lookupSelectedNetworks: this.lookupSelectedNetworks.bind(this),
resetWallet: this.resetWallet.bind(this),
};
}

Expand All @@ -3394,6 +3399,16 @@ export default class MetamaskController extends EventEmitter {
});
}

async resetWallet() {
// clear SeedlessOnboardingController state
this.seedlessOnboardingController.clearState();

// reset onboarding state
this.onboardingController.resetOnboarding();

this.appStateController.setIsWalletResetInProgress(true);
}

async exportAccount(address, password) {
await this.verifyPassword(password);
return this.keyringController.exportAccount(password, address);
Expand Down Expand Up @@ -3768,7 +3783,6 @@ export default class MetamaskController extends EventEmitter {
* and user has changed password more than 20 times since the last time they used the app on this device.
*/
async syncPasswordAndUnlockWallet(password) {
let isPasswordSynced = false;
const isSocialLoginFlow = this.onboardingController.getIsSocialLoginFlow();
// check if the password is outdated
let isPasswordOutdated = false;
Expand Down Expand Up @@ -3804,8 +3818,7 @@ export default class MetamaskController extends EventEmitter {
});
});
}
isPasswordSynced = true;
return isPasswordSynced;
return;
}
const releaseLock = await this.seedlessOperationMutex.acquire();

Expand All @@ -3830,14 +3843,8 @@ export default class MetamaskController extends EventEmitter {
globalPassword: password,
maxKeyChainLength: 20,
})
.then(() => {
// Case 1.
isPasswordSynced = true;
})
.catch((err) => {
log.error(
`error while submitting global password: ${err.message} , isKeyringPasswordValid: ${isKeyringPasswordValid}`,
);
log.error(`error while submitting global password: ${err.message}`);
if (err instanceof RecoveryError) {
// Keyring controller password verification succeeds and seedless controller failed.
if (
Expand All @@ -3850,28 +3857,11 @@ export default class MetamaskController extends EventEmitter {
);
}
throw new JsonRpcError(-32603, err.message, err.data);
} else if (
err.message ===
SeedlessOnboardingControllerErrorMessage.MaxKeyChainLengthExceeded
) {
isPasswordSynced = false;
} else {
throw err;
}
});

// we are unable to recover the old pwd enc key as user is on a very old device.
// create a new vault and encrypt the new vault with the latest global password.
// also show a info popup to user.
if (!isPasswordSynced) {
// refresh the current auth tokens to get the latest auth tokens
await this.seedlessOnboardingController.refreshAuthTokens();
// create a new vault and encrypt the new vault with the latest global password
await this.restoreSocialBackupAndGetSeedPhrase(password);
// display info popup to user based on the password sync status
return isPasswordSynced;
}

// re-encrypt the old vault data with the latest global password
const keyringEncryptionKey =
await this.seedlessOnboardingController.loadKeyringEncryptionKey();
Expand Down Expand Up @@ -3937,7 +3927,6 @@ export default class MetamaskController extends EventEmitter {
data: { success: changePasswordSuccess },
});
}
return isPasswordSynced;
} finally {
releaseLock();
}
Expand Down Expand Up @@ -4169,16 +4158,42 @@ export default class MetamaskController extends EventEmitter {
*/
async createNewVaultAndKeychain(password) {
const releaseLock = await this.createVaultMutex.acquire();
const isWalletResetInProgress =
this.appStateController.getIsWalletResetInProgress();
try {
if (isWalletResetInProgress) {
// clear permissions
this.permissionController.clearState();

// Clear snap state
await this.snapController.clearState();

// Clear account tree state
this.accountTreeController.clearState();

// Currently, the account-order-controller is not in sync with
// the accounts-controller. To properly persist the hidden state
// of accounts, we should add a new flag to the account struct
// to indicate if it is hidden or not.
// TODO: Update @metamask/accounts-controller to support this.
this.accountOrderController.updateHiddenAccountsList([]);

this.txController.clearUnapprovedTransactions();
}

await this.keyringController.createNewVaultAndKeychain(password);

// set is resetting wallet in progress to false, after new vault and keychain are created
this.appStateController.setIsWalletResetInProgress(false);

const primaryKeyring = this.keyringController.state.keyrings[0];

// Once we have our first HD keyring available, we re-create the internal list of
// accounts (they should be up-to-date already, but we still run `updateAccounts` as
// there are some account migration happening in that function).
await this.accountsController.updateAccounts();
// Then we can build the initial tree.
this.accountTreeController.init();
this.accountTreeController.reinit();
// TODO: Move this logic to the SnapKeyring directly.
// Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts.
await this.forwardSelectedAccountGroupToSnapKeyring(
Expand Down Expand Up @@ -4562,6 +4577,9 @@ export default class MetamaskController extends EventEmitter {
seedPhraseAsUint8Array,
);

// set is resetting wallet in progress to false, after new vault and keychain are created
this.appStateController.setIsWalletResetInProgress(false);

// We re-created the vault, meaning we only have 1 new HD keyring
// now. We re-create the internal list of accounts (which is
// not an expensive operation, since we should only have 1 HD
Expand Down
20 changes: 17 additions & 3 deletions lavamoat/browserify/beta/policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,20 @@
"eslint>json-stable-stringify-without-jsonify": true
}
},
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@metamask/auth-network-utils": {
"globals": {
"clearTimeout": true,
"setTimeout": true
},
"packages": {
"@noble/curves": true,
"@noble/hashes": true,
"bn.js": true,
"browserify>buffer": true,
"@toruslabs/eccrypto>elliptic": true,
"eslint>json-stable-stringify-without-jsonify": true
}
},
"@metamask/base-controller": {
"globals": {
"console.error": true
Expand Down Expand Up @@ -1992,11 +2006,11 @@
"fetch": true
},
"packages": {
"@metamask/seedless-onboarding-controller>@metamask/auth-network-utils": true,
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@metamask/auth-network-utils": true,
"@noble/ciphers": true,
"@noble/curves": true,
"@noble/hashes": true,
"@toruslabs/eccrypto": true,
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@toruslabs/eccrypto": true,
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@toruslabs/fetch-node-details": true,
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@toruslabs/http-helpers": true,
"bn.js": true,
Expand Down Expand Up @@ -2524,7 +2538,7 @@
"browserify>browser-resolve": true
}
},
"@toruslabs/eccrypto": {
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@toruslabs/eccrypto": {
"globals": {
"crypto": true,
"msCrypto": true
Expand Down
20 changes: 17 additions & 3 deletions lavamoat/browserify/experimental/policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,20 @@
"eslint>json-stable-stringify-without-jsonify": true
}
},
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@metamask/auth-network-utils": {
"globals": {
"clearTimeout": true,
"setTimeout": true
},
"packages": {
"@noble/curves": true,
"@noble/hashes": true,
"bn.js": true,
"browserify>buffer": true,
"@toruslabs/eccrypto>elliptic": true,
"eslint>json-stable-stringify-without-jsonify": true
}
},
"@metamask/base-controller": {
"globals": {
"console.error": true
Expand Down Expand Up @@ -1992,11 +2006,11 @@
"fetch": true
},
"packages": {
"@metamask/seedless-onboarding-controller>@metamask/auth-network-utils": true,
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@metamask/auth-network-utils": true,
"@noble/ciphers": true,
"@noble/curves": true,
"@noble/hashes": true,
"@toruslabs/eccrypto": true,
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@toruslabs/eccrypto": true,
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@toruslabs/fetch-node-details": true,
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@toruslabs/http-helpers": true,
"bn.js": true,
Expand Down Expand Up @@ -2524,7 +2538,7 @@
"browserify>browser-resolve": true
}
},
"@toruslabs/eccrypto": {
"@metamask/seedless-onboarding-controller>@metamask/toprf-secure-backup>@toruslabs/eccrypto": {
"globals": {
"crypto": true,
"msCrypto": true
Expand Down
Loading
Loading