{"version":3,"file":"base-signer.cjs","names":["z","z","#generator","#storage","#ttl","#logger","#pending","swallow","#storage","#logger","#deleteScope","#untrackScope","swallow","#trackScope","#readIndex","#vault","#store","#relayer","#signer","#permitTTL","#logger","#signPermit","swallow","ZamaError","wrapSigningError","#logger","#prefix","#map","IndexedDBStorage","ConfigurationError","#chains","#relayers","#workers","ConfigurationError","#chainId","#active","toError","mainnet","sepolia","hoodi","ingenTestnet","bscTestnet","z","#addresses","#ttlMs","#cache","parseConfiguration","ConfigurationError","#getCached","getTokenPairsLengthContract","#setCached","getTokenPairsSliceContract","#pairWithMetadata","nameContract","symbolContract","decimalsContract","erc20TotalSupplyContract","getConfidentialTokenAddressContract","zeroAddress","getTokenAddressContract","getTokenPairsContract","getTokenPairContract","isConfidentialTokenValidContract","parseConfiguration","#listeners","#snapshot","#resolved","#emit","WalletNotConnectedError","#disposed"],"sources":["../../src/credentials/storage-keys.ts","../../src/schemas/primitives.ts","../../src/credentials/utils.ts","../../src/credentials/schemas.ts","../../src/credentials/keypair-vault.ts","../../src/credentials/permissions.ts","../../src/credentials/permission-store.ts","../../src/credentials/credential-service.ts","../../src/services/logger-service.ts","../../src/storage/memory-storage.ts","../../src/config/resolve.ts","../../src/relayer/relayer-dispatcher.ts","../../src/wrappers-registry.ts","../../src/config/build.ts","../../src/signer/wallet-account-store.ts","../../src/signer/base-signer.ts"],"sourcesContent":["import type { ChecksummedAddress } from \"../schemas/primitives\";\n\nexport interface PermissionScope {\n  signerAddress: ChecksummedAddress;\n  chainId: number;\n  delegatorAddress: ChecksummedAddress;\n}\n\nexport function transportKeyPairStorageKey(signerAddress: ChecksummedAddress): string {\n  // The \"keypair:\" prefix is intentionally preserved for back-compat with already-persisted entries.\n  return `keypair:${signerAddress}`;\n}\n\nexport function permissionScopeKey(scope: PermissionScope): string {\n  return `permits:${scope.signerAddress}:${scope.chainId}:${scope.delegatorAddress}`;\n}\n\nexport function permissionIndexKey(signerAddress: ChecksummedAddress): string {\n  return `permits-index:${signerAddress}`;\n}\n","import { type Address, getAddress, isAddress, isHex, type Hex } from \"viem\";\nimport { z } from \"zod/mini\";\n\ndeclare const checksummedTag: unique symbol;\n\n/** An EVM address that has been put through `getAddress` (EIP-55 checksum form). */\nexport type ChecksummedAddress = Address & { readonly [checksummedTag]: true };\n\n/** Stamp the brand on an arbitrary `Address` after normalizing it. */\nexport function checksum(value: Address): ChecksummedAddress {\n  return getAddress(value) as ChecksummedAddress;\n}\n\n/** `0x`-prefixed hex string. */\nexport const hex = z.custom<Hex>(\n  (v) => typeof v === \"string\" && isHex(v, { strict: true }),\n  \"expected 0x-prefixed hex string\",\n);\n\n/** Validates an EVM address string. Output type is `Address` (`` `0x${string}` ``). */\nexport const evmAddress = z.custom<Address>(\n  (v) => typeof v === \"string\" && isAddress(v, { strict: false }),\n  \"expected EVM address\",\n);\n\n/** Validates and EIP-55 checksums an EVM address. Output is {@link ChecksummedAddress}. */\nexport const checksummedAddress = z.pipe(evmAddress, z.transform(checksum));\n\n/** Non-negative integer Unix timestamp in seconds. */\nexport const unixSeconds = z.int().check(z.nonnegative());\n\n/** Positive integer count of seconds (e.g. a TTL). */\nexport const positiveSeconds = z.int().check(z.positive());\n\n/** Non-negative integer count of seconds (e.g. a cache TTL where 0 disables caching). */\nexport const nonNegativeSeconds = z.int().check(z.nonnegative());\n\n/** Positive integer count of days (e.g. a permit duration). */\nexport const positiveDays = z.int().check(z.positive());\n\n/** Positive integer EVM chain ID. */\nexport const chainId = z.int().check(z.positive());\n","import type { Address } from \"viem\";\nimport { type ChecksummedAddress, checksum } from \"../schemas/primitives\";\nexport { checksum, type ChecksummedAddress };\n\n/** Maximum number of contract addresses a single permit may bind, enforced by the FHE protocol. */\nexport const MAX_CONTRACTS_PER_PERMIT = 10;\n\nexport const SECONDS_PER_DAY = 86400;\n\n/** Current Unix time in whole seconds. */\nexport function nowSeconds(): number {\n  return Math.floor(Date.now() / 1000);\n}\n\n/** Deduplicate and sort a list of addresses by their checksummed form. */\nexport function normalizeAddresses(addresses: readonly Address[]): ChecksummedAddress[] {\n  return [...new Set(addresses.map(checksum))].toSorted();\n}\n","import { z } from \"zod/mini\";\nimport {\n  checksummedAddress,\n  chainId,\n  hex,\n  positiveDays,\n  positiveSeconds,\n  unixSeconds,\n} from \"../schemas/primitives\";\nimport { MAX_CONTRACTS_PER_PERMIT, SECONDS_PER_DAY } from \"./utils\";\n\nconst transportKeyPairTTLError = \"transportKeyPairTTL must be a positive integer number of seconds\";\nconst permitTTLError = \"permitTTL must be a positive integer number of days\";\n\n/** Maximum transportKeyPairTTL accepted by the fhevm ACL contract (365 days, in seconds). */\nexport const MAX_TRANSPORT_KEY_PAIR_TTL_SECONDS = 365 * SECONDS_PER_DAY;\n\n// z.int already rejects NaN, Infinity, and non-integers, so it covers\n// the previous .finite() + .int() combo with a single schema.\nexport const TransportKeyPairTTLSchema = z\n  .int({ error: transportKeyPairTTLError })\n  .check(\n    z.positive({ error: transportKeyPairTTLError }),\n    z.maximum(\n      MAX_TRANSPORT_KEY_PAIR_TTL_SECONDS,\n      `transportKeyPairTTL must not exceed the fhevm ACL maximum of ${MAX_TRANSPORT_KEY_PAIR_TTL_SECONDS}s (365 days)`,\n    ),\n  );\n\nexport const PermitTTLSchema = z\n  .int({ error: permitTTLError })\n  .check(z.positive({ error: permitTTLError }));\n\nexport const StoredTransportKeyPairSchema = z.object({\n  publicKey: hex,\n  privateKey: hex,\n  createdAt: unixSeconds,\n  expiresAt: positiveSeconds,\n});\n\nexport const PermissionSchema = z.object({\n  keypairPublicKey: hex,\n  signerAddress: checksummedAddress,\n  delegatorAddress: checksummedAddress,\n  chainId,\n  signedContractAddresses: z.array(checksummedAddress).check(z.maxLength(MAX_CONTRACTS_PER_PERMIT)),\n  signature: hex,\n  startTimestamp: unixSeconds,\n  durationDays: positiveDays,\n});\n\nexport const PermissionListSchema = z.array(PermissionSchema);\n\nexport const ScopeIndexSchema = z.array(z.string());\n","import type { GenericStorage } from \"../types\";\nimport { swallow } from \"../utils/swallow\";\nimport { transportKeyPairStorageKey } from \"./storage-keys\";\nimport { StoredTransportKeyPairSchema } from \"./schemas\";\nimport type { TransportKeyPair, StoredTransportKeyPair } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport type { GenericLogger } from \"../worker/worker.types\";\nimport { nowSeconds } from \"./utils\";\n\ninterface TransportKeyPairVaultConfig {\n  generator: () => Promise<TransportKeyPair>;\n  storage: GenericStorage;\n  /** Transport key pair lifetime in seconds. Pre-validated by the caller. */\n  ttl: number;\n  /** SDK-wide logger for best-effort storage diagnostics. */\n  logger: GenericLogger;\n}\n\n/**\n * Identity-scoped, chain-independent vault for ML-KEM transport key pairs.\n *\n * One transport key pair per signer address; the key pair survives chain switches and\n * permit revocations. Storage entries are keyed only by the signer address.\n */\nexport class TransportKeyPairVault {\n  readonly #generator: () => Promise<TransportKeyPair>;\n  readonly #storage: GenericStorage;\n  readonly #ttl: number;\n  readonly #logger: GenericLogger;\n  readonly #pending = new Map<ChecksummedAddress, Promise<StoredTransportKeyPair>>();\n\n  constructor(config: TransportKeyPairVaultConfig) {\n    this.#generator = config.generator;\n    this.#storage = config.storage;\n    this.#ttl = config.ttl;\n    this.#logger = config.logger;\n  }\n\n  async readStored(signerAddress: ChecksummedAddress): Promise<StoredTransportKeyPair | null> {\n    const key = transportKeyPairStorageKey(signerAddress);\n    const raw = await this.#storage.get(key);\n    if (raw === null || raw === undefined) {\n      return null;\n    }\n    const parsed = StoredTransportKeyPairSchema.safeParse(raw);\n    if (!parsed.success) {\n      await swallow(\n        \"delete transport key pair entry\",\n        () => this.#storage.delete(key),\n        this.#logger,\n      );\n      return null;\n    }\n    const stored = parsed.data;\n    if (nowSeconds() >= stored.expiresAt) {\n      await swallow(\n        \"delete transport key pair entry\",\n        () => this.#storage.delete(key),\n        this.#logger,\n      );\n      return null;\n    }\n    return stored;\n  }\n\n  /**\n   * Return the cached transport key pair, generating and persisting a fresh one if absent or expired.\n   *\n   * @remarks Deduplicates concurrent calls — simultaneous requests share one generation promise.\n   */\n  async getOrCreate(signerAddress: ChecksummedAddress): Promise<StoredTransportKeyPair> {\n    const existing = this.#pending.get(signerAddress);\n    if (existing) {\n      return existing;\n    }\n\n    const promise = (async () => {\n      const cached = await this.readStored(signerAddress);\n      if (cached !== null) {\n        return cached;\n      }\n      const fresh = await this.#generator();\n      const createdAt = nowSeconds();\n      const stored: StoredTransportKeyPair = {\n        publicKey: fresh.publicKey,\n        privateKey: fresh.privateKey,\n        createdAt,\n        expiresAt: createdAt + this.#ttl,\n      };\n      const key = transportKeyPairStorageKey(signerAddress);\n      await swallow(\n        \"persist transport key pair\",\n        () => this.#storage.set(key, stored),\n        this.#logger,\n      );\n      return stored;\n    })().finally(() => {\n      this.#pending.delete(signerAddress);\n    });\n\n    this.#pending.set(signerAddress, promise);\n    return promise;\n  }\n\n  /** Delete the stored transport key pair for the given address. */\n  async clear(signerAddress: ChecksummedAddress): Promise<void> {\n    const key = transportKeyPairStorageKey(signerAddress);\n    await swallow(\"delete transport key pair entry\", () => this.#storage.delete(key), this.#logger);\n  }\n}\n","import type { Hex } from \"viem\";\nimport type { Permission } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport { MAX_CONTRACTS_PER_PERMIT, SECONDS_PER_DAY } from \"./utils\";\n\n/** Contracts in `requested` not covered by the signed payload of any permission. */\nexport function uncoveredContracts(\n  permissions: readonly Permission[],\n  requested: readonly ChecksummedAddress[],\n): ChecksummedAddress[] {\n  const covered = new Set(permissions.flatMap((p) => p.signedContractAddresses));\n  return requested.filter((addr) => !covered.has(addr));\n}\n\n/** Split a list of addresses into permit-sized chunks (≤ {@link MAX_CONTRACTS_PER_PERMIT}). */\nexport function chunkContracts(addresses: readonly ChecksummedAddress[]): ChecksummedAddress[][] {\n  const chunks: ChecksummedAddress[][] = [];\n  for (let i = 0; i < addresses.length; i += MAX_CONTRACTS_PER_PERMIT) {\n    chunks.push(addresses.slice(i, i + MAX_CONTRACTS_PER_PERMIT));\n  }\n  return chunks;\n}\n\n/** Drop permissions that are time-expired or bound to a stale keypair. */\nexport function pruneUnusable(\n  permissions: readonly Permission[],\n  keypairPublicKey: Hex,\n  nowSeconds: number,\n): Permission[] {\n  return permissions.filter(\n    (p) =>\n      p.keypairPublicKey === keypairPublicKey &&\n      nowSeconds < p.startTimestamp + p.durationDays * SECONDS_PER_DAY,\n  );\n}\n\n/** Drop every permission whose signed payload touches any address in `contracts`. */\nexport function withoutPermitsTouching(\n  permissions: readonly Permission[],\n  contracts: readonly ChecksummedAddress[],\n): Permission[] {\n  const removeSet = new Set(contracts);\n  return permissions.filter((p) => !p.signedContractAddresses.some((a) => removeSet.has(a)));\n}\n\n/** Deduplicate and sort the union of two pre-checksummed address lists. */\nexport function sortedUnion<T extends string>(a: readonly T[], b: readonly T[]): T[] {\n  return [...new Set([...a, ...b])].toSorted();\n}\n\n/**\n * Find the in-scope permit best suited to be widened with `uncovered`.\n *\n * Returns the permit whose `signedContractAddresses ∪ uncovered` still fits\n * the 10-contract cap and that has the largest overlap with `requested`. Ties\n * broken by most-recent `startTimestamp`. Returns `null` when none fits.\n */\nexport function findPermitToWiden(\n  permits: readonly Permission[],\n  uncovered: readonly ChecksummedAddress[],\n  requested: readonly ChecksummedAddress[],\n): Permission | null {\n  const requestedSet = new Set(requested);\n  const feasible = permits.filter(\n    (p) => new Set([...p.signedContractAddresses, ...uncovered]).size <= MAX_CONTRACTS_PER_PERMIT,\n  );\n  if (feasible.length === 0) {\n    return null;\n  }\n\n  function overlap(p: Permission) {\n    return p.signedContractAddresses.reduce((n, a) => n + (requestedSet.has(a) ? 1 : 0), 0);\n  }\n\n  const maxOverlap = Math.max(...feasible.map(overlap));\n  const topTier = feasible.filter((p) => overlap(p) === maxOverlap);\n  return topTier.reduce((a, b) => (b.startTimestamp > a.startTimestamp ? b : a));\n}\n","import type { Hex } from \"viem\";\nimport type { GenericStorage } from \"../types\";\nimport { swallow } from \"../utils/swallow\";\nimport { pruneUnusable, withoutPermitsTouching } from \"./permissions\";\nimport { PermissionListSchema, PermissionSchema, ScopeIndexSchema } from \"./schemas\";\nimport { permissionIndexKey, permissionScopeKey, type PermissionScope } from \"./storage-keys\";\nimport type { Permission } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport type { GenericLogger } from \"../worker/worker.types\";\n\nexport type { PermissionScope };\n\ninterface PermissionStoreConfig {\n  storage: GenericStorage;\n  /** SDK-wide logger for best-effort storage diagnostics. */\n  logger: GenericLogger;\n}\n\n/**\n * Chain-scoped, 1-to-many store of EIP-712 permits.\n *\n * Permits are grouped by `(signerAddress, chainId, delegatorAddress)` so that\n * direct (`delegator === signer`) and delegated permits never collide. An\n * auxiliary per-signer index lists every scope so `clearAllForSigner` can\n * cascade across chains and delegators without enumerating storage keys.\n */\nexport class PermissionStore {\n  readonly #storage: GenericStorage;\n  readonly #logger: GenericLogger;\n\n  constructor(config: PermissionStoreConfig) {\n    this.#storage = config.storage;\n    this.#logger = config.logger;\n  }\n\n  /** Read all stored permissions for the given scope. Returns `[]` if none. */\n  async list(scope: PermissionScope): Promise<Permission[]> {\n    const key = permissionScopeKey(scope);\n    const raw = await this.#storage.get(key);\n    if (raw === null || raw === undefined) {\n      return [];\n    }\n    const parsed = PermissionListSchema.safeParse(raw);\n    if (!parsed.success) {\n      await this.#deleteScope(key);\n      await this.#untrackScope(scope);\n      return [];\n    }\n    return parsed.data;\n  }\n\n  /**\n   * Return permissions still live and bound to the current keypair.\n   * Expired or stale-keypair permissions are pruned in one storage pass.\n   */\n  async listUsableAndPrune(scope: PermissionScope, keypairPublicKey: Hex): Promise<Permission[]> {\n    const all = await this.list(scope);\n    const usable = pruneUnusable(all, keypairPublicKey, Math.floor(Date.now() / 1000));\n\n    if (usable.length !== all.length) {\n      const key = permissionScopeKey(scope);\n      if (usable.length === 0) {\n        await this.#deleteScope(key);\n        await this.#untrackScope(scope);\n      } else {\n        await swallow(\"update permit entry\", () => this.#storage.set(key, usable), this.#logger);\n      }\n    }\n    return usable;\n  }\n\n  /**\n   * Append signed permits to the given scope. Every permission is run through\n   * `PermissionSchema` so the schema is the single normalization point for both\n   * read and write paths. Signed payloads themselves are immutable and never\n   * edited — only addresses and types are normalized.\n   */\n  async append(scope: PermissionScope, permissions: readonly Permission[]): Promise<void> {\n    if (permissions.length === 0) {\n      return;\n    }\n    const validated = permissions.map((p) => PermissionSchema.parse(p));\n    const existing = await this.list(scope);\n    await this.#storage.set(permissionScopeKey(scope), [...existing, ...validated]);\n    await this.#trackScope(scope);\n  }\n\n  /**\n   * Replace the entry identified by `oldSignature` with `newPermission`.\n   *\n   * Atomic relative to the storage backend's `set`: the old entry survives in\n   * storage until the new list is written. If `oldSignature` is not found\n   * (raced eviction or concurrent prune), `newPermission` is still persisted —\n   * equivalent to {@link append}.\n   */\n  async replace(\n    scope: PermissionScope,\n    oldSignature: Hex,\n    newPermission: Permission,\n  ): Promise<void> {\n    const validated = PermissionSchema.parse(newPermission);\n    const existing = await this.list(scope);\n    const filtered = existing.filter((p) => p.signature !== oldSignature);\n    await this.#storage.set(permissionScopeKey(scope), [...filtered, validated]);\n    await this.#trackScope(scope);\n  }\n\n  /**\n   * Delete every permit whose signed payload touches any listed contract.\n   *\n   * The store never edits `signedContractAddresses`, because that field is part\n   * of the EIP-712 payload covered by `signature`.\n   */\n  async deletePermitsTouching(\n    scope: PermissionScope,\n    contractsToRemove: ChecksummedAddress[],\n  ): Promise<void> {\n    const existing = await this.list(scope);\n    if (existing.length === 0) {\n      return;\n    }\n    const key = permissionScopeKey(scope);\n    const next = withoutPermitsTouching(existing, contractsToRemove);\n    if (next.length === 0) {\n      await this.#deleteScope(key);\n      await this.#untrackScope(scope);\n    } else {\n      await this.#storage.set(key, next);\n    }\n  }\n\n  /**\n   * Delete every permission for the given signer across all chains and delegators.\n   * Uses the per-signer scope index to cascade without enumerating all storage keys.\n   */\n  async clearAllForSigner(signerAddress: ChecksummedAddress): Promise<void> {\n    const indexKey = permissionIndexKey(signerAddress);\n    const scopeKeys = await this.#readIndex(indexKey);\n    await Promise.all(scopeKeys.map((k) => this.#deleteScope(k)));\n    await swallow(\"delete permit index\", () => this.#storage.delete(indexKey), this.#logger);\n  }\n\n  async #readIndex(indexKey: string): Promise<string[]> {\n    const raw = await this.#storage.get(indexKey);\n    if (raw === null || raw === undefined) {\n      return [];\n    }\n    const parsed = ScopeIndexSchema.safeParse(raw);\n    if (!parsed.success) {\n      await swallow(\"delete permit index\", () => this.#storage.delete(indexKey), this.#logger);\n      return [];\n    }\n    return parsed.data;\n  }\n\n  async #trackScope(scope: PermissionScope): Promise<void> {\n    const indexKey = permissionIndexKey(scope.signerAddress);\n    const scopeKey = permissionScopeKey(scope);\n    const list = await this.#readIndex(indexKey);\n    if (list.includes(scopeKey)) {\n      return;\n    }\n    await this.#storage.set(indexKey, [...list, scopeKey]);\n  }\n\n  async #untrackScope(scope: PermissionScope): Promise<void> {\n    const indexKey = permissionIndexKey(scope.signerAddress);\n    const scopeKey = permissionScopeKey(scope);\n    const list = await this.#readIndex(indexKey);\n    const next = list.filter((entry) => entry !== scopeKey);\n    if (next.length === list.length) {\n      return;\n    }\n    if (next.length === 0) {\n      await swallow(\"delete permit index\", () => this.#storage.delete(indexKey), this.#logger);\n    } else {\n      await swallow(\"update permit index\", () => this.#storage.set(indexKey, next), this.#logger);\n    }\n  }\n\n  async #deleteScope(scopeKey: string): Promise<void> {\n    await swallow(\"delete permit entry\", () => this.#storage.delete(scopeKey), this.#logger);\n  }\n}\n","import type { Address } from \"viem\";\nimport type { GenericSigner, GenericStorage } from \"../types\";\nimport type { RelayerDispatcher } from \"../relayer/relayer-dispatcher\";\nimport { ZamaError } from \"../errors/base\";\nimport { wrapSigningError } from \"../errors/signing\";\nimport { swallow } from \"../utils/swallow\";\nimport { TransportKeyPairVault } from \"./keypair-vault\";\nimport { chunkContracts, findPermitToWiden, sortedUnion, uncoveredContracts } from \"./permissions\";\nimport { PermissionStore } from \"./permission-store\";\nimport type { PermissionScope } from \"./storage-keys\";\nimport type {\n  StoredTransportKeyPairWithPermits,\n  Permission,\n  StoredTransportKeyPair,\n} from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport { checksum } from \"../schemas/primitives\";\nimport type { GenericLogger } from \"../worker/worker.types\";\nimport { normalizeAddresses, nowSeconds, SECONDS_PER_DAY } from \"./utils\";\n\nexport const DEFAULT_TRANSPORT_KEY_PAIR_TTL_SECONDS = 30 * SECONDS_PER_DAY;\nexport const DEFAULT_PERMIT_DURATION_DAYS = 30;\n\n/** Configuration for {@link CredentialService}. TTLs are pre-validated by the caller. */\nexport interface CredentialServiceConfig {\n  relayer: RelayerDispatcher;\n  signer: GenericSigner;\n  /** Transport key pair lifetime in seconds. Pre-validated. */\n  transportKeyPairTTL: number;\n  /** Permit lifetime in days. Pre-validated. */\n  permitTTL: number;\n  /** Backing storage for transport key pairs (and permits if `permitStorage` is omitted). */\n  storage: GenericStorage;\n  /** Optional dedicated storage for permits; defaults to `storage`. */\n  permitStorage?: GenericStorage;\n  /** SDK-wide logger for credential-path diagnostics. */\n  logger: GenericLogger;\n}\n\n/**\n * Single facade coordinating the keypair vault and the permission store.\n *\n * `CredentialService` is the only credentials object held by `ZamaSDK`. It accepts identity\n * transitions via `handleWalletAccountChange`.\n */\nexport class CredentialService {\n  readonly #vault: TransportKeyPairVault;\n  readonly #store: PermissionStore;\n  readonly #relayer: RelayerDispatcher;\n  readonly #signer: GenericSigner;\n  readonly #permitTTL: number;\n  readonly #logger: GenericLogger;\n\n  constructor(config: CredentialServiceConfig) {\n    this.#vault = new TransportKeyPairVault({\n      generator: () => config.relayer.generateTransportKeyPair(),\n      storage: config.storage,\n      ttl: config.transportKeyPairTTL,\n      logger: config.logger,\n    });\n    this.#store = new PermissionStore({\n      storage: config.permitStorage ?? config.storage,\n      logger: config.logger,\n    });\n    this.#relayer = config.relayer;\n    this.#signer = config.signer;\n    this.#permitTTL = config.permitTTL;\n    this.#logger = config.logger;\n  }\n\n  /**\n   * Resolve a keypair and permissions covering `contracts`, minimizing wallet\n   * prompts by reusing or widening existing permits where possible. Empty\n   * `contracts` warms the keypair without prompting.\n   *\n   * @returns The resolved keypair and permits covering the requested contracts.\n   * @throws if the user rejects a wallet signature prompt. {@link SigningRejectedError}\n   * @throws if signing fails for any other reason. {@link SigningFailedError}\n   */\n  async grantPermit(\n    contracts: readonly Address[],\n    delegator?: Address,\n  ): Promise<StoredTransportKeyPairWithPermits> {\n    const account = this.#signer.requireWalletAccount(\"grantPermit\");\n    const signerAddress = checksum(account.address);\n    const requested = normalizeAddresses(contracts);\n    const keypair = await this.#vault.getOrCreate(signerAddress);\n    if (requested.length === 0) {\n      return { keypair, permits: [] };\n    }\n\n    const chainId = account.chainId;\n    const scope: PermissionScope = {\n      signerAddress,\n      chainId,\n      delegatorAddress: delegator ? checksum(delegator) : signerAddress,\n    };\n    const permits = await this.#store.listUsableAndPrune(scope, keypair.publicKey);\n\n    const uncovered = uncoveredContracts(permits, requested);\n    if (uncovered.length > 0) {\n      const candidate = findPermitToWiden(permits, uncovered, requested);\n      if (candidate !== null) {\n        const widenedSet = sortedUnion(candidate.signedContractAddresses, uncovered);\n        const widened = await this.#signPermit({\n          chunk: widenedSet,\n          keypair,\n          scope,\n        });\n        await swallow(\n          \"replace permit\",\n          () => this.#store.replace(scope, candidate.signature, widened),\n          this.#logger,\n        );\n        permits[permits.indexOf(candidate)] = widened;\n      } else {\n        for (const chunk of chunkContracts(uncovered)) {\n          const permission = await this.#signPermit({ chunk, keypair, scope });\n          permits.push(permission);\n          await swallow(\n            \"persist permit\",\n            () => this.#store.append(scope, [permission]),\n            this.#logger,\n          );\n        }\n      }\n    }\n\n    const requestedSet = new Set(requested);\n    return {\n      keypair,\n      permits: permits.filter((p) => p.signedContractAddresses.some((a) => requestedSet.has(a))),\n    };\n  }\n\n  /**\n   * Pure store lookup: are stored permits sufficient to cover `contracts`? No wallet prompt.\n   *\n   * @returns `true` if cached permits cover all requested contracts (vacuously\n   *   true for an empty list); `false` if no keypair exists or coverage is\n   *   incomplete.\n   */\n  async hasPermit(contracts: readonly Address[], delegator?: Address): Promise<boolean> {\n    if (contracts.length === 0) {\n      return true;\n    }\n    const account = this.#signer.walletAccount.getSnapshot();\n    if (!account) {\n      return false;\n    }\n    const signerAddress = checksum(account.address);\n    const keypair = await this.#vault.readStored(signerAddress);\n    if (keypair === null) {\n      return false;\n    }\n    const chainId = account.chainId;\n    const delegatorAddress = delegator ? checksum(delegator) : signerAddress;\n    const scope: PermissionScope = { signerAddress, chainId, delegatorAddress };\n    const permits = await this.#store.listUsableAndPrune(scope, keypair.publicKey);\n    return uncoveredContracts(permits, normalizeAddresses(contracts)).length === 0;\n  }\n\n  /**\n   * Wipe FHE permits for the current signer.\n   *\n   * - With no argument: every permit referencing this signer is removed across\n   *   all chains and delegators. The keypair survives — use\n   *   {@link clearCredentials} to also wipe the keypair.\n   * - With a contract list: every signed permit in the direct-decrypt scope\n   *   (current chain) whose immutable payload touches any listed address is\n   *   removed. Delegated permits are not touched in this mode.\n   *\n   * @throws if reading the signer address fails. {@link SigningFailedError}\n   */\n  async revokePermits(contracts?: readonly Address[]): Promise<void> {\n    const account = this.#signer.requireWalletAccount(\"revokePermits\");\n    const signerAddress = checksum(account.address);\n    if (contracts === undefined) {\n      await this.#store.clearAllForSigner(signerAddress);\n      return;\n    }\n    const normalized = normalizeAddresses(contracts);\n    if (normalized.length === 0) {\n      return;\n    }\n    const chainId = account.chainId;\n    await this.#store.deletePermitsTouching(\n      { signerAddress, chainId, delegatorAddress: signerAddress },\n      normalized,\n    );\n  }\n\n  /**\n   * Wipe the keypair for the current signer and cascade-delete every\n   * permission referencing it across all chains and delegators.\n   *\n   * @throws if reading the signer address fails. {@link SigningFailedError}\n   */\n  async clearCredentials(): Promise<void> {\n    const account = this.#signer.requireWalletAccount(\"clearCredentials\");\n    const signerAddress = checksum(account.address);\n    await this.#vault.clear(signerAddress);\n    await this.#store.clearAllForSigner(signerAddress);\n  }\n\n  /**\n   * Warm the signer transport key pair cache for a known address.\n   *\n   * Best-effort prefetch primitive: correctness still comes from `grantPermit`,\n   * which lazily creates the transport key pair when needed. Errors (storage failure,\n   * relayer 4xx, missing Worker in SSR) are **not** swallowed here — the caller\n   * decides whether to log, ignore, or surface them.\n   */\n  async warmTransportKeyPair(address: Address): Promise<void> {\n    await this.#vault.getOrCreate(checksum(address));\n  }\n\n  /**\n   * Apply a wallet account transition.\n   *\n   * Address change clears persisted credentials for the previous account.\n   * Chain-only changes keep credentials intact because permits are chain-scoped\n   * already and stale decrypt plaintext is cleared by `ZamaSDK`.\n   */\n  async handleWalletAccountChange(\n    prev?: { address: Address },\n    next?: { address: Address },\n  ): Promise<void> {\n    const prevAddr = prev ? checksum(prev.address) : undefined;\n    const nextAddr = next ? checksum(next.address) : undefined;\n    if (prevAddr === nextAddr) {\n      return;\n    }\n    if (prevAddr) {\n      await this.#vault.clear(prevAddr);\n      await this.#store.clearAllForSigner(prevAddr);\n    }\n  }\n\n  async #signPermit(input: {\n    chunk: ChecksummedAddress[];\n    keypair: StoredTransportKeyPair;\n    scope: PermissionScope;\n  }): Promise<Permission> {\n    const { chunk, keypair, scope } = input;\n    const startTimestamp = nowSeconds();\n    const isDelegated = scope.delegatorAddress !== scope.signerAddress;\n\n    try {\n      const eip712 = isDelegated\n        ? await this.#relayer.createDelegatedUserDecryptEIP712(\n            keypair.publicKey,\n            chunk,\n            scope.delegatorAddress,\n            startTimestamp,\n            this.#permitTTL,\n          )\n        : await this.#relayer.createEIP712(\n            keypair.publicKey,\n            chunk,\n            startTimestamp,\n            this.#permitTTL,\n          );\n\n      const signature = await this.#signer.signTypedData(eip712);\n\n      return {\n        keypairPublicKey: keypair.publicKey,\n        signerAddress: scope.signerAddress,\n        delegatorAddress: scope.delegatorAddress,\n        chainId: scope.chainId,\n        signedContractAddresses: chunk,\n        signature,\n        startTimestamp,\n        durationDays: this.#permitTTL,\n      };\n    } catch (error) {\n      if (error instanceof ZamaError) {\n        throw error;\n      }\n      throw wrapSigningError(error, \"Credential signing failed\");\n    }\n  }\n}\n","import type { GenericLogger } from \"../worker/worker.types\";\n\n/**\n * Internal logger with a consistent, always-present shape.\n *\n * The consumer supplies an optional {@link GenericLogger} via configuration;\n * it is wrapped once into a `LoggerService` that is threaded through the SDK.\n * Internal code therefore calls `logger.warn(...)` directly — no optional\n * chaining, no per-call `undefined` checks — and a single place (this class)\n * owns the \"silent by default\" behavior: when no logger was supplied, every\n * level is a no-op.\n *\n * Every message is prefixed with `[zama-sdk]` here, so call sites pass only\n * their own message (and optional component tag) without repeating the prefix.\n *\n * `LoggerService` itself satisfies `GenericLogger`, so it can be passed\n * anywhere a logger is expected (e.g. the worker client).\n */\nexport class LoggerService implements GenericLogger {\n  readonly #logger: GenericLogger | undefined;\n  readonly #prefix = \"[zama-sdk]\";\n\n  constructor(logger?: GenericLogger) {\n    this.#logger = logger;\n  }\n\n  error(message: string, data?: Record<string, unknown>): void {\n    this.#logger?.error(`${this.#prefix} ${message}`, data);\n  }\n\n  warn(message: string, data?: Record<string, unknown>): void {\n    this.#logger?.warn(`${this.#prefix} ${message}`, data);\n  }\n\n  info(message: string, data?: Record<string, unknown>): void {\n    this.#logger?.info(`${this.#prefix} ${message}`, data);\n  }\n\n  debug(message: string, data?: Record<string, unknown>): void {\n    this.#logger?.debug(`${this.#prefix} ${message}`, data);\n  }\n}\n","import type { GenericStorage } from \"../types\";\n\n/** In-memory credential store. Credentials are lost on page reload. */\nexport class MemoryStorage implements GenericStorage {\n  #map = new Map<string, unknown>();\n\n  async get<T = unknown>(key: string): Promise<T | null> {\n    return (this.#map.get(key) as T) ?? null;\n  }\n\n  async set<T = unknown>(key: string, value: T): Promise<void> {\n    this.#map.set(key, value);\n  }\n\n  async delete(key: string): Promise<void> {\n    this.#map.delete(key);\n  }\n}\n\n/** Default singleton for application-wide use. */\nexport const memoryStorage = new MemoryStorage();\n","import type { FheChain } from \"../chains\";\nimport { ConfigurationError } from \"../errors\";\nimport { IndexedDBStorage } from \"../storage/indexeddb-storage\";\nimport { MemoryStorage } from \"../storage/memory-storage\";\nimport type { GenericStorage } from \"../types\";\nimport type { RelayerConfig } from \"./types\";\n\n// ── Storage defaults ─────────────────────────────────────────────────────────\n\nfunction getDefaultStorage(): GenericStorage {\n  return typeof window !== \"undefined\"\n    ? new IndexedDBStorage(\"CredentialStore\")\n    : new MemoryStorage();\n}\n\nexport function resolveStorage(\n  storage: GenericStorage | undefined = getDefaultStorage(),\n  permitStorage: GenericStorage | undefined = storage,\n): { storage: GenericStorage; permitStorage: GenericStorage } {\n  return { storage, permitStorage };\n}\n\n// ── Chain relayer resolution ────────────────────────────────────────────────\n\nexport interface ResolvedChainRelayer {\n  chain: FheChain;\n  relayer: RelayerConfig;\n}\n\nexport function resolveChainRelayers(\n  chains: readonly FheChain[],\n  relayers: Readonly<Record<number, RelayerConfig>>,\n): Map<number, ResolvedChainRelayer> {\n  const chainMap = new Map(chains.map((c) => [c.id, c]));\n  if (chainMap.size !== chains.length) {\n    const ids = chains.map((c) => c.id);\n    const dupes = [...new Set(ids.filter((id, i) => ids.indexOf(id) !== i))];\n    throw new ConfigurationError(\n      `Duplicate chain id(s) [${dupes.join(\", \")}] in the chains array. ` +\n        `Each chain id must appear only once. Note: hardhat and anvil are aliases (both use 31337).`,\n    );\n  }\n  const relayerMap = new Map(Object.entries(relayers));\n  const result = new Map<number, ResolvedChainRelayer>();\n\n  for (const id of chainMap.keys()) {\n    const chainConfig = chainMap.get(id);\n    const relayerConfig = relayerMap.get(String(id));\n\n    if (!relayerConfig) {\n      throw new ConfigurationError(\n        `Chain ${id} has no relayer configured. ` +\n          `Add a relayer entry: relayers: { [${id}]: web() }`,\n      );\n    }\n\n    if (!chainConfig) {\n      throw new ConfigurationError(\n        `Chain ${id} has a relayer configured but no entry in the chains array. ` +\n          `Add the chain config to the chains array.`,\n      );\n    }\n\n    result.set(id, {\n      chain: chainConfig,\n      relayer: relayerConfig,\n    });\n  }\n\n  const relayerIdSet = new Set(Object.keys(relayers).map(Number));\n  const orphaned = new Set([...relayerIdSet].filter((id) => !chainMap.has(id)));\n  if (orphaned.size > 0) {\n    throw new ConfigurationError(\n      `Relayer entries for chain(s) [${[...orphaned].join(\", \")}] have no matching entry ` +\n        `in the chains array. Remove them or add the corresponding chain config.`,\n    );\n  }\n\n  return result;\n}\n","import type {\n  InputProofBytesType,\n  KmsDelegatedUserDecryptEIP712Type,\n  ZKProofLike,\n} from \"@zama-fhe/relayer-sdk/bundle\";\nimport type { Address, Hex } from \"viem\";\nimport type { FheChain } from \"../chains/types\";\nimport type { RelayerConfig } from \"../config/types\";\nimport { resolveChainRelayers } from \"../config/resolve\";\nimport type { TransportKeyPair } from \"../credentials/types\";\nimport { ConfigurationError } from \"../errors\";\nimport { assertNonNullable, toError } from \"../utils\";\nimport type { GenericLogger } from \"../worker/worker.types\";\nimport type { RelayerSDK } from \"./relayer-sdk\";\nimport type {\n  ClearValue,\n  DelegatedUserDecryptParams,\n  EIP712TypedData,\n  EncryptParams,\n  EncryptResult,\n  EncryptedValue,\n  FheEncryptionKey,\n  PublicDecryptResult,\n  PublicParamsData,\n  UserDecryptParams,\n} from \"./relayer-sdk.types\";\n\n/** Anything with a synchronous `terminate()` method (workers, pools). */\nexport interface WorkerLike {\n  terminate(): void;\n}\n\n/**\n * Owns chain management (chains / activeChain / switchChain) and delegates\n * every {@link RelayerSDK} operation to the relayer for the currently active\n * chain.\n *\n * Groups chains by relayer config reference identity, calls `createWorker`\n * once per group with all chain configs, then calls `createRelayer`\n * per chain with the shared worker.\n *\n * Workers/pools are held separately from relayers so the dispatcher can\n * terminate them directly — relayers never own worker lifecycle.\n */\nexport class RelayerDispatcher implements RelayerSDK, Disposable {\n  readonly #chains: Map<number, FheChain>;\n  readonly #relayers: Map<number, RelayerSDK>;\n  readonly #workers: readonly WorkerLike[];\n  #chainId: number;\n\n  constructor(\n    chains: readonly [FheChain, ...FheChain[]],\n    configs: Readonly<Record<number, RelayerConfig>>,\n    logger: GenericLogger,\n  ) {\n    if (chains.length === 0) {\n      throw new ConfigurationError(\"At least one chain is required.\");\n    }\n    this.#chains = new Map(chains.map((c) => [c.id, c]));\n    this.#chainId = chains[0].id;\n\n    const chainRelayers = resolveChainRelayers(chains, configs);\n\n    // Group chains by relayer config reference — same object = same group = shared worker.\n    const groups = new Map<RelayerConfig, Array<[number, FheChain]>>();\n    for (const [chainId, config] of chainRelayers) {\n      const key = config.relayer;\n      let group = groups.get(key);\n      if (!group) {\n        group = [];\n        groups.set(key, group);\n      }\n      group.push([chainId, config.chain]);\n    }\n\n    // For each group: create shared worker once, then create per-chain relayers.\n    const relayers = new Map<number, RelayerSDK>();\n    const workers: WorkerLike[] = [];\n    try {\n      for (const [relayerCfg, groupChains] of groups) {\n        const allChainConfigs = groupChains.map(([, chain]) => chain);\n        const worker = relayerCfg.createWorker?.(allChainConfigs, logger);\n        if (worker) {\n          workers.push(worker);\n        }\n        for (const [chainId, chain] of groupChains) {\n          relayers.set(chainId, relayerCfg.createRelayer(chain, worker, logger));\n        }\n      }\n    } catch (error) {\n      for (const w of workers) {\n        try {\n          w.terminate();\n        } catch {\n          /* best-effort cleanup */\n        }\n      }\n      throw error;\n    }\n\n    this.#relayers = relayers;\n    this.#workers = workers;\n  }\n\n  get chains(): readonly FheChain[] {\n    return [...this.#chains.values()];\n  }\n\n  get chain(): FheChain {\n    const chain = this.#chains.get(this.#chainId);\n    assertNonNullable(chain, \"RelayerDispatcher: chain\");\n    return chain;\n  }\n\n  switchChain(chainId: number): void {\n    if (!this.#chains.has(chainId)) {\n      throw new ConfigurationError(\n        `No relayer configured for chain ${chainId}. Add it to the chains array.`,\n      );\n    }\n    this.#chainId = chainId;\n  }\n\n  get #active(): RelayerSDK {\n    const relayer = this.#relayers.get(this.#chainId);\n    assertNonNullable(relayer, \"RelayerDispatcher: relayer\");\n    return relayer;\n  }\n\n  generateTransportKeyPair(): Promise<TransportKeyPair> {\n    return this.#active.generateTransportKeyPair();\n  }\n\n  createEIP712(\n    publicKey: Hex,\n    contractAddresses: Address[],\n    startTimestamp: number,\n    durationDays?: number,\n  ): Promise<EIP712TypedData> {\n    return this.#active.createEIP712(publicKey, contractAddresses, startTimestamp, durationDays);\n  }\n\n  encrypt(params: EncryptParams): Promise<EncryptResult> {\n    return this.#active.encrypt(params);\n  }\n\n  userDecrypt(params: UserDecryptParams): Promise<Readonly<Record<EncryptedValue, ClearValue>>> {\n    return this.#active.userDecrypt(params);\n  }\n\n  publicDecrypt(encryptedValues: EncryptedValue[]): Promise<PublicDecryptResult> {\n    return this.#active.publicDecrypt(encryptedValues);\n  }\n\n  createDelegatedUserDecryptEIP712(\n    publicKey: Hex,\n    contractAddresses: Address[],\n    delegatorAddress: Address,\n    startTimestamp: number,\n    durationDays?: number,\n  ): Promise<KmsDelegatedUserDecryptEIP712Type> {\n    return this.#active.createDelegatedUserDecryptEIP712(\n      publicKey,\n      contractAddresses,\n      delegatorAddress,\n      startTimestamp,\n      durationDays,\n    );\n  }\n\n  delegatedUserDecrypt(\n    params: DelegatedUserDecryptParams,\n  ): Promise<Readonly<Record<EncryptedValue, ClearValue>>> {\n    return this.#active.delegatedUserDecrypt(params);\n  }\n\n  requestZKProofVerification(zkProof: ZKProofLike): Promise<InputProofBytesType> {\n    return this.#active.requestZKProofVerification(zkProof);\n  }\n\n  fetchFheEncryptionKeyBytes(): Promise<FheEncryptionKey | null> {\n    return this.#active.fetchFheEncryptionKeyBytes();\n  }\n\n  getPublicParams(bits: number): Promise<PublicParamsData | null> {\n    return this.#active.getPublicParams(bits);\n  }\n\n  getAclAddress(): Promise<Address> {\n    return this.#active.getAclAddress();\n  }\n\n  terminate(): void {\n    const errors: Error[] = [];\n\n    // Clean up relayer-owned caches (no worker termination).\n    for (const r of new Set(this.#relayers.values())) {\n      try {\n        r.terminate();\n      } catch (e) {\n        errors.push(toError(e));\n      }\n    }\n\n    // Terminate the actual workers/pools (deduplicated).\n    for (const w of new Set(this.#workers)) {\n      try {\n        w.terminate();\n      } catch (e) {\n        errors.push(toError(e));\n      }\n    }\n\n    if (errors.length > 0) {\n      throw new AggregateError(errors, \"Failed to terminate relayer resources\");\n    }\n  }\n\n  [Symbol.dispose](): void {\n    this.terminate();\n  }\n}\n","import { type Address, getAddress, zeroAddress } from \"viem\";\nimport { z } from \"zod/mini\";\nimport type { TokenWrapperPairWithMetadata, PaginatedResult, TokenWrapperPair } from \"./contracts\";\nimport {\n  decimalsContract,\n  erc20TotalSupplyContract,\n  getConfidentialTokenAddressContract,\n  getTokenAddressContract,\n  getTokenPairContract,\n  getTokenPairsContract,\n  getTokenPairsLengthContract,\n  getTokenPairsSliceContract,\n  isConfidentialTokenValidContract,\n  nameContract,\n  symbolContract,\n} from \"./contracts\";\nimport { ConfigurationError } from \"./errors/relayer\";\nimport { mainnet, sepolia, hoodi, ingenTestnet, bscTestnet } from \"./chains\";\nimport { checksummedAddress, nonNegativeSeconds } from \"./schemas/primitives\";\nimport type { GenericProvider } from \"./types/provider\";\nimport { parseConfiguration } from \"./validation\";\n\n/**\n * Default wrappers registry addresses for known chains.\n * Only includes chains where a registry is deployed (excludes Hardhat).\n */\nexport const DefaultRegistryAddresses: Record<number, Address> = {\n  [mainnet.id]: mainnet.registryAddress,\n  [sepolia.id]: sepolia.registryAddress,\n  [hoodi.id]: hoodi.registryAddress,\n  [ingenTestnet.id]: ingenTestnet.registryAddress,\n  [bscTestnet.id]: bscTestnet.registryAddress,\n};\n\n/** Default registry TTL in seconds (24 hours). */\nexport const DEFAULT_REGISTRY_TTL_SECONDS = 86_400;\n\n/** Per-chain wrappers-registry address overrides. */\nexport const RegistryAddressesSchema = z.record(\n  z.string().check(z.regex(/^\\d+$/, \"expected numeric chain id key\")),\n  checksummedAddress,\n);\n\n/** TTL (seconds) for cached registry results. `0` means entries expire immediately. */\nexport const RegistryTTLSchema = nonNegativeSeconds;\n\n/** Default page size for {@link WrappersRegistry.listPairs}. */\nconst DEFAULT_PAGE_SIZE = 100;\n\n/** Configuration for {@link WrappersRegistry}. */\nexport interface WrappersRegistryConfig {\n  /** Read-only chain provider used for every registry lookup. */\n  provider: GenericProvider;\n  /**\n   * Per-chain registry address overrides, merged on top of\n   * {@link DefaultRegistryAddresses}. Use this to supply a registry\n   * address for custom or local chains (e.g. Hardhat).\n   *\n   * @example\n   * ```ts\n   * new WrappersRegistry({\n   *   provider,\n   *   registryAddresses: { [31337]: \"0xYourHardhatRegistry\" },\n   * });\n   * ```\n   */\n  registryAddresses?: Record<number, Address>;\n  /**\n   * How long cached registry results remain valid, in seconds.\n   * Default: `86400` (24 hours).\n   */\n  registryTTL?: number;\n}\n\n/** Options for {@link WrappersRegistry.listPairs}. */\nexport interface ListPairsOptions {\n  /** Page number (1-indexed). Default: `1`. */\n  page?: number;\n  /** Number of items per page. Default: `100`. */\n  pageSize?: number;\n  /**\n   * When `true`, fetches on-chain metadata (name, symbol, decimals) for both\n   * the ERC-20 and confidential token, plus totalSupply for the ERC-20.\n   * Default: `false`.\n   */\n  metadata?: boolean;\n}\n\n/** Shorter TTL for negative lookups (5 minutes) so newly registered tokens are discoverable quickly. */\nconst NEGATIVE_CACHE_TTL_MS = 5 * 60 * 1000;\n\n/** Cache entry with expiry timestamp. */\ninterface CacheEntry<T> {\n  data: T;\n  expiresAt: number;\n}\n\n/**\n * High-level interface for the on-chain token wrappers registry.\n *\n * Uses the configured {@link GenericProvider} to resolve the correct registry\n * contract address for the current chain and exposes typed read helpers for\n * every registry query. Results are cached in memory with a configurable TTL\n * (default 24 hours).\n *\n * @example\n * ```ts\n * const registry = new WrappersRegistry({ provider });\n *\n * // Paginated listing\n * const page1 = await registry.listPairs({ page: 1, pageSize: 20 });\n *\n * // Structured lookups\n * const result = await registry.getConfidentialToken(erc20Address);\n * if (result) console.log(result.confidentialTokenAddress);\n *\n * // Force refresh\n * registry.refresh();\n * ```\n */\nexport class WrappersRegistry {\n  readonly provider: GenericProvider;\n  readonly #addresses: Record<number, Address>;\n  readonly #ttlMs: number;\n  readonly #cache = new Map<string, CacheEntry<unknown>>();\n\n  constructor(config: WrappersRegistryConfig) {\n    this.provider = config.provider;\n    this.#addresses = Object.assign(\n      {},\n      DefaultRegistryAddresses,\n      parseConfiguration(z.optional(RegistryAddressesSchema), config.registryAddresses),\n    );\n    this.#ttlMs =\n      parseConfiguration(RegistryTTLSchema, config.registryTTL ?? DEFAULT_REGISTRY_TTL_SECONDS) *\n      1000;\n  }\n\n  /**\n   * Synchronous lookup of the registry address for a given chain ID.\n   * Returns `undefined` if no address is configured for that chain.\n   */\n  getAddress(chainId: number): Address | undefined {\n    return this.#addresses[chainId];\n  }\n\n  // ---------------------------------------------------------------------------\n  // Cache helpers\n  // ---------------------------------------------------------------------------\n\n  #getCached<T>(key: string): T | undefined {\n    const entry = this.#cache.get(key);\n    if (!entry) {\n      return undefined;\n    }\n    if (Date.now() >= entry.expiresAt) {\n      this.#cache.delete(key);\n      return undefined;\n    }\n    return entry.data as T;\n  }\n\n  #setCached<T>(key: string, data: T, ttlMs = this.#ttlMs): T {\n    this.#cache.set(key, {\n      data,\n      expiresAt: Date.now() + ttlMs,\n    });\n    return data;\n  }\n\n  /**\n   * Force-invalidate the in-memory cache. The next call to any read method\n   * will fetch fresh data from the chain.\n   */\n  refresh(): void {\n    this.#cache.clear();\n  }\n\n  /**\n   * The cache TTL in milliseconds.\n   * Exposed so query option factories can set a matching `staleTime`.\n   */\n  get ttlMs(): number {\n    return this.#ttlMs;\n  }\n\n  // ---------------------------------------------------------------------------\n  // Registry address resolution\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Resolve the registry contract address for the current chain.\n   *\n   * Priority: `registryAddresses[chainId]` \\> built-in default.\n   *\n   * @returns The registry contract address for the connected chain.\n   * @throws if no address is configured for the chain. {@link ConfigurationError}\n   */\n  async getRegistryAddress(): Promise<Address> {\n    const chainId = await this.provider.getChainId();\n    const address = this.#addresses[chainId];\n\n    if (!address) {\n      throw new ConfigurationError(\n        `No wrappers registry address configured for chain ${chainId}.\\n` +\n          `Pass a registryAddresses entry for this chain.`,\n      );\n    }\n\n    return getAddress(address);\n  }\n\n  // ---------------------------------------------------------------------------\n  // Paginated listing\n  // ---------------------------------------------------------------------------\n\n  /**\n   * List token wrapper pairs with page-based pagination.\n   *\n   * Internally maps to `getTokenConfidentialTokenPairsSlice` on-chain.\n   *\n   * @param options - Pagination and enrichment options.\n   * @returns A {@link PaginatedResult} of pairs.\n   *\n   * @example\n   * ```ts\n   * const result = await registry.listPairs({ page: 1, pageSize: 20 });\n   * console.log(`${result.total} pairs, showing page ${result.page}`);\n   *\n   * // With on-chain metadata\n   * const withMeta = await registry.listPairs({ metadata: true, pageSize: 10 });\n   * for (const pair of withMeta.items) {\n   *   console.log(pair.underlying.symbol, \"→\", pair.confidential.symbol);\n   * }\n   * ```\n   */\n  async listPairs(\n    options: ListPairsOptions & { metadata: true },\n  ): Promise<PaginatedResult<TokenWrapperPairWithMetadata>>;\n  async listPairs(options?: ListPairsOptions): Promise<PaginatedResult<TokenWrapperPair>>;\n  async listPairs(\n    options: ListPairsOptions = {},\n  ): Promise<PaginatedResult<TokenWrapperPair | TokenWrapperPairWithMetadata>> {\n    const page = options.page ?? 1;\n    const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE;\n    const metadata = options.metadata ?? false;\n\n    if (page < 1) {\n      throw new ConfigurationError(`page must be >= 1, got ${page}`);\n    }\n    if (pageSize < 1) {\n      throw new ConfigurationError(`pageSize must be >= 1, got ${pageSize}`);\n    }\n\n    const registry = await this.getRegistryAddress();\n\n    // Fetch total (cached)\n    const totalCacheKey = `total:${registry}`;\n    let total = this.#getCached<number>(totalCacheKey);\n    if (total === undefined) {\n      const raw = await this.provider.readContract(getTokenPairsLengthContract(registry));\n      total = this.#setCached(totalCacheKey, Number(raw));\n    }\n\n    // Compute slice indices, clamping toIndex to total\n    const fromIndex = BigInt((page - 1) * pageSize);\n    const clampedToIndex =\n      fromIndex + BigInt(pageSize) > BigInt(total) ? BigInt(total) : fromIndex + BigInt(pageSize);\n\n    // Page beyond total — return empty\n    if (fromIndex >= BigInt(total)) {\n      return { items: [], total, page, pageSize };\n    }\n\n    // Fetch slice (cached)\n    const sliceCacheKey = `slice:${registry}:${fromIndex}:${clampedToIndex}`;\n    let items = this.#getCached<TokenWrapperPair[]>(sliceCacheKey);\n    if (items === undefined) {\n      const raw = await this.provider.readContract(\n        getTokenPairsSliceContract(registry, fromIndex, clampedToIndex),\n      );\n      items = this.#setCached(sliceCacheKey, [...raw]);\n    }\n\n    if (!metadata) {\n      return { items, total, page, pageSize };\n    }\n\n    // Enrich with on-chain metadata (resilient — individual failures don't break the batch)\n    const metadataCacheKey = `metadata:${registry}:${fromIndex}:${clampedToIndex}`;\n    let metadataItems = this.#getCached<TokenWrapperPairWithMetadata[]>(metadataCacheKey);\n    if (metadataItems === undefined) {\n      const settled = await Promise.allSettled(items.map((pair) => this.#pairWithMetadata(pair)));\n      const hasFailures = settled.some((r) => r.status === \"rejected\");\n      const enriched = settled.map((result, i) =>\n        result.status === \"fulfilled\"\n          ? result.value\n          : Object.assign({}, items[i], {\n              metadataFailed: true as const,\n              underlying: {\n                name: \"Unknown\",\n                symbol: \"???\",\n                decimals: 0,\n                totalSupply: 0n,\n              },\n              confidential: { name: \"Unknown\", symbol: \"???\", decimals: 0 },\n            }),\n      );\n      // Use negative cache TTL when any metadata fetch failed so retries happen sooner\n      metadataItems = this.#setCached(\n        metadataCacheKey,\n        enriched,\n        hasFailures ? NEGATIVE_CACHE_TTL_MS : undefined,\n      );\n    }\n\n    return { items: metadataItems, total, page, pageSize };\n  }\n\n  async #pairWithMetadata(pair: TokenWrapperPair): Promise<TokenWrapperPairWithMetadata> {\n    const [uName, uSymbol, uDecimals, uTotalSupply, cName, cSymbol, cDecimals] = await Promise.all([\n      this.provider.readContract(nameContract(pair.tokenAddress)),\n      this.provider.readContract(symbolContract(pair.tokenAddress)),\n      this.provider.readContract(decimalsContract(pair.tokenAddress)),\n      this.provider.readContract(erc20TotalSupplyContract(pair.tokenAddress)),\n      this.provider.readContract(nameContract(pair.confidentialTokenAddress)),\n      this.provider.readContract(symbolContract(pair.confidentialTokenAddress)),\n      this.provider.readContract(decimalsContract(pair.confidentialTokenAddress)),\n    ]);\n\n    return {\n      ...pair,\n      underlying: {\n        name: uName,\n        symbol: uSymbol,\n        decimals: uDecimals,\n        totalSupply: uTotalSupply,\n      },\n      confidential: { name: cName, symbol: cSymbol, decimals: cDecimals },\n    };\n  }\n\n  // ---------------------------------------------------------------------------\n  // Structured single-pair lookups\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Look up the confidential token for a given plain ERC-20 address.\n   *\n   * @param tokenAddress - The plain ERC-20 token address.\n   * @returns The lookup result, or `null` if the token has never been registered.\n   *   **Note:** revoked tokens (registered then invalidated) return a non-null result\n   *   with `isValid: false`. Check `result.isValid` explicitly rather than using\n   *   `if (result)` to guard against processing revoked tokens.\n   *\n   * @example\n   * ```ts\n   * const result = await registry.getConfidentialToken(usdcAddress);\n   * if (result?.isValid) {\n   *   console.log(result.confidentialTokenAddress);\n   * }\n   * ```\n   */\n  async getConfidentialToken(\n    tokenAddress: Address,\n  ): Promise<{ confidentialTokenAddress: Address; isValid: boolean } | null> {\n    const registry = await this.getRegistryAddress();\n    const normalized = getAddress(tokenAddress);\n\n    const cacheKey = `ct:${registry}:${normalized}`;\n    const cached = this.#getCached<{\n      confidentialTokenAddress: Address;\n      isValid: boolean;\n    } | null>(cacheKey);\n    if (cached !== undefined) {\n      return cached;\n    }\n\n    const [isValid, confidentialTokenAddress] = await this.provider.readContract(\n      getConfidentialTokenAddressContract(registry, normalized),\n    );\n\n    // Zero address means the token is not registered at all (never seen by the registry).\n    // A non-zero address with isValid=false means it was registered but later revoked.\n    if (confidentialTokenAddress === zeroAddress) {\n      return this.#setCached(cacheKey, null, NEGATIVE_CACHE_TTL_MS);\n    }\n\n    return this.#setCached(cacheKey, { confidentialTokenAddress, isValid });\n  }\n\n  /**\n   * Reverse lookup — find the plain ERC-20 for a given confidential token.\n   *\n   * @param confidentialTokenAddress - The confidential token address.\n   * @returns The lookup result, or `null` if no pair is registered.\n   *\n   * @example\n   * ```ts\n   * const result = await registry.getUnderlyingToken(cUsdcAddress);\n   * if (result) {\n   *   console.log(result.tokenAddress, result.isValid);\n   * }\n   * ```\n   */\n  async getUnderlyingToken(\n    confidentialTokenAddress: Address,\n  ): Promise<{ tokenAddress: Address; isValid: boolean } | null> {\n    const registry = await this.getRegistryAddress();\n    const normalized = getAddress(confidentialTokenAddress);\n\n    const cacheKey = `ut:${registry}:${normalized}`;\n    const cached = this.#getCached<{\n      tokenAddress: Address;\n      isValid: boolean;\n    } | null>(cacheKey);\n    if (cached !== undefined) {\n      return cached;\n    }\n\n    const [isValid, tokenAddress] = await this.provider.readContract(\n      getTokenAddressContract(registry, normalized),\n    );\n\n    // Zero address means the confidential token is not registered at all.\n    // A non-zero address with isValid=false means it was registered but later revoked.\n    if (tokenAddress === zeroAddress) {\n      return this.#setCached(cacheKey, null, NEGATIVE_CACHE_TTL_MS);\n    }\n\n    return this.#setCached(cacheKey, { tokenAddress, isValid });\n  }\n\n  // ---------------------------------------------------------------------------\n  // Low-level pass-through methods (backward compatible)\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Fetch all token wrapper pairs from the registry.\n   *\n   * @returns All registered `TokenWrapperPair` entries.\n   */\n  async getTokenPairs(): Promise<readonly TokenWrapperPair[]> {\n    const registry = await this.getRegistryAddress();\n    return this.provider.readContract(getTokenPairsContract(registry));\n  }\n\n  /**\n   * Get the total number of token wrapper pairs.\n   *\n   * @returns The count as a bigint.\n   */\n  async getTokenPairsLength(): Promise<bigint> {\n    const registry = await this.getRegistryAddress();\n    return this.provider.readContract(getTokenPairsLengthContract(registry));\n  }\n\n  /**\n   * Fetch a range of token wrapper pairs (paginated by index).\n   *\n   * @param fromIndex - Start index (inclusive).\n   * @param toIndex - End index (exclusive).\n   * @returns The slice of `TokenWrapperPair` entries.\n   */\n  async getTokenPairsSlice(\n    fromIndex: bigint,\n    toIndex: bigint,\n  ): Promise<readonly TokenWrapperPair[]> {\n    const registry = await this.getRegistryAddress();\n    return this.provider.readContract(getTokenPairsSliceContract(registry, fromIndex, toIndex));\n  }\n\n  /**\n   * Fetch a single token wrapper pair by index.\n   *\n   * @param index - Zero-based pair index.\n   * @returns The `TokenWrapperPair` at that index.\n   */\n  async getTokenPair(index: bigint): Promise<TokenWrapperPair> {\n    const registry = await this.getRegistryAddress();\n    return this.provider.readContract(getTokenPairContract(registry, index));\n  }\n\n  /**\n   * Look up the confidential token address for a given plain ERC-20 token.\n   *\n   * @param tokenAddress - The plain ERC-20 token address.\n   * @returns A tuple `[isValid, confidentialTokenAddress]`. `isValid` is `true` only for a\n   *   registered, non-revoked wrapper. The address is the zero address when no pair is registered.\n   *   A non-zero address with `isValid=false` means the wrapper was registered but later revoked.\n   */\n  async getConfidentialTokenAddress(tokenAddress: Address): Promise<readonly [boolean, Address]> {\n    const registry = await this.getRegistryAddress();\n    return this.provider.readContract(\n      getConfidentialTokenAddressContract(registry, getAddress(tokenAddress)),\n    );\n  }\n\n  /**\n   * Reverse lookup — find the plain ERC-20 for a given confidential token.\n   *\n   * @param confidentialTokenAddress - The confidential token address.\n   * @returns A tuple `[isValid, tokenAddress]`. `isValid` is `true` only for a registered,\n   *   non-revoked wrapper. The address is the zero address when no pair is registered.\n   *   A non-zero address with `isValid=false` means the wrapper was registered but later revoked.\n   */\n  async getTokenAddress(confidentialTokenAddress: Address): Promise<readonly [boolean, Address]> {\n    const registry = await this.getRegistryAddress();\n    return this.provider.readContract(\n      getTokenAddressContract(registry, getAddress(confidentialTokenAddress)),\n    );\n  }\n\n  /**\n   * Check whether a confidential token is registered and valid.\n   *\n   * @param confidentialTokenAddress - The confidential token address to check.\n   * @returns `true` if the token is a known valid wrapper in the registry.\n   */\n  async isConfidentialTokenValid(confidentialTokenAddress: Address): Promise<boolean> {\n    const registry = await this.getRegistryAddress();\n    return this.provider.readContract(\n      isConfidentialTokenValidContract(registry, getAddress(confidentialTokenAddress)),\n    );\n  }\n}\n","import {\n  DEFAULT_TRANSPORT_KEY_PAIR_TTL_SECONDS,\n  DEFAULT_PERMIT_DURATION_DAYS,\n} from \"../credentials/credential-service\";\nimport { TransportKeyPairTTLSchema, PermitTTLSchema } from \"../credentials/schemas\";\nimport { LoggerService } from \"../services/logger-service\";\nimport { RelayerDispatcher } from \"../relayer/relayer-dispatcher\";\nimport type { GenericProvider, GenericSigner } from \"../types\";\nimport { DEFAULT_REGISTRY_TTL_SECONDS, RegistryTTLSchema } from \"../wrappers-registry\";\nimport { parseConfiguration } from \"../validation\";\nimport { resolveStorage } from \"./resolve\";\nimport type { ZamaConfig, ZamaConfigBase } from \"./types\";\n\n/**\n * @internal Shared config builder — not part of the public API.\n *\n * Applies defaults, validates TTLs, and resolves storage so the\n * returned config is fully populated and ready for `ZamaSDK`.\n */\nexport function buildZamaConfig(\n  signer: GenericSigner | undefined,\n  provider: GenericProvider,\n  params: ZamaConfigBase,\n): ZamaConfig {\n  const { storage, permitStorage } = resolveStorage(params.storage, params.permitStorage);\n  const logger = new LoggerService(params.logger);\n  const relayer = new RelayerDispatcher(params.chains, params.relayers, logger);\n\n  return {\n    chains: params.chains,\n    relayer,\n    provider,\n    signer,\n    storage,\n    permitStorage,\n    transportKeyPairTTL: parseConfiguration(\n      TransportKeyPairTTLSchema,\n      params.transportKeyPairTTL ?? DEFAULT_TRANSPORT_KEY_PAIR_TTL_SECONDS,\n    ),\n    permitTTL: parseConfiguration(\n      PermitTTLSchema,\n      params.permitTTL ?? DEFAULT_PERMIT_DURATION_DAYS,\n    ),\n    registryTTL: parseConfiguration(\n      RegistryTTLSchema,\n      params.registryTTL ?? DEFAULT_REGISTRY_TTL_SECONDS,\n    ),\n    logger,\n    onEvent: params.onEvent,\n  } as unknown as ZamaConfig;\n}\n","import type {\n  WalletAccount,\n  WalletAccountChange,\n  WalletAccountListener,\n  WalletAccountStore,\n} from \"../types\";\n\nexport function walletAccountsEqual(\n  a: WalletAccount | undefined,\n  b: WalletAccount | undefined,\n): boolean {\n  return a?.address === b?.address && a?.chainId === b?.chainId;\n}\n\n/**\n * Writable {@link WalletAccountStore} for custom signer adapters. Adapters call\n * {@link MutableWalletAccountStore.setSnapshot} when their underlying wallet\n * provider notifies of a connect, disconnect, account change, or chain change.\n *\n * Most custom adapters should use the {@link createWalletAccountStore} factory\n * rather than instantiating this class directly.\n */\nexport class MutableWalletAccountStore implements WalletAccountStore {\n  readonly #listeners = new Set<WalletAccountListener>();\n  #snapshot: WalletAccount | undefined;\n  #resolved: boolean;\n\n  constructor(initial?: WalletAccount) {\n    this.#snapshot = initial;\n    this.#resolved = initial !== undefined;\n  }\n\n  getSnapshot(): WalletAccount | undefined {\n    return this.#snapshot;\n  }\n\n  /**\n   * Whether the store has received at least one snapshot (via the constructor\n   * or {@link setSnapshot}). Adapters whose initial account is only available\n   * asynchronously start unresolved; callers can distinguish \"still loading\"\n   * from \"wallet not connected\".\n   */\n  isReady(): boolean {\n    return this.#resolved;\n  }\n\n  /**\n   * Push a new wallet account snapshot. No-op when the next value is\n   * value-equal to the current one. Emits `{ previous, next }` to every\n   * subscriber otherwise.\n   */\n  setSnapshot(next: WalletAccount | undefined): void {\n    this.#resolved = true;\n    const previous = this.#snapshot;\n    if (walletAccountsEqual(previous, next)) {\n      return;\n    }\n    this.#snapshot = next;\n    this.#emit({ previous, next });\n  }\n\n  subscribe(listener: WalletAccountListener): () => void {\n    this.#listeners.add(listener);\n    const snapshot = this.#snapshot;\n    if (snapshot) {\n      listener({ previous: undefined, next: snapshot });\n    }\n    return () => {\n      this.#listeners.delete(listener);\n    };\n  }\n\n  #emit(change: WalletAccountChange): void {\n    for (const listener of this.#listeners) {\n      listener(change);\n    }\n  }\n}\n\n/**\n * Create a {@link MutableWalletAccountStore} for a custom {@link GenericSigner}\n * adapter.\n *\n * @param initial - Optional initial wallet account snapshot.\n */\nexport function createWalletAccountStore(initial?: WalletAccount): MutableWalletAccountStore {\n  return new MutableWalletAccountStore(initial);\n}\n","import type { Hex } from \"viem\";\nimport { WalletNotConnectedError } from \"../errors\";\nimport type { EIP712TypedData } from \"../relayer/relayer-sdk.types\";\nimport type {\n  ContractAbi,\n  GenericSigner,\n  WalletAccount,\n  WriteContractArgs,\n  WriteContractConfig,\n  WriteFunctionName,\n} from \"../types\";\nimport { MutableWalletAccountStore } from \"./wallet-account-store\";\n\n/**\n * Abstract base class that implements the shared {@link GenericSigner}\n * boilerplate: wallet-account store, `requireWalletAccount`, idempotent\n * `dispose` / `Disposable`. Subclasses provide `signTypedData`,\n * `writeContract`, and optionally override `onDispose` for cleanup.\n *\n * Using this class is optional — implementing {@link GenericSigner} directly\n * with {@link createWalletAccountStore} remains fully supported.\n */\nexport abstract class BaseSigner implements GenericSigner, Disposable {\n  readonly walletAccount: MutableWalletAccountStore;\n  #disposed = false;\n\n  constructor(initial?: WalletAccount) {\n    this.walletAccount = new MutableWalletAccountStore(initial);\n  }\n\n  requireWalletAccount(operation: string): WalletAccount {\n    const account = this.walletAccount.getSnapshot();\n    if (!account) {\n      throw new WalletNotConnectedError(operation);\n    }\n    return account;\n  }\n\n  abstract signTypedData(typedData: EIP712TypedData): Promise<Hex>;\n\n  abstract writeContract<\n    const TAbi extends ContractAbi,\n    TFunctionName extends WriteFunctionName<TAbi>,\n    const TArgs extends WriteContractArgs<TAbi, TFunctionName>,\n  >(config: WriteContractConfig<TAbi, TFunctionName, TArgs>): Promise<Hex>;\n\n  dispose(): void {\n    if (this.#disposed) {\n      return;\n    }\n    this.#disposed = true;\n    this.onDispose();\n  }\n\n  [Symbol.dispose](): void {\n    this.dispose();\n  }\n\n  protected onDispose(): void {}\n}\n"],"mappings":"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"}