Skip to content
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: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ linkStyle default opacity:0.5
multichain_account_service --> base_controller;
multichain_account_service --> keyring_controller;
multichain_account_service --> messenger;
multichain_account_service --> snap_account_service;
multichain_account_service --> controller_utils;
multichain_api_middleware --> accounts_controller;
multichain_api_middleware --> chain_agnostic_permission;
Expand Down Expand Up @@ -507,6 +508,7 @@ linkStyle default opacity:0.5
signature_controller --> logging_controller;
signature_controller --> messenger;
signature_controller --> network_controller;
snap_account_service --> keyring_controller;
snap_account_service --> messenger;
social_controllers --> base_controller;
social_controllers --> base_data_service;
Expand Down
22 changes: 16 additions & 6 deletions eslint-suppressions.json
Original file line number Diff line number Diff line change
Expand Up @@ -1299,19 +1299,14 @@
"count": 2
}
},
"packages/multichain-account-service/src/snaps/SnapPlatformWatcher.ts": {
"no-restricted-syntax": {
"count": 2
}
},
"packages/multichain-account-service/src/tests/accounts.ts": {
"@typescript-eslint/explicit-function-return-type": {
"count": 7
}
},
"packages/multichain-account-service/src/tests/messenger.ts": {
"no-restricted-syntax": {
"count": 2
"count": 1
}
},
"packages/multichain-api-middleware/src/handlers/types.ts": {
Expand Down Expand Up @@ -2172,6 +2167,21 @@
"count": 2
}
},
"packages/snap-account-service/src/SnapAccountService.test.ts": {
"no-restricted-syntax": {
"count": 2
}
},
"packages/snap-account-service/src/SnapPlatformWatcher.test.ts": {
"no-restricted-syntax": {
"count": 2
}
},
"packages/snap-account-service/src/SnapPlatformWatcher.ts": {
"no-restricted-syntax": {
"count": 2
}
},
"packages/subscription-controller/src/SubscriptionController.test.ts": {
"no-restricted-syntax": {
"count": 2
Expand Down
11 changes: 11 additions & 0 deletions packages/multichain-account-service/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- **BREAKING:** The service messenger now requires the `SnapAccountService:ensureReady` action to be declared ([#8715](https://github.com/MetaMask/core/pull/8715))
- **BREAKING:** Delegate Snap platform readiness to `@metamask/snap-account-service` ([#8715](https://github.com/MetaMask/core/pull/8715))
- Removed `MultichainAccountService.ensureCanUseSnapPlatform()` method and the corresponding `MultichainAccountService:ensureCanUseSnapPlatform` messenger action.
- Removed the `MultichainAccountServiceEnsureCanUseSnapPlatformAction` type export.
- Removed `MultichainAccountServiceOptions.ensureOnboardingComplete`. Configure it via `SnapAccountService`'s `config.snapPlatformWatcher.ensureOnboardingComplete` instead.
- Removed `MultichainAccountServiceConfig.snapPlatformWatcher` and the `SnapPlatformWatcherConfig` type export. Configure the keyring-wait timeout via `SnapAccountService`'s `config.snapPlatformWatcher.snapKeyringWaitTimeoutMs` instead.
- The service messenger no longer needs `SnapController:getState` or `SnapController:stateChange`.
- **BREAKING:** Rename `SnapAccountProvider.ensureCanUseSnapPlatform()` to `ensureReady()` ([#8715](https://github.com/MetaMask/core/pull/8715))

## [9.0.0]

### Added
Expand Down
1 change: 1 addition & 0 deletions packages/multichain-account-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"@metamask/keyring-snap-client": "^9.0.2",
"@metamask/keyring-utils": "^3.2.1",
"@metamask/messenger": "^1.2.0",
"@metamask/snap-account-service": "^0.0.0",
"@metamask/snaps-controllers": "^19.0.0",
"@metamask/snaps-sdk": "^11.0.0",
"@metamask/snaps-utils": "^12.1.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ export type MultichainAccountServiceResyncAccountsAction = {
handler: MultichainAccountService['resyncAccounts'];
};

export type MultichainAccountServiceEnsureCanUseSnapPlatformAction = {
type: `MultichainAccountService:ensureCanUseSnapPlatform`;
handler: MultichainAccountService['ensureCanUseSnapPlatform'];
};

/**
* Gets a reference to the multichain account wallet matching this entropy source.
*
Expand Down Expand Up @@ -201,7 +196,6 @@ export type MultichainAccountServiceAlignWalletAction = {
export type MultichainAccountServiceMethodActions =
| MultichainAccountServiceInitAction
| MultichainAccountServiceResyncAccountsAction
| MultichainAccountServiceEnsureCanUseSnapPlatformAction
| MultichainAccountServiceGetMultichainAccountWalletAction
| MultichainAccountServiceGetMultichainAccountWalletsAction
| MultichainAccountServiceCreateMultichainAccountWalletAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import {
TRX_ACCOUNT_PROVIDER_NAME,
TrxAccountProvider,
} from './providers/TrxAccountProvider';
import { SnapPlatformWatcher } from './snaps/SnapPlatformWatcher';
import type { RootMessenger, MockAccountProvider } from './tests';
import {
MOCK_HARDWARE_ACCOUNT_1,
Expand All @@ -53,7 +52,6 @@ import {
import {
MOCK_HD_KEYRING_1,
MOCK_HD_KEYRING_2,
MOCK_SNAP_KEYRING,
getMultichainAccountServiceMessenger,
getRootMessenger,
makeMockAccountProvider,
Expand Down Expand Up @@ -114,10 +112,6 @@ type Mocks = {
captureException: jest.Mock;
};
// eslint-disable-next-line @typescript-eslint/naming-convention
SnapController: {
getState: jest.Mock;
};
// eslint-disable-next-line @typescript-eslint/naming-convention
EvmAccountProvider: MockAccountProvider;
// eslint-disable-next-line @typescript-eslint/naming-convention
SolAccountProvider: MockAccountProvider;
Expand All @@ -127,13 +121,6 @@ type Mocks = {
TrxAccountProvider: MockAccountProvider;
};

type Spies = {
// eslint-disable-next-line @typescript-eslint/naming-convention
SnapPlatformWatcher: {
ensureCanUseSnapPlatform: jest.SpyInstance;
};
};

function mockAccountProvider<Provider extends Bip44AccountProvider>(
providerClass: new (messenger: MultichainAccountServiceMessenger) => Provider,
mocks: MockAccountProvider,
Expand Down Expand Up @@ -193,7 +180,6 @@ async function setup({
rootMessenger: RootMessenger;
messenger: MultichainAccountServiceMessenger;
mocks: Mocks;
spies: Spies;
}> {
const mocks: Mocks = {
KeyringController: {
Expand All @@ -212,36 +198,15 @@ async function setup({
ErrorReportingService: {
captureException: jest.fn(),
},
SnapController: {
getState: jest.fn(),
},
EvmAccountProvider: makeMockAccountProvider(),
SolAccountProvider: makeMockAccountProvider(),
BtcAccountProvider: makeMockAccountProvider(),
TrxAccountProvider: makeMockAccountProvider(),
};

const spies: Spies = {
SnapPlatformWatcher: {
ensureCanUseSnapPlatform: jest.spyOn(
SnapPlatformWatcher.prototype,
'ensureCanUseSnapPlatform',
),
},
};

// Required for the `assert` on `MultichainAccountWallet.createMultichainAccountGroup`.
Object.setPrototypeOf(mocks.EvmAccountProvider, EvmAccountProvider.prototype);

mocks.SnapController.getState.mockImplementation(() => ({
isReady: true,
}));

rootMessenger.registerActionHandler(
'SnapController:getState',
mocks.SnapController.getState,
);

mocks.KeyringController.getState.mockImplementation(() => ({
isUnlocked: true,
keyrings: mocks.KeyringController.keyrings,
Expand Down Expand Up @@ -339,7 +304,6 @@ async function setup({
rootMessenger,
messenger,
mocks,
spies,
};
}

Expand Down Expand Up @@ -1223,20 +1187,6 @@ describe('MultichainAccountService', () => {
MOCK_HD_ACCOUNT_1.address,
);
});

it('checks for Snap platform readiness with MultichainAccountService:ensureCanUseSnapPlatform', async () => {
const { rootMessenger, spies } = await setup({
accounts: [],
keyrings: [MOCK_HD_KEYRING_1, MOCK_HD_KEYRING_2, MOCK_SNAP_KEYRING],
});

await rootMessenger.call(
'MultichainAccountService:ensureCanUseSnapPlatform',
);
expect(
spies.SnapPlatformWatcher.ensureCanUseSnapPlatform,
).toHaveBeenCalled();
});
});

describe('resyncAccounts', () => {
Expand Down Expand Up @@ -1608,19 +1558,4 @@ describe('MultichainAccountService', () => {
});
});
});

describe('ensureCanUseSnapPlatform', () => {
it('delegates Snap platform readiness check to SnapPlatformWatcher (method)', async () => {
const { service, spies } = await setup({
accounts: [],
keyrings: [MOCK_HD_KEYRING_1, MOCK_HD_KEYRING_2, MOCK_SNAP_KEYRING],
});

await service.ensureCanUseSnapPlatform();

expect(
spies.SnapPlatformWatcher.ensureCanUseSnapPlatform,
).toHaveBeenCalledTimes(1);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ import {
SOL_ACCOUNT_PROVIDER_NAME,
SolAccountProviderConfig,
} from './providers/SolAccountProvider';
import { SnapPlatformWatcher } from './snaps/SnapPlatformWatcher';
import type {
MultichainAccountServiceConfig,
MultichainAccountServiceMessenger,
Expand All @@ -61,10 +60,6 @@ export type MultichainAccountServiceOptions = {
[TRX_ACCOUNT_PROVIDER_NAME]?: TrxAccountProviderConfig;
};
config?: MultichainAccountServiceConfig;
/**
* When provided, used to prevent using Snap platform before onboarding completion.
*/
ensureOnboardingComplete?: () => Promise<void>;
};

/**
Expand Down Expand Up @@ -116,7 +111,6 @@ const MESSENGER_EXPOSED_METHODS = [
'createMultichainAccountWallet',
'resyncAccounts',
'removeMultichainAccountWallet',
'ensureCanUseSnapPlatform',
'init',
] as const;

Expand All @@ -126,8 +120,6 @@ const MESSENGER_EXPOSED_METHODS = [
export class MultichainAccountService {
readonly #messenger: MultichainAccountServiceMessenger;

readonly #watcher: SnapPlatformWatcher;

readonly #providers: Bip44AccountProvider[];

readonly #trace: TraceCallback;
Expand All @@ -151,15 +143,12 @@ export class MultichainAccountService {
* @param options.providers - Optional list of account
* @param options.providerConfigs - Optional provider configs
* @param options.config - Optional config.
* @param options.ensureOnboardingComplete - Optional callback to ensure
* onboarding is completed before using the Snap platform.
*/
constructor({
messenger,
providers = [],
providerConfigs,
config,
ensureOnboardingComplete,
}: MultichainAccountServiceOptions) {
this.#messenger = messenger;
this.#wallets = new Map();
Expand Down Expand Up @@ -211,11 +200,6 @@ export class MultichainAccountService {
...providers,
];

this.#watcher = new SnapPlatformWatcher(messenger, {
ensureOnboardingComplete,
snapKeyringWaitTimeoutMs: config?.snapPlatformWatcher?.timeoutMs,
});

this.#messenger.registerMethodActionHandlers(
this,
MESSENGER_EXPOSED_METHODS,
Expand Down Expand Up @@ -349,10 +333,6 @@ export class MultichainAccountService {
log('Providers got re-synced!');
}

ensureCanUseSnapPlatform(): Promise<void> {
return this.#watcher.ensureCanUseSnapPlatform();
}

/**
* Get the wallet matching the given entropy source.
*
Expand Down
1 change: 0 additions & 1 deletion packages/multichain-account-service/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export type {
} from './types';
export type {
MultichainAccountServiceResyncAccountsAction,
MultichainAccountServiceEnsureCanUseSnapPlatformAction,
MultichainAccountServiceGetMultichainAccountWalletAction,
MultichainAccountServiceGetMultichainAccountWalletsAction,
MultichainAccountServiceCreateMultichainAccountWalletAction,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class MockBtcKeyring {
}

class MockBtcAccountProvider extends BtcAccountProvider {
override async ensureCanUseSnapPlatform(): Promise<void> {
override async ensureReady(): Promise<void> {
// Override to avoid waiting during tests.
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ const setup = ({
},
handleRequest: jest.fn(),
},
MultichainAccountService: {
ensureCanUseSnapPlatform: jest.fn(),
SnapAccountService: {
ensureReady: jest.fn(),
},
};

Expand All @@ -185,13 +185,11 @@ const setup = ({
mocks.AccountsController.listMultichainAccounts.mockReturnValue(accounts);

messenger.registerActionHandler(
'MultichainAccountService:ensureCanUseSnapPlatform',
mocks.MultichainAccountService.ensureCanUseSnapPlatform,
'SnapAccountService:ensureReady',
mocks.SnapAccountService.ensureReady,
);
// Make the platform ready right away (having a resolved promise is enough).
mocks.MultichainAccountService.ensureCanUseSnapPlatform.mockResolvedValue(
undefined,
);
mocks.SnapAccountService.ensureReady.mockResolvedValue(undefined);

messenger.registerActionHandler(
'SnapController:handleRequest',
Expand Down Expand Up @@ -239,10 +237,7 @@ const setup = ({
),
);

const serviceMessenger = getMultichainAccountServiceMessenger(messenger, {
// We need this extra action to be able to mock it.
actions: ['MultichainAccountService:ensureCanUseSnapPlatform'],
});
const serviceMessenger = getMultichainAccountServiceMessenger(messenger);
const config = deepmerge(
DEFAULT_TEST_CONFIG,
configOverride as SnapAccountProviderConfig,
Expand Down Expand Up @@ -954,15 +949,13 @@ describe('SnapAccountProvider', () => {
});
});

describe('ensureCanUseSnapPlatform', () => {
it('delegates Snap platform readiness check to SnapPlatformWatcher', async () => {
describe('ensureReady', () => {
it('delegates Snap platform readiness check to SnapAccountService:ensureReady', async () => {
const { provider, mocks } = setup();

await provider.ensureCanUseSnapPlatform();
await provider.ensureReady();

expect(
mocks.MultichainAccountService.ensureCanUseSnapPlatform,
).toHaveBeenCalledTimes(1);
expect(mocks.SnapAccountService.ensureReady).toHaveBeenCalledTimes(1);
});
});
});
Loading
Loading