{"version":3,"file":"adapters.cjs","sourceRoot":"","sources":["../../../src/api/multichain/adapters.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\n// This rule seems to be triggering a false positive. Possibly eslint is not\n// inferring the `InternalAccount` type correctly which causes issue with the\n// union `| undefined`.\n\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport type { AccountId } from '@metamask/keyring-utils';\nimport { isScopeEqualToAny } from '@metamask/keyring-utils';\n\nimport type {\n  AccountGroupId,\n  AccountProvider,\n  MultichainAccount,\n  MultichainAccountId,\n  MultichainAccountSelector,\n  MultichainAccountWallet,\n  MultichainAccountWalletId,\n} from '..';\nimport {\n  getGroupIndexFromAccountGroupId,\n  toDefaultAccountGroupId,\n  toMultichainAccountId,\n  toMultichainAccountWalletId,\n} from '..';\n\nexport class MultichainAccountAdapter<Account extends KeyringAccount>\n  implements MultichainAccount<Account>\n{\n  readonly #id: MultichainAccountId;\n\n  readonly #wallet: MultichainAccountWallet<Account>;\n\n  readonly #index: number;\n\n  readonly #providers: AccountProvider<Account>[];\n\n  readonly #providersByAccountId: Map<AccountId, AccountProvider<Account>>;\n\n  readonly #accounts: Map<AccountProvider<Account>, AccountId[]>;\n\n  constructor({\n    groupIndex,\n    wallet,\n    providers,\n  }: {\n    groupIndex: number;\n    wallet: MultichainAccountWallet<Account>;\n    providers: AccountProvider<Account>[];\n  }) {\n    this.#id = toMultichainAccountId(wallet.id, groupIndex);\n    this.#index = groupIndex;\n    this.#wallet = wallet;\n    this.#providers = providers;\n    this.#accounts = new Map();\n    this.#providersByAccountId = new Map();\n\n    for (const provider of this.#providers) {\n      const accounts = provider.getAccounts({\n        entropySource: this.#wallet.entropySource,\n        groupIndex: this.#index,\n      });\n\n      this.#accounts.set(provider, accounts);\n      for (const id of accounts) {\n        this.#providersByAccountId.set(id, provider);\n      }\n    }\n  }\n\n  get id(): MultichainAccountId {\n    return this.#id;\n  }\n\n  get wallet(): MultichainAccountWallet<Account> {\n    return this.#wallet;\n  }\n\n  get index(): number {\n    return this.#index;\n  }\n\n  hasAccounts(): boolean {\n    // Use this map, cause if there's no accounts, then this map will also\n    // be empty.\n    return this.#providersByAccountId.size > 0;\n  }\n\n  getAccounts(): Account[] {\n    let allAccounts: Account[] = [];\n\n    for (const [provider, accounts] of this.#accounts.entries()) {\n      allAccounts = allAccounts.concat(\n        accounts.map((id) => provider.getAccount(id)),\n      );\n    }\n\n    return allAccounts;\n  }\n\n  getAccount(id: AccountId): Account | undefined {\n    const provider = this.#providersByAccountId.get(id);\n\n    return provider?.getAccount(id);\n  }\n\n  get(selector: MultichainAccountSelector): Account | undefined {\n    const accounts = this.select(selector);\n\n    if (accounts.length > 1) {\n      throw new Error(\n        `Too many account candidates, expected 1, got: ${accounts.length}`,\n      );\n    }\n\n    if (accounts.length === 0) {\n      return undefined;\n    }\n\n    return accounts[0]; // This is safe, see checks above.\n  }\n\n  select(selector: MultichainAccountSelector): Account[] {\n    return this.getAccounts().filter((account) => {\n      let selected = true;\n\n      if (selector.id) {\n        selected &&= account.id === selector.id;\n      }\n      if (selector.address) {\n        selected &&= account.address === selector.address;\n      }\n      if (selector.type) {\n        selected &&= account.type === selector.type;\n      }\n      if (selector.methods !== undefined) {\n        selected &&= selector.methods.some((method) =>\n          account.methods.includes(method),\n        );\n      }\n      if (selector.scopes !== undefined) {\n        selected &&= selector.scopes.some((scope) => {\n          return (\n            // This will cover specific EVM EOA scopes as well.\n            isScopeEqualToAny(scope, account.scopes)\n          );\n        });\n      }\n\n      return selected;\n    });\n  }\n}\n\nexport class MultichainAccountWalletAdapter<Account extends KeyringAccount>\n  implements MultichainAccountWallet<Account>\n{\n  readonly #id: MultichainAccountWalletId;\n\n  readonly #providers: AccountProvider<Account>[];\n\n  readonly #entropySource: EntropySourceId;\n\n  readonly #accounts: Map<number, MultichainAccount<Account>>;\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.#accounts = new Map();\n\n    let groupIndex = 0;\n    let hasAccounts = false;\n\n    do {\n      const multichainAccount = new MultichainAccountAdapter({\n        groupIndex,\n        wallet: this,\n        providers: this.#providers,\n      });\n\n      // We only add multichain account that has underlying accounts.\n      hasAccounts = multichainAccount.hasAccounts();\n      if (hasAccounts) {\n        this.#accounts.set(groupIndex, multichainAccount);\n      }\n\n      groupIndex += 1;\n    } while (hasAccounts);\n  }\n\n  get id(): MultichainAccountWalletId {\n    return this.#id;\n  }\n\n  get entropySource(): EntropySourceId {\n    return this.#entropySource;\n  }\n\n  getAccountGroup(\n    groupId: AccountGroupId,\n  ): MultichainAccount<Account> | undefined {\n    // We consider the \"default case\" to be mapped to index 0.\n    if (groupId === toDefaultAccountGroupId(this.id)) {\n      return this.#accounts.get(0);\n    }\n\n    const groupIndex = getGroupIndexFromAccountGroupId(groupId);\n    if (groupIndex === undefined) {\n      return undefined;\n    }\n    return this.#accounts.get(groupIndex);\n  }\n\n  getAccountGroups(): MultichainAccount<Account>[] {\n    return this.getMultichainAccounts();\n  }\n\n  getMultichainAccount(\n    groupIndex: number,\n  ): MultichainAccount<Account> | undefined {\n    return this.#accounts.get(groupIndex);\n  }\n\n  getMultichainAccounts(): MultichainAccount<Account>[] {\n    return Array.from(this.#accounts.values()); // TODO: Prevent copy here.\n  }\n\n  #createMultichainAccount(groupIndex: number): MultichainAccount<Account> {\n    const multichainAccount = new MultichainAccountAdapter({\n      wallet: this,\n      providers: this.#providers,\n      groupIndex,\n    });\n\n    // Register the account to our internal map.\n    this.#accounts.set(groupIndex, multichainAccount);\n\n    return multichainAccount;\n  }\n\n  getNextGroupIndex(): number {\n    // Assuming we cannot have indexes gaps.\n    return this.#accounts.size; // No +1 here, group indexes starts at 0.\n  }\n\n  async createMultichainAccount(\n    groupIndex: number,\n  ): Promise<MultichainAccount<Account>> {\n    const nextGroupIndex = this.getNextGroupIndex();\n    if (groupIndex > nextGroupIndex) {\n      throw new Error(\n        `You cannot use an group index that is higher than the next available one: expect <${nextGroupIndex}, got ${groupIndex}`,\n      );\n    }\n\n    for (const provider of this.#providers) {\n      await provider.createAccounts({\n        entropySource: this.#entropySource,\n        groupIndex,\n      });\n    }\n\n    // Re-create and \"refresh\" the multichain account (we assume all account creations are\n    // idempotent, so we should get the same accounts and potentially some new accounts (if\n    // some account providers decide to return more of them this time).\n    return this.#createMultichainAccount(groupIndex);\n  }\n\n  async createNextMultichainAccount(): Promise<MultichainAccount<Account>> {\n    return this.createMultichainAccount(this.getNextGroupIndex());\n  }\n\n  async discoverAndCreateMultichainAccounts(): Promise<\n    MultichainAccount<Account>[]\n  > {\n    const multichainAccounts: MultichainAccount<Account>[] = [];\n\n    let discovered: boolean;\n    let groupIndex = 0;\n\n    do {\n      // Keep track if any accounts got discovered for that new index.\n      discovered = false;\n\n      const missingProviders = [];\n      for (const provider of this.#providers) {\n        const discoveredAccounts = await provider.discoverAndCreateAccounts({\n          entropySource: this.#entropySource,\n          groupIndex,\n        });\n\n        if (discoveredAccounts.length) {\n          // This provider has discovered and created accounts, meaning there might\n          // be something to discover on the next index.\n          discovered = true;\n        } else {\n          // This provider did not discover or create any accounts. We mark it as\n          // \"missing\", so we can create accounts on this index if other providers\n          // did discover something.\n          missingProviders.push(provider);\n        }\n      }\n\n      if (discovered) {\n        // We only create missing accounts if one of the provider has discovered\n        // and created accounts.\n        for (const provider of missingProviders) {\n          await provider.createAccounts({\n            entropySource: this.#entropySource,\n            groupIndex,\n          });\n        }\n\n        // We've got all the accounts now, we can create our multichain account.\n        multichainAccounts.push(this.#createMultichainAccount(groupIndex));\n\n        // We have accounts, we need to check the next index.\n        groupIndex += 1;\n      }\n    } while (discovered);\n\n    return multichainAccounts;\n  }\n}\n"]}