{"version":3,"file":"token.cjs","names":["ZamaError","ZamaErrorCode","ZamaError","ZamaErrorCode","ZamaError","ZamaErrorCode","SigningRejectedError","SigningFailedError","ConfigurationError","SignerNotConfiguredError","WalletAccountNotReadyError","swallow","ZamaError","requireConfigured","nameContract","symbolContract","decimalsContract","supportsInterfaceContract","ERC7984_INTERFACE_ID","ERC7984_WRAPPER_INTERFACE_ID","DecryptionFailedError","ZamaError","toError","#requireSigner","swallow","EncryptionFailedError","confidentialTransferContract","confidentialTransferFromContract","setOperatorContract","isOperatorContract","confidentialBalanceOfContract","submitSdkTransaction","ConfigurationError"],"sources":["../../src/errors/transaction.ts","../../src/errors/chain.ts","../../src/errors/balance.ts","../../src/errors/fatal-batch.ts","../../src/abi/acl.abi.ts","../../src/contracts/acl.ts","../../src/contracts/constants.ts","../../src/utils/alignment.ts","../../src/events/sdk-events.ts","../../src/utils/concurrency.ts","../../src/utils/handles.ts","../../src/utils/submit-transaction.ts","../../src/token/token.ts"],"sourcesContent":["import { ZamaError, ZamaErrorCode } from \"./base\";\n\n/** On-chain transaction reverted. */\nexport class TransactionRevertedError extends ZamaError {\n  constructor(message: string, options?: ErrorOptions) {\n    super(ZamaErrorCode.TransactionReverted, message, options);\n    this.name = \"TransactionRevertedError\";\n  }\n}\n","import { ZamaError, ZamaErrorCode } from \"./base\";\n\n/**\n * Thrown when the signer and provider are connected to different chains at the\n * start of a write operation.\n *\n * Every write method runs a chain-alignment pre-flight check. If\n * `signer.getChainId()` and `provider.getChainId()` return different values,\n * this error is thrown before any RPC mutation is attempted.\n *\n * @example\n * ```ts\n * try {\n *   await token.shield(1000n);\n * } catch (e) {\n *   if (e instanceof ChainMismatchError) {\n *     console.error(\n *       `Signer is on chain ${e.signerChainId} but provider is on chain ${e.providerChainId}`,\n *     );\n *   }\n * }\n * ```\n */\nexport class ChainMismatchError extends ZamaError {\n  readonly operation: string;\n  readonly signerChainId: number;\n  readonly providerChainId: number;\n\n  constructor(\n    {\n      operation,\n      signerChainId,\n      providerChainId,\n    }: { operation: string; signerChainId: number; providerChainId: number },\n    options?: ErrorOptions,\n  ) {\n    super(\n      ZamaErrorCode.ChainMismatch,\n      `Operation \"${operation}\" requires signer and provider to be on the same chain, ` +\n        `but signer is on chain ${signerChainId} and provider is on chain ${providerChainId}.`,\n      options,\n    );\n    this.name = \"ChainMismatchError\";\n    this.operation = operation;\n    this.signerChainId = signerChainId;\n    this.providerChainId = providerChainId;\n  }\n}\n","import type { Address } from \"viem\";\nimport { ZamaError, ZamaErrorCode } from \"./base\";\n\n/** Structured details shared by balance-related errors. */\nexport interface BalanceErrorDetails {\n  readonly requested: bigint;\n  readonly available: bigint;\n  readonly token: Address;\n}\n\n/** Confidential (cToken) balance is insufficient for the requested operation. */\nexport class InsufficientConfidentialBalanceError extends ZamaError {\n  /** The amount the caller requested. */\n  readonly requested: bigint;\n  /** The available balance at the time of the check. */\n  readonly available: bigint;\n  /** The token contract address. */\n  readonly token: Address;\n\n  constructor(message: string, details: BalanceErrorDetails, options?: ErrorOptions) {\n    super(ZamaErrorCode.InsufficientConfidentialBalance, message, options);\n    this.name = \"InsufficientConfidentialBalanceError\";\n    this.requested = details.requested;\n    this.available = details.available;\n    this.token = details.token;\n  }\n}\n\n/** ERC-20 balance is insufficient for the requested shield amount. */\nexport class InsufficientERC20BalanceError extends ZamaError {\n  /** The amount the caller requested. */\n  readonly requested: bigint;\n  /** The available balance at the time of the check. */\n  readonly available: bigint;\n  /** The ERC-20 token contract address. */\n  readonly token: Address;\n\n  constructor(message: string, details: BalanceErrorDetails, options?: ErrorOptions) {\n    super(ZamaErrorCode.InsufficientERC20Balance, message, options);\n    this.name = \"InsufficientERC20BalanceError\";\n    this.requested = details.requested;\n    this.available = details.available;\n    this.token = details.token;\n  }\n}\n\n/** Balance validation could not be performed (no cached credentials and decryption not possible). */\nexport class BalanceCheckUnavailableError extends ZamaError {\n  constructor(message: string, options?: ErrorOptions) {\n    super(ZamaErrorCode.BalanceCheckUnavailable, message, options);\n    this.name = \"BalanceCheckUnavailableError\";\n  }\n}\n\n/** A public ERC-20 read (e.g. balanceOf) failed due to a network or contract error. */\nexport class ERC20ReadFailedError extends ZamaError {\n  constructor(message: string, options?: ErrorOptions) {\n    super(ZamaErrorCode.ERC20ReadFailed, message, options);\n    this.name = \"ERC20ReadFailedError\";\n  }\n}\n","import { ConfigurationError } from \"./relayer\";\nimport { SigningRejectedError, SigningFailedError } from \"./signing\";\n\n/**\n * Returns `true` for errors that should abort an entire batch operation\n * rather than be recorded per-item — wallet signature rejected, signing\n * infrastructure broken, or SDK misconfigured. These are systemic failures\n * that won't recover within the same call.\n *\n * Callers iterating over a batch (e.g. per-token decrypt) should rethrow when\n * this predicate is true so the whole batch aborts, and record the error\n * per-item otherwise.\n */\nexport function isFatalBatchError(error: unknown): boolean {\n  return (\n    error instanceof SigningRejectedError ||\n    error instanceof SigningFailedError ||\n    error instanceof ConfigurationError\n  );\n}\n","// DO NOT EDIT: generated by `pnpm abi:build` from\n// contracts/out/Impl.sol/IACL.json.\n// Regenerate after `pnpm contracts:build`; `pnpm abi:check` enforces this in CI.\nexport const aclAbi = [\n  {\n    type: \"function\",\n    name: \"allow\",\n    inputs: [\n      {\n        name: \"handle\",\n        type: \"bytes32\",\n        internalType: \"bytes32\",\n      },\n      {\n        name: \"account\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n    ],\n    outputs: [],\n    stateMutability: \"nonpayable\",\n  },\n  {\n    type: \"function\",\n    name: \"allowForDecryption\",\n    inputs: [\n      {\n        name: \"handlesList\",\n        type: \"bytes32[]\",\n        internalType: \"bytes32[]\",\n      },\n    ],\n    outputs: [],\n    stateMutability: \"nonpayable\",\n  },\n  {\n    type: \"function\",\n    name: \"allowTransient\",\n    inputs: [\n      {\n        name: \"ciphertext\",\n        type: \"bytes32\",\n        internalType: \"bytes32\",\n      },\n      {\n        name: \"account\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n    ],\n    outputs: [],\n    stateMutability: \"nonpayable\",\n  },\n  {\n    type: \"function\",\n    name: \"cleanTransientStorage\",\n    inputs: [],\n    outputs: [],\n    stateMutability: \"nonpayable\",\n  },\n  {\n    type: \"function\",\n    name: \"delegateForUserDecryption\",\n    inputs: [\n      {\n        name: \"delegate\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n      {\n        name: \"contractAddress\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n      {\n        name: \"expirationDate\",\n        type: \"uint64\",\n        internalType: \"uint64\",\n      },\n    ],\n    outputs: [],\n    stateMutability: \"nonpayable\",\n  },\n  {\n    type: \"function\",\n    name: \"getUserDecryptionDelegationExpirationDate\",\n    inputs: [\n      {\n        name: \"delegator\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n      {\n        name: \"delegate\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n      {\n        name: \"contractAddress\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n    ],\n    outputs: [\n      {\n        name: \"\",\n        type: \"uint64\",\n        internalType: \"uint64\",\n      },\n    ],\n    stateMutability: \"view\",\n  },\n  {\n    type: \"function\",\n    name: \"isAccountDenied\",\n    inputs: [\n      {\n        name: \"account\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n    ],\n    outputs: [\n      {\n        name: \"\",\n        type: \"bool\",\n        internalType: \"bool\",\n      },\n    ],\n    stateMutability: \"view\",\n  },\n  {\n    type: \"function\",\n    name: \"isAllowed\",\n    inputs: [\n      {\n        name: \"handle\",\n        type: \"bytes32\",\n        internalType: \"bytes32\",\n      },\n      {\n        name: \"account\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n    ],\n    outputs: [\n      {\n        name: \"\",\n        type: \"bool\",\n        internalType: \"bool\",\n      },\n    ],\n    stateMutability: \"view\",\n  },\n  {\n    type: \"function\",\n    name: \"isAllowedForDecryption\",\n    inputs: [\n      {\n        name: \"handle\",\n        type: \"bytes32\",\n        internalType: \"bytes32\",\n      },\n    ],\n    outputs: [\n      {\n        name: \"\",\n        type: \"bool\",\n        internalType: \"bool\",\n      },\n    ],\n    stateMutability: \"view\",\n  },\n  {\n    type: \"function\",\n    name: \"isHandleDelegatedForUserDecryption\",\n    inputs: [\n      {\n        name: \"delegator\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n      {\n        name: \"delegate\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n      {\n        name: \"contractAddress\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n      {\n        name: \"handle\",\n        type: \"bytes32\",\n        internalType: \"bytes32\",\n      },\n    ],\n    outputs: [\n      {\n        name: \"\",\n        type: \"bool\",\n        internalType: \"bool\",\n      },\n    ],\n    stateMutability: \"view\",\n  },\n  {\n    type: \"function\",\n    name: \"multicall\",\n    inputs: [\n      {\n        name: \"data\",\n        type: \"bytes[]\",\n        internalType: \"bytes[]\",\n      },\n    ],\n    outputs: [\n      {\n        name: \"results\",\n        type: \"bytes[]\",\n        internalType: \"bytes[]\",\n      },\n    ],\n    stateMutability: \"payable\",\n  },\n  {\n    type: \"function\",\n    name: \"persistAllowed\",\n    inputs: [\n      {\n        name: \"handle\",\n        type: \"bytes32\",\n        internalType: \"bytes32\",\n      },\n      {\n        name: \"account\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n    ],\n    outputs: [\n      {\n        name: \"\",\n        type: \"bool\",\n        internalType: \"bool\",\n      },\n    ],\n    stateMutability: \"view\",\n  },\n  {\n    type: \"function\",\n    name: \"revokeDelegationForUserDecryption\",\n    inputs: [\n      {\n        name: \"delegate\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n      {\n        name: \"contractAddress\",\n        type: \"address\",\n        internalType: \"address\",\n      },\n    ],\n    outputs: [],\n    stateMutability: \"nonpayable\",\n  },\n] as const;\n","import type { Address } from \"viem\";\nimport { aclAbi } from \"../abi/acl.abi\";\n\n/**\n * Returns the contract config to delegate user decryption rights.\n *\n * @example\n * ```ts\n * const txHash = await signer.writeContract(\n *   delegateForUserDecryptionContract(aclAddress, delegateAddress, contractAddress, expirationDate),\n * );\n * ```\n */\nexport function delegateForUserDecryptionContract(\n  aclAddress: Address,\n  delegateAddress: Address,\n  contractAddress: Address,\n  expirationDate: bigint,\n) {\n  return {\n    address: aclAddress,\n    abi: aclAbi,\n    functionName: \"delegateForUserDecryption\",\n    args: [delegateAddress, contractAddress, expirationDate],\n  } as const;\n}\n\n/**\n * Returns the contract config to revoke a user decryption delegation.\n *\n * @example\n * ```ts\n * const txHash = await signer.writeContract(\n *   revokeDelegationContract(aclAddress, delegateAddress, contractAddress),\n * );\n * ```\n */\nexport function revokeDelegationContract(\n  aclAddress: Address,\n  delegateAddress: Address,\n  contractAddress: Address,\n) {\n  return {\n    address: aclAddress,\n    abi: aclAbi,\n    functionName: \"revokeDelegationForUserDecryption\",\n    args: [delegateAddress, contractAddress],\n  } as const;\n}\n\n/**\n * Returns the contract config to read the delegation expiry date.\n *\n * @example\n * ```ts\n * const expiry = await provider.readContract(\n *   getDelegationExpiryContract(aclAddress, delegatorAddress, delegateAddress, contractAddress),\n * );\n * ```\n */\nexport function getDelegationExpiryContract(\n  aclAddress: Address,\n  delegatorAddress: Address,\n  delegateAddress: Address,\n  contractAddress: Address,\n) {\n  return {\n    address: aclAddress,\n    abi: aclAbi,\n    functionName: \"getUserDecryptionDelegationExpirationDate\",\n    args: [delegatorAddress, delegateAddress, contractAddress],\n  } as const;\n}\n\n/**\n * Returns the contract config to check if a specific handle is delegated.\n *\n * @example\n * ```ts\n * const isDelegated = await provider.readContract(\n *   isHandleDelegatedContract(aclAddress, delegatorAddress, delegateAddress, contractAddress, handle),\n * );\n * ```\n */\nexport function isHandleDelegatedContract(\n  aclAddress: Address,\n  delegatorAddress: Address,\n  delegateAddress: Address,\n  contractAddress: Address,\n  handle: `0x${string}`,\n) {\n  return {\n    address: aclAddress,\n    abi: aclAbi,\n    functionName: \"isHandleDelegatedForUserDecryption\",\n    args: [delegatorAddress, delegateAddress, contractAddress, handle],\n  } as const;\n}\n","/** uint64 max — represents a permanent (no-expiry) delegation. */\nexport const MAX_UINT64 = 2n ** 64n - 1n;\n","import {\n  ChainMismatchError,\n  SignerNotConfiguredError,\n  WalletAccountNotReadyError,\n} from \"../errors\";\nimport type { GenericProvider, GenericSigner, WalletAccount } from \"../types\";\n\n/**\n * Pre-flight guard for signer-required operations. Resolves the connected\n * wallet account (refreshing once if the signer reports it isn't ready) and\n * verifies the signer's chain matches the provider's.\n *\n * @internal\n */\nexport async function requireAlignedWalletAccount(\n  operation: string,\n  signer: GenericSigner | undefined,\n  provider: GenericProvider,\n): Promise<WalletAccount> {\n  if (!signer) {\n    throw new SignerNotConfiguredError(operation);\n  }\n  let account: WalletAccount;\n  try {\n    account = signer.requireWalletAccount(operation);\n  } catch (error) {\n    if (!(error instanceof WalletAccountNotReadyError) || !signer.refreshWalletAccount) {\n      throw error;\n    }\n    await signer.refreshWalletAccount();\n    account = signer.requireWalletAccount(operation);\n  }\n  const providerChainId = await provider.getChainId();\n  if (account.chainId !== providerChainId) {\n    throw new ChainMismatchError({\n      operation,\n      signerChainId: account.chainId,\n      providerChainId,\n    });\n  }\n  return account;\n}\n\n/**\n * Variant of {@link requireAlignedWalletAccount} that returns only the aligned\n * chain ID. Useful when a write path only needs to ensure signer/provider\n * coherence and doesn't otherwise consume the account.\n *\n * @internal\n */\nexport async function requireChainAlignment(\n  operation: string,\n  signer: GenericSigner | undefined,\n  provider: GenericProvider,\n): Promise<number> {\n  return (await requireAlignedWalletAccount(operation, signer, provider)).chainId;\n}\n","import type { Address, Hex } from \"viem\";\nimport type { ClearValue, EncryptedValue } from \"../relayer/relayer-sdk.types\";\nimport type { ShieldPath } from \"../types/token\";\n\n/**\n * All SDK event keys, accessible as `ZamaSDKEvents.EncryptStart` etc.\n */\nexport const ZamaSDKEvents = {\n  // FHE operations\n  EncryptStart: \"encrypt:start\",\n  EncryptEnd: \"encrypt:end\",\n  EncryptError: \"encrypt:error\",\n  DecryptStart: \"decrypt:start\",\n  DecryptEnd: \"decrypt:end\",\n  DecryptError: \"decrypt:error\",\n  // Write operations\n  TransactionError: \"transaction:error\",\n  ShieldSubmitted: \"shield:submitted\",\n  TransferSubmitted: \"transfer:submitted\",\n  TransferFromSubmitted: \"transferFrom:submitted\",\n  SetOperatorSubmitted: \"setOperator:submitted\",\n  ApproveUnderlyingSubmitted: \"approveUnderlying:submitted\",\n  UnwrapSubmitted: \"unwrap:submitted\",\n  FinalizeUnwrapSubmitted: \"finalizeUnwrap:submitted\",\n  // Delegation operations\n  DelegationSubmitted: \"delegation:submitted\",\n  RevokeDelegationSubmitted: \"revokeDelegation:submitted\",\n  // Unshield orchestration\n  UnshieldPhase1Submitted: \"unshield:phase1_submitted\",\n  UnshieldPhase2Started: \"unshield:phase2_started\",\n  UnshieldPhase2Submitted: \"unshield:phase2_submitted\",\n} as const;\n\n/** Union of all SDK event type strings. */\nexport type ZamaSDKEventType = (typeof ZamaSDKEvents)[keyof typeof ZamaSDKEvents];\n\n// -- Base fields present on every event --\n\nexport interface BaseEvent {\n  tokenAddress?: Address;\n  timestamp: number;\n  /** Shared identifier linking related events in multi-phase operations (e.g. unshield). */\n  operationId?: string;\n}\n\n// -- Per-event typed payloads --\n\nexport interface EncryptStartEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.EncryptStart;\n}\n\nexport interface EncryptEndEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.EncryptEnd;\n  durationMs: number;\n}\n\nexport interface EncryptErrorEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.EncryptError;\n  /** The error that caused the encryption to fail. */\n  error: Error;\n  durationMs: number;\n}\n\nexport interface DecryptStartEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.DecryptStart;\n  /** Encrypted values being decrypted — correlate with matching DecryptEnd/DecryptError. */\n  encryptedValues: EncryptedValue[];\n}\n\nexport interface DecryptEndEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.DecryptEnd;\n  durationMs: number;\n  /** Encrypted values that were decrypted. */\n  encryptedValues: EncryptedValue[];\n  /** Decrypted values keyed by encrypted value — use this to correlate events to specific entries. */\n  result: Record<EncryptedValue, ClearValue>;\n}\n\nexport interface DecryptErrorEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.DecryptError;\n  /** The error that caused the decryption to fail. */\n  error: Error;\n  durationMs: number;\n  /** Encrypted values that were being decrypted when the error occurred. */\n  encryptedValues: EncryptedValue[];\n}\n\nexport interface TransactionErrorEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.TransactionError;\n  /** Which SDK operation failed. */\n  operation: TransactionOperation;\n  /** The error that caused the transaction to fail. */\n  error: Error;\n}\n\nexport interface ShieldSubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.ShieldSubmitted;\n  txHash: Hex;\n  /** Which execution path was used: single-tx `transferAndCall` or two-tx `approveAndWrap`. */\n  shieldPath: ShieldPath;\n}\n\nexport interface TransferSubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.TransferSubmitted;\n  txHash: Hex;\n}\n\nexport interface TransferFromSubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.TransferFromSubmitted;\n  txHash: Hex;\n}\n\nexport interface SetOperatorSubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.SetOperatorSubmitted;\n  txHash: Hex;\n}\n\nexport interface ApproveUnderlyingSubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.ApproveUnderlyingSubmitted;\n  txHash: Hex;\n  /** Which approval transaction was submitted. */\n  step: \"reset\" | \"approve\";\n}\n\nexport interface UnwrapSubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.UnwrapSubmitted;\n  txHash: Hex;\n}\n\nexport interface FinalizeUnwrapSubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.FinalizeUnwrapSubmitted;\n  txHash: Hex;\n}\n\nexport interface DelegationSubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.DelegationSubmitted;\n  txHash: Hex;\n}\n\nexport interface RevokeDelegationSubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.RevokeDelegationSubmitted;\n  txHash: Hex;\n}\n\nexport interface UnshieldPhase1SubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.UnshieldPhase1Submitted;\n  txHash: Hex;\n}\n\nexport interface UnshieldPhase2StartedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.UnshieldPhase2Started;\n}\n\nexport interface UnshieldPhase2SubmittedEvent extends BaseEvent {\n  type: typeof ZamaSDKEvents.UnshieldPhase2Submitted;\n  txHash: Hex;\n}\n\n/**\n * Discriminated union of all SDK events.\n *\n * Decrypt events carry encrypted values and decrypted clear-text values so event\n * subscribers can correlate and bind them in UI layers. Events never carry\n * private keys, permit signatures, or ZK proofs.\n */\nexport type ZamaSDKEvent =\n  | EncryptStartEvent\n  | EncryptEndEvent\n  | EncryptErrorEvent\n  | DecryptStartEvent\n  | DecryptEndEvent\n  | DecryptErrorEvent\n  | TransactionErrorEvent\n  | ShieldSubmittedEvent\n  | TransferSubmittedEvent\n  | TransferFromSubmittedEvent\n  | SetOperatorSubmittedEvent\n  | ApproveUnderlyingSubmittedEvent\n  | UnwrapSubmittedEvent\n  | FinalizeUnwrapSubmittedEvent\n  | DelegationSubmittedEvent\n  | RevokeDelegationSubmittedEvent\n  | UnshieldPhase1SubmittedEvent\n  | UnshieldPhase2StartedEvent\n  | UnshieldPhase2SubmittedEvent;\n\nexport type ZamaSDKEventListener = (event: ZamaSDKEvent) => void;\n\n/** Distributive Omit that preserves the discriminated union. */\nexport type ZamaSDKEventInput = ZamaSDKEvent extends infer E\n  ? E extends ZamaSDKEvent\n    ? Omit<E, \"timestamp\" | \"tokenAddress\">\n    : never\n  : never;\n\n/**\n * Single source of truth for each transaction operation's submitted-event payload.\n *\n * Adding a write op = adding one entry here. `TransactionOperation` is then\n * `keyof typeof transactionOperationMetadata`, so the dispatch table and the\n * operation union cannot drift.\n *\n * The `satisfies` check enforces that every entry produces a valid\n * {@link ZamaSDKEventInput}.\n */\nexport const transactionOperationMetadata = {\n  approveUnderlying: {\n    submittedEvent: (txHash: Hex) => ({\n      type: ZamaSDKEvents.ApproveUnderlyingSubmitted,\n      txHash,\n      step: \"approve\" as const,\n    }),\n  },\n  \"approveUnderlying:reset\": {\n    submittedEvent: (txHash: Hex) => ({\n      type: ZamaSDKEvents.ApproveUnderlyingSubmitted,\n      txHash,\n      step: \"reset\" as const,\n    }),\n  },\n  delegateDecryption: {\n    submittedEvent: (txHash: Hex) => ({ type: ZamaSDKEvents.DelegationSubmitted, txHash }),\n  },\n  finalizeUnwrap: {\n    submittedEvent: (txHash: Hex) => ({ type: ZamaSDKEvents.FinalizeUnwrapSubmitted, txHash }),\n  },\n  revokeDelegation: {\n    submittedEvent: (txHash: Hex) => ({ type: ZamaSDKEvents.RevokeDelegationSubmitted, txHash }),\n  },\n  setOperator: {\n    submittedEvent: (txHash: Hex) => ({ type: ZamaSDKEvents.SetOperatorSubmitted, txHash }),\n  },\n  \"shield:transferAndCall\": {\n    submittedEvent: (txHash: Hex) => ({\n      type: ZamaSDKEvents.ShieldSubmitted,\n      txHash,\n      shieldPath: \"transferAndCall\" as const,\n    }),\n  },\n  \"shield:approveAndWrap\": {\n    submittedEvent: (txHash: Hex) => ({\n      type: ZamaSDKEvents.ShieldSubmitted,\n      txHash,\n      shieldPath: \"approveAndWrap\" as const,\n    }),\n  },\n  transfer: {\n    submittedEvent: (txHash: Hex) => ({ type: ZamaSDKEvents.TransferSubmitted, txHash }),\n  },\n  transferFrom: {\n    submittedEvent: (txHash: Hex) => ({ type: ZamaSDKEvents.TransferFromSubmitted, txHash }),\n  },\n  unwrap: {\n    submittedEvent: (txHash: Hex) => ({ type: ZamaSDKEvents.UnwrapSubmitted, txHash }),\n  },\n  unwrapAll: {\n    submittedEvent: (txHash: Hex) => ({ type: ZamaSDKEvents.UnwrapSubmitted, txHash }),\n  },\n} satisfies Record<string, { submittedEvent: (txHash: Hex) => ZamaSDKEventInput }>;\n\n/**\n * SDK transaction operations that emit submitted/error lifecycle events.\n *\n * Operation strings encode the execution-path discriminator for flows that have\n * one (`shield:transferAndCall` vs. `shield:approveAndWrap`), routing both error\n * and success events on a single field — see {@link transactionOperationMetadata}.\n */\nexport type TransactionOperation = keyof typeof transactionOperationMetadata;\n","/**\n * Execute an array of async thunks with bounded concurrency.\n * Defaults to `Infinity` (equivalent to `Promise.all`).\n */\nexport async function pLimit<T>(\n  fns: (() => Promise<T>)[],\n  maxConcurrency = Infinity,\n): Promise<T[]> {\n  if (Number.isFinite(maxConcurrency) && maxConcurrency <= 0) {\n    throw new Error(\"maxConcurrency must be a positive number\");\n  }\n  if (!Number.isFinite(maxConcurrency) || maxConcurrency >= fns.length) {\n    return Promise.all(fns.map((f) => f()));\n  }\n\n  const results: T[] = Array.from({ length: fns.length });\n  let index = 0;\n\n  async function worker() {\n    while (index < fns.length) {\n      const i = index++;\n      if (fns[i]) {\n        results[i] = await fns[i]();\n      }\n    }\n  }\n\n  await Promise.all(Array.from({ length: maxConcurrency }, worker));\n  return results;\n}\n","export const ZERO_ENCRYPTED_VALUE =\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\" as const;\n\n/**\n * Check whether an encrypted value represents the zero value.\n */\nexport function isEncryptedValueZero(encryptedValue: string): boolean {\n  return encryptedValue === ZERO_ENCRYPTED_VALUE || encryptedValue === \"0x\";\n}\n","import type { Hex } from \"viem\";\nimport { TransactionRevertedError, ZamaError } from \"../errors\";\nimport type { TransactionOperation, ZamaSDKEventInput } from \"../events/sdk-events\";\nimport { transactionOperationMetadata, ZamaSDKEvents } from \"../events/sdk-events\";\nimport type {\n  GenericProvider,\n  GenericSigner,\n  TransactionResult,\n  WriteContractConfig,\n} from \"../types\";\nimport type { GenericLogger } from \"../worker/worker.types\";\nimport { swallow } from \"./swallow\";\n\n/**\n * Shared write-transaction pipeline for SDK calls that submit a transaction.\n *\n * On success: writes the tx, emits the per-operation submitted event from\n * {@link transactionOperationMetadata}, fires `onSubmitted`, waits for the\n * receipt, and returns `{ txHash, receipt }`.\n *\n * On failure: emits a {@link ZamaSDKEvents.TransactionError} event with the\n * transaction-level error it will throw, then throws it. Existing `ZamaError`\n * instances are rethrown as-is; all other failures are wrapped in\n * `TransactionRevertedError` with the original error as `cause`.\n */\nexport async function submitTransaction(params: {\n  operation: TransactionOperation;\n  signer: GenericSigner;\n  provider: GenericProvider;\n  config: WriteContractConfig;\n  emit: (input: ZamaSDKEventInput) => void;\n  onSubmitted?: (txHash: Hex) => void;\n  logger: GenericLogger;\n}): Promise<TransactionResult> {\n  const { operation, signer, provider, config, emit, onSubmitted, logger } = params;\n  const metadata = transactionOperationMetadata[operation];\n\n  try {\n    const txHash = await signer.writeContract(config);\n    emit(metadata.submittedEvent(txHash));\n    void swallow(`${operation}: onSubmitted`, () => onSubmitted?.(txHash), logger);\n    const receipt = await provider.waitForTransactionReceipt(txHash);\n    return { txHash, receipt };\n  } catch (error) {\n    const failure =\n      error instanceof ZamaError\n        ? error\n        : new TransactionRevertedError(`Transaction failed during ${operation}`, {\n            cause: error,\n          });\n\n    emit({\n      type: ZamaSDKEvents.TransactionError,\n      operation,\n      error: failure,\n    });\n    throw failure;\n  }\n}\n","import { type Address, getAddress, type Hex } from \"viem\";\nimport {\n  confidentialBalanceOfContract,\n  confidentialTransferContract,\n  confidentialTransferFromContract,\n  decimalsContract,\n  ERC7984_INTERFACE_ID,\n  ERC7984_WRAPPER_INTERFACE_ID,\n  isOperatorContract,\n  nameContract,\n  setOperatorContract,\n  supportsInterfaceContract,\n  symbolContract,\n} from \"../contracts\";\nimport {\n  BalanceCheckUnavailableError,\n  ConfigurationError,\n  DecryptionFailedError,\n  EncryptionFailedError,\n  InsufficientConfidentialBalanceError,\n  isFatalBatchError,\n  requireConfigured,\n  ZamaError,\n} from \"../errors\";\nimport type { TransactionOperation, ZamaSDKEventInput } from \"../events/sdk-events\";\nimport type { ClearValue, EncryptedValue } from \"../relayer/relayer-sdk.types\";\nimport { toError } from \"../utils\";\nimport { requireAlignedWalletAccount, requireChainAlignment } from \"../utils/alignment\";\nimport { assertBigint } from \"../utils/assertions\";\nimport { pLimit } from \"../utils/concurrency\";\nimport { isEncryptedValueZero } from \"../utils/handles\";\nimport { submitTransaction as submitSdkTransaction } from \"../utils/submit-transaction\";\nimport { swallow } from \"../utils/swallow\";\nimport type {\n  GenericSigner,\n  TransactionResult,\n  TransferCallbacks,\n  TransferOptions,\n  WriteContractConfig,\n} from \"../types\";\nimport type { ZamaSDK } from \"../zama-sdk\";\n\n/** Options for {@link Token.batchDecryptBalancesAs}. */\nexport interface BatchDecryptAsOptions {\n  /** The address of the account that delegated decryption rights. */\n  delegatorAddress: Address;\n  /** Pre-fetched encrypted values. When omitted, they are fetched from the chain. */\n  encryptedValues?: EncryptedValue[];\n  /**\n   * The account whose on-chain balance to read. Defaults to the delegator\n   * address, which is the common case (the delegator grants permission to\n   * decrypt their own balance). Only set this when the account differs\n   * from the delegator.\n   *\n   * Matches the `account` parameter of `confidentialBalanceOf(account)` on-chain.\n   */\n  accountAddress?: Address;\n  /** Maximum number of concurrent decrypt calls. Default: 10. */\n  maxConcurrency?: number;\n  /** Called when decryption fails for a single token. Return a fallback bigint. */\n  onError?: (error: Error, address: Address) => bigint;\n}\n\n/** Result of {@link Token.batchBalancesOf}. */\nexport interface BatchBalancesResult {\n  /** Successfully decrypted balances, keyed by token address. */\n  results: Map<Address, bigint>;\n  /** Per-token errors for tokens that failed to decrypt. */\n  errors: Map<Address, ZamaError>;\n}\n\n/**\n * High-level interface for an ERC-7984 confidential token.\n * Hides FHE complexity (encryption, decryption, EIP-712 signing) behind\n * familiar ERC-20-like methods.\n *\n * For ERC-7984 wrappers (shield/unshield), use {@link WrappedToken} instead —\n * it extends `Token` with wrapper-specific operations.\n *\n * Decryption, credentials, caching, and event emission are handled by the\n * owning {@link ZamaSDK} — this class only exposes token-scoped helpers\n * that delegate to `sdk.decryption.decryptValues` and `sdk.permits.grantPermit`.\n */\nexport class Token {\n  readonly sdk: ZamaSDK;\n  readonly address: Address;\n\n  constructor(sdk: ZamaSDK, address: Address) {\n    this.sdk = sdk;\n    this.address = getAddress(address);\n  }\n\n  /** Resolve `sdk.signer` or throw {@link SignerNotConfiguredError} tagged with `operation`. */\n  #requireSigner(operation: string): GenericSigner {\n    return requireConfigured(this.sdk.signer, operation);\n  }\n\n  // METADATA\n\n  /** Read the token name from the contract. */\n  async name(): Promise<string> {\n    return this.sdk.provider.readContract(nameContract(this.address));\n  }\n\n  /** Read the token symbol from the contract. */\n  async symbol(): Promise<string> {\n    return this.sdk.provider.readContract(symbolContract(this.address));\n  }\n\n  /** Read the token decimals from the contract. */\n  async decimals(): Promise<number> {\n    return this.sdk.provider.readContract(decimalsContract(this.address));\n  }\n\n  // ERC-165 DISCOVERY\n\n  /**\n   * ERC-165 check for {@link ERC7984_INTERFACE_ID} support.\n   *\n   * @returns `true` if the contract implements the ERC-7984 confidential token interface.\n   */\n  async isConfidential(): Promise<boolean> {\n    return this.sdk.provider.readContract(\n      supportsInterfaceContract(this.address, ERC7984_INTERFACE_ID),\n    );\n  }\n\n  /**\n   * ERC-165 check for IERC7984ERC20Wrapper support.\n   *\n   * @returns `true` if the contract implements the ERC-7984 wrapper interface\n   *   ({@link ERC7984_WRAPPER_INTERFACE_ID}, `0x1f1c62b2`).\n   */\n  async isWrapper(): Promise<boolean> {\n    return this.sdk.provider.readContract(\n      supportsInterfaceContract(this.address, ERC7984_WRAPPER_INTERFACE_ID),\n    );\n  }\n\n  // BALANCES\n\n  /**\n   * Decrypt and return the plaintext balance for the given owner.\n   * Acquires FHE credentials via a wallet signature if none are cached.\n   *\n   * @param owner - Balance owner address.\n   * @returns The decrypted plaintext balance as a bigint.\n   * @throws if FHE decryption fails. {@link DecryptionFailedError}\n   *\n   * @example\n   * ```ts\n   * const balance = await token.balanceOf(\"0xOwner\");\n   * ```\n   */\n  async balanceOf(owner: Address): Promise<bigint> {\n    const ownerAddress = getAddress(owner);\n    const encryptedValue = await this.readConfidentialBalanceOf(ownerAddress);\n    const result = await this.sdk.decryption.decryptValues([\n      { encryptedValue, contractAddress: this.address },\n    ]);\n    const value = result[encryptedValue];\n    if (value === undefined) {\n      throw new DecryptionFailedError(`Decryption returned no value for ${encryptedValue}`);\n    }\n    assertBigint(value, \"balanceOf: result[encryptedValue]\");\n    return value;\n  }\n\n  /**\n   * Return the raw encrypted balance without decrypting.\n   *\n   * @param owner - Balance owner address.\n   * @returns The encrypted balance as a hex string.\n   *\n   * @example\n   * ```ts\n   * const encryptedValue = await token.confidentialBalanceOf(\"0xOwner\");\n   * ```\n   */\n  async confidentialBalanceOf(owner: Address): Promise<EncryptedValue> {\n    return this.readConfidentialBalanceOf(getAddress(owner));\n  }\n\n  /**\n   * Decrypt the balance of a delegator using delegated decryption credentials.\n   * The connected signer acts as the delegatee who has been granted permission\n   * by the delegator to decrypt their balance.\n   *\n   * Clear values are cached in storage keyed by `(account, token, encryptedValue)`.\n   * Because every on-chain balance change produces a new encrypted value,\n   * stale cache entries are never served. Cache write failures are silently\n   * ignored — they do not affect the returned value.\n   *\n   * @param delegatorAddress - The address of the account that delegated decryption rights.\n   * @param accountAddress - The account whose on-chain balance to read. Defaults\n   *   to the delegator address.\n   * @returns The decrypted plaintext balance as a bigint.\n   * @throws if no active delegation exists. {@link DelegationNotFoundError}\n   * @throws if the delegation has expired. {@link DelegationExpiredError}\n   * @throws if delegated decryption fails. {@link DecryptionFailedError}\n   *\n   * @example\n   * ```ts\n   * const balance = await token.decryptBalanceAs({\n   *   delegatorAddress: \"0xDelegator\",\n   * });\n   * ```\n   */\n  async decryptBalanceAs({\n    delegatorAddress,\n    accountAddress,\n  }: {\n    delegatorAddress: Address;\n    accountAddress?: Address;\n  }): Promise<bigint> {\n    await requireChainAlignment(\"decryptBalanceAs\", this.sdk.signer, this.sdk.provider);\n    const normalizedDelegator = getAddress(delegatorAddress);\n    const normalizedAccount = accountAddress ? getAddress(accountAddress) : normalizedDelegator;\n\n    const encryptedValue = await this.readConfidentialBalanceOf(normalizedAccount);\n    if (isEncryptedValueZero(encryptedValue)) {\n      return 0n;\n    }\n\n    const result = await this.sdk.decryption.delegatedDecryptValues(\n      [{ encryptedValue, contractAddress: this.address }],\n      normalizedDelegator,\n      normalizedAccount,\n    );\n\n    const value = result[encryptedValue];\n    if (value === undefined) {\n      throw new DecryptionFailedError(\n        `Delegated decryption returned no value for ${encryptedValue}`,\n      );\n    }\n    assertBigint(value, \"decryptBalanceAs: result[encryptedValue]\");\n    return value;\n  }\n\n  // BATCH STATICS\n\n  /**\n   * Decrypt confidential balances for multiple tokens in parallel, returning\n   * successes and per-token errors separately. Pre-authorizes all token\n   * addresses in a single wallet signature, then delegates each decrypt to\n   * `sdk.decryption.decryptValues`.\n   *\n   * Tokens that fail to decrypt land in `errors` rather than aborting the\n   * whole batch — caller decides how to surface them.\n   *\n   * @param tokens - Array of {@link Token} instances bound to the same SDK.\n   * @param owner - Balance owner address.\n   * @returns `{ results, errors }` partitioning the per-token outcomes.\n   *\n   * @example\n   * ```ts\n   * const { results, errors } = await Token.batchBalancesOf(tokens, owner);\n   * ```\n   */\n  static async batchBalancesOf(tokens: Token[], owner: Address): Promise<BatchBalancesResult> {\n    const results = new Map<Address, bigint>();\n    const errors = new Map<Address, ZamaError>();\n    if (tokens.length === 0) {\n      return { results, errors };\n    }\n\n    const sdk = Token.assertSameSdk(tokens);\n    // Fail fast on chain mismatch before prompting the wallet for a signature.\n    await requireChainAlignment(\"batchBalancesOf\", sdk.signer, sdk.provider);\n    // Pre-authorize the full token set in one wallet signature so subsequent\n    // per-token decryptValues calls reuse the cached credentials.\n    await sdk.permits.grantPermit(tokens.map((t) => t.address));\n\n    const outcomes = await pLimit(\n      tokens.map((t) => async () => {\n        try {\n          return {\n            status: \"fulfilled\" as const,\n            value: await t.balanceOf(owner),\n          };\n        } catch (reason) {\n          return { status: \"rejected\" as const, reason };\n        }\n      }),\n      5,\n    );\n\n    for (let i = 0; i < tokens.length; i++) {\n      const tokenAddress = tokens[i]!.address;\n      const outcome = outcomes[i]!;\n      if (outcome.status === \"fulfilled\") {\n        results.set(tokenAddress, outcome.value);\n      } else {\n        const reason = outcome.reason;\n        // Session-level failures (user rejected signature, SDK misconfigured)\n        // apply to every token — surface them instead of collecting per-token.\n        if (isFatalBatchError(reason)) {\n          throw reason;\n        }\n        const error =\n          reason instanceof ZamaError\n            ? reason\n            : new DecryptionFailedError(toError(reason).message, {\n                cause: reason,\n              });\n        errors.set(tokenAddress, error);\n      }\n    }\n\n    // Total failure: surface the first error so callers know nothing decrypted.\n    if (errors.size === tokens.length) {\n      const firstError = errors.values().next().value;\n      throw firstError ?? new DecryptionFailedError(\"All token balance decryptions failed\");\n    }\n\n    return { results, errors };\n  }\n\n  /**\n   * Batch decrypt confidential balances as a delegate across multiple tokens.\n   * Mirrors {@link batchBalancesOf} but uses delegated credentials.\n   *\n   * **Error handling:** If a per-token decryption fails and no `onError` callback\n   * is provided, errors are collected and thrown as an aggregated\n   * `DecryptionFailedError`. When the relayer returns no value for an encrypted value,\n   * a `DecryptionFailedError` is thrown for that token (never silently returns `0n`).\n   * Pass `onError: () => 0n` to opt into the silent zero behavior.\n   *\n   * @param tokens - Array of Token instances to decrypt balances for.\n   * @param options - Delegated decryption configuration.\n   * @returns A Map from token address to decrypted balance.\n   * @throws if no active delegation exists. {@link DelegationNotFoundError}\n   * @throws if the delegation has expired. {@link DelegationExpiredError}\n   * @throws if any decryption fails and no `onError` is provided. {@link DecryptionFailedError}\n   *\n   * @example\n   * ```ts\n   * const balances = await Token.batchDecryptBalancesAs(tokens, {\n   *   delegatorAddress: \"0xDelegator\",\n   *   onError: (err, addr) => { console.error(addr, err); return 0n; },\n   * });\n   * ```\n   */\n  static async batchDecryptBalancesAs(\n    tokens: Token[],\n    options: BatchDecryptAsOptions,\n  ): Promise<Map<Address, bigint>> {\n    if (tokens.length === 0) {\n      return new Map();\n    }\n\n    const sdk = Token.assertSameSdk(tokens);\n    const results = new Map<Address, bigint>();\n    const errors = new Map<Address, ZamaError>();\n    const normalizedAccount = options.accountAddress\n      ? getAddress(options.accountAddress)\n      : getAddress(options.delegatorAddress);\n    const maxConcurrency = options.maxConcurrency ?? 10;\n    if (options.encryptedValues && tokens.length !== options.encryptedValues.length) {\n      throw new DecryptionFailedError(\n        `tokens.length (${tokens.length}) must equal encryptedValues.length (${options.encryptedValues.length})`,\n      );\n    }\n    const resolvedEncryptedValues =\n      options.encryptedValues ??\n      (await Token.readBalanceHandlesBatch(tokens, normalizedAccount, errors, maxConcurrency));\n\n    const decryptRequests: Array<{ token: Token; encryptedValue: EncryptedValue }> = [];\n    for (const [index, token] of tokens.entries()) {\n      const encryptedValue = resolvedEncryptedValues[index];\n      if (!encryptedValue || errors.has(token.address)) {\n        continue;\n      }\n      if (isEncryptedValueZero(encryptedValue)) {\n        // Zero balance → skip the relayer; no decryption needed.\n        results.set(token.address, 0n);\n      } else {\n        decryptRequests.push({ token, encryptedValue });\n      }\n    }\n\n    if (decryptRequests.length > 0) {\n      const decrypted = await sdk.decryption.delegatedBatchDecryptValues({\n        encryptedInputs: decryptRequests.map(({ token, encryptedValue }) => ({\n          encryptedValue,\n          contractAddress: token.address,\n        })),\n        delegatorAddress: options.delegatorAddress,\n        accountAddress: options.accountAddress,\n        maxConcurrency,\n      });\n\n      for (const [index, item] of decrypted.items.entries()) {\n        const request = decryptRequests[index];\n        if (!request) {\n          continue;\n        }\n        if (item.error) {\n          errors.set(request.token.address, item.error);\n          continue;\n        }\n        const value = item.value;\n        if (value === undefined) {\n          errors.set(\n            request.token.address,\n            new DecryptionFailedError(\n              `Batch delegated decryption returned no value for ${item.encryptedValue} on token ${request.token.address}`,\n            ),\n          );\n          continue;\n        }\n        assertBigint(value, \"batchDecryptBalancesAs: result[encryptedValue]\");\n        results.set(request.token.address, value);\n      }\n    }\n\n    if (errors.size === 0) {\n      return results;\n    }\n\n    if (options.onError) {\n      const callbackErrors: Array<{ address: Address; error: Error }> = [];\n      for (const [address, error] of errors) {\n        try {\n          results.set(address, options.onError(error, address));\n        } catch (callbackError) {\n          callbackErrors.push({ address, error: toError(callbackError) });\n        }\n      }\n      if (callbackErrors.length > 0) {\n        const message = callbackErrors\n          .map(({ address, error }) => `${address}: ${error.message}`)\n          .join(\"; \");\n        throw new DecryptionFailedError(\n          `Batch delegated decryption onError callback failed for ${callbackErrors.length} token(s): ${message}`,\n          { cause: callbackErrors[0]?.error },\n        );\n      }\n      return results;\n    }\n\n    const errorEntries = Array.from(errors.entries());\n    const message = errorEntries.map(([addr, e]) => `${addr}: ${e.message}`).join(\"; \");\n    throw new DecryptionFailedError(\n      `Batch delegated decryption failed for ${errors.size} token(s): ${message}`,\n      { cause: errorEntries[0]?.[1] },\n    );\n  }\n\n  private static async readBalanceHandlesBatch(\n    tokens: Token[],\n    accountAddress: Address,\n    errors: Map<Address, ZamaError>,\n    maxConcurrency: number,\n  ): Promise<Array<EncryptedValue | undefined>> {\n    const outcomes = await pLimit(\n      tokens.map((token) => async () => {\n        try {\n          return {\n            status: \"fulfilled\" as const,\n            value: await token.readConfidentialBalanceOf(accountAddress),\n          };\n        } catch (reason) {\n          return { status: \"rejected\" as const, reason };\n        }\n      }),\n      maxConcurrency,\n    );\n\n    const encryptedValues: Array<EncryptedValue | undefined> = [];\n    for (const [index, token] of tokens.entries()) {\n      const outcome = outcomes[index];\n      if (!outcome) {\n        continue;\n      }\n      if (outcome.status === \"fulfilled\") {\n        encryptedValues[index] = outcome.value;\n        continue;\n      }\n      if (isFatalBatchError(outcome.reason)) {\n        throw outcome.reason;\n      }\n      errors.set(\n        token.address,\n        outcome.reason instanceof ZamaError\n          ? outcome.reason\n          : new DecryptionFailedError(toError(outcome.reason).message, {\n              cause: outcome.reason,\n            }),\n      );\n    }\n    return encryptedValues;\n  }\n\n  // WRITE OPERATIONS\n\n  /**\n   * Confidential transfer. Encrypts the amount via FHE, then calls the contract.\n   *\n   * By default, the SDK validates the confidential balance before submitting.\n   * If a cached plaintext balance exists it is used; otherwise, if credentials\n   * are cached, it decrypts on the fly. Set `skipBalanceCheck: true` to bypass\n   * this validation (e.g. for smart wallets).\n   *\n   * @param to - Recipient address.\n   * @param amount - Plaintext amount to transfer (encrypted automatically via FHE).\n   * @param options - Optional: `skipBalanceCheck` (default `false`).\n   * @returns The transaction hash and mined receipt.\n   * @throws if signer and provider are on different chains. {@link ChainMismatchError}\n   * @throws if the balance is less than `amount`. {@link InsufficientConfidentialBalanceError}\n   * @throws if balance validation requires decryption that is not possible. {@link BalanceCheckUnavailableError}\n   * @throws if FHE encryption fails. {@link EncryptionFailedError}\n   * @throws if the on-chain transfer reverts. {@link TransactionRevertedError}\n   *\n   * @example\n   * ```ts\n   * const txHash = await token.confidentialTransfer(\"0xRecipient\", 1000n);\n   * ```\n   */\n  async confidentialTransfer(\n    to: Address,\n    amount: bigint,\n    options?: TransferOptions,\n  ): Promise<TransactionResult> {\n    this.#requireSigner(\"confidentialTransfer\");\n    const account = await requireAlignedWalletAccount(\n      \"confidentialTransfer\",\n      this.sdk.signer,\n      this.sdk.provider,\n    );\n    const { skipBalanceCheck = false, onEncryptComplete, onTransferSubmitted } = options ?? {};\n\n    const normalizedTo = getAddress(to);\n\n    if (!skipBalanceCheck) {\n      await this.assertConfidentialBalance(amount);\n    }\n\n    const { encryptedValues, inputProof } = await this.sdk.encrypt({\n      values: [{ value: amount, type: \"euint64\" }],\n      contractAddress: this.address,\n      userAddress: getAddress(account.address),\n    });\n    void swallow(\"transfer: onEncryptComplete\", () => onEncryptComplete?.(), this.sdk.logger);\n\n    if (encryptedValues.length === 0) {\n      throw new EncryptionFailedError(\"Encryption returned no encrypted values\");\n    }\n\n    return this.submitTransaction({\n      operation: \"transfer\",\n      config: confidentialTransferContract(\n        this.address,\n        normalizedTo,\n        encryptedValues[0]!,\n        inputProof,\n      ),\n      onSubmitted: onTransferSubmitted,\n    });\n  }\n\n  /**\n   * Operator encrypted transfer on behalf of another address.\n   * The caller must be an approved operator for `from`.\n   *\n   * @param from - The address to transfer from (caller must be an approved operator).\n   * @param to - Recipient address.\n   * @param amount - Plaintext amount to transfer (encrypted automatically via FHE).\n   * @returns The transaction hash and mined receipt.\n   *\n   * @example\n   * ```ts\n   * const txHash = await token.confidentialTransferFrom(\"0xFrom\", \"0xTo\", 500n);\n   * ```\n   */\n  async confidentialTransferFrom(\n    from: Address,\n    to: Address,\n    amount: bigint,\n    callbacks?: TransferCallbacks,\n  ): Promise<TransactionResult> {\n    this.#requireSigner(\"confidentialTransferFrom\");\n    await requireAlignedWalletAccount(\n      \"confidentialTransferFrom\",\n      this.sdk.signer,\n      this.sdk.provider,\n    );\n    const normalizedFrom = getAddress(from);\n    const normalizedTo = getAddress(to);\n\n    const { encryptedValues, inputProof } = await this.sdk.encrypt({\n      values: [{ value: amount, type: \"euint64\" }],\n      contractAddress: this.address,\n      userAddress: normalizedFrom,\n    });\n    void swallow(\n      \"transferFrom: onEncryptComplete\",\n      () => callbacks?.onEncryptComplete?.(),\n      this.sdk.logger,\n    );\n\n    if (encryptedValues.length === 0) {\n      throw new EncryptionFailedError(\"Encryption returned no encrypted values\");\n    }\n\n    return this.submitTransaction({\n      operation: \"transferFrom\",\n      config: confidentialTransferFromContract(\n        this.address,\n        normalizedFrom,\n        normalizedTo,\n        encryptedValues[0]!,\n        inputProof,\n      ),\n      onSubmitted: callbacks?.onTransferSubmitted,\n    });\n  }\n\n  // OPERATOR APPROVAL\n\n  /**\n   * Set operator approval for the confidential token.\n   * Defaults to 1 hour from now if `until` is not specified.\n   *\n   * @param operator - The address to set as an operator.\n   * @param until - Optional Unix timestamp for approval expiry. Defaults to now + 1 hour.\n   * @returns The transaction hash and mined receipt.\n   *\n   * @example\n   * ```ts\n   * const txHash = await token.setOperator(\"0xOperator\");\n   * ```\n   */\n  async setOperator(operator: Address, until?: number): Promise<TransactionResult> {\n    this.#requireSigner(\"setOperator\");\n    await requireChainAlignment(\"setOperator\", this.sdk.signer, this.sdk.provider);\n    const normalizedOperator = getAddress(operator);\n    return this.submitTransaction({\n      operation: \"setOperator\",\n      config: setOperatorContract(this.address, normalizedOperator, until),\n    });\n  }\n\n  /**\n   * Check if a spender is an approved operator for a given holder.\n   *\n   * @param holder - The token holder address.\n   * @param spender - The address to check operator approval for.\n   * @returns `true` if the spender is an approved operator for the holder.\n   *\n   * @example\n   * ```ts\n   * if (await token.isOperator(\"0xHolder\", \"0xSpender\")) {\n   *   // spender can call transferFrom on behalf of holder\n   * }\n   * ```\n   */\n  async isOperator(holder: Address, spender: Address): Promise<boolean> {\n    return this.sdk.provider.readContract(\n      isOperatorContract(this.address, getAddress(holder), getAddress(spender)),\n    );\n  }\n\n  // PROTECTED HELPERS\n\n  /**\n   * Read the on-chain encrypted balance for a given owner.\n   *\n   * @internal\n   */\n  protected async readConfidentialBalanceOf(owner: Address): Promise<EncryptedValue> {\n    return await this.sdk.provider.readContract(confidentialBalanceOfContract(this.address, owner));\n  }\n\n  /**\n   * Pre-flight check: decrypt the confidential balance and compare against the\n   * requested amount. If credentials are cached the decrypt happens silently;\n   * if not, throws {@link BalanceCheckUnavailableError} instead of triggering\n   * a surprise EIP-712 popup.\n   *\n   * @internal\n   */\n  protected async assertConfidentialBalance(amount: bigint): Promise<void> {\n    if (amount === 0n) {\n      return;\n    }\n\n    let balance: bigint;\n    try {\n      const account = await requireAlignedWalletAccount(\n        \"assertConfidentialBalance\",\n        this.sdk.signer,\n        this.sdk.provider,\n      );\n      balance = await this.balanceOf(getAddress(account.address));\n    } catch (error) {\n      if (error instanceof ZamaError) {\n        throw error;\n      }\n      throw new BalanceCheckUnavailableError(`Balance validation failed (token: ${this.address})`, {\n        cause: error,\n      });\n    }\n\n    if (balance < amount) {\n      throw new InsufficientConfidentialBalanceError(\n        `Insufficient confidential balance: requested ${amount}, available ${balance} (token: ${this.address})`,\n        { requested: amount, available: balance, token: this.address },\n      );\n    }\n  }\n\n  /**\n   * Emit a token-scoped event through the owning {@link ZamaSDK} so that\n   * subscribers see a unified stream.\n   *\n   * @internal\n   */\n  protected emit(input: ZamaSDKEventInput): void {\n    this.sdk.emitEvent(input, this.address);\n  }\n\n  /**\n   * Submit a token-scoped write transaction through the shared SDK transaction\n   * pipeline. Callers keep pre-flight and operation-specific work local.\n   *\n   * @internal\n   */\n  protected async submitTransaction(params: {\n    operation: TransactionOperation;\n    config: WriteContractConfig;\n    onSubmitted?: (txHash: Hex) => void;\n  }): Promise<TransactionResult> {\n    const { operation, config, onSubmitted } = params;\n    return submitSdkTransaction({\n      operation,\n      signer: this.#requireSigner(operation),\n      provider: this.sdk.provider,\n      config,\n      emit: (input) => this.emit(input),\n      onSubmitted,\n      logger: this.sdk.logger,\n    });\n  }\n\n  /** Verify all tokens share the same SDK instance and return it. */\n  private static assertSameSdk(tokens: Token[]): ZamaSDK {\n    const sdk = tokens[0]!.sdk;\n    for (let i = 1; i < tokens.length; i++) {\n      if (tokens[i]!.sdk !== sdk) {\n        throw new ConfigurationError(\n          \"All tokens in a batch operation must share the same ZamaSDK instance\",\n        );\n      }\n    }\n    return sdk;\n  }\n}\n\n/** @internal */\nexport type DecryptedHandlesMap = Map<EncryptedValue, ClearValue>;\n"],"mappings":"wJAGA,IAAa,EAAb,cAA8CA,EAAAA,CAAU,CACtD,YAAY,EAAiB,EAAwB,CACnD,MAAMC,EAAAA,EAAc,oBAAqB,EAAS,CAAO,EACzD,KAAK,KAAO,0BACd,CACF,ECea,EAAb,cAAwCC,EAAAA,CAAU,CAChD,UACA,cACA,gBAEA,YACE,CACE,YACA,gBACA,mBAEF,EACA,CACA,MACEC,EAAAA,EAAc,cACd,cAAc,EAAU,iFACI,EAAc,4BAA4B,EAAgB,GACtF,CACF,EACA,KAAK,KAAO,qBACZ,KAAK,UAAY,EACjB,KAAK,cAAgB,EACrB,KAAK,gBAAkB,CACzB,CACF,ECpCa,EAAb,cAA0DC,EAAAA,CAAU,CAElE,UAEA,UAEA,MAEA,YAAY,EAAiB,EAA8B,EAAwB,CACjF,MAAMC,EAAAA,EAAc,gCAAiC,EAAS,CAAO,EACrE,KAAK,KAAO,uCACZ,KAAK,UAAY,EAAQ,UACzB,KAAK,UAAY,EAAQ,UACzB,KAAK,MAAQ,EAAQ,KACvB,CACF,EAGa,EAAb,cAAmDD,EAAAA,CAAU,CAE3D,UAEA,UAEA,MAEA,YAAY,EAAiB,EAA8B,EAAwB,CACjF,MAAMC,EAAAA,EAAc,yBAA0B,EAAS,CAAO,EAC9D,KAAK,KAAO,gCACZ,KAAK,UAAY,EAAQ,UACzB,KAAK,UAAY,EAAQ,UACzB,KAAK,MAAQ,EAAQ,KACvB,CACF,EAGa,EAAb,cAAkDD,EAAAA,CAAU,CAC1D,YAAY,EAAiB,EAAwB,CACnD,MAAMC,EAAAA,EAAc,wBAAyB,EAAS,CAAO,EAC7D,KAAK,KAAO,8BACd,CACF,EAGa,EAAb,cAA0CD,EAAAA,CAAU,CAClD,YAAY,EAAiB,EAAwB,CACnD,MAAMC,EAAAA,EAAc,gBAAiB,EAAS,CAAO,EACrD,KAAK,KAAO,sBACd,CACF,EC/CA,SAAgB,EAAkB,EAAyB,CACzD,OACE,aAAiBC,EAAAA,GACjB,aAAiBC,EAAAA,GACjB,aAAiBC,EAAAA,CAErB,CChBA,MAAa,EAAS,CACpB,CACE,KAAM,WACN,KAAM,QACN,OAAQ,CACN,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,qBACN,OAAQ,CACN,CACE,KAAM,cACN,KAAM,YACN,aAAc,WAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,iBACN,OAAQ,CACN,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,wBACN,OAAQ,CAAC,EACT,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,4BACN,OAAQ,CACN,CACE,KAAM,WACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,kBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,iBACN,KAAM,SACN,aAAc,QAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,4CACN,OAAQ,CACN,CACE,KAAM,YACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,WACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,kBACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,SACN,aAAc,QAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,kBACN,OAAQ,CACN,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,YACN,OAAQ,CACN,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,yBACN,OAAQ,CACN,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,qCACN,OAAQ,CACN,CACE,KAAM,YACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,WACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,kBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,YACN,OAAQ,CACN,CACE,KAAM,OACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,SACnB,EACA,CACE,KAAM,WACN,KAAM,iBACN,OAAQ,CACN,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,oCACN,OAAQ,CACN,CACE,KAAM,WACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,kBACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,CACF,EChQA,SAAgB,EACd,EACA,EACA,EACA,EACA,CACA,MAAO,CACL,QAAS,EACT,IAAK,EACL,aAAc,4BACd,KAAM,CAAC,EAAiB,EAAiB,CAAc,CACzD,CACF,CAYA,SAAgB,EACd,EACA,EACA,EACA,CACA,MAAO,CACL,QAAS,EACT,IAAK,EACL,aAAc,oCACd,KAAM,CAAC,EAAiB,CAAe,CACzC,CACF,CAYA,SAAgB,EACd,EACA,EACA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"}