@metamask-previews/multichain-account-service 0.6.0-preview-55f2e41 → 0.6.0-preview-cab2ca5

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/MultichainAccountGroup.cjs.map +1 -1
  3. package/dist/MultichainAccountGroup.d.cts +2 -2
  4. package/dist/MultichainAccountGroup.d.cts.map +1 -1
  5. package/dist/MultichainAccountGroup.d.mts +2 -2
  6. package/dist/MultichainAccountGroup.d.mts.map +1 -1
  7. package/dist/MultichainAccountGroup.mjs.map +1 -1
  8. package/dist/MultichainAccountService.cjs.map +1 -1
  9. package/dist/MultichainAccountService.d.cts +3 -2
  10. package/dist/MultichainAccountService.d.cts.map +1 -1
  11. package/dist/MultichainAccountService.d.mts +3 -2
  12. package/dist/MultichainAccountService.d.mts.map +1 -1
  13. package/dist/MultichainAccountService.mjs.map +1 -1
  14. package/dist/MultichainAccountWallet.cjs +66 -0
  15. package/dist/MultichainAccountWallet.cjs.map +1 -1
  16. package/dist/MultichainAccountWallet.d.cts +14 -2
  17. package/dist/MultichainAccountWallet.d.cts.map +1 -1
  18. package/dist/MultichainAccountWallet.d.mts +14 -2
  19. package/dist/MultichainAccountWallet.d.mts.map +1 -1
  20. package/dist/MultichainAccountWallet.mjs +66 -0
  21. package/dist/MultichainAccountWallet.mjs.map +1 -1
  22. package/dist/providers/AccountProviderWrapper.cjs +3 -0
  23. package/dist/providers/AccountProviderWrapper.cjs.map +1 -1
  24. package/dist/providers/AccountProviderWrapper.d.cts +1 -0
  25. package/dist/providers/AccountProviderWrapper.d.cts.map +1 -1
  26. package/dist/providers/AccountProviderWrapper.d.mts +1 -0
  27. package/dist/providers/AccountProviderWrapper.d.mts.map +1 -1
  28. package/dist/providers/AccountProviderWrapper.mjs +3 -0
  29. package/dist/providers/AccountProviderWrapper.mjs.map +1 -1
  30. package/dist/providers/BaseBip44AccountProvider.cjs.map +1 -1
  31. package/dist/providers/BaseBip44AccountProvider.d.cts +5 -1
  32. package/dist/providers/BaseBip44AccountProvider.d.cts.map +1 -1
  33. package/dist/providers/BaseBip44AccountProvider.d.mts +5 -1
  34. package/dist/providers/BaseBip44AccountProvider.d.mts.map +1 -1
  35. package/dist/providers/BaseBip44AccountProvider.mjs.map +1 -1
  36. package/dist/providers/EvmAccountProvider.cjs +87 -15
  37. package/dist/providers/EvmAccountProvider.cjs.map +1 -1
  38. package/dist/providers/EvmAccountProvider.d.cts +21 -52
  39. package/dist/providers/EvmAccountProvider.d.cts.map +1 -1
  40. package/dist/providers/EvmAccountProvider.d.mts +21 -52
  41. package/dist/providers/EvmAccountProvider.d.mts.map +1 -1
  42. package/dist/providers/EvmAccountProvider.mjs +88 -16
  43. package/dist/providers/EvmAccountProvider.mjs.map +1 -1
  44. package/dist/providers/SolAccountProvider.cjs +62 -21
  45. package/dist/providers/SolAccountProvider.cjs.map +1 -1
  46. package/dist/providers/SolAccountProvider.d.cts +3 -1
  47. package/dist/providers/SolAccountProvider.d.cts.map +1 -1
  48. package/dist/providers/SolAccountProvider.d.mts +3 -1
  49. package/dist/providers/SolAccountProvider.d.mts.map +1 -1
  50. package/dist/providers/SolAccountProvider.mjs +61 -20
  51. package/dist/providers/SolAccountProvider.mjs.map +1 -1
  52. package/dist/tests/accounts.cjs +11 -6
  53. package/dist/tests/accounts.cjs.map +1 -1
  54. package/dist/tests/accounts.d.cts +4 -1
  55. package/dist/tests/accounts.d.cts.map +1 -1
  56. package/dist/tests/accounts.d.mts +4 -1
  57. package/dist/tests/accounts.d.mts.map +1 -1
  58. package/dist/tests/accounts.mjs +6 -1
  59. package/dist/tests/accounts.mjs.map +1 -1
  60. package/dist/tests/messenger.cjs +2 -0
  61. package/dist/tests/messenger.cjs.map +1 -1
  62. package/dist/tests/messenger.d.cts.map +1 -1
  63. package/dist/tests/messenger.d.mts.map +1 -1
  64. package/dist/tests/messenger.mjs +2 -0
  65. package/dist/tests/messenger.mjs.map +1 -1
  66. package/dist/tests/providers.cjs +1 -0
  67. package/dist/tests/providers.cjs.map +1 -1
  68. package/dist/tests/providers.d.cts +1 -0
  69. package/dist/tests/providers.d.cts.map +1 -1
  70. package/dist/tests/providers.d.mts +1 -0
  71. package/dist/tests/providers.d.mts.map +1 -1
  72. package/dist/tests/providers.mjs +1 -0
  73. package/dist/tests/providers.mjs.map +1 -1
  74. package/dist/types.cjs.map +1 -1
  75. package/dist/types.d.cts +2 -1
  76. package/dist/types.d.cts.map +1 -1
  77. package/dist/types.d.mts +2 -1
  78. package/dist/types.d.mts.map +1 -1
  79. package/dist/types.mjs.map +1 -1
  80. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountWallet.cjs","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getGroupIndexFromMultichainAccountGroupId,\n isMultichainAccountGroupId,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport { toDefaultAccountGroupId } from '@metamask/account-api';\nimport { AccountWalletType } from '@metamask/account-api';\nimport type {\n Bip44Account,\n MultichainAccountWalletId,\n MultichainAccountWallet as MultichainAccountWalletDefinition,\n} from '@metamask/account-api';\nimport type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountProvider } from '@metamask/account-api';\nimport {\n type EntropySourceId,\n type KeyringAccount,\n} from '@metamask/keyring-api';\n\nimport { MultichainAccountGroup } from './MultichainAccountGroup';\n\n/**\n * A multichain account wallet that holds multiple multichain accounts (one multichain account per\n * group index).\n */\nexport class MultichainAccountWallet<\n Account extends Bip44Account<KeyringAccount>,\n> implements MultichainAccountWalletDefinition<Account>\n{\n readonly #id: MultichainAccountWalletId;\n\n readonly #providers: AccountProvider<Account>[];\n\n readonly #entropySource: EntropySourceId;\n\n readonly #accountGroups: Map<number, MultichainAccountGroup<Account>>;\n\n #isAlignmentInProgress: boolean = false;\n\n constructor({\n providers,\n entropySource,\n }: {\n providers: AccountProvider<Account>[];\n entropySource: EntropySourceId;\n }) {\n this.#id = toMultichainAccountWalletId(entropySource);\n this.#providers = providers;\n this.#entropySource = entropySource;\n this.#accountGroups = new Map();\n\n // Initial synchronization.\n this.sync();\n }\n\n /**\n * Force wallet synchronization.\n *\n * This can be used if account providers got new accounts that the wallet\n * doesn't know about.\n */\n sync(): void {\n for (const provider of this.#providers) {\n for (const account of provider.getAccounts()) {\n const { entropy } = account.options;\n\n // Filter for this wallet only.\n if (entropy.id !== this.entropySource) {\n continue;\n }\n\n // This multichain account might exists already.\n let multichainAccount = this.#accountGroups.get(entropy.groupIndex);\n if (!multichainAccount) {\n multichainAccount = new MultichainAccountGroup<Account>({\n groupIndex: entropy.groupIndex,\n wallet: this,\n providers: this.#providers,\n });\n\n // This existing multichain account group might differ from the\n // `createMultichainAccountGroup` behavior. When creating a new\n // group, we expect the providers to all succeed. But here, we're\n // just fetching the account lists from them, so this group might\n // not be \"aligned\" yet (e.g having a missing Solana account).\n //\n // Since \"aligning\" is an async operation, it would have to be run\n // after the first-sync.\n // TODO: Implement align mechanism to create \"missing\" accounts.\n\n this.#accountGroups.set(entropy.groupIndex, multichainAccount);\n }\n }\n }\n\n // Now force-sync all remaining multichain accounts.\n for (const [\n groupIndex,\n multichainAccount,\n ] of this.#accountGroups.entries()) {\n multichainAccount.sync();\n\n // Clean up old multichain accounts.\n if (!multichainAccount.hasAccounts()) {\n this.#accountGroups.delete(groupIndex);\n }\n }\n }\n\n /**\n * Gets the multichain account wallet ID.\n *\n * @returns The multichain account wallet ID.\n */\n get id(): MultichainAccountWalletId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account wallet type, which is always {@link AccountWalletType.Entropy}.\n *\n * @returns The multichain account wallet type.\n */\n get type(): AccountWalletType.Entropy {\n return AccountWalletType.Entropy;\n }\n\n /**\n * Gets the multichain account wallet entropy source.\n *\n * @returns The multichain account wallet entropy source.\n */\n get entropySource(): EntropySourceId {\n return this.#entropySource;\n }\n\n /**\n * Gets multichain account for a given ID.\n * The default group ID will default to the multichain account with index 0.\n *\n * @param id - Account group ID.\n * @returns Account group.\n */\n getAccountGroup(\n id: AccountGroupId,\n ): MultichainAccountGroup<Account> | undefined {\n // We consider the \"default case\" to be mapped to index 0.\n if (id === toDefaultAccountGroupId(this.id)) {\n return this.#accountGroups.get(0);\n }\n\n // If it is not a valid ID, we cannot extract the group index\n // from it, so we fail fast.\n if (!isMultichainAccountGroupId(id)) {\n return undefined;\n }\n\n const groupIndex = getGroupIndexFromMultichainAccountGroupId(id);\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain accounts. Similar to {@link MultichainAccountWallet.getMultichainAccountGroups}.\n *\n * @returns The multichain accounts.\n */\n getAccountGroups(): MultichainAccountGroup<Account>[] {\n return this.getMultichainAccountGroups();\n }\n\n /**\n * Gets multichain account group for a given index.\n *\n * @param groupIndex - Multichain account index.\n * @returns The multichain account associated with the given index.\n */\n getMultichainAccountGroup(\n groupIndex: number,\n ): MultichainAccountGroup<Account> | undefined {\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain account groups.\n *\n * @returns The multichain accounts.\n */\n getMultichainAccountGroups(): MultichainAccountGroup<Account>[] {\n return Array.from(this.#accountGroups.values()); // TODO: Prevent copy here.\n }\n\n /**\n * Gets next group index for this wallet.\n *\n * @returns The next group index of this wallet.\n */\n getNextGroupIndex(): number {\n // We do not check for gaps.\n return (\n Math.max(\n -1, // So it will default to 0 if no groups.\n ...this.#accountGroups.keys(),\n ) + 1\n );\n }\n\n /**\n * Creates a multichain account group for a given group index.\n *\n * @param groupIndex - The group index to use.\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup(\n groupIndex: number,\n ): Promise<MultichainAccountGroup<Account>> {\n const nextGroupIndex = this.getNextGroupIndex();\n if (groupIndex > nextGroupIndex) {\n throw new Error(\n `You cannot use a group index that is higher than the next available one: expected <=${nextGroupIndex}, got ${groupIndex}`,\n );\n }\n\n let group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n // If the group already exists, we just `sync` it and returns the same\n // reference.\n group.sync();\n\n return group;\n }\n\n const results = await Promise.allSettled(\n this.#providers.map((provider) =>\n provider.createAccounts({\n entropySource: this.#entropySource,\n groupIndex,\n }),\n ),\n );\n\n // --------------------------------------------------------------------------------\n // READ THIS CAREFULLY:\n //\n // Since we're not \"fully supporting multichain\" for now, we still rely on single\n // :accountCreated events to sync multichain account groups and wallets. Which means\n // that even if of the provider fails, some accounts will still be created on some\n // other providers and will become \"available\" on the `AccountsController`, like:\n //\n // 1. Creating a multichain account group for index 1\n // 2. EvmAccountProvider.createAccounts returns the EVM account for index 1\n // * AccountsController WILL fire :accountCreated for this account\n // * This account WILL BE \"available\" on the AccountsController state\n // 3. SolAccountProvider.createAccounts fails to create a Solana account for index 1\n // * AccountsController WON't fire :accountCreated for this account\n // * This account WON'T be \"available\" on the Account\n // 4. MultichainAccountService will receive a :accountCreated for the EVM account from\n // step 2 and will create a new multichain account group for index 1, but it won't\n // receive any event for the Solana account of this group. Thus, this group won't be\n // \"aligned\" (missing \"blockchain account\" on this group).\n //\n // --------------------------------------------------------------------------------\n\n // If any of the provider failed to create their accounts, then we consider the\n // multichain account group to have failed too.\n if (results.some((result) => result.status === 'rejected')) {\n // NOTE: Some accounts might still have been created on other account providers. We\n // don't rollback them.\n const error = `Unable to create multichain account group for index: ${groupIndex}`;\n\n let warn = `${error}:`;\n for (const result of results) {\n if (result.status === 'rejected') {\n warn += `\\n- ${result.reason}`;\n }\n }\n console.warn(warn);\n\n throw new Error(error);\n }\n\n // Because of the :accountAdded automatic sync, we might already have created the\n // group, so we first try to get it.\n group = this.getMultichainAccountGroup(groupIndex);\n if (!group) {\n // If for some reason it's still not created, we're creating it explicitly now:\n group = new MultichainAccountGroup({\n wallet: this,\n providers: this.#providers,\n groupIndex,\n });\n }\n\n // Register the account to our internal map.\n this.#accountGroups.set(groupIndex, group); // `group` cannot be undefined here.\n\n return group;\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for the next group index available.\n */\n async createNextMultichainAccountGroup(): Promise<\n MultichainAccountGroup<Account>\n > {\n return this.createMultichainAccountGroup(this.getNextGroupIndex());\n }\n\n /**\n * Gets whether alignment is currently in progress for this wallet.\n *\n * @returns True if alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return this.#isAlignmentInProgress;\n }\n\n /**\n * Align all multichain account groups.\n */\n async alignGroups(): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const groups = this.getMultichainAccountGroups();\n await Promise.all(groups.map((g) => g.align()));\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n\n /**\n * Align a specific multichain account group.\n *\n * @param groupIndex - The group index to align.\n */\n async alignGroup(groupIndex: number): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n await group.align();\n }\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"MultichainAccountWallet.cjs","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getGroupIndexFromMultichainAccountGroupId,\n isMultichainAccountGroupId,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport { toDefaultAccountGroupId } from '@metamask/account-api';\nimport { AccountWalletType } from '@metamask/account-api';\nimport type {\n Bip44Account,\n MultichainAccountWalletId,\n MultichainAccountWallet as MultichainAccountWalletDefinition,\n} from '@metamask/account-api';\nimport type { AccountGroupId } from '@metamask/account-api';\nimport {\n type EntropySourceId,\n type KeyringAccount,\n} from '@metamask/keyring-api';\nimport { createProjectLogger } from '@metamask/utils';\n\nimport { MultichainAccountGroup } from './MultichainAccountGroup';\nimport type { NamedAccountProvider } from './providers';\n\n/**\n * The context for a provider discovery.\n */\ntype AccountProviderDiscoveryContext = {\n provider: NamedAccountProvider;\n stopped: boolean;\n groupIndex: number;\n count: number;\n};\n\n/**\n * The metrics resulting from account discovery.\n */\nexport type AccountDiscoveryMetrics = {\n [providerName: string]: number;\n};\n\nconst log = createProjectLogger('multichain-account-service');\n\n/**\n * A multichain account wallet that holds multiple multichain accounts (one multichain account per\n * group index).\n */\nexport class MultichainAccountWallet<\n Account extends Bip44Account<KeyringAccount>,\n> implements MultichainAccountWalletDefinition<Account>\n{\n readonly #id: MultichainAccountWalletId;\n\n readonly #providers: NamedAccountProvider<Account>[];\n\n readonly #entropySource: EntropySourceId;\n\n readonly #accountGroups: Map<number, MultichainAccountGroup<Account>>;\n\n #isAlignmentInProgress: boolean = false;\n\n constructor({\n providers,\n entropySource,\n }: {\n providers: NamedAccountProvider<Account>[];\n entropySource: EntropySourceId;\n }) {\n this.#id = toMultichainAccountWalletId(entropySource);\n this.#providers = providers;\n this.#entropySource = entropySource;\n this.#accountGroups = new Map();\n\n // Initial synchronization.\n this.sync();\n }\n\n /**\n * Force wallet synchronization.\n *\n * This can be used if account providers got new accounts that the wallet\n * doesn't know about.\n */\n sync(): void {\n for (const provider of this.#providers) {\n for (const account of provider.getAccounts()) {\n const { entropy } = account.options;\n\n // Filter for this wallet only.\n if (entropy.id !== this.entropySource) {\n continue;\n }\n\n // This multichain account might exists already.\n let multichainAccount = this.#accountGroups.get(entropy.groupIndex);\n if (!multichainAccount) {\n multichainAccount = new MultichainAccountGroup<Account>({\n groupIndex: entropy.groupIndex,\n wallet: this,\n providers: this.#providers,\n });\n\n // This existing multichain account group might differ from the\n // `createMultichainAccountGroup` behavior. When creating a new\n // group, we expect the providers to all succeed. But here, we're\n // just fetching the account lists from them, so this group might\n // not be \"aligned\" yet (e.g having a missing Solana account).\n //\n // Since \"aligning\" is an async operation, it would have to be run\n // after the first-sync.\n // TODO: Implement align mechanism to create \"missing\" accounts.\n\n this.#accountGroups.set(entropy.groupIndex, multichainAccount);\n }\n }\n }\n\n // Now force-sync all remaining multichain accounts.\n for (const [\n groupIndex,\n multichainAccount,\n ] of this.#accountGroups.entries()) {\n multichainAccount.sync();\n\n // Clean up old multichain accounts.\n if (!multichainAccount.hasAccounts()) {\n this.#accountGroups.delete(groupIndex);\n }\n }\n }\n\n /**\n * Gets the multichain account wallet ID.\n *\n * @returns The multichain account wallet ID.\n */\n get id(): MultichainAccountWalletId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account wallet type, which is always {@link AccountWalletType.Entropy}.\n *\n * @returns The multichain account wallet type.\n */\n get type(): AccountWalletType.Entropy {\n return AccountWalletType.Entropy;\n }\n\n /**\n * Gets the multichain account wallet entropy source.\n *\n * @returns The multichain account wallet entropy source.\n */\n get entropySource(): EntropySourceId {\n return this.#entropySource;\n }\n\n /**\n * Gets multichain account for a given ID.\n * The default group ID will default to the multichain account with index 0.\n *\n * @param id - Account group ID.\n * @returns Account group.\n */\n getAccountGroup(\n id: AccountGroupId,\n ): MultichainAccountGroup<Account> | undefined {\n // We consider the \"default case\" to be mapped to index 0.\n if (id === toDefaultAccountGroupId(this.id)) {\n return this.#accountGroups.get(0);\n }\n\n // If it is not a valid ID, we cannot extract the group index\n // from it, so we fail fast.\n if (!isMultichainAccountGroupId(id)) {\n return undefined;\n }\n\n const groupIndex = getGroupIndexFromMultichainAccountGroupId(id);\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain accounts. Similar to {@link MultichainAccountWallet.getMultichainAccountGroups}.\n *\n * @returns The multichain accounts.\n */\n getAccountGroups(): MultichainAccountGroup<Account>[] {\n return this.getMultichainAccountGroups();\n }\n\n /**\n * Gets multichain account group for a given index.\n *\n * @param groupIndex - Multichain account index.\n * @returns The multichain account associated with the given index.\n */\n getMultichainAccountGroup(\n groupIndex: number,\n ): MultichainAccountGroup<Account> | undefined {\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain account groups.\n *\n * @returns The multichain accounts.\n */\n getMultichainAccountGroups(): MultichainAccountGroup<Account>[] {\n return Array.from(this.#accountGroups.values()); // TODO: Prevent copy here.\n }\n\n /**\n * Gets next group index for this wallet.\n *\n * @returns The next group index of this wallet.\n */\n getNextGroupIndex(): number {\n // We do not check for gaps.\n return (\n Math.max(\n -1, // So it will default to 0 if no groups.\n ...this.#accountGroups.keys(),\n ) + 1\n );\n }\n\n /**\n * Creates a multichain account group for a given group index.\n *\n * @param groupIndex - The group index to use.\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup(\n groupIndex: number,\n ): Promise<MultichainAccountGroup<Account>> {\n const nextGroupIndex = this.getNextGroupIndex();\n if (groupIndex > nextGroupIndex) {\n throw new Error(\n `You cannot use a group index that is higher than the next available one: expected <=${nextGroupIndex}, got ${groupIndex}`,\n );\n }\n\n let group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n // If the group already exists, we just `sync` it and returns the same\n // reference.\n group.sync();\n\n return group;\n }\n\n const results = await Promise.allSettled(\n this.#providers.map((provider) =>\n provider.createAccounts({\n entropySource: this.#entropySource,\n groupIndex,\n }),\n ),\n );\n\n // --------------------------------------------------------------------------------\n // READ THIS CAREFULLY:\n //\n // Since we're not \"fully supporting multichain\" for now, we still rely on single\n // :accountCreated events to sync multichain account groups and wallets. Which means\n // that even if of the provider fails, some accounts will still be created on some\n // other providers and will become \"available\" on the `AccountsController`, like:\n //\n // 1. Creating a multichain account group for index 1\n // 2. EvmAccountProvider.createAccounts returns the EVM account for index 1\n // * AccountsController WILL fire :accountCreated for this account\n // * This account WILL BE \"available\" on the AccountsController state\n // 3. SolAccountProvider.createAccounts fails to create a Solana account for index 1\n // * AccountsController WON't fire :accountCreated for this account\n // * This account WON'T be \"available\" on the Account\n // 4. MultichainAccountService will receive a :accountCreated for the EVM account from\n // step 2 and will create a new multichain account group for index 1, but it won't\n // receive any event for the Solana account of this group. Thus, this group won't be\n // \"aligned\" (missing \"blockchain account\" on this group).\n //\n // --------------------------------------------------------------------------------\n\n // If any of the provider failed to create their accounts, then we consider the\n // multichain account group to have failed too.\n if (results.some((result) => result.status === 'rejected')) {\n // NOTE: Some accounts might still have been created on other account providers. We\n // don't rollback them.\n const error = `Unable to create multichain account group for index: ${groupIndex}`;\n\n let warn = `${error}:`;\n for (const result of results) {\n if (result.status === 'rejected') {\n warn += `\\n- ${result.reason}`;\n }\n }\n console.warn(warn);\n\n throw new Error(error);\n }\n\n // Because of the :accountAdded automatic sync, we might already have created the\n // group, so we first try to get it.\n group = this.getMultichainAccountGroup(groupIndex);\n if (!group) {\n // If for some reason it's still not created, we're creating it explicitly now:\n group = new MultichainAccountGroup({\n wallet: this,\n providers: this.#providers,\n groupIndex,\n });\n }\n\n // Register the account to our internal map.\n this.#accountGroups.set(groupIndex, group); // `group` cannot be undefined here.\n\n return group;\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for the next group index available.\n */\n async createNextMultichainAccountGroup(): Promise<\n MultichainAccountGroup<Account>\n > {\n return this.createMultichainAccountGroup(this.getNextGroupIndex());\n }\n\n /**\n * Gets whether alignment is currently in progress for this wallet.\n *\n * @returns True if alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return this.#isAlignmentInProgress;\n }\n\n /**\n * Align all multichain account groups.\n */\n async alignGroups(): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const groups = this.getMultichainAccountGroups();\n await Promise.all(groups.map((g) => g.align()));\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n\n /**\n * Align a specific multichain account group.\n *\n * @param groupIndex - The group index to align.\n */\n async alignGroup(groupIndex: number): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n await group.align();\n }\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n\n /**\n * Discover and create accounts for all providers.\n *\n * @returns The discovered accounts for each provider.\n */\n async discoverAndCreateAccounts(): Promise<AccountDiscoveryMetrics> {\n // Start with the next available group index (so we can resume the discovery\n // from there).\n let maxGroupIndex = this.getNextGroupIndex();\n\n // One serialized loop per provider; all run concurrently\n const runProviderDiscovery = async (\n context: AccountProviderDiscoveryContext,\n ) => {\n const message = (stepName: string, groupIndex: number) =>\n `[${context.provider.getName()}] Discovery ${stepName} (groupIndex=${groupIndex})`;\n\n while (!context.stopped) {\n // Fast‑forward to current high‑water mark\n const targetGroupIndex = Math.max(context.groupIndex, maxGroupIndex);\n\n log(message('STARTED', targetGroupIndex));\n\n let accounts: Bip44Account<KeyringAccount>[] = [];\n try {\n accounts = await context.provider.discoverAndCreateAccounts({\n entropySource: this.#entropySource,\n groupIndex: targetGroupIndex,\n });\n } catch (error) {\n context.stopped = true;\n console.error(error);\n log(message('FAILED', targetGroupIndex), error);\n break;\n }\n\n if (!accounts.length) {\n log(message('STOPPED', targetGroupIndex));\n context.stopped = true;\n break;\n }\n\n log(message('SUCCEEDED', targetGroupIndex));\n\n context.count += accounts.length;\n\n const nextGroupIndex = targetGroupIndex + 1;\n context.groupIndex = nextGroupIndex;\n\n if (nextGroupIndex > maxGroupIndex) {\n maxGroupIndex = nextGroupIndex;\n }\n }\n };\n\n const providerContexts: AccountProviderDiscoveryContext[] =\n this.#providers.map((provider) => ({\n provider,\n stopped: false,\n groupIndex: maxGroupIndex,\n count: 0,\n }));\n\n // Start discovery for each providers.\n await Promise.all(providerContexts.map(runProviderDiscovery));\n\n // Sync the wallet after discovery to ensure that the newly added accounts are added into their groups.\n // We can potentially remove this if we know that this race condition is not an issue in practice.\n this.sync();\n\n // Align missing accounts from group. This is required to create missing account from non-discovered\n // indexes for some providers.\n await this.alignGroups();\n\n const discoveredAccounts: Record<string, number> = {};\n for (const context of providerContexts) {\n const providerName = context.provider.getName();\n discoveredAccounts[providerName] = context.count;\n }\n\n return discoveredAccounts;\n }\n}\n"]}
@@ -1,9 +1,15 @@
1
1
  import { AccountWalletType } from "@metamask/account-api";
2
2
  import type { Bip44Account, MultichainAccountWalletId, MultichainAccountWallet as MultichainAccountWalletDefinition } from "@metamask/account-api";
3
3
  import type { AccountGroupId } from "@metamask/account-api";
4
- import type { AccountProvider } from "@metamask/account-api";
5
4
  import { type EntropySourceId, type KeyringAccount } from "@metamask/keyring-api";
6
5
  import { MultichainAccountGroup } from "./MultichainAccountGroup.cjs";
6
+ import type { NamedAccountProvider } from "./providers/index.cjs";
7
+ /**
8
+ * The metrics resulting from account discovery.
9
+ */
10
+ export type AccountDiscoveryMetrics = {
11
+ [providerName: string]: number;
12
+ };
7
13
  /**
8
14
  * A multichain account wallet that holds multiple multichain accounts (one multichain account per
9
15
  * group index).
@@ -11,7 +17,7 @@ import { MultichainAccountGroup } from "./MultichainAccountGroup.cjs";
11
17
  export declare class MultichainAccountWallet<Account extends Bip44Account<KeyringAccount>> implements MultichainAccountWalletDefinition<Account> {
12
18
  #private;
13
19
  constructor({ providers, entropySource, }: {
14
- providers: AccountProvider<Account>[];
20
+ providers: NamedAccountProvider<Account>[];
15
21
  entropySource: EntropySourceId;
16
22
  });
17
23
  /**
@@ -103,5 +109,11 @@ export declare class MultichainAccountWallet<Account extends Bip44Account<Keyrin
103
109
  * @param groupIndex - The group index to align.
104
110
  */
105
111
  alignGroup(groupIndex: number): Promise<void>;
112
+ /**
113
+ * Discover and create accounts for all providers.
114
+ *
115
+ * @returns The discovered accounts for each provider.
116
+ */
117
+ discoverAndCreateAccounts(): Promise<AccountDiscoveryMetrics>;
106
118
  }
107
119
  //# sourceMappingURL=MultichainAccountWallet.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountWallet.d.cts","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,IAAI,iCAAiC,EAC7D,8BAA8B;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,8BAA8B;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAC7D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,8BAA8B;AAE/B,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE;;;GAGG;AACH,qBAAa,uBAAuB,CAClC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,CAC5C,YAAW,iCAAiC,CAAC,OAAO,CAAC;;gBAYzC,EACV,SAAS,EACT,aAAa,GACd,EAAE;QACD,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,aAAa,EAAE,eAAe,CAAC;KAChC;IAUD;;;;;OAKG;IACH,IAAI,IAAI,IAAI;IAgDZ;;;;OAIG;IACH,IAAI,EAAE,IAAI,yBAAyB,CAElC;IAED;;;;OAIG;IACH,IAAI,IAAI,IAAI,iBAAiB,CAAC,OAAO,CAEpC;IAED;;;;OAIG;IACH,IAAI,aAAa,IAAI,eAAe,CAEnC;IAED;;;;;;OAMG;IACH,eAAe,CACb,EAAE,EAAE,cAAc,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAgB9C;;;;OAIG;IACH,gBAAgB,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAIrD;;;;;OAKG;IACH,yBAAyB,CACvB,UAAU,EAAE,MAAM,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAI9C;;;;OAIG;IACH,0BAA0B,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAI/D;;;;OAIG;IACH,iBAAiB,IAAI,MAAM;IAU3B;;;;;;OAMG;IACG,4BAA4B,CAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAoF3C;;;;;OAKG;IACG,gCAAgC,IAAI,OAAO,CAC/C,sBAAsB,CAAC,OAAO,CAAC,CAChC;IAID;;;;OAIG;IACH,wBAAwB,IAAI,OAAO;IAInC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAclC;;;;OAIG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAepD"}
1
+ {"version":3,"file":"MultichainAccountWallet.d.cts","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,IAAI,iCAAiC,EAC7D,8BAA8B;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,8BAA8B;AAC5D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,8BAA8B;AAG/B,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,8BAAoB;AAYxD;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC,CAAC;AAIF;;;GAGG;AACH,qBAAa,uBAAuB,CAClC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,CAC5C,YAAW,iCAAiC,CAAC,OAAO,CAAC;;gBAYzC,EACV,SAAS,EACT,aAAa,GACd,EAAE;QACD,SAAS,EAAE,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3C,aAAa,EAAE,eAAe,CAAC;KAChC;IAUD;;;;;OAKG;IACH,IAAI,IAAI,IAAI;IAgDZ;;;;OAIG;IACH,IAAI,EAAE,IAAI,yBAAyB,CAElC;IAED;;;;OAIG;IACH,IAAI,IAAI,IAAI,iBAAiB,CAAC,OAAO,CAEpC;IAED;;;;OAIG;IACH,IAAI,aAAa,IAAI,eAAe,CAEnC;IAED;;;;;;OAMG;IACH,eAAe,CACb,EAAE,EAAE,cAAc,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAgB9C;;;;OAIG;IACH,gBAAgB,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAIrD;;;;;OAKG;IACH,yBAAyB,CACvB,UAAU,EAAE,MAAM,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAI9C;;;;OAIG;IACH,0BAA0B,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAI/D;;;;OAIG;IACH,iBAAiB,IAAI,MAAM;IAU3B;;;;;;OAMG;IACG,4BAA4B,CAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAoF3C;;;;;OAKG;IACG,gCAAgC,IAAI,OAAO,CAC/C,sBAAsB,CAAC,OAAO,CAAC,CAChC;IAID;;;;OAIG;IACH,wBAAwB,IAAI,OAAO;IAInC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAclC;;;;OAIG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnD;;;;OAIG;IACG,yBAAyB,IAAI,OAAO,CAAC,uBAAuB,CAAC;CA6EpE"}
@@ -1,9 +1,15 @@
1
1
  import { AccountWalletType } from "@metamask/account-api";
2
2
  import type { Bip44Account, MultichainAccountWalletId, MultichainAccountWallet as MultichainAccountWalletDefinition } from "@metamask/account-api";
3
3
  import type { AccountGroupId } from "@metamask/account-api";
4
- import type { AccountProvider } from "@metamask/account-api";
5
4
  import { type EntropySourceId, type KeyringAccount } from "@metamask/keyring-api";
6
5
  import { MultichainAccountGroup } from "./MultichainAccountGroup.mjs";
6
+ import type { NamedAccountProvider } from "./providers/index.mjs";
7
+ /**
8
+ * The metrics resulting from account discovery.
9
+ */
10
+ export type AccountDiscoveryMetrics = {
11
+ [providerName: string]: number;
12
+ };
7
13
  /**
8
14
  * A multichain account wallet that holds multiple multichain accounts (one multichain account per
9
15
  * group index).
@@ -11,7 +17,7 @@ import { MultichainAccountGroup } from "./MultichainAccountGroup.mjs";
11
17
  export declare class MultichainAccountWallet<Account extends Bip44Account<KeyringAccount>> implements MultichainAccountWalletDefinition<Account> {
12
18
  #private;
13
19
  constructor({ providers, entropySource, }: {
14
- providers: AccountProvider<Account>[];
20
+ providers: NamedAccountProvider<Account>[];
15
21
  entropySource: EntropySourceId;
16
22
  });
17
23
  /**
@@ -103,5 +109,11 @@ export declare class MultichainAccountWallet<Account extends Bip44Account<Keyrin
103
109
  * @param groupIndex - The group index to align.
104
110
  */
105
111
  alignGroup(groupIndex: number): Promise<void>;
112
+ /**
113
+ * Discover and create accounts for all providers.
114
+ *
115
+ * @returns The discovered accounts for each provider.
116
+ */
117
+ discoverAndCreateAccounts(): Promise<AccountDiscoveryMetrics>;
106
118
  }
107
119
  //# sourceMappingURL=MultichainAccountWallet.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountWallet.d.mts","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,IAAI,iCAAiC,EAC7D,8BAA8B;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,8BAA8B;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAC7D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,8BAA8B;AAE/B,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE;;;GAGG;AACH,qBAAa,uBAAuB,CAClC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,CAC5C,YAAW,iCAAiC,CAAC,OAAO,CAAC;;gBAYzC,EACV,SAAS,EACT,aAAa,GACd,EAAE;QACD,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,aAAa,EAAE,eAAe,CAAC;KAChC;IAUD;;;;;OAKG;IACH,IAAI,IAAI,IAAI;IAgDZ;;;;OAIG;IACH,IAAI,EAAE,IAAI,yBAAyB,CAElC;IAED;;;;OAIG;IACH,IAAI,IAAI,IAAI,iBAAiB,CAAC,OAAO,CAEpC;IAED;;;;OAIG;IACH,IAAI,aAAa,IAAI,eAAe,CAEnC;IAED;;;;;;OAMG;IACH,eAAe,CACb,EAAE,EAAE,cAAc,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAgB9C;;;;OAIG;IACH,gBAAgB,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAIrD;;;;;OAKG;IACH,yBAAyB,CACvB,UAAU,EAAE,MAAM,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAI9C;;;;OAIG;IACH,0BAA0B,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAI/D;;;;OAIG;IACH,iBAAiB,IAAI,MAAM;IAU3B;;;;;;OAMG;IACG,4BAA4B,CAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAoF3C;;;;;OAKG;IACG,gCAAgC,IAAI,OAAO,CAC/C,sBAAsB,CAAC,OAAO,CAAC,CAChC;IAID;;;;OAIG;IACH,wBAAwB,IAAI,OAAO;IAInC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAclC;;;;OAIG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAepD"}
1
+ {"version":3,"file":"MultichainAccountWallet.d.mts","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,IAAI,iCAAiC,EAC7D,8BAA8B;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,8BAA8B;AAC5D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,8BAA8B;AAG/B,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,8BAAoB;AAYxD;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC,CAAC;AAIF;;;GAGG;AACH,qBAAa,uBAAuB,CAClC,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,CAC5C,YAAW,iCAAiC,CAAC,OAAO,CAAC;;gBAYzC,EACV,SAAS,EACT,aAAa,GACd,EAAE;QACD,SAAS,EAAE,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3C,aAAa,EAAE,eAAe,CAAC;KAChC;IAUD;;;;;OAKG;IACH,IAAI,IAAI,IAAI;IAgDZ;;;;OAIG;IACH,IAAI,EAAE,IAAI,yBAAyB,CAElC;IAED;;;;OAIG;IACH,IAAI,IAAI,IAAI,iBAAiB,CAAC,OAAO,CAEpC;IAED;;;;OAIG;IACH,IAAI,aAAa,IAAI,eAAe,CAEnC;IAED;;;;;;OAMG;IACH,eAAe,CACb,EAAE,EAAE,cAAc,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAgB9C;;;;OAIG;IACH,gBAAgB,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAIrD;;;;;OAKG;IACH,yBAAyB,CACvB,UAAU,EAAE,MAAM,GACjB,sBAAsB,CAAC,OAAO,CAAC,GAAG,SAAS;IAI9C;;;;OAIG;IACH,0BAA0B,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAI/D;;;;OAIG;IACH,iBAAiB,IAAI,MAAM;IAU3B;;;;;;OAMG;IACG,4BAA4B,CAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAoF3C;;;;;OAKG;IACG,gCAAgC,IAAI,OAAO,CAC/C,sBAAsB,CAAC,OAAO,CAAC,CAChC;IAID;;;;OAIG;IACH,wBAAwB,IAAI,OAAO;IAInC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAclC;;;;OAIG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnD;;;;OAIG;IACG,yBAAyB,IAAI,OAAO,CAAC,uBAAuB,CAAC;CA6EpE"}
@@ -13,7 +13,9 @@ var _MultichainAccountWallet_id, _MultichainAccountWallet_providers, _Multichain
13
13
  import { getGroupIndexFromMultichainAccountGroupId, isMultichainAccountGroupId, toMultichainAccountWalletId } from "@metamask/account-api";
14
14
  import { toDefaultAccountGroupId } from "@metamask/account-api";
15
15
  import { AccountWalletType } from "@metamask/account-api";
16
+ import { createProjectLogger } from "@metamask/utils";
16
17
  import { MultichainAccountGroup } from "./MultichainAccountGroup.mjs";
18
+ const log = createProjectLogger('multichain-account-service');
17
19
  /**
18
20
  * A multichain account wallet that holds multiple multichain accounts (one multichain account per
19
21
  * group index).
@@ -282,6 +284,70 @@ export class MultichainAccountWallet {
282
284
  __classPrivateFieldSet(this, _MultichainAccountWallet_isAlignmentInProgress, false, "f");
283
285
  }
284
286
  }
287
+ /**
288
+ * Discover and create accounts for all providers.
289
+ *
290
+ * @returns The discovered accounts for each provider.
291
+ */
292
+ async discoverAndCreateAccounts() {
293
+ // Start with the next available group index (so we can resume the discovery
294
+ // from there).
295
+ let maxGroupIndex = this.getNextGroupIndex();
296
+ // One serialized loop per provider; all run concurrently
297
+ const runProviderDiscovery = async (context) => {
298
+ const message = (stepName, groupIndex) => `[${context.provider.getName()}] Discovery ${stepName} (groupIndex=${groupIndex})`;
299
+ while (!context.stopped) {
300
+ // Fast‑forward to current high‑water mark
301
+ const targetGroupIndex = Math.max(context.groupIndex, maxGroupIndex);
302
+ log(message('STARTED', targetGroupIndex));
303
+ let accounts = [];
304
+ try {
305
+ accounts = await context.provider.discoverAndCreateAccounts({
306
+ entropySource: __classPrivateFieldGet(this, _MultichainAccountWallet_entropySource, "f"),
307
+ groupIndex: targetGroupIndex,
308
+ });
309
+ }
310
+ catch (error) {
311
+ context.stopped = true;
312
+ console.error(error);
313
+ log(message('FAILED', targetGroupIndex), error);
314
+ break;
315
+ }
316
+ if (!accounts.length) {
317
+ log(message('STOPPED', targetGroupIndex));
318
+ context.stopped = true;
319
+ break;
320
+ }
321
+ log(message('SUCCEEDED', targetGroupIndex));
322
+ context.count += accounts.length;
323
+ const nextGroupIndex = targetGroupIndex + 1;
324
+ context.groupIndex = nextGroupIndex;
325
+ if (nextGroupIndex > maxGroupIndex) {
326
+ maxGroupIndex = nextGroupIndex;
327
+ }
328
+ }
329
+ };
330
+ const providerContexts = __classPrivateFieldGet(this, _MultichainAccountWallet_providers, "f").map((provider) => ({
331
+ provider,
332
+ stopped: false,
333
+ groupIndex: maxGroupIndex,
334
+ count: 0,
335
+ }));
336
+ // Start discovery for each providers.
337
+ await Promise.all(providerContexts.map(runProviderDiscovery));
338
+ // Sync the wallet after discovery to ensure that the newly added accounts are added into their groups.
339
+ // We can potentially remove this if we know that this race condition is not an issue in practice.
340
+ this.sync();
341
+ // Align missing accounts from group. This is required to create missing account from non-discovered
342
+ // indexes for some providers.
343
+ await this.alignGroups();
344
+ const discoveredAccounts = {};
345
+ for (const context of providerContexts) {
346
+ const providerName = context.provider.getName();
347
+ discoveredAccounts[providerName] = context.count;
348
+ }
349
+ return discoveredAccounts;
350
+ }
285
351
  }
286
352
  _MultichainAccountWallet_id = new WeakMap(), _MultichainAccountWallet_providers = new WeakMap(), _MultichainAccountWallet_entropySource = new WeakMap(), _MultichainAccountWallet_accountGroups = new WeakMap(), _MultichainAccountWallet_isAlignmentInProgress = new WeakMap();
287
353
  //# sourceMappingURL=MultichainAccountWallet.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultichainAccountWallet.mjs","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getGroupIndexFromMultichainAccountGroupId,\n isMultichainAccountGroupId,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport { toDefaultAccountGroupId } from '@metamask/account-api';\nimport { AccountWalletType } from '@metamask/account-api';\nimport type {\n Bip44Account,\n MultichainAccountWalletId,\n MultichainAccountWallet as MultichainAccountWalletDefinition,\n} from '@metamask/account-api';\nimport type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountProvider } from '@metamask/account-api';\nimport {\n type EntropySourceId,\n type KeyringAccount,\n} from '@metamask/keyring-api';\n\nimport { MultichainAccountGroup } from './MultichainAccountGroup';\n\n/**\n * A multichain account wallet that holds multiple multichain accounts (one multichain account per\n * group index).\n */\nexport class MultichainAccountWallet<\n Account extends Bip44Account<KeyringAccount>,\n> implements MultichainAccountWalletDefinition<Account>\n{\n readonly #id: MultichainAccountWalletId;\n\n readonly #providers: AccountProvider<Account>[];\n\n readonly #entropySource: EntropySourceId;\n\n readonly #accountGroups: Map<number, MultichainAccountGroup<Account>>;\n\n #isAlignmentInProgress: boolean = false;\n\n constructor({\n providers,\n entropySource,\n }: {\n providers: AccountProvider<Account>[];\n entropySource: EntropySourceId;\n }) {\n this.#id = toMultichainAccountWalletId(entropySource);\n this.#providers = providers;\n this.#entropySource = entropySource;\n this.#accountGroups = new Map();\n\n // Initial synchronization.\n this.sync();\n }\n\n /**\n * Force wallet synchronization.\n *\n * This can be used if account providers got new accounts that the wallet\n * doesn't know about.\n */\n sync(): void {\n for (const provider of this.#providers) {\n for (const account of provider.getAccounts()) {\n const { entropy } = account.options;\n\n // Filter for this wallet only.\n if (entropy.id !== this.entropySource) {\n continue;\n }\n\n // This multichain account might exists already.\n let multichainAccount = this.#accountGroups.get(entropy.groupIndex);\n if (!multichainAccount) {\n multichainAccount = new MultichainAccountGroup<Account>({\n groupIndex: entropy.groupIndex,\n wallet: this,\n providers: this.#providers,\n });\n\n // This existing multichain account group might differ from the\n // `createMultichainAccountGroup` behavior. When creating a new\n // group, we expect the providers to all succeed. But here, we're\n // just fetching the account lists from them, so this group might\n // not be \"aligned\" yet (e.g having a missing Solana account).\n //\n // Since \"aligning\" is an async operation, it would have to be run\n // after the first-sync.\n // TODO: Implement align mechanism to create \"missing\" accounts.\n\n this.#accountGroups.set(entropy.groupIndex, multichainAccount);\n }\n }\n }\n\n // Now force-sync all remaining multichain accounts.\n for (const [\n groupIndex,\n multichainAccount,\n ] of this.#accountGroups.entries()) {\n multichainAccount.sync();\n\n // Clean up old multichain accounts.\n if (!multichainAccount.hasAccounts()) {\n this.#accountGroups.delete(groupIndex);\n }\n }\n }\n\n /**\n * Gets the multichain account wallet ID.\n *\n * @returns The multichain account wallet ID.\n */\n get id(): MultichainAccountWalletId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account wallet type, which is always {@link AccountWalletType.Entropy}.\n *\n * @returns The multichain account wallet type.\n */\n get type(): AccountWalletType.Entropy {\n return AccountWalletType.Entropy;\n }\n\n /**\n * Gets the multichain account wallet entropy source.\n *\n * @returns The multichain account wallet entropy source.\n */\n get entropySource(): EntropySourceId {\n return this.#entropySource;\n }\n\n /**\n * Gets multichain account for a given ID.\n * The default group ID will default to the multichain account with index 0.\n *\n * @param id - Account group ID.\n * @returns Account group.\n */\n getAccountGroup(\n id: AccountGroupId,\n ): MultichainAccountGroup<Account> | undefined {\n // We consider the \"default case\" to be mapped to index 0.\n if (id === toDefaultAccountGroupId(this.id)) {\n return this.#accountGroups.get(0);\n }\n\n // If it is not a valid ID, we cannot extract the group index\n // from it, so we fail fast.\n if (!isMultichainAccountGroupId(id)) {\n return undefined;\n }\n\n const groupIndex = getGroupIndexFromMultichainAccountGroupId(id);\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain accounts. Similar to {@link MultichainAccountWallet.getMultichainAccountGroups}.\n *\n * @returns The multichain accounts.\n */\n getAccountGroups(): MultichainAccountGroup<Account>[] {\n return this.getMultichainAccountGroups();\n }\n\n /**\n * Gets multichain account group for a given index.\n *\n * @param groupIndex - Multichain account index.\n * @returns The multichain account associated with the given index.\n */\n getMultichainAccountGroup(\n groupIndex: number,\n ): MultichainAccountGroup<Account> | undefined {\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain account groups.\n *\n * @returns The multichain accounts.\n */\n getMultichainAccountGroups(): MultichainAccountGroup<Account>[] {\n return Array.from(this.#accountGroups.values()); // TODO: Prevent copy here.\n }\n\n /**\n * Gets next group index for this wallet.\n *\n * @returns The next group index of this wallet.\n */\n getNextGroupIndex(): number {\n // We do not check for gaps.\n return (\n Math.max(\n -1, // So it will default to 0 if no groups.\n ...this.#accountGroups.keys(),\n ) + 1\n );\n }\n\n /**\n * Creates a multichain account group for a given group index.\n *\n * @param groupIndex - The group index to use.\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup(\n groupIndex: number,\n ): Promise<MultichainAccountGroup<Account>> {\n const nextGroupIndex = this.getNextGroupIndex();\n if (groupIndex > nextGroupIndex) {\n throw new Error(\n `You cannot use a group index that is higher than the next available one: expected <=${nextGroupIndex}, got ${groupIndex}`,\n );\n }\n\n let group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n // If the group already exists, we just `sync` it and returns the same\n // reference.\n group.sync();\n\n return group;\n }\n\n const results = await Promise.allSettled(\n this.#providers.map((provider) =>\n provider.createAccounts({\n entropySource: this.#entropySource,\n groupIndex,\n }),\n ),\n );\n\n // --------------------------------------------------------------------------------\n // READ THIS CAREFULLY:\n //\n // Since we're not \"fully supporting multichain\" for now, we still rely on single\n // :accountCreated events to sync multichain account groups and wallets. Which means\n // that even if of the provider fails, some accounts will still be created on some\n // other providers and will become \"available\" on the `AccountsController`, like:\n //\n // 1. Creating a multichain account group for index 1\n // 2. EvmAccountProvider.createAccounts returns the EVM account for index 1\n // * AccountsController WILL fire :accountCreated for this account\n // * This account WILL BE \"available\" on the AccountsController state\n // 3. SolAccountProvider.createAccounts fails to create a Solana account for index 1\n // * AccountsController WON't fire :accountCreated for this account\n // * This account WON'T be \"available\" on the Account\n // 4. MultichainAccountService will receive a :accountCreated for the EVM account from\n // step 2 and will create a new multichain account group for index 1, but it won't\n // receive any event for the Solana account of this group. Thus, this group won't be\n // \"aligned\" (missing \"blockchain account\" on this group).\n //\n // --------------------------------------------------------------------------------\n\n // If any of the provider failed to create their accounts, then we consider the\n // multichain account group to have failed too.\n if (results.some((result) => result.status === 'rejected')) {\n // NOTE: Some accounts might still have been created on other account providers. We\n // don't rollback them.\n const error = `Unable to create multichain account group for index: ${groupIndex}`;\n\n let warn = `${error}:`;\n for (const result of results) {\n if (result.status === 'rejected') {\n warn += `\\n- ${result.reason}`;\n }\n }\n console.warn(warn);\n\n throw new Error(error);\n }\n\n // Because of the :accountAdded automatic sync, we might already have created the\n // group, so we first try to get it.\n group = this.getMultichainAccountGroup(groupIndex);\n if (!group) {\n // If for some reason it's still not created, we're creating it explicitly now:\n group = new MultichainAccountGroup({\n wallet: this,\n providers: this.#providers,\n groupIndex,\n });\n }\n\n // Register the account to our internal map.\n this.#accountGroups.set(groupIndex, group); // `group` cannot be undefined here.\n\n return group;\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for the next group index available.\n */\n async createNextMultichainAccountGroup(): Promise<\n MultichainAccountGroup<Account>\n > {\n return this.createMultichainAccountGroup(this.getNextGroupIndex());\n }\n\n /**\n * Gets whether alignment is currently in progress for this wallet.\n *\n * @returns True if alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return this.#isAlignmentInProgress;\n }\n\n /**\n * Align all multichain account groups.\n */\n async alignGroups(): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const groups = this.getMultichainAccountGroups();\n await Promise.all(groups.map((g) => g.align()));\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n\n /**\n * Align a specific multichain account group.\n *\n * @param groupIndex - The group index to align.\n */\n async alignGroup(groupIndex: number): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n await group.align();\n }\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"MultichainAccountWallet.mjs","sourceRoot":"","sources":["../src/MultichainAccountWallet.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getGroupIndexFromMultichainAccountGroupId,\n isMultichainAccountGroupId,\n toMultichainAccountWalletId,\n} from '@metamask/account-api';\nimport { toDefaultAccountGroupId } from '@metamask/account-api';\nimport { AccountWalletType } from '@metamask/account-api';\nimport type {\n Bip44Account,\n MultichainAccountWalletId,\n MultichainAccountWallet as MultichainAccountWalletDefinition,\n} from '@metamask/account-api';\nimport type { AccountGroupId } from '@metamask/account-api';\nimport {\n type EntropySourceId,\n type KeyringAccount,\n} from '@metamask/keyring-api';\nimport { createProjectLogger } from '@metamask/utils';\n\nimport { MultichainAccountGroup } from './MultichainAccountGroup';\nimport type { NamedAccountProvider } from './providers';\n\n/**\n * The context for a provider discovery.\n */\ntype AccountProviderDiscoveryContext = {\n provider: NamedAccountProvider;\n stopped: boolean;\n groupIndex: number;\n count: number;\n};\n\n/**\n * The metrics resulting from account discovery.\n */\nexport type AccountDiscoveryMetrics = {\n [providerName: string]: number;\n};\n\nconst log = createProjectLogger('multichain-account-service');\n\n/**\n * A multichain account wallet that holds multiple multichain accounts (one multichain account per\n * group index).\n */\nexport class MultichainAccountWallet<\n Account extends Bip44Account<KeyringAccount>,\n> implements MultichainAccountWalletDefinition<Account>\n{\n readonly #id: MultichainAccountWalletId;\n\n readonly #providers: NamedAccountProvider<Account>[];\n\n readonly #entropySource: EntropySourceId;\n\n readonly #accountGroups: Map<number, MultichainAccountGroup<Account>>;\n\n #isAlignmentInProgress: boolean = false;\n\n constructor({\n providers,\n entropySource,\n }: {\n providers: NamedAccountProvider<Account>[];\n entropySource: EntropySourceId;\n }) {\n this.#id = toMultichainAccountWalletId(entropySource);\n this.#providers = providers;\n this.#entropySource = entropySource;\n this.#accountGroups = new Map();\n\n // Initial synchronization.\n this.sync();\n }\n\n /**\n * Force wallet synchronization.\n *\n * This can be used if account providers got new accounts that the wallet\n * doesn't know about.\n */\n sync(): void {\n for (const provider of this.#providers) {\n for (const account of provider.getAccounts()) {\n const { entropy } = account.options;\n\n // Filter for this wallet only.\n if (entropy.id !== this.entropySource) {\n continue;\n }\n\n // This multichain account might exists already.\n let multichainAccount = this.#accountGroups.get(entropy.groupIndex);\n if (!multichainAccount) {\n multichainAccount = new MultichainAccountGroup<Account>({\n groupIndex: entropy.groupIndex,\n wallet: this,\n providers: this.#providers,\n });\n\n // This existing multichain account group might differ from the\n // `createMultichainAccountGroup` behavior. When creating a new\n // group, we expect the providers to all succeed. But here, we're\n // just fetching the account lists from them, so this group might\n // not be \"aligned\" yet (e.g having a missing Solana account).\n //\n // Since \"aligning\" is an async operation, it would have to be run\n // after the first-sync.\n // TODO: Implement align mechanism to create \"missing\" accounts.\n\n this.#accountGroups.set(entropy.groupIndex, multichainAccount);\n }\n }\n }\n\n // Now force-sync all remaining multichain accounts.\n for (const [\n groupIndex,\n multichainAccount,\n ] of this.#accountGroups.entries()) {\n multichainAccount.sync();\n\n // Clean up old multichain accounts.\n if (!multichainAccount.hasAccounts()) {\n this.#accountGroups.delete(groupIndex);\n }\n }\n }\n\n /**\n * Gets the multichain account wallet ID.\n *\n * @returns The multichain account wallet ID.\n */\n get id(): MultichainAccountWalletId {\n return this.#id;\n }\n\n /**\n * Gets the multichain account wallet type, which is always {@link AccountWalletType.Entropy}.\n *\n * @returns The multichain account wallet type.\n */\n get type(): AccountWalletType.Entropy {\n return AccountWalletType.Entropy;\n }\n\n /**\n * Gets the multichain account wallet entropy source.\n *\n * @returns The multichain account wallet entropy source.\n */\n get entropySource(): EntropySourceId {\n return this.#entropySource;\n }\n\n /**\n * Gets multichain account for a given ID.\n * The default group ID will default to the multichain account with index 0.\n *\n * @param id - Account group ID.\n * @returns Account group.\n */\n getAccountGroup(\n id: AccountGroupId,\n ): MultichainAccountGroup<Account> | undefined {\n // We consider the \"default case\" to be mapped to index 0.\n if (id === toDefaultAccountGroupId(this.id)) {\n return this.#accountGroups.get(0);\n }\n\n // If it is not a valid ID, we cannot extract the group index\n // from it, so we fail fast.\n if (!isMultichainAccountGroupId(id)) {\n return undefined;\n }\n\n const groupIndex = getGroupIndexFromMultichainAccountGroupId(id);\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain accounts. Similar to {@link MultichainAccountWallet.getMultichainAccountGroups}.\n *\n * @returns The multichain accounts.\n */\n getAccountGroups(): MultichainAccountGroup<Account>[] {\n return this.getMultichainAccountGroups();\n }\n\n /**\n * Gets multichain account group for a given index.\n *\n * @param groupIndex - Multichain account index.\n * @returns The multichain account associated with the given index.\n */\n getMultichainAccountGroup(\n groupIndex: number,\n ): MultichainAccountGroup<Account> | undefined {\n return this.#accountGroups.get(groupIndex);\n }\n\n /**\n * Gets all multichain account groups.\n *\n * @returns The multichain accounts.\n */\n getMultichainAccountGroups(): MultichainAccountGroup<Account>[] {\n return Array.from(this.#accountGroups.values()); // TODO: Prevent copy here.\n }\n\n /**\n * Gets next group index for this wallet.\n *\n * @returns The next group index of this wallet.\n */\n getNextGroupIndex(): number {\n // We do not check for gaps.\n return (\n Math.max(\n -1, // So it will default to 0 if no groups.\n ...this.#accountGroups.keys(),\n ) + 1\n );\n }\n\n /**\n * Creates a multichain account group for a given group index.\n *\n * @param groupIndex - The group index to use.\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for this group index.\n */\n async createMultichainAccountGroup(\n groupIndex: number,\n ): Promise<MultichainAccountGroup<Account>> {\n const nextGroupIndex = this.getNextGroupIndex();\n if (groupIndex > nextGroupIndex) {\n throw new Error(\n `You cannot use a group index that is higher than the next available one: expected <=${nextGroupIndex}, got ${groupIndex}`,\n );\n }\n\n let group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n // If the group already exists, we just `sync` it and returns the same\n // reference.\n group.sync();\n\n return group;\n }\n\n const results = await Promise.allSettled(\n this.#providers.map((provider) =>\n provider.createAccounts({\n entropySource: this.#entropySource,\n groupIndex,\n }),\n ),\n );\n\n // --------------------------------------------------------------------------------\n // READ THIS CAREFULLY:\n //\n // Since we're not \"fully supporting multichain\" for now, we still rely on single\n // :accountCreated events to sync multichain account groups and wallets. Which means\n // that even if of the provider fails, some accounts will still be created on some\n // other providers and will become \"available\" on the `AccountsController`, like:\n //\n // 1. Creating a multichain account group for index 1\n // 2. EvmAccountProvider.createAccounts returns the EVM account for index 1\n // * AccountsController WILL fire :accountCreated for this account\n // * This account WILL BE \"available\" on the AccountsController state\n // 3. SolAccountProvider.createAccounts fails to create a Solana account for index 1\n // * AccountsController WON't fire :accountCreated for this account\n // * This account WON'T be \"available\" on the Account\n // 4. MultichainAccountService will receive a :accountCreated for the EVM account from\n // step 2 and will create a new multichain account group for index 1, but it won't\n // receive any event for the Solana account of this group. Thus, this group won't be\n // \"aligned\" (missing \"blockchain account\" on this group).\n //\n // --------------------------------------------------------------------------------\n\n // If any of the provider failed to create their accounts, then we consider the\n // multichain account group to have failed too.\n if (results.some((result) => result.status === 'rejected')) {\n // NOTE: Some accounts might still have been created on other account providers. We\n // don't rollback them.\n const error = `Unable to create multichain account group for index: ${groupIndex}`;\n\n let warn = `${error}:`;\n for (const result of results) {\n if (result.status === 'rejected') {\n warn += `\\n- ${result.reason}`;\n }\n }\n console.warn(warn);\n\n throw new Error(error);\n }\n\n // Because of the :accountAdded automatic sync, we might already have created the\n // group, so we first try to get it.\n group = this.getMultichainAccountGroup(groupIndex);\n if (!group) {\n // If for some reason it's still not created, we're creating it explicitly now:\n group = new MultichainAccountGroup({\n wallet: this,\n providers: this.#providers,\n groupIndex,\n });\n }\n\n // Register the account to our internal map.\n this.#accountGroups.set(groupIndex, group); // `group` cannot be undefined here.\n\n return group;\n }\n\n /**\n * Creates the next multichain account group.\n *\n * @throws If any of the account providers fails to create their accounts.\n * @returns The multichain account group for the next group index available.\n */\n async createNextMultichainAccountGroup(): Promise<\n MultichainAccountGroup<Account>\n > {\n return this.createMultichainAccountGroup(this.getNextGroupIndex());\n }\n\n /**\n * Gets whether alignment is currently in progress for this wallet.\n *\n * @returns True if alignment is in progress, false otherwise.\n */\n getIsAlignmentInProgress(): boolean {\n return this.#isAlignmentInProgress;\n }\n\n /**\n * Align all multichain account groups.\n */\n async alignGroups(): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const groups = this.getMultichainAccountGroups();\n await Promise.all(groups.map((g) => g.align()));\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n\n /**\n * Align a specific multichain account group.\n *\n * @param groupIndex - The group index to align.\n */\n async alignGroup(groupIndex: number): Promise<void> {\n if (this.#isAlignmentInProgress) {\n return; // Prevent concurrent alignments\n }\n\n this.#isAlignmentInProgress = true;\n try {\n const group = this.getMultichainAccountGroup(groupIndex);\n if (group) {\n await group.align();\n }\n } finally {\n this.#isAlignmentInProgress = false;\n }\n }\n\n /**\n * Discover and create accounts for all providers.\n *\n * @returns The discovered accounts for each provider.\n */\n async discoverAndCreateAccounts(): Promise<AccountDiscoveryMetrics> {\n // Start with the next available group index (so we can resume the discovery\n // from there).\n let maxGroupIndex = this.getNextGroupIndex();\n\n // One serialized loop per provider; all run concurrently\n const runProviderDiscovery = async (\n context: AccountProviderDiscoveryContext,\n ) => {\n const message = (stepName: string, groupIndex: number) =>\n `[${context.provider.getName()}] Discovery ${stepName} (groupIndex=${groupIndex})`;\n\n while (!context.stopped) {\n // Fast‑forward to current high‑water mark\n const targetGroupIndex = Math.max(context.groupIndex, maxGroupIndex);\n\n log(message('STARTED', targetGroupIndex));\n\n let accounts: Bip44Account<KeyringAccount>[] = [];\n try {\n accounts = await context.provider.discoverAndCreateAccounts({\n entropySource: this.#entropySource,\n groupIndex: targetGroupIndex,\n });\n } catch (error) {\n context.stopped = true;\n console.error(error);\n log(message('FAILED', targetGroupIndex), error);\n break;\n }\n\n if (!accounts.length) {\n log(message('STOPPED', targetGroupIndex));\n context.stopped = true;\n break;\n }\n\n log(message('SUCCEEDED', targetGroupIndex));\n\n context.count += accounts.length;\n\n const nextGroupIndex = targetGroupIndex + 1;\n context.groupIndex = nextGroupIndex;\n\n if (nextGroupIndex > maxGroupIndex) {\n maxGroupIndex = nextGroupIndex;\n }\n }\n };\n\n const providerContexts: AccountProviderDiscoveryContext[] =\n this.#providers.map((provider) => ({\n provider,\n stopped: false,\n groupIndex: maxGroupIndex,\n count: 0,\n }));\n\n // Start discovery for each providers.\n await Promise.all(providerContexts.map(runProviderDiscovery));\n\n // Sync the wallet after discovery to ensure that the newly added accounts are added into their groups.\n // We can potentially remove this if we know that this race condition is not an issue in practice.\n this.sync();\n\n // Align missing accounts from group. This is required to create missing account from non-discovered\n // indexes for some providers.\n await this.alignGroups();\n\n const discoveredAccounts: Record<string, number> = {};\n for (const context of providerContexts) {\n const providerName = context.provider.getName();\n discoveredAccounts[providerName] = context.count;\n }\n\n return discoveredAccounts;\n }\n}\n"]}
@@ -12,6 +12,9 @@ class AccountProviderWrapper extends BaseBip44AccountProvider_1.BaseBip44Account
12
12
  this.isEnabled = true;
13
13
  this.provider = provider;
14
14
  }
15
+ getName() {
16
+ return this.provider.getName();
17
+ }
15
18
  /**
16
19
  * Set the enabled state for this provider.
17
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"AccountProviderWrapper.cjs","sourceRoot":"","sources":["../../src/providers/AccountProviderWrapper.ts"],"names":[],"mappings":";;;AAGA,6EAAsE;AAGtE;;;GAGG;AACH,MAAa,sBAAuB,SAAQ,mDAAwB;IAKlE,YACE,SAA4C,EAC5C,QAAkC;QAElC,KAAK,CAAC,SAAS,CAAC,CAAC;QARX,cAAS,GAAY,IAAI,CAAC;QAShC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,OAAgB;QACzB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACM,WAAW;QAClB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACM,UAAU,CACjB,EAAsC;QAEtC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;SACzC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAqC;QACvD,OAAO,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,cAAc,CAAC,OAGpB;QACC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,yBAAyB,CAAC,OAG/B;QACC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;CACF;AAhGD,wDAgGC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB,CACtC,QAAiB;IAEjB,OAAO,QAAQ,YAAY,sBAAsB,CAAC;AACpD,CAAC;AAJD,4DAIC","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\n\nimport { BaseBip44AccountProvider } from './BaseBip44AccountProvider';\nimport type { MultichainAccountServiceMessenger } from '../types';\n\n/**\n * A simple wrapper that adds disable functionality to any BaseBip44AccountProvider.\n * When disabled, the provider will not create new accounts and return empty results.\n */\nexport class AccountProviderWrapper extends BaseBip44AccountProvider {\n private isEnabled: boolean = true;\n\n private readonly provider: BaseBip44AccountProvider;\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n provider: BaseBip44AccountProvider,\n ) {\n super(messenger);\n this.provider = provider;\n }\n\n /**\n * Set the enabled state for this provider.\n *\n * @param enabled - Whether the provider should be enabled.\n */\n setEnabled(enabled: boolean): void {\n this.isEnabled = enabled;\n }\n\n /**\n * Override getAccounts to return empty array when disabled.\n *\n * @returns Array of accounts, or empty array if disabled.\n */\n override getAccounts(): Bip44Account<KeyringAccount>[] {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.getAccounts();\n }\n\n /**\n * Override getAccount to throw when disabled.\n *\n * @param id - The account ID to retrieve.\n * @returns The account with the specified ID.\n * @throws When disabled or account not found.\n */\n override getAccount(\n id: Bip44Account<KeyringAccount>['id'],\n ): Bip44Account<KeyringAccount> {\n if (!this.isEnabled) {\n throw new Error('Provider is disabled');\n }\n return this.provider.getAccount(id);\n }\n\n /**\n * Implement abstract method: Check if account is compatible.\n * Delegates directly to wrapped provider - no runtime checks needed!\n *\n * @param account - The account to check.\n * @returns True if the account is compatible.\n */\n isAccountCompatible(account: Bip44Account<KeyringAccount>): boolean {\n return this.provider.isAccountCompatible(account);\n }\n\n /**\n * Implement abstract method: Create accounts, returns empty array when disabled.\n *\n * @param options - Account creation options.\n * @param options.entropySource - The entropy source to use.\n * @param options.groupIndex - The group index to use.\n * @returns Promise resolving to created accounts, or empty array if disabled.\n */\n async createAccounts(options: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.createAccounts(options);\n }\n\n /**\n * Implement abstract method: Discover and create accounts, returns empty array when disabled.\n *\n * @param options - Account discovery options.\n * @param options.entropySource - The entropy source to use.\n * @param options.groupIndex - The group index to use.\n * @returns Promise resolving to discovered accounts, or empty array if disabled.\n */\n async discoverAndCreateAccounts(options: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.discoverAndCreateAccounts(options);\n }\n}\n\n/**\n * Simple type guard to check if a provider is wrapped.\n *\n * @param provider - The provider to check.\n * @returns True if the provider is an AccountProviderWrapper.\n */\nexport function isAccountProviderWrapper(\n provider: unknown,\n): provider is AccountProviderWrapper {\n return provider instanceof AccountProviderWrapper;\n}\n"]}
1
+ {"version":3,"file":"AccountProviderWrapper.cjs","sourceRoot":"","sources":["../../src/providers/AccountProviderWrapper.ts"],"names":[],"mappings":";;;AAGA,6EAAsE;AAGtE;;;GAGG;AACH,MAAa,sBAAuB,SAAQ,mDAAwB;IAKlE,YACE,SAA4C,EAC5C,QAAkC;QAElC,KAAK,CAAC,SAAS,CAAC,CAAC;QARX,cAAS,GAAY,IAAI,CAAC;QAShC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAEQ,OAAO;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,OAAgB;QACzB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACM,WAAW;QAClB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACM,UAAU,CACjB,EAAsC;QAEtC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;SACzC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAqC;QACvD,OAAO,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,cAAc,CAAC,OAGpB;QACC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,yBAAyB,CAAC,OAG/B;QACC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;CACF;AApGD,wDAoGC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB,CACtC,QAAiB;IAEjB,OAAO,QAAQ,YAAY,sBAAsB,CAAC;AACpD,CAAC;AAJD,4DAIC","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\n\nimport { BaseBip44AccountProvider } from './BaseBip44AccountProvider';\nimport type { MultichainAccountServiceMessenger } from '../types';\n\n/**\n * A simple wrapper that adds disable functionality to any BaseBip44AccountProvider.\n * When disabled, the provider will not create new accounts and return empty results.\n */\nexport class AccountProviderWrapper extends BaseBip44AccountProvider {\n private isEnabled: boolean = true;\n\n private readonly provider: BaseBip44AccountProvider;\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n provider: BaseBip44AccountProvider,\n ) {\n super(messenger);\n this.provider = provider;\n }\n\n override getName(): string {\n return this.provider.getName();\n }\n\n /**\n * Set the enabled state for this provider.\n *\n * @param enabled - Whether the provider should be enabled.\n */\n setEnabled(enabled: boolean): void {\n this.isEnabled = enabled;\n }\n\n /**\n * Override getAccounts to return empty array when disabled.\n *\n * @returns Array of accounts, or empty array if disabled.\n */\n override getAccounts(): Bip44Account<KeyringAccount>[] {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.getAccounts();\n }\n\n /**\n * Override getAccount to throw when disabled.\n *\n * @param id - The account ID to retrieve.\n * @returns The account with the specified ID.\n * @throws When disabled or account not found.\n */\n override getAccount(\n id: Bip44Account<KeyringAccount>['id'],\n ): Bip44Account<KeyringAccount> {\n if (!this.isEnabled) {\n throw new Error('Provider is disabled');\n }\n return this.provider.getAccount(id);\n }\n\n /**\n * Implement abstract method: Check if account is compatible.\n * Delegates directly to wrapped provider - no runtime checks needed!\n *\n * @param account - The account to check.\n * @returns True if the account is compatible.\n */\n isAccountCompatible(account: Bip44Account<KeyringAccount>): boolean {\n return this.provider.isAccountCompatible(account);\n }\n\n /**\n * Implement abstract method: Create accounts, returns empty array when disabled.\n *\n * @param options - Account creation options.\n * @param options.entropySource - The entropy source to use.\n * @param options.groupIndex - The group index to use.\n * @returns Promise resolving to created accounts, or empty array if disabled.\n */\n async createAccounts(options: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.createAccounts(options);\n }\n\n /**\n * Implement abstract method: Discover and create accounts, returns empty array when disabled.\n *\n * @param options - Account discovery options.\n * @param options.entropySource - The entropy source to use.\n * @param options.groupIndex - The group index to use.\n * @returns Promise resolving to discovered accounts, or empty array if disabled.\n */\n async discoverAndCreateAccounts(options: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.discoverAndCreateAccounts(options);\n }\n}\n\n/**\n * Simple type guard to check if a provider is wrapped.\n *\n * @param provider - The provider to check.\n * @returns True if the provider is an AccountProviderWrapper.\n */\nexport function isAccountProviderWrapper(\n provider: unknown,\n): provider is AccountProviderWrapper {\n return provider instanceof AccountProviderWrapper;\n}\n"]}
@@ -10,6 +10,7 @@ export declare class AccountProviderWrapper extends BaseBip44AccountProvider {
10
10
  private isEnabled;
11
11
  private readonly provider;
12
12
  constructor(messenger: MultichainAccountServiceMessenger, provider: BaseBip44AccountProvider);
13
+ getName(): string;
13
14
  /**
14
15
  * Set the enabled state for this provider.
15
16
  *
@@ -1 +1 @@
1
- {"version":3,"file":"AccountProviderWrapper.d.cts","sourceRoot":"","sources":["../../src/providers/AccountProviderWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAE7E,OAAO,EAAE,wBAAwB,EAAE,uCAAmC;AACtE,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,wBAAwB;IAClE,OAAO,CAAC,SAAS,CAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;gBAGlD,SAAS,EAAE,iCAAiC,EAC5C,QAAQ,EAAE,wBAAwB;IAMpC;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC;;;;OAIG;IACM,WAAW,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE;IAOtD;;;;;;OAMG;IACM,UAAU,CACjB,EAAE,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GACrC,YAAY,CAAC,cAAc,CAAC;IAO/B;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,GAAG,OAAO;IAInE;;;;;;;OAOG;IACG,cAAc,CAAC,OAAO,EAAE;QAC5B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAO3C;;;;;;;OAOG;IACG,yBAAyB,CAAC,OAAO,EAAE;QACvC,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;CAM5C;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,OAAO,GAChB,QAAQ,IAAI,sBAAsB,CAEpC"}
1
+ {"version":3,"file":"AccountProviderWrapper.d.cts","sourceRoot":"","sources":["../../src/providers/AccountProviderWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAE7E,OAAO,EAAE,wBAAwB,EAAE,uCAAmC;AACtE,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,wBAAwB;IAClE,OAAO,CAAC,SAAS,CAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;gBAGlD,SAAS,EAAE,iCAAiC,EAC5C,QAAQ,EAAE,wBAAwB;IAM3B,OAAO,IAAI,MAAM;IAI1B;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC;;;;OAIG;IACM,WAAW,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE;IAOtD;;;;;;OAMG;IACM,UAAU,CACjB,EAAE,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GACrC,YAAY,CAAC,cAAc,CAAC;IAO/B;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,GAAG,OAAO;IAInE;;;;;;;OAOG;IACG,cAAc,CAAC,OAAO,EAAE;QAC5B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAO3C;;;;;;;OAOG;IACG,yBAAyB,CAAC,OAAO,EAAE;QACvC,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;CAM5C;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,OAAO,GAChB,QAAQ,IAAI,sBAAsB,CAEpC"}
@@ -10,6 +10,7 @@ export declare class AccountProviderWrapper extends BaseBip44AccountProvider {
10
10
  private isEnabled;
11
11
  private readonly provider;
12
12
  constructor(messenger: MultichainAccountServiceMessenger, provider: BaseBip44AccountProvider);
13
+ getName(): string;
13
14
  /**
14
15
  * Set the enabled state for this provider.
15
16
  *
@@ -1 +1 @@
1
- {"version":3,"file":"AccountProviderWrapper.d.mts","sourceRoot":"","sources":["../../src/providers/AccountProviderWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAE7E,OAAO,EAAE,wBAAwB,EAAE,uCAAmC;AACtE,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,wBAAwB;IAClE,OAAO,CAAC,SAAS,CAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;gBAGlD,SAAS,EAAE,iCAAiC,EAC5C,QAAQ,EAAE,wBAAwB;IAMpC;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC;;;;OAIG;IACM,WAAW,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE;IAOtD;;;;;;OAMG;IACM,UAAU,CACjB,EAAE,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GACrC,YAAY,CAAC,cAAc,CAAC;IAO/B;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,GAAG,OAAO;IAInE;;;;;;;OAOG;IACG,cAAc,CAAC,OAAO,EAAE;QAC5B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAO3C;;;;;;;OAOG;IACG,yBAAyB,CAAC,OAAO,EAAE;QACvC,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;CAM5C;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,OAAO,GAChB,QAAQ,IAAI,sBAAsB,CAEpC"}
1
+ {"version":3,"file":"AccountProviderWrapper.d.mts","sourceRoot":"","sources":["../../src/providers/AccountProviderWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAE7E,OAAO,EAAE,wBAAwB,EAAE,uCAAmC;AACtE,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,wBAAwB;IAClE,OAAO,CAAC,SAAS,CAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;gBAGlD,SAAS,EAAE,iCAAiC,EAC5C,QAAQ,EAAE,wBAAwB;IAM3B,OAAO,IAAI,MAAM;IAI1B;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC;;;;OAIG;IACM,WAAW,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE;IAOtD;;;;;;OAMG;IACM,UAAU,CACjB,EAAE,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GACrC,YAAY,CAAC,cAAc,CAAC;IAO/B;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,GAAG,OAAO;IAInE;;;;;;;OAOG;IACG,cAAc,CAAC,OAAO,EAAE;QAC5B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAO3C;;;;;;;OAOG;IACG,yBAAyB,CAAC,OAAO,EAAE;QACvC,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;CAM5C;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,OAAO,GAChB,QAAQ,IAAI,sBAAsB,CAEpC"}
@@ -9,6 +9,9 @@ export class AccountProviderWrapper extends BaseBip44AccountProvider {
9
9
  this.isEnabled = true;
10
10
  this.provider = provider;
11
11
  }
12
+ getName() {
13
+ return this.provider.getName();
14
+ }
12
15
  /**
13
16
  * Set the enabled state for this provider.
14
17
  *
@@ -1 +1 @@
1
- {"version":3,"file":"AccountProviderWrapper.mjs","sourceRoot":"","sources":["../../src/providers/AccountProviderWrapper.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,uCAAmC;AAGtE;;;GAGG;AACH,MAAM,OAAO,sBAAuB,SAAQ,wBAAwB;IAKlE,YACE,SAA4C,EAC5C,QAAkC;QAElC,KAAK,CAAC,SAAS,CAAC,CAAC;QARX,cAAS,GAAY,IAAI,CAAC;QAShC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,OAAgB;QACzB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACM,WAAW;QAClB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACM,UAAU,CACjB,EAAsC;QAEtC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;SACzC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAqC;QACvD,OAAO,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,cAAc,CAAC,OAGpB;QACC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,yBAAyB,CAAC,OAG/B;QACC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,QAAiB;IAEjB,OAAO,QAAQ,YAAY,sBAAsB,CAAC;AACpD,CAAC","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\n\nimport { BaseBip44AccountProvider } from './BaseBip44AccountProvider';\nimport type { MultichainAccountServiceMessenger } from '../types';\n\n/**\n * A simple wrapper that adds disable functionality to any BaseBip44AccountProvider.\n * When disabled, the provider will not create new accounts and return empty results.\n */\nexport class AccountProviderWrapper extends BaseBip44AccountProvider {\n private isEnabled: boolean = true;\n\n private readonly provider: BaseBip44AccountProvider;\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n provider: BaseBip44AccountProvider,\n ) {\n super(messenger);\n this.provider = provider;\n }\n\n /**\n * Set the enabled state for this provider.\n *\n * @param enabled - Whether the provider should be enabled.\n */\n setEnabled(enabled: boolean): void {\n this.isEnabled = enabled;\n }\n\n /**\n * Override getAccounts to return empty array when disabled.\n *\n * @returns Array of accounts, or empty array if disabled.\n */\n override getAccounts(): Bip44Account<KeyringAccount>[] {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.getAccounts();\n }\n\n /**\n * Override getAccount to throw when disabled.\n *\n * @param id - The account ID to retrieve.\n * @returns The account with the specified ID.\n * @throws When disabled or account not found.\n */\n override getAccount(\n id: Bip44Account<KeyringAccount>['id'],\n ): Bip44Account<KeyringAccount> {\n if (!this.isEnabled) {\n throw new Error('Provider is disabled');\n }\n return this.provider.getAccount(id);\n }\n\n /**\n * Implement abstract method: Check if account is compatible.\n * Delegates directly to wrapped provider - no runtime checks needed!\n *\n * @param account - The account to check.\n * @returns True if the account is compatible.\n */\n isAccountCompatible(account: Bip44Account<KeyringAccount>): boolean {\n return this.provider.isAccountCompatible(account);\n }\n\n /**\n * Implement abstract method: Create accounts, returns empty array when disabled.\n *\n * @param options - Account creation options.\n * @param options.entropySource - The entropy source to use.\n * @param options.groupIndex - The group index to use.\n * @returns Promise resolving to created accounts, or empty array if disabled.\n */\n async createAccounts(options: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.createAccounts(options);\n }\n\n /**\n * Implement abstract method: Discover and create accounts, returns empty array when disabled.\n *\n * @param options - Account discovery options.\n * @param options.entropySource - The entropy source to use.\n * @param options.groupIndex - The group index to use.\n * @returns Promise resolving to discovered accounts, or empty array if disabled.\n */\n async discoverAndCreateAccounts(options: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.discoverAndCreateAccounts(options);\n }\n}\n\n/**\n * Simple type guard to check if a provider is wrapped.\n *\n * @param provider - The provider to check.\n * @returns True if the provider is an AccountProviderWrapper.\n */\nexport function isAccountProviderWrapper(\n provider: unknown,\n): provider is AccountProviderWrapper {\n return provider instanceof AccountProviderWrapper;\n}\n"]}
1
+ {"version":3,"file":"AccountProviderWrapper.mjs","sourceRoot":"","sources":["../../src/providers/AccountProviderWrapper.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,uCAAmC;AAGtE;;;GAGG;AACH,MAAM,OAAO,sBAAuB,SAAQ,wBAAwB;IAKlE,YACE,SAA4C,EAC5C,QAAkC;QAElC,KAAK,CAAC,SAAS,CAAC,CAAC;QARX,cAAS,GAAY,IAAI,CAAC;QAShC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAEQ,OAAO;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,OAAgB;QACzB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACM,WAAW;QAClB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACM,UAAU,CACjB,EAAsC;QAEtC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;SACzC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAqC;QACvD,OAAO,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,cAAc,CAAC,OAGpB;QACC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,yBAAyB,CAAC,OAG/B;QACC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,EAAE,CAAC;SACX;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,QAAiB;IAEjB,OAAO,QAAQ,YAAY,sBAAsB,CAAC;AACpD,CAAC","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\n\nimport { BaseBip44AccountProvider } from './BaseBip44AccountProvider';\nimport type { MultichainAccountServiceMessenger } from '../types';\n\n/**\n * A simple wrapper that adds disable functionality to any BaseBip44AccountProvider.\n * When disabled, the provider will not create new accounts and return empty results.\n */\nexport class AccountProviderWrapper extends BaseBip44AccountProvider {\n private isEnabled: boolean = true;\n\n private readonly provider: BaseBip44AccountProvider;\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n provider: BaseBip44AccountProvider,\n ) {\n super(messenger);\n this.provider = provider;\n }\n\n override getName(): string {\n return this.provider.getName();\n }\n\n /**\n * Set the enabled state for this provider.\n *\n * @param enabled - Whether the provider should be enabled.\n */\n setEnabled(enabled: boolean): void {\n this.isEnabled = enabled;\n }\n\n /**\n * Override getAccounts to return empty array when disabled.\n *\n * @returns Array of accounts, or empty array if disabled.\n */\n override getAccounts(): Bip44Account<KeyringAccount>[] {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.getAccounts();\n }\n\n /**\n * Override getAccount to throw when disabled.\n *\n * @param id - The account ID to retrieve.\n * @returns The account with the specified ID.\n * @throws When disabled or account not found.\n */\n override getAccount(\n id: Bip44Account<KeyringAccount>['id'],\n ): Bip44Account<KeyringAccount> {\n if (!this.isEnabled) {\n throw new Error('Provider is disabled');\n }\n return this.provider.getAccount(id);\n }\n\n /**\n * Implement abstract method: Check if account is compatible.\n * Delegates directly to wrapped provider - no runtime checks needed!\n *\n * @param account - The account to check.\n * @returns True if the account is compatible.\n */\n isAccountCompatible(account: Bip44Account<KeyringAccount>): boolean {\n return this.provider.isAccountCompatible(account);\n }\n\n /**\n * Implement abstract method: Create accounts, returns empty array when disabled.\n *\n * @param options - Account creation options.\n * @param options.entropySource - The entropy source to use.\n * @param options.groupIndex - The group index to use.\n * @returns Promise resolving to created accounts, or empty array if disabled.\n */\n async createAccounts(options: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.createAccounts(options);\n }\n\n /**\n * Implement abstract method: Discover and create accounts, returns empty array when disabled.\n *\n * @param options - Account discovery options.\n * @param options.entropySource - The entropy source to use.\n * @param options.groupIndex - The group index to use.\n * @returns Promise resolving to discovered accounts, or empty array if disabled.\n */\n async discoverAndCreateAccounts(options: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n if (!this.isEnabled) {\n return [];\n }\n return this.provider.discoverAndCreateAccounts(options);\n }\n}\n\n/**\n * Simple type guard to check if a provider is wrapped.\n *\n * @param provider - The provider to check.\n * @returns True if the provider is an AccountProviderWrapper.\n */\nexport function isAccountProviderWrapper(\n provider: unknown,\n): provider is AccountProviderWrapper {\n return provider instanceof AccountProviderWrapper;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"BaseBip44AccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/BaseBip44AccountProvider.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uDAI+B;AAS/B;;;;;GAKG;AACH,SAAgB,oBAAoB,CAClC,OAAuB;IAEvB,IAAI,CAAC,IAAA,4BAAc,EAAC,OAAO,CAAC,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;KAC7D;AACH,CAAC;AAND,oDAMC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CACpC,QAA0B;IAE1B,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;AACzC,CAAC;AAJD,wDAIC;AAED,MAAsB,wBAAwB;IAK5C,YAAY,SAA4C;;QACtD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAyBD,WAAW;QACT,OAAO,uBAAA,IAAI,kFAAa,MAAjB,IAAI,CAAe,CAAC;IAC7B,CAAC;IAED,UAAU,CACR,EAAsC;QAEtC,wDAAwD;QACxD,MAAM,CAAC,KAAK,CAAC,GAAG,uBAAA,IAAI,kFAAa,MAAjB,IAAI,EAAc,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;SAClD;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAES,KAAK,CAAC,WAAW,CACzB,QAAyB,EACzB,SAM6B;QAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACtC,+BAA+B,EAC/B,QAAQ,EACR,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CACxB,SAAS,CAAC;YACR,OAAO,EAAE,OAA0B;YACnC,QAAQ;SACT,CAAC,CACL,CAAC;QAEF,OAAO,MAAwB,CAAC;IAClC,CAAC;CAmBF;AAzFD,4DAyFC;4IA/EG,SAA+C,GAAG,EAAE,CAAC,IAAI;IAEzD,MAAM,QAAQ,GAAmC,EAAE,CAAC;IAEpD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI;IACvC,2EAA2E;IAC3E,yEAAyE;IACzE,kDAAkD;IAClD,2CAA2C,CAC5C,EAAE;QACD,IACE,IAAA,4BAAc,EAAC,OAAO,CAAC;YACvB,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC;YACjC,MAAM,CAAC,OAAO,CAAC,EACf;YACA,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACxB;KACF;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import {\n isBip44Account,\n type AccountProvider,\n type Bip44Account,\n} from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport type {\n KeyringMetadata,\n KeyringSelector,\n} from '@metamask/keyring-controller';\n\nimport type { MultichainAccountServiceMessenger } from '../types';\n\n/**\n * Asserts a keyring account is BIP-44 compatible.\n *\n * @param account - Keyring account to check.\n * @throws If the keyring account is not compatible.\n */\nexport function assertIsBip44Account(\n account: KeyringAccount,\n): asserts account is Bip44Account<KeyringAccount> {\n if (!isBip44Account(account)) {\n throw new Error('Created account is not BIP-44 compatible');\n }\n}\n\n/**\n * Asserts that a list of keyring accounts are all BIP-44 compatible.\n *\n * @param accounts - Keyring accounts to check.\n * @throws If any of the keyring account is not compatible.\n */\nexport function assertAreBip44Accounts(\n accounts: KeyringAccount[],\n): asserts accounts is Bip44Account<KeyringAccount>[] {\n accounts.forEach(assertIsBip44Account);\n}\n\nexport abstract class BaseBip44AccountProvider\n implements AccountProvider<Bip44Account<KeyringAccount>>\n{\n protected readonly messenger: MultichainAccountServiceMessenger;\n\n constructor(messenger: MultichainAccountServiceMessenger) {\n this.messenger = messenger;\n }\n\n #getAccounts(\n filter: (account: KeyringAccount) => boolean = () => true,\n ): Bip44Account<KeyringAccount>[] {\n const accounts: Bip44Account<KeyringAccount>[] = [];\n\n for (const account of this.messenger.call(\n // NOTE: Even though the name is misleading, this only fetches all internal\n // accounts, including EVM and non-EVM. We might wanna change this action\n // name once we fully support multichain accounts.\n 'AccountsController:listMultichainAccounts',\n )) {\n if (\n isBip44Account(account) &&\n this.isAccountCompatible(account) &&\n filter(account)\n ) {\n accounts.push(account);\n }\n }\n\n return accounts;\n }\n\n getAccounts(): Bip44Account<KeyringAccount>[] {\n return this.#getAccounts();\n }\n\n getAccount(\n id: Bip44Account<KeyringAccount>['id'],\n ): Bip44Account<KeyringAccount> {\n // TODO: Maybe just use a proper find for faster lookup?\n const [found] = this.#getAccounts((account) => account.id === id);\n\n if (!found) {\n throw new Error(`Unable to find account: ${id}`);\n }\n\n return found;\n }\n\n protected async withKeyring<SelectedKeyring, CallbackResult = void>(\n selector: KeyringSelector,\n operation: ({\n keyring,\n metadata,\n }: {\n keyring: SelectedKeyring;\n metadata: KeyringMetadata;\n }) => Promise<CallbackResult>,\n ): Promise<CallbackResult> {\n const result = await this.messenger.call(\n 'KeyringController:withKeyring',\n selector,\n ({ keyring, metadata }) =>\n operation({\n keyring: keyring as SelectedKeyring,\n metadata,\n }),\n );\n\n return result as CallbackResult;\n }\n\n abstract isAccountCompatible(account: Bip44Account<KeyringAccount>): boolean;\n\n abstract createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]>;\n\n abstract discoverAndCreateAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]>;\n}\n"]}
1
+ {"version":3,"file":"BaseBip44AccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/BaseBip44AccountProvider.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uDAI+B;AAS/B;;;;;GAKG;AACH,SAAgB,oBAAoB,CAClC,OAAuB;IAEvB,IAAI,CAAC,IAAA,4BAAc,EAAC,OAAO,CAAC,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;KAC7D;AACH,CAAC;AAND,oDAMC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CACpC,QAA0B;IAE1B,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;AACzC,CAAC;AAJD,wDAIC;AAQD,MAAsB,wBAAwB;IAG5C,YAAY,SAA4C;;QACtD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IA2BD,WAAW;QACT,OAAO,uBAAA,IAAI,kFAAa,MAAjB,IAAI,CAAe,CAAC;IAC7B,CAAC;IAED,UAAU,CACR,EAAsC;QAEtC,wDAAwD;QACxD,MAAM,CAAC,KAAK,CAAC,GAAG,uBAAA,IAAI,kFAAa,MAAjB,IAAI,EAAc,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;SAClD;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAES,KAAK,CAAC,WAAW,CACzB,QAAyB,EACzB,SAM6B;QAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACtC,+BAA+B,EAC/B,QAAQ,EACR,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CACxB,SAAS,CAAC;YACR,OAAO,EAAE,OAA0B;YACnC,QAAQ;SACT,CAAC,CACL,CAAC;QAEF,OAAO,MAAwB,CAAC;IAClC,CAAC;CAmBF;AAzFD,4DAyFC;4IA/EG,SAA+C,GAAG,EAAE,CAAC,IAAI;IAEzD,MAAM,QAAQ,GAAmC,EAAE,CAAC;IAEpD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI;IACvC,2EAA2E;IAC3E,yEAAyE;IACzE,kDAAkD;IAClD,2CAA2C,CAC5C,EAAE;QACD,IACE,IAAA,4BAAc,EAAC,OAAO,CAAC;YACvB,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC;YACjC,MAAM,CAAC,OAAO,CAAC,EACf;YACA,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACxB;KACF;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import {\n isBip44Account,\n type AccountProvider,\n type Bip44Account,\n} from '@metamask/account-api';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport type {\n KeyringMetadata,\n KeyringSelector,\n} from '@metamask/keyring-controller';\n\nimport type { MultichainAccountServiceMessenger } from '../types';\n\n/**\n * Asserts a keyring account is BIP-44 compatible.\n *\n * @param account - Keyring account to check.\n * @throws If the keyring account is not compatible.\n */\nexport function assertIsBip44Account(\n account: KeyringAccount,\n): asserts account is Bip44Account<KeyringAccount> {\n if (!isBip44Account(account)) {\n throw new Error('Created account is not BIP-44 compatible');\n }\n}\n\n/**\n * Asserts that a list of keyring accounts are all BIP-44 compatible.\n *\n * @param accounts - Keyring accounts to check.\n * @throws If any of the keyring account is not compatible.\n */\nexport function assertAreBip44Accounts(\n accounts: KeyringAccount[],\n): asserts accounts is Bip44Account<KeyringAccount>[] {\n accounts.forEach(assertIsBip44Account);\n}\n\nexport type NamedAccountProvider<\n Account extends Bip44Account<KeyringAccount> = Bip44Account<KeyringAccount>,\n> = AccountProvider<Account> & {\n getName(): string;\n};\n\nexport abstract class BaseBip44AccountProvider implements NamedAccountProvider {\n protected readonly messenger: MultichainAccountServiceMessenger;\n\n constructor(messenger: MultichainAccountServiceMessenger) {\n this.messenger = messenger;\n }\n\n abstract getName(): string;\n\n #getAccounts(\n filter: (account: KeyringAccount) => boolean = () => true,\n ): Bip44Account<KeyringAccount>[] {\n const accounts: Bip44Account<KeyringAccount>[] = [];\n\n for (const account of this.messenger.call(\n // NOTE: Even though the name is misleading, this only fetches all internal\n // accounts, including EVM and non-EVM. We might wanna change this action\n // name once we fully support multichain accounts.\n 'AccountsController:listMultichainAccounts',\n )) {\n if (\n isBip44Account(account) &&\n this.isAccountCompatible(account) &&\n filter(account)\n ) {\n accounts.push(account);\n }\n }\n\n return accounts;\n }\n\n getAccounts(): Bip44Account<KeyringAccount>[] {\n return this.#getAccounts();\n }\n\n getAccount(\n id: Bip44Account<KeyringAccount>['id'],\n ): Bip44Account<KeyringAccount> {\n // TODO: Maybe just use a proper find for faster lookup?\n const [found] = this.#getAccounts((account) => account.id === id);\n\n if (!found) {\n throw new Error(`Unable to find account: ${id}`);\n }\n\n return found;\n }\n\n protected async withKeyring<SelectedKeyring, CallbackResult = void>(\n selector: KeyringSelector,\n operation: ({\n keyring,\n metadata,\n }: {\n keyring: SelectedKeyring;\n metadata: KeyringMetadata;\n }) => Promise<CallbackResult>,\n ): Promise<CallbackResult> {\n const result = await this.messenger.call(\n 'KeyringController:withKeyring',\n selector,\n ({ keyring, metadata }) =>\n operation({\n keyring: keyring as SelectedKeyring,\n metadata,\n }),\n );\n\n return result as CallbackResult;\n }\n\n abstract isAccountCompatible(account: Bip44Account<KeyringAccount>): boolean;\n\n abstract createAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]>;\n\n abstract discoverAndCreateAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]>;\n}\n"]}
@@ -16,10 +16,14 @@ export declare function assertIsBip44Account(account: KeyringAccount): asserts a
16
16
  * @throws If any of the keyring account is not compatible.
17
17
  */
18
18
  export declare function assertAreBip44Accounts(accounts: KeyringAccount[]): asserts accounts is Bip44Account<KeyringAccount>[];
19
- export declare abstract class BaseBip44AccountProvider implements AccountProvider<Bip44Account<KeyringAccount>> {
19
+ export type NamedAccountProvider<Account extends Bip44Account<KeyringAccount> = Bip44Account<KeyringAccount>> = AccountProvider<Account> & {
20
+ getName(): string;
21
+ };
22
+ export declare abstract class BaseBip44AccountProvider implements NamedAccountProvider {
20
23
  #private;
21
24
  protected readonly messenger: MultichainAccountServiceMessenger;
22
25
  constructor(messenger: MultichainAccountServiceMessenger);
26
+ abstract getName(): string;
23
27
  getAccounts(): Bip44Account<KeyringAccount>[];
24
28
  getAccount(id: Bip44Account<KeyringAccount>['id']): Bip44Account<KeyringAccount>;
25
29
  protected withKeyring<SelectedKeyring, CallbackResult = void>(selector: KeyringSelector, operation: ({ keyring, metadata, }: {
@@ -1 +1 @@
1
- {"version":3,"file":"BaseBip44AccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/BaseBip44AccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAC7E,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAChB,qCAAqC;AAEtC,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC,cAAc,CAAC,CAIjD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,EAAE,GACzB,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE,CAEpD;AAED,8BAAsB,wBACpB,YAAW,eAAe,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;;IAExD,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iCAAiC,CAAC;gBAEpD,SAAS,EAAE,iCAAiC;IA2BxD,WAAW,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE;IAI7C,UAAU,CACR,EAAE,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GACrC,YAAY,CAAC,cAAc,CAAC;cAWf,WAAW,CAAC,eAAe,EAAE,cAAc,GAAG,IAAI,EAChE,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,CAAC,EACV,OAAO,EACP,QAAQ,GACT,EAAE;QACD,OAAO,EAAE,eAAe,CAAC;QACzB,QAAQ,EAAE,eAAe,CAAC;KAC3B,KAAK,OAAO,CAAC,cAAc,CAAC,GAC5B,OAAO,CAAC,cAAc,CAAC;IAc1B,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,GAAG,OAAO;IAE5E,QAAQ,CAAC,cAAc,CAAC,EACtB,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;IAE3C,QAAQ,CAAC,yBAAyB,CAAC,EACjC,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;CAC5C"}
1
+ {"version":3,"file":"BaseBip44AccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/BaseBip44AccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAC7E,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAChB,qCAAqC;AAEtC,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC,cAAc,CAAC,CAIjD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,EAAE,GACzB,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE,CAEpD;AAED,MAAM,MAAM,oBAAoB,CAC9B,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,cAAc,CAAC,IACzE,eAAe,CAAC,OAAO,CAAC,GAAG;IAC7B,OAAO,IAAI,MAAM,CAAC;CACnB,CAAC;AAEF,8BAAsB,wBAAyB,YAAW,oBAAoB;;IAC5E,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iCAAiC,CAAC;gBAEpD,SAAS,EAAE,iCAAiC;IAIxD,QAAQ,CAAC,OAAO,IAAI,MAAM;IAyB1B,WAAW,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE;IAI7C,UAAU,CACR,EAAE,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GACrC,YAAY,CAAC,cAAc,CAAC;cAWf,WAAW,CAAC,eAAe,EAAE,cAAc,GAAG,IAAI,EAChE,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,CAAC,EACV,OAAO,EACP,QAAQ,GACT,EAAE;QACD,OAAO,EAAE,eAAe,CAAC;QACzB,QAAQ,EAAE,eAAe,CAAC;KAC3B,KAAK,OAAO,CAAC,cAAc,CAAC,GAC5B,OAAO,CAAC,cAAc,CAAC;IAc1B,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,GAAG,OAAO;IAE5E,QAAQ,CAAC,cAAc,CAAC,EACtB,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;IAE3C,QAAQ,CAAC,yBAAyB,CAAC,EACjC,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;CAC5C"}
@@ -16,10 +16,14 @@ export declare function assertIsBip44Account(account: KeyringAccount): asserts a
16
16
  * @throws If any of the keyring account is not compatible.
17
17
  */
18
18
  export declare function assertAreBip44Accounts(accounts: KeyringAccount[]): asserts accounts is Bip44Account<KeyringAccount>[];
19
- export declare abstract class BaseBip44AccountProvider implements AccountProvider<Bip44Account<KeyringAccount>> {
19
+ export type NamedAccountProvider<Account extends Bip44Account<KeyringAccount> = Bip44Account<KeyringAccount>> = AccountProvider<Account> & {
20
+ getName(): string;
21
+ };
22
+ export declare abstract class BaseBip44AccountProvider implements NamedAccountProvider {
20
23
  #private;
21
24
  protected readonly messenger: MultichainAccountServiceMessenger;
22
25
  constructor(messenger: MultichainAccountServiceMessenger);
26
+ abstract getName(): string;
23
27
  getAccounts(): Bip44Account<KeyringAccount>[];
24
28
  getAccount(id: Bip44Account<KeyringAccount>['id']): Bip44Account<KeyringAccount>;
25
29
  protected withKeyring<SelectedKeyring, CallbackResult = void>(selector: KeyringSelector, operation: ({ keyring, metadata, }: {
@@ -1 +1 @@
1
- {"version":3,"file":"BaseBip44AccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/BaseBip44AccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAC7E,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAChB,qCAAqC;AAEtC,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC,cAAc,CAAC,CAIjD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,EAAE,GACzB,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE,CAEpD;AAED,8BAAsB,wBACpB,YAAW,eAAe,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;;IAExD,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iCAAiC,CAAC;gBAEpD,SAAS,EAAE,iCAAiC;IA2BxD,WAAW,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE;IAI7C,UAAU,CACR,EAAE,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GACrC,YAAY,CAAC,cAAc,CAAC;cAWf,WAAW,CAAC,eAAe,EAAE,cAAc,GAAG,IAAI,EAChE,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,CAAC,EACV,OAAO,EACP,QAAQ,GACT,EAAE;QACD,OAAO,EAAE,eAAe,CAAC;QACzB,QAAQ,EAAE,eAAe,CAAC;KAC3B,KAAK,OAAO,CAAC,cAAc,CAAC,GAC5B,OAAO,CAAC,cAAc,CAAC;IAc1B,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,GAAG,OAAO;IAE5E,QAAQ,CAAC,cAAc,CAAC,EACtB,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;IAE3C,QAAQ,CAAC,yBAAyB,CAAC,EACjC,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;CAC5C"}
1
+ {"version":3,"file":"BaseBip44AccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/BaseBip44AccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAC7E,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAChB,qCAAqC;AAEtC,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC,cAAc,CAAC,CAIjD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,EAAE,GACzB,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE,CAEpD;AAED,MAAM,MAAM,oBAAoB,CAC9B,OAAO,SAAS,YAAY,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,cAAc,CAAC,IACzE,eAAe,CAAC,OAAO,CAAC,GAAG;IAC7B,OAAO,IAAI,MAAM,CAAC;CACnB,CAAC;AAEF,8BAAsB,wBAAyB,YAAW,oBAAoB;;IAC5E,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iCAAiC,CAAC;gBAEpD,SAAS,EAAE,iCAAiC;IAIxD,QAAQ,CAAC,OAAO,IAAI,MAAM;IAyB1B,WAAW,IAAI,YAAY,CAAC,cAAc,CAAC,EAAE;IAI7C,UAAU,CACR,EAAE,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GACrC,YAAY,CAAC,cAAc,CAAC;cAWf,WAAW,CAAC,eAAe,EAAE,cAAc,GAAG,IAAI,EAChE,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,CAAC,EACV,OAAO,EACP,QAAQ,GACT,EAAE;QACD,OAAO,EAAE,eAAe,CAAC;QACzB,QAAQ,EAAE,eAAe,CAAC;KAC3B,KAAK,OAAO,CAAC,cAAc,CAAC,GAC5B,OAAO,CAAC,cAAc,CAAC;IAc1B,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,GAAG,OAAO;IAE5E,QAAQ,CAAC,cAAc,CAAC,EACtB,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;IAE3C,QAAQ,CAAC,yBAAyB,CAAC,EACjC,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;CAC5C"}