{"version":3,"file":"simple-keyring.mjs","sourceRoot":"","sources":["../../src/v2/simple-keyring.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n  EthAccountType,\n  EthMethod,\n  EthScope,\n  KeyringAccountEntropyTypeOption,\n} from '@metamask/keyring-api';\nimport type { KeyringAccount } from '@metamask/keyring-api';\nimport { KeyringType, PrivateKeyEncoding } from '@metamask/keyring-api/v2';\nimport type {\n  CreateAccountOptions,\n  ExportAccountOptions,\n  ExportedAccount,\n  KeyringCapabilities,\n  Keyring,\n} from '@metamask/keyring-api/v2';\nimport { EthKeyringMethod, EthKeyringWrapper } from '@metamask/keyring-sdk/v2';\nimport type { AccountId } from '@metamask/keyring-utils';\nimport { add0x } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport type LegacySimpleKeyring from '../simple-keyring';\n\n/**\n * Methods supported by SimpleKeyring EOA accounts.\n * SimpleKeyring supports all standard signing methods plus encryption and app keys.\n */\nconst SIMPLE_KEYRING_METHODS = [\n  EthMethod.SignTransaction,\n  EthMethod.Sign,\n  EthMethod.PersonalSign,\n  EthMethod.SignTypedDataV1,\n  EthMethod.SignTypedDataV3,\n  EthMethod.SignTypedDataV4,\n  EthKeyringMethod.Decrypt,\n  EthKeyringMethod.GetEncryptionPublicKey,\n  EthKeyringMethod.GetAppKeyAddress,\n  EthKeyringMethod.SignEip7702Authorization,\n];\n\nconst simpleKeyringCapabilities: KeyringCapabilities = {\n  scopes: [EthScope.Eoa],\n  privateKey: {\n    importFormats: [\n      { encoding: PrivateKeyEncoding.Hexadecimal, type: EthAccountType.Eoa },\n    ],\n    exportFormats: [{ encoding: PrivateKeyEncoding.Hexadecimal }],\n  },\n};\n\n/**\n * Concrete {@link Keyring} adapter for {@link SimpleKeyring}.\n *\n * This wrapper exposes the accounts and signing capabilities of the legacy\n * SimpleKeyring via the unified V2 interface.\n */\nexport type SimpleKeyringOptions = {\n  legacyKeyring: LegacySimpleKeyring;\n};\n\nexport class SimpleKeyring\n  extends EthKeyringWrapper<LegacySimpleKeyring>\n  implements Keyring\n{\n  constructor(options: SimpleKeyringOptions) {\n    super({\n      type: KeyringType.PrivateKey,\n      inner: options.legacyKeyring,\n      capabilities: simpleKeyringCapabilities,\n    });\n  }\n\n  /**\n   * Creates a KeyringAccount object for the given address and index.\n   *\n   * @param address - The account address.\n   * @returns The created KeyringAccount.\n   */\n  #createKeyringAccount(address: Hex): KeyringAccount {\n    const id = this.registry.register(address);\n\n    const account: KeyringAccount = {\n      id,\n      type: EthAccountType.Eoa,\n      address,\n      scopes: [...this.capabilities.scopes],\n      methods: [...SIMPLE_KEYRING_METHODS],\n      options: {\n        entropy: {\n          type: KeyringAccountEntropyTypeOption.PrivateKey,\n        },\n        exportable: true,\n      },\n    };\n\n    // Add the account to the registry\n    this.registry.set(account);\n\n    return account;\n  }\n\n  /**\n   * Get all private keys from the inner SimpleKeyring.\n   *\n   * @returns An array of private keys in hexadecimal format.\n   */\n  async #getPrivateKeys(): Promise<string[]> {\n    return await this.inner.serialize();\n  }\n\n  /**\n   * Set private keys in the inner SimpleKeyring.\n   *\n   * @param privateKeys - An array of private keys in hexadecimal format.\n   */\n  async #setPrivateKeys(privateKeys: string[]): Promise<void> {\n    await this.inner.deserialize(privateKeys);\n  }\n\n  /**\n   * Executes a transactional update on the inner keyring state.\n   * If the callback throws, the state is automatically rolled back.\n   *\n   * @param callback - A function that receives the current private keys and performs the update.\n   * Should return the result on success, or throw to trigger rollback.\n   * @returns The result of the callback.\n   * @throws Error if the callback throws (after rollback).\n   */\n  async #withRollback<Result>(\n    callback: (currentPrivateKeys: string[]) => Promise<Result>,\n  ): Promise<Result> {\n    const originalPrivateKeys = await this.#getPrivateKeys();\n\n    try {\n      return await callback(originalPrivateKeys);\n    } catch (error) {\n      // Rollback on error\n      await this.#setPrivateKeys(originalPrivateKeys);\n      throw error;\n    }\n  }\n\n  /**\n   * Import a private key and return the new address.\n   * If the import fails (no new address added), rolls back to the original state.\n   *\n   * @param privateKey - The private key to import in hexadecimal format.\n   * @returns The address of the newly imported account.\n   * @throws Error if the import fails or no new address is added.\n   */\n  async #importPrivateKeyOrRollback(privateKey: string): Promise<Hex> {\n    return this.#withRollback(async (currentPrivateKeys) => {\n      // Get current addresses before import\n      const addressesBefore = new Set(await this.inner.getAccounts());\n\n      // Import the new private key\n      await this.#setPrivateKeys([...currentPrivateKeys, privateKey]);\n\n      // Get addresses after import and find the newly added one\n      const addressesAfter = await this.inner.getAccounts();\n\n      // Find the new address by diffing the two sets\n      const newAddresses = addressesAfter.filter(\n        (addr) => !addressesBefore.has(addr),\n      );\n\n      if (newAddresses.length !== 1 || !newAddresses[0]) {\n        throw new Error('Failed to import private key');\n      }\n\n      return newAddresses[0];\n    });\n  }\n\n  async getAccounts(): Promise<KeyringAccount[]> {\n    const addresses = await this.inner.getAccounts();\n\n    return addresses.map((address) => {\n      // Check if we already have this account in the registry\n      const existingId = this.registry.getAccountId(address);\n      if (existingId) {\n        const cached = this.registry.get(existingId);\n        if (cached) {\n          return cached;\n        }\n      }\n\n      // Create and register the account if not already cached\n      return this.#createKeyringAccount(address);\n    });\n  }\n\n  async createAccounts(\n    options: CreateAccountOptions,\n  ): Promise<KeyringAccount[]> {\n    return this.withLock(async () => {\n      // For SimpleKeyring, we only support private key import\n      if (options.type !== 'private-key:import') {\n        throw new Error(\n          `Unsupported account creation type for SimpleKeyring: ${options.type}`,\n        );\n      }\n\n      // Validate account type\n      if (options.accountType !== EthAccountType.Eoa) {\n        throw new Error(\n          `Unsupported account type for SimpleKeyring: ${options.accountType}. Only '${EthAccountType.Eoa}' is supported.`,\n        );\n      }\n\n      const { encoding, privateKey } = options;\n\n      // Validate encoding\n      if (encoding !== PrivateKeyEncoding.Hexadecimal) {\n        throw new Error(\n          `Unsupported encoding for SimpleKeyring: ${encoding}. Only '${PrivateKeyEncoding.Hexadecimal}' is supported.`,\n        );\n      }\n\n      // Import the private key (with automatic rollback on failure)\n      const newAddress = await this.#importPrivateKeyOrRollback(privateKey);\n\n      // Create and return the new KeyringAccount\n      const newAccount = this.#createKeyringAccount(newAddress);\n      return [newAccount];\n    });\n  }\n\n  /**\n   * Delete an account from the keyring.\n   *\n   * @param accountId - The account ID to delete.\n   */\n  async deleteAccount(accountId: AccountId): Promise<void> {\n    await this.withLock(async () => {\n      const account = await this.getAccount(accountId);\n\n      // Remove from the legacy keyring\n      this.inner.removeAccount(account.address);\n\n      // Remove from the registry\n      this.registry.delete(accountId);\n    });\n  }\n\n  /**\n   * Export the private key for an account in hexadecimal format.\n   *\n   * @param accountId - The ID of the account to export.\n   * @param options - Export options (only hexadecimal encoding is supported).\n   * @returns The exported account with private key.\n   */\n  async exportAccount(\n    accountId: AccountId,\n    options?: ExportAccountOptions,\n  ): Promise<ExportedAccount> {\n    const account = await this.getAccount(accountId);\n\n    const requestedEncoding =\n      options?.encoding ?? PrivateKeyEncoding.Hexadecimal;\n\n    if (requestedEncoding !== PrivateKeyEncoding.Hexadecimal) {\n      throw new Error(\n        `Unsupported encoding for SimpleKeyring: ${requestedEncoding}. Only '${PrivateKeyEncoding.Hexadecimal}' is supported.`,\n      );\n    }\n\n    const privateKeyHex = await this.inner.exportAccount(\n      this.toHexAddress(account.address),\n    );\n    // Sanitize private key format\n    const privateKey = add0x(privateKeyHex);\n\n    const exported: ExportedAccount = {\n      type: 'private-key',\n      privateKey,\n      encoding: PrivateKeyEncoding.Hexadecimal,\n    };\n\n    return exported;\n  }\n}\n"]}