{"version":3,"file":"BaseBip44AccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/BaseBip44AccountProvider.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uDAAuD;AAmBvD;;;;;GAKG;AACH,SAAgB,oBAAoB,CAClC,OAAuB;IAEvB,IAAI,CAAC,IAAA,4BAAc,EAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAND,oDAMC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CACpC,QAA0B;IAE1B,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;AACzC,CAAC;AAJD,wDAIC;AA6ED,MAAsB,wBAAwB;IAO5C,YAAY,SAA4C;;QAF9C,aAAQ,GAA4C,IAAI,GAAG,EAAE,CAAC;QAGtE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,IAAI,CAAC,QAAyB;QAC5B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAWD;;;;OAIG;IACH,WAAW;QACT,MAAM,WAAW,GAAG,uBAAA,IAAI,oFAAe,MAAnB,IAAI,CAAiB,CAAC;QAC1C,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC1C,gCAAgC,EAChC,WAAW,CACZ,CAAC;QACF,uEAAuE;QACvE,OAAO,gBAAwC,CAAC;IAClD,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,EAAiB;QAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEzC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,iFAAiF;QACjF,gFAAgF;QAChF,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CACxB,+BAA+B,EAC/B,EAAE,CACmB,CAAC;IAC1B,CAAC;IAED;;;;;;;;;;OAUG;IACO,KAAK,CAAC,aAAa,CAI3B,QAA4C,EAC5C,SAM6B;QAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACtC,iCAAiC,EACjC,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;IAED,SAAS,CACP,QAAgE,EAChE,UAA2B;QAE3B,OAAO,CACL,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAC1E,CAAC;IACJ,CAAC;CAuBF;AAzID,4DAyIC;;IA3GG,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC","sourcesContent":["import { isBip44Account } from '@metamask/account-api';\nimport type { AccountProvider, Bip44Account } from '@metamask/account-api';\nimport type {\n  CreateAccountOptions,\n  EntropySourceId,\n  KeyringAccount,\n} from '@metamask/keyring-api';\nimport type {\n  Keyring as KeyringV2,\n  KeyringCapabilities,\n} from '@metamask/keyring-api/v2';\nimport type {\n  KeyringMetadata,\n  KeyringSelectorV2,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\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 Bip44AccountProvider<\n  Account extends Bip44Account<KeyringAccount> = Bip44Account<KeyringAccount>,\n> = AccountProvider<Account> & {\n  /**\n   * Provider capabilities, including supported scopes and BIP-44 options.\n   *\n   * @returns The provider capabilities.\n   */\n  get capabilities(): KeyringCapabilities;\n  /**\n   * Get the name of the provider.\n   *\n   * @returns The name of the provider.\n   */\n  getName(): string;\n  /**\n   * Initialize the provider with the given accounts.\n   *\n   * @param accounts - The accounts to initialize the provider with.\n   */\n  init(accounts: Bip44Account<KeyringAccount>['id'][]): void;\n  /**\n   * Check if the account is compatible with the provider.\n   */\n  isAccountCompatible(account: Bip44Account<KeyringAccount>): boolean;\n  /**\n   * Create accounts for the provider.\n   *\n   * @param options - The options for creating the accounts.\n   * @param options.entropySource - The entropy source.\n   * @param options.groupIndex - The group index.\n   * @param options.type - The type of account creation.\n   * @returns The created accounts.\n   */\n  createAccounts(options: CreateAccountOptions): Promise<Account[]>;\n  /**\n   * Delete an account managed by this provider.\n   *\n   * Mirrors the v2 keyring `deleteAccount(accountId)` contract. Each provider\n   * implementation is responsible for resolving any extra information it needs\n   * (e.g. address for snap-based providers) and for performing the underlying\n   * keyring removal.\n   *\n   * @param id - The id of the account to delete.\n   */\n  deleteAccount(id: Account['id']): Promise<void>;\n  /**\n   * Re-synchronize MetaMask accounts and the providers accounts if needed.\n   *\n   * NOTE: This is mostly required if one of the providers (keyrings or Snaps)\n   * have different sets of accounts. This method would ensure that both are\n   * in-sync and use the same accounts (and same IDs).\n   */\n  resyncAccounts(accounts: Bip44Account<InternalAccount>[]): Promise<void>;\n  /**\n   * Check if the provider has an aligned (i.e. present and owned) account for\n   * the given entropy source and group index.\n   *\n   * Callers pre-filter the relevant account IDs from the group and pass them\n   * in so the provider needs no messenger call.\n   *\n   * @param context - The entropy source and group index to check.\n   * @param context.entropySource - The entropy source to check against.\n   * @param context.groupIndex - The group index to check against.\n   * @param accountIds - Account IDs already associated with this provider for\n   * the given group (may be empty if no alignment has happened yet).\n   * @returns `true` when `accountIds` is non-empty and every ID is in the\n   * provider's internal accounts Set.\n   */\n  isAligned(\n    context: { entropySource: EntropySourceId; groupIndex: number },\n    accountIds: Account['id'][],\n  ): boolean;\n};\n\nexport abstract class BaseBip44AccountProvider<\n  Account extends Bip44Account<KeyringAccount> = Bip44Account<KeyringAccount>,\n> implements Bip44AccountProvider<Account> {\n  protected readonly messenger: MultichainAccountServiceMessenger;\n\n  protected accounts: Set<Bip44Account<KeyringAccount>['id']> = new Set();\n\n  constructor(messenger: MultichainAccountServiceMessenger) {\n    this.messenger = messenger;\n  }\n\n  /**\n   * Add accounts to the provider.\n   *\n   * Note: There's an implicit assumption that the accounts are BIP-44 compatible.\n   *\n   * @param accounts - The accounts to add.\n   */\n  init(accounts: Account['id'][]): void {\n    for (const account of accounts) {\n      this.accounts.add(account);\n    }\n  }\n\n  /**\n   * Get the accounts list for the provider.\n   *\n   * @returns The accounts list.\n   */\n  #getAccountIds(): Account['id'][] {\n    return [...this.accounts];\n  }\n\n  /**\n   * Get the accounts list for the provider from the AccountsController.\n   *\n   * @returns The accounts list.\n   */\n  getAccounts(): Account[] {\n    const accountsIds = this.#getAccountIds();\n    const internalAccounts = this.messenger.call(\n      'AccountsController:getAccounts',\n      accountsIds,\n    );\n    // we cast here because we know that the accounts are BIP-44 compatible\n    return internalAccounts as unknown as Account[];\n  }\n\n  /**\n   * Get the account for the provider.\n   *\n   * @param id - The account ID.\n   * @returns The account.\n   * @throws If the account is not found.\n   */\n  getAccount(id: Account['id']): Account {\n    const hasAccount = this.accounts.has(id);\n\n    if (!hasAccount) {\n      throw new Error(`Unable to find account: ${id}`);\n    }\n\n    // We need to upcast here since InternalAccounts are not always BIP-44 compatible\n    // but we know that the account is BIP-44 compatible here so it is safe to do so\n    return this.messenger.call(\n      'AccountsController:getAccount',\n      id,\n    ) as unknown as Account;\n  }\n\n  /**\n   * Run an operation against a V2 keyring selected by `selector`.\n   *\n   * Forwards to `KeyringController:withKeyringV2`. Use this for keyrings\n   * that implement the unified V2 `Keyring` interface from\n   * `@metamask/keyring-api/v2`.\n   *\n   * @param selector - The selector identifying the keyring.\n   * @param operation - The operation to run with the selected keyring.\n   * @returns The result of the operation.\n   */\n  protected async withKeyringV2<\n    SelectedKeyring extends KeyringV2 = KeyringV2,\n    CallbackResult = void,\n  >(\n    selector: KeyringSelectorV2<SelectedKeyring>,\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:withKeyringV2',\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  isAligned(\n    _context: { entropySource: EntropySourceId; groupIndex: number },\n    accountIds: Account['id'][],\n  ): boolean {\n    return (\n      accountIds.length >= 1 && accountIds.every((id) => this.accounts.has(id))\n    );\n  }\n\n  abstract get capabilities(): KeyringCapabilities;\n\n  abstract getName(): string;\n\n  abstract resyncAccounts(\n    accounts: Bip44Account<InternalAccount>[],\n  ): Promise<void>;\n\n  abstract isAccountCompatible(account: Bip44Account<KeyringAccount>): boolean;\n\n  abstract createAccounts(options: CreateAccountOptions): Promise<Account[]>;\n\n  abstract deleteAccount(id: Account['id']): Promise<void>;\n\n  abstract discoverAccounts({\n    entropySource,\n    groupIndex,\n  }: {\n    entropySource: EntropySourceId;\n    groupIndex: number;\n  }): Promise<Account[]>;\n}\n"]}