@metamask-previews/multichain-account-service 4.0.0-preview-267e79c3 → 4.0.1-preview-d717276a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [4.0.1]
11
+
10
12
  ### Changed
11
13
 
12
14
  - Move peer dependencies for controller and service packages to direct dependencies ([#7209](https://github.com/MetaMask/core/pull/7209))
@@ -19,6 +21,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
19
21
  - For example, this scenario would be valid: a client relies on `@metamask/controller-a` 1.0.0 and `@metamask/controller-b` 1.0.0, and `@metamask/controller-b` depends on `@metamask/controller-a` 1.1.0.
20
22
  - Note, however, that the versions specified in the client's `package.json` always "win", and you are expected to keep them up to date so as not to break controller and service intercommunication.
21
23
 
24
+ ### Fixed
25
+
26
+ - Harden EVM discovery in case of bad RPC response ([#7434](https://github.com/MetaMask/core/pull/7434))
27
+ - If the response was not hex-formatted, then the EVM discovery was continuously running.
28
+
22
29
  ## [4.0.0]
23
30
 
24
31
  ### Changed
@@ -294,7 +301,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
294
301
  - Add `MultichainAccountService` ([#6141](https://github.com/MetaMask/core/pull/6141)), ([#6165](https://github.com/MetaMask/core/pull/6165))
295
302
  - This service manages multichain accounts/wallets.
296
303
 
297
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@4.0.0...HEAD
304
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@4.0.1...HEAD
305
+ [4.0.1]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@4.0.0...@metamask/multichain-account-service@4.0.1
298
306
  [4.0.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@3.0.0...@metamask/multichain-account-service@4.0.0
299
307
  [3.0.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@2.1.0...@metamask/multichain-account-service@3.0.0
300
308
  [2.1.0]: https://github.com/MetaMask/core/compare/@metamask/multichain-account-service@2.0.1...@metamask/multichain-account-service@2.1.0
@@ -20,9 +20,11 @@ const utils_1 = require("@metamask/utils");
20
20
  const analytics_1 = require("./analytics/index.cjs");
21
21
  const logger_1 = require("./logger.cjs");
22
22
  const MultichainAccountWallet_1 = require("./MultichainAccountWallet.cjs");
23
+ const providers_1 = require("./providers/index.cjs");
23
24
  const AccountProviderWrapper_1 = require("./providers/AccountProviderWrapper.cjs");
24
25
  const EvmAccountProvider_1 = require("./providers/EvmAccountProvider.cjs");
25
26
  const SolAccountProvider_1 = require("./providers/SolAccountProvider.cjs");
27
+ const SolAccountProvider_2 = require("./providers/SolAccountProvider.cjs");
26
28
  const utils_2 = require("./utils.cjs");
27
29
  exports.serviceName = 'MultichainAccountService';
28
30
  /**
@@ -57,8 +59,8 @@ class MultichainAccountService {
57
59
  const traceCallback = config?.trace ?? analytics_1.traceFallback;
58
60
  // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.
59
61
  __classPrivateFieldSet(this, _MultichainAccountService_providers, [
60
- new EvmAccountProvider_1.EvmAccountProvider(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), providerConfigs?.[EvmAccountProvider_1.EvmAccountProvider.NAME], traceCallback),
61
- new AccountProviderWrapper_1.AccountProviderWrapper(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), new SolAccountProvider_1.SolAccountProvider(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), providerConfigs?.[SolAccountProvider_1.SolAccountProvider.NAME], traceCallback)),
62
+ new EvmAccountProvider_1.EvmAccountProvider(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), providerConfigs?.[providers_1.EVM_ACCOUNT_PROVIDER_NAME], traceCallback),
63
+ new AccountProviderWrapper_1.AccountProviderWrapper(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), new SolAccountProvider_1.SolAccountProvider(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), providerConfigs?.[SolAccountProvider_2.SOL_ACCOUNT_PROVIDER_NAME], traceCallback)),
62
64
  // Custom account providers that can be provided by the MetaMask client.
63
65
  ...providers,
64
66
  ], "f");
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountService.cjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isBip44Account,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport type {\n MultichainAccountWalletId,\n Bip44Account,\n} from '@metamask/account-api';\nimport type { HdKeyring } from '@metamask/eth-hd-keyring';\nimport { mnemonicPhraseToBytes } from '@metamask/key-tree';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport { areUint8ArraysEqual } from '@metamask/utils';\n\nimport { traceFallback } from './analytics';\nimport { projectLogger as log } from './logger';\nimport type { MultichainAccountGroup } from './MultichainAccountGroup';\nimport { MultichainAccountWallet } from './MultichainAccountWallet';\nimport type {\n EvmAccountProviderConfig,\n Bip44AccountProvider,\n} from './providers';\nimport {\n AccountProviderWrapper,\n isAccountProviderWrapper,\n} from './providers/AccountProviderWrapper';\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { SolAccountProviderConfig } from './providers/SolAccountProvider';\nimport type {\n MultichainAccountServiceConfig,\n MultichainAccountServiceMessenger,\n} from './types';\nimport { createSentryError } from './utils';\n\nexport const serviceName = 'MultichainAccountService';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\nexport type MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n providers?: Bip44AccountProvider[];\n providerConfigs?: {\n [EvmAccountProvider.NAME]?: EvmAccountProviderConfig;\n [SolAccountProvider.NAME]?: SolAccountProviderConfig;\n };\n config?: MultichainAccountServiceConfig;\n};\n\n/** Reverse mapping object used to map account IDs and their wallet/multichain account. */\ntype AccountContext<Account extends Bip44Account<KeyringAccount>> = {\n wallet: MultichainAccountWallet<Account>;\n group: MultichainAccountGroup<Account>;\n};\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService {\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #providers: Bip44AccountProvider[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<Bip44Account<KeyringAccount>>\n >;\n\n readonly #accountIdToContext: Map<\n Bip44Account<KeyringAccount>['id'],\n AccountContext<Bip44Account<KeyringAccount>>\n >;\n\n /**\n * The name of the service.\n */\n name: typeof serviceName = serviceName;\n\n /**\n * Constructs a new MultichainAccountService.\n *\n * @param options - The options.\n * @param options.messenger - The messenger suited to this\n * MultichainAccountService.\n * @param options.providers - Optional list of account\n * @param options.providerConfigs - Optional provider configs\n * @param options.config - Optional config.\n */\n constructor({\n messenger,\n providers = [],\n providerConfigs,\n config,\n }: MultichainAccountServiceOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\n this.#accountIdToContext = new Map();\n\n // Pass trace callback directly to preserve original 'this' context\n // This avoids binding the callback to the MultichainAccountService instance\n const traceCallback = config?.trace ?? traceFallback;\n\n // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n this.#providers = [\n new EvmAccountProvider(\n this.#messenger,\n providerConfigs?.[EvmAccountProvider.NAME],\n traceCallback,\n ),\n new AccountProviderWrapper(\n this.#messenger,\n new SolAccountProvider(\n this.#messenger,\n providerConfigs?.[SolAccountProvider.NAME],\n traceCallback,\n ),\n ),\n // Custom account providers that can be provided by the MetaMask client.\n ...providers,\n ];\n\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroup',\n (...args) => this.getMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroups',\n (...args) => this.getMultichainAccountGroups(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallet',\n (...args) => this.getMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallets',\n (...args) => this.getMultichainAccountWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createNextMultichainAccountGroup',\n (...args) => this.createNextMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountGroup',\n (...args) => this.createMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:setBasicFunctionality',\n (...args) => this.setBasicFunctionality(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallets',\n (...args) => this.alignWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallet',\n (...args) => this.alignWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountWallet',\n (...args) => this.createMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:resyncAccounts',\n (...args) => this.resyncAccounts(...args),\n );\n\n this.#messenger.subscribe('AccountsController:accountAdded', (account) =>\n this.#handleOnAccountAdded(account),\n );\n this.#messenger.subscribe('AccountsController:accountRemoved', (id) =>\n this.#handleOnAccountRemoved(id),\n );\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n async init(): Promise<void> {\n log('Initializing...');\n\n this.#wallets.clear();\n this.#accountIdToContext.clear();\n\n // Create initial wallets.\n const { keyrings } = this.#messenger.call('KeyringController:getState');\n for (const keyring of keyrings) {\n if (keyring.type === (KeyringTypes.hd as string)) {\n // Only HD keyrings have an entropy source/SRP.\n const entropySource = keyring.metadata.id;\n\n log(`Adding new wallet for entropy: \"${entropySource}\"`);\n\n // This will automatically \"associate\" all multichain accounts for that wallet\n // (based on the accounts owned by each account providers).\n const wallet = new MultichainAccountWallet({\n entropySource,\n providers: this.#providers,\n messenger: this.#messenger,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // Reverse mapping between account ID and their multichain wallet/account:\n for (const group of wallet.getMultichainAccountGroups()) {\n for (const account of group.getAccounts()) {\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n }\n }\n\n log('Initialized');\n }\n\n /**\n * Re-synchronize MetaMask accounts and the providers accounts if needed.\n *\n * NOTE: This is mostly required if one of the providers (keyrings or Snaps)\n * have different sets of accounts. This method would ensure that both are\n * in-sync and use the same accounts (and same IDs).\n *\n * READ THIS CAREFULLY (State inconsistency bugs/de-sync)\n * We've seen some problems were keyring accounts on some Snaps were not synchronized\n * with the accounts on MM side. This causes problems where we cannot interact with\n * those accounts because the Snap does know about them.\n * To \"workaround\" this de-sync problem for now, we make sure that both parties are\n * in-sync when the service boots up.\n * ----------------------------------------------------------------------------------\n */\n async resyncAccounts(): Promise<void> {\n log('Re-sync provider accounts if needed...');\n const accounts = this.#messenger\n .call('AccountsController:listMultichainAccounts')\n .filter(isBip44Account);\n // We use `Promise.all` + `try-catch` combo, since we don't wanna block the wallet\n // from being used even if some accounts are not sync (best-effort).\n await Promise.all(\n this.#providers.map(async (provider) => {\n try {\n await provider.resyncAccounts(accounts);\n } catch (error) {\n const errorMessage = `Unable to re-sync provider \"${provider.getName()}\"`;\n log(errorMessage);\n console.error(errorMessage);\n\n const sentryError = createSentryError(errorMessage, error as Error, {\n provider: provider.getName(),\n });\n this.#messenger.call(\n 'ErrorReportingService:captureException',\n sentryError,\n );\n }\n }),\n );\n log('Providers got re-synced!');\n }\n\n #handleOnAccountAdded(account: KeyringAccount): void {\n // We completely omit non-BIP-44 accounts!\n if (!isBip44Account(account)) {\n return;\n }\n\n let sync = true;\n\n let wallet = this.#wallets.get(\n toMultichainAccountWalletId(account.options.entropy.id),\n );\n if (!wallet) {\n log(\n `Adding new wallet for entropy: \"${account.options.entropy.id}\" (for account: \"${account.id}\")`,\n );\n\n // That's a new wallet.\n wallet = new MultichainAccountWallet({\n entropySource: account.options.entropy.id,\n providers: this.#providers,\n messenger: this.#messenger,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // If that's a new wallet wallet. There's nothing to \"force-sync\".\n sync = false;\n }\n\n let group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n if (!group) {\n // This new account is a new multichain account, let the wallet know\n // it has to re-sync with its providers.\n if (sync) {\n wallet.sync();\n }\n\n group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n\n // If that's a new multichain account. There's nothing to \"force-sync\".\n sync = false;\n }\n\n // We have to check against `undefined` in case `getMultichainAccount` is\n // not able to find this multichain account (which should not be possible...)\n if (group) {\n if (sync) {\n group.sync();\n }\n\n // Same here, this account should have been already grouped in that\n // multichain account.\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n\n #handleOnAccountRemoved(id: KeyringAccount['id']): void {\n // Force sync of the appropriate wallet if an account got removed.\n const found = this.#accountIdToContext.get(id);\n if (found) {\n const { wallet } = found;\n\n log(\n `Re-synchronize wallet [${wallet.id}] since account \"${id}\" got removed`,\n );\n wallet.sync();\n }\n\n // Safe to call delete even if the `id` was not referencing a BIP-44 account.\n this.#accountIdToContext.delete(id);\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(entropySource),\n );\n\n if (!wallet) {\n throw new Error('Unknown wallet, no wallet matching this entropy source');\n }\n\n return wallet;\n }\n\n /**\n * Gets the account's context which contains its multichain wallet and\n * multichain account group references.\n *\n * @param id - Account ID.\n * @returns The account context if any, undefined otherwise.\n */\n getAccountContext(\n id: KeyringAccount['id'],\n ): AccountContext<Bip44Account<KeyringAccount>> | undefined {\n return this.#accountIdToContext.get(id);\n }\n\n /**\n * Gets a reference to the multichain account wallet matching this entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @throws If none multichain account match this entropy.\n * @returns A reference to the multichain account wallet.\n */\n getMultichainAccountWallet({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n return this.#getWallet(entropySource);\n }\n\n /**\n * Gets an array of all multichain account wallets.\n *\n * @returns An array of all multichain account wallets.\n */\n getMultichainAccountWallets(): MultichainAccountWallet<\n Bip44Account<KeyringAccount>\n >[] {\n return Array.from(this.#wallets.values());\n }\n\n /**\n * Creates a new multichain account wallet with the given mnemonic.\n *\n * NOTE: This method should only be called in client code where a mutex lock is acquired.\n * `discoverAndCreateAccounts` should be called after this method to discover and create accounts.\n *\n * @param options - Options.\n * @param options.mnemonic - The mnemonic to use to create the new wallet.\n * @throws If the mnemonic has already been imported.\n * @returns The new multichain account wallet.\n */\n async createMultichainAccountWallet({\n mnemonic,\n }: {\n mnemonic: string;\n }): Promise<MultichainAccountWallet<Bip44Account<KeyringAccount>>> {\n const existingKeyrings = this.#messenger.call(\n 'KeyringController:getKeyringsByType',\n KeyringTypes.hd,\n ) as HdKeyring[];\n\n const mnemonicAsBytes = mnemonicPhraseToBytes(mnemonic);\n\n const alreadyHasImportedSrp = existingKeyrings.some((keyring) => {\n if (!keyring.mnemonic) {\n return false;\n }\n return areUint8ArraysEqual(keyring.mnemonic, mnemonicAsBytes);\n });\n\n if (alreadyHasImportedSrp) {\n throw new Error('This Secret Recovery Phrase has already been imported.');\n }\n\n log(`Creating new wallet...`);\n\n const result = await this.#messenger.call(\n 'KeyringController:addNewKeyring',\n KeyringTypes.hd,\n { mnemonic },\n );\n\n const wallet = new MultichainAccountWallet({\n providers: this.#providers,\n entropySource: result.id,\n messenger: this.#messenger,\n });\n\n this.#wallets.set(wallet.id, wallet);\n\n log(`Wallet created: [${wallet.id}]`);\n\n return wallet;\n }\n\n /**\n * Gets a reference to the multichain account group matching this entropy source\n * and a group index.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @param options.groupIndex - The group index of the multichain account.\n * @throws If none multichain account match this entropy source and group index.\n * @returns A reference to the multichain account.\n */\n getMultichainAccountGroup({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccountGroup(groupIndex);\n\n if (!multichainAccount) {\n throw new Error(`No multichain account for index: ${groupIndex}`);\n }\n\n return multichainAccount;\n }\n\n /**\n * Gets all multichain account groups for a given entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source to query.\n * @throws If no multichain accounts match this entropy source.\n * @returns A list of all multichain accounts.\n */\n getMultichainAccountGroups({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>>[] {\n return this.#getWallet(entropySource).getMultichainAccountGroups();\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @param options - Options.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The next multichain account group.\n */\n async createNextMultichainAccountGroup({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(\n entropySource,\n ).createNextMultichainAccountGroup();\n }\n\n /**\n * Creates a multichain account group.\n *\n * @param options - Options.\n * @param options.groupIndex - The group index to use.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup({\n groupIndex,\n entropySource,\n }: {\n groupIndex: number;\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(entropySource).createMultichainAccountGroup(\n groupIndex,\n );\n }\n\n /**\n * Set basic functionality state and trigger alignment if enabled.\n * When basic functionality is disabled, snap-based providers are disabled.\n * When enabled, all snap providers are enabled and wallet alignment is triggered.\n * EVM providers are never disabled as they're required for basic wallet functionality.\n *\n * @param enabled - Whether basic functionality is enabled.\n */\n async setBasicFunctionality(enabled: boolean): Promise<void> {\n log(`Turning basic functionality: ${enabled ? 'ON' : 'OFF'}`);\n\n // Loop through providers and enable/disable only wrapped ones when basic functionality changes\n for (const provider of this.#providers) {\n if (isAccountProviderWrapper(provider)) {\n log(\n `${enabled ? 'Enabling' : 'Disabling'} account provider: \"${provider.getName()}\"`,\n );\n provider.setEnabled(enabled);\n }\n // Regular providers (like EVM) are never disabled for basic functionality\n }\n\n // Trigger alignment only when basic functionality is enabled\n if (enabled) {\n await this.alignWallets();\n }\n }\n\n /**\n * Align all multichain account wallets.\n */\n async alignWallets(): Promise<void> {\n log(`Triggering alignment on all wallets...`);\n\n const wallets = this.getMultichainAccountWallets();\n await Promise.all(wallets.map((w) => w.alignAccounts()));\n\n log(`Wallets aligned`);\n }\n\n /**\n * Align a specific multichain account wallet.\n *\n * @param entropySource - The entropy source of the multichain account wallet.\n */\n async alignWallet(entropySource: EntropySourceId): Promise<void> {\n const wallet = this.getMultichainAccountWallet({ entropySource });\n\n log(`Triggering alignment for wallet: [${wallet.id}]`);\n await wallet.alignAccounts();\n log(`Wallet [${wallet.id}] aligned`);\n }\n}\n"]}
1
+ {"version":3,"file":"MultichainAccountService.cjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isBip44Account,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport type {\n MultichainAccountWalletId,\n Bip44Account,\n} from '@metamask/account-api';\nimport type { HdKeyring } from '@metamask/eth-hd-keyring';\nimport { mnemonicPhraseToBytes } from '@metamask/key-tree';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport { areUint8ArraysEqual } from '@metamask/utils';\n\nimport { traceFallback } from './analytics';\nimport { projectLogger as log } from './logger';\nimport type { MultichainAccountGroup } from './MultichainAccountGroup';\nimport { MultichainAccountWallet } from './MultichainAccountWallet';\nimport {\n EvmAccountProviderConfig,\n Bip44AccountProvider,\n EVM_ACCOUNT_PROVIDER_NAME,\n} from './providers';\nimport {\n AccountProviderWrapper,\n isAccountProviderWrapper,\n} from './providers/AccountProviderWrapper';\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport {\n SOL_ACCOUNT_PROVIDER_NAME,\n SolAccountProviderConfig,\n} from './providers/SolAccountProvider';\nimport type {\n MultichainAccountServiceConfig,\n MultichainAccountServiceMessenger,\n} from './types';\nimport { createSentryError } from './utils';\n\nexport const serviceName = 'MultichainAccountService';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\nexport type MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n providers?: Bip44AccountProvider[];\n providerConfigs?: {\n [EVM_ACCOUNT_PROVIDER_NAME]?: EvmAccountProviderConfig;\n [SOL_ACCOUNT_PROVIDER_NAME]?: SolAccountProviderConfig;\n };\n config?: MultichainAccountServiceConfig;\n};\n\n/** Reverse mapping object used to map account IDs and their wallet/multichain account. */\ntype AccountContext<Account extends Bip44Account<KeyringAccount>> = {\n wallet: MultichainAccountWallet<Account>;\n group: MultichainAccountGroup<Account>;\n};\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService {\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #providers: Bip44AccountProvider[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<Bip44Account<KeyringAccount>>\n >;\n\n readonly #accountIdToContext: Map<\n Bip44Account<KeyringAccount>['id'],\n AccountContext<Bip44Account<KeyringAccount>>\n >;\n\n /**\n * The name of the service.\n */\n name: typeof serviceName = serviceName;\n\n /**\n * Constructs a new MultichainAccountService.\n *\n * @param options - The options.\n * @param options.messenger - The messenger suited to this\n * MultichainAccountService.\n * @param options.providers - Optional list of account\n * @param options.providerConfigs - Optional provider configs\n * @param options.config - Optional config.\n */\n constructor({\n messenger,\n providers = [],\n providerConfigs,\n config,\n }: MultichainAccountServiceOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\n this.#accountIdToContext = new Map();\n\n // Pass trace callback directly to preserve original 'this' context\n // This avoids binding the callback to the MultichainAccountService instance\n const traceCallback = config?.trace ?? traceFallback;\n\n // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n this.#providers = [\n new EvmAccountProvider(\n this.#messenger,\n providerConfigs?.[EVM_ACCOUNT_PROVIDER_NAME],\n traceCallback,\n ),\n new AccountProviderWrapper(\n this.#messenger,\n new SolAccountProvider(\n this.#messenger,\n providerConfigs?.[SOL_ACCOUNT_PROVIDER_NAME],\n traceCallback,\n ),\n ),\n // Custom account providers that can be provided by the MetaMask client.\n ...providers,\n ];\n\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroup',\n (...args) => this.getMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroups',\n (...args) => this.getMultichainAccountGroups(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallet',\n (...args) => this.getMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallets',\n (...args) => this.getMultichainAccountWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createNextMultichainAccountGroup',\n (...args) => this.createNextMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountGroup',\n (...args) => this.createMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:setBasicFunctionality',\n (...args) => this.setBasicFunctionality(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallets',\n (...args) => this.alignWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallet',\n (...args) => this.alignWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountWallet',\n (...args) => this.createMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:resyncAccounts',\n (...args) => this.resyncAccounts(...args),\n );\n\n this.#messenger.subscribe('AccountsController:accountAdded', (account) =>\n this.#handleOnAccountAdded(account),\n );\n this.#messenger.subscribe('AccountsController:accountRemoved', (id) =>\n this.#handleOnAccountRemoved(id),\n );\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n async init(): Promise<void> {\n log('Initializing...');\n\n this.#wallets.clear();\n this.#accountIdToContext.clear();\n\n // Create initial wallets.\n const { keyrings } = this.#messenger.call('KeyringController:getState');\n for (const keyring of keyrings) {\n if (keyring.type === (KeyringTypes.hd as string)) {\n // Only HD keyrings have an entropy source/SRP.\n const entropySource = keyring.metadata.id;\n\n log(`Adding new wallet for entropy: \"${entropySource}\"`);\n\n // This will automatically \"associate\" all multichain accounts for that wallet\n // (based on the accounts owned by each account providers).\n const wallet = new MultichainAccountWallet({\n entropySource,\n providers: this.#providers,\n messenger: this.#messenger,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // Reverse mapping between account ID and their multichain wallet/account:\n for (const group of wallet.getMultichainAccountGroups()) {\n for (const account of group.getAccounts()) {\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n }\n }\n\n log('Initialized');\n }\n\n /**\n * Re-synchronize MetaMask accounts and the providers accounts if needed.\n *\n * NOTE: This is mostly required if one of the providers (keyrings or Snaps)\n * have different sets of accounts. This method would ensure that both are\n * in-sync and use the same accounts (and same IDs).\n *\n * READ THIS CAREFULLY (State inconsistency bugs/de-sync)\n * We've seen some problems were keyring accounts on some Snaps were not synchronized\n * with the accounts on MM side. This causes problems where we cannot interact with\n * those accounts because the Snap does know about them.\n * To \"workaround\" this de-sync problem for now, we make sure that both parties are\n * in-sync when the service boots up.\n * ----------------------------------------------------------------------------------\n */\n async resyncAccounts(): Promise<void> {\n log('Re-sync provider accounts if needed...');\n const accounts = this.#messenger\n .call('AccountsController:listMultichainAccounts')\n .filter(isBip44Account);\n // We use `Promise.all` + `try-catch` combo, since we don't wanna block the wallet\n // from being used even if some accounts are not sync (best-effort).\n await Promise.all(\n this.#providers.map(async (provider) => {\n try {\n await provider.resyncAccounts(accounts);\n } catch (error) {\n const errorMessage = `Unable to re-sync provider \"${provider.getName()}\"`;\n log(errorMessage);\n console.error(errorMessage);\n\n const sentryError = createSentryError(errorMessage, error as Error, {\n provider: provider.getName(),\n });\n this.#messenger.call(\n 'ErrorReportingService:captureException',\n sentryError,\n );\n }\n }),\n );\n log('Providers got re-synced!');\n }\n\n #handleOnAccountAdded(account: KeyringAccount): void {\n // We completely omit non-BIP-44 accounts!\n if (!isBip44Account(account)) {\n return;\n }\n\n let sync = true;\n\n let wallet = this.#wallets.get(\n toMultichainAccountWalletId(account.options.entropy.id),\n );\n if (!wallet) {\n log(\n `Adding new wallet for entropy: \"${account.options.entropy.id}\" (for account: \"${account.id}\")`,\n );\n\n // That's a new wallet.\n wallet = new MultichainAccountWallet({\n entropySource: account.options.entropy.id,\n providers: this.#providers,\n messenger: this.#messenger,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // If that's a new wallet wallet. There's nothing to \"force-sync\".\n sync = false;\n }\n\n let group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n if (!group) {\n // This new account is a new multichain account, let the wallet know\n // it has to re-sync with its providers.\n if (sync) {\n wallet.sync();\n }\n\n group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n\n // If that's a new multichain account. There's nothing to \"force-sync\".\n sync = false;\n }\n\n // We have to check against `undefined` in case `getMultichainAccount` is\n // not able to find this multichain account (which should not be possible...)\n if (group) {\n if (sync) {\n group.sync();\n }\n\n // Same here, this account should have been already grouped in that\n // multichain account.\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n\n #handleOnAccountRemoved(id: KeyringAccount['id']): void {\n // Force sync of the appropriate wallet if an account got removed.\n const found = this.#accountIdToContext.get(id);\n if (found) {\n const { wallet } = found;\n\n log(\n `Re-synchronize wallet [${wallet.id}] since account \"${id}\" got removed`,\n );\n wallet.sync();\n }\n\n // Safe to call delete even if the `id` was not referencing a BIP-44 account.\n this.#accountIdToContext.delete(id);\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(entropySource),\n );\n\n if (!wallet) {\n throw new Error('Unknown wallet, no wallet matching this entropy source');\n }\n\n return wallet;\n }\n\n /**\n * Gets the account's context which contains its multichain wallet and\n * multichain account group references.\n *\n * @param id - Account ID.\n * @returns The account context if any, undefined otherwise.\n */\n getAccountContext(\n id: KeyringAccount['id'],\n ): AccountContext<Bip44Account<KeyringAccount>> | undefined {\n return this.#accountIdToContext.get(id);\n }\n\n /**\n * Gets a reference to the multichain account wallet matching this entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @throws If none multichain account match this entropy.\n * @returns A reference to the multichain account wallet.\n */\n getMultichainAccountWallet({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n return this.#getWallet(entropySource);\n }\n\n /**\n * Gets an array of all multichain account wallets.\n *\n * @returns An array of all multichain account wallets.\n */\n getMultichainAccountWallets(): MultichainAccountWallet<\n Bip44Account<KeyringAccount>\n >[] {\n return Array.from(this.#wallets.values());\n }\n\n /**\n * Creates a new multichain account wallet with the given mnemonic.\n *\n * NOTE: This method should only be called in client code where a mutex lock is acquired.\n * `discoverAndCreateAccounts` should be called after this method to discover and create accounts.\n *\n * @param options - Options.\n * @param options.mnemonic - The mnemonic to use to create the new wallet.\n * @throws If the mnemonic has already been imported.\n * @returns The new multichain account wallet.\n */\n async createMultichainAccountWallet({\n mnemonic,\n }: {\n mnemonic: string;\n }): Promise<MultichainAccountWallet<Bip44Account<KeyringAccount>>> {\n const existingKeyrings = this.#messenger.call(\n 'KeyringController:getKeyringsByType',\n KeyringTypes.hd,\n ) as HdKeyring[];\n\n const mnemonicAsBytes = mnemonicPhraseToBytes(mnemonic);\n\n const alreadyHasImportedSrp = existingKeyrings.some((keyring) => {\n if (!keyring.mnemonic) {\n return false;\n }\n return areUint8ArraysEqual(keyring.mnemonic, mnemonicAsBytes);\n });\n\n if (alreadyHasImportedSrp) {\n throw new Error('This Secret Recovery Phrase has already been imported.');\n }\n\n log(`Creating new wallet...`);\n\n const result = await this.#messenger.call(\n 'KeyringController:addNewKeyring',\n KeyringTypes.hd,\n { mnemonic },\n );\n\n const wallet = new MultichainAccountWallet({\n providers: this.#providers,\n entropySource: result.id,\n messenger: this.#messenger,\n });\n\n this.#wallets.set(wallet.id, wallet);\n\n log(`Wallet created: [${wallet.id}]`);\n\n return wallet;\n }\n\n /**\n * Gets a reference to the multichain account group matching this entropy source\n * and a group index.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @param options.groupIndex - The group index of the multichain account.\n * @throws If none multichain account match this entropy source and group index.\n * @returns A reference to the multichain account.\n */\n getMultichainAccountGroup({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccountGroup(groupIndex);\n\n if (!multichainAccount) {\n throw new Error(`No multichain account for index: ${groupIndex}`);\n }\n\n return multichainAccount;\n }\n\n /**\n * Gets all multichain account groups for a given entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source to query.\n * @throws If no multichain accounts match this entropy source.\n * @returns A list of all multichain accounts.\n */\n getMultichainAccountGroups({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>>[] {\n return this.#getWallet(entropySource).getMultichainAccountGroups();\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @param options - Options.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The next multichain account group.\n */\n async createNextMultichainAccountGroup({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(\n entropySource,\n ).createNextMultichainAccountGroup();\n }\n\n /**\n * Creates a multichain account group.\n *\n * @param options - Options.\n * @param options.groupIndex - The group index to use.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup({\n groupIndex,\n entropySource,\n }: {\n groupIndex: number;\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(entropySource).createMultichainAccountGroup(\n groupIndex,\n );\n }\n\n /**\n * Set basic functionality state and trigger alignment if enabled.\n * When basic functionality is disabled, snap-based providers are disabled.\n * When enabled, all snap providers are enabled and wallet alignment is triggered.\n * EVM providers are never disabled as they're required for basic wallet functionality.\n *\n * @param enabled - Whether basic functionality is enabled.\n */\n async setBasicFunctionality(enabled: boolean): Promise<void> {\n log(`Turning basic functionality: ${enabled ? 'ON' : 'OFF'}`);\n\n // Loop through providers and enable/disable only wrapped ones when basic functionality changes\n for (const provider of this.#providers) {\n if (isAccountProviderWrapper(provider)) {\n log(\n `${enabled ? 'Enabling' : 'Disabling'} account provider: \"${provider.getName()}\"`,\n );\n provider.setEnabled(enabled);\n }\n // Regular providers (like EVM) are never disabled for basic functionality\n }\n\n // Trigger alignment only when basic functionality is enabled\n if (enabled) {\n await this.alignWallets();\n }\n }\n\n /**\n * Align all multichain account wallets.\n */\n async alignWallets(): Promise<void> {\n log(`Triggering alignment on all wallets...`);\n\n const wallets = this.getMultichainAccountWallets();\n await Promise.all(wallets.map((w) => w.alignAccounts()));\n\n log(`Wallets aligned`);\n }\n\n /**\n * Align a specific multichain account wallet.\n *\n * @param entropySource - The entropy source of the multichain account wallet.\n */\n async alignWallet(entropySource: EntropySourceId): Promise<void> {\n const wallet = this.getMultichainAccountWallet({ entropySource });\n\n log(`Triggering alignment for wallet: [${wallet.id}]`);\n await wallet.alignAccounts();\n log(`Wallet [${wallet.id}] aligned`);\n }\n}\n"]}
@@ -2,10 +2,8 @@ import type { Bip44Account } from "@metamask/account-api";
2
2
  import type { EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
3
3
  import type { MultichainAccountGroup } from "./MultichainAccountGroup.cjs";
4
4
  import { MultichainAccountWallet } from "./MultichainAccountWallet.cjs";
5
- import type { EvmAccountProviderConfig, Bip44AccountProvider } from "./providers/index.cjs";
6
- import { EvmAccountProvider } from "./providers/EvmAccountProvider.cjs";
7
- import { SolAccountProvider } from "./providers/SolAccountProvider.cjs";
8
- import type { SolAccountProviderConfig } from "./providers/SolAccountProvider.cjs";
5
+ import { EvmAccountProviderConfig, Bip44AccountProvider, EVM_ACCOUNT_PROVIDER_NAME } from "./providers/index.cjs";
6
+ import { SOL_ACCOUNT_PROVIDER_NAME, SolAccountProviderConfig } from "./providers/SolAccountProvider.cjs";
9
7
  import type { MultichainAccountServiceConfig, MultichainAccountServiceMessenger } from "./types.cjs";
10
8
  export declare const serviceName = "MultichainAccountService";
11
9
  /**
@@ -15,8 +13,8 @@ export type MultichainAccountServiceOptions = {
15
13
  messenger: MultichainAccountServiceMessenger;
16
14
  providers?: Bip44AccountProvider[];
17
15
  providerConfigs?: {
18
- [EvmAccountProvider.NAME]?: EvmAccountProviderConfig;
19
- [SolAccountProvider.NAME]?: SolAccountProviderConfig;
16
+ [EVM_ACCOUNT_PROVIDER_NAME]?: EvmAccountProviderConfig;
17
+ [SOL_ACCOUNT_PROVIDER_NAME]?: SolAccountProviderConfig;
20
18
  };
21
19
  config?: MultichainAccountServiceConfig;
22
20
  };
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountService.d.cts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,YAAY,EACb,8BAA8B;AAG/B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAM7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,qCAAiC;AACvE,OAAO,EAAE,uBAAuB,EAAE,sCAAkC;AACpE,OAAO,KAAK,EACV,wBAAwB,EACxB,oBAAoB,EACrB,8BAAoB;AAKrB,OAAO,EAAE,kBAAkB,EAAE,2CAAuC;AACpE,OAAO,EAAE,kBAAkB,EAAE,2CAAuC;AACpE,OAAO,KAAK,EAAE,wBAAwB,EAAE,2CAAuC;AAC/E,OAAO,KAAK,EACV,8BAA8B,EAC9B,iCAAiC,EAClC,oBAAgB;AAGjB,eAAO,MAAM,WAAW,6BAA6B,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,SAAS,EAAE,iCAAiC,CAAC;IAC7C,SAAS,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACnC,eAAe,CAAC,EAAE;QAChB,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,EAAE,wBAAwB,CAAC;QACrD,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,EAAE,wBAAwB,CAAC;KACtD,CAAC;IACF,MAAM,CAAC,EAAE,8BAA8B,CAAC;CACzC,CAAC;AAEF,0FAA0F;AAC1F,KAAK,cAAc,CAAC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,IAAI;IAClE,MAAM,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACzC,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,qBAAa,wBAAwB;;IAenC;;OAEG;IACH,IAAI,EAAE,OAAO,WAAW,CAAe;IAEvC;;;;;;;;;OASG;gBACS,EACV,SAAS,EACT,SAAc,EACd,eAAe,EACf,MAAM,GACP,EAAE,+BAA+B;IAiFlC;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuC3B;;;;;;;;;;;;;;OAcG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAyHrC;;;;;;OAMG;IACH,iBAAiB,CACf,EAAE,EAAE,cAAc,CAAC,IAAI,CAAC,GACvB,cAAc,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,GAAG,SAAS;IAI3D;;;;;;;OAOG;IACH,0BAA0B,CAAC,EACzB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,uBAAuB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;IAIzD;;;;OAIG;IACH,2BAA2B,IAAI,uBAAuB,CACpD,YAAY,CAAC,cAAc,CAAC,CAC7B,EAAE;IAIH;;;;;;;;;;OAUG;IACG,6BAA6B,CAAC,EAClC,QAAQ,GACT,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,uBAAuB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC;IAwClE;;;;;;;;;OASG;IACH,yBAAyB,CAAC,EACxB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;IAWxD;;;;;;;OAOG;IACH,0BAA0B,CAAC,EACzB,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,EAAE;IAI1D;;;;;;OAMG;IACG,gCAAgC,CAAC,EACrC,aAAa,GACd,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,OAAO,CAAC,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC;IAMjE;;;;;;;OAOG;IACG,4BAA4B,CAAC,EACjC,UAAU,EACV,aAAa,GACd,EAAE;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,OAAO,CAAC,sBAAsB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC;IAMjE;;;;;;;OAOG;IACG,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB5D;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IASnC;;;;OAIG;IACG,WAAW,CAAC,aAAa,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAOjE"}
1
+ {"version":3,"file":"MultichainAccountService.d.cts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,8 @@ import type { Bip44Account } from "@metamask/account-api";
2
2
  import type { EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
3
3
  import type { MultichainAccountGroup } from "./MultichainAccountGroup.mjs";
4
4
  import { MultichainAccountWallet } from "./MultichainAccountWallet.mjs";
5
- import type { EvmAccountProviderConfig, Bip44AccountProvider } from "./providers/index.mjs";
6
- import { EvmAccountProvider } from "./providers/EvmAccountProvider.mjs";
7
- import { SolAccountProvider } from "./providers/SolAccountProvider.mjs";
8
- import type { SolAccountProviderConfig } from "./providers/SolAccountProvider.mjs";
5
+ import { EvmAccountProviderConfig, Bip44AccountProvider, EVM_ACCOUNT_PROVIDER_NAME } from "./providers/index.mjs";
6
+ import { SOL_ACCOUNT_PROVIDER_NAME, SolAccountProviderConfig } from "./providers/SolAccountProvider.mjs";
9
7
  import type { MultichainAccountServiceConfig, MultichainAccountServiceMessenger } from "./types.mjs";
10
8
  export declare const serviceName = "MultichainAccountService";
11
9
  /**
@@ -15,8 +13,8 @@ export type MultichainAccountServiceOptions = {
15
13
  messenger: MultichainAccountServiceMessenger;
16
14
  providers?: Bip44AccountProvider[];
17
15
  providerConfigs?: {
18
- [EvmAccountProvider.NAME]?: EvmAccountProviderConfig;
19
- [SolAccountProvider.NAME]?: SolAccountProviderConfig;
16
+ [EVM_ACCOUNT_PROVIDER_NAME]?: EvmAccountProviderConfig;
17
+ [SOL_ACCOUNT_PROVIDER_NAME]?: SolAccountProviderConfig;
20
18
  };
21
19
  config?: MultichainAccountServiceConfig;
22
20
  };
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountService.d.mts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MultichainAccountService.d.mts","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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"}
@@ -17,9 +17,11 @@ import { areUint8ArraysEqual } from "@metamask/utils";
17
17
  import { traceFallback } from "./analytics/index.mjs";
18
18
  import { projectLogger as log } from "./logger.mjs";
19
19
  import { MultichainAccountWallet } from "./MultichainAccountWallet.mjs";
20
+ import { EVM_ACCOUNT_PROVIDER_NAME } from "./providers/index.mjs";
20
21
  import { AccountProviderWrapper, isAccountProviderWrapper } from "./providers/AccountProviderWrapper.mjs";
21
22
  import { EvmAccountProvider } from "./providers/EvmAccountProvider.mjs";
22
23
  import { SolAccountProvider } from "./providers/SolAccountProvider.mjs";
24
+ import { SOL_ACCOUNT_PROVIDER_NAME } from "./providers/SolAccountProvider.mjs";
23
25
  import { createSentryError } from "./utils.mjs";
24
26
  export const serviceName = 'MultichainAccountService';
25
27
  /**
@@ -54,8 +56,8 @@ export class MultichainAccountService {
54
56
  const traceCallback = config?.trace ?? traceFallback;
55
57
  // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.
56
58
  __classPrivateFieldSet(this, _MultichainAccountService_providers, [
57
- new EvmAccountProvider(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), providerConfigs?.[EvmAccountProvider.NAME], traceCallback),
58
- new AccountProviderWrapper(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), new SolAccountProvider(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), providerConfigs?.[SolAccountProvider.NAME], traceCallback)),
59
+ new EvmAccountProvider(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), providerConfigs?.[EVM_ACCOUNT_PROVIDER_NAME], traceCallback),
60
+ new AccountProviderWrapper(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), new SolAccountProvider(__classPrivateFieldGet(this, _MultichainAccountService_messenger, "f"), providerConfigs?.[SOL_ACCOUNT_PROVIDER_NAME], traceCallback)),
59
61
  // Custom account providers that can be provided by the MetaMask client.
60
62
  ...providers,
61
63
  ], "f");
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountService.mjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isBip44Account,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport type {\n MultichainAccountWalletId,\n Bip44Account,\n} from '@metamask/account-api';\nimport type { HdKeyring } from '@metamask/eth-hd-keyring';\nimport { mnemonicPhraseToBytes } from '@metamask/key-tree';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport { areUint8ArraysEqual } from '@metamask/utils';\n\nimport { traceFallback } from './analytics';\nimport { projectLogger as log } from './logger';\nimport type { MultichainAccountGroup } from './MultichainAccountGroup';\nimport { MultichainAccountWallet } from './MultichainAccountWallet';\nimport type {\n EvmAccountProviderConfig,\n Bip44AccountProvider,\n} from './providers';\nimport {\n AccountProviderWrapper,\n isAccountProviderWrapper,\n} from './providers/AccountProviderWrapper';\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { SolAccountProviderConfig } from './providers/SolAccountProvider';\nimport type {\n MultichainAccountServiceConfig,\n MultichainAccountServiceMessenger,\n} from './types';\nimport { createSentryError } from './utils';\n\nexport const serviceName = 'MultichainAccountService';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\nexport type MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n providers?: Bip44AccountProvider[];\n providerConfigs?: {\n [EvmAccountProvider.NAME]?: EvmAccountProviderConfig;\n [SolAccountProvider.NAME]?: SolAccountProviderConfig;\n };\n config?: MultichainAccountServiceConfig;\n};\n\n/** Reverse mapping object used to map account IDs and their wallet/multichain account. */\ntype AccountContext<Account extends Bip44Account<KeyringAccount>> = {\n wallet: MultichainAccountWallet<Account>;\n group: MultichainAccountGroup<Account>;\n};\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService {\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #providers: Bip44AccountProvider[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<Bip44Account<KeyringAccount>>\n >;\n\n readonly #accountIdToContext: Map<\n Bip44Account<KeyringAccount>['id'],\n AccountContext<Bip44Account<KeyringAccount>>\n >;\n\n /**\n * The name of the service.\n */\n name: typeof serviceName = serviceName;\n\n /**\n * Constructs a new MultichainAccountService.\n *\n * @param options - The options.\n * @param options.messenger - The messenger suited to this\n * MultichainAccountService.\n * @param options.providers - Optional list of account\n * @param options.providerConfigs - Optional provider configs\n * @param options.config - Optional config.\n */\n constructor({\n messenger,\n providers = [],\n providerConfigs,\n config,\n }: MultichainAccountServiceOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\n this.#accountIdToContext = new Map();\n\n // Pass trace callback directly to preserve original 'this' context\n // This avoids binding the callback to the MultichainAccountService instance\n const traceCallback = config?.trace ?? traceFallback;\n\n // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n this.#providers = [\n new EvmAccountProvider(\n this.#messenger,\n providerConfigs?.[EvmAccountProvider.NAME],\n traceCallback,\n ),\n new AccountProviderWrapper(\n this.#messenger,\n new SolAccountProvider(\n this.#messenger,\n providerConfigs?.[SolAccountProvider.NAME],\n traceCallback,\n ),\n ),\n // Custom account providers that can be provided by the MetaMask client.\n ...providers,\n ];\n\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroup',\n (...args) => this.getMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroups',\n (...args) => this.getMultichainAccountGroups(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallet',\n (...args) => this.getMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallets',\n (...args) => this.getMultichainAccountWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createNextMultichainAccountGroup',\n (...args) => this.createNextMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountGroup',\n (...args) => this.createMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:setBasicFunctionality',\n (...args) => this.setBasicFunctionality(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallets',\n (...args) => this.alignWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallet',\n (...args) => this.alignWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountWallet',\n (...args) => this.createMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:resyncAccounts',\n (...args) => this.resyncAccounts(...args),\n );\n\n this.#messenger.subscribe('AccountsController:accountAdded', (account) =>\n this.#handleOnAccountAdded(account),\n );\n this.#messenger.subscribe('AccountsController:accountRemoved', (id) =>\n this.#handleOnAccountRemoved(id),\n );\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n async init(): Promise<void> {\n log('Initializing...');\n\n this.#wallets.clear();\n this.#accountIdToContext.clear();\n\n // Create initial wallets.\n const { keyrings } = this.#messenger.call('KeyringController:getState');\n for (const keyring of keyrings) {\n if (keyring.type === (KeyringTypes.hd as string)) {\n // Only HD keyrings have an entropy source/SRP.\n const entropySource = keyring.metadata.id;\n\n log(`Adding new wallet for entropy: \"${entropySource}\"`);\n\n // This will automatically \"associate\" all multichain accounts for that wallet\n // (based on the accounts owned by each account providers).\n const wallet = new MultichainAccountWallet({\n entropySource,\n providers: this.#providers,\n messenger: this.#messenger,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // Reverse mapping between account ID and their multichain wallet/account:\n for (const group of wallet.getMultichainAccountGroups()) {\n for (const account of group.getAccounts()) {\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n }\n }\n\n log('Initialized');\n }\n\n /**\n * Re-synchronize MetaMask accounts and the providers accounts if needed.\n *\n * NOTE: This is mostly required if one of the providers (keyrings or Snaps)\n * have different sets of accounts. This method would ensure that both are\n * in-sync and use the same accounts (and same IDs).\n *\n * READ THIS CAREFULLY (State inconsistency bugs/de-sync)\n * We've seen some problems were keyring accounts on some Snaps were not synchronized\n * with the accounts on MM side. This causes problems where we cannot interact with\n * those accounts because the Snap does know about them.\n * To \"workaround\" this de-sync problem for now, we make sure that both parties are\n * in-sync when the service boots up.\n * ----------------------------------------------------------------------------------\n */\n async resyncAccounts(): Promise<void> {\n log('Re-sync provider accounts if needed...');\n const accounts = this.#messenger\n .call('AccountsController:listMultichainAccounts')\n .filter(isBip44Account);\n // We use `Promise.all` + `try-catch` combo, since we don't wanna block the wallet\n // from being used even if some accounts are not sync (best-effort).\n await Promise.all(\n this.#providers.map(async (provider) => {\n try {\n await provider.resyncAccounts(accounts);\n } catch (error) {\n const errorMessage = `Unable to re-sync provider \"${provider.getName()}\"`;\n log(errorMessage);\n console.error(errorMessage);\n\n const sentryError = createSentryError(errorMessage, error as Error, {\n provider: provider.getName(),\n });\n this.#messenger.call(\n 'ErrorReportingService:captureException',\n sentryError,\n );\n }\n }),\n );\n log('Providers got re-synced!');\n }\n\n #handleOnAccountAdded(account: KeyringAccount): void {\n // We completely omit non-BIP-44 accounts!\n if (!isBip44Account(account)) {\n return;\n }\n\n let sync = true;\n\n let wallet = this.#wallets.get(\n toMultichainAccountWalletId(account.options.entropy.id),\n );\n if (!wallet) {\n log(\n `Adding new wallet for entropy: \"${account.options.entropy.id}\" (for account: \"${account.id}\")`,\n );\n\n // That's a new wallet.\n wallet = new MultichainAccountWallet({\n entropySource: account.options.entropy.id,\n providers: this.#providers,\n messenger: this.#messenger,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // If that's a new wallet wallet. There's nothing to \"force-sync\".\n sync = false;\n }\n\n let group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n if (!group) {\n // This new account is a new multichain account, let the wallet know\n // it has to re-sync with its providers.\n if (sync) {\n wallet.sync();\n }\n\n group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n\n // If that's a new multichain account. There's nothing to \"force-sync\".\n sync = false;\n }\n\n // We have to check against `undefined` in case `getMultichainAccount` is\n // not able to find this multichain account (which should not be possible...)\n if (group) {\n if (sync) {\n group.sync();\n }\n\n // Same here, this account should have been already grouped in that\n // multichain account.\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n\n #handleOnAccountRemoved(id: KeyringAccount['id']): void {\n // Force sync of the appropriate wallet if an account got removed.\n const found = this.#accountIdToContext.get(id);\n if (found) {\n const { wallet } = found;\n\n log(\n `Re-synchronize wallet [${wallet.id}] since account \"${id}\" got removed`,\n );\n wallet.sync();\n }\n\n // Safe to call delete even if the `id` was not referencing a BIP-44 account.\n this.#accountIdToContext.delete(id);\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(entropySource),\n );\n\n if (!wallet) {\n throw new Error('Unknown wallet, no wallet matching this entropy source');\n }\n\n return wallet;\n }\n\n /**\n * Gets the account's context which contains its multichain wallet and\n * multichain account group references.\n *\n * @param id - Account ID.\n * @returns The account context if any, undefined otherwise.\n */\n getAccountContext(\n id: KeyringAccount['id'],\n ): AccountContext<Bip44Account<KeyringAccount>> | undefined {\n return this.#accountIdToContext.get(id);\n }\n\n /**\n * Gets a reference to the multichain account wallet matching this entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @throws If none multichain account match this entropy.\n * @returns A reference to the multichain account wallet.\n */\n getMultichainAccountWallet({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n return this.#getWallet(entropySource);\n }\n\n /**\n * Gets an array of all multichain account wallets.\n *\n * @returns An array of all multichain account wallets.\n */\n getMultichainAccountWallets(): MultichainAccountWallet<\n Bip44Account<KeyringAccount>\n >[] {\n return Array.from(this.#wallets.values());\n }\n\n /**\n * Creates a new multichain account wallet with the given mnemonic.\n *\n * NOTE: This method should only be called in client code where a mutex lock is acquired.\n * `discoverAndCreateAccounts` should be called after this method to discover and create accounts.\n *\n * @param options - Options.\n * @param options.mnemonic - The mnemonic to use to create the new wallet.\n * @throws If the mnemonic has already been imported.\n * @returns The new multichain account wallet.\n */\n async createMultichainAccountWallet({\n mnemonic,\n }: {\n mnemonic: string;\n }): Promise<MultichainAccountWallet<Bip44Account<KeyringAccount>>> {\n const existingKeyrings = this.#messenger.call(\n 'KeyringController:getKeyringsByType',\n KeyringTypes.hd,\n ) as HdKeyring[];\n\n const mnemonicAsBytes = mnemonicPhraseToBytes(mnemonic);\n\n const alreadyHasImportedSrp = existingKeyrings.some((keyring) => {\n if (!keyring.mnemonic) {\n return false;\n }\n return areUint8ArraysEqual(keyring.mnemonic, mnemonicAsBytes);\n });\n\n if (alreadyHasImportedSrp) {\n throw new Error('This Secret Recovery Phrase has already been imported.');\n }\n\n log(`Creating new wallet...`);\n\n const result = await this.#messenger.call(\n 'KeyringController:addNewKeyring',\n KeyringTypes.hd,\n { mnemonic },\n );\n\n const wallet = new MultichainAccountWallet({\n providers: this.#providers,\n entropySource: result.id,\n messenger: this.#messenger,\n });\n\n this.#wallets.set(wallet.id, wallet);\n\n log(`Wallet created: [${wallet.id}]`);\n\n return wallet;\n }\n\n /**\n * Gets a reference to the multichain account group matching this entropy source\n * and a group index.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @param options.groupIndex - The group index of the multichain account.\n * @throws If none multichain account match this entropy source and group index.\n * @returns A reference to the multichain account.\n */\n getMultichainAccountGroup({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccountGroup(groupIndex);\n\n if (!multichainAccount) {\n throw new Error(`No multichain account for index: ${groupIndex}`);\n }\n\n return multichainAccount;\n }\n\n /**\n * Gets all multichain account groups for a given entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source to query.\n * @throws If no multichain accounts match this entropy source.\n * @returns A list of all multichain accounts.\n */\n getMultichainAccountGroups({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>>[] {\n return this.#getWallet(entropySource).getMultichainAccountGroups();\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @param options - Options.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The next multichain account group.\n */\n async createNextMultichainAccountGroup({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(\n entropySource,\n ).createNextMultichainAccountGroup();\n }\n\n /**\n * Creates a multichain account group.\n *\n * @param options - Options.\n * @param options.groupIndex - The group index to use.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup({\n groupIndex,\n entropySource,\n }: {\n groupIndex: number;\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(entropySource).createMultichainAccountGroup(\n groupIndex,\n );\n }\n\n /**\n * Set basic functionality state and trigger alignment if enabled.\n * When basic functionality is disabled, snap-based providers are disabled.\n * When enabled, all snap providers are enabled and wallet alignment is triggered.\n * EVM providers are never disabled as they're required for basic wallet functionality.\n *\n * @param enabled - Whether basic functionality is enabled.\n */\n async setBasicFunctionality(enabled: boolean): Promise<void> {\n log(`Turning basic functionality: ${enabled ? 'ON' : 'OFF'}`);\n\n // Loop through providers and enable/disable only wrapped ones when basic functionality changes\n for (const provider of this.#providers) {\n if (isAccountProviderWrapper(provider)) {\n log(\n `${enabled ? 'Enabling' : 'Disabling'} account provider: \"${provider.getName()}\"`,\n );\n provider.setEnabled(enabled);\n }\n // Regular providers (like EVM) are never disabled for basic functionality\n }\n\n // Trigger alignment only when basic functionality is enabled\n if (enabled) {\n await this.alignWallets();\n }\n }\n\n /**\n * Align all multichain account wallets.\n */\n async alignWallets(): Promise<void> {\n log(`Triggering alignment on all wallets...`);\n\n const wallets = this.getMultichainAccountWallets();\n await Promise.all(wallets.map((w) => w.alignAccounts()));\n\n log(`Wallets aligned`);\n }\n\n /**\n * Align a specific multichain account wallet.\n *\n * @param entropySource - The entropy source of the multichain account wallet.\n */\n async alignWallet(entropySource: EntropySourceId): Promise<void> {\n const wallet = this.getMultichainAccountWallet({ entropySource });\n\n log(`Triggering alignment for wallet: [${wallet.id}]`);\n await wallet.alignAccounts();\n log(`Wallet [${wallet.id}] aligned`);\n }\n}\n"]}
1
+ {"version":3,"file":"MultichainAccountService.mjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isBip44Account,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport type {\n MultichainAccountWalletId,\n Bip44Account,\n} from '@metamask/account-api';\nimport type { HdKeyring } from '@metamask/eth-hd-keyring';\nimport { mnemonicPhraseToBytes } from '@metamask/key-tree';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport { areUint8ArraysEqual } from '@metamask/utils';\n\nimport { traceFallback } from './analytics';\nimport { projectLogger as log } from './logger';\nimport type { MultichainAccountGroup } from './MultichainAccountGroup';\nimport { MultichainAccountWallet } from './MultichainAccountWallet';\nimport {\n EvmAccountProviderConfig,\n Bip44AccountProvider,\n EVM_ACCOUNT_PROVIDER_NAME,\n} from './providers';\nimport {\n AccountProviderWrapper,\n isAccountProviderWrapper,\n} from './providers/AccountProviderWrapper';\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport {\n SOL_ACCOUNT_PROVIDER_NAME,\n SolAccountProviderConfig,\n} from './providers/SolAccountProvider';\nimport type {\n MultichainAccountServiceConfig,\n MultichainAccountServiceMessenger,\n} from './types';\nimport { createSentryError } from './utils';\n\nexport const serviceName = 'MultichainAccountService';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\nexport type MultichainAccountServiceOptions = {\n messenger: MultichainAccountServiceMessenger;\n providers?: Bip44AccountProvider[];\n providerConfigs?: {\n [EVM_ACCOUNT_PROVIDER_NAME]?: EvmAccountProviderConfig;\n [SOL_ACCOUNT_PROVIDER_NAME]?: SolAccountProviderConfig;\n };\n config?: MultichainAccountServiceConfig;\n};\n\n/** Reverse mapping object used to map account IDs and their wallet/multichain account. */\ntype AccountContext<Account extends Bip44Account<KeyringAccount>> = {\n wallet: MultichainAccountWallet<Account>;\n group: MultichainAccountGroup<Account>;\n};\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService {\n readonly #messenger: MultichainAccountServiceMessenger;\n\n readonly #providers: Bip44AccountProvider[];\n\n readonly #wallets: Map<\n MultichainAccountWalletId,\n MultichainAccountWallet<Bip44Account<KeyringAccount>>\n >;\n\n readonly #accountIdToContext: Map<\n Bip44Account<KeyringAccount>['id'],\n AccountContext<Bip44Account<KeyringAccount>>\n >;\n\n /**\n * The name of the service.\n */\n name: typeof serviceName = serviceName;\n\n /**\n * Constructs a new MultichainAccountService.\n *\n * @param options - The options.\n * @param options.messenger - The messenger suited to this\n * MultichainAccountService.\n * @param options.providers - Optional list of account\n * @param options.providerConfigs - Optional provider configs\n * @param options.config - Optional config.\n */\n constructor({\n messenger,\n providers = [],\n providerConfigs,\n config,\n }: MultichainAccountServiceOptions) {\n this.#messenger = messenger;\n this.#wallets = new Map();\n this.#accountIdToContext = new Map();\n\n // Pass trace callback directly to preserve original 'this' context\n // This avoids binding the callback to the MultichainAccountService instance\n const traceCallback = config?.trace ?? traceFallback;\n\n // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n this.#providers = [\n new EvmAccountProvider(\n this.#messenger,\n providerConfigs?.[EVM_ACCOUNT_PROVIDER_NAME],\n traceCallback,\n ),\n new AccountProviderWrapper(\n this.#messenger,\n new SolAccountProvider(\n this.#messenger,\n providerConfigs?.[SOL_ACCOUNT_PROVIDER_NAME],\n traceCallback,\n ),\n ),\n // Custom account providers that can be provided by the MetaMask client.\n ...providers,\n ];\n\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroup',\n (...args) => this.getMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountGroups',\n (...args) => this.getMultichainAccountGroups(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallet',\n (...args) => this.getMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:getMultichainAccountWallets',\n (...args) => this.getMultichainAccountWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createNextMultichainAccountGroup',\n (...args) => this.createNextMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountGroup',\n (...args) => this.createMultichainAccountGroup(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:setBasicFunctionality',\n (...args) => this.setBasicFunctionality(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallets',\n (...args) => this.alignWallets(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:alignWallet',\n (...args) => this.alignWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:createMultichainAccountWallet',\n (...args) => this.createMultichainAccountWallet(...args),\n );\n this.#messenger.registerActionHandler(\n 'MultichainAccountService:resyncAccounts',\n (...args) => this.resyncAccounts(...args),\n );\n\n this.#messenger.subscribe('AccountsController:accountAdded', (account) =>\n this.#handleOnAccountAdded(account),\n );\n this.#messenger.subscribe('AccountsController:accountRemoved', (id) =>\n this.#handleOnAccountRemoved(id),\n );\n }\n\n /**\n * Initialize the service and constructs the internal reprensentation of\n * multichain accounts and wallets.\n */\n async init(): Promise<void> {\n log('Initializing...');\n\n this.#wallets.clear();\n this.#accountIdToContext.clear();\n\n // Create initial wallets.\n const { keyrings } = this.#messenger.call('KeyringController:getState');\n for (const keyring of keyrings) {\n if (keyring.type === (KeyringTypes.hd as string)) {\n // Only HD keyrings have an entropy source/SRP.\n const entropySource = keyring.metadata.id;\n\n log(`Adding new wallet for entropy: \"${entropySource}\"`);\n\n // This will automatically \"associate\" all multichain accounts for that wallet\n // (based on the accounts owned by each account providers).\n const wallet = new MultichainAccountWallet({\n entropySource,\n providers: this.#providers,\n messenger: this.#messenger,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // Reverse mapping between account ID and their multichain wallet/account:\n for (const group of wallet.getMultichainAccountGroups()) {\n for (const account of group.getAccounts()) {\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n }\n }\n\n log('Initialized');\n }\n\n /**\n * Re-synchronize MetaMask accounts and the providers accounts if needed.\n *\n * NOTE: This is mostly required if one of the providers (keyrings or Snaps)\n * have different sets of accounts. This method would ensure that both are\n * in-sync and use the same accounts (and same IDs).\n *\n * READ THIS CAREFULLY (State inconsistency bugs/de-sync)\n * We've seen some problems were keyring accounts on some Snaps were not synchronized\n * with the accounts on MM side. This causes problems where we cannot interact with\n * those accounts because the Snap does know about them.\n * To \"workaround\" this de-sync problem for now, we make sure that both parties are\n * in-sync when the service boots up.\n * ----------------------------------------------------------------------------------\n */\n async resyncAccounts(): Promise<void> {\n log('Re-sync provider accounts if needed...');\n const accounts = this.#messenger\n .call('AccountsController:listMultichainAccounts')\n .filter(isBip44Account);\n // We use `Promise.all` + `try-catch` combo, since we don't wanna block the wallet\n // from being used even if some accounts are not sync (best-effort).\n await Promise.all(\n this.#providers.map(async (provider) => {\n try {\n await provider.resyncAccounts(accounts);\n } catch (error) {\n const errorMessage = `Unable to re-sync provider \"${provider.getName()}\"`;\n log(errorMessage);\n console.error(errorMessage);\n\n const sentryError = createSentryError(errorMessage, error as Error, {\n provider: provider.getName(),\n });\n this.#messenger.call(\n 'ErrorReportingService:captureException',\n sentryError,\n );\n }\n }),\n );\n log('Providers got re-synced!');\n }\n\n #handleOnAccountAdded(account: KeyringAccount): void {\n // We completely omit non-BIP-44 accounts!\n if (!isBip44Account(account)) {\n return;\n }\n\n let sync = true;\n\n let wallet = this.#wallets.get(\n toMultichainAccountWalletId(account.options.entropy.id),\n );\n if (!wallet) {\n log(\n `Adding new wallet for entropy: \"${account.options.entropy.id}\" (for account: \"${account.id}\")`,\n );\n\n // That's a new wallet.\n wallet = new MultichainAccountWallet({\n entropySource: account.options.entropy.id,\n providers: this.#providers,\n messenger: this.#messenger,\n });\n this.#wallets.set(wallet.id, wallet);\n\n // If that's a new wallet wallet. There's nothing to \"force-sync\".\n sync = false;\n }\n\n let group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n if (!group) {\n // This new account is a new multichain account, let the wallet know\n // it has to re-sync with its providers.\n if (sync) {\n wallet.sync();\n }\n\n group = wallet.getMultichainAccountGroup(\n account.options.entropy.groupIndex,\n );\n\n // If that's a new multichain account. There's nothing to \"force-sync\".\n sync = false;\n }\n\n // We have to check against `undefined` in case `getMultichainAccount` is\n // not able to find this multichain account (which should not be possible...)\n if (group) {\n if (sync) {\n group.sync();\n }\n\n // Same here, this account should have been already grouped in that\n // multichain account.\n this.#accountIdToContext.set(account.id, {\n wallet,\n group,\n });\n }\n }\n\n #handleOnAccountRemoved(id: KeyringAccount['id']): void {\n // Force sync of the appropriate wallet if an account got removed.\n const found = this.#accountIdToContext.get(id);\n if (found) {\n const { wallet } = found;\n\n log(\n `Re-synchronize wallet [${wallet.id}] since account \"${id}\" got removed`,\n );\n wallet.sync();\n }\n\n // Safe to call delete even if the `id` was not referencing a BIP-44 account.\n this.#accountIdToContext.delete(id);\n }\n\n #getWallet(\n entropySource: EntropySourceId,\n ): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n const wallet = this.#wallets.get(\n toMultichainAccountWalletId(entropySource),\n );\n\n if (!wallet) {\n throw new Error('Unknown wallet, no wallet matching this entropy source');\n }\n\n return wallet;\n }\n\n /**\n * Gets the account's context which contains its multichain wallet and\n * multichain account group references.\n *\n * @param id - Account ID.\n * @returns The account context if any, undefined otherwise.\n */\n getAccountContext(\n id: KeyringAccount['id'],\n ): AccountContext<Bip44Account<KeyringAccount>> | undefined {\n return this.#accountIdToContext.get(id);\n }\n\n /**\n * Gets a reference to the multichain account wallet matching this entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @throws If none multichain account match this entropy.\n * @returns A reference to the multichain account wallet.\n */\n getMultichainAccountWallet({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountWallet<Bip44Account<KeyringAccount>> {\n return this.#getWallet(entropySource);\n }\n\n /**\n * Gets an array of all multichain account wallets.\n *\n * @returns An array of all multichain account wallets.\n */\n getMultichainAccountWallets(): MultichainAccountWallet<\n Bip44Account<KeyringAccount>\n >[] {\n return Array.from(this.#wallets.values());\n }\n\n /**\n * Creates a new multichain account wallet with the given mnemonic.\n *\n * NOTE: This method should only be called in client code where a mutex lock is acquired.\n * `discoverAndCreateAccounts` should be called after this method to discover and create accounts.\n *\n * @param options - Options.\n * @param options.mnemonic - The mnemonic to use to create the new wallet.\n * @throws If the mnemonic has already been imported.\n * @returns The new multichain account wallet.\n */\n async createMultichainAccountWallet({\n mnemonic,\n }: {\n mnemonic: string;\n }): Promise<MultichainAccountWallet<Bip44Account<KeyringAccount>>> {\n const existingKeyrings = this.#messenger.call(\n 'KeyringController:getKeyringsByType',\n KeyringTypes.hd,\n ) as HdKeyring[];\n\n const mnemonicAsBytes = mnemonicPhraseToBytes(mnemonic);\n\n const alreadyHasImportedSrp = existingKeyrings.some((keyring) => {\n if (!keyring.mnemonic) {\n return false;\n }\n return areUint8ArraysEqual(keyring.mnemonic, mnemonicAsBytes);\n });\n\n if (alreadyHasImportedSrp) {\n throw new Error('This Secret Recovery Phrase has already been imported.');\n }\n\n log(`Creating new wallet...`);\n\n const result = await this.#messenger.call(\n 'KeyringController:addNewKeyring',\n KeyringTypes.hd,\n { mnemonic },\n );\n\n const wallet = new MultichainAccountWallet({\n providers: this.#providers,\n entropySource: result.id,\n messenger: this.#messenger,\n });\n\n this.#wallets.set(wallet.id, wallet);\n\n log(`Wallet created: [${wallet.id}]`);\n\n return wallet;\n }\n\n /**\n * Gets a reference to the multichain account group matching this entropy source\n * and a group index.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source of the multichain account.\n * @param options.groupIndex - The group index of the multichain account.\n * @throws If none multichain account match this entropy source and group index.\n * @returns A reference to the multichain account.\n */\n getMultichainAccountGroup({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>> {\n const multichainAccount =\n this.#getWallet(entropySource).getMultichainAccountGroup(groupIndex);\n\n if (!multichainAccount) {\n throw new Error(`No multichain account for index: ${groupIndex}`);\n }\n\n return multichainAccount;\n }\n\n /**\n * Gets all multichain account groups for a given entropy source.\n *\n * @param options - Options.\n * @param options.entropySource - The entropy source to query.\n * @throws If no multichain accounts match this entropy source.\n * @returns A list of all multichain accounts.\n */\n getMultichainAccountGroups({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): MultichainAccountGroup<Bip44Account<KeyringAccount>>[] {\n return this.#getWallet(entropySource).getMultichainAccountGroups();\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @param options - Options.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The next multichain account group.\n */\n async createNextMultichainAccountGroup({\n entropySource,\n }: {\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(\n entropySource,\n ).createNextMultichainAccountGroup();\n }\n\n /**\n * Creates a multichain account group.\n *\n * @param options - Options.\n * @param options.groupIndex - The group index to use.\n * @param options.entropySource - The wallet's entropy source.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup({\n groupIndex,\n entropySource,\n }: {\n groupIndex: number;\n entropySource: EntropySourceId;\n }): Promise<MultichainAccountGroup<Bip44Account<KeyringAccount>>> {\n return await this.#getWallet(entropySource).createMultichainAccountGroup(\n groupIndex,\n );\n }\n\n /**\n * Set basic functionality state and trigger alignment if enabled.\n * When basic functionality is disabled, snap-based providers are disabled.\n * When enabled, all snap providers are enabled and wallet alignment is triggered.\n * EVM providers are never disabled as they're required for basic wallet functionality.\n *\n * @param enabled - Whether basic functionality is enabled.\n */\n async setBasicFunctionality(enabled: boolean): Promise<void> {\n log(`Turning basic functionality: ${enabled ? 'ON' : 'OFF'}`);\n\n // Loop through providers and enable/disable only wrapped ones when basic functionality changes\n for (const provider of this.#providers) {\n if (isAccountProviderWrapper(provider)) {\n log(\n `${enabled ? 'Enabling' : 'Disabling'} account provider: \"${provider.getName()}\"`,\n );\n provider.setEnabled(enabled);\n }\n // Regular providers (like EVM) are never disabled for basic functionality\n }\n\n // Trigger alignment only when basic functionality is enabled\n if (enabled) {\n await this.alignWallets();\n }\n }\n\n /**\n * Align all multichain account wallets.\n */\n async alignWallets(): Promise<void> {\n log(`Triggering alignment on all wallets...`);\n\n const wallets = this.getMultichainAccountWallets();\n await Promise.all(wallets.map((w) => w.alignAccounts()));\n\n log(`Wallets aligned`);\n }\n\n /**\n * Align a specific multichain account wallet.\n *\n * @param entropySource - The entropy source of the multichain account wallet.\n */\n async alignWallet(entropySource: EntropySourceId): Promise<void> {\n const wallet = this.getMultichainAccountWallet({ entropySource });\n\n log(`Triggering alignment for wallet: [${wallet.id}]`);\n await wallet.alignAccounts();\n log(`Wallet [${wallet.id}] aligned`);\n }\n}\n"]}
@@ -21,6 +21,7 @@ const BaseBip44AccountProvider_1 = require("./BaseBip44AccountProvider.cjs");
21
21
  const utils_2 = require("./utils.cjs");
22
22
  const analytics_1 = require("../analytics/index.cjs");
23
23
  const traces_1 = require("../constants/traces.cjs");
24
+ const logger_1 = require("../logger.cjs");
24
25
  const ETH_MAINNET_CHAIN_ID = '0x1';
25
26
  /**
26
27
  * Asserts an internal account exists.
@@ -137,14 +138,22 @@ _EvmAccountProvider_config = new WeakMap(), _EvmAccountProvider_trace = new Weak
137
138
  });
138
139
  return result;
139
140
  }, _EvmAccountProvider_getTransactionCount = async function _EvmAccountProvider_getTransactionCount(provider, address) {
140
- const countHex = await (0, utils_2.withRetry)(() => (0, utils_2.withTimeout)(provider.request({
141
- method: 'eth_getTransactionCount',
141
+ const method = 'eth_getTransactionCount';
142
+ const response = await (0, utils_2.withRetry)(() => (0, utils_2.withTimeout)(provider.request({
143
+ method,
142
144
  params: [address, 'latest'],
143
145
  }), __classPrivateFieldGet(this, _EvmAccountProvider_config, "f").discovery.timeoutMs), {
144
146
  maxAttempts: __classPrivateFieldGet(this, _EvmAccountProvider_config, "f").discovery.maxAttempts,
145
147
  backOffMs: __classPrivateFieldGet(this, _EvmAccountProvider_config, "f").discovery.backOffMs,
146
148
  });
147
- return parseInt(countHex, 16);
149
+ // Make sure we got the right response format, if not, we fallback to "0x0", to avoid having to deal with `NaN`.
150
+ if (!(0, utils_1.isStrictHexString)(response)) {
151
+ const message = `Received invalid hex response from "${method}" request: ${JSON.stringify(response)}`;
152
+ (0, logger_1.projectLogger)(`${logger_1.WARNING_PREFIX} ${message}`);
153
+ console.warn(message);
154
+ return 0;
155
+ }
156
+ return parseInt(response, 16);
148
157
  }, _EvmAccountProvider_getAddressFromGroupIndex = async function _EvmAccountProvider_getAddressFromGroupIndex({ entropySource, groupIndex, }) {
149
158
  // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state
150
159
  // and compute the derivation here.
@@ -1 +1 @@
1
- {"version":3,"file":"EvmAccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { publicToAddress } from '@ethereumjs/util';\nimport type { Bip44Account } from '@metamask/account-api';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport type { HdKeyring } from '@metamask/eth-hd-keyring';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { EthAccountType } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport type { Provider } from '@metamask/network-controller';\nimport { add0x, assert, bytesToHex } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n assertAreBip44Accounts,\n assertIsBip44Account,\n BaseBip44AccountProvider,\n} from './BaseBip44AccountProvider';\nimport { withRetry, withTimeout } from './utils';\nimport { traceFallback } from '../analytics';\nimport { TraceName } from '../constants/traces';\nimport type { MultichainAccountServiceMessenger } from '../types';\n\nconst ETH_MAINNET_CHAIN_ID = '0x1';\n\n/**\n * Asserts an internal account exists.\n *\n * @param account - The internal account to check.\n * @throws An error if the internal account does not exist.\n */\nfunction assertInternalAccountExists(\n account: InternalAccount | undefined,\n): asserts account is InternalAccount {\n if (!account) {\n throw new Error('Internal account does not exist');\n }\n}\n\nexport type EvmAccountProviderConfig = {\n discovery: {\n maxAttempts: number;\n timeoutMs: number;\n backOffMs: number;\n };\n};\n\nexport const EVM_ACCOUNT_PROVIDER_NAME = 'EVM' as const;\n\nexport class EvmAccountProvider extends BaseBip44AccountProvider {\n static NAME = EVM_ACCOUNT_PROVIDER_NAME;\n\n readonly #config: EvmAccountProviderConfig;\n\n readonly #trace: TraceCallback;\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n config: EvmAccountProviderConfig = {\n discovery: {\n maxAttempts: 3,\n timeoutMs: 500,\n backOffMs: 500,\n },\n },\n trace?: TraceCallback,\n ) {\n super(messenger);\n this.#config = config;\n this.#trace = trace ?? traceFallback;\n }\n\n isAccountCompatible(account: Bip44Account<InternalAccount>): boolean {\n return (\n account.type === EthAccountType.Eoa &&\n account.metadata.keyring.type === (KeyringTypes.hd as string)\n );\n }\n\n getName(): string {\n return EvmAccountProvider.NAME;\n }\n\n /**\n * Get the EVM provider.\n *\n * @returns The EVM provider.\n */\n getEvmProvider(): Provider {\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n ETH_MAINNET_CHAIN_ID,\n );\n const { provider } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return provider;\n }\n\n async #createAccount({\n entropySource,\n groupIndex,\n throwOnGap = false,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n throwOnGap?: boolean;\n }): Promise<[Hex, boolean]> {\n const result = await this.withKeyring<EthKeyring, [Hex, boolean]>(\n { id: entropySource },\n async ({ keyring }) => {\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return [existing[groupIndex], false];\n }\n\n // If the throwOnGap flag is set, we throw an error to prevent index gaps.\n if (throwOnGap && groupIndex !== existing.length) {\n throw new Error('Trying to create too many accounts');\n }\n\n const [added] = await keyring.addAccounts(1);\n return [added, true];\n },\n );\n\n return result;\n }\n\n async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n throwOnGap: true,\n });\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n\n // We MUST have the associated internal account.\n assertInternalAccountExists(account);\n\n const accountsArray = [account];\n assertAreBip44Accounts(accountsArray);\n\n return accountsArray;\n }\n\n async #getTransactionCount(\n provider: Provider,\n address: Hex,\n ): Promise<number> {\n const countHex = await withRetry<Hex>(\n () =>\n withTimeout(\n provider.request({\n method: 'eth_getTransactionCount',\n params: [address, 'latest'],\n }),\n this.#config.discovery.timeoutMs,\n ),\n {\n maxAttempts: this.#config.discovery.maxAttempts,\n backOffMs: this.#config.discovery.backOffMs,\n },\n );\n\n return parseInt(countHex, 16);\n }\n\n async #getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Hex> {\n // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state\n // and compute the derivation here.\n return await this.withKeyring<HdKeyring, Hex>(\n { id: entropySource },\n async ({ keyring }) => {\n // If the account already exist, do not re-derive and just re-use that account.\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return existing[groupIndex];\n }\n\n // If not, then we just \"peek\" the next address to avoid creating the account.\n assert(keyring.root, 'Expected HD keyring.root to be set');\n const hdKey = keyring.root.deriveChild(groupIndex);\n assert(hdKey.publicKey, 'Expected public key to be set');\n\n return add0x(\n bytesToHex(publicToAddress(hdKey.publicKey, true)).toLowerCase(),\n );\n },\n );\n }\n\n /**\n * Discover and create accounts for the EVM provider.\n *\n * @param opts - The options for the discovery and creation of accounts.\n * @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.\n * @param opts.groupIndex - The index of the group to create the accounts for.\n * @returns The accounts for the EVM provider.\n */\n async discoverAccounts(opts: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n return this.#trace(\n {\n name: TraceName.EvmDiscoverAccounts,\n data: {\n provider: this.getName(),\n },\n },\n async () => {\n const provider = this.getEvmProvider();\n const { entropySource, groupIndex } = opts;\n\n const addressFromGroupIndex = await this.#getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n });\n\n const count = await this.#getTransactionCount(\n provider,\n addressFromGroupIndex,\n );\n if (count === 0) {\n return [];\n }\n\n // We have some activity on this address, we try to create the account.\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n });\n assert(\n addressFromGroupIndex === address,\n 'Created account does not match address from group index.',\n );\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n assertInternalAccountExists(account);\n assertIsBip44Account(account);\n return [account];\n },\n );\n }\n\n async resyncAccounts(): Promise<void> {\n // No-op for the EVM account provider, since keyring accounts are already on\n // the MetaMask side.\n }\n}\n"]}
1
+ {"version":3,"file":"EvmAccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { publicToAddress } from '@ethereumjs/util';\nimport type { Bip44Account } from '@metamask/account-api';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport type { HdKeyring } from '@metamask/eth-hd-keyring';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { EthAccountType } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport type { Provider } from '@metamask/network-controller';\nimport { add0x, assert, bytesToHex, isStrictHexString } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n assertAreBip44Accounts,\n assertIsBip44Account,\n BaseBip44AccountProvider,\n} from './BaseBip44AccountProvider';\nimport { withRetry, withTimeout } from './utils';\nimport { traceFallback } from '../analytics';\nimport { TraceName } from '../constants/traces';\nimport { projectLogger as log, WARNING_PREFIX } from '../logger';\nimport type { MultichainAccountServiceMessenger } from '../types';\n\nconst ETH_MAINNET_CHAIN_ID = '0x1';\n\n/**\n * Asserts an internal account exists.\n *\n * @param account - The internal account to check.\n * @throws An error if the internal account does not exist.\n */\nfunction assertInternalAccountExists(\n account: InternalAccount | undefined,\n): asserts account is InternalAccount {\n if (!account) {\n throw new Error('Internal account does not exist');\n }\n}\n\nexport type EvmAccountProviderConfig = {\n discovery: {\n maxAttempts: number;\n timeoutMs: number;\n backOffMs: number;\n };\n};\n\nexport const EVM_ACCOUNT_PROVIDER_NAME = 'EVM';\n\nexport class EvmAccountProvider extends BaseBip44AccountProvider {\n static NAME = EVM_ACCOUNT_PROVIDER_NAME;\n\n readonly #config: EvmAccountProviderConfig;\n\n readonly #trace: TraceCallback;\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n config: EvmAccountProviderConfig = {\n discovery: {\n maxAttempts: 3,\n timeoutMs: 500,\n backOffMs: 500,\n },\n },\n trace?: TraceCallback,\n ) {\n super(messenger);\n this.#config = config;\n this.#trace = trace ?? traceFallback;\n }\n\n isAccountCompatible(account: Bip44Account<InternalAccount>): boolean {\n return (\n account.type === EthAccountType.Eoa &&\n account.metadata.keyring.type === (KeyringTypes.hd as string)\n );\n }\n\n getName(): string {\n return EvmAccountProvider.NAME;\n }\n\n /**\n * Get the EVM provider.\n *\n * @returns The EVM provider.\n */\n getEvmProvider(): Provider {\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n ETH_MAINNET_CHAIN_ID,\n );\n const { provider } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return provider;\n }\n\n async #createAccount({\n entropySource,\n groupIndex,\n throwOnGap = false,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n throwOnGap?: boolean;\n }): Promise<[Hex, boolean]> {\n const result = await this.withKeyring<EthKeyring, [Hex, boolean]>(\n { id: entropySource },\n async ({ keyring }) => {\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return [existing[groupIndex], false];\n }\n\n // If the throwOnGap flag is set, we throw an error to prevent index gaps.\n if (throwOnGap && groupIndex !== existing.length) {\n throw new Error('Trying to create too many accounts');\n }\n\n const [added] = await keyring.addAccounts(1);\n return [added, true];\n },\n );\n\n return result;\n }\n\n async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n throwOnGap: true,\n });\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n\n // We MUST have the associated internal account.\n assertInternalAccountExists(account);\n\n const accountsArray = [account];\n assertAreBip44Accounts(accountsArray);\n\n return accountsArray;\n }\n\n async #getTransactionCount(\n provider: Provider,\n address: Hex,\n ): Promise<number> {\n const method = 'eth_getTransactionCount';\n\n const response = await withRetry(\n () =>\n withTimeout(\n provider.request({\n method,\n params: [address, 'latest'],\n }),\n this.#config.discovery.timeoutMs,\n ),\n {\n maxAttempts: this.#config.discovery.maxAttempts,\n backOffMs: this.#config.discovery.backOffMs,\n },\n );\n\n // Make sure we got the right response format, if not, we fallback to \"0x0\", to avoid having to deal with `NaN`.\n if (!isStrictHexString(response)) {\n const message = `Received invalid hex response from \"${method}\" request: ${JSON.stringify(response)}`;\n\n log(`${WARNING_PREFIX} ${message}`);\n console.warn(message);\n\n return 0;\n }\n\n return parseInt(response, 16);\n }\n\n async #getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Hex> {\n // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state\n // and compute the derivation here.\n return await this.withKeyring<HdKeyring, Hex>(\n { id: entropySource },\n async ({ keyring }) => {\n // If the account already exist, do not re-derive and just re-use that account.\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return existing[groupIndex];\n }\n\n // If not, then we just \"peek\" the next address to avoid creating the account.\n assert(keyring.root, 'Expected HD keyring.root to be set');\n const hdKey = keyring.root.deriveChild(groupIndex);\n assert(hdKey.publicKey, 'Expected public key to be set');\n\n return add0x(\n bytesToHex(publicToAddress(hdKey.publicKey, true)).toLowerCase(),\n );\n },\n );\n }\n\n /**\n * Discover and create accounts for the EVM provider.\n *\n * @param opts - The options for the discovery and creation of accounts.\n * @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.\n * @param opts.groupIndex - The index of the group to create the accounts for.\n * @returns The accounts for the EVM provider.\n */\n async discoverAccounts(opts: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n return this.#trace(\n {\n name: TraceName.EvmDiscoverAccounts,\n data: {\n provider: this.getName(),\n },\n },\n async () => {\n const provider = this.getEvmProvider();\n const { entropySource, groupIndex } = opts;\n\n const addressFromGroupIndex = await this.#getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n });\n\n const count = await this.#getTransactionCount(\n provider,\n addressFromGroupIndex,\n );\n if (count === 0) {\n return [];\n }\n\n // We have some activity on this address, we try to create the account.\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n });\n assert(\n addressFromGroupIndex === address,\n 'Created account does not match address from group index.',\n );\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n assertInternalAccountExists(account);\n assertIsBip44Account(account);\n return [account];\n },\n );\n }\n\n async resyncAccounts(): Promise<void> {\n // No-op for the EVM account provider, since keyring accounts are already on\n // the MetaMask side.\n }\n}\n"]}
@@ -12,10 +12,10 @@ export type EvmAccountProviderConfig = {
12
12
  backOffMs: number;
13
13
  };
14
14
  };
15
- export declare const EVM_ACCOUNT_PROVIDER_NAME: "EVM";
15
+ export declare const EVM_ACCOUNT_PROVIDER_NAME = "EVM";
16
16
  export declare class EvmAccountProvider extends BaseBip44AccountProvider {
17
17
  #private;
18
- static NAME: "EVM";
18
+ static NAME: string;
19
19
  constructor(messenger: MultichainAccountServiceMessenger, config?: EvmAccountProviderConfig, trace?: TraceCallback);
20
20
  isAccountCompatible(account: Bip44Account<InternalAccount>): boolean;
21
21
  getName(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"EvmAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,qCAAqC;AAI7D,OAAO,EAGL,wBAAwB,EACzB,uCAAmC;AAIpC,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAkBlE,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,yBAAyB,OAAiB,CAAC;AAExD,qBAAa,kBAAmB,SAAQ,wBAAwB;;IAC9D,MAAM,CAAC,IAAI,QAA6B;gBAOtC,SAAS,EAAE,iCAAiC,EAC5C,MAAM,GAAE,wBAMP,EACD,KAAK,CAAC,EAAE,aAAa;IAOvB,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;IAOpE,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,cAAc,IAAI,QAAQ;IA0CpB,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAyE3C;;;;;;;OAOG;IACG,gBAAgB,CAAC,IAAI,EAAE;QAC3B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IA8CrC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAItC"}
1
+ {"version":3,"file":"EvmAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,qCAAqC;AAI7D,OAAO,EAGL,wBAAwB,EACzB,uCAAmC;AAKpC,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAkBlE,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,qBAAa,kBAAmB,SAAQ,wBAAwB;;IAC9D,MAAM,CAAC,IAAI,SAA6B;gBAOtC,SAAS,EAAE,iCAAiC,EAC5C,MAAM,GAAE,wBAMP,EACD,KAAK,CAAC,EAAE,aAAa;IAOvB,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;IAOpE,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,cAAc,IAAI,QAAQ;IA0CpB,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAqF3C;;;;;;;OAOG;IACG,gBAAgB,CAAC,IAAI,EAAE;QAC3B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IA8CrC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAItC"}
@@ -12,10 +12,10 @@ export type EvmAccountProviderConfig = {
12
12
  backOffMs: number;
13
13
  };
14
14
  };
15
- export declare const EVM_ACCOUNT_PROVIDER_NAME: "EVM";
15
+ export declare const EVM_ACCOUNT_PROVIDER_NAME = "EVM";
16
16
  export declare class EvmAccountProvider extends BaseBip44AccountProvider {
17
17
  #private;
18
- static NAME: "EVM";
18
+ static NAME: string;
19
19
  constructor(messenger: MultichainAccountServiceMessenger, config?: EvmAccountProviderConfig, trace?: TraceCallback);
20
20
  isAccountCompatible(account: Bip44Account<InternalAccount>): boolean;
21
21
  getName(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"EvmAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,qCAAqC;AAI7D,OAAO,EAGL,wBAAwB,EACzB,uCAAmC;AAIpC,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAkBlE,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,yBAAyB,OAAiB,CAAC;AAExD,qBAAa,kBAAmB,SAAQ,wBAAwB;;IAC9D,MAAM,CAAC,IAAI,QAA6B;gBAOtC,SAAS,EAAE,iCAAiC,EAC5C,MAAM,GAAE,wBAMP,EACD,KAAK,CAAC,EAAE,aAAa;IAOvB,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;IAOpE,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,cAAc,IAAI,QAAQ;IA0CpB,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAyE3C;;;;;;;OAOG;IACG,gBAAgB,CAAC,IAAI,EAAE;QAC3B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IA8CrC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAItC"}
1
+ {"version":3,"file":"EvmAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,qCAAqC;AAI7D,OAAO,EAGL,wBAAwB,EACzB,uCAAmC;AAKpC,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAkBlE,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,qBAAa,kBAAmB,SAAQ,wBAAwB;;IAC9D,MAAM,CAAC,IAAI,SAA6B;gBAOtC,SAAS,EAAE,iCAAiC,EAC5C,MAAM,GAAE,wBAMP,EACD,KAAK,CAAC,EAAE,aAAa;IAOvB,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;IAOpE,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,cAAc,IAAI,QAAQ;IA0CpB,cAAc,CAAC,EACnB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAqF3C;;;;;;;OAOG;IACG,gBAAgB,CAAC,IAAI,EAAE;QAC3B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IA8CrC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAItC"}
@@ -13,11 +13,12 @@ var _EvmAccountProvider_instances, _EvmAccountProvider_config, _EvmAccountProvid
13
13
  import { publicToAddress } from "@ethereumjs/util";
14
14
  import { EthAccountType } from "@metamask/keyring-api";
15
15
  import { KeyringTypes } from "@metamask/keyring-controller";
16
- import { add0x, assert, bytesToHex } from "@metamask/utils";
16
+ import { add0x, assert, bytesToHex, isStrictHexString } from "@metamask/utils";
17
17
  import { assertAreBip44Accounts, assertIsBip44Account, BaseBip44AccountProvider } from "./BaseBip44AccountProvider.mjs";
18
18
  import { withRetry, withTimeout } from "./utils.mjs";
19
19
  import { traceFallback } from "../analytics/index.mjs";
20
20
  import { TraceName } from "../constants/traces.mjs";
21
+ import { projectLogger as log, WARNING_PREFIX } from "../logger.mjs";
21
22
  const ETH_MAINNET_CHAIN_ID = '0x1';
22
23
  /**
23
24
  * Asserts an internal account exists.
@@ -133,14 +134,22 @@ _EvmAccountProvider_config = new WeakMap(), _EvmAccountProvider_trace = new Weak
133
134
  });
134
135
  return result;
135
136
  }, _EvmAccountProvider_getTransactionCount = async function _EvmAccountProvider_getTransactionCount(provider, address) {
136
- const countHex = await withRetry(() => withTimeout(provider.request({
137
- method: 'eth_getTransactionCount',
137
+ const method = 'eth_getTransactionCount';
138
+ const response = await withRetry(() => withTimeout(provider.request({
139
+ method,
138
140
  params: [address, 'latest'],
139
141
  }), __classPrivateFieldGet(this, _EvmAccountProvider_config, "f").discovery.timeoutMs), {
140
142
  maxAttempts: __classPrivateFieldGet(this, _EvmAccountProvider_config, "f").discovery.maxAttempts,
141
143
  backOffMs: __classPrivateFieldGet(this, _EvmAccountProvider_config, "f").discovery.backOffMs,
142
144
  });
143
- return parseInt(countHex, 16);
145
+ // Make sure we got the right response format, if not, we fallback to "0x0", to avoid having to deal with `NaN`.
146
+ if (!isStrictHexString(response)) {
147
+ const message = `Received invalid hex response from "${method}" request: ${JSON.stringify(response)}`;
148
+ log(`${WARNING_PREFIX} ${message}`);
149
+ console.warn(message);
150
+ return 0;
151
+ }
152
+ return parseInt(response, 16);
144
153
  }, _EvmAccountProvider_getAddressFromGroupIndex = async function _EvmAccountProvider_getAddressFromGroupIndex({ entropySource, groupIndex, }) {
145
154
  // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state
146
155
  // and compute the derivation here.
@@ -1 +1 @@
1
- {"version":3,"file":"EvmAccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { publicToAddress } from '@ethereumjs/util';\nimport type { Bip44Account } from '@metamask/account-api';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport type { HdKeyring } from '@metamask/eth-hd-keyring';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { EthAccountType } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport type { Provider } from '@metamask/network-controller';\nimport { add0x, assert, bytesToHex } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n assertAreBip44Accounts,\n assertIsBip44Account,\n BaseBip44AccountProvider,\n} from './BaseBip44AccountProvider';\nimport { withRetry, withTimeout } from './utils';\nimport { traceFallback } from '../analytics';\nimport { TraceName } from '../constants/traces';\nimport type { MultichainAccountServiceMessenger } from '../types';\n\nconst ETH_MAINNET_CHAIN_ID = '0x1';\n\n/**\n * Asserts an internal account exists.\n *\n * @param account - The internal account to check.\n * @throws An error if the internal account does not exist.\n */\nfunction assertInternalAccountExists(\n account: InternalAccount | undefined,\n): asserts account is InternalAccount {\n if (!account) {\n throw new Error('Internal account does not exist');\n }\n}\n\nexport type EvmAccountProviderConfig = {\n discovery: {\n maxAttempts: number;\n timeoutMs: number;\n backOffMs: number;\n };\n};\n\nexport const EVM_ACCOUNT_PROVIDER_NAME = 'EVM' as const;\n\nexport class EvmAccountProvider extends BaseBip44AccountProvider {\n static NAME = EVM_ACCOUNT_PROVIDER_NAME;\n\n readonly #config: EvmAccountProviderConfig;\n\n readonly #trace: TraceCallback;\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n config: EvmAccountProviderConfig = {\n discovery: {\n maxAttempts: 3,\n timeoutMs: 500,\n backOffMs: 500,\n },\n },\n trace?: TraceCallback,\n ) {\n super(messenger);\n this.#config = config;\n this.#trace = trace ?? traceFallback;\n }\n\n isAccountCompatible(account: Bip44Account<InternalAccount>): boolean {\n return (\n account.type === EthAccountType.Eoa &&\n account.metadata.keyring.type === (KeyringTypes.hd as string)\n );\n }\n\n getName(): string {\n return EvmAccountProvider.NAME;\n }\n\n /**\n * Get the EVM provider.\n *\n * @returns The EVM provider.\n */\n getEvmProvider(): Provider {\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n ETH_MAINNET_CHAIN_ID,\n );\n const { provider } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return provider;\n }\n\n async #createAccount({\n entropySource,\n groupIndex,\n throwOnGap = false,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n throwOnGap?: boolean;\n }): Promise<[Hex, boolean]> {\n const result = await this.withKeyring<EthKeyring, [Hex, boolean]>(\n { id: entropySource },\n async ({ keyring }) => {\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return [existing[groupIndex], false];\n }\n\n // If the throwOnGap flag is set, we throw an error to prevent index gaps.\n if (throwOnGap && groupIndex !== existing.length) {\n throw new Error('Trying to create too many accounts');\n }\n\n const [added] = await keyring.addAccounts(1);\n return [added, true];\n },\n );\n\n return result;\n }\n\n async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n throwOnGap: true,\n });\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n\n // We MUST have the associated internal account.\n assertInternalAccountExists(account);\n\n const accountsArray = [account];\n assertAreBip44Accounts(accountsArray);\n\n return accountsArray;\n }\n\n async #getTransactionCount(\n provider: Provider,\n address: Hex,\n ): Promise<number> {\n const countHex = await withRetry<Hex>(\n () =>\n withTimeout(\n provider.request({\n method: 'eth_getTransactionCount',\n params: [address, 'latest'],\n }),\n this.#config.discovery.timeoutMs,\n ),\n {\n maxAttempts: this.#config.discovery.maxAttempts,\n backOffMs: this.#config.discovery.backOffMs,\n },\n );\n\n return parseInt(countHex, 16);\n }\n\n async #getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Hex> {\n // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state\n // and compute the derivation here.\n return await this.withKeyring<HdKeyring, Hex>(\n { id: entropySource },\n async ({ keyring }) => {\n // If the account already exist, do not re-derive and just re-use that account.\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return existing[groupIndex];\n }\n\n // If not, then we just \"peek\" the next address to avoid creating the account.\n assert(keyring.root, 'Expected HD keyring.root to be set');\n const hdKey = keyring.root.deriveChild(groupIndex);\n assert(hdKey.publicKey, 'Expected public key to be set');\n\n return add0x(\n bytesToHex(publicToAddress(hdKey.publicKey, true)).toLowerCase(),\n );\n },\n );\n }\n\n /**\n * Discover and create accounts for the EVM provider.\n *\n * @param opts - The options for the discovery and creation of accounts.\n * @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.\n * @param opts.groupIndex - The index of the group to create the accounts for.\n * @returns The accounts for the EVM provider.\n */\n async discoverAccounts(opts: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n return this.#trace(\n {\n name: TraceName.EvmDiscoverAccounts,\n data: {\n provider: this.getName(),\n },\n },\n async () => {\n const provider = this.getEvmProvider();\n const { entropySource, groupIndex } = opts;\n\n const addressFromGroupIndex = await this.#getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n });\n\n const count = await this.#getTransactionCount(\n provider,\n addressFromGroupIndex,\n );\n if (count === 0) {\n return [];\n }\n\n // We have some activity on this address, we try to create the account.\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n });\n assert(\n addressFromGroupIndex === address,\n 'Created account does not match address from group index.',\n );\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n assertInternalAccountExists(account);\n assertIsBip44Account(account);\n return [account];\n },\n );\n }\n\n async resyncAccounts(): Promise<void> {\n // No-op for the EVM account provider, since keyring accounts are already on\n // the MetaMask side.\n }\n}\n"]}
1
+ {"version":3,"file":"EvmAccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { publicToAddress } from '@ethereumjs/util';\nimport type { Bip44Account } from '@metamask/account-api';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport type { HdKeyring } from '@metamask/eth-hd-keyring';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport { EthAccountType } from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport type { Provider } from '@metamask/network-controller';\nimport { add0x, assert, bytesToHex, isStrictHexString } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n assertAreBip44Accounts,\n assertIsBip44Account,\n BaseBip44AccountProvider,\n} from './BaseBip44AccountProvider';\nimport { withRetry, withTimeout } from './utils';\nimport { traceFallback } from '../analytics';\nimport { TraceName } from '../constants/traces';\nimport { projectLogger as log, WARNING_PREFIX } from '../logger';\nimport type { MultichainAccountServiceMessenger } from '../types';\n\nconst ETH_MAINNET_CHAIN_ID = '0x1';\n\n/**\n * Asserts an internal account exists.\n *\n * @param account - The internal account to check.\n * @throws An error if the internal account does not exist.\n */\nfunction assertInternalAccountExists(\n account: InternalAccount | undefined,\n): asserts account is InternalAccount {\n if (!account) {\n throw new Error('Internal account does not exist');\n }\n}\n\nexport type EvmAccountProviderConfig = {\n discovery: {\n maxAttempts: number;\n timeoutMs: number;\n backOffMs: number;\n };\n};\n\nexport const EVM_ACCOUNT_PROVIDER_NAME = 'EVM';\n\nexport class EvmAccountProvider extends BaseBip44AccountProvider {\n static NAME = EVM_ACCOUNT_PROVIDER_NAME;\n\n readonly #config: EvmAccountProviderConfig;\n\n readonly #trace: TraceCallback;\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n config: EvmAccountProviderConfig = {\n discovery: {\n maxAttempts: 3,\n timeoutMs: 500,\n backOffMs: 500,\n },\n },\n trace?: TraceCallback,\n ) {\n super(messenger);\n this.#config = config;\n this.#trace = trace ?? traceFallback;\n }\n\n isAccountCompatible(account: Bip44Account<InternalAccount>): boolean {\n return (\n account.type === EthAccountType.Eoa &&\n account.metadata.keyring.type === (KeyringTypes.hd as string)\n );\n }\n\n getName(): string {\n return EvmAccountProvider.NAME;\n }\n\n /**\n * Get the EVM provider.\n *\n * @returns The EVM provider.\n */\n getEvmProvider(): Provider {\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n ETH_MAINNET_CHAIN_ID,\n );\n const { provider } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return provider;\n }\n\n async #createAccount({\n entropySource,\n groupIndex,\n throwOnGap = false,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n throwOnGap?: boolean;\n }): Promise<[Hex, boolean]> {\n const result = await this.withKeyring<EthKeyring, [Hex, boolean]>(\n { id: entropySource },\n async ({ keyring }) => {\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return [existing[groupIndex], false];\n }\n\n // If the throwOnGap flag is set, we throw an error to prevent index gaps.\n if (throwOnGap && groupIndex !== existing.length) {\n throw new Error('Trying to create too many accounts');\n }\n\n const [added] = await keyring.addAccounts(1);\n return [added, true];\n },\n );\n\n return result;\n }\n\n async createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n throwOnGap: true,\n });\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n\n // We MUST have the associated internal account.\n assertInternalAccountExists(account);\n\n const accountsArray = [account];\n assertAreBip44Accounts(accountsArray);\n\n return accountsArray;\n }\n\n async #getTransactionCount(\n provider: Provider,\n address: Hex,\n ): Promise<number> {\n const method = 'eth_getTransactionCount';\n\n const response = await withRetry(\n () =>\n withTimeout(\n provider.request({\n method,\n params: [address, 'latest'],\n }),\n this.#config.discovery.timeoutMs,\n ),\n {\n maxAttempts: this.#config.discovery.maxAttempts,\n backOffMs: this.#config.discovery.backOffMs,\n },\n );\n\n // Make sure we got the right response format, if not, we fallback to \"0x0\", to avoid having to deal with `NaN`.\n if (!isStrictHexString(response)) {\n const message = `Received invalid hex response from \"${method}\" request: ${JSON.stringify(response)}`;\n\n log(`${WARNING_PREFIX} ${message}`);\n console.warn(message);\n\n return 0;\n }\n\n return parseInt(response, 16);\n }\n\n async #getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Hex> {\n // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state\n // and compute the derivation here.\n return await this.withKeyring<HdKeyring, Hex>(\n { id: entropySource },\n async ({ keyring }) => {\n // If the account already exist, do not re-derive and just re-use that account.\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return existing[groupIndex];\n }\n\n // If not, then we just \"peek\" the next address to avoid creating the account.\n assert(keyring.root, 'Expected HD keyring.root to be set');\n const hdKey = keyring.root.deriveChild(groupIndex);\n assert(hdKey.publicKey, 'Expected public key to be set');\n\n return add0x(\n bytesToHex(publicToAddress(hdKey.publicKey, true)).toLowerCase(),\n );\n },\n );\n }\n\n /**\n * Discover and create accounts for the EVM provider.\n *\n * @param opts - The options for the discovery and creation of accounts.\n * @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.\n * @param opts.groupIndex - The index of the group to create the accounts for.\n * @returns The accounts for the EVM provider.\n */\n async discoverAccounts(opts: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n return this.#trace(\n {\n name: TraceName.EvmDiscoverAccounts,\n data: {\n provider: this.getName(),\n },\n },\n async () => {\n const provider = this.getEvmProvider();\n const { entropySource, groupIndex } = opts;\n\n const addressFromGroupIndex = await this.#getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n });\n\n const count = await this.#getTransactionCount(\n provider,\n addressFromGroupIndex,\n );\n if (count === 0) {\n return [];\n }\n\n // We have some activity on this address, we try to create the account.\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n });\n assert(\n addressFromGroupIndex === address,\n 'Created account does not match address from group index.',\n );\n\n const account = this.messenger.call(\n 'AccountsController:getAccountByAddress',\n address,\n );\n assertInternalAccountExists(account);\n assertIsBip44Account(account);\n return [account];\n },\n );\n }\n\n async resyncAccounts(): Promise<void> {\n // No-op for the EVM account provider, since keyring accounts are already on\n // the MetaMask side.\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/multichain-account-service",
3
- "version": "4.0.0-preview-267e79c3",
3
+ "version": "4.0.1-preview-d717276a",
4
4
  "description": "Service to manage multichain accounts",
5
5
  "keywords": [
6
6
  "MetaMask",