{"version":3,"file":"index.mjs","names":["#data"],"sources":["../src/types/utils.ts","../src/keyring/encryption.ts","../src/keyring/utils.ts","../src/keyring/Keyring.ts"],"sourcesContent":["import {\n  detectAddressEncoding,\n  getAccountPlatformFromAddress,\n  getAccountPlatformFromCurve,\n  isBitcoinAddress,\n  isEthereumAddress,\n  isSolanaAddress,\n} from \"@talismn/crypto\"\n\nimport type { Account, AccountLedgerPolkadot, AccountType } from \"./account\"\n\nexport type AccountOfType<Type extends AccountType> = Extract<Account, { type: Type }>\n\nexport const isAccountOfType = <Type extends AccountType>(\n  account: Account | null | undefined,\n  type: Type\n): account is AccountOfType<Type> => {\n  return account?.type === type\n}\n\nexport const isAccountInTypes = <Types extends AccountType[]>(\n  account: Account | null | undefined,\n  types: Types\n): account is AccountOfType<Types[number]> => {\n  return !!account && types.includes(account.type)\n}\n\nconst ACCOUNT_TYPES_OWNED = [\n  \"keypair\",\n  \"ledger-ethereum\",\n  \"ledger-polkadot\",\n  \"ledger-solana\",\n  \"polkadot-vault\",\n] as const\n\nconst ACCOUNT_TYPES_EXTERNAL = [\n  \"contact\",\n  \"watch-only\",\n  \"ledger-ethereum\",\n  \"ledger-polkadot\",\n  \"ledger-solana\",\n  \"polkadot-vault\",\n  \"signet\",\n] as const\n\nconst ACCOUNT_TYPES_ADDRESS_ETHEREUM = [\n  \"contact\",\n  \"watch-only\",\n  \"keypair\",\n  \"ledger-ethereum\",\n  \"ledger-polkadot\",\n] as const\n\nconst ACCOUNT_TYPES_PLATFORM_ETHEREUM = [\n  \"contact\",\n  \"watch-only\",\n  \"keypair\",\n  \"ledger-ethereum\",\n] as const\n\nconst ACCOUNT_TYPES_PLATFORM_POLKADOT = [\n  \"contact\",\n  \"watch-only\",\n  \"keypair\",\n  \"ledger-polkadot\",\n  \"polkadot-vault\",\n  \"signet\",\n] as const\n\nconst ACCOUNT_TYPES_ADDRESS_SS58 = [\n  \"contact\",\n  \"watch-only\",\n  \"keypair\",\n  \"ledger-polkadot\",\n  \"polkadot-vault\",\n  \"signet\",\n] as const\n\nconst ACCOUNT_TYPES_PLATFORM_SOLANA = [\"contact\", \"watch-only\", \"keypair\", \"ledger-solana\"] as const\n\nconst ACCOUNT_TYPES_BITCOIN = [\"contact\", \"watch-only\"] as const\n\nexport const isAccountExternal = (\n  account: Account | null | undefined\n): account is AccountOfType<(typeof ACCOUNT_TYPES_EXTERNAL)[number]> => {\n  return isAccountInTypes(account, ACCOUNT_TYPES_EXTERNAL as unknown as AccountType[])\n}\n\nexport const isAccountOwned = (\n  account: Account | null | undefined\n): account is AccountOfType<(typeof ACCOUNT_TYPES_OWNED)[number]> => {\n  return isAccountInTypes(account, ACCOUNT_TYPES_OWNED as unknown as AccountType[])\n}\n\nexport const isAccountPortfolio = (account: Account | null | undefined): account is Account => {\n  return isAccountOwned(account) || (isAccountOfType(account, \"watch-only\") && account.isPortfolio)\n}\n\nexport const isAccountNotContact = (acc: Account) => acc.type !== \"contact\"\n\ntype AccountAddressEthereum = Extract<\n  Account,\n  { type: (typeof ACCOUNT_TYPES_ADDRESS_ETHEREUM)[number] }\n> & {\n  address: `0x${string}`\n}\nexport const isAccountAddressEthereum = (\n  account: Account | null | undefined\n): account is AccountAddressEthereum => {\n  return !!account && isEthereumAddress(account.address)\n}\n\ntype AccountPlatformEthereum = Extract<\n  Account,\n  { type: (typeof ACCOUNT_TYPES_PLATFORM_ETHEREUM)[number] }\n> & {\n  address: `0x${string}`\n}\nexport const isAccountPlatformEthereum = (\n  account: Account | null | undefined\n): account is AccountPlatformEthereum => {\n  return !!account && account.type !== \"ledger-polkadot\" && isEthereumAddress(account.address)\n}\n\ntype AccountPlatformSolana = Extract<\n  Account,\n  { type: (typeof ACCOUNT_TYPES_PLATFORM_SOLANA)[number] }\n>\n\nexport const isAccountPlatformSolana = (\n  account: Account | null | undefined\n): account is AccountPlatformSolana => {\n  return !!account && isSolanaAddress(account.address)\n}\n\ntype AccountPlatformPolkadot = Extract<\n  Account,\n  { type: (typeof ACCOUNT_TYPES_PLATFORM_POLKADOT)[number] }\n>\nexport const isAccountPlatformPolkadot = (\n  account: Account | null | undefined\n): account is AccountPlatformPolkadot => {\n  return (\n    !!account &&\n    account.type !== \"ledger-ethereum\" &&\n    (isAccountAddressEthereum(account) || isAccountAddressSs58(account))\n  )\n}\n\ntype AccountAddressSs58 = Extract<\n  Account,\n  { type: (typeof ACCOUNT_TYPES_ADDRESS_SS58)[number] }\n> & {\n  genesisHash?: `0x${string}`\n}\nexport const isAccountAddressSs58 = (\n  account: Account | null | undefined\n): account is AccountAddressSs58 => {\n  return !!account && detectAddressEncoding(account.address) === \"ss58\"\n}\n\nexport const isAccountLedgerPolkadot = (\n  account: Account | null | undefined\n): account is AccountLedgerPolkadot => {\n  return isAccountOfType(account, \"ledger-polkadot\")\n}\n\nexport const isAccountLedgerPolkadotGeneric = (\n  account: Account | null | undefined\n): account is AccountLedgerPolkadot & { genesisHash: undefined } => {\n  return isAccountOfType(account, \"ledger-polkadot\") && !account.genesisHash\n}\n\nexport const isAccountLedgerPolkadotLegacy = (\n  account: Account | null | undefined\n): account is AccountLedgerPolkadot & { genesisHash: `0x${string}` } => {\n  return isAccountOfType(account, \"ledger-polkadot\") && !!account.genesisHash\n}\n\ntype AccountBitcoin = Extract<Account, { type: (typeof ACCOUNT_TYPES_BITCOIN)[number] }>\nexport const isAccountBitcoin = (\n  account: Account | null | undefined\n): account is AccountBitcoin => {\n  return !!account && isBitcoinAddress(account.address)\n}\n\nexport const getAccountGenesisHash = (account: Account | null | undefined) => {\n  if (!account) return undefined\n  return \"genesisHash\" in account ? account.genesisHash || undefined : undefined\n}\n\nexport const getAccountSignetUrl = (account: Account | null | undefined) => {\n  return isAccountOfType(account, \"signet\") ? account.url : undefined\n}\n\nexport const getAccountPlatform = (account: Account | null | undefined) => {\n  if (!account) return undefined\n  return \"curve\" in account\n    ? getAccountPlatformFromCurve(account.curve)\n    : getAccountPlatformFromAddress(account.address)\n}\n","import { pbkdf2 } from \"@talismn/crypto\"\n\n// Derive a key generated with PBKDF2 that will be used for AES-GCM encryption\nconst deriveKey = async (password: string, salt: Uint8Array): Promise<CryptoKey> =>\n  // Deriving 32-byte key using PBKDF2 with 100,000 iterations and SHA-256\n  await crypto.subtle.importKey(\n    \"raw\",\n    await pbkdf2(\n      \"SHA-256\",\n      new TextEncoder().encode(password),\n      salt,\n      100_000, // 100,000 iterations\n      32 // 32 bytes (32 * 8 == 256 bits)\n    ),\n    { name: \"AES-GCM\", length: 256 },\n    false,\n    [\"encrypt\", \"decrypt\"]\n  )\n\nexport const encryptData = async (data: Uint8Array, password: string): Promise<string> => {\n  try {\n    const salt = crypto.getRandomValues(new Uint8Array(16)) // 16 bytes of salt\n    const iv = crypto.getRandomValues(new Uint8Array(12)) // 12-byte IV for AES-GCM\n    const key = await deriveKey(password, salt)\n\n    // encrypt\n    const encryptedSeed = await crypto.subtle.encrypt(\n      { name: \"AES-GCM\", iv },\n      key,\n      data as Uint8Array<ArrayBuffer>\n    )\n\n    // Combine salt, IV, and encrypted seed\n    const combined = new Uint8Array(salt.length + iv.length + encryptedSeed.byteLength)\n    combined.set(salt, 0)\n    combined.set(iv, salt.length)\n    combined.set(new Uint8Array(encryptedSeed), salt.length + iv.length)\n\n    // Base64 encode the combined data\n    return btoa(String.fromCharCode(...combined))\n  } catch (cause) {\n    throw new Error(\"Failed to encrypt data\", { cause })\n  }\n}\n\nexport const decryptData = async (encryptedData: string, password: string): Promise<Uint8Array> => {\n  try {\n    // Decode Base64 and parse the combined data\n    const combined = Uint8Array.from(atob(encryptedData), (c) => c.charCodeAt(0))\n\n    // Extract salt, IV, and encrypted seed\n    const salt = combined.slice(0, 16) // First 16 bytes\n    const iv = combined.slice(16, 28) // Next 12 bytes\n    const encryptedSeed = combined.slice(28) // Remaining bytes\n\n    const key = await deriveKey(password, salt)\n\n    // Decrypt the seed\n    const decryptedSeed = await crypto.subtle.decrypt({ name: \"AES-GCM\", iv }, key, encryptedSeed)\n\n    return new Uint8Array(decryptedSeed)\n  } catch (cause) {\n    throw new Error(\"Failed to decrypt data\", { cause })\n  }\n}\n\nexport const changeEncryptedDataPassword = async (\n  encryptedData: string,\n  oldPassword: string,\n  newPassword: string\n) => {\n  try {\n    const decrypted = await decryptData(encryptedData, oldPassword)\n    return await encryptData(decrypted, newPassword)\n  } catch (cause) {\n    throw new Error(\"Failed to change password on encrypted data\", { cause })\n  }\n}\n","// we dont want to reference @talismn/util in the keyring, so we copy this here\ntype HexString = `0x${string}`\n\nconst REGEX_HEX_STRING = /^0x[0-9a-fA-F]*$/\n\nexport const isHexString = (value: unknown): value is HexString => {\n  return typeof value === \"string\" && REGEX_HEX_STRING.test(value)\n}\n","import {\n  addressEncodingFromCurve,\n  addressFromPublicKey,\n  base58,\n  blake3,\n  deriveKeypair,\n  entropyToMnemonic,\n  entropyToSeed,\n  getPublicKeyFromSecret,\n  isAddressEqual,\n  isValidMnemonic,\n  type KeypairCurve,\n  mnemonicToEntropy,\n  normalizeAddress,\n  utf8,\n} from \"@talismn/crypto\"\n\nimport type { Account, Mnemonic } from \"../types\"\nimport { isAccountExternal } from \"../types\"\nimport type {\n  AddAccountDeriveOptions,\n  AddAccountExternalOptions,\n  AddAccountKeypairOptions,\n  AddMnemonicOptions,\n  UpdateAccountOptions,\n  UpdateMnemonicOptions,\n} from \"../types/keyring\"\nimport { changeEncryptedDataPassword, decryptData, encryptData } from \"./encryption\"\nimport type { AccountStorage, MnemonicStorage } from \"./types\"\nimport { isHexString } from \"./utils\"\n\nexport type KeyringStorage = {\n  passwordCheck: string | null // well-known data encrypted using the password, used to ensure all secrets of the keyring are encrypted with the same password\n  mnemonics: MnemonicStorage[]\n  accounts: AccountStorage[]\n}\n\nexport class Keyring {\n  #data: KeyringStorage\n\n  protected constructor(data: KeyringStorage) {\n    this.#data = structuredClone(data)\n  }\n\n  public static create(): Keyring {\n    return new Keyring({\n      passwordCheck: null, // well-known data encrypted using the password, used to ensure all secrets of the keyring are encrypted with the same password\n      mnemonics: [],\n      accounts: [],\n    })\n  }\n\n  public static load(data: KeyringStorage): Keyring {\n    if (!data.accounts || !data.mnemonics) throw new Error(\"Invalid data\")\n\n    // automatic upgrade : set default values for newly introduced properties\n    for (const account of data.accounts) {\n      // @ts-expect-error\n      if (account.type === \"ledger-polkadot\" && !account.curve) account.curve = \"ed25519\"\n    }\n\n    return new Keyring(data)\n  }\n\n  private async checkPassword(password: string, reset = false) {\n    if (typeof password !== \"string\" || !password) throw new Error(\"password is required\")\n\n    const passwordHash = oneWayHash(password)\n    const PASSWORD_CHECK_PHRASE = \"PASSWORD_CHECK_PHRASE\"\n\n    // run through same complexity as for other secrets, to make it so it s not easier to brute force passwordCheck than other secrets\n    if (!this.#data.passwordCheck || reset) {\n      const bytes = utf8.decode(PASSWORD_CHECK_PHRASE)\n      this.#data.passwordCheck = await encryptData(bytes, passwordHash)\n    } else {\n      try {\n        const bytes = await decryptData(this.#data.passwordCheck, passwordHash)\n        const text = utf8.encode(bytes)\n        if (text !== PASSWORD_CHECK_PHRASE) throw new Error(\"Invalid password\")\n      } catch {\n        throw new Error(\"Invalid password\")\n      }\n    }\n  }\n\n  /** Returns true if a password has been set on this keyring. */\n  public hasPassword(): boolean {\n    return this.#data.passwordCheck !== null\n  }\n\n  /**\n   * Verify a password against the keyring's passwordCheck blob.\n   * Returns true on success, false on wrong password.\n   * Throws if no password has been set (caller should check hasPassword() first).\n   */\n  public async verifyPassword(password: string): Promise<boolean> {\n    if (!this.#data.passwordCheck) {\n      throw new Error(\"No password set — call hasPassword() before verifyPassword()\")\n    }\n    try {\n      await this.checkPassword(password)\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  /**\n   * Initialize the password on a fresh keyring that has no password set.\n   * Throws if a password is already set (use changePassword flow instead).\n   */\n  public async initializePassword(password: string): Promise<void> {\n    if (this.#data.passwordCheck !== null) {\n      throw new Error(\"Password already set — cannot re-initialize\")\n    }\n    await this.checkPassword(password, true)\n  }\n\n  public toJson() {\n    return structuredClone(this.#data)\n  }\n\n  public async export(password: string, jsonPassword: string): Promise<KeyringStorage> {\n    const keyring = new Keyring(structuredClone(this.#data))\n\n    for (const mnemonic of keyring.#data.mnemonics)\n      mnemonic.entropy = await changeEncryptedDataPassword(mnemonic.entropy, password, jsonPassword)\n\n    for (const account of keyring.#data.accounts)\n      if (account.type === \"keypair\")\n        account.secretKey = await changeEncryptedDataPassword(\n          account.secretKey,\n          password,\n          jsonPassword\n        )\n\n    // reset password check\n    await keyring.checkPassword(jsonPassword, true)\n\n    return keyring.toJson()\n  }\n\n  public getMnemonics(): Mnemonic[] {\n    return this.#data.mnemonics.map(mnemonicFromStorage)\n  }\n\n  public async addMnemonic(\n    { name, mnemonic, confirmed }: AddMnemonicOptions,\n    password: string\n  ): Promise<Mnemonic> {\n    if (typeof name !== \"string\" || !name) throw new Error(\"name is required\")\n    if (typeof mnemonic !== \"string\") throw new Error(\"mnemonic is required\")\n    if (typeof confirmed !== \"boolean\") throw new Error(\"confirmed is required\")\n    if (!isValidMnemonic(mnemonic)) throw new Error(\"Invalid mnemonic\")\n\n    await this.checkPassword(password)\n\n    const entropy = mnemonicToEntropy(mnemonic)\n\n    // id is a hash of the entropy, helps us prevent having duplicates and allows automatic remapping of accounts/mnemonics if mnemonics are deleted then re-added\n    const id = oneWayHash(entropy)\n\n    if (this.#data.mnemonics.find((s) => s.id === id)) throw new Error(\"Mnemonic already exists\")\n\n    const storage: MnemonicStorage = {\n      id,\n      name,\n      entropy: await encryptData(entropy, password),\n      confirmed,\n      createdAt: Date.now(),\n    }\n\n    this.#data.mnemonics.push(storage)\n\n    return mnemonicFromStorage(storage)\n  }\n\n  public getMnemonic(id: string): Mnemonic | null {\n    const mnemonic = this.#data.mnemonics.find((s) => s.id === id)\n    return mnemonic ? mnemonicFromStorage(mnemonic) : null\n  }\n\n  public updateMnemonic(id: string, { name, confirmed }: UpdateMnemonicOptions) {\n    const mnemonic = this.#data.mnemonics.find((s) => s.id === id)\n    if (!mnemonic) throw new Error(\"Mnemonic not found\")\n    if (name !== undefined) {\n      if (typeof name !== \"string\" || !name) throw new Error(\"name must be a string\")\n      mnemonic.name = name\n    }\n    if (confirmed !== undefined) {\n      if (typeof confirmed !== \"boolean\") throw new Error(\"confirmed must be a boolean\")\n      mnemonic.confirmed = confirmed\n    }\n    return mnemonicFromStorage(mnemonic)\n  }\n\n  public removeMnemonic(id: string) {\n    const index = this.#data.mnemonics.findIndex((mnemonic) => mnemonic.id === id)\n    if (index === -1) throw new Error(\"Mnemonic not found\")\n    this.#data.mnemonics.splice(index, 1)\n  }\n\n  async getMnemonicText(id: string, password: string): Promise<string> {\n    const mnemonic = this.#data.mnemonics.find((s) => s.id === id)\n    if (!mnemonic) throw new Error(\"Mnemonic not found\")\n\n    const entropy = await decryptData(mnemonic.entropy, password)\n\n    return entropyToMnemonic(entropy)\n  }\n\n  public getExistingMnemonicId(mnemonic: string): string | null {\n    const entropy = mnemonicToEntropy(mnemonic)\n    const mnemonicId = oneWayHash(entropy)\n    return this.#data.mnemonics.some((s) => s.id === mnemonicId) ? mnemonicId : null\n  }\n\n  public getAccounts(): Account[] {\n    return this.#data.accounts.map(accountFromStorage)\n  }\n\n  public getAccount(address: string): Account | null {\n    const account = this.#data.accounts.find((s) => isAddressEqual(s.address, address))\n    return account ? accountFromStorage(account) : null\n  }\n\n  public updateAccount(address: string, { name, isPortfolio, genesisHash }: UpdateAccountOptions) {\n    const account = this.#data.accounts.find((s) => s.address === address)\n    if (!account) throw new Error(\"Account not found\")\n\n    if (name) {\n      if (typeof name !== \"string\" || !name) throw new Error(\"name is required\")\n      account.name = name\n    }\n    if (account.type === \"watch-only\" && isPortfolio !== undefined) {\n      if (typeof isPortfolio !== \"boolean\") throw new Error(\"isPortfolio must be a boolean\")\n      account.isPortfolio = isPortfolio\n    }\n    // allow updating genesisHash only for contacts\n    if (account.type === \"contact\") {\n      if (genesisHash) {\n        if (!isHexString(genesisHash)) throw new Error(\"genesisHash must be a hex string\")\n        account.genesisHash = genesisHash\n      } else delete account.genesisHash\n    }\n\n    return accountFromStorage(account)\n  }\n\n  public removeAccount(address: string) {\n    const index = this.#data.accounts.findIndex((s) => isAddressEqual(s.address, address))\n    if (index === -1) throw new Error(\"Account not found\")\n    this.#data.accounts.splice(index, 1)\n  }\n\n  public addAccountExternal(options: AddAccountExternalOptions): Account {\n    const address = normalizeAddress(options.address) // breaks if invalid address\n\n    if (this.getAccount(address)) throw new Error(\"Account already exists\")\n\n    const account: AccountStorage = {\n      ...options,\n      address,\n      createdAt: Date.now(),\n    }\n\n    if (!isAccountExternal(account)) throw new Error(\"Invalid account type\")\n\n    this.#data.accounts.push(account)\n\n    return accountFromStorage(account)\n  }\n\n  /**\n   * Needs to be called before deriving an account from a mnemonic.\n   *\n   * This will ensure that it is present (or add it if possible) in the keyring before actually creating the account.\n   *\n   * @param options\n   * @param password\n   * @returns the id of the mnemonic\n   */\n  private async ensureMnemonic(options: AddAccountDeriveOptions, password: string) {\n    await this.checkPassword(password)\n\n    switch (options.type) {\n      case \"new-mnemonic\": {\n        const { mnemonic, mnemonicName: name, confirmed } = options\n\n        if (typeof name !== \"string\" || !name) throw new Error(\"mnemonicName is required\")\n        if (typeof confirmed !== \"boolean\") throw new Error(\"confirmed is required\")\n\n        const mnemonicId = this.getExistingMnemonicId(mnemonic)\n        if (mnemonicId) return mnemonicId\n\n        const { id } = await this.addMnemonic(\n          {\n            name,\n            mnemonic,\n            confirmed,\n          },\n          password\n        )\n\n        return id\n      }\n      case \"existing-mnemonic\": {\n        if (typeof options.mnemonicId !== \"string\" || !options.mnemonicId)\n          throw new Error(\"mnemonicId must be a string\")\n\n        return options.mnemonicId\n      }\n    }\n  }\n\n  public async addAccountDerive(\n    options: AddAccountDeriveOptions,\n    password: string\n  ): Promise<Account> {\n    await this.checkPassword(password)\n\n    const { curve, derivationPath, name } = options\n\n    const mnemonicId = await this.ensureMnemonic(options, password)\n\n    const mnemonic = this.#data.mnemonics.find((s) => s.id === mnemonicId)\n    if (!mnemonic) throw new Error(\"Mnemonic not found\")\n\n    const entropy = await decryptData(mnemonic.entropy, password)\n    const seed = await entropyToSeed(entropy, curve)\n    const pair = deriveKeypair(seed, derivationPath, curve)\n\n    if (this.getAccount(pair.address)) throw new Error(\"Account already exists\")\n\n    const account: AccountStorage = {\n      type: \"keypair\",\n      curve,\n      name,\n      address: normalizeAddress(pair.address),\n      secretKey: await encryptData(pair.secretKey, password),\n      mnemonicId,\n      derivationPath,\n      createdAt: Date.now(),\n    }\n\n    this.#data.accounts.push(account)\n\n    return accountFromStorage(account)\n  }\n\n  public async addAccountKeypair(\n    { curve, name, secretKey }: AddAccountKeypairOptions,\n    password: string\n  ): Promise<Account> {\n    await this.checkPassword(password)\n\n    const publicKey = getPublicKeyFromSecret(secretKey, curve)\n    const encoding = addressEncodingFromCurve(curve)\n    const address = addressFromPublicKey(publicKey, encoding)\n\n    if (this.getAccount(address)) throw new Error(\"Account already exists\")\n\n    const account: AccountStorage = {\n      type: \"keypair\",\n      curve,\n      name,\n      address: normalizeAddress(address),\n      secretKey: await encryptData(secretKey, password),\n      createdAt: Date.now(),\n    }\n\n    this.#data.accounts.push(account)\n\n    return accountFromStorage(account)\n  }\n\n  public getAccountSecretKey(address: string, password: string): Promise<Uint8Array> {\n    if (typeof address !== \"string\" || !address) throw new Error(\"address is required\")\n    if (typeof password !== \"string\" || !password) throw new Error(\"password is required\")\n\n    const account = this.#data.accounts.find((a) => a.address === normalizeAddress(address))\n    if (!account) throw new Error(\"Account not found\")\n    if (account.type !== \"keypair\") throw new Error(\"Secret key unavailable\")\n\n    return decryptData(account.secretKey, password)\n  }\n\n  public async getDerivedAddress(\n    mnemonicId: string,\n    derivationPath: string,\n    curve: KeypairCurve,\n    password: string\n  ): Promise<string> {\n    if (typeof mnemonicId !== \"string\" || !mnemonicId) throw new Error(\"mnemonicId is required\")\n    if (typeof password !== \"string\" || !password) throw new Error(\"password is required\")\n\n    const mnemonic = this.#data.mnemonics.find((s) => s.id === mnemonicId)\n    if (!mnemonic) throw new Error(\"Mnemonic not found\")\n\n    const entropy = await decryptData(mnemonic.entropy, password)\n    const seed = await entropyToSeed(entropy, curve)\n    const pair = deriveKeypair(seed, derivationPath, curve)\n\n    return pair.address\n  }\n}\n\nconst oneWayHash = (bytes: Uint8Array | string) => {\n  if (typeof bytes === \"string\") bytes = utf8.decode(bytes)\n\n  // cryptographically secure one way hash\n  // outputs 44 characters without special characters\n  return base58.encode(blake3(bytes))\n}\n\nconst mnemonicFromStorage = (data: MnemonicStorage): Mnemonic => {\n  const copy = structuredClone(data) as Mnemonic\n  if (\"entropy\" in copy) delete copy.entropy\n  return Object.freeze(copy)\n}\n\nconst accountFromStorage = (data: AccountStorage): Account => {\n  const copy = structuredClone(data) as Account\n  if (\"secretKey\" in copy) delete copy.secretKey\n  return Object.freeze(copy)\n}\n"],"mappings":"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"}