{"version":3,"sources":["../../../../src/batch-settlement/server/scheme.ts","../../../../src/batch-settlement/server/channelManager.ts","../../../../src/batch-settlement/server/storage.ts","../../../../src/batch-settlement/server/verify.ts","../../../../src/batch-settlement/server/utils.ts","../../../../src/batch-settlement/server/settle.ts"],"sourcesContent":["import {\n  AssetAmount,\n  Network,\n  PaymentPayload,\n  PaymentRequirements,\n  Price,\n  SchemeNetworkServer,\n  SchemeServerHooks,\n  MoneyParser,\n  SupportedKind,\n} from \"@x402/core/types\";\nimport type { DeepReadonly } from \"@x402/core/types\";\nimport type { SettleContext, SettleResultContext } from \"@x402/core/server\";\nimport { convertToTokenAmount, numberToDecimalString, parseMoneyString } from \"@x402/core/utils\";\nimport type { FacilitatorClient } from \"@x402/core/server\";\nimport { getAddress } from \"viem\";\nimport { BatchSettlementChannelManager } from \"./channelManager\";\nimport { getDefaultAsset } from \"../../shared/defaultAssets\";\nimport type { AuthorizerSigner } from \"../types\";\nimport { BATCH_SETTLEMENT_SCHEME, MIN_WITHDRAW_DELAY } from \"../constants\";\nimport { InMemoryChannelStorage, ChannelStorage, type Channel } from \"./storage\";\nimport {\n  handleAfterVerify,\n  handleBeforeVerify,\n  handleEnrichPaymentRequiredResponse,\n  handleVerifyFailure,\n  handleVerifiedPaymentCanceled,\n} from \"./verify\";\nimport {\n  handleAfterSettle,\n  handleBeforeSettle,\n  handleEnrichSettlementPayload,\n  handleEnrichSettlementResponse,\n  handleSettleFailure,\n} from \"./settle\";\n\nexport interface BatchSettlementEvmSchemeServerConfig {\n  storage?: ChannelStorage;\n  receiverAuthorizerSigner?: AuthorizerSigner;\n  withdrawDelay?: number;\n  onchainStateTtlMs?: number;\n}\n\nexport interface BatchSettlementRequestContext {\n  channelId?: string;\n  pendingId?: string;\n  channelSnapshot?: Channel;\n  localVerify?: boolean;\n}\n\n/**\n * Server-side implementation of the `batch-settlement` scheme for EVM networks.\n */\nexport class BatchSettlementEvmScheme implements SchemeNetworkServer {\n  readonly scheme = BATCH_SETTLEMENT_SCHEME;\n  readonly schemeHooks: SchemeServerHooks;\n\n  private readonly requestContexts = new WeakMap<\n    DeepReadonly<PaymentPayload>,\n    BatchSettlementRequestContext\n  >();\n  private moneyParsers: MoneyParser[] = [];\n  private readonly storage: ChannelStorage;\n  private readonly receiverAuthorizerSigner: AuthorizerSigner | undefined;\n  private readonly receiverAddress: `0x${string}`;\n  private readonly withdrawDelay: number;\n  private readonly onchainStateTtlMs: number;\n\n  /**\n   * Constructs a batched server scheme.\n   *\n   * @param receiverAddress - The server's receiver address (payTo).\n   * @param config - Optional configuration for storage, receiver-authorizer signer, and withdraw delay.\n   */\n  constructor(receiverAddress: `0x${string}`, config?: BatchSettlementEvmSchemeServerConfig) {\n    this.receiverAddress = receiverAddress;\n    this.storage = config?.storage ?? new InMemoryChannelStorage();\n    this.receiverAuthorizerSigner = config?.receiverAuthorizerSigner;\n    this.withdrawDelay = config?.withdrawDelay ?? MIN_WITHDRAW_DELAY;\n    this.onchainStateTtlMs =\n      config?.onchainStateTtlMs ?? defaultOnchainStateTtlMs(this.withdrawDelay);\n    this.schemeHooks = {\n      onBeforeVerify: ctx => handleBeforeVerify(this, ctx),\n      onAfterVerify: ctx => handleAfterVerify(this, ctx),\n      onBeforeSettle: ctx => handleBeforeSettle(this, ctx),\n      onAfterSettle: ctx => handleAfterSettle(this, ctx),\n      onVerifyFailure: ctx => handleVerifyFailure(this, ctx),\n      onSettleFailure: ctx => handleSettleFailure(this, ctx),\n      onVerifiedPaymentCanceled: ctx => handleVerifiedPaymentCanceled(this, ctx),\n    };\n  }\n\n  /**\n   * Adds server-owned settlement fields before facilitator settlement.\n   *\n   * @param ctx - Settlement context for the current payment.\n   * @returns Additive payload fields, or nothing when no enrichment is needed.\n   */\n  enrichSettlementPayload = (ctx: SettleContext): Promise<Record<string, unknown> | void> =>\n    handleEnrichSettlementPayload(this, ctx);\n\n  /**\n   * Adds corrective channel state to payment-required responses when available.\n   *\n   * @param ctx - Payment-required response context for the current request.\n   * @returns Updated payment requirements, or nothing when no enrichment is needed.\n   */\n  enrichPaymentRequiredResponse = (\n    ctx: Parameters<typeof handleEnrichPaymentRequiredResponse>[1],\n  ): Promise<PaymentRequirements[] | void> => handleEnrichPaymentRequiredResponse(this, ctx);\n\n  /**\n   * Adds server-owned extra fields after facilitator settlement.\n   *\n   * @param ctx - Settlement result context for the current payment.\n   * @returns Additive response extra fields, or nothing when no enrichment is needed.\n   */\n  enrichSettlementResponse = (ctx: SettleResultContext): Promise<Record<string, unknown> | void> =>\n    handleEnrichSettlementResponse(this, ctx);\n\n  /**\n   * Merges batch-settlement state into the current request context.\n   *\n   * @param payload - Request-scoped payment payload object.\n   * @param context - Partial context fields to merge.\n   */\n  mergeRequestContext(\n    payload: DeepReadonly<PaymentPayload>,\n    context: BatchSettlementRequestContext,\n  ): void {\n    this.requestContexts.set(payload, {\n      ...this.requestContexts.get(payload),\n      ...context,\n    });\n  }\n\n  /**\n   * Reads batch-settlement state for the current request without clearing it.\n   *\n   * @param payload - Request-scoped payment payload object.\n   * @returns Request context, if one was recorded.\n   */\n  readRequestContext(\n    payload: DeepReadonly<PaymentPayload>,\n  ): BatchSettlementRequestContext | undefined {\n    return this.requestContexts.get(payload);\n  }\n\n  /**\n   * Reads and clears batch-settlement state for the current request.\n   *\n   * @param payload - Request-scoped payment payload object.\n   * @returns Request context, if one was recorded.\n   */\n  takeRequestContext(\n    payload: DeepReadonly<PaymentPayload>,\n  ): BatchSettlementRequestContext | undefined {\n    const context = this.requestContexts.get(payload);\n    this.requestContexts.delete(payload);\n    return context;\n  }\n\n  /**\n   * Stores a channel snapshot for the current settlement request.\n   *\n   * @param payload - Request-scoped payment payload object.\n   * @param channel - Channel state to use during response enrichment.\n   */\n  rememberChannelSnapshot(payload: DeepReadonly<PaymentPayload>, channel: Channel): void {\n    this.mergeRequestContext(payload, {\n      channelId: channel.channelId,\n      channelSnapshot: channel,\n    });\n  }\n\n  /**\n   * Reads and clears a channel snapshot for the current settlement request.\n   *\n   * @param payload - Request-scoped payment payload object.\n   * @returns Stored channel state, if one was recorded.\n   */\n  takeChannelSnapshot(payload: DeepReadonly<PaymentPayload>): Channel | undefined {\n    return this.takeRequestContext(payload)?.channelSnapshot;\n  }\n\n  /**\n   * Clears this request's pending reservation without touching newer reservations.\n   *\n   * @param payload - Request-scoped payment payload object.\n   */\n  async clearPendingRequest(payload: DeepReadonly<PaymentPayload>): Promise<void> {\n    const context = this.takeRequestContext(payload);\n    if (!context?.channelId || !context.pendingId) {\n      return;\n    }\n\n    await this.storage.updateChannel(context.channelId, current => {\n      if (!current || current.pendingRequest?.pendingId !== context.pendingId) {\n        return current;\n      }\n\n      if (!context.channelSnapshot) {\n        return undefined;\n      }\n\n      return {\n        ...current,\n        pendingRequest: undefined,\n      };\n    });\n  }\n\n  /**\n   * Registers a custom money parser for converting price strings to token amounts.\n   *\n   * @param parser - A parser function to try before the default USD→token conversion.\n   * @returns `this` for chaining.\n   */\n  registerMoneyParser(parser: MoneyParser): BatchSettlementEvmScheme {\n    this.moneyParsers.push(parser);\n    return this;\n  }\n\n  /**\n   * Resolves a human-readable price (e.g. `\"$0.01\"`) into an onchain token amount.\n   *\n   * @param price - A price string, number, or explicit {@link AssetAmount}.\n   * @param network - CAIP-2 network identifier for looking up the default asset.\n   * @returns Token amount with asset address and metadata.\n   */\n  async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n    if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n      if (!price.asset) {\n        throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n      }\n      return {\n        amount: price.amount,\n        asset: price.asset,\n        extra: price.extra || {},\n      };\n    }\n\n    const amount = this.parseMoneyToDecimal(price);\n\n    for (const parser of this.moneyParsers) {\n      const result = await parser(amount, network);\n      if (result !== null) {\n        return result;\n      }\n    }\n\n    return this.defaultMoneyConversion(amount, network);\n  }\n\n  /**\n   * Injects batched-specific fields into the payment requirements returned to\n   * the client (receiverAuthorizer, withdrawDelay, EIP-712 domain info).\n   *\n   * @param paymentRequirements - Base payment requirements from the middleware.\n   * @param supportedKind - Matched scheme/network kind (extra may contain overrides).\n   * @param supportedKind.x402Version - Protocol version from the matched kind.\n   * @param supportedKind.scheme - Scheme name from the matched kind.\n   * @param supportedKind.network - Network identifier from the matched kind.\n   * @param supportedKind.extra - Optional extra fields on the matched kind.\n   * @param _extensionKeys - Extension keys (unused).\n   * @returns Enhanced payment requirements with batched fields in `extra`.\n   */\n  async enhancePaymentRequirements(\n    paymentRequirements: PaymentRequirements,\n    supportedKind: {\n      x402Version: number;\n      scheme: string;\n      network: Network;\n      extra?: Record<string, unknown>;\n    },\n    _extensionKeys: string[],\n  ): Promise<PaymentRequirements> {\n    void _extensionKeys;\n\n    const assetInfo = getDefaultAsset(paymentRequirements.network as Network);\n\n    const receiverAuthorizer =\n      this.receiverAuthorizerSigner?.address ??\n      (typeof supportedKind.extra?.receiverAuthorizer === \"string\"\n        ? supportedKind.extra.receiverAuthorizer\n        : undefined);\n\n    if (\n      !receiverAuthorizer ||\n      getAddress(receiverAuthorizer) === \"0x0000000000000000000000000000000000000000\"\n    ) {\n      throw new Error(\"Payment requirements must include a non-zero extra.receiverAuthorizer\");\n    }\n\n    return {\n      ...paymentRequirements,\n      extra: {\n        ...paymentRequirements.extra,\n        receiverAuthorizer: getAddress(receiverAuthorizer),\n        withdrawDelay: this.withdrawDelay,\n        name: assetInfo.name,\n        version: assetInfo.version,\n        assetTransferMethod:\n          paymentRequirements.extra?.assetTransferMethod ?? assetInfo.assetTransferMethod,\n      },\n    };\n  }\n\n  /**\n   * Fails server startup when this scheme delegates the receiver-authorizer role\n   * but the facilitator does not advertise a usable `receiverAuthorizer`.\n   *\n   * @param network - The network identifier being validated.\n   * @param supportedKind - The facilitator's advertised kind for this scheme/network.\n   * @param _ - Extensions advertised by the facilitator (unused).\n   * @returns A problem message when delegation is impossible, or void when valid.\n   */\n  validateFacilitatorSupport(\n    network: Network,\n    supportedKind: SupportedKind,\n    _: string[],\n  ): string | void {\n    if (this.receiverAuthorizerSigner) return;\n\n    const advertised = supportedKind.extra?.receiverAuthorizer;\n    const hasValid =\n      typeof advertised === \"string\" &&\n      getAddress(advertised) !== \"0x0000000000000000000000000000000000000000\";\n\n    if (!hasValid) {\n      return (\n        `no receiverAuthorizerSigner is configured and the facilitator does not advertise a ` +\n        `receiverAuthorizer on ${network}. Configure a receiverAuthorizerSigner or use a ` +\n        `facilitator that advertises one.`\n      );\n    }\n  }\n\n  /**\n   * Returns the underlying channel storage instance.\n   *\n   * @returns The configured {@link ChannelStorage} backend.\n   */\n  getStorage(): ChannelStorage {\n    return this.storage;\n  }\n\n  /**\n   * Returns the server's receiver address.\n   *\n   * @returns Receiver wallet address for the payment channel.\n   */\n  getReceiverAddress(): `0x${string}` {\n    return this.receiverAddress;\n  }\n\n  /**\n   * Returns the configured withdraw delay (seconds).\n   *\n   * @returns Withdraw delay in seconds before uncooperative withdrawal is allowed.\n   */\n  getWithdrawDelay(): number {\n    return this.withdrawDelay;\n  }\n\n  /**\n   * Returns how long mirrored onchain channel state is trusted for local voucher verification.\n   *\n   * @returns Freshness window in milliseconds.\n   */\n  getOnchainStateTtlMs(): number {\n    return this.onchainStateTtlMs;\n  }\n\n  /**\n   * Returns the receiver-authorizer signer, if configured.\n   *\n   * @returns Receiver-authorizer signer, or `undefined` when not set.\n   */\n  getReceiverAuthorizerSigner(): AuthorizerSigner | undefined {\n    return this.receiverAuthorizerSigner;\n  }\n\n  /**\n   * Creates a {@link BatchSettlementChannelManager} pre-configured with this scheme's\n   * receiver, default token for the given network, and the provided facilitator.\n   *\n   * @param facilitator - Facilitator client for submitting onchain claims/settlements.\n   * @param network - CAIP-2 network identifier (e.g. `\"eip155:84532\"`).\n   * @returns A ready-to-use channel manager.\n   */\n  createChannelManager(\n    facilitator: FacilitatorClient,\n    network: Network,\n  ): BatchSettlementChannelManager {\n    const token = getDefaultAsset(network).address as `0x${string}`;\n    return new BatchSettlementChannelManager({\n      scheme: this,\n      facilitator,\n      receiver: this.receiverAddress,\n      token,\n      network,\n    });\n  }\n\n  /**\n   * Parses a human-readable money string (e.g. `\"$1.50\"`) into a decimal number.\n   *\n   * @param money - Money string (may include `$`) or numeric amount.\n   * @returns Parsed finite number.\n   */\n  private parseMoneyToDecimal(money: string | number): number {\n    if (typeof money === \"number\") {\n      return money;\n    }\n\n    return parseMoneyString(money);\n  }\n\n  /**\n   * Converts a decimal dollar amount to the network's default token amount.\n   *\n   * @param amount - Decimal amount in display units.\n   * @param network - Target chain/network for default asset resolution.\n   * @returns {@link AssetAmount} with integer token amount, contract address, and metadata.\n   */\n  private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n    const assetInfo = getDefaultAsset(network);\n    const tokenAmount = convertToTokenAmount(numberToDecimalString(amount), assetInfo.decimals);\n\n    return {\n      amount: tokenAmount,\n      asset: assetInfo.address,\n      extra: {\n        name: assetInfo.name,\n        version: assetInfo.version,\n      },\n    };\n  }\n}\n\n/**\n * Derives a reasonable onchain state freshness window from the channel withdraw delay.\n *\n * @param withdrawDelaySeconds - Onchain withdraw delay for the channel, in seconds.\n * @returns TTL in milliseconds, clamped between 30 seconds and 5 minutes.\n */\nfunction defaultOnchainStateTtlMs(withdrawDelaySeconds: number): number {\n  const withdrawDelayMs = Math.max(0, withdrawDelaySeconds) * 1000;\n  return Math.min(5 * 60 * 1000, Math.max(30 * 1000, Math.floor(withdrawDelayMs / 3)));\n}\n","import type {\n  Network,\n  PaymentPayload,\n  PaymentRequirements,\n  SettleResponse,\n} from \"@x402/core/types\";\nimport type { FacilitatorClient } from \"@x402/core/server\";\nimport type { BatchSettlementVoucherClaim } from \"../types\";\nimport type { BatchSettlementEvmScheme } from \"./scheme\";\nimport { computeChannelId } from \"../utils\";\nimport { BATCH_SETTLEMENT_SCHEME } from \"../constants\";\nimport { signClaimBatch, signRefund } from \"../authorizerSigner\";\nimport type { Channel } from \"./storage\";\n\nexport interface ChannelManagerConfig {\n  scheme: BatchSettlementEvmScheme;\n  facilitator: FacilitatorClient;\n  receiver: `0x${string}`;\n  token: `0x${string}`;\n  network: Network;\n}\n\nexport type ClaimChannelSelector = (\n  channels: Channel[],\n  context: AutoSettlementContext,\n) => Channel[] | Promise<Channel[]>;\n\nexport interface ClaimOptions {\n  maxClaimsPerBatch?: number;\n  idleSecs?: number;\n  selectClaimChannels?: ClaimChannelSelector;\n}\n\nexport interface AutoSettlementConfig {\n  claimIntervalSecs?: number;\n  settleIntervalSecs?: number;\n  refundIntervalSecs?: number;\n  maxClaimsPerBatch?: number;\n  selectClaimChannels?: ClaimChannelSelector;\n  shouldSettle?: (context: AutoSettlementContext) => boolean | Promise<boolean>;\n  selectRefundChannels?: (\n    channels: Channel[],\n    context: AutoSettlementContext,\n  ) => Channel[] | Promise<Channel[]>;\n  onClaim?: (result: ClaimResult) => void;\n  onSettle?: (result: SettleResult) => void;\n  onRefund?: (result: RefundResult) => void;\n  onError?: (error: unknown) => void;\n}\n\nexport interface AutoSettlementContext {\n  now: number;\n  lastClaimTime: number;\n  lastSettleTime: number;\n  pendingSettle: boolean;\n}\n\nexport interface ClaimResult {\n  vouchers: number;\n  transaction: string;\n}\n\nexport interface SettleResult {\n  transaction: string;\n}\n\nexport interface RefundResult {\n  channel: string;\n  transaction: string;\n}\n\ntype AutoJob = \"claim\" | \"settle\" | \"refund\";\n\nconst AUTO_JOB_PRIORITY: AutoJob[] = [\"claim\", \"settle\", \"refund\"];\n\n/**\n * Formats a `Facilitator.settle()` failure into a human-readable error message.\n *\n * @param operation - Operation label (e.g. `\"Claim\"`, `\"Settle\"`, `\"Refund\"`).\n * @param response - The failed settle response.\n * @returns Error message including reason and (when available) facilitator-provided detail.\n */\nfunction formatFacilitatorFailure(operation: string, response: SettleResponse): string {\n  return `${operation} failed: ${response.errorReason ?? \"unknown\"} — ${response.errorMessage ?? \"\"}`;\n}\n\n/**\n * Checks whether a channel has a non-expired payer request reservation.\n *\n * @param channel - Channel state to inspect.\n * @param now - Current wall-clock time in milliseconds.\n * @returns Whether the channel is busy with a live pending request.\n */\nfunction hasLivePendingRequest(channel: Channel, now = Date.now()): boolean {\n  return channel.pendingRequest !== undefined && channel.pendingRequest.expiresAt > now;\n}\n\n/**\n * Manages the server-side channel lifecycle for the `batch-settlement` scheme:\n * batch claiming of vouchers, settlement of claimed funds, and cooperative refund.\n *\n * Provides one-shot operations (`claim()`, `settle()`, `claimAndSettle()`,\n * `refundIdleChannels()`) and an optional interval runner.\n */\nexport class BatchSettlementChannelManager {\n  private readonly scheme: BatchSettlementEvmScheme;\n  private readonly facilitator: FacilitatorClient;\n  private readonly receiver: `0x${string}`;\n  private readonly token: `0x${string}`;\n  private readonly network: Network;\n\n  private timers: Partial<Record<AutoJob, ReturnType<typeof setInterval>>> = {};\n  private lastClaimTime = 0;\n  private lastSettleTime = 0;\n  private pendingSettle = false;\n  private running = false;\n  private pendingJobs = new Set<AutoJob>();\n  private drainingJobs = false;\n  private autoSettleConfig: AutoSettlementConfig = {};\n\n  /**\n   * Creates a new channel manager.\n   *\n   * @param config - Manager configuration: scheme, facilitator, receiver, token, network.\n   */\n  constructor(config: ChannelManagerConfig) {\n    this.scheme = config.scheme;\n    this.facilitator = config.facilitator;\n    this.receiver = config.receiver;\n    this.token = config.token;\n    this.network = config.network;\n  }\n\n  /**\n   * Collects claimable vouchers and submits them in batches to the facilitator via `claim()`.\n   *\n   * @param opts - Optional claim execution and target selection options.\n   * @param opts.maxClaimsPerBatch - Max vouchers per facilitator `claim` batch.\n   * @param opts.idleSecs - When set, only include channels idle for at least this many seconds.\n   * @param opts.selectClaimChannels - Optional selector for choosing channels before claimability checks.\n   * @returns Array of claim results (one per batch).\n   */\n  async claim(opts?: ClaimOptions): Promise<ClaimResult[]> {\n    const channels = await this.selectClaimTargets(opts);\n    return this.claimFromChannels(channels, {\n      maxClaimsPerBatch: opts?.maxClaimsPerBatch ?? 100,\n      ...(opts?.idleSecs !== undefined ? { idleSecs: opts.idleSecs } : {}),\n    });\n  }\n\n  /**\n   * Transfers claimed (but unsettled) funds to the receiver by calling `settle(receiver, token)`.\n   *\n   * @returns Settle result with the transaction hash.\n   */\n  async settle(): Promise<SettleResult> {\n    const paymentPayload = this.buildSettlePaymentPayload();\n    const requirements = this.buildPaymentRequirements();\n\n    const response = await this.facilitator.settle(paymentPayload, requirements);\n    if (!response.success) {\n      throw new Error(formatFacilitatorFailure(\"Settle\", response));\n    }\n\n    this.pendingSettle = false;\n    return { transaction: response.transaction };\n  }\n\n  /**\n   * Convenience: claims all eligible vouchers then settles in one call.\n   *\n   * @param opts - Optional claim execution and target selection options.\n   * @param opts.maxClaimsPerBatch - Max vouchers per claim batch before settling.\n   * @param opts.idleSecs - When set, only include channels idle for at least this many seconds.\n   * @param opts.selectClaimChannels - Optional selector for choosing channels before claimability checks.\n   * @returns Combined claim and settle results.\n   */\n  async claimAndSettle(\n    opts?: ClaimOptions,\n  ): Promise<{ claims: ClaimResult[]; settle?: SettleResult }> {\n    const claims = await this.claim(opts);\n    let settleResult: SettleResult | undefined;\n    if (claims.length > 0) {\n      settleResult = await this.settle();\n    }\n    return { claims, settle: settleResult };\n  }\n\n  /**\n   * Initiates cooperative refunds for one or more channels.\n   *\n   * @param channelIds - Specific channels to refund; defaults to all sessions.\n   * @returns One result per successfully refunded channel.\n   */\n  async refund(channelIds?: string[]): Promise<RefundResult[]> {\n    const storage = this.scheme.getStorage();\n    const channels = await storage.list();\n\n    const now = Date.now();\n    const targets = (\n      channelIds\n        ? channels.filter(s =>\n            channelIds.some(id => id.toLowerCase() === s.channelId.toLowerCase()),\n          )\n        : channels\n    ).filter(channel => !hasLivePendingRequest(channel, now));\n\n    if (targets.length === 0) {\n      return [];\n    }\n\n    return this.refundChannels(targets);\n  }\n\n  /**\n   * Refunds idle channels with non-zero balances.\n   *\n   * @param opts - Idle refund options.\n   * @param opts.idleSecs - Minimum seconds since the last request.\n   * @returns One result per successfully refunded channel.\n   */\n  async refundIdleChannels(opts: { idleSecs: number }): Promise<RefundResult[]> {\n    const channels = await this.getIdleChannelsForRefund(opts.idleSecs);\n    return this.refundChannels(channels);\n  }\n\n  /**\n   * Collects vouchers that are eligible for onchain claiming.\n   *\n   * A voucher is claimable when its `chargedCumulativeAmount` exceeds what has already\n   * been claimed onchain.  An optional idle filter skips sessions that received a\n   * request within the last `idleSecs` seconds.\n   *\n   * @param opts - Optional filtering: `idleSecs` to only return idle channels.\n   * @param opts.idleSecs - Minimum seconds since last request for a channel to be included.\n   * @returns Array of {@link BatchSettlementVoucherClaim} entries for batch submission.\n   */\n  async getClaimableVouchers(opts?: { idleSecs?: number }): Promise<BatchSettlementVoucherClaim[]> {\n    const channels = await this.scheme.getStorage().list();\n    return this.getClaimableVouchersFromChannels(channels, opts);\n  }\n\n  /**\n   * Returns channels that have a pending payer-initiated withdrawal.\n   *\n   * @returns All stored channel records with `withdrawRequestedAt` set.\n   */\n  async getWithdrawalPendingSessions(): Promise<Channel[]> {\n    const channels = await this.scheme.getStorage().list();\n    return channels.filter(s => s.withdrawRequestedAt > 0);\n  }\n\n  /**\n   * Starts auto-settlement jobs for configured claim, settle, and refund intervals.\n   *\n   * @param config - Auto-settlement policy configuration.\n   */\n  start(config: AutoSettlementConfig = {}): void {\n    if (this.running) {\n      return;\n    }\n\n    const now = Date.now();\n    this.lastClaimTime = now;\n    this.lastSettleTime = now;\n    this.running = true;\n    this.autoSettleConfig = config;\n\n    this.startAutoTimer(\"claim\", config.claimIntervalSecs);\n    this.startAutoTimer(\"settle\", config.settleIntervalSecs);\n    this.startAutoTimer(\"refund\", config.refundIntervalSecs);\n  }\n\n  /**\n   * Stops the auto-settlement loop.\n   *\n   * @param opts - Stop options.\n   * @param opts.flush - When true, run `claimAndSettle` before stopping.\n   * @returns Resolves when the loop is stopped (and flush work completes, if requested).\n   */\n  async stop(opts?: { flush?: boolean }): Promise<void> {\n    this.running = false;\n    for (const timer of Object.values(this.timers)) {\n      clearInterval(timer);\n    }\n    this.timers = {};\n    this.pendingJobs.clear();\n\n    if (opts?.flush) {\n      await this.claimAndSettle({\n        maxClaimsPerBatch: this.autoSettleConfig.maxClaimsPerBatch,\n        selectClaimChannels: this.autoSettleConfig.selectClaimChannels,\n      });\n    }\n  }\n\n  /**\n   * Refunds a single channel and removes it from storage after success.\n   *\n   * @param target - Channel to refund.\n   * @returns Successful refund transaction.\n   */\n  private async refundChannel(target: Channel): Promise<RefundResult> {\n    const authorizerSigner = this.scheme.getReceiverAuthorizerSigner();\n    const claims = this.buildRefundClaims(target);\n\n    const refundAmount = (\n      BigInt(target.balance) - BigInt(target.chargedCumulativeAmount)\n    ).toString();\n\n    const nonce = String(target.refundNonce ?? 0);\n\n    const refundAuthorizerSignature = authorizerSigner\n      ? await signRefund(\n          authorizerSigner,\n          target.channelId as `0x${string}`,\n          refundAmount,\n          nonce,\n          this.network,\n        )\n      : undefined;\n\n    const claimAuthorizerSignature =\n      authorizerSigner && claims.length > 0\n        ? await signClaimBatch(authorizerSigner, claims, this.network)\n        : undefined;\n\n    const paymentPayload: PaymentPayload = {\n      x402Version: 2,\n      accepted: this.buildPaymentRequirements(),\n      payload: {\n        type: \"refund\",\n        channelConfig: target.channelConfig,\n        voucher: {\n          channelId: target.channelId as `0x${string}`,\n          maxClaimableAmount: target.signedMaxClaimable,\n          signature: target.signature as `0x${string}`,\n        },\n        amount: refundAmount,\n        refundNonce: nonce,\n        claims,\n        ...(refundAuthorizerSignature ? { refundAuthorizerSignature } : {}),\n        ...(claimAuthorizerSignature ? { claimAuthorizerSignature } : {}),\n      },\n    };\n\n    const response = await this.facilitator.settle(paymentPayload, this.buildPaymentRequirements());\n    if (!response.success) {\n      throw new Error(formatFacilitatorFailure(\"Refund\", response));\n    }\n\n    await this.scheme\n      .getStorage()\n      .updateChannel(target.channelId, current =>\n        current && !hasLivePendingRequest(current) ? undefined : current,\n      );\n\n    return {\n      channel: target.channelId,\n      transaction: response.transaction,\n    };\n  }\n\n  /**\n   * Starts a recurring timer for one auto job.\n   *\n   * @param job - Job to enqueue when the interval fires.\n   * @param intervalSecs - Timer interval in seconds.\n   */\n  private startAutoTimer(job: AutoJob, intervalSecs?: number): void {\n    if (intervalSecs === undefined) {\n      return;\n    }\n\n    this.timers[job] = setInterval(() => {\n      this.enqueueJob(job);\n    }, intervalSecs * 1000);\n  }\n\n  /**\n   * Adds an auto job to the coalescing queue.\n   *\n   * @param job - Job to run.\n   */\n  private enqueueJob(job: AutoJob): void {\n    if (!this.running) {\n      return;\n    }\n\n    this.pendingJobs.add(job);\n    if (!this.drainingJobs) {\n      void this.drainJobs();\n    }\n  }\n\n  /**\n   * Drains queued auto jobs in priority order.\n   */\n  private async drainJobs(): Promise<void> {\n    if (this.drainingJobs) {\n      return;\n    }\n\n    this.drainingJobs = true;\n    try {\n      while (this.running && this.pendingJobs.size > 0) {\n        const job = this.nextPendingJob();\n        if (!job) {\n          return;\n        }\n        this.pendingJobs.delete(job);\n        await this.runAutoJob(job);\n      }\n    } finally {\n      this.drainingJobs = false;\n    }\n  }\n\n  /**\n   * Returns the highest-priority queued auto job.\n   *\n   * @returns Next job to run.\n   */\n  private nextPendingJob(): AutoJob | undefined {\n    return AUTO_JOB_PRIORITY.find(job => this.pendingJobs.has(job));\n  }\n\n  /**\n   * Runs one auto job.\n   *\n   * @param job - Job to run.\n   */\n  private async runAutoJob(job: AutoJob): Promise<void> {\n    switch (job) {\n      case \"claim\":\n        await this.runClaimJob();\n        return;\n      case \"settle\":\n        await this.runSettleJob();\n        return;\n      case \"refund\":\n        await this.runRefundJob();\n        return;\n    }\n  }\n\n  /**\n   * Runs the claim auto job.\n   */\n  private async runClaimJob(): Promise<void> {\n    const cfg = this.autoSettleConfig;\n    try {\n      const targets = await this.selectClaimTargets({\n        selectClaimChannels: cfg.selectClaimChannels,\n      });\n      const results = await this.claimFromChannels(targets, {\n        maxClaimsPerBatch: cfg.maxClaimsPerBatch ?? 100,\n      });\n\n      this.lastClaimTime = Date.now();\n      for (const result of results) {\n        cfg.onClaim?.(result);\n      }\n    } catch (err) {\n      cfg.onError?.(err);\n    }\n  }\n\n  /**\n   * Runs the settlement auto job.\n   */\n  private async runSettleJob(): Promise<void> {\n    const cfg = this.autoSettleConfig;\n    const context = this.buildAutoSettlementContext(Date.now());\n    if (!context.pendingSettle) {\n      return;\n    }\n\n    try {\n      if (cfg.shouldSettle && !(await cfg.shouldSettle(context))) {\n        return;\n      }\n\n      const result = await this.settle();\n      this.lastSettleTime = Date.now();\n      cfg.onSettle?.(result);\n    } catch (err) {\n      cfg.onError?.(err);\n    }\n  }\n\n  /**\n   * Runs the refund auto job.\n   */\n  private async runRefundJob(): Promise<void> {\n    const cfg = this.autoSettleConfig;\n    if (!cfg.selectRefundChannels) {\n      return;\n    }\n\n    try {\n      const context = this.buildAutoSettlementContext(Date.now());\n      const channels = await this.scheme.getStorage().list();\n      const targets = await cfg.selectRefundChannels(channels, context);\n      for (const result of await this.refundChannels(targets)) {\n        cfg.onRefund?.(result);\n      }\n    } catch (err) {\n      cfg.onError?.(err);\n    }\n  }\n\n  /**\n   * Claims vouchers from a provided channel snapshot.\n   *\n   * @param channels - Channels to inspect for claimable vouchers.\n   * @param opts - Claim batching and filtering options.\n   * @param opts.maxClaimsPerBatch - Max vouchers per facilitator claim transaction.\n   * @param opts.idleSecs - Optional idle filter.\n   * @returns Claim results, one per submitted batch.\n   */\n  private async claimFromChannels(\n    channels: Channel[],\n    opts: {\n      maxClaimsPerBatch: number;\n      idleSecs?: number;\n    },\n  ): Promise<ClaimResult[]> {\n    const allClaims = this.getClaimableVouchersFromChannels(\n      channels,\n      opts.idleSecs !== undefined ? { idleSecs: opts.idleSecs } : undefined,\n    );\n\n    if (allClaims.length === 0) {\n      return [];\n    }\n\n    const results: ClaimResult[] = [];\n    for (let i = 0; i < allClaims.length; i += opts.maxClaimsPerBatch) {\n      const batch = allClaims.slice(i, i + opts.maxClaimsPerBatch);\n      const result = await this.submitClaim(batch);\n      results.push(result);\n      await this.updateClaimedSessions(batch);\n    }\n\n    if (results.length > 0) {\n      this.pendingSettle = true;\n    }\n\n    return results;\n  }\n\n  /**\n   * Loads stored channels and applies the configured claim selector, if any.\n   *\n   * @param opts - Claim options containing an optional target selector.\n   * @returns The channel snapshot that should be inspected for claimable vouchers.\n   */\n  private async selectClaimTargets(\n    opts?: Pick<ClaimOptions, \"selectClaimChannels\">,\n  ): Promise<Channel[]> {\n    const channels = await this.scheme.getStorage().list();\n    if (!opts?.selectClaimChannels) {\n      return channels;\n    }\n\n    const context = this.buildAutoSettlementContext(Date.now());\n    return opts.selectClaimChannels(channels, context);\n  }\n\n  /**\n   * Refunds each eligible channel independently.\n   *\n   * @param channels - Channels to refund.\n   * @returns Successful refund results.\n   */\n  private async refundChannels(channels: Channel[]): Promise<RefundResult[]> {\n    const results: RefundResult[] = [];\n    for (const channel of channels) {\n      if (hasLivePendingRequest(channel)) {\n        continue;\n      }\n      results.push(await this.refundChannel(channel));\n    }\n    return results;\n  }\n\n  /**\n   * Builds an outstanding voucher claim for a refund payload.\n   *\n   * @param channel - Channel being refunded.\n   * @returns Claim payloads needed before refunding unclaimed balance.\n   */\n  private buildRefundClaims(channel: Channel): BatchSettlementVoucherClaim[] {\n    if (BigInt(channel.chargedCumulativeAmount) <= BigInt(channel.totalClaimed)) {\n      return [];\n    }\n\n    return [\n      {\n        voucher: {\n          channel: channel.channelConfig,\n          maxClaimableAmount: channel.signedMaxClaimable,\n        },\n        signature: channel.signature as `0x${string}`,\n        totalClaimed: channel.chargedCumulativeAmount,\n      },\n    ];\n  }\n\n  /**\n   * Builds the policy context passed to interval hooks.\n   *\n   * @param now - Current wall-clock time in milliseconds.\n   * @returns Auto-settlement policy context.\n   */\n  private buildAutoSettlementContext(now: number): AutoSettlementContext {\n    return {\n      now,\n      lastClaimTime: this.lastClaimTime,\n      lastSettleTime: this.lastSettleTime,\n      pendingSettle: this.pendingSettle,\n    };\n  }\n\n  /**\n   * Collects claimable vouchers from a provided channel snapshot.\n   *\n   * @param channels - Channels to inspect.\n   * @param opts - Optional idle filter.\n   * @param opts.idleSecs - Minimum seconds since last request.\n   * @returns Claimable voucher payloads.\n   */\n  private getClaimableVouchersFromChannels(\n    channels: Channel[],\n    opts?: { idleSecs?: number },\n  ): BatchSettlementVoucherClaim[] {\n    const now = Date.now();\n    const claims: BatchSettlementVoucherClaim[] = [];\n\n    for (const c of channels) {\n      if (BigInt(c.chargedCumulativeAmount) <= BigInt(c.totalClaimed)) {\n        continue;\n      }\n      if (opts?.idleSecs !== undefined) {\n        const idleMs = now - c.lastRequestTimestamp;\n        if (idleMs < opts.idleSecs * 1000) {\n          continue;\n        }\n      }\n      claims.push({\n        voucher: {\n          channel: c.channelConfig,\n          maxClaimableAmount: c.signedMaxClaimable,\n        },\n        signature: c.signature as `0x${string}`,\n        totalClaimed: c.chargedCumulativeAmount,\n      });\n    }\n\n    return claims;\n  }\n\n  /**\n   * Filters idle channels that can be cooperatively refunded.\n   *\n   * @param channels - Channels to inspect.\n   * @param idleSecs - Minimum seconds since the last request.\n   * @returns Idle refundable channels.\n   */\n  private getIdleChannelsForRefundFromChannels(channels: Channel[], idleSecs: number): Channel[] {\n    const now = Date.now();\n    const idleMs = idleSecs * 1000;\n    return channels.filter(c => {\n      if (BigInt(c.balance) === 0n) return false;\n      if (hasLivePendingRequest(c, now)) return false;\n      return now - c.lastRequestTimestamp >= idleMs;\n    });\n  }\n\n  /**\n   * Returns channels that have been idle longer than `idleSecs` and still have\n   * a non-zero balance (candidates for cooperative refund).\n   *\n   * @param idleSecs - Minimum seconds since last request for a session to count as idle.\n   * @returns Channels meeting the idle and balance criteria.\n   */\n  private async getIdleChannelsForRefund(idleSecs: number): Promise<Channel[]> {\n    const channels = await this.scheme.getStorage().list();\n    return this.getIdleChannelsForRefundFromChannels(channels, idleSecs);\n  }\n\n  /**\n   * Submits a batch of voucher claims to the facilitator.\n   *\n   * @param claims - Voucher claims to send in one `type: \"claim\"` payload.\n   * @returns Per-batch claim summary (count and transaction hash).\n   */\n  private async submitClaim(claims: BatchSettlementVoucherClaim[]): Promise<ClaimResult> {\n    const authorizerSigner = this.scheme.getReceiverAuthorizerSigner();\n\n    const claimAuthorizerSignature = authorizerSigner\n      ? await signClaimBatch(authorizerSigner, claims, this.network)\n      : undefined;\n\n    const paymentPayload: PaymentPayload = {\n      x402Version: 2,\n      accepted: this.buildPaymentRequirements(),\n      payload: {\n        type: \"claim\",\n        claims,\n        ...(claimAuthorizerSignature ? { claimAuthorizerSignature } : {}),\n      },\n    };\n\n    const response: SettleResponse = await this.facilitator.settle(\n      paymentPayload,\n      this.buildPaymentRequirements(),\n    );\n\n    if (!response.success) {\n      throw new Error(formatFacilitatorFailure(\"Claim\", response));\n    }\n\n    return { vouchers: claims.length, transaction: response.transaction };\n  }\n\n  /**\n   * Builds a settlement payment payload for `settle(receiver, token)`.\n   *\n   * @returns Payload with `type: \"settle\"` and receiver/token fields.\n   */\n  private buildSettlePaymentPayload(): PaymentPayload {\n    return {\n      x402Version: 2,\n      accepted: this.buildPaymentRequirements(),\n      payload: {\n        type: \"settle\",\n        receiver: this.receiver,\n        token: this.token,\n      },\n    };\n  }\n\n  /**\n   * Builds a minimal {@link PaymentRequirements} for channel manager operations.\n   *\n   * @returns Requirements describing batched operations for this manager.\n   */\n  private buildPaymentRequirements(): PaymentRequirements {\n    return {\n      scheme: BATCH_SETTLEMENT_SCHEME,\n      network: this.network,\n      asset: this.token,\n      amount: \"0\",\n      payTo: this.receiver,\n      maxTimeoutSeconds: 0,\n      extra: {},\n    };\n  }\n\n  /**\n   * Updates session records after a successful claim submission so that\n   * `getClaimableVouchers` no longer returns already-claimed vouchers.\n   *\n   * @param claims - Voucher claims that were included in the submitted settlement transaction.\n   */\n  private async updateClaimedSessions(claims: BatchSettlementVoucherClaim[]): Promise<void> {\n    const storage = this.scheme.getStorage();\n    for (const claim of claims) {\n      const channelId = computeChannelId(claim.voucher.channel, this.network);\n      const channel = await storage.get(channelId);\n      if (!channel) {\n        continue;\n      }\n      const claimedAmount = BigInt(claim.totalClaimed);\n      if (claimedAmount <= BigInt(channel.totalClaimed)) {\n        continue;\n      }\n      await storage.updateChannel(channelId, current => {\n        if (!current || claimedAmount <= BigInt(current.totalClaimed)) {\n          return current;\n        }\n        return {\n          ...current,\n          totalClaimed: claimedAmount.toString(),\n        };\n      });\n    }\n  }\n}\n","import type { ChannelConfig } from \"../types\";\n\nexport interface Channel {\n  channelId: string;\n  channelConfig: ChannelConfig;\n  chargedCumulativeAmount: string;\n  signedMaxClaimable: string;\n  signature: string;\n  balance: string;\n  totalClaimed: string;\n  withdrawRequestedAt: number;\n  refundNonce: number;\n  onchainSyncedAt?: number;\n  lastRequestTimestamp: number;\n  pendingRequest?: PendingRequest;\n}\n\nexport interface PendingRequest {\n  pendingId: string;\n  signedMaxClaimable: string;\n  expiresAt: number;\n}\n\nexport interface ChannelUpdateResult {\n  channel: Channel | undefined;\n  status: \"updated\" | \"unchanged\" | \"deleted\";\n}\n\nexport interface ChannelStorage {\n  get(channelId: string): Promise<Channel | undefined>;\n  list(): Promise<Channel[]>;\n  /**\n   * Atomically inspects and mutates a channel record.\n   *\n   * Implementations must guarantee that no concurrent mutation can interleave between\n   * reading `current` and writing the callback result for all application instances that\n   * share the backend. The in-memory backend only provides this guarantee inside one JS\n   * runtime; production multi-instance deployments need storage with backend-level atomic\n   * conditional mutation, such as Redis/Valkey Lua scripts, SQL transactions, or Durable Objects.\n   *\n   * @param channelId - The channel identifier.\n   * @param update - Mutation callback. Return `undefined` to delete, or `current` to leave unchanged.\n   * @returns The final stored channel and whether storage updated, stayed unchanged, or deleted.\n   */\n  updateChannel(\n    channelId: string,\n    update: (current: Channel | undefined) => Channel | undefined,\n  ): Promise<ChannelUpdateResult>;\n}\n\n/**\n * In-memory {@link ChannelStorage} backed by a Map keyed by `channelId`.\n */\nexport class InMemoryChannelStorage implements ChannelStorage {\n  private readonly channels = new Map<string, Channel>();\n  private readonly channelLocks = new Map<string, Promise<void>>();\n\n  /**\n   * Returns the channel record for a channel, if present.\n   *\n   * @param channelId - The channel identifier.\n   * @returns The channel record or undefined when not found.\n   */\n  async get(channelId: string): Promise<Channel | undefined> {\n    return this.channels.get(channelId.toLowerCase());\n  }\n\n  /**\n   * Lists all stored channel records.\n   *\n   * @returns All channel records in storage.\n   */\n  async list(): Promise<Channel[]> {\n    return [...this.channels.values()];\n  }\n\n  /**\n   * Atomically inspects and mutates a channel record while holding a per-channel lock.\n   *\n   * @param channelId - The channel identifier.\n   * @param update - Mutation callback. Return `undefined` to delete, or `current` to leave unchanged.\n   * @returns The final stored channel and whether storage updated, stayed unchanged, or deleted.\n   */\n  async updateChannel(\n    channelId: string,\n    update: (current: Channel | undefined) => Channel | undefined,\n  ): Promise<ChannelUpdateResult> {\n    const key = channelId.toLowerCase();\n    return this.withChannelLock(key, async () => {\n      const current = this.channels.get(key);\n      const next = update(current);\n\n      if (next === current) {\n        return { channel: current, status: \"unchanged\" };\n      }\n\n      if (!next) {\n        this.channels.delete(key);\n        return { channel: undefined, status: current ? \"deleted\" : \"unchanged\" };\n      }\n\n      this.channels.set(key, next);\n      return { channel: next, status: \"updated\" };\n    });\n  }\n\n  /**\n   * Runs `fn` after any prior locked work for the same channel key has finished.\n   *\n   * @param key - Lowercased channel id used as the lock key.\n   * @param fn - Async work to run while holding the logical per-channel lock.\n   * @returns The resolved result of `fn`.\n   */\n  private async withChannelLock<T>(key: string, fn: () => Promise<T>): Promise<T> {\n    const previous = this.channelLocks.get(key) ?? Promise.resolve();\n    let release!: () => void;\n    const current = new Promise<void>(resolve => {\n      release = resolve;\n    });\n    const next = previous.catch(() => {}).then(() => current);\n    this.channelLocks.set(key, next);\n\n    await previous.catch(() => {});\n    try {\n      return await fn();\n    } finally {\n      release();\n      if (this.channelLocks.get(key) === next) {\n        this.channelLocks.delete(key);\n      }\n    }\n  }\n}\n","import type {\n  VerifiedPaymentCanceledContext,\n  VerifyContext,\n  VerifyFailureContext,\n  VerifyResultContext,\n} from \"@x402/core/server\";\nimport type { VerifyResponse } from \"@x402/core/types\";\nimport type { SchemePaymentRequiredContext } from \"@x402/core/types\";\nimport { getAddress, verifyTypedData } from \"viem\";\nimport {\n  type BatchSettlementDepositPayload,\n  type BatchSettlementRefundPayload,\n  type BatchSettlementVoucherPayload,\n  isBatchSettlementDepositPayload,\n  isBatchSettlementRefundPayload,\n  isBatchSettlementVoucherPayload,\n} from \"../types\";\nimport { BATCH_SETTLEMENT_SCHEME, voucherTypes } from \"../constants\";\nimport type { ChannelConfig } from \"../types\";\nimport { createNonce, getEvmChainId } from \"../../utils\";\nimport { computeChannelId, getBatchSettlementEip712Domain } from \"../utils\";\nimport { validateChannelConfig } from \"../facilitator/utils\";\nimport * as Errors from \"../errors\";\nimport type { BatchSettlementEvmScheme } from \"./scheme\";\nimport type { Channel, PendingRequest } from \"./storage\";\nimport { readExtraNumber, readExtraString } from \"./utils\";\n\n// Framework cleanup hooks clear pending reservations for normal failures\n// This bounded TTL releases channels when cleanup cannot run or complete\nconst MIN_PENDING_TTL_MS = 5_000; // 5 seconds\nconst MAX_PENDING_TTL_MS = 10 * 60 * 1000; // 600 seconds\n\n/**\n * Computes the bounded pending reservation expiry time.\n *\n * @param maxTimeoutSeconds - Resource timeout from payment requirements.\n * @param now - Current wall-clock time in milliseconds.\n * @returns Expiry timestamp in milliseconds.\n */\nfunction pendingExpiresAt(maxTimeoutSeconds: number | undefined, now: number): number {\n  const requestedMs = Math.max(0, maxTimeoutSeconds ?? 0) * 1000;\n  const ttlMs = Math.min(MAX_PENDING_TTL_MS, Math.max(MIN_PENDING_TTL_MS, requestedMs));\n  return now + ttlMs;\n}\n\n/**\n * Checks whether a pending reservation still blocks same-channel work.\n *\n * @param pending - Pending reservation to inspect.\n * @param now - Current wall-clock time in milliseconds.\n * @returns Whether the reservation exists and has not expired.\n */\nfunction isPendingLive(pending: PendingRequest | undefined, now: number): boolean {\n  return pending !== undefined && pending.expiresAt > now;\n}\n\n/**\n * Lifecycle hook: runs before the facilitator verifies a payment.\n *\n * For paid payloads, checks whether the client's cumulative amount matches server\n * state. If mismatched, aborts with `invalid_batch_settlement_evm_cumulative_amount_mismatch`.\n *\n * Refund vouchers are zero-charge: the expected `maxClaimableAmount` equals\n * the existing `chargedCumulativeAmount`.\n *\n * When no local channel record exists, verification is delegated to the facilitator (which checks onchain state);\n * `handleAfterVerify` then rebuilds the channel record from the verify response.\n *\n * @param scheme - Owning `BatchSettlementEvmScheme` instance for storage access.\n * @param ctx - Verify lifecycle context (payload, requirements, and related state).\n * @returns Nothing to continue verification; or an object with `abort` to fail with a reason.\n */\nexport async function handleBeforeVerify(\n  scheme: BatchSettlementEvmScheme,\n  ctx: VerifyContext,\n): Promise<\n  void | { abort: true; reason: string; message?: string } | { skip: true; result: VerifyResponse }\n> {\n  const { paymentPayload, requirements } = ctx;\n\n  const raw = paymentPayload.payload;\n  const isPaidPayload =\n    isBatchSettlementVoucherPayload(raw) || isBatchSettlementDepositPayload(raw);\n  const isZeroChargePayload = isBatchSettlementRefundPayload(raw);\n  if (!isPaidPayload && !isZeroChargePayload) {\n    return;\n  }\n\n  const channelId = raw.voucher.channelId;\n  const now = Date.now();\n  const pendingId = createNonce();\n  let outcome:\n    | { status: \"reserved\"; channelSnapshot?: Channel }\n    | { status: \"busy\" }\n    | { status: \"mismatch\"; channel: Channel }\n    | undefined;\n\n  await scheme.getStorage().updateChannel(channelId, current => {\n    if (isPendingLive(current?.pendingRequest, now)) {\n      outcome = { status: \"busy\" };\n      return current;\n    }\n\n    const chargedCumulativeAmount =\n      current?.chargedCumulativeAmount ??\n      inferMissingLocalChargedAmount(\n        raw.voucher.maxClaimableAmount,\n        requirements.amount,\n        isPaidPayload,\n      );\n    const expectedMaxClaimable = isZeroChargePayload\n      ? BigInt(chargedCumulativeAmount)\n      : BigInt(chargedCumulativeAmount) + BigInt(requirements.amount);\n\n    if (BigInt(raw.voucher.maxClaimableAmount) !== expectedMaxClaimable) {\n      if (current) {\n        outcome = { status: \"mismatch\", channel: current };\n      } else {\n        outcome = {\n          status: \"mismatch\",\n          channel: buildProvisionalChannel(raw, chargedCumulativeAmount),\n        };\n      }\n      return current;\n    }\n\n    const pendingRequest: PendingRequest = {\n      pendingId,\n      signedMaxClaimable: raw.voucher.maxClaimableAmount,\n      expiresAt: pendingExpiresAt(requirements.maxTimeoutSeconds, now),\n    };\n\n    outcome = { status: \"reserved\", channelSnapshot: current };\n    return {\n      ...(current ?? buildProvisionalChannel(raw, chargedCumulativeAmount)),\n      pendingRequest,\n      lastRequestTimestamp: now,\n    };\n  });\n\n  if (outcome?.status === \"busy\") {\n    return {\n      abort: true,\n      reason: Errors.ErrChannelBusy,\n      message: \"Channel is already processing a request\",\n    };\n  }\n\n  if (outcome?.status === \"mismatch\") {\n    scheme.rememberChannelSnapshot(paymentPayload, outcome.channel);\n    return {\n      abort: true,\n      reason: Errors.ErrCumulativeAmountMismatch,\n      message: \"Client voucher base does not match server state\",\n    };\n  }\n\n  if (outcome?.status === \"reserved\") {\n    scheme.mergeRequestContext(paymentPayload, {\n      channelId,\n      pendingId,\n      channelSnapshot: outcome.channelSnapshot,\n    });\n\n    if (isBatchSettlementVoucherPayload(raw)) {\n      const localResult = await verifyVoucherLocally(\n        scheme,\n        raw,\n        requirements,\n        outcome.channelSnapshot,\n        now,\n      );\n      if (localResult) {\n        scheme.mergeRequestContext(paymentPayload, { localVerify: true });\n        return { skip: true, result: localResult };\n      }\n    }\n  }\n}\n\n/**\n * Adds server channel state to corrective 402 responses for cumulative mismatches.\n *\n * @param scheme - Owning `BatchSettlementEvmScheme` instance for storage access.\n * @param ctx - Payment-required response context.\n */\nexport async function handleEnrichPaymentRequiredResponse(\n  scheme: BatchSettlementEvmScheme,\n  ctx: SchemePaymentRequiredContext,\n): Promise<void> {\n  if (ctx.error !== Errors.ErrCumulativeAmountMismatch) {\n    return;\n  }\n\n  const { paymentPayload } = ctx;\n  if (!paymentPayload) {\n    return;\n  }\n\n  const raw = paymentPayload.payload;\n  if (\n    !isBatchSettlementVoucherPayload(raw) &&\n    !isBatchSettlementDepositPayload(raw) &&\n    !isBatchSettlementRefundPayload(raw)\n  ) {\n    return;\n  }\n\n  const channel =\n    scheme.takeChannelSnapshot(paymentPayload) ??\n    (await scheme.getStorage().get(raw.voucher.channelId));\n  if (!channel) {\n    return;\n  }\n\n  const accept = ctx.requirements.find(\n    req =>\n      req.scheme === BATCH_SETTLEMENT_SCHEME && req.network === paymentPayload.accepted.network,\n  );\n  if (!accept) {\n    return;\n  }\n\n  accept.extra = {\n    ...accept.extra,\n    channelState: {\n      channelId: channel.channelId,\n      balance: channel.balance,\n      totalClaimed: channel.totalClaimed,\n      withdrawRequestedAt: channel.withdrawRequestedAt,\n      refundNonce: String(channel.refundNonce),\n      chargedCumulativeAmount: channel.chargedCumulativeAmount,\n    },\n    voucherState: {\n      signedMaxClaimable: channel.signedMaxClaimable,\n      signature: channel.signature as `0x${string}`,\n    },\n  };\n}\n\n/**\n * Lifecycle hook: runs after the facilitator verifies a payment.\n *\n * Persists channel state (balance, totalClaimed, voucher info) so that\n * subsequent requests can correctly calculate cumulative amounts and detect stale state.\n *\n * For refund payloads, additionally returns a `skipHandler` directive so that\n * the resource server bypasses the application handler and settles inline.\n *\n * @param scheme - Owning `BatchSettlementEvmScheme` instance for storage access.\n * @param ctx - Post-verify lifecycle context.\n * @param ctx.paymentPayload - Incoming payment payload that was verified.\n * @param ctx.requirements - Requirements used for verification.\n * @param ctx.result - Facilitator verify response.\n * @returns Optional `skipHandler` directive when this is a refund voucher; otherwise void.\n */\nexport async function handleAfterVerify(\n  scheme: BatchSettlementEvmScheme,\n  ctx: VerifyResultContext,\n): Promise<void | { skipHandler: true; response?: { contentType?: string; body?: unknown } }> {\n  const { paymentPayload, result } = ctx;\n  if (!result.isValid || !result.payer) {\n    await scheme.clearPendingRequest(paymentPayload);\n    return;\n  }\n\n  const raw = paymentPayload.payload;\n  let channelId: string;\n  let signedMaxClaimable: string;\n  let signature: `0x${string}`;\n  let channelConfig: ChannelConfig;\n  let isRefundVoucher = false;\n\n  if (isBatchSettlementDepositPayload(raw)) {\n    channelId = raw.voucher.channelId;\n    signedMaxClaimable = raw.voucher.maxClaimableAmount;\n    signature = raw.voucher.signature;\n    channelConfig = raw.channelConfig;\n  } else if (isBatchSettlementVoucherPayload(raw)) {\n    channelId = raw.voucher.channelId;\n    signedMaxClaimable = raw.voucher.maxClaimableAmount;\n    signature = raw.voucher.signature;\n    channelConfig = raw.channelConfig;\n  } else if (isBatchSettlementRefundPayload(raw)) {\n    channelId = raw.voucher.channelId;\n    signedMaxClaimable = raw.voucher.maxClaimableAmount;\n    signature = raw.voucher.signature;\n    channelConfig = raw.channelConfig;\n    isRefundVoucher = true;\n  } else {\n    return;\n  }\n\n  const ex = result.extra ?? {};\n  const balance = readExtraString(ex, \"balance\", \"0\");\n  const totalClaimed = readExtraString(ex, \"totalClaimed\", \"0\");\n  const withdrawRequestedAt = readExtraNumber(ex, \"withdrawRequestedAt\", 0);\n  const refundNonce = readExtraNumber(ex, \"refundNonce\", 0);\n  const now = Date.now();\n\n  const storage = scheme.getStorage();\n  const requestContext = scheme.readRequestContext(paymentPayload);\n  if (!requestContext?.pendingId) {\n    return;\n  }\n  if (requestContext.localVerify && isBatchSettlementVoucherPayload(raw)) {\n    return;\n  }\n\n  const updateResult = await storage.updateChannel(channelId, current => {\n    if (!current || current.pendingRequest?.pendingId !== requestContext.pendingId) {\n      return current;\n    }\n\n    const channel: Channel = {\n      channelId,\n      channelConfig,\n      chargedCumulativeAmount: current.chargedCumulativeAmount,\n      signedMaxClaimable,\n      signature,\n      balance,\n      totalClaimed,\n      withdrawRequestedAt,\n      refundNonce,\n      onchainSyncedAt: requestContext.localVerify ? current.onchainSyncedAt : now,\n      lastRequestTimestamp: now,\n      pendingRequest: current.pendingRequest,\n    };\n    return channel;\n  });\n  if (updateResult.status === \"updated\" && updateResult.channel) {\n    scheme.rememberChannelSnapshot(paymentPayload, updateResult.channel);\n  }\n\n  if (isRefundVoucher && updateResult.status === \"updated\") {\n    return {\n      skipHandler: true,\n      response: {\n        contentType: \"application/json\",\n        body: { message: \"Refund acknowledged\", channelId },\n      },\n    };\n  }\n}\n\n/**\n * Cleanup hook: clears this request's reservation after verify throws.\n *\n * @param scheme - Owning `BatchSettlementEvmScheme` instance.\n * @param ctx - Verify failure context for the current payment.\n */\nexport async function handleVerifyFailure(\n  scheme: BatchSettlementEvmScheme,\n  ctx: VerifyFailureContext,\n): Promise<void> {\n  await scheme.clearPendingRequest(ctx.paymentPayload);\n}\n\n/**\n * Cleanup hook: clears this request's reservation when handler work is canceled.\n *\n * @param scheme - Owning `BatchSettlementEvmScheme` instance.\n * @param ctx - Verified-payment cancellation context.\n */\nexport async function handleVerifiedPaymentCanceled(\n  scheme: BatchSettlementEvmScheme,\n  ctx: VerifiedPaymentCanceledContext,\n): Promise<void> {\n  if (ctx.reason !== \"handler_threw\" && ctx.reason !== \"handler_failed\") {\n    return;\n  }\n  await scheme.clearPendingRequest(ctx.paymentPayload);\n}\n\n/**\n * Verifies a voucher against locally cached channel state when that state is fresh.\n *\n * @param scheme - Batch settlement scheme (TTL for onchain sync freshness).\n * @param raw - Decoded batch-settlement voucher payload.\n * @param requirements - Payment requirements (network, etc.).\n * @param channel - Cached channel row, if any.\n * @param now - Current wall-clock time in milliseconds.\n * @returns A {@link VerifyResponse}, or `undefined` to fall back to facilitator verification.\n */\nasync function verifyVoucherLocally(\n  scheme: BatchSettlementEvmScheme,\n  raw: BatchSettlementVoucherPayload,\n  requirements: VerifyContext[\"requirements\"],\n  channel: Channel | undefined,\n  now: number,\n): Promise<VerifyResponse | undefined> {\n  if (!channel || !isOnchainStateFresh(channel, scheme.getOnchainStateTtlMs(), now)) {\n    return;\n  }\n\n  if (raw.channelConfig.payerAuthorizer === \"0x0000000000000000000000000000000000000000\") {\n    return;\n  }\n\n  const payer = raw.channelConfig.payer;\n  const configErr = validateChannelConfig(\n    raw.channelConfig,\n    raw.voucher.channelId,\n    requirements as Parameters<typeof validateChannelConfig>[2],\n  );\n  if (configErr) {\n    return invalidVerifyResponse(payer, configErr);\n  }\n\n  if (\n    computeChannelId(raw.channelConfig, requirements.network).toLowerCase() !==\n    channel.channelId.toLowerCase()\n  ) {\n    return invalidVerifyResponse(payer, Errors.ErrChannelIdMismatch);\n  }\n\n  const signatureOk = await verifyLocalVoucherSignature(raw, requirements.network);\n  if (!signatureOk) {\n    return invalidVerifyResponse(payer, Errors.ErrInvalidVoucherSignature);\n  }\n\n  const maxClaimableAmount = BigInt(raw.voucher.maxClaimableAmount);\n  if (maxClaimableAmount > BigInt(channel.balance)) {\n    return invalidVerifyResponse(payer, Errors.ErrCumulativeExceedsBalance);\n  }\n\n  if (maxClaimableAmount <= BigInt(channel.totalClaimed)) {\n    return invalidVerifyResponse(payer, Errors.ErrCumulativeAmountBelowClaimed);\n  }\n\n  return {\n    isValid: true,\n    payer,\n    extra: {\n      channelId: raw.voucher.channelId,\n      balance: channel.balance,\n      totalClaimed: channel.totalClaimed,\n      withdrawRequestedAt: channel.withdrawRequestedAt,\n      refundNonce: channel.refundNonce.toString(),\n    },\n  };\n}\n\n/**\n * Returns whether cached onchain fields for a channel are still within the freshness window.\n *\n * @param channel - Cached channel row.\n * @param ttlMs - Maximum age of `onchainSyncedAt` in milliseconds.\n * @param now - Current wall-clock time in milliseconds.\n * @returns `true` if onchain sync time is present and still within `ttlMs` of `now`.\n */\nfunction isOnchainStateFresh(channel: Channel, ttlMs: number, now: number): boolean {\n  return channel.onchainSyncedAt !== undefined && now - channel.onchainSyncedAt <= ttlMs;\n}\n\n/**\n * Verifies the EIP-712 voucher signature against the payer authorizer.\n *\n * @param raw - Decoded batch-settlement voucher payload.\n * @param network - EVM network identifier for chain ID / domain.\n * @returns Whether the typed-data signature is valid.\n */\nasync function verifyLocalVoucherSignature(\n  raw: BatchSettlementVoucherPayload,\n  network: string,\n): Promise<boolean> {\n  try {\n    return await verifyTypedData({\n      address: getAddress(raw.channelConfig.payerAuthorizer),\n      domain: getBatchSettlementEip712Domain(getEvmChainId(network)),\n      types: voucherTypes,\n      primaryType: \"Voucher\",\n      message: {\n        channelId: raw.voucher.channelId,\n        maxClaimableAmount: BigInt(raw.voucher.maxClaimableAmount),\n      },\n      signature: raw.voucher.signature,\n    });\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Builds a failed verify response with the payer address preserved for reporting.\n *\n * @param payer - Payer address from the payload.\n * @param invalidReason - Machine-readable failure reason.\n * @returns Invalid {@link VerifyResponse} with `isValid: false`.\n */\nfunction invalidVerifyResponse(payer: `0x${string}`, invalidReason: string): VerifyResponse {\n  return { isValid: false, invalidReason, payer };\n}\n\n/**\n * Builds the minimal local channel record needed to reserve missing state.\n *\n * @param raw - Batch-settlement payload containing channel config and voucher.\n * @param chargedCumulativeAmount - Local charged base inferred before facilitator verification.\n * @returns Provisional channel state.\n */\nfunction buildProvisionalChannel(\n  raw: BatchSettlementVoucherPayload | BatchSettlementDepositPayload | BatchSettlementRefundPayload,\n  chargedCumulativeAmount: string,\n): Channel {\n  return {\n    channelId: raw.voucher.channelId,\n    channelConfig: raw.channelConfig,\n    chargedCumulativeAmount,\n    signedMaxClaimable: raw.voucher.maxClaimableAmount,\n    signature: raw.voucher.signature,\n    balance: \"0\",\n    totalClaimed: \"0\",\n    withdrawRequestedAt: 0,\n    refundNonce: 0,\n    lastRequestTimestamp: Date.now(),\n  };\n}\n\n/**\n * Infers the local charged base when storage has no channel record.\n *\n * @param signedMaxClaimable - Client-signed cumulative voucher cap.\n * @param price - Current request amount.\n * @param isPaidPayload - Whether the payload should add `price` to the local base.\n * @returns Inferred charged base as a decimal string.\n */\nfunction inferMissingLocalChargedAmount(\n  signedMaxClaimable: string,\n  price: string,\n  isPaidPayload: boolean,\n): string {\n  if (!isPaidPayload) {\n    return signedMaxClaimable;\n  }\n\n  const signed = BigInt(signedMaxClaimable);\n  const amount = BigInt(price);\n  if (signed < amount) {\n    return \"0\";\n  }\n  return (signed - amount).toString();\n}\n","import type { BatchSettlementChannelStateExtra } from \"../types\";\nimport { ErrRefundPayload } from \"../errors\";\n\n/**\n * Reads the nested channel snapshot from payment response extra fields.\n *\n * @param extra - Payment response extra fields.\n * @returns Channel state object, or undefined when absent.\n */\nexport function readChannelStateExtra(\n  extra: Record<string, unknown> | undefined,\n): Partial<BatchSettlementChannelStateExtra> | undefined {\n  const value = extra?.channelState;\n  if (typeof value !== \"object\" || value === null) {\n    return undefined;\n  }\n  return value as Partial<BatchSettlementChannelStateExtra>;\n}\n\n/**\n * Reads a string value from optional payment `extra`, with a fallback when missing or invalid.\n *\n * @param extra - Optional payment extra record.\n * @param key - Key on `BatchSettlementPaymentResponseExtra` to read.\n * @param fallback - Value returned when the entry is absent or not coercible to string.\n * @returns String representation of the value, or `fallback`.\n */\nexport function readExtraString(\n  extra: Partial<Record<keyof BatchSettlementChannelStateExtra, unknown>> | undefined,\n  key: keyof BatchSettlementChannelStateExtra,\n  fallback: string,\n): string {\n  const value = extra?.[key];\n  if (typeof value === \"string\") return value;\n  if (typeof value === \"number\") return String(value);\n  return fallback;\n}\n\n/**\n * Reads a numeric value from optional payment `extra`, with a fallback when missing or invalid.\n *\n * @param extra - Optional payment extra record.\n * @param key - Key on `BatchSettlementPaymentResponseExtra` to read.\n * @param fallback - Value returned when the entry is absent or not parseable as a number.\n * @returns Parsed number, or `fallback`.\n */\nexport function readExtraNumber(\n  extra: Partial<Record<keyof BatchSettlementChannelStateExtra, unknown>> | undefined,\n  key: keyof BatchSettlementChannelStateExtra,\n  fallback: number,\n): number {\n  const value = extra?.[key];\n  if (typeof value === \"number\") return value;\n  if (typeof value === \"string\") return parseInt(value, 10) || fallback;\n  return fallback;\n}\n\nexport type RefundSettlementSnapshot = {\n  balance: string;\n  totalClaimed: string;\n  withdrawRequestedAt: number;\n  refundNonce: number;\n};\n\n/**\n * Parses the facilitator's post-refund channel snapshot.\n *\n * @param extra - Settlement response extra fields.\n * @returns Validated refund settlement snapshot.\n */\nexport function parseRefundSettlementSnapshot(\n  extra: Record<string, unknown> | undefined,\n): RefundSettlementSnapshot {\n  const channelState = readChannelStateExtra(extra);\n  return {\n    balance: parseUintStringExtra(channelState, \"balance\"),\n    totalClaimed: parseUintStringExtra(channelState, \"totalClaimed\"),\n    withdrawRequestedAt: parseUintNumberExtra(channelState, \"withdrawRequestedAt\"),\n    refundNonce: parseUintNumberExtra(channelState, \"refundNonce\"),\n  };\n}\n\n/**\n * Parses a non-negative integer as a decimal string from refund snapshot `extra`.\n *\n * @param extra - Settlement response extra fields from the facilitator.\n * @param key - Field name: `balance` or `totalClaimed`.\n * @returns Decimal string representation of the uint (digits only).\n */\nfunction parseUintStringExtra(\n  extra: Partial<Record<keyof BatchSettlementChannelStateExtra, unknown>> | undefined,\n  key: \"balance\" | \"totalClaimed\",\n): string {\n  const value = extra?.[key];\n  if (typeof value === \"string\" && /^\\d+$/.test(value)) return value;\n  if (typeof value === \"number\" && Number.isInteger(value) && value >= 0) return String(value);\n  throw new Error(ErrRefundPayload);\n}\n\n/**\n * Parses a non-negative integer from refund snapshot `extra`.\n *\n * @param extra - Settlement response extra fields from the facilitator.\n * @param key - Field name: `withdrawRequestedAt` or `refundNonce`.\n * @returns Parsed non-negative integer.\n */\nfunction parseUintNumberExtra(\n  extra: Partial<Record<keyof BatchSettlementChannelStateExtra, unknown>> | undefined,\n  key: \"withdrawRequestedAt\" | \"refundNonce\",\n): number {\n  const value = extra?.[key];\n  if (typeof value === \"number\" && Number.isInteger(value) && value >= 0) return value;\n  if (typeof value === \"string\" && /^\\d+$/.test(value)) {\n    const parsed = parseInt(value, 10);\n    if (!Number.isNaN(parsed)) return parsed;\n  }\n  throw new Error(ErrRefundPayload);\n}\n","import type { SettleResponse } from \"@x402/core/types\";\nimport type { SettleContext, SettleFailureContext, SettleResultContext } from \"@x402/core/server\";\nimport { signClaimBatch, signRefund } from \"../authorizerSigner\";\nimport {\n  isBatchSettlementDepositPayload,\n  isBatchSettlementRefundPayload,\n  isBatchSettlementVoucherPayload,\n} from \"../types\";\nimport type { BatchSettlementPaymentResponseExtra, BatchSettlementVoucherClaim } from \"../types\";\nimport { computeChannelId } from \"../utils\";\nimport * as Errors from \"../errors\";\nimport type { BatchSettlementEvmScheme } from \"./scheme\";\nimport type { Channel } from \"./storage\";\nimport {\n  parseRefundSettlementSnapshot,\n  readChannelStateExtra,\n  readExtraNumber,\n  readExtraString,\n} from \"./utils\";\n\n/**\n * Converts stored channel state into the public response snapshot shape.\n *\n * @param channel - Stored channel state.\n * @param chargedCumulativeAmount - Optional current charged cumulative amount.\n * @returns Response-ready channel snapshot.\n */\nfunction channelStateExtra(\n  channel: Pick<\n    Channel,\n    \"channelId\" | \"balance\" | \"totalClaimed\" | \"withdrawRequestedAt\" | \"refundNonce\"\n  >,\n  chargedCumulativeAmount?: string,\n): NonNullable<BatchSettlementPaymentResponseExtra[\"channelState\"]> {\n  return {\n    channelId: channel.channelId as `0x${string}`,\n    balance: channel.balance,\n    totalClaimed: channel.totalClaimed,\n    withdrawRequestedAt: channel.withdrawRequestedAt,\n    refundNonce: String(channel.refundNonce),\n    ...(chargedCumulativeAmount !== undefined ? { chargedCumulativeAmount } : {}),\n  };\n}\n\n/**\n * Lifecycle hook: runs before the facilitator settles a payment.\n *\n * For voucher payloads the server does NOT trigger an onchain settle.  Instead, it\n * increments the local `chargedCumulativeAmount` and returns a `skip` result so the\n * middleware responds immediately. Cooperative refund payloads proceed to settlement\n * enrichment before facilitator settlement.\n *\n * @param scheme - Owning `BatchSettlementEvmScheme` instance for storage access.\n * @param ctx - Settle lifecycle context (payload and requirements).\n * @returns Nothing to proceed; `abort` to fail; `skip` with a result to short-circuit settlement.\n */\nexport async function handleBeforeSettle(\n  scheme: BatchSettlementEvmScheme,\n  ctx: SettleContext,\n): Promise<\n  void | { abort: true; reason: string; message?: string } | { skip: true; result: SettleResponse }\n> {\n  const { paymentPayload, requirements } = ctx;\n\n  const raw = paymentPayload.payload;\n  const storage = scheme.getStorage();\n\n  if (!isBatchSettlementVoucherPayload(raw)) {\n    return;\n  }\n\n  const { voucher } = raw;\n  const channelId = voucher.channelId;\n  const pendingId = scheme.readRequestContext(paymentPayload)?.pendingId;\n\n  const increment = BigInt(requirements.amount);\n  const signedCap = BigInt(voucher.maxClaimableAmount);\n  let outcome:\n    | { status: \"missing\" }\n    | { status: \"pending_mismatch\" }\n    | { status: \"cap_exceeded\"; charged: string }\n    | { status: \"committed\"; previous: Channel; current: Channel }\n    | undefined;\n\n  const updateResult = await storage.updateChannel(channelId, current => {\n    if (!current) {\n      outcome = { status: \"missing\" };\n      return current;\n    }\n\n    if (!pendingId || current.pendingRequest?.pendingId !== pendingId) {\n      outcome = { status: \"pending_mismatch\" };\n      return current;\n    }\n\n    const newCharged = BigInt(current.chargedCumulativeAmount) + increment;\n    if (newCharged > signedCap) {\n      outcome = { status: \"cap_exceeded\", charged: newCharged.toString() };\n      return {\n        ...current,\n        pendingRequest: undefined,\n      };\n    }\n\n    const updatedChannel: Channel = {\n      ...current,\n      chargedCumulativeAmount: newCharged.toString(),\n      signedMaxClaimable: voucher.maxClaimableAmount,\n      signature: voucher.signature,\n      lastRequestTimestamp: Date.now(),\n      pendingRequest: undefined,\n    };\n    outcome = { status: \"committed\", previous: current, current: updatedChannel };\n    return updatedChannel;\n  });\n\n  if (outcome?.status === \"missing\") {\n    scheme.takeRequestContext(paymentPayload);\n    return {\n      abort: true,\n      reason: Errors.ErrMissingChannel,\n      message: \"No channel record\",\n    };\n  }\n\n  if (outcome?.status === \"cap_exceeded\") {\n    scheme.takeRequestContext(paymentPayload);\n    return {\n      abort: true,\n      reason: Errors.ErrChargeExceedsSignedCumulative,\n      message: `Charged ${outcome.charged} exceeds signed max ${signedCap.toString()}`,\n    };\n  }\n\n  if (updateResult.status !== \"updated\" || outcome?.status !== \"committed\") {\n    scheme.takeRequestContext(paymentPayload);\n    return {\n      abort: true,\n      reason: Errors.ErrChannelBusy,\n      message: \"Concurrent request modified channel state\",\n    };\n  }\n  scheme.takeRequestContext(paymentPayload);\n\n  const skipExtra: BatchSettlementPaymentResponseExtra = {\n    channelState: channelStateExtra(outcome.previous, outcome.current.chargedCumulativeAmount),\n    chargedAmount: requirements.amount,\n  };\n\n  return {\n    skip: true,\n    result: {\n      success: true,\n      payer: outcome.previous.channelConfig.payer.toLowerCase() as `0x${string}`,\n      transaction: \"\",\n      network: requirements.network,\n      amount: \"\",\n      extra: skipExtra,\n    },\n  };\n}\n\n/**\n * Enriches cooperative refund vouchers with facilitator settlement fields.\n *\n * @param scheme - Owning `BatchSettlementEvmScheme` instance for storage and signer access.\n * @param ctx - Settlement context for the current payment.\n * @returns Additive refund settlement fields, or nothing for non-refund payloads.\n */\nexport async function handleEnrichSettlementPayload(\n  scheme: BatchSettlementEvmScheme,\n  ctx: SettleContext,\n): Promise<Record<string, unknown> | void> {\n  const { paymentPayload, requirements } = ctx;\n  const raw = paymentPayload.payload;\n  if (!isBatchSettlementRefundPayload(raw)) {\n    return;\n  }\n\n  const channelId = computeChannelId(raw.channelConfig, requirements.network);\n  if (raw.voucher.channelId !== channelId) {\n    throw new Error(\"refund channelId does not match channelConfig\");\n  }\n\n  const channel = await scheme.getStorage().get(channelId);\n  if (!channel) {\n    throw new Error(Errors.ErrMissingChannel);\n  }\n  const pendingId = scheme.readRequestContext(paymentPayload)?.pendingId;\n  if (!pendingId || channel.pendingRequest?.pendingId !== pendingId) {\n    throw new Error(Errors.ErrChannelBusy);\n  }\n  if (BigInt(raw.voucher.maxClaimableAmount) !== BigInt(channel.chargedCumulativeAmount)) {\n    throw new Error(Errors.ErrCumulativeAmountMismatch);\n  }\n  if (raw.voucher.signature !== channel.signature) {\n    throw new Error(Errors.ErrInvalidVoucherSignature);\n  }\n\n  const config = raw.channelConfig;\n\n  const claimEntry: BatchSettlementVoucherClaim = {\n    voucher: {\n      channel: config,\n      maxClaimableAmount: raw.voucher.maxClaimableAmount,\n    },\n    signature: raw.voucher.signature,\n    totalClaimed: channel.chargedCumulativeAmount,\n  };\n\n  const remainder = BigInt(channel.balance) - BigInt(channel.chargedCumulativeAmount);\n  if (remainder <= 0n) {\n    throw new Error(Errors.ErrRefundNoBalance);\n  }\n\n  let refundAmountBig = remainder;\n  if (raw.amount !== undefined) {\n    if (!/^\\d+$/.test(raw.amount)) {\n      throw new Error(Errors.ErrRefundAmountInvalid);\n    }\n    const requested = BigInt(raw.amount);\n    if (requested <= 0n) {\n      throw new Error(Errors.ErrRefundAmountInvalid);\n    }\n    refundAmountBig = requested;\n  }\n\n  const refundAmount = refundAmountBig.toString();\n  const nonce = String(channel.refundNonce ?? 0);\n\n  const receiverAuthorizerSigner = scheme.getReceiverAuthorizerSigner();\n\n  const refundAuthorizerSignature = receiverAuthorizerSigner\n    ? await signRefund(\n        receiverAuthorizerSigner,\n        channelId as `0x${string}`,\n        refundAmount,\n        nonce,\n        requirements.network,\n      )\n    : undefined;\n\n  const claimAuthorizerSignature = receiverAuthorizerSigner\n    ? await signClaimBatch(receiverAuthorizerSigner, [claimEntry], requirements.network)\n    : undefined;\n\n  scheme.rememberChannelSnapshot(paymentPayload, channel);\n\n  return {\n    ...(raw.amount === undefined ? { amount: refundAmount } : {}),\n    refundNonce: nonce,\n    claims: [claimEntry],\n    refundAuthorizerSignature,\n    claimAuthorizerSignature,\n  };\n}\n\n/**\n * Lifecycle hook: runs after the facilitator settles a payment.\n *\n * Updates channel state to reflect the settlement outcome — adjusting charged amounts,\n * balances, and handling cooperative-refund cleanup (channel record deletion).\n *\n * @param scheme - Owning `BatchSettlementEvmScheme` instance for storage access.\n * @param ctx - Post-settle lifecycle context.\n * @param ctx.paymentPayload - Payment payload that was settled (possibly rewritten).\n * @param ctx.requirements - Requirements used for settlement.\n * @param ctx.result - Facilitator settle response.\n * @returns Resolves when session updates are complete (no return value).\n */\nexport async function handleAfterSettle(\n  scheme: BatchSettlementEvmScheme,\n  ctx: SettleResultContext,\n): Promise<void> {\n  const { paymentPayload, requirements, result } = ctx;\n  if (!result.success) {\n    return;\n  }\n\n  const raw = paymentPayload.payload;\n  const storage = scheme.getStorage();\n\n  if (isBatchSettlementRefundPayload(raw)) {\n    const channelId = computeChannelId(raw.channelConfig, requirements.network);\n    const pendingId = scheme.readRequestContext(paymentPayload)?.pendingId;\n    const now = Date.now();\n\n    const snapshot = parseRefundSettlementSnapshot(result.extra);\n    const updateResult = await storage.updateChannel(channelId, current => {\n      if (!current) {\n        return current;\n      }\n      if (!pendingId || current.pendingRequest?.pendingId !== pendingId) {\n        return current;\n      }\n      if (BigInt(snapshot.balance) <= BigInt(current.chargedCumulativeAmount)) {\n        return undefined;\n      }\n      return {\n        ...current,\n        ...snapshot,\n        onchainSyncedAt: now,\n        lastRequestTimestamp: now,\n        pendingRequest: undefined,\n      };\n    });\n    if (updateResult.status === \"unchanged\") {\n      throw new Error(Errors.ErrChannelBusy);\n    }\n    if (!updateResult.channel) {\n      return;\n    }\n    return;\n  }\n\n  if (isBatchSettlementVoucherPayload(raw)) {\n    return;\n  }\n\n  if (isBatchSettlementDepositPayload(raw)) {\n    const channelId = raw.voucher.channelId;\n    const pendingId = scheme.readRequestContext(paymentPayload)?.pendingId;\n    const ex = result.extra ?? {};\n    const channelState = readChannelStateExtra(ex);\n    const config = raw.channelConfig;\n    const signedMaxClaimable = raw.voucher.maxClaimableAmount;\n    const now = Date.now();\n\n    const updateResult = await storage.updateChannel(channelId, current => {\n      if (!current) {\n        return current;\n      }\n      if (!pendingId || current.pendingRequest?.pendingId !== pendingId) {\n        return current;\n      }\n      const chargedActual = (\n        BigInt(current.chargedCumulativeAmount) + BigInt(requirements.amount)\n      ).toString();\n      return {\n        channelId,\n        channelConfig: config,\n        chargedCumulativeAmount: chargedActual,\n        signedMaxClaimable,\n        signature: raw.voucher.signature,\n        balance: readExtraString(channelState, \"balance\", current.balance),\n        totalClaimed: readExtraString(channelState, \"totalClaimed\", current.totalClaimed),\n        withdrawRequestedAt: readExtraNumber(\n          channelState,\n          \"withdrawRequestedAt\",\n          current.withdrawRequestedAt,\n        ),\n        refundNonce: readExtraNumber(channelState, \"refundNonce\", current.refundNonce),\n        onchainSyncedAt: now,\n        lastRequestTimestamp: now,\n      };\n    });\n    if (updateResult.status === \"updated\" && updateResult.channel) {\n      scheme.rememberChannelSnapshot(paymentPayload, updateResult.channel);\n      return;\n    }\n    scheme.takeRequestContext(paymentPayload);\n    throw new Error(Errors.ErrChannelBusy);\n  }\n}\n\n/**\n * Cleanup hook: clears this request's reservation after settlement throws.\n *\n * @param scheme - Owning `BatchSettlementEvmScheme` instance.\n * @param ctx - Settle failure context for the current payment.\n */\nexport async function handleSettleFailure(\n  scheme: BatchSettlementEvmScheme,\n  ctx: SettleFailureContext,\n): Promise<void> {\n  await scheme.clearPendingRequest(ctx.paymentPayload);\n}\n\n/**\n * Supplies server-owned settlement response fields from the channel snapshot.\n *\n * @param scheme - Owning `BatchSettlementEvmScheme` instance for snapshot access.\n * @param ctx - Settlement result context for the current payment.\n * @returns Additive response extra fields, or nothing when no snapshot exists.\n */\nexport async function handleEnrichSettlementResponse(\n  scheme: BatchSettlementEvmScheme,\n  ctx: SettleResultContext,\n): Promise<Record<string, unknown> | void> {\n  const raw = ctx.paymentPayload.payload;\n  if (isBatchSettlementVoucherPayload(raw)) {\n    return;\n  }\n\n  const channel = scheme.takeChannelSnapshot(ctx.paymentPayload);\n  if (!channel) {\n    return;\n  }\n\n  if (isBatchSettlementRefundPayload(raw)) {\n    return {\n      channelState: {\n        chargedCumulativeAmount: channel.chargedCumulativeAmount,\n      },\n    };\n  }\n\n  if (isBatchSettlementDepositPayload(raw)) {\n    return {\n      channelState: {\n        chargedCumulativeAmount: channel.chargedCumulativeAmount,\n      },\n      chargedAmount: ctx.requirements.amount,\n    };\n  }\n  return {\n    channelState: {\n      chargedCumulativeAmount: channel.chargedCumulativeAmount,\n    },\n  };\n}\n"],"mappings":"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","names":["getAddress","getAddress"]}