{"version":3,"file":"MultichainAccountService.cjs","sourceRoot":"","sources":["../src/MultichainAccountService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAIA,uDAI+B;AAM/B,qEAA4D;AAG5D,2EAAoE;AACpE,2EAAoE;AAUpE;;;;;GAKG;AACH,SAAS,+BAA+B,CAAC,KAA6B;IACpE,OAAO,KAAK,CAAC,QAAQ,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAa,wBAAwB;IAUnC;;;;;;OAMG;IACH,YAAY,EAAE,SAAS,EAAmC;;QAhBjD,sDAA8C;QAE9C,sDAA+C;QAE/C,oDAGP;QAUA,uBAAA,IAAI,uCAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,qCAAY,IAAI,GAAG,EAAE,MAAA,CAAC;QAC1B,mFAAmF;QACnF,uBAAA,IAAI,uCAAc;YAChB,IAAI,uCAAkB,CAAC,uBAAA,IAAI,2CAAW,CAAC;YACvC,IAAI,uCAAkB,CAAC,uBAAA,IAAI,2CAAW,CAAC;SACxC,MAAA,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,oCAAoC;QACpC,MAAM,KAAK,GAAG,uBAAA,IAAI,2CAAW,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACjE,uBAAA,IAAI,kGAA6B,MAAjC,IAAI,EAA8B,KAAK,CAAC,QAAQ,CAAC,CAAC;QAElD,uBAAA,IAAI,2CAAW,CAAC,SAAS,CACvB,+BAA+B,EAC/B,CAAC,QAAQ,EAAE,EAAE;YACX,uBAAA,IAAI,kGAA6B,MAAjC,IAAI,EAA8B,QAAQ,CAAC,CAAC;QAC9C,CAAC,EACD,+BAA+B,CAChC,CAAC;IACJ,CAAC;IAuCD;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EACnB,aAAa,EACb,UAAU,GAIX;QACC,MAAM,iBAAiB,GACrB,uBAAA,IAAI,gFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAElE,IAAI,CAAC,iBAAiB,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,UAAU,EAAE,CAAC,CAAC;SACnE;QAED,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED;;;;;;;OAOG;IACH,qBAAqB,CAAC,EACpB,aAAa,GAGd;QACC,OAAO,uBAAA,IAAI,gFAAW,MAAf,IAAI,EAAY,aAAa,CAAC,CAAC,qBAAqB,EAAE,CAAC;IAChE,CAAC;CACF;AA3HD,4DA2HC;yUA9E8B,QAAyB;IACpD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;QAC9B,IAAI,OAAO,CAAC,IAAI,KAAM,iCAAY,CAAC,EAAa,EAAE;YAChD,+CAA+C;YAC/C,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAE1C,qFAAqF;YACrF,iFAAiF;YACjF,4DAA4D;YAC5D,IAAI,CAAC,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,IAAA,yCAA2B,EAAC,aAAa,CAAC,CAAC,EAAE;gBAClE,8EAA8E;gBAC9E,2DAA2D;gBAC3D,MAAM,MAAM,GAAG,IAAI,qCAAuB,CAAC;oBACzC,aAAa;oBACb,SAAS,EAAE,uBAAA,IAAI,2CAAW;iBAC3B,CAAC,CAAC;gBAEH,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;aACtC;SACF;KACF;AACH,CAAC,qFAGC,aAA8B;IAE9B,MAAM,MAAM,GAAG,uBAAA,IAAI,yCAAS,CAAC,GAAG,CAC9B,IAAA,yCAA2B,EAAC,aAAa,CAAC,CAC3C,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;KAC3E;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type {\n  MultichainAccountWalletId,\n  AccountProvider,\n} from '@metamask/account-api';\nimport {\n  MultichainAccountWallet,\n  toMultichainAccountWalletId,\n  type MultichainAccount,\n} from '@metamask/account-api';\nimport type { EntropySourceId } from '@metamask/keyring-api';\nimport type {\n  KeyringControllerState,\n  KeyringObject,\n} from '@metamask/keyring-controller';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport { EvmAccountProvider } from './providers/EvmAccountProvider';\nimport { SolAccountProvider } from './providers/SolAccountProvider';\nimport type { MultichainAccountServiceMessenger } from './types';\n\n/**\n * The options that {@link MultichainAccountService} takes.\n */\ntype MultichainAccountServiceOptions = {\n  messenger: MultichainAccountServiceMessenger;\n};\n\n/**\n * Select keyrings from keyring controller state.\n *\n * @param state - The keyring controller state.\n * @returns The keyrings.\n */\nfunction selectKeyringControllerKeyrings(state: KeyringControllerState) {\n  return state.keyrings;\n}\n\n/**\n * Service to expose multichain accounts capabilities.\n */\nexport class MultichainAccountService {\n  readonly #messenger: MultichainAccountServiceMessenger;\n\n  readonly #providers: AccountProvider<InternalAccount>[];\n\n  readonly #wallets: Map<\n    MultichainAccountWalletId,\n    MultichainAccountWallet<InternalAccount>\n  >;\n\n  /**\n   * Constructs a new MultichainAccountService.\n   *\n   * @param options - The options.\n   * @param options.messenger - The messenger suited to this\n   * MultichainAccountService.\n   */\n  constructor({ messenger }: MultichainAccountServiceOptions) {\n    this.#messenger = messenger;\n    this.#wallets = new Map();\n    // TODO: Rely on keyring capabilities once the keyring API is used by all keyrings.\n    this.#providers = [\n      new EvmAccountProvider(this.#messenger),\n      new SolAccountProvider(this.#messenger),\n    ];\n  }\n\n  /**\n   * Initialize the service and constructs the internal reprensentation of\n   * multichain accounts and wallets.\n   */\n  init(): void {\n    // Gather all entropy sources first.\n    const state = this.#messenger.call('KeyringController:getState');\n    this.#setMultichainAccountWallets(state.keyrings);\n\n    this.#messenger.subscribe(\n      'KeyringController:stateChange',\n      (keyrings) => {\n        this.#setMultichainAccountWallets(keyrings);\n      },\n      selectKeyringControllerKeyrings,\n    );\n  }\n\n  #setMultichainAccountWallets(keyrings: KeyringObject[]) {\n    for (const keyring of keyrings) {\n      if (keyring.type === (KeyringTypes.hd as string)) {\n        // Only HD keyrings have an entropy source/SRP.\n        const entropySource = keyring.metadata.id;\n\n        // Do not re-create wallets if they exists. Even if a keyrings got new accounts, this\n        // will be handled by the `*AccountProvider`s which are always in-sync with their\n        // keyrings and controllers (like the `AccountsController`).\n        if (!this.#wallets.has(toMultichainAccountWalletId(entropySource))) {\n          // This will automatically \"associate\" all multichain accounts for that wallet\n          // (based on the accounts owned by each account providers).\n          const wallet = new MultichainAccountWallet({\n            entropySource,\n            providers: this.#providers,\n          });\n\n          this.#wallets.set(wallet.id, wallet);\n        }\n      }\n    }\n  }\n\n  #getWallet(\n    entropySource: EntropySourceId,\n  ): MultichainAccountWallet<InternalAccount> {\n    const wallet = this.#wallets.get(\n      toMultichainAccountWalletId(entropySource),\n    );\n\n    if (!wallet) {\n      throw new Error('Unknown wallet, no wallet matching this entropy source');\n    }\n\n    return wallet;\n  }\n\n  /**\n   * Gets a reference to the multichain account matching this entropy source and group index.\n   *\n   * @param options - Options.\n   * @param options.entropySource - The entropy source of the multichain account.\n   * @param options.groupIndex - The group index of the multichain account.\n   * @throws If none multichain account match this entropy source and group index.\n   * @returns A reference to the multichain account.\n   */\n  getMultichainAccount({\n    entropySource,\n    groupIndex,\n  }: {\n    entropySource: EntropySourceId;\n    groupIndex: number;\n  }): MultichainAccount<InternalAccount> {\n    const multichainAccount =\n      this.#getWallet(entropySource).getMultichainAccount(groupIndex);\n\n    if (!multichainAccount) {\n      throw new Error(`No multichain account for index: ${groupIndex}`);\n    }\n\n    return multichainAccount;\n  }\n\n  /**\n   * Gets all multichain accounts for a given entropy source.\n   *\n   * @param options - Options.\n   * @param options.entropySource - The entropy source to query.\n   * @throws If no multichain accounts match this entropy source.\n   * @returns A list of all multichain accounts.\n   */\n  getMultichainAccounts({\n    entropySource,\n  }: {\n    entropySource: EntropySourceId;\n  }): MultichainAccount<InternalAccount>[] {\n    return this.#getWallet(entropySource).getMultichainAccounts();\n  }\n}\n"]}