diff --git a/packages/multichain-account-service/src/MultichainAccountService.test.ts b/packages/multichain-account-service/src/MultichainAccountService.test.ts index 1cdac410036..ae8ede11341 100644 --- a/packages/multichain-account-service/src/MultichainAccountService.test.ts +++ b/packages/multichain-account-service/src/MultichainAccountService.test.ts @@ -3,12 +3,12 @@ import type { Messenger } from '@metamask/base-controller'; import { mnemonicPhraseToBytes } from '@metamask/key-tree'; import type { KeyringAccount } from '@metamask/keyring-api'; -import { EthAccountType, SolAccountType } from '@metamask/keyring-api'; +import { BtcAccountType, EthAccountType, SolAccountType, TrxAccountType } from '@metamask/keyring-api'; import { KeyringTypes, type KeyringObject } from '@metamask/keyring-controller'; import type { MultichainAccountServiceOptions } from './MultichainAccountService'; import { MultichainAccountService } from './MultichainAccountService'; -import type { NamedAccountProvider } from './providers'; +import { BTC_ACCOUNT_PROVIDER_NAME, BtcAccountProvider, TRX_ACCOUNT_PROVIDER_NAME, TrxAccountProvider, type NamedAccountProvider } from './providers'; import { AccountProviderWrapper } from './providers/AccountProviderWrapper'; import { EVM_ACCOUNT_PROVIDER_NAME, @@ -59,6 +59,18 @@ jest.mock('./providers/SolAccountProvider', () => { SolAccountProvider: jest.fn(), }; }); +jest.mock('./providers/BtcAccountProvider', () => { + return { + ...jest.requireActual('./providers/BtcAccountProvider'), + BtcAccountProvider: jest.fn(), + }; +}); +jest.mock('./providers/TrxAccountProvider', () => { + return { + ...jest.requireActual('./providers/TrxAccountProvider'), + TrxAccountProvider: jest.fn(), + }; +}); type Mocks = { KeyringController: { @@ -72,6 +84,8 @@ type Mocks = { }; EvmAccountProvider: MockAccountProvider; SolAccountProvider: MockAccountProvider; + BtcAccountProvider: MockAccountProvider; + TrxAccountProvider: MockAccountProvider; }; function mockAccountProvider( @@ -126,6 +140,8 @@ function setup({ }, EvmAccountProvider: makeMockAccountProvider(), SolAccountProvider: makeMockAccountProvider(), + BtcAccountProvider: makeMockAccountProvider(), + TrxAccountProvider: makeMockAccountProvider(), }; // Required for the `assert` on `MultichainAccountWallet.createMultichainAccountGroup`. @@ -165,6 +181,8 @@ function setup({ // force it here. EvmAccountProvider.NAME = EVM_ACCOUNT_PROVIDER_NAME; SolAccountProvider.NAME = SOL_ACCOUNT_PROVIDER_NAME; + BtcAccountProvider.NAME = BTC_ACCOUNT_PROVIDER_NAME; + TrxAccountProvider.NAME = TRX_ACCOUNT_PROVIDER_NAME; mockAccountProvider( EvmAccountProvider, @@ -178,6 +196,18 @@ function setup({ accounts, SolAccountType.DataAccount, ); + mockAccountProvider( + BtcAccountProvider, + mocks.BtcAccountProvider, + accounts, + BtcAccountType.P2wpkh, + ); + mockAccountProvider( + TrxAccountProvider, + mocks.TrxAccountProvider, + accounts, + TrxAccountType.Eoa, + ); } const serviceMessenger = getMultichainAccountServiceMessenger(messenger); @@ -214,6 +244,26 @@ describe('MultichainAccountService', () => { timeoutMs: 3000, }, }, + [BTC_ACCOUNT_PROVIDER_NAME]: { + discovery: { + timeoutMs: 5000, + maxAttempts: 4, + backOffMs: 2000, + }, + createAccounts: { + timeoutMs: 3000, + }, + }, + [TRX_ACCOUNT_PROVIDER_NAME]: { + discovery: { + timeoutMs: 5000, + maxAttempts: 4, + backOffMs: 2000, + }, + createAccounts: { + timeoutMs: 3000, + }, + }, }; const { mocks, serviceMessenger } = setup({ @@ -229,6 +279,14 @@ describe('MultichainAccountService', () => { serviceMessenger, providerConfigs[SolAccountProvider.NAME], ); + expect(mocks.BtcAccountProvider.constructor).toHaveBeenCalledWith( + serviceMessenger, + providerConfigs[BtcAccountProvider.NAME], + ); + expect(mocks.TrxAccountProvider.constructor).toHaveBeenCalledWith( + serviceMessenger, + providerConfigs[TrxAccountProvider.NAME], + ); }); it('allows optional configs for some providers', () => { @@ -246,6 +304,26 @@ describe('MultichainAccountService', () => { timeoutMs: 3000, }, }, + [BTC_ACCOUNT_PROVIDER_NAME]: { + discovery: { + timeoutMs: 5000, + maxAttempts: 4, + backOffMs: 2000, + }, + createAccounts: { + timeoutMs: 3000, + }, + }, + [TRX_ACCOUNT_PROVIDER_NAME]: { + discovery: { + timeoutMs: 5000, + maxAttempts: 4, + backOffMs: 2000, + }, + createAccounts: { + timeoutMs: 3000, + }, + }, // No `EVM_ACCOUNT_PROVIDER_NAME`, cause it's optional in this test. }; @@ -262,6 +340,14 @@ describe('MultichainAccountService', () => { serviceMessenger, providerConfigs[SolAccountProvider.NAME], ); + expect(mocks.BtcAccountProvider.constructor).toHaveBeenCalledWith( + serviceMessenger, + providerConfigs[BtcAccountProvider.NAME], + ); + expect(mocks.TrxAccountProvider.constructor).toHaveBeenCalledWith( + serviceMessenger, + providerConfigs[TrxAccountProvider.NAME], + ); }); }); diff --git a/packages/multichain-account-service/src/MultichainAccountService.ts b/packages/multichain-account-service/src/MultichainAccountService.ts index 776e057b139..9b8c76d74c9 100644 --- a/packages/multichain-account-service/src/MultichainAccountService.ts +++ b/packages/multichain-account-service/src/MultichainAccountService.ts @@ -15,17 +15,21 @@ import { areUint8ArraysEqual } from '@metamask/utils'; import { projectLogger as log } from './logger'; import type { MultichainAccountGroup } from './MultichainAccountGroup'; import { MultichainAccountWallet } from './MultichainAccountWallet'; -import type { - EvmAccountProviderConfig, - NamedAccountProvider, - SolAccountProviderConfig, +import { + BtcAccountProvider, + EvmAccountProvider, + SolAccountProvider, + TrxAccountProvider, + type BtcAccountProviderConfig, + type EvmAccountProviderConfig, + type NamedAccountProvider, + type SolAccountProviderConfig, + type TrxAccountProviderConfig, } from './providers'; import { AccountProviderWrapper, isAccountProviderWrapper, } from './providers/AccountProviderWrapper'; -import { EvmAccountProvider } from './providers/EvmAccountProvider'; -import { SolAccountProvider } from './providers/SolAccountProvider'; import type { MultichainAccountServiceMessenger } from './types'; export const serviceName = 'MultichainAccountService'; @@ -39,6 +43,8 @@ export type MultichainAccountServiceOptions = { providerConfigs?: { [EvmAccountProvider.NAME]?: EvmAccountProviderConfig; [SolAccountProvider.NAME]?: SolAccountProviderConfig; + [BtcAccountProvider.NAME]?: BtcAccountProviderConfig; + [TrxAccountProvider.NAME]?: TrxAccountProviderConfig }; }; @@ -103,6 +109,20 @@ export class MultichainAccountService { providerConfigs?.[SolAccountProvider.NAME], ), ), + new AccountProviderWrapper( + this.#messenger, + new BtcAccountProvider( + this.#messenger, + providerConfigs?.[BtcAccountProvider.NAME], + ), + ), + new AccountProviderWrapper( + this.#messenger, + new TrxAccountProvider( + this.#messenger, + providerConfigs?.[TrxAccountProvider.NAME], + ), + ), // Custom account providers that can be provided by the MetaMask client. ...providers, ];