Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Chore/update accounts controller messenger code owner #12416

Merged
merged 4 commits into from
Nov 25, 2024
Merged
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
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ app/util/walletconnect.js @MetaMask/sdk-devs @MetaMask/mobile-platform

# Accounts Team
app/core/Encryptor/ @MetaMask/accounts-engineers
app/core/Engine/controller/AccountsController @MetaMask/accounts-engineers
app/core/Engine/controllers/accounts @MetaMask/accounts-engineers
Cal-L marked this conversation as resolved.
Show resolved Hide resolved

# Swaps Team
app/components/UI/Swaps @MetaMask/swaps-engineers @MetaMask/mobile-platform
Expand Down
21 changes: 18 additions & 3 deletions app/core/Engine/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,9 @@ import {
AccountsControllerSelectedAccountChangeEvent,
AccountsControllerAccountAddedEvent,
AccountsControllerAccountRenamedEvent,
} from './controllers/AccountsController/constants';
import { createAccountsController } from './controllers/AccountsController/utils';
} from './controllers/accounts/constants';
import { AccountsControllerMessenger } from '@metamask/accounts-controller';
import { createAccountsController } from './controllers/accounts/utils';
import { captureException } from '@sentry/react-native';
import { lowerCase } from 'lodash';
import {
Expand Down Expand Up @@ -339,8 +340,22 @@ export class Engine {
});

// Create AccountsController
const accountsControllerMessenger: AccountsControllerMessenger =
Cal-L marked this conversation as resolved.
Show resolved Hide resolved
this.controllerMessenger.getRestricted({
name: 'AccountsController',
allowedEvents: [
'SnapController:stateChange',
'KeyringController:accountRemoved',
'KeyringController:stateChange',
],
allowedActions: [
'KeyringController:getAccounts',
'KeyringController:getKeyringsByType',
'KeyringController:getKeyringForAccount',
],
});
const accountsController = createAccountsController({
messenger: this.controllerMessenger,
messenger: accountsControllerMessenger,
initialState: initialState.AccountsController,
});

Expand Down
3 changes: 3 additions & 0 deletions app/core/Engine/controllers/accounts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Controllers owned by the Accounts team

This folder contains controllers that are owned by the Accounts team.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { AccountsControllerState } from '@metamask/accounts-controller';
import {
AccountsControllerMessenger,
AccountsControllerState,
} from '@metamask/accounts-controller';
import { ExtendedControllerMessenger } from '../../../ExtendedControllerMessenger';
import {
createAccountsController,
defaultAccountsControllerState,
} from './utils';
import { ControllerMessenger } from '../../';
import { withScope } from '@sentry/react-native';
import { AGREED, METRICS_OPT_IN } from '../../../../constants/storage';
import StorageWrapper from '../../../../store/storage-wrapper';
Expand All @@ -16,7 +18,24 @@ const mockedWithScope = jest.mocked(withScope);

describe('accountControllersUtils', () => {
describe('createAccountsController', () => {
let accountsControllerMessenger: AccountsControllerMessenger;

beforeEach(() => {
const globalMessenger = new ExtendedControllerMessenger();
accountsControllerMessenger = globalMessenger.getRestricted({
name: 'AccountsController',
allowedEvents: [
'SnapController:stateChange',
'KeyringController:accountRemoved',
'KeyringController:stateChange',
],
allowedActions: [
'KeyringController:getAccounts',
'KeyringController:getKeyringsByType',
'KeyringController:getKeyringForAccount',
],
});
// Mock required for Logger
StorageWrapper.getItem = jest.fn((key: string) => {
switch (key) {
case METRICS_OPT_IN:
Expand All @@ -32,42 +51,41 @@ describe('accountControllersUtils', () => {
});

it('AccountsController state should be default state when no initial state is passed in', () => {
const controllerMessenger = new ExtendedControllerMessenger();
const accountsController = createAccountsController({
messenger: controllerMessenger,
messenger: accountsControllerMessenger,
});
expect(accountsController.state).toEqual(defaultAccountsControllerState);
});
it('AccountsController state should be initial state when initial state is passed in', () => {
const controllerMessenger = new ExtendedControllerMessenger();
const initialAccountsControllerState: AccountsControllerState = {
internalAccounts: {
accounts: {},
selectedAccount: '0x1',
},
};
const accountsController = createAccountsController({
messenger: controllerMessenger,
messenger: accountsControllerMessenger,
initialState: initialAccountsControllerState,
});
expect(accountsController.state).toEqual(initialAccountsControllerState);
});
it('AccountsController name should be AccountsController', () => {
const controllerMessenger = new ExtendedControllerMessenger();
const accountsControllerName = 'AccountsController';
const accountsController = createAccountsController({
messenger: controllerMessenger,
messenger: accountsControllerMessenger,
});
expect(accountsController.name).toEqual(accountsControllerName);
});
it('should catch error when controller fails to initialize', async () => {
const controllerMessenger =
'controllerMessenger' as unknown as ControllerMessenger;
const accountsController = await createAccountsController({
messenger: controllerMessenger,
});
it('should detect and log an error when controller fails to initialize', async () => {
const brokenAccountsControllerMessenger =
'controllerMessenger' as unknown as AccountsControllerMessenger;
await expect(() =>
createAccountsController({
messenger: brokenAccountsControllerMessenger,
}),
).toThrow();

expect(mockedWithScope).toHaveBeenCalledTimes(1);
expect(accountsController).toEqual({});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
AccountsControllerMessenger,
AccountsControllerState,
} from '@metamask/accounts-controller';
import { ControllerMessenger } from '../../types';
import Logger from '../../../../util/Logger';

// Default AccountsControllerState
Expand All @@ -25,36 +24,20 @@ export const createAccountsController = ({
messenger,
initialState,
}: {
messenger: ControllerMessenger;
messenger: AccountsControllerMessenger;
initialState?: AccountsControllerState;
}): AccountsController => {
let accountsController = {} as AccountsController;

try {
const accountsControllerMessenger: AccountsControllerMessenger =
messenger.getRestricted({
name: 'AccountsController',
allowedEvents: [
'SnapController:stateChange',
'KeyringController:accountRemoved',
'KeyringController:stateChange',
],
allowedActions: [
'KeyringController:getAccounts',
'KeyringController:getKeyringsByType',
'KeyringController:getKeyringForAccount',
],
});

accountsController = new AccountsController({
messenger: accountsControllerMessenger,
const accountsController = new AccountsController({
messenger,
state: initialState ?? defaultAccountsControllerState,
});
return accountsController;
} catch (error) {
// Report error while initializing AccountsController
// TODO: Direct to vault recovery to reset controller states
Logger.error(error as Error, 'Failed to initialize AccountsController');
}

return accountsController;
// TODO: Direct to vault recovery to reset controller states
throw error;
}
};
Loading