Skip to content

Commit 391c05b

Browse files
committed
fix(account-tree-controller): prevent :account{Added,Removed} if init has not been called yet
1 parent a263c74 commit 391c05b

File tree

2 files changed

+46
-16
lines changed

2 files changed

+46
-16
lines changed

packages/account-tree-controller/src/AccountTreeController.test.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
} from './AccountTreeController';
3333
import type { BackupAndSyncAnalyticsEventPayload } from './backup-and-sync/analytics';
3434
import { BackupAndSyncService } from './backup-and-sync/service';
35-
import { isAccountGroupNameUnique } from './group';
35+
import { AccountGroupMultichainAccountObject, isAccountGroupNameUnique } from './group';
3636
import { getAccountWalletNameFromKeyringType } from './rules/keyring';
3737
import {
3838
type AccountTreeControllerMessenger,
@@ -42,6 +42,7 @@ import {
4242
type AllowedActions,
4343
type AllowedEvents,
4444
} from './types';
45+
import { AccountWalletKeyringObject, AccountWalletObject } from './wallet';
4546

4647
// Local mock of EMPTY_ACCOUNT to avoid circular dependency
4748
const EMPTY_ACCOUNT_MOCK: InternalAccount = {
@@ -1215,6 +1216,26 @@ describe('AccountTreeController', () => {
12151216
},
12161217
} as AccountTreeControllerState);
12171218
});
1219+
1220+
it('does not remove account if init has not been called', () => {
1221+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
1222+
const { controller, messenger } = setup({
1223+
accounts: [MOCK_HD_ACCOUNT_1],
1224+
});
1225+
1226+
const mockAccountTreeChange = jest.fn();
1227+
messenger.subscribe(
1228+
'AccountTreeController:accountTreeChange',
1229+
mockAccountTreeChange,
1230+
);
1231+
1232+
messenger.publish(
1233+
'AccountsController:accountRemoved',
1234+
MOCK_HD_ACCOUNT_1.id,
1235+
);
1236+
1237+
expect(mockAccountTreeChange).not.toHaveBeenCalled();
1238+
});
12181239
});
12191240

12201241
describe('account ordering by type', () => {
@@ -1487,6 +1508,14 @@ describe('AccountTreeController', () => {
14871508
hasAccountTreeSyncingSyncedAtLeastOnce: false,
14881509
} as AccountTreeControllerState);
14891510
});
1511+
1512+
it('does not add any account if init has not been called', () => {
1513+
const { controller, messenger } = setup();
1514+
1515+
expect(controller.state.accountTree.wallets).toStrictEqual({});
1516+
messenger.publish('AccountsController:accountAdded', MOCK_HD_ACCOUNT_1);
1517+
expect(controller.state.accountTree.wallets).toStrictEqual({});
1518+
});
14901519
});
14911520

14921521
describe('on MultichainAccountService:walletStatusUpdate', () => {
@@ -4266,6 +4295,8 @@ describe('AccountTreeController', () => {
42664295
it('names non-HD keyrings accounts properly', () => {
42674296
const { controller, messenger } = setup();
42684297

4298+
controller.init();
4299+
42694300
// Add all 3 accounts.
42704301
[mockAccount1, mockAccount2, mockAccount3].forEach(
42714302
(mockAccount, index) => {
@@ -4418,6 +4449,8 @@ describe('AccountTreeController', () => {
44184449
it('fallbacks to natural indexing if group names are not using our default name pattern', () => {
44194450
const { controller, messenger } = setup();
44204451

4452+
controller.init();
4453+
44214454
[mockAccount1, mockAccount2, mockAccount3].forEach((mockAccount) =>
44224455
messenger.publish('AccountsController:accountAdded', mockAccount),
44234456
);

packages/account-tree-controller/src/AccountTreeController.ts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -346,15 +346,6 @@ export class AccountTreeController extends BaseController<
346346
this.init();
347347
}
348348

349-
/**
350-
* Force-init if the controller's state has not been initilized yet.
351-
*/
352-
#initAtLeastOnce() {
353-
if (!this.#initialized) {
354-
this.init();
355-
}
356-
}
357-
358349
/**
359350
* Rule for entropy-base wallets.
360351
*
@@ -664,9 +655,12 @@ export class AccountTreeController extends BaseController<
664655
* @param account - New account.
665656
*/
666657
#handleAccountAdded(account: InternalAccount) {
667-
// We force-init to make sure we have the proper account groups for the
668-
// incoming account change.
669-
this.#initAtLeastOnce();
658+
// We wait for the first `init` to be called to actually build up the tree and
659+
// mutate it. We expect the caller to first update the `AccountsController` state
660+
// to force the migration of accounts, and then call `init`.
661+
if (!this.#initialized) {
662+
return;
663+
}
670664

671665
// Check if this account got already added by `#initAtLeastOnce`, if not, then we
672666
// can proceed.
@@ -700,9 +694,12 @@ export class AccountTreeController extends BaseController<
700694
* @param accountId - Removed account ID.
701695
*/
702696
#handleAccountRemoved(accountId: AccountId) {
703-
// We force-init to make sure we have the proper account groups for the
704-
// incoming account change.
705-
this.#initAtLeastOnce();
697+
// We wait for the first `init` to be called to actually build up the tree and
698+
// mutate it. We expect the caller to first update the `AccountsController` state
699+
// to force the migration of accounts, and then call `init`.
700+
if (!this.#initialized) {
701+
return;
702+
}
706703

707704
const context = this.#accountIdToContext.get(accountId);
708705

0 commit comments

Comments
 (0)