Skip to content
Open
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
5 changes: 5 additions & 0 deletions packages/multichain-account-service/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]

### Added

- Add `config.discovery.enabled` option for all account provider config objects ([#7447](https://github.com/MetaMask/core/pull/7447))
- Add `{EVM,SOL,BTC,TRX}_ACCOUNT_PROVIDER_DEFAULT_CONFIG` ([#7447](https://github.com/MetaMask/core/pull/7447))

## [4.0.1]

### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ describe('MultichainAccountService', () => {
);
expect(mocks.SolAccountProvider.constructor).toHaveBeenCalledWith(
messenger,
providerConfigs?.[SolAccountProvider.NAME],
providerConfigs?.[SOL_ACCOUNT_PROVIDER_NAME],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this PR, but I had to make this change to make the linter happy!

expect.any(Function), // TraceCallback
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import type {

import { AccountProviderWrapper } from './AccountProviderWrapper';
import {
BTC_ACCOUNT_PROVIDER_DEFAULT_CONFIG,
BTC_ACCOUNT_PROVIDER_NAME,
BtcAccountProvider,
} from './BtcAccountProvider';
import { SnapAccountProviderConfig } from './SnapAccountProvider';
import { TraceName } from '../constants/traces';
import {
getMultichainAccountServiceMessenger,
Expand Down Expand Up @@ -103,14 +105,17 @@ class MockBtcKeyring {
* @param options - Configuration options for setup.
* @param options.messenger - An optional messenger instance to use. Defaults to a new Messenger.
* @param options.accounts - List of accounts to use.
* @param options.config - Provider config.
* @returns An object containing the controller instance and the messenger.
*/
function setup({
messenger = getRootMessenger(),
accounts = [],
config,
}: {
messenger?: RootMessenger;
accounts?: InternalAccount[];
config?: SnapAccountProviderConfig;
} = {}): {
provider: AccountProviderWrapper;
messenger: RootMessenger;
Expand Down Expand Up @@ -153,7 +158,7 @@ function setup({
const multichainMessenger = getMultichainAccountServiceMessenger(messenger);
const provider = new AccountProviderWrapper(
multichainMessenger,
new BtcAccountProvider(multichainMessenger),
new BtcAccountProvider(multichainMessenger, config),
);

return {
Expand Down Expand Up @@ -329,6 +334,26 @@ describe('BtcAccountProvider', () => {
expect(discovered).toStrictEqual([]);
});

it('does not run discovery if disabled', async () => {
const { provider } = setup({
accounts: [MOCK_BTC_P2WPKH_ACCOUNT_1],
config: {
...BTC_ACCOUNT_PROVIDER_DEFAULT_CONFIG,
discovery: {
...BTC_ACCOUNT_PROVIDER_DEFAULT_CONFIG.discovery,
enabled: false,
},
},
});

expect(
await provider.discoverAccounts({
entropySource: MOCK_HD_KEYRING_1.metadata.id,
groupIndex: 0,
}),
).toStrictEqual([]);
});

describe('trace functionality', () => {
it('calls trace callback during account discovery', async () => {
const mockTrace = jest.fn().mockImplementation(async (request, fn) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,20 @@ import type { MultichainAccountServiceMessenger } from '../types';

export type BtcAccountProviderConfig = SnapAccountProviderConfig;

export const BTC_ACCOUNT_PROVIDER_NAME = 'Bitcoin' as const;
export const BTC_ACCOUNT_PROVIDER_NAME = 'Bitcoin';

export const BTC_ACCOUNT_PROVIDER_DEFAULT_CONFIG: BtcAccountProviderConfig = {
maxConcurrency: 3,
createAccounts: {
timeoutMs: 3000,
},
discovery: {
enabled: true,
timeoutMs: 2000,
maxAttempts: 3,
backOffMs: 1000,
},
};

export class BtcAccountProvider extends SnapAccountProvider {
static NAME = BTC_ACCOUNT_PROVIDER_NAME;
Expand All @@ -24,17 +37,7 @@ export class BtcAccountProvider extends SnapAccountProvider {

constructor(
messenger: MultichainAccountServiceMessenger,
config: BtcAccountProviderConfig = {
maxConcurrency: 3,
createAccounts: {
timeoutMs: 3000,
},
discovery: {
timeoutMs: 2000,
maxAttempts: 3,
backOffMs: 1000,
},
},
config: BtcAccountProviderConfig = BTC_ACCOUNT_PROVIDER_DEFAULT_CONFIG,
trace: TraceCallback = traceFallback,
) {
super(BtcAccountProvider.BTC_SNAP_ID, messenger, config, trace);
Expand Down Expand Up @@ -91,6 +94,10 @@ export class BtcAccountProvider extends SnapAccountProvider {
},
},
async () => {
if (!this.config.discovery.enabled) {
return [];
}

const discoveredAccounts = await withRetry(
() =>
withTimeout(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import type { Hex } from '@metamask/utils';
import { createBytes } from '@metamask/utils';

import {
EVM_ACCOUNT_PROVIDER_DEFAULT_CONFIG,
EVM_ACCOUNT_PROVIDER_NAME,
EvmAccountProvider,
EvmAccountProviderConfig,
} from './EvmAccountProvider';
import { TimeoutError } from './utils';
import { TraceName } from '../constants/traces';
Expand Down Expand Up @@ -117,18 +119,21 @@ class MockEthKeyring implements EthKeyring {
* @param options.accounts - List of accounts to use.
* @param options.discovery - Discovery options.
* @param options.discovery.transactionCount - Transaction count (use '0x0' to stop the discovery).
* @param options.config - Provider config.
* @returns An object containing the controller instance and the messenger.
*/
function setup({
messenger = getRootMessenger(),
accounts = [],
discovery,
config,
}: {
messenger?: RootMessenger;
accounts?: InternalAccount[];
discovery?: {
transactionCount: string;
};
config?: EvmAccountProviderConfig;
} = {}): {
provider: EvmAccountProvider;
messenger: RootMessenger;
Expand Down Expand Up @@ -190,6 +195,7 @@ function setup({

const provider = new EvmAccountProvider(
getMultichainAccountServiceMessenger(messenger),
config,
);

return {
Expand Down Expand Up @@ -547,6 +553,26 @@ describe('EvmAccountProvider', () => {
expect(mockTrace).toHaveBeenCalledTimes(1);
});

it('does not run discovery if disabled', async () => {
const { provider } = setup({
accounts: [MOCK_HD_ACCOUNT_1, MOCK_HD_ACCOUNT_2],
config: {
...EVM_ACCOUNT_PROVIDER_DEFAULT_CONFIG,
discovery: {
...EVM_ACCOUNT_PROVIDER_DEFAULT_CONFIG.discovery,
enabled: false,
},
},
});

expect(
await provider.discoverAccounts({
entropySource: MOCK_HD_KEYRING_1.metadata.id,
groupIndex: 0,
}),
).toStrictEqual([]);
});

it('does nothing when re-syncing accounts', async () => {
const { provider } = setup({
accounts: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ function assertInternalAccountExists(

export type EvmAccountProviderConfig = {
discovery: {
enabled?: boolean;
maxAttempts: number;
timeoutMs: number;
backOffMs: number;
Expand All @@ -50,6 +51,14 @@ export type EvmAccountProviderConfig = {

export const EVM_ACCOUNT_PROVIDER_NAME = 'EVM';

export const EVM_ACCOUNT_PROVIDER_DEFAULT_CONFIG = {
discovery: {
maxAttempts: 3,
timeoutMs: 500,
backOffMs: 500,
},
};

export class EvmAccountProvider extends BaseBip44AccountProvider {
static NAME = EVM_ACCOUNT_PROVIDER_NAME;

Expand All @@ -59,17 +68,17 @@ export class EvmAccountProvider extends BaseBip44AccountProvider {

constructor(
messenger: MultichainAccountServiceMessenger,
config: EvmAccountProviderConfig = {
discovery: {
maxAttempts: 3,
timeoutMs: 500,
backOffMs: 500,
},
},
config: EvmAccountProviderConfig = EVM_ACCOUNT_PROVIDER_DEFAULT_CONFIG,
trace?: TraceCallback,
) {
super(messenger);
this.#config = config;
this.#config = {
...config,
discovery: {
...config.discovery,
enabled: config.discovery.enabled ?? true,
},
};
this.#trace = trace ?? traceFallback;
}

Expand Down Expand Up @@ -242,6 +251,10 @@ export class EvmAccountProvider extends BaseBip44AccountProvider {
},
},
async () => {
if (!this.#config.discovery.enabled) {
return [];
}

const provider = this.getEvmProvider();
const { entropySource, groupIndex } = opts;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type RestrictedSnapKeyringCreateAccount = (
export type SnapAccountProviderConfig = {
maxConcurrency?: number;
discovery: {
enabled?: boolean;
maxAttempts: number;
timeoutMs: number;
backOffMs: number;
Expand Down Expand Up @@ -57,6 +58,10 @@ export abstract class SnapAccountProvider extends BaseBip44AccountProvider {
const maxConcurrency = config.maxConcurrency ?? Infinity;
this.config = {
...config,
discovery: {
...config.discovery,
enabled: config.discovery.enabled ?? true,
},
maxConcurrency,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import type {
} from '@metamask/keyring-internal-api';

import { AccountProviderWrapper } from './AccountProviderWrapper';
import { SnapAccountProviderConfig } from './SnapAccountProvider';
import {
SOL_ACCOUNT_PROVIDER_DEFAULT_CONFIG,
SOL_ACCOUNT_PROVIDER_NAME,
SolAccountProvider,
} from './SolAccountProvider';
Expand Down Expand Up @@ -86,14 +88,17 @@ class MockSolanaKeyring {
* @param options - Configuration options for setup.
* @param options.messenger - An optional messenger instance to use. Defaults to a new Messenger.
* @param options.accounts - List of accounts to use.
* @param options.config - Provider config.
* @returns An object containing the controller instance and the messenger.
*/
function setup({
messenger = getRootMessenger(),
accounts = [],
config,
}: {
messenger?: RootMessenger;
accounts?: InternalAccount[];
config?: SnapAccountProviderConfig;
} = {}): {
provider: AccountProviderWrapper;
messenger: RootMessenger;
Expand Down Expand Up @@ -146,7 +151,7 @@ function setup({
const multichainMessenger = getMultichainAccountServiceMessenger(messenger);
const provider = new AccountProviderWrapper(
multichainMessenger,
new SolAccountProvider(multichainMessenger, undefined, mockTrace),
new SolAccountProvider(multichainMessenger, config, mockTrace),
);

return {
Expand Down Expand Up @@ -323,6 +328,26 @@ describe('SolAccountProvider', () => {
expect(discovered).toStrictEqual([]);
});

it('does not run discovery if disabled', async () => {
const { provider } = setup({
accounts: [MOCK_SOL_ACCOUNT_1],
config: {
...SOL_ACCOUNT_PROVIDER_DEFAULT_CONFIG,
discovery: {
...SOL_ACCOUNT_PROVIDER_DEFAULT_CONFIG.discovery,
enabled: false,
},
},
});

expect(
await provider.discoverAccounts({
entropySource: MOCK_HD_KEYRING_1.metadata.id,
groupIndex: 0,
}),
).toStrictEqual([]);
});

describe('trace functionality', () => {
it('calls trace callback during account discovery', async () => {
const { messenger, mocks } = setup({
Expand Down
Loading
Loading