Skip to content

Commit 8c7e1e0

Browse files
authored
fix: add HD keyring check to persistAllKeyrings (#4168)
1 parent 1536fce commit 8c7e1e0

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

packages/keyring-controller/src/KeyringController.test.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -1111,12 +1111,20 @@ describe('KeyringController', () => {
11111111
* If there is only HD Key Tree keyring with 1 account and removeAccount is called passing that account
11121112
* It deletes keyring object also from state - not sure if this is correct behavior.
11131113
* https://github.com/MetaMask/core/issues/801
1114+
*
1115+
* Update: The behaviour is now modified to never remove the HD keyring as a preventive and temporal solution to the current race
1116+
* condition case we have been seeing lately. https://github.com/MetaMask/mobile-planning/issues/1507
1117+
* Enforcing this behaviour is not a 100% correct and it should be responsibility of the consumer to handle the accounts
1118+
* and keyrings in a way that it matches the expected behaviour.
11141119
*/
1115-
it('should remove HD Key Tree keyring from state when single account associated with it is deleted', async () => {
1120+
it('should not remove HD Key Tree keyring nor the single account from state', async () => {
11161121
await withController(async ({ controller, initialState }) => {
11171122
const account = initialState.keyrings[0].accounts[0] as Hex;
1118-
await controller.removeAccount(account);
1119-
expect(controller.state.keyrings).toHaveLength(0);
1123+
await expect(controller.removeAccount(account)).rejects.toThrow(
1124+
KeyringControllerError.NoHdKeyring,
1125+
);
1126+
expect(controller.state.keyrings).toHaveLength(1);
1127+
expect(controller.state.keyrings[0].accounts).toHaveLength(1);
11201128
});
11211129
});
11221130

packages/keyring-controller/src/KeyringController.ts

+6
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,12 @@ export class KeyringController extends BaseController<
953953

954954
serializedKeyrings.push(...this.#unsupportedKeyrings);
955955

956+
if (
957+
!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)
958+
) {
959+
throw new Error(KeyringControllerError.NoHdKeyring);
960+
}
961+
956962
const updatedState: Partial<KeyringControllerState> = {};
957963

958964
if (this.#cacheEncryptionKey) {

packages/keyring-controller/src/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ export enum KeyringControllerError {
2626
ExpiredCredentials = 'KeyringController - Encryption key and salt provided are expired',
2727
NoKeyringBuilder = 'KeyringController - No keyringBuilder found for keyring',
2828
DataType = 'KeyringController - Incorrect data type provided',
29+
NoHdKeyring = 'KeyringController - No HD Keyring found',
2930
}

0 commit comments

Comments
 (0)