Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,22 @@ linkStyle default opacity:0.5
account_tree_controller --> multichain_account_service;
account_tree_controller --> profile_sync_controller;
accounts_controller --> base_controller;
accounts_controller --> messenger;
accounts_controller --> controller_utils;
accounts_controller --> keyring_controller;
accounts_controller --> network_controller;
address_book_controller --> base_controller;
address_book_controller --> controller_utils;
address_book_controller --> messenger;
announcement_controller --> base_controller;
announcement_controller --> messenger;
app_metadata_controller --> base_controller;
app_metadata_controller --> messenger;
approval_controller --> base_controller;
approval_controller --> messenger;
assets_controllers --> base_controller;
assets_controllers --> controller_utils;
assets_controllers --> messenger;
assets_controllers --> polling_controller;
assets_controllers --> account_tree_controller;
assets_controllers --> accounts_controller;
Expand All @@ -174,6 +180,7 @@ linkStyle default opacity:0.5
bridge_controller --> base_controller;
bridge_controller --> controller_utils;
bridge_controller --> gas_fee_controller;
bridge_controller --> messenger;
bridge_controller --> multichain_network_controller;
bridge_controller --> polling_controller;
bridge_controller --> accounts_controller;
Expand Down Expand Up @@ -201,10 +208,12 @@ linkStyle default opacity:0.5
core_backend --> accounts_controller;
core_backend --> keyring_controller;
delegation_controller --> base_controller;
delegation_controller --> messenger;
delegation_controller --> accounts_controller;
delegation_controller --> keyring_controller;
earn_controller --> base_controller;
earn_controller --> controller_utils;
earn_controller --> messenger;
earn_controller --> account_tree_controller;
earn_controller --> network_controller;
earn_controller --> transaction_controller;
Expand All @@ -216,6 +225,7 @@ linkStyle default opacity:0.5
eip1193_permission_middleware --> permission_controller;
ens_controller --> base_controller;
ens_controller --> controller_utils;
ens_controller --> messenger;
ens_controller --> network_controller;
error_reporting_service --> base_controller;
eth_json_rpc_provider --> json_rpc_engine;
Expand All @@ -224,8 +234,10 @@ linkStyle default opacity:0.5
gas_fee_controller --> polling_controller;
gas_fee_controller --> network_controller;
gator_permissions_controller --> base_controller;
gator_permissions_controller --> messenger;
json_rpc_middleware_stream --> json_rpc_engine;
keyring_controller --> base_controller;
keyring_controller --> messenger;
logging_controller --> base_controller;
logging_controller --> controller_utils;
message_manager --> base_controller;
Expand Down Expand Up @@ -254,6 +266,7 @@ linkStyle default opacity:0.5
network_controller --> controller_utils;
network_controller --> eth_json_rpc_provider;
network_controller --> json_rpc_engine;
network_controller --> messenger;
network_controller --> error_reporting_service;
network_enablement_controller --> base_controller;
network_enablement_controller --> controller_utils;
Expand Down Expand Up @@ -301,6 +314,7 @@ linkStyle default opacity:0.5
signature_controller --> controller_utils;
signature_controller --> accounts_controller;
signature_controller --> approval_controller;
signature_controller --> gator_permissions_controller;
signature_controller --> keyring_controller;
signature_controller --> logging_controller;
signature_controller --> network_controller;
Expand All @@ -310,6 +324,7 @@ linkStyle default opacity:0.5
token_search_discovery_controller --> base_controller;
transaction_controller --> base_controller;
transaction_controller --> controller_utils;
transaction_controller --> messenger;
transaction_controller --> accounts_controller;
transaction_controller --> approval_controller;
transaction_controller --> eth_json_rpc_provider;
Expand Down
8 changes: 4 additions & 4 deletions eslint-warning-thresholds.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
"jsdoc/tag-lines": 1
},
"packages/assets-controllers/src/RatesController/RatesController.test.ts": {
"import-x/order": 2,
"jsdoc/tag-lines": 4
"import-x/order": 1,
"jsdoc/tag-lines": 2
},
"packages/assets-controllers/src/RatesController/RatesController.ts": {
"@typescript-eslint/prefer-readonly": 1,
Expand All @@ -56,7 +56,7 @@
},
"packages/assets-controllers/src/TokenListController.test.ts": {
"import-x/namespace": 7,
"import-x/order": 3,
"import-x/order": 2,
"jest/no-conditional-in-test": 2
},
"packages/assets-controllers/src/TokenRatesController.test.ts": {
Expand All @@ -68,7 +68,7 @@
},
"packages/assets-controllers/src/TokensController.test.ts": {
"import-x/namespace": 1,
"import-x/order": 4,
"import-x/order": 3,
"jest/no-conditional-in-test": 2
},
"packages/assets-controllers/src/TokensController.ts": {
Expand Down
5 changes: 5 additions & 0 deletions packages/account-tree-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- **BREAKING:** Use new `Messenger` from `@metamask/messenger` ([#6380](https://github.com/MetaMask/core/pull/6380))
- Previously, `AccountTreeController` accepted a `RestrictedMessenger` instance from `@metamask/base-controller`.

### Fixed

- Fix wallet metadata cleanup when wallets are completely removed ([#6813](https://github.com/MetaMask/core/pull/6813))
Expand Down
1 change: 1 addition & 0 deletions packages/account-tree-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
},
"dependencies": {
"@metamask/base-controller": "^8.4.1",
"@metamask/messenger": "^0.3.0",
"@metamask/snaps-sdk": "^9.0.0",
"@metamask/snaps-utils": "^11.0.0",
"@metamask/superstruct": "^3.1.0",
Expand Down
128 changes: 37 additions & 91 deletions packages/account-tree-controller/src/AccountTreeController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
toMultichainAccountWalletId,
type AccountGroupId,
} from '@metamask/account-api';
import { Messenger, deriveStateFromMetadata } from '@metamask/base-controller';
import { deriveStateFromMetadata } from '@metamask/base-controller/next';
import {
EthAccountType,
EthMethod,
Expand All @@ -34,14 +34,11 @@ import type { BackupAndSyncAnalyticsEventPayload } from './backup-and-sync/analy
import { BackupAndSyncService } from './backup-and-sync/service';
import { isAccountGroupNameUnique } from './group';
import { getAccountWalletNameFromKeyringType } from './rules/keyring';
import { type AccountTreeControllerState } from './types';
import {
type AccountTreeControllerMessenger,
type AccountTreeControllerActions,
type AccountTreeControllerEvents,
type AccountTreeControllerState,
type AllowedActions,
type AllowedEvents,
} from './types';
getAccountTreeControllerMessenger,
getRootMessenger,
} from '../tests/mockMessenger';

// Local mock of EMPTY_ACCOUNT to avoid circular dependency
const EMPTY_ACCOUNT_MOCK: InternalAccount = {
Expand Down Expand Up @@ -231,53 +228,7 @@ const MOCK_HARDWARE_ACCOUNT_1: InternalAccount = {
},
};

/**
* Creates a new root messenger instance for testing.
*
* @returns A new Messenger instance.
*/
function getRootMessenger() {
return new Messenger<
AccountTreeControllerActions | AllowedActions,
AccountTreeControllerEvents | AllowedEvents
>();
}

/**
* Retrieves a restricted messenger for the AccountTreeController.
*
* @param messenger - The root messenger instance. Defaults to a new Messenger created by getRootMessenger().
* @returns The restricted messenger for the AccountTreeController.
*/
function getAccountTreeControllerMessenger(
messenger = getRootMessenger(),
): AccountTreeControllerMessenger {
return messenger.getRestricted({
name: 'AccountTreeController',
allowedEvents: [
'AccountsController:accountAdded',
'AccountsController:accountRemoved',
'AccountsController:selectedAccountChange',
'UserStorageController:stateChange',
'MultichainAccountService:walletStatusChange',
],
allowedActions: [
'AccountsController:listMultichainAccounts',
'AccountsController:getAccount',
'AccountsController:getSelectedMultichainAccount',
'AccountsController:setSelectedAccount',
'UserStorageController:getState',
'UserStorageController:performGetStorage',
'UserStorageController:performGetStorageAllFeatureEntries',
'UserStorageController:performSetStorage',
'UserStorageController:performBatchSetStorage',
'AuthenticationController:getSessionProfile',
'MultichainAccountService:createMultichainAccountGroup',
'KeyringController:getState',
'SnapController:get',
],
});
}
const mockGetSelectedMultichainAccountActionHandler = jest.fn();

/**
* Sets up the AccountTreeController for testing.
Expand Down Expand Up @@ -308,10 +259,7 @@ function setup({
},
}: {
state?: Partial<AccountTreeControllerState>;
messenger?: Messenger<
AccountTreeControllerActions | AllowedActions,
AccountTreeControllerEvents | AllowedEvents
>;
messenger?: ReturnType<typeof getRootMessenger>;
accounts?: InternalAccount[];
keyrings?: KeyringObject[];
config?: {
Expand All @@ -325,9 +273,9 @@ function setup({
};
} = {}): {
controller: AccountTreeController;
messenger: Messenger<
AccountTreeControllerActions | AllowedActions,
AccountTreeControllerEvents | AllowedEvents
messenger: ReturnType<typeof getRootMessenger>;
accountTreeControllerMessenger: ReturnType<
typeof getAccountTreeControllerMessenger
>;
spies: {
consoleWarn: jest.SpyInstance;
Expand Down Expand Up @@ -388,6 +336,7 @@ function setup({
mocks.AccountsController.listMultichainAccounts.mockImplementation(
() => mocks.AccountsController.accounts,
);

messenger.registerActionHandler(
'AccountsController:listMultichainAccounts',
mocks.AccountsController.listMultichainAccounts,
Expand Down Expand Up @@ -461,8 +410,10 @@ function setup({
);
}

const accountTreeControllerMessenger =
getAccountTreeControllerMessenger(messenger);
const controller = new AccountTreeController({
messenger: getAccountTreeControllerMessenger(messenger),
messenger: accountTreeControllerMessenger,
state,
...(config && { config }),
});
Expand All @@ -474,6 +425,7 @@ function setup({
return {
controller,
messenger,
accountTreeControllerMessenger,
spies: { consoleWarn: consoleWarnSpy },
mocks,
};
Expand Down Expand Up @@ -1709,12 +1661,15 @@ describe('AccountTreeController', () => {
});

it('updates AccountsController selected account (with EVM account) when selectedAccountGroup changes', () => {
const { controller, messenger } = setup({
const { controller, accountTreeControllerMessenger } = setup({
accounts: [MOCK_HD_ACCOUNT_1, MOCK_HD_ACCOUNT_2],
keyrings: [MOCK_HD_KEYRING_1, MOCK_HD_KEYRING_2],
});

const setSelectedAccountSpy = jest.spyOn(messenger, 'call');
const setSelectedAccountSpy = jest.spyOn(
accountTreeControllerMessenger,
'call',
);

controller.init();

Expand Down Expand Up @@ -1746,15 +1701,18 @@ describe('AccountTreeController', () => {
},
},
} as const;
const { controller, messenger } = setup({
const { controller, accountTreeControllerMessenger } = setup({
accounts: [
MOCK_HD_ACCOUNT_1,
nonEvmAccount2, // Wallet 2 > Account 1.
],
keyrings: [MOCK_HD_KEYRING_1, MOCK_HD_KEYRING_2],
});

const setSelectedAccountSpy = jest.spyOn(messenger, 'call');
const setSelectedAccountSpy = jest.spyOn(
accountTreeControllerMessenger,
'call',
);

controller.init();

Expand Down Expand Up @@ -1876,18 +1834,14 @@ describe('AccountTreeController', () => {
});

it('falls back to first wallet first group when AccountsController returns EMPTY_ACCOUNT', () => {
const { controller, messenger } = setup({
const { controller } = setup({
accounts: [MOCK_HD_ACCOUNT_1, MOCK_HD_ACCOUNT_2],
keyrings: [MOCK_HD_KEYRING_1, MOCK_HD_KEYRING_2],
});

// Unregister existing handler and register new one BEFORE init
messenger.unregisterActionHandler(
'AccountsController:getSelectedMultichainAccount',
);
messenger.registerActionHandler(
'AccountsController:getSelectedMultichainAccount',
() => EMPTY_ACCOUNT_MOCK,
// Mock action handler BEFORE init
mockGetSelectedMultichainAccountActionHandler.mockReturnValue(
EMPTY_ACCOUNT_MOCK,
);

controller.init();
Expand All @@ -1905,7 +1859,7 @@ describe('AccountTreeController', () => {
});

it('falls back to first wallet first group when selected account is not in tree', () => {
const { controller, messenger } = setup({
const { controller } = setup({
accounts: [MOCK_HD_ACCOUNT_1, MOCK_HD_ACCOUNT_2],
keyrings: [MOCK_HD_KEYRING_1, MOCK_HD_KEYRING_2],
});
Expand All @@ -1916,12 +1870,8 @@ describe('AccountTreeController', () => {
id: 'unknown-account-id',
};

messenger.unregisterActionHandler(
'AccountsController:getSelectedMultichainAccount',
);
messenger.registerActionHandler(
'AccountsController:getSelectedMultichainAccount',
() => unknownAccount,
mockGetSelectedMultichainAccountActionHandler.mockReturnValue(
unknownAccount,
);

controller.init();
Expand All @@ -1939,18 +1889,14 @@ describe('AccountTreeController', () => {
});

it('returns empty string when no wallets exist and getSelectedMultichainAccount returns EMPTY_ACCOUNT', () => {
const { controller, messenger } = setup({
const { controller } = setup({
accounts: [],
keyrings: [],
});

// Mock getSelectedMultichainAccount to return EMPTY_ACCOUNT_MOCK (id is '') BEFORE init
messenger.unregisterActionHandler(
'AccountsController:getSelectedMultichainAccount',
);
messenger.registerActionHandler(
'AccountsController:getSelectedMultichainAccount',
() => EMPTY_ACCOUNT_MOCK,
// Mock getSelectedAccount to return EMPTY_ACCOUNT_MOCK (id is '') BEFORE init
mockGetSelectedMultichainAccountActionHandler.mockReturnValue(
EMPTY_ACCOUNT_MOCK,
);

controller.init();
Expand Down Expand Up @@ -4154,7 +4100,7 @@ describe('AccountTreeController', () => {
deriveStateFromMetadata(
controller.state,
controller.metadata,
'anonymous',
'includeInDebugSnapshot',
),
).toMatchInlineSnapshot(`Object {}`);
});
Expand Down
Loading