{"version":3,"sources":["../../src/core/SubRav.ts","../../src/billing/core/strategy-registry.ts","../../src/storage/sql/channel.sql.ts","../../src/storage/sql/serialization.ts","../../src/storage/sql/rav.sql.ts","../../src/storage/sql/pendingSubRav.sql.ts","../../src/storage/sql/index.ts","../../src/index.node.ts","../../src/index.browser.ts","../../src/errors/codes.ts","../../src/core/PaymentProcessor.ts","../../src/billing/rate/types.ts","../../src/billing/core/converter.ts","../../src/billing/strategies/base.ts","../../src/billing/strategies/perRequest.ts","../../src/billing/strategies/perToken.ts","../../src/billing/strategies/finalCost.ts","../../src/billing/strategies/index.ts","../../src/middlewares/http/HttpPaymentCodec.ts","../../src/codecs/PaymentCodec.ts","../../src/rooch/ChannelUtils.ts","../../src/core/RavVerifier.ts","../../src/core/PaymentUtils.ts","../../src/client/PaymentChannelPayerClient.ts","../../src/billing/rate/contract.ts","../../src/client/PaymentHubClient.ts","../../src/client/PaymentChannelPayeeClient.ts","../../src/rooch/RoochPaymentChannelContract.ts","../../src/factory/chainFactory.ts","../../src/billing/core/rule-matcher.ts","../../src/middlewares/http/HttpBillingMiddleware.ts","../../src/types/api.ts","../../src/errors/PaymentKitError.ts","../../src/core/SubRavValidator.ts","../../src/integrations/http/internal/DidAuthHelper.ts","../../src/schema/core/index.ts","../../src/utils/json.ts","../../src/storage/memory/channel.memory.ts","../../src/storage/indexeddb/channel.indexeddb.ts","../../src/storage/factories/createChannelRepo.ts","../../src/storage/memory/rav.memory.ts","../../src/storage/indexeddb/rav.indexeddb.ts","../../src/storage/factories/createRAVRepo.ts","../../src/storage/memory/pendingSubRav.memory.ts","../../src/storage/indexeddb/pendingSubRav.indexeddb.ts","../../src/storage/factories/createPendingSubRAVRepo.ts","../../src/storage/memory/transaction.memory.ts","../../src/storage/indexeddb/transactions.indexeddb.ts","../../src/storage/factories/createTransactionStore.ts","../../src/storage/index.ts","../../src/integrations/http/internal/LocalStore.ts","../../src/schema/api/recovery.ts","../../src/schema/api/commit.ts","../../src/schema/api/discovery.ts","../../src/schema/api/health.ts","../../src/schema/api/subrav.ts","../../src/schema/api/admin.ts","../../src/integrations/http/PaymentChannelHttpClient.ts","../../src/integrations/http/internal/StreamPaymentFilter.ts","../../src/integrations/http/internal/utils.ts","../../src/integrations/http/internal/RequestScheduler.ts","../../src/integrations/http/core/PaymentState.ts","../../src/integrations/http/core/PaymentProtocol.ts","../../src/integrations/http/core/RequestManager.ts","../../src/integrations/http/core/ChannelManager.ts","../../src/integrations/http/PaymentChannelAdminClient.ts","../../src/helpers/fromIdentityEnv.ts","../../src/integrations/http/factory.ts","../../src/utils/index.ts","../../src/transport/express/BillableRouter.ts","../../src/transport/express/HandlerRestAdapter.ts","../../src/transport/express/ExpressPaymentKit.ts","../../src/api/handlers/recovery.ts","../../src/api/handlers/commit.ts","../../src/api/handlers/admin.ts","../../src/api/handlers/subrav.ts","../../src/api/handlers/health.ts","../../src/api/utils.ts","../../src/api/index.ts","../../src/core/HubBalanceService.ts","../../src/core/ClaimTriggerService.ts","../../src/transport/express/utils.ts","../../src/transport/express/fromIdentityEnv.ts"],"sourcesContent":["/**\n * SubRAV encoding, decoding, signing and verification utilities\n */\n\nimport type {\n  SignerInterface,\n  DIDResolver,\n  DIDDocument,\n  KeyType,\n  VerificationMethod,\n} from '@nuwa-ai/identity-kit';\nimport { CryptoUtils, MultibaseCodec } from '@nuwa-ai/identity-kit';\nimport { bcs, type BcsType } from '@roochnetwork/rooch-sdk';\nimport type { SubRAV, SignedSubRAV } from './types';\n\n/**\n * Constants for SubRAV protocol versions\n */\nexport const SUBRAV_VERSION_1 = 1;\nexport const CURRENT_SUBRAV_VERSION = SUBRAV_VERSION_1;\n\n/**\n * BCS Schema for SubRAV serialization\n * Must match the Move contract SubRAV struct definition\n */\nexport const SubRAVSchema: BcsType<any> = bcs.struct('SubRAV', {\n  version: bcs.u8(),\n  chain_id: bcs.u64(),\n  channel_id: bcs.ObjectId,\n  channel_epoch: bcs.u64(),\n  vm_id_fragment: bcs.string(),\n  accumulated_amount: bcs.u256(),\n  nonce: bcs.u64(),\n});\n\n/**\n * SubRAV codec for encoding and decoding using BCS\n */\nexport class SubRAVCodec {\n  /**\n   * Encode a SubRAV to bytes using BCS serialization\n   * This ensures cross-platform consistency with Move contracts\n   */\n  static encode(subRav: SubRAV): Uint8Array {\n    try {\n      // Convert to BCS-compatible format\n      // Note: BCS expects string representations for large numbers\n      const bcsSubRAV = {\n        version: subRav.version,\n        chain_id: subRav.chainId.toString(),\n        channel_id: subRav.channelId,\n        channel_epoch: subRav.channelEpoch.toString(),\n        vm_id_fragment: subRav.vmIdFragment,\n        accumulated_amount: subRav.accumulatedAmount.toString(),\n        nonce: subRav.nonce.toString(),\n      };\n\n      return SubRAVSchema.serialize(bcsSubRAV).toBytes();\n    } catch (error) {\n      throw new Error(\n        `Failed to encode SubRAV: ${error instanceof Error ? error.message : 'Unknown error'}`\n      );\n    }\n  }\n\n  /**\n   * Decode bytes to SubRAV using BCS deserialization\n   */\n  static decode(bytes: Uint8Array): SubRAV {\n    try {\n      const bcsSubRAV = SubRAVSchema.parse(bytes);\n\n      return {\n        version: bcsSubRAV.version,\n        chainId: BigInt(bcsSubRAV.chain_id),\n        channelId: bcsSubRAV.channel_id,\n        channelEpoch: BigInt(bcsSubRAV.channel_epoch),\n        vmIdFragment: bcsSubRAV.vm_id_fragment,\n        accumulatedAmount: BigInt(bcsSubRAV.accumulated_amount),\n        nonce: BigInt(bcsSubRAV.nonce),\n      };\n    } catch (error) {\n      throw new Error(\n        `Failed to decode SubRAV: ${error instanceof Error ? error.message : 'Unknown error'}`\n      );\n    }\n  }\n\n  /**\n   * Get the BCS hex string representation of a SubRAV (useful for debugging)\n   */\n  static toHex(subRav: SubRAV): string {\n    const bytes = this.encode(subRav);\n    return (\n      '0x' +\n      Array.from(bytes)\n        .map(byte => byte.toString(16).padStart(2, '0'))\n        .join('')\n    );\n  }\n\n  /**\n   * Create SubRAV from BCS hex string\n   */\n  static fromHex(hex: string): SubRAV {\n    const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex;\n    const bytes = new Uint8Array(cleanHex.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []);\n    return this.decode(bytes);\n  }\n}\n\n/**\n * SubRAV signing and verification utilities\n */\nexport class SubRAVSigner {\n  /**\n   * Sign a SubRAV using the provided signer and key\n   */\n  static async sign(subRav: SubRAV, signer: SignerInterface, keyId: string): Promise<SignedSubRAV> {\n    const bytes = SubRAVCodec.encode(subRav);\n    const signature = await signer.signWithKeyId(bytes, keyId);\n    return { subRav, signature };\n  }\n\n  /**\n   * Verify a signed SubRAV using public key or DID document\n   */\n  static async verify(\n    signedSubRAV: SignedSubRAV,\n    verificationMethod:\n      | {\n          publicKey: Uint8Array;\n          keyType: KeyType;\n        }\n      | {\n          didDocument: DIDDocument;\n        }\n  ): Promise<boolean> {\n    try {\n      const bytes = SubRAVCodec.encode(signedSubRAV.subRav);\n\n      let publicKey: Uint8Array;\n      let keyType: KeyType;\n\n      if ('publicKey' in verificationMethod) {\n        // Direct public key verification\n        publicKey = verificationMethod.publicKey;\n        keyType = verificationMethod.keyType;\n      } else {\n        // DID document verification\n        const { didDocument } = verificationMethod;\n\n        // Construct keyId from didDocument.id and vmIdFragment from SubRAV\n        const keyId = `${didDocument.id}#${signedSubRAV.subRav.vmIdFragment}`;\n\n        const vm = didDocument.verificationMethod?.find(\n          (vm: VerificationMethod) => vm.id === keyId\n        );\n        if (!vm) return false;\n\n        keyType = vm.type as KeyType;\n\n        // Get public key material\n        if (vm.publicKeyMultibase) {\n          publicKey = MultibaseCodec.decodeBase58btc(vm.publicKeyMultibase);\n        } else if (vm.publicKeyJwk) {\n          // Handle JWK format - this would need proper JWK to raw key conversion\n          // For now, we don't support JWK format in this context\n          return false;\n        } else {\n          return false; // No supported key format\n        }\n      }\n\n      // Verify signature\n      return CryptoUtils.verify(bytes, signedSubRAV.signature, publicKey, keyType);\n    } catch (error) {\n      return false;\n    }\n  }\n\n  /**\n   * Verify a signed SubRAV using DID resolver (convenience method)\n   */\n  static async verifyWithResolver(\n    signedSubRAV: SignedSubRAV,\n    payerDid: string,\n    resolver: DIDResolver\n  ): Promise<boolean> {\n    try {\n      // Resolve DID document\n      const didDocument = await resolver.resolveDID(payerDid);\n      if (!didDocument) return false;\n\n      // Use the flexible verify method\n      return this.verify(signedSubRAV, { didDocument });\n    } catch (error) {\n      return false;\n    }\n  }\n}\n\n/**\n * SubRAV validation utilities\n */\nexport class SubRAVValidator {\n  /**\n   * Validate SubRAV structure and constraints\n   */\n  static validate(subRav: SubRAV): { valid: boolean; errors: string[] } {\n    const errors: string[] = [];\n\n    // Check version\n    if (!Number.isInteger(subRav.version) || subRav.version < 1) {\n      errors.push('Version must be a positive integer (minimum 1)');\n    }\n\n    // For now, only support version 1\n    if (subRav.version !== SUBRAV_VERSION_1) {\n      errors.push(\n        `Unsupported SubRAV version: ${subRav.version}. Supported versions: ${SUBRAV_VERSION_1}`\n      );\n    }\n\n    // Check required fields\n    if (!subRav.channelId || subRav.channelId.length !== 66) {\n      errors.push('Invalid channel ID format (must be 32-byte hex string with 0x prefix)');\n    }\n\n    if (!subRav.vmIdFragment || subRav.vmIdFragment.length === 0) {\n      errors.push('VM ID fragment is required');\n    }\n\n    if (subRav.chainId < 0) {\n      errors.push('Chain ID must be non-negative');\n    }\n\n    if (subRav.channelEpoch < 0) {\n      errors.push('Channel epoch must be non-negative');\n    }\n\n    if (subRav.accumulatedAmount < 0) {\n      errors.push('Accumulated amount must be non-negative');\n    }\n\n    if (subRav.nonce < 0) {\n      errors.push('Nonce must be non-negative');\n    }\n\n    return {\n      valid: errors.length === 0,\n      errors,\n    };\n  }\n\n  /**\n   * Validate SubRAV sequence (for checking monotonicity)\n   */\n  static validateSequence(\n    prev: SubRAV | null,\n    current: SubRAV\n  ): { valid: boolean; errors: string[] } {\n    const errors: string[] = [];\n\n    if (prev) {\n      // Check version compatibility\n      if (prev.version !== current.version) {\n        errors.push('Version mismatch between previous and current SubRAV');\n      }\n\n      // Check same channel and sub-channel\n      if (prev.channelId !== current.channelId) {\n        errors.push('Channel ID mismatch');\n      }\n\n      if (prev.vmIdFragment !== current.vmIdFragment) {\n        errors.push('VM ID fragment mismatch');\n      }\n\n      if (prev.channelEpoch !== current.channelEpoch) {\n        errors.push('Channel epoch mismatch');\n      }\n\n      // Check monotonicity\n      if (current.nonce <= prev.nonce) {\n        errors.push('Nonce must be strictly increasing');\n      }\n\n      if (current.accumulatedAmount < prev.accumulatedAmount) {\n        errors.push('Accumulated amount cannot decrease');\n      }\n    }\n\n    return {\n      valid: errors.length === 0,\n      errors,\n    };\n  }\n}\n\n/**\n * Helper functions for creating SubRAV instances\n */\nexport class SubRAVUtils {\n  /**\n   * Create a new SubRAV with default version\n   */\n  static create(params: Omit<SubRAV, 'version'> & { version?: number }): SubRAV {\n    return {\n      version: params.version ?? CURRENT_SUBRAV_VERSION,\n      chainId: params.chainId,\n      channelId: params.channelId,\n      channelEpoch: params.channelEpoch,\n      vmIdFragment: params.vmIdFragment,\n      accumulatedAmount: params.accumulatedAmount,\n      nonce: params.nonce,\n    };\n  }\n\n  /**\n   * Check if a SubRAV version is supported\n   */\n  static isSupportedVersion(version: number): boolean {\n    return version === SUBRAV_VERSION_1;\n  }\n}\n","import { BillingRule, Strategy, StrategyConfig } from './types';\n\nexport type StrategyBuilder<T extends StrategyConfig = StrategyConfig> = (cfg: T) => Strategy;\n\nconst registry = new Map<string, StrategyBuilder>();\n// Use WeakMap keyed by BillingRule object reference to avoid collisions when\n// different services re-use the same `rule.id`.\nlet cache: WeakMap<BillingRule, Strategy> = new WeakMap();\n\n/**\n * Register a strategy builder with the global registry.\n * This should be called exactly once per strategy type (during module init).\n */\nexport function register(type: string, builder: StrategyBuilder): void {\n  if (registry.has(type)) {\n    // eslint-disable-next-line no-console\n    console.warn(`Billing strategy type '${type}' is already registered – overwriting.`);\n  }\n  registry.set(type, builder);\n}\n\n/**\n * Resolve (and lazily cache) a strategy instance for the given rule.\n */\nexport function getStrategy(rule: BillingRule): Strategy {\n  const cached = cache.get(rule);\n  if (cached) {\n    return cached;\n  }\n\n  const builder = registry.get(rule.strategy.type);\n  if (!builder) {\n    throw new Error(\n      `Unknown billing strategy type '${rule.strategy.type}'. Make sure it has been registered.`\n    );\n  }\n\n  const strategy = builder(rule.strategy);\n  cache.set(rule, strategy);\n  return strategy;\n}\n\n/**\n * Clear cached strategy instances – mostly useful for hot-reloading.\n */\nexport function clearCache(rule?: BillingRule): void {\n  if (rule) {\n    cache.delete(rule);\n  } else {\n    cache = new WeakMap();\n  }\n}\n","/**\n * SQL-based ChannelRepository implementation for PostgreSQL/Supabase\n */\n\nimport type { Pool, PoolClient } from 'pg';\nimport type { ChannelRepository } from '../interfaces/ChannelRepository';\nimport type { ChannelInfo, SubChannelInfo } from '../../core/types';\nimport type {\n  PaginationParams,\n  ChannelFilter,\n  PaginatedResult,\n  CacheStats,\n} from '../types/pagination';\n\nexport interface SqlChannelRepositoryOptions {\n  /** PostgreSQL connection pool */\n  pool: Pool;\n  /** Table name prefix (default: 'nuwa_') */\n  tablePrefix?: string;\n  /** Auto-create tables if they don't exist */\n  autoMigrate?: boolean;\n  /** Allow unsafe auto-migration in production */\n  allowUnsafeAutoMigrateInProd?: boolean;\n}\n\n/**\n * PostgreSQL/Supabase implementation of ChannelRepository\n */\nexport class SqlChannelRepository implements ChannelRepository {\n  private pool: Pool;\n  private tablePrefix: string;\n  private autoMigrate: boolean;\n  private allowUnsafeAutoMigrateInProd: boolean;\n\n  constructor(options: SqlChannelRepositoryOptions) {\n    this.pool = options.pool;\n    this.tablePrefix = options.tablePrefix || 'nuwa_';\n    this.autoMigrate = options.autoMigrate ?? true;\n    this.allowUnsafeAutoMigrateInProd = options.allowUnsafeAutoMigrateInProd ?? false;\n\n    // Only auto-migrate in development or when explicitly allowed in production\n    if (\n      this.autoMigrate &&\n      (process.env.NODE_ENV !== 'production' || this.allowUnsafeAutoMigrateInProd)\n    ) {\n      this.initialize().catch(console.error);\n    }\n  }\n\n  private get channelsTable(): string {\n    return `${this.tablePrefix}channels`;\n  }\n\n  private get subChannelStatesTable(): string {\n    return `${this.tablePrefix}sub_channel_states`;\n  }\n\n  /**\n   * Initialize database tables if they don't exist\n   */\n  async initialize(): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      // Create channels table\n      await client.query(`\n        CREATE TABLE IF NOT EXISTS ${this.channelsTable} (\n          channel_id        TEXT PRIMARY KEY,\n          payer_did         TEXT NOT NULL,\n          payee_did         TEXT NOT NULL,\n          asset_id          TEXT NOT NULL,\n          status            TEXT NOT NULL,\n          balance           NUMERIC(78,0) NOT NULL,\n          created_at        BIGINT NOT NULL,\n          updated_at        BIGINT NOT NULL,\n          metadata          JSONB\n        )\n      `);\n\n      // Create sub-channel states table\n      await client.query(`\n        CREATE TABLE IF NOT EXISTS ${this.subChannelStatesTable} (\n          channel_id          TEXT NOT NULL,\n          vm_id_fragment      TEXT NOT NULL,\n          channel_id_ref      TEXT NOT NULL,\n          epoch               NUMERIC(78,0) NOT NULL DEFAULT 0,\n          last_confirmed_nonce NUMERIC(78,0) NOT NULL DEFAULT 0,\n          last_claimed_amount NUMERIC(78,0) NOT NULL DEFAULT 0,\n          last_update_time    BIGINT NOT NULL,\n          PRIMARY KEY(channel_id, vm_id_fragment)\n        )\n      `);\n\n      // Create indexes\n      await client.query(`\n        CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}channels_payer \n        ON ${this.channelsTable}(payer_did)\n      `);\n\n      await client.query(`\n        CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}channels_payee \n        ON ${this.channelsTable}(payee_did)\n      `);\n    } finally {\n      client.release();\n    }\n  }\n\n  // -------- Channel Metadata Operations --------\n\n  async getChannelMetadata(channelId: string): Promise<ChannelInfo | null> {\n    const client = await this.pool.connect();\n    try {\n      const result = await client.query(\n        `\n        SELECT channel_id, payer_did, payee_did, asset_id, status, balance, created_at, updated_at, metadata\n        FROM ${this.channelsTable}\n        WHERE channel_id = $1\n      `,\n        [channelId]\n      );\n\n      if (result.rows.length === 0) {\n        return null;\n      }\n\n      const row = result.rows[0];\n      return {\n        channelId: row.channel_id,\n        payerDid: row.payer_did,\n        payeeDid: row.payee_did,\n        assetId: row.asset_id,\n        status: row.status,\n        epoch: row.metadata?.epoch ? BigInt(row.metadata.epoch) : BigInt(0),\n      };\n    } finally {\n      client.release();\n    }\n  }\n\n  async setChannelMetadata(channelId: string, metadata: ChannelInfo): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      const metadataJson = {\n        epoch: metadata.epoch?.toString(),\n        // Add any other metadata fields that aren't in the main columns\n      };\n\n      await client.query(\n        `\n        INSERT INTO ${this.channelsTable} \n        (channel_id, payer_did, payee_did, asset_id, status, balance, created_at, updated_at, metadata)\n        VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)\n        ON CONFLICT (channel_id) \n        DO UPDATE SET\n          payer_did = EXCLUDED.payer_did,\n          payee_did = EXCLUDED.payee_did,\n          asset_id = EXCLUDED.asset_id,\n          status = EXCLUDED.status,\n          balance = EXCLUDED.balance,\n          updated_at = EXCLUDED.updated_at,\n          metadata = EXCLUDED.metadata\n      `,\n        [\n          channelId,\n          metadata.payerDid,\n          metadata.payeeDid,\n          metadata.assetId,\n          metadata.status,\n          '0', // balance not in ChannelInfo\n          Date.now().toString(), // created_at\n          Date.now().toString(), // updated_at\n          JSON.stringify(metadataJson),\n        ]\n      );\n    } finally {\n      client.release();\n    }\n  }\n\n  async listChannelMetadata(\n    filter?: ChannelFilter,\n    pagination?: PaginationParams\n  ): Promise<PaginatedResult<ChannelInfo>> {\n    const client = await this.pool.connect();\n    try {\n      let whereClause = '';\n      const params: any[] = [];\n      let paramIndex = 1;\n\n      // Build WHERE clause from filter\n      if (filter) {\n        const conditions: string[] = [];\n\n        if (filter.payerDid) {\n          conditions.push(`payer_did = $${paramIndex++}`);\n          params.push(filter.payerDid);\n        }\n\n        if (filter.payeeDid) {\n          conditions.push(`payee_did = $${paramIndex++}`);\n          params.push(filter.payeeDid);\n        }\n\n        if (filter.status) {\n          conditions.push(`status = $${paramIndex++}`);\n          params.push(filter.status);\n        }\n\n        if (conditions.length > 0) {\n          whereClause = `WHERE ${conditions.join(' AND ')}`;\n        }\n      }\n\n      // Build pagination\n      const limit = pagination?.limit || 50;\n      const offset = pagination?.offset || 0;\n\n      // Get total count\n      const countQuery = `SELECT COUNT(*) as total FROM ${this.channelsTable} ${whereClause}`;\n      const countResult = await client.query(countQuery, params);\n      const total = parseInt(countResult.rows[0].total);\n\n      // Get data\n      const dataQuery = `\n        SELECT channel_id, payer_did, payee_did, asset_id, status, balance, created_at, updated_at, metadata\n        FROM ${this.channelsTable} \n        ${whereClause}\n        ORDER BY created_at DESC\n        LIMIT $${paramIndex++} OFFSET $${paramIndex++}\n      `;\n      params.push(limit, offset);\n\n      const dataResult = await client.query(dataQuery, params);\n\n      const items = dataResult.rows.map(row => ({\n        channelId: row.channel_id,\n        payerDid: row.payer_did,\n        payeeDid: row.payee_did,\n        assetId: row.asset_id,\n        status: row.status,\n        epoch: row.metadata?.epoch ? BigInt(row.metadata.epoch) : BigInt(0),\n      }));\n\n      return {\n        items,\n        totalCount: total,\n        hasMore: offset + limit < total,\n      };\n    } finally {\n      client.release();\n    }\n  }\n\n  async removeChannelMetadata(channelId: string): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      await client.query(\n        `\n        DELETE FROM ${this.channelsTable} WHERE channel_id = $1\n      `,\n        [channelId]\n      );\n    } finally {\n      client.release();\n    }\n  }\n\n  // -------- Sub-Channel State Operations --------\n\n  async getSubChannelState(\n    channelId: string,\n    vmIdFragment: string\n  ): Promise<SubChannelInfo | null> {\n    const client = await this.pool.connect();\n    try {\n      const result = await client.query(\n        `\n        SELECT channel_id_ref, epoch, last_confirmed_nonce, last_claimed_amount, last_update_time, vm_id_fragment\n        FROM ${this.subChannelStatesTable}\n        WHERE channel_id = $1 AND vm_id_fragment = $2\n      `,\n        [channelId, vmIdFragment]\n      );\n\n      if (result.rows.length === 0) {\n        return null;\n      }\n\n      const row = result.rows[0];\n      return {\n        channelId: row.channel_id_ref,\n        vmIdFragment: row.vm_id_fragment,\n        epoch: BigInt(row.epoch),\n        lastConfirmedNonce: BigInt(row.last_confirmed_nonce),\n        lastClaimedAmount: BigInt(row.last_claimed_amount),\n        lastUpdated: parseInt(row.last_update_time),\n      } as any;\n    } finally {\n      client.release();\n    }\n  }\n\n  async updateSubChannelState(\n    channelId: string,\n    vmIdFragment: string,\n    updates: Partial<SubChannelInfo>\n  ): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      // First, get current state or create default\n      const current =\n        (await this.getSubChannelState(channelId, vmIdFragment)) ||\n        ({\n          channelId,\n          vmIdFragment,\n          epoch: BigInt(0),\n          lastConfirmedNonce: BigInt(0),\n          lastClaimedAmount: BigInt(0),\n          lastUpdated: Date.now(),\n        } as any);\n\n      // Apply updates\n      const newState: any = {\n        channelId: (updates as any).channelId ?? current.channelId,\n        epoch: (updates as any).epoch ?? current.epoch,\n        lastConfirmedNonce: (updates as any).lastConfirmedNonce ?? current.lastConfirmedNonce,\n        lastClaimedAmount: (updates as any).lastClaimedAmount ?? current.lastClaimedAmount,\n        lastUpdated: (updates as any).lastUpdated ?? Date.now(),\n      };\n\n      await client.query(\n        `\n        INSERT INTO ${this.subChannelStatesTable} \n        (channel_id, vm_id_fragment, channel_id_ref, epoch, last_confirmed_nonce, last_claimed_amount, last_update_time)\n        VALUES ($1, $2, $3, $4, $5, $6, $7)\n        ON CONFLICT (channel_id, vm_id_fragment) \n        DO UPDATE SET\n          channel_id_ref = EXCLUDED.channel_id_ref,\n          epoch = EXCLUDED.epoch,\n          last_confirmed_nonce = EXCLUDED.last_confirmed_nonce,\n          last_claimed_amount = EXCLUDED.last_claimed_amount,\n          last_update_time = EXCLUDED.last_update_time\n      `,\n        [\n          channelId,\n          vmIdFragment,\n          newState.channelId,\n          newState.epoch.toString(),\n          newState.lastConfirmedNonce.toString(),\n          newState.lastClaimedAmount.toString(),\n          newState.lastUpdated.toString(),\n        ]\n      );\n    } finally {\n      client.release();\n    }\n  }\n\n  async listSubChannelStates(channelId: string): Promise<Record<string, SubChannelInfo>> {\n    const client = await this.pool.connect();\n    try {\n      const result = await client.query(\n        `\n        SELECT vm_id_fragment, channel_id_ref, epoch, last_confirmed_nonce, last_claimed_amount, last_update_time\n        FROM ${this.subChannelStatesTable}\n        WHERE channel_id = $1\n      `,\n        [channelId]\n      );\n\n      const states: Record<string, SubChannelInfo> = {};\n\n      for (const row of result.rows) {\n        states[row.vm_id_fragment] = {\n          channelId: row.channel_id_ref,\n          vmIdFragment: row.vm_id_fragment,\n          epoch: BigInt(row.epoch),\n          lastConfirmedNonce: BigInt(row.last_confirmed_nonce),\n          lastClaimedAmount: BigInt(row.last_claimed_amount),\n          lastUpdated: parseInt(row.last_update_time),\n        } as any;\n      }\n\n      return states;\n    } finally {\n      client.release();\n    }\n  }\n\n  async removeSubChannelState(channelId: string, vmIdFragment: string): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      await client.query(\n        `\n        DELETE FROM ${this.subChannelStatesTable} \n        WHERE channel_id = $1 AND vm_id_fragment = $2\n      `,\n        [channelId, vmIdFragment]\n      );\n    } finally {\n      client.release();\n    }\n  }\n\n  // -------- Management Operations --------\n\n  async getStats(): Promise<CacheStats> {\n    const client = await this.pool.connect();\n    try {\n      const channelResult = await client.query(`\n        SELECT COUNT(*) as total_channels FROM ${this.channelsTable}\n      `);\n\n      const subChannelResult = await client.query(`\n        SELECT COUNT(*) as total_sub_channels FROM ${this.subChannelStatesTable}\n      `);\n\n      return {\n        channelCount: parseInt(channelResult.rows[0].total_channels),\n        subChannelCount: parseInt(subChannelResult.rows[0].total_sub_channels),\n        hitRate: 0, // TODO: Could calculate actual size if needed\n        sizeBytes: 0, // TODO: Could calculate actual size if needed\n      };\n    } finally {\n      client.release();\n    }\n  }\n\n  async clear(): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      await client.query(`DELETE FROM ${this.subChannelStatesTable}`);\n      await client.query(`DELETE FROM ${this.channelsTable}`);\n    } finally {\n      client.release();\n    }\n  }\n}\n","/**\n * BCS serialization utilities for SQL storage\n * Uses SubRAVCodec to ensure consistency with Move contracts\n */\n\nimport { SubRAVCodec } from '../../core/SubRav';\nimport type { SubRAV } from '../../core/types';\n\n/**\n * Encode SubRAV to Buffer using BCS serialization\n * This ensures cross-platform consistency with Move contracts\n */\nexport function encodeSubRAV(subRav: SubRAV): Buffer {\n  try {\n    const bytes = SubRAVCodec.encode(subRav);\n    return Buffer.from(bytes);\n  } catch (error) {\n    throw new Error(\n      `Failed to encode SubRAV: ${error instanceof Error ? error.message : 'Unknown error'}`\n    );\n  }\n}\n\n/**\n * Decode Buffer to SubRAV using BCS deserialization\n */\nexport function decodeSubRAV(buffer: Buffer): SubRAV {\n  try {\n    const bytes = new Uint8Array(buffer);\n    return SubRAVCodec.decode(bytes);\n  } catch (error) {\n    throw new Error(\n      `Failed to decode SubRAV: ${error instanceof Error ? error.message : 'Unknown error'}`\n    );\n  }\n}\n\n/**\n * Get BCS hex representation of SubRAV (useful for debugging and contract calls)\n */\nexport function getSubRAVHex(subRav: SubRAV): string {\n  return SubRAVCodec.toHex(subRav);\n}\n","/**\n * SQL-based RAVRepository implementation for PostgreSQL/Supabase\n */\n\n// Note: 'pg' is an optional dependency. Install with: npm install pg @types/pg\nimport type { Pool, PoolClient } from 'pg';\nimport { encodeSubRAV, decodeSubRAV } from './serialization';\nimport type { RAVRepository } from '../interfaces/RAVRepository';\nimport type { SignedSubRAV } from '../../core/types';\n\nexport interface SqlRAVRepositoryOptions {\n  /** PostgreSQL connection pool */\n  pool: Pool;\n  /** Table name prefix (default: 'nuwa_') */\n  tablePrefix?: string;\n  /** Auto-create tables if they don't exist */\n  autoMigrate?: boolean;\n  /** Allow unsafe auto-migration in production */\n  allowUnsafeAutoMigrateInProd?: boolean;\n}\n\n/**\n * PostgreSQL/Supabase implementation of RAVRepository\n *\n * Compatible with both self-hosted Postgres and Supabase\n * Uses standard SQL that works across both platforms\n */\nexport class SqlRAVRepository implements RAVRepository {\n  private pool: Pool;\n  private tablePrefix: string;\n  private autoMigrate: boolean;\n  private allowUnsafeAutoMigrateInProd: boolean;\n\n  constructor(options: SqlRAVRepositoryOptions) {\n    this.pool = options.pool;\n    this.tablePrefix = options.tablePrefix || 'nuwa_';\n    this.autoMigrate = options.autoMigrate ?? true;\n    this.allowUnsafeAutoMigrateInProd = options.allowUnsafeAutoMigrateInProd ?? false;\n\n    // Only auto-migrate in development or when explicitly allowed in production\n    if (this.autoMigrate) {\n      if (process.env.NODE_ENV === 'production' && this.allowUnsafeAutoMigrateInProd) {\n        // Unsafe auto-migration in production – proceed only if explicitly allowed\n      } else if (process.env.NODE_ENV === 'production') {\n        throw new Error(\n          \"Auto-migration is disabled in production by default. To enable it, set 'allowUnsafeAutoMigrateInProd' to true \" +\n            'and acknowledge the risks.'\n        );\n      }\n      this.initialize().catch(() => {});\n    }\n  }\n\n  private get ravsTable(): string {\n    return `${this.tablePrefix}ravs`;\n  }\n\n  private get claimsTable(): string {\n    return `${this.tablePrefix}claims`;\n  }\n\n  /**\n   * Initialize database tables if they don't exist\n   */\n  async initialize(): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      // Create RAVs table\n      await client.query(`\n        CREATE TABLE IF NOT EXISTS ${this.ravsTable} (\n          id                SERIAL PRIMARY KEY,\n          channel_id        TEXT NOT NULL,\n          vm_id_fragment    TEXT NOT NULL,\n          nonce             NUMERIC(78,0) NOT NULL,\n          accumulated_amount NUMERIC(78,0) NOT NULL,\n          sub_rav_bcs       BYTEA NOT NULL,\n          signature         BYTEA NOT NULL,\n          created_at        TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n          UNIQUE(channel_id, vm_id_fragment, nonce)\n        )\n      `);\n\n      // Create index for efficient queries\n      await client.query(`\n        CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}ravs_channel \n        ON ${this.ravsTable}(channel_id)\n      `);\n\n      await client.query(`\n        CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}ravs_channel_vm \n        ON ${this.ravsTable}(channel_id, vm_id_fragment)\n      `);\n\n      // Create claims tracking table\n      await client.query(`\n        CREATE TABLE IF NOT EXISTS ${this.claimsTable} (\n          channel_id        TEXT NOT NULL,\n          vm_id_fragment    TEXT NOT NULL,\n          claimed_nonce     NUMERIC(78,0) NOT NULL,\n          claimed_at        TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n          tx_hash          TEXT,\n          PRIMARY KEY(channel_id, vm_id_fragment)\n        )\n      `);\n    } finally {\n      client.release();\n    }\n  }\n\n  async save(rav: SignedSubRAV): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      // Encode SubRAV using BCS serialization\n      const subRavBcs = encodeSubRAV(rav.subRav);\n      const signature = Buffer.from(rav.signature);\n\n      await client.query(\n        `\n        INSERT INTO ${this.ravsTable} \n        (channel_id, vm_id_fragment, nonce, accumulated_amount, sub_rav_bcs, signature)\n        VALUES ($1, $2, $3, $4, $5, $6)\n        ON CONFLICT (channel_id, vm_id_fragment, nonce) \n        DO NOTHING\n      `,\n        [\n          rav.subRav.channelId,\n          rav.subRav.vmIdFragment,\n          rav.subRav.nonce.toString(),\n          rav.subRav.accumulatedAmount.toString(),\n          subRavBcs,\n          signature,\n        ]\n      );\n    } finally {\n      client.release();\n    }\n  }\n\n  async get(channelId: string, vmIdFragment: string, nonce: bigint): Promise<SignedSubRAV | null> {\n    const client = await this.pool.connect();\n    try {\n      const result = await client.query(\n        `\n        SELECT sub_rav_bcs, signature \n        FROM ${this.ravsTable}\n        WHERE channel_id = $1 AND vm_id_fragment = $2 AND nonce = $3\n      `,\n        [channelId, vmIdFragment, nonce.toString()]\n      );\n\n      if (result.rows.length === 0) {\n        return null;\n      }\n\n      const subRavBcs = result.rows[0].sub_rav_bcs as Buffer;\n      const signature = result.rows[0].signature as Buffer;\n\n      const subRav = decodeSubRAV(subRavBcs);\n      return {\n        subRav,\n        signature: new Uint8Array(signature),\n      };\n    } finally {\n      client.release();\n    }\n  }\n\n  async getLatest(channelId: string, vmIdFragment: string): Promise<SignedSubRAV | null> {\n    const client = await this.pool.connect();\n    try {\n      const result = await client.query(\n        `\n        SELECT sub_rav_bcs, signature \n        FROM ${this.ravsTable}\n        WHERE channel_id = $1 AND vm_id_fragment = $2\n        ORDER BY nonce DESC\n        LIMIT 1\n      `,\n        [channelId, vmIdFragment]\n      );\n\n      if (result.rows.length === 0) {\n        return null;\n      }\n\n      const subRavBcs = result.rows[0].sub_rav_bcs as Buffer;\n      const signature = result.rows[0].signature as Buffer;\n\n      const subRav = decodeSubRAV(subRavBcs);\n      return {\n        subRav,\n        signature: new Uint8Array(signature),\n      };\n    } finally {\n      client.release();\n    }\n  }\n\n  async *list(channelId: string): AsyncIterable<SignedSubRAV> {\n    const client = await this.pool.connect();\n    try {\n      const result = await client.query(\n        `\n        SELECT sub_rav_bcs, signature\n        FROM ${this.ravsTable}\n        WHERE channel_id = $1\n        ORDER BY vm_id_fragment, nonce\n      `,\n        [channelId]\n      );\n\n      for (const row of result.rows) {\n        const subRavBcs = row.sub_rav_bcs as Buffer;\n        const signature = row.signature as Buffer;\n\n        const subRav = decodeSubRAV(subRavBcs);\n        yield {\n          subRav,\n          signature: new Uint8Array(signature),\n        };\n      }\n    } finally {\n      client.release();\n    }\n  }\n\n  async getUnclaimedRAVs(channelId: string): Promise<Map<string, SignedSubRAV>> {\n    const client = await this.pool.connect();\n    try {\n      const result = await client.query(\n        `\n        SELECT DISTINCT ON (r.vm_id_fragment) \n               r.vm_id_fragment, r.sub_rav_bcs, r.signature\n        FROM ${this.ravsTable} r\n        LEFT JOIN ${this.claimsTable} c \n          ON r.channel_id = c.channel_id \n          AND r.vm_id_fragment = c.vm_id_fragment\n        WHERE r.channel_id = $1 \n          AND (c.claimed_nonce IS NULL OR r.nonce > c.claimed_nonce)\n        ORDER BY r.vm_id_fragment, r.nonce DESC\n      `,\n        [channelId]\n      );\n\n      const unclaimedRAVs = new Map<string, SignedSubRAV>();\n\n      for (const row of result.rows) {\n        const subRavBcs = row.sub_rav_bcs as Buffer;\n        const signature = row.signature as Buffer;\n\n        const subRav = decodeSubRAV(subRavBcs);\n        const signedSubRAV = {\n          subRav,\n          signature: new Uint8Array(signature),\n        };\n\n        unclaimedRAVs.set(row.vm_id_fragment, signedSubRAV);\n      }\n\n      return unclaimedRAVs;\n    } finally {\n      client.release();\n    }\n  }\n\n  async markAsClaimed(channelId: string, vmIdFragment: string, nonce: bigint): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      await client.query(\n        `\n        INSERT INTO ${this.claimsTable} \n        (channel_id, vm_id_fragment, claimed_nonce)\n        VALUES ($1, $2, $3)\n        ON CONFLICT (channel_id, vm_id_fragment) \n        DO UPDATE SET \n          claimed_nonce = GREATEST(${this.claimsTable}.claimed_nonce, EXCLUDED.claimed_nonce),\n          claimed_at = NOW()\n      `,\n        [channelId, vmIdFragment, nonce.toString()]\n      );\n    } finally {\n      client.release();\n    }\n  }\n\n  async getStats(): Promise<{ totalRAVs: number; unclaimedRAVs: number }> {\n    const client = await this.pool.connect();\n    try {\n      // Get total RAVs count\n      const totalResult = await client.query(`\n        SELECT COUNT(*) as total_ravs FROM ${this.ravsTable}\n      `);\n      const totalRAVs = parseInt(totalResult.rows[0].total_ravs);\n\n      // Get unclaimed RAVs count (count distinct vm_id_fragments with unclaimed RAVs)\n      const unclaimedResult = await client.query(`\n        SELECT COUNT(DISTINCT r.vm_id_fragment) as unclaimed_ravs\n        FROM ${this.ravsTable} r\n        LEFT JOIN ${this.claimsTable} c \n          ON r.channel_id = c.channel_id \n          AND r.vm_id_fragment = c.vm_id_fragment\n        WHERE c.claimed_nonce IS NULL OR r.nonce > c.claimed_nonce\n      `);\n      const unclaimedRAVs = parseInt(unclaimedResult.rows[0].unclaimed_ravs);\n\n      return { totalRAVs, unclaimedRAVs };\n    } finally {\n      client.release();\n    }\n  }\n\n  async cleanup(): Promise<number> {\n    const client = await this.pool.connect();\n    try {\n      const result = await client.query(`\n        DELETE FROM ${this.ravsTable} r\n        WHERE EXISTS (\n          SELECT 1 FROM ${this.claimsTable} c\n          WHERE c.channel_id = r.channel_id \n            AND c.vm_id_fragment = r.vm_id_fragment\n            AND r.nonce <= c.claimed_nonce\n        )\n      `);\n\n      return result.rowCount || 0;\n    } finally {\n      client.release();\n    }\n  }\n}\n","/**\n * SQL-based PendingSubRAVRepository implementation for PostgreSQL/Supabase\n */\n\nimport type { Pool, PoolClient } from 'pg';\nimport { encodeSubRAV, decodeSubRAV } from './serialization';\nimport type { PendingSubRAVRepository } from '../interfaces/PendingSubRAVRepository';\nimport type { SubRAV } from '../../core/types';\nimport type { PendingSubRAVStats } from '../types/pagination';\n\nexport interface SqlPendingSubRAVRepositoryOptions {\n  /** PostgreSQL connection pool */\n  pool: Pool;\n  /** Table name prefix (default: 'nuwa_') */\n  tablePrefix?: string;\n  /** Auto-create tables if they don't exist */\n  autoMigrate?: boolean;\n  /** Allow unsafe auto-migration in production */\n  allowUnsafeAutoMigrateInProd?: boolean;\n}\n\n/**\n * PostgreSQL/Supabase implementation of PendingSubRAVRepository\n */\nexport class SqlPendingSubRAVRepository implements PendingSubRAVRepository {\n  private pool: Pool;\n  private tablePrefix: string;\n  private autoMigrate: boolean;\n  private allowUnsafeAutoMigrateInProd: boolean;\n\n  constructor(options: SqlPendingSubRAVRepositoryOptions) {\n    this.pool = options.pool;\n    this.tablePrefix = options.tablePrefix || 'nuwa_';\n    this.autoMigrate = options.autoMigrate ?? true;\n    this.allowUnsafeAutoMigrateInProd = options.allowUnsafeAutoMigrateInProd ?? false;\n\n    // Only auto-migrate in development or when explicitly allowed in production\n    if (\n      this.autoMigrate &&\n      (process.env.NODE_ENV !== 'production' || this.allowUnsafeAutoMigrateInProd)\n    ) {\n      this.initialize().catch(console.error);\n    }\n  }\n\n  private get pendingSubRAVsTable(): string {\n    return `${this.tablePrefix}pending_sub_ravs`;\n  }\n\n  /**\n   * Initialize database tables if they don't exist\n   */\n  async initialize(): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      // Create pending SubRAVs table\n      await client.query(`\n        CREATE TABLE IF NOT EXISTS ${this.pendingSubRAVsTable} (\n          channel_id        TEXT NOT NULL,\n          vm_id_fragment    TEXT NOT NULL,\n          nonce             NUMERIC(78,0) NOT NULL,\n          sub_rav_bcs       BYTEA NOT NULL,\n          created_at        TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n          PRIMARY KEY(channel_id, vm_id_fragment, nonce)\n        )\n      `);\n\n      // Create index for cleanup operations\n      await client.query(`\n        CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}pending_sub_ravs_created_at \n        ON ${this.pendingSubRAVsTable}(created_at)\n      `);\n      await client.query(`\n        CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}pending_sub_ravs_sub_channel \n        ON ${this.pendingSubRAVsTable}(channel_id, vm_id_fragment)\n      `);\n    } finally {\n      client.release();\n    }\n  }\n\n  async save(subRAV: SubRAV): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      // Encode SubRAV using BCS serialization\n      const subRavBcs = encodeSubRAV(subRAV);\n\n      await client.query(\n        `\n        INSERT INTO ${this.pendingSubRAVsTable} \n        (channel_id, vm_id_fragment, nonce, sub_rav_bcs)\n        VALUES ($1, $2, $3, $4)\n        ON CONFLICT (channel_id, vm_id_fragment, nonce) \n        DO UPDATE SET \n          sub_rav_bcs = EXCLUDED.sub_rav_bcs,\n          created_at = NOW()\n      `,\n        [subRAV.channelId, subRAV.vmIdFragment, subRAV.nonce.toString(), subRavBcs]\n      );\n    } finally {\n      client.release();\n    }\n  }\n\n  async find(channelId: string, vmIdFragment: string, nonce: bigint): Promise<SubRAV | null> {\n    const client = await this.pool.connect();\n    try {\n      const result = await client.query(\n        `\n        SELECT sub_rav_bcs \n        FROM ${this.pendingSubRAVsTable}\n        WHERE channel_id = $1 AND vm_id_fragment = $2 AND nonce = $3\n      `,\n        [channelId, vmIdFragment, nonce.toString()]\n      );\n\n      if (result.rows.length === 0) {\n        return null;\n      }\n\n      const subRavBcs = result.rows[0].sub_rav_bcs as Buffer;\n      return decodeSubRAV(subRavBcs);\n    } finally {\n      client.release();\n    }\n  }\n\n  async findLatestBySubChannel(channelId: string, vmIdFragment: string): Promise<SubRAV | null> {\n    const client = await this.pool.connect();\n    try {\n      const result = await client.query(\n        `\n        SELECT sub_rav_bcs \n        FROM ${this.pendingSubRAVsTable}\n        WHERE channel_id = $1 AND vm_id_fragment = $2\n        ORDER BY nonce DESC\n        LIMIT 1\n      `,\n        [channelId, vmIdFragment]\n      );\n\n      if (result.rows.length === 0) {\n        return null;\n      }\n\n      const subRavBcs = result.rows[0].sub_rav_bcs as Buffer;\n      return decodeSubRAV(subRavBcs);\n    } finally {\n      client.release();\n    }\n  }\n\n  async remove(channelId: string, vmIdFragment: string, nonce: bigint): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      await client.query(\n        `\n        DELETE FROM ${this.pendingSubRAVsTable} \n        WHERE channel_id = $1 AND vm_id_fragment = $2 AND nonce = $3\n      `,\n        [channelId, vmIdFragment, nonce.toString()]\n      );\n    } finally {\n      client.release();\n    }\n  }\n\n  /**\n   * Clean up expired pending SubRAVs\n   *\n   * Note: This method uses database server time (NOW()) instead of client time\n   * to avoid issues with time drift between client and database server.\n   * This ensures that cleanup works correctly even when client and server\n   * clocks are not perfectly synchronized.\n   *\n   * @param maxAgeMs Maximum age in milliseconds (default: 30 minutes)\n   * @returns Number of records deleted\n   */\n  async cleanup(maxAgeMs: number = 30 * 60 * 1000): Promise<number> {\n    const client = await this.pool.connect();\n    try {\n      // Use database server time to avoid client-server time drift issues\n      const result = await client.query(\n        `\n        DELETE FROM ${this.pendingSubRAVsTable} \n        WHERE created_at < NOW() - (make_interval(secs => $1 / 1000))\n      `,\n        [maxAgeMs]\n      );\n\n      return result.rowCount || 0;\n    } finally {\n      client.release();\n    }\n  }\n\n  async getStats(): Promise<PendingSubRAVStats> {\n    const client = await this.pool.connect();\n    try {\n      // Get total count\n      const totalResult = await client.query(`\n        SELECT COUNT(*) as total_count FROM ${this.pendingSubRAVsTable}\n      `);\n      const totalCount = parseInt(totalResult.rows[0].total_count);\n\n      // Get count by channel\n      const byChannelResult = await client.query(`\n        SELECT channel_id, COUNT(*) as count \n        FROM ${this.pendingSubRAVsTable}\n        GROUP BY channel_id\n      `);\n\n      const byChannel: Record<string, number> = {};\n      for (const row of byChannelResult.rows) {\n        byChannel[row.channel_id] = parseInt(row.count);\n      }\n\n      // Get oldest and newest timestamps\n      const timestampResult = await client.query(`\n        SELECT \n          MIN(EXTRACT(EPOCH FROM created_at) * 1000) as oldest,\n          MAX(EXTRACT(EPOCH FROM created_at) * 1000) as newest\n        FROM ${this.pendingSubRAVsTable}\n      `);\n\n      const oldestTimestamp = timestampResult.rows[0].oldest\n        ? parseInt(timestampResult.rows[0].oldest)\n        : undefined;\n      const newestTimestamp = timestampResult.rows[0].newest\n        ? parseInt(timestampResult.rows[0].newest)\n        : undefined;\n\n      return {\n        totalCount,\n        byChannel,\n        oldestTimestamp,\n        newestTimestamp,\n      };\n    } finally {\n      client.release();\n    }\n  }\n\n  async clear(): Promise<void> {\n    const client = await this.pool.connect();\n    try {\n      await client.query(`DELETE FROM ${this.pendingSubRAVsTable}`);\n    } finally {\n      client.release();\n    }\n  }\n}\n","export { SqlChannelRepository, type SqlChannelRepositoryOptions } from './channel.sql';\n\nexport { SqlRAVRepository, type SqlRAVRepositoryOptions } from './rav.sql';\n\nexport {\n  SqlPendingSubRAVRepository,\n  type SqlPendingSubRAVRepositoryOptions,\n} from './pendingSubRav.sql';\n\nexport { encodeSubRAV, decodeSubRAV, getSubRAVHex } from './serialization';\n\n// Node-only async factory to create repositories with a pg Pool loaded via dynamic import\nimport type { ChannelRepository } from '../interfaces/ChannelRepository';\nimport type { RAVRepository } from '../interfaces/RAVRepository';\nimport type { PendingSubRAVRepository } from '../interfaces/PendingSubRAVRepository';\nimport { SqlChannelRepository } from './channel.sql';\nimport { SqlRAVRepository } from './rav.sql';\nimport { SqlPendingSubRAVRepository } from './pendingSubRav.sql';\n\nexport async function createSqlStorageRepositories(options: {\n  connectionString: string;\n  tablePrefix?: string;\n  autoMigrate?: boolean;\n  allowUnsafeAutoMigrateInProd?: boolean;\n}): Promise<{\n  channelRepo: ChannelRepository;\n  ravRepo: RAVRepository;\n  pendingSubRAVRepo: PendingSubRAVRepository;\n}> {\n  const { connectionString, tablePrefix, autoMigrate, allowUnsafeAutoMigrateInProd } = options;\n  const { Pool } = await import('pg');\n  const isSupabase = connectionString.includes('supabase');\n  const pool = new Pool({\n    connectionString,\n    ssl: isSupabase ? { rejectUnauthorized: false } : false,\n  });\n\n  return {\n    channelRepo: new SqlChannelRepository({\n      pool,\n      tablePrefix,\n      autoMigrate,\n      allowUnsafeAutoMigrateInProd,\n    }),\n    ravRepo: new SqlRAVRepository({\n      pool,\n      tablePrefix,\n      autoMigrate,\n      allowUnsafeAutoMigrateInProd,\n    }),\n    pendingSubRAVRepo: new SqlPendingSubRAVRepository({\n      pool,\n      tablePrefix,\n      autoMigrate,\n      allowUnsafeAutoMigrateInProd,\n    }),\n  };\n}\n","// Node bundle entry: export isomorphic modules + Node-only modules\n\n// Isomorphic exports\nexport * from './index.browser';\n\n// Node-only: Express transport & API handlers\nexport * from './transport/express';\nexport * from './api';\n\n// Node-only: SQL storage aggregator (provided via subpath as well)\nexport * from './storage/sql';\n","// Browser bundle entry: export only isomorphic + browser-safe modules\n\n// Core types and utilities\nexport * from './core/types';\nexport * from './core/SubRav';\n// Legacy ClaimScheduler export removed in favor of reactive claims\nexport * from './core/PaymentProcessor';\nexport * from './core/PaymentUtils';\n\n// Contract interfaces\nexport * from './contracts/IPaymentChannelContract';\n\n// Chain-agnostic clients\nexport * from './client/PaymentChannelPayerClient';\nexport * from './client/PaymentChannelPayeeClient';\nexport * from './client/PaymentHubClient';\n\n// Factory for creating clients\nexport * from './factory/chainFactory';\n\n// HTTP codec and middleware (browser-safe parts)\nexport { HttpPaymentCodec } from './middlewares/http/HttpPaymentCodec';\nexport { HttpBillingMiddleware } from './middlewares/http/HttpBillingMiddleware';\n\n// Rooch implementation (rooch-sdk is browser-compatible)\nexport * from './rooch/RoochPaymentChannelContract';\n\n// HTTP Payer Client integration\nexport * from './integrations/http';\n\n// Storage: browser-safe exports (types, memory, IndexedDB, and factory)\nexport type {\n  TransactionStore,\n  TransactionRecord,\n  TransactionStatus,\n  PaymentSnapshot,\n} from './storage/interfaces/TransactionStore';\nexport { MemoryTransactionStore } from './storage/memory/transaction.memory';\nexport { IndexedDBTransactionStore } from './storage/indexeddb/transactions.indexeddb';\nexport {\n  createTransactionStore,\n  type TransactionStoreOptions,\n} from './storage/factories/createTransactionStore';\n\n// Framework-agnostic API types and errors (data-only)\nexport * from './types/api';\nexport * from './errors';\n\n// Zod schemas for validation and serialization (core/api)\nexport {\n  PersistedHttpClientStateSchema,\n  ServiceDiscoverySchema,\n  SystemStatusSchema,\n  ClaimTriggerRequestSchema,\n  ClaimTriggerResponseSchema,\n  RecoveryRequestSchema,\n  RecoveryResponseSchema,\n  CommitRequestSchema,\n  CommitResponseSchema,\n  HealthRequestSchema,\n  HealthResponseSchema,\n  SubRavRequestSchema,\n  SubRavResponseSchema,\n  AdminRequestSchema,\n  SystemStatusResponseSchema,\n  DiscoveryRequestSchema,\n  DiscoveryResponseSchema,\n} from './schema';\n\n// Utilities\nexport {\n  generateNonce,\n  extractFragment,\n  isValidHex,\n  formatAmount,\n  generateChannelId,\n  bigintToString,\n  stringToBigint,\n  formatUsdAmount,\n  DebugLogger,\n} from './utils';\n\n// IdentityEnv helpers\nexport { getChainConfigFromEnv } from './helpers/fromIdentityEnv';\n","export enum PaymentErrorCode {\n  // Auth\n  AUTH_MISSING = 'AUTH_MISSING',\n  AUTH_INVALID = 'AUTH_INVALID',\n  AUTH_ADMIN_FORBIDDEN = 'AUTH_ADMIN_FORBIDDEN',\n  DID_RESOLVE_FAILED = 'DID_RESOLVE_FAILED',\n\n  // Channel\n  CHANNEL_NOT_FOUND = 'CHANNEL_NOT_FOUND',\n  SUBCHANNEL_NOT_AUTHORIZED = 'SUBCHANNEL_NOT_AUTHORIZED',\n  CHANNEL_CONTEXT_MISSING = 'CHANNEL_CONTEXT_MISSING',\n\n  // RAV/SubRAV\n  PAYMENT_REQUIRED = 'PAYMENT_REQUIRED',\n  RAV_CONFLICT = 'RAV_CONFLICT',\n  INVALID_SIGNATURE = 'INVALID_SIGNATURE',\n  UNKNOWN_SUBRAV = 'UNKNOWN_SUBRAV',\n  TAMPERED_SUBRAV = 'TAMPERED_SUBRAV',\n\n  // Billing/Rate\n  BILLING_RATE_FETCH_FAILED = 'BILLING_RATE_FETCH_FAILED',\n  BILLING_RATE_NOT_AVAILABLE = 'BILLING_RATE_NOT_AVAILABLE',\n  BILLING_MAX_AMOUNT_EXCEEDED = 'BILLING_MAX_AMOUNT_EXCEEDED',\n  BILLING_CONFIG_ERROR = 'BILLING_CONFIG_ERROR',\n\n  // Hub Balance\n  HUB_INSUFFICIENT_FUNDS = 'HUB_INSUFFICIENT_FUNDS',\n  HUB_BALANCE_FETCH_FAILED = 'HUB_BALANCE_FETCH_FAILED',\n\n  // Channel state\n  CHANNEL_CLOSED = 'CHANNEL_CLOSED',\n  EPOCH_MISMATCH = 'EPOCH_MISMATCH',\n\n  // Internal\n  INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR',\n}\n\nexport interface PaymentError {\n  code: PaymentErrorCode;\n  message: string;\n  details?: Record<string, unknown>;\n}\n\nexport function httpStatusFor(code?: PaymentErrorCode | string): number {\n  switch (code as PaymentErrorCode) {\n    case PaymentErrorCode.PAYMENT_REQUIRED:\n    case PaymentErrorCode.HUB_INSUFFICIENT_FUNDS:\n      return 402;\n    case PaymentErrorCode.RAV_CONFLICT:\n    case PaymentErrorCode.CHANNEL_CONTEXT_MISSING:\n      return 409;\n\n    case PaymentErrorCode.INVALID_SIGNATURE:\n    case PaymentErrorCode.UNKNOWN_SUBRAV:\n    case PaymentErrorCode.TAMPERED_SUBRAV:\n    case PaymentErrorCode.CHANNEL_CLOSED:\n    case PaymentErrorCode.EPOCH_MISMATCH:\n    case PaymentErrorCode.BILLING_MAX_AMOUNT_EXCEEDED:\n    case PaymentErrorCode.AUTH_MISSING:\n    case PaymentErrorCode.AUTH_INVALID:\n    case PaymentErrorCode.AUTH_ADMIN_FORBIDDEN:\n    case PaymentErrorCode.DID_RESOLVE_FAILED:\n      return 400;\n\n    case PaymentErrorCode.CHANNEL_NOT_FOUND:\n    case PaymentErrorCode.SUBCHANNEL_NOT_AUTHORIZED:\n      return 404;\n\n    case PaymentErrorCode.BILLING_RATE_NOT_AVAILABLE:\n    case PaymentErrorCode.BILLING_RATE_FETCH_FAILED:\n    case PaymentErrorCode.BILLING_CONFIG_ERROR:\n    case PaymentErrorCode.HUB_BALANCE_FETCH_FAILED:\n    default:\n      return 500;\n  }\n}\n\nexport const Errors = {\n  paymentRequired: (msg?: string): PaymentError => ({\n    code: PaymentErrorCode.PAYMENT_REQUIRED,\n    message: msg ?? 'Signature required for pending proposal',\n  }),\n  ravConflict: (msg: string): PaymentError => ({\n    code: PaymentErrorCode.RAV_CONFLICT,\n    message: msg,\n  }),\n  channelContextMissing: (): PaymentError => ({\n    code: PaymentErrorCode.CHANNEL_CONTEXT_MISSING,\n    message: 'channelId or vmIdFragment not derivable. Check DID authentication.',\n  }),\n  channelNotFound: (id: string): PaymentError => ({\n    code: PaymentErrorCode.CHANNEL_NOT_FOUND,\n    message: `CHANNEL_NOT_FOUND: ${id}`,\n  }),\n  subchannelNotAuthorized: (id: string, vm: string): PaymentError => ({\n    code: PaymentErrorCode.SUBCHANNEL_NOT_AUTHORIZED,\n    message: `SUBCHANNEL_NOT_AUTHORIZED: ${id}#${vm}`,\n  }),\n  didResolveFailed: (did: string): PaymentError => ({\n    code: PaymentErrorCode.DID_RESOLVE_FAILED,\n    message: `DID_RESOLVE_FAILED: ${did}`,\n  }),\n  rateFetchFailed: (e: unknown): PaymentError => ({\n    code: PaymentErrorCode.BILLING_RATE_FETCH_FAILED,\n    message: String(e),\n  }),\n  rateNotAvailable: (assetId: string): PaymentError => ({\n    code: PaymentErrorCode.BILLING_RATE_NOT_AVAILABLE,\n    message: `Missing exchange rate for asset ${assetId}`,\n  }),\n  maxAmountExceeded: (finalCost: bigint, max: bigint): PaymentError => ({\n    code: PaymentErrorCode.BILLING_MAX_AMOUNT_EXCEEDED,\n    message: `Cost ${finalCost} exceeds maxAmount ${max}`,\n    details: { finalCost: finalCost.toString(), max: max.toString() },\n  }),\n  internal: (msg: string): PaymentError => ({\n    code: PaymentErrorCode.INTERNAL_SERVER_ERROR,\n    message: msg,\n  }),\n  hubInsufficientFunds: (balance: bigint, required: bigint, assetId: string): PaymentError => ({\n    code: PaymentErrorCode.HUB_INSUFFICIENT_FUNDS,\n    message: `PaymentHub balance insufficient: ${balance}, required: ${required} for asset ${assetId}`,\n    details: { balance: balance.toString(), required: required.toString(), assetId },\n  }),\n  hubBalanceFetchFailed: (error: unknown, ownerDid: string, assetId: string): PaymentError => ({\n    code: PaymentErrorCode.HUB_BALANCE_FETCH_FAILED,\n    message: `Failed to fetch PaymentHub balance for ${ownerDid}#${assetId}: ${String(error)}`,\n    details: { ownerDid, assetId, error: String(error) },\n  }),\n} as const;\n","import type { SignedSubRAV, SubChannelInfo, SubRAV } from './types';\nimport { PaymentChannelPayeeClient } from '../client/PaymentChannelPayeeClient';\nimport type { VerificationResult } from '../client/PaymentChannelPayeeClient';\nimport type { BillingContext } from '../billing';\nimport { Errors, type PaymentError } from '../errors/codes';\nimport { getStrategy } from '../billing/core/strategy-registry';\nimport { convertUsdToAssetUsingPrice } from '../billing/core/converter';\nimport type { RateProvider, RateResult } from '../billing/rate/types';\n// Ensure built-in strategies are registered explicitly (no side-effect import)\nimport { registerBuiltinStrategies } from '../billing/strategies';\nimport type { PendingSubRAVRepository } from '../storage/interfaces/PendingSubRAVRepository';\nimport type { RAVRepository } from '../storage/interfaces/RAVRepository';\nimport { createPendingSubRAVRepo } from '../storage/factories/createPendingSubRAVRepo';\nimport { HttpPaymentCodec } from '../middlewares/http/HttpPaymentCodec';\nimport { PaymentUtils } from './PaymentUtils';\nimport { deriveChannelId } from '../rooch/ChannelUtils';\nimport { verify as verifyRav } from './RavVerifier';\nimport type { DIDResolver } from '@nuwa-ai/identity-kit';\nimport { DebugLogger } from '@nuwa-ai/identity-kit';\nimport type { HubBalanceService } from './HubBalanceService';\nimport type { ClaimTriggerService } from './ClaimTriggerService';\n\n/**\n * Configuration for PaymentProcessor\n */\nexport interface PaymentProcessorConfig {\n  /** Payee client for payment operations */\n  payeeClient: PaymentChannelPayeeClient;\n\n  /** Service ID for billing configuration */\n  serviceId: string;\n\n  /** Rate provider for asset conversion */\n  rateProvider: RateProvider;\n\n  /** DID resolver used for signature verification (avoid accessing payeeClient internals) */\n  didResolver: DIDResolver;\n\n  /** Store for pending unsigned SubRAV proposals */\n  pendingSubRAVStore: PendingSubRAVRepository;\n  /** Repository for persisted SignedSubRAVs to retrieve latest baseline */\n  ravRepository: RAVRepository;\n\n  /** Default asset ID if not provided in request context */\n  defaultAssetId?: string;\n\n  /** Hub balance service for payer balance checks */\n  hubBalanceService: HubBalanceService;\n\n  /** Claim trigger service for reactive claims (optional) */\n  claimTriggerService?: ClaimTriggerService;\n\n  /** Minimum claim amount threshold */\n  minClaimAmount: bigint;\n\n  /** Debug logging */\n  debug?: boolean;\n}\n\n/**\n * Enhanced verification result with payer key ID\n */\nexport interface PaymentVerificationResult extends VerificationResult {\n  payerKeyId?: string;\n}\n\n/**\n * Payment processing statistics\n */\nexport interface PaymentProcessingStats {\n  totalRequests: number;\n  successfulPayments: number;\n  failedPayments: number;\n  autoClaimsTriggered: number;\n}\n\n// Strongly typed non-null state after preProcess\ntype PaymentState = NonNullable<BillingContext['state']>;\ntype PreprocessedBillingContext = BillingContext & { state: PaymentState };\n\n// Use centralized error factories from errors/codes\n\n/**\n * PaymentProcessor - Protocol-agnostic payment negotiation component\n *\n * This component handles the core payment logic that can be reused across\n * different protocols (HTTP, MCP, A2A, etc.) by abstracting away protocol-specific\n * details and focusing on the deferred payment model implementation.\n */\nexport class PaymentProcessor {\n  private config: PaymentProcessorConfig;\n  private pendingSubRAVStore: PendingSubRAVRepository;\n  private ravRepository: RAVRepository;\n  private stats: PaymentProcessingStats;\n  private logger: DebugLogger;\n\n  constructor(config: PaymentProcessorConfig) {\n    this.config = config;\n    // Register built-in billing strategies explicitly\n    try {\n      registerBuiltinStrategies();\n    } catch {}\n    this.pendingSubRAVStore = config.pendingSubRAVStore;\n    this.ravRepository = config.ravRepository;\n    this.stats = {\n      totalRequests: 0,\n      successfulPayments: 0,\n      failedPayments: 0,\n      autoClaimsTriggered: 0,\n    };\n\n    this.logger = DebugLogger.get('PaymentProcessor');\n    this.logger.setLevel(config.debug ? 'debug' : 'info');\n  }\n\n  getServiceId(): string {\n    return this.config.serviceId;\n  }\n\n  /**\n   * Step A: Pre-process request - complete all I/O operations and verification\n   * Returns context with state populated for both pre-flight and post-flight\n   */\n  async preProcess(ctx: BillingContext): Promise<PreprocessedBillingContext> {\n    this.stats.totalRequests++;\n\n    this.log('Pre-processing payment for operation:', ctx.meta.operation);\n\n    const pctx = this.asPreprocessed(ctx);\n\n    try {\n      const rule = pctx.meta.billingRule;\n      // For free routes without a SignedSubRAV, skip verification entirely in preProcess\n      if (rule && rule.paymentRequired === false && !pctx.meta.signedSubRav) {\n        this.log('Free route without SignedSubRAV - skipping preProcess verification');\n        return pctx;\n      }\n      // Step 0: Prefetch channel context (channelInfo, baseline, chainId)\n      // Determine channelId and vmIdFragment (must exist)\n      let channelId: string | undefined;\n      let vmIdFragment: string | undefined;\n\n      if (ctx.meta.signedSubRav) {\n        channelId = ctx.meta.signedSubRav.subRav.channelId;\n        vmIdFragment = ctx.meta.signedSubRav.subRav.vmIdFragment;\n      } else {\n        const didAuth = await this.tryDIDAuthFallback(ctx);\n        if (didAuth) {\n          channelId = didAuth.channelId;\n          vmIdFragment = didAuth.vmIdFragment;\n        }\n      }\n\n      if (!channelId || !vmIdFragment) {\n        return this.fail(pctx, Errors.channelContextMissing(), { attachHeader: false });\n      }\n\n      // Fetch channelInfo (must exist)\n      const channelInfo = await this.config.payeeClient.getChannelInfo(channelId);\n      if (!channelInfo) {\n        return this.fail(pctx, Errors.channelNotFound(channelId), { attachHeader: false });\n      }\n\n      const subChannelInfo = await this.config.payeeClient.getSubChannelState(\n        channelId,\n        vmIdFragment\n      );\n      if (!subChannelInfo) {\n        return this.fail(pctx, Errors.subchannelNotAuthorized(channelId, vmIdFragment), {\n          attachHeader: false,\n        });\n      }\n\n      // Latest signed RAV from repository\n      const latestSignedSubRav = await this.ravRepository.getLatest(channelId, vmIdFragment);\n\n      // Fetch and cache chainId for proposal generation\n      pctx.state.chainId = await this.config.payeeClient.getContract().getChainId();\n\n      const payerDidDoc = await this.config.didResolver.resolveDID(channelInfo.payerDid);\n      if (!payerDidDoc) {\n        return this.fail(pctx, Errors.didResolveFailed(channelInfo.payerDid), {\n          attachHeader: false,\n        });\n      }\n      // Latest pending SubRAV from pending repository\n      const latestPendingSubRav = await this.pendingSubRAVStore.findLatestBySubChannel(\n        channelId,\n        vmIdFragment\n      );\n\n      // Single-entry verification using prefetched context\n      const ravResult = await verifyRav({\n        channelInfo,\n        subChannelInfo,\n        billingRule: ctx.meta.billingRule!,\n        payerDidDoc,\n        signedSubRav: ctx.meta.signedSubRav,\n        latestSignedSubRav: latestSignedSubRav || undefined,\n        latestPendingSubRav: latestPendingSubRav || undefined,\n        debug: this.config.debug,\n      });\n\n      pctx.state.channelInfo = channelInfo;\n      pctx.state.subChannelInfo = subChannelInfo;\n      pctx.state.latestSignedSubRav = latestSignedSubRav || undefined;\n      pctx.state.latestPendingSubRav = latestPendingSubRav || undefined;\n\n      try {\n        const hubBalance = await this.config.hubBalanceService.getBalance(\n          channelInfo.payerDid,\n          channelInfo.assetId\n        );\n\n        // Compute outstanding withdrawable delta based on latest signed vs last claimed\n        const latestAccumulatedForDelta =\n          (latestSignedSubRav?.subRav?.accumulatedAmount as bigint | undefined) ??\n          subChannelInfo.lastClaimedAmount;\n        const lastClaimedAmount = subChannelInfo.lastClaimedAmount;\n        const deltaOutstanding =\n          latestAccumulatedForDelta > lastClaimedAmount\n            ? latestAccumulatedForDelta - lastClaimedAmount\n            : 0n;\n\n        this.log('Hub balance check (cached)', {\n          payerDid: channelInfo.payerDid,\n          assetId: channelInfo.assetId,\n          cachedBalance: hubBalance.toString(),\n          minClaimAmount: this.config.minClaimAmount.toString(),\n          deltaOutstanding: deltaOutstanding.toString(),\n          sufficient: hubBalance >= this.config.minClaimAmount && hubBalance >= deltaOutstanding,\n          source: 'HubBalanceService_cache',\n        });\n\n        // If withdrawable delta already crosses threshold but hub balance is insufficient, block with 402\n        if (deltaOutstanding >= this.config.minClaimAmount && hubBalance < deltaOutstanding) {\n          this.log('❌ Hub balance insufficient for outstanding delta - rejecting request', {\n            payerDid: channelInfo.payerDid,\n            assetId: channelInfo.assetId,\n            cachedBalance: hubBalance.toString(),\n            deltaOutstanding: deltaOutstanding.toString(),\n          });\n\n          return this.fail(\n            pctx,\n            Errors.hubInsufficientFunds(hubBalance, deltaOutstanding, channelInfo.assetId),\n            { attachHeader: true }\n          );\n        }\n\n        if (hubBalance < this.config.minClaimAmount) {\n          this.log('❌ Hub balance insufficient - rejecting request', {\n            payerDid: channelInfo.payerDid,\n            assetId: channelInfo.assetId,\n            cachedBalance: hubBalance.toString(),\n            minClaimAmount: this.config.minClaimAmount.toString(),\n            deficit: (this.config.minClaimAmount - hubBalance).toString(),\n          });\n\n          return this.fail(\n            pctx,\n            Errors.hubInsufficientFunds(\n              hubBalance,\n              this.config.minClaimAmount,\n              channelInfo.assetId\n            ),\n            { attachHeader: true }\n          );\n        }\n      } catch (error) {\n        this.log('⚠️ Hub balance check failed - proceeding anyway', {\n          payerDid: channelInfo.payerDid,\n          assetId: channelInfo.assetId,\n          error: error instanceof Error ? error.message : String(error),\n          source: 'HubBalanceService_cache',\n        });\n        // Don't fail the request on balance fetch errors - let it proceed\n        // The claim will fail later if balance is actually insufficient\n      }\n\n      // Handle early-return decisions\n      if (ravResult.decision === 'REQUIRE_SIGNATURE_402' || ravResult.decision === 'CONFLICT') {\n        this.log(\n          '⚠️ Early return from preProcess due to decision:',\n          ravResult.decision,\n          ravResult.error\n        );\n        return this.fail(\n          pctx,\n          {\n            code: (ravResult.error?.code as PaymentError['code']) ?? 'INTERNAL_SERVER_ERROR',\n            message: ravResult.error?.message ?? 'Verification decision error',\n          },\n          { attachHeader: false }\n        );\n      }\n\n      // Persist verification flags and apply side-effects on success\n      pctx.state.signedSubRavVerified = ravResult.signedVerified;\n      if (ravResult.signedVerified && pctx.meta.signedSubRav) {\n        this.log('🗑️ Removing matched pending SubRAV and persisting verified SignedSubRAV:', {\n          channelId: pctx.meta.signedSubRav.subRav.channelId,\n          vmIdFragment: pctx.meta.signedSubRav.subRav.vmIdFragment,\n          nonce: pctx.meta.signedSubRav.subRav.nonce.toString(),\n        });\n        if (ravResult.pendingMatched) {\n          try {\n            await this.pendingSubRAVStore.remove(\n              pctx.meta.signedSubRav.subRav.channelId,\n              pctx.meta.signedSubRav.subRav.vmIdFragment,\n              pctx.meta.signedSubRav.subRav.nonce\n            );\n          } catch (e) {\n            this.log('⚠️ Failed to remove matched pending:', e);\n          }\n        }\n        try {\n          await this.ravRepository.save(pctx.meta.signedSubRav);\n        } catch (e) {\n          this.log('⚠️ Failed to persist verified SignedSubRAV:', e);\n        }\n      }\n\n      const assetId = channelInfo.assetId;\n      // Step 3: Prefetch exchange rate only (no cost calculation here)\n      {\n        try {\n          const price = await this.config.rateProvider.getPricePicoUSD(assetId);\n          const timestamp = this.config.rateProvider.getLastUpdated(assetId) ?? Date.now();\n          const exchangeRate: RateResult = {\n            price,\n            timestamp,\n            provider: 'rate-provider',\n            assetId,\n          };\n          pctx.state.exchangeRate = exchangeRate;\n        } catch (e) {\n          pctx.state.error = Errors.rateFetchFailed(e);\n        }\n      }\n\n      this.log('✅ Pre-processing completed');\n      return pctx;\n    } catch (error) {\n      this.log('🚨 Pre-processing error:', error);\n      pctx.state.signedSubRavVerified = false;\n      return this.fail(pctx, Errors.internal(String(error)), {\n        attachHeader: false,\n      });\n    }\n  }\n\n  getPendingSubRAVRepository(): PendingSubRAVRepository {\n    return this.pendingSubRAVStore;\n  }\n\n  /**\n   * Step B & C: Settle billing - lightweight synchronous operations only\n   * For Pre-flight: essentially no-op (already completed in preProcess)\n   * For Post-flight: calculate cost based on usage and generate header\n   */\n  // Overloads to allow external call sites to pass BillingContext while we enforce state internally\n  settle(ctx: PreprocessedBillingContext, units?: number): PreprocessedBillingContext;\n  settle(ctx: BillingContext, units?: number): BillingContext;\n  settle(\n    ctx: BillingContext | PreprocessedBillingContext,\n    units?: number\n  ): BillingContext | PreprocessedBillingContext {\n    this.log('🔄 Settling billing with units:', units);\n\n    const pctx = this.asPreprocessed(ctx as BillingContext);\n\n    // Settling uses numeric units; no structured usage is attached to state\n\n    try {\n      const rule = pctx.meta.billingRule;\n\n      // If a protocol-level error was set during preProcess or earlier, generate error header now\n      if (pctx.state.error) {\n        return this.fail(pctx, pctx.state.error);\n      }\n\n      // Unified synchronous calculation for both pre-flight and post-flight\n      if (rule) {\n        this.log(\n          '📊 Processing billing rule:',\n          rule.id,\n          'paymentRequired:',\n          rule.paymentRequired,\n          'units:',\n          units\n        );\n        const usageUnits =\n          Number.isFinite(units) && (units as number) >= 0 ? Math.floor(units as number) : 0;\n\n        const strategy = getStrategy(rule);\n        const usdCost = strategy.evaluate(pctx, usageUnits);\n\n        // Convert to asset units only when needed\n        let finalCost = usdCost;\n        // Free routes: don't require channel context or exchange rate\n        if (rule.paymentRequired !== false) {\n          if (usdCost > 0n) {\n            const assetId = pctx.state?.channelInfo?.assetId;\n            if (!assetId) {\n              throw new Error('CHANNEL_INFO_MISSING: assetId not derivable. Check channelInfo.');\n            }\n            const rate = pctx.state.exchangeRate;\n            if (!rate) {\n              return this.fail(pctx, Errors.rateNotAvailable(String(assetId)));\n            }\n            const conversion = convertUsdToAssetUsingPrice(usdCost, rate);\n            finalCost = conversion.assetCost;\n          } else {\n            // Zero-cost paid route still generates SubRAV; cost stays 0\n            finalCost = 0n;\n          }\n        } else {\n          // Free route: ensure cost is zero regardless of USD price\n          finalCost = 0n;\n        }\n\n        pctx.state.cost = finalCost;\n\n        // Check maxAmount limit\n        if (pctx.meta.maxAmount && pctx.meta.maxAmount > 0n && finalCost > pctx.meta.maxAmount) {\n          this.log(`Cost ${finalCost} exceeds maxAmount ${pctx.meta.maxAmount}`);\n          return this.fail(pctx, Errors.maxAmountExceeded(finalCost, pctx.meta.maxAmount));\n        }\n\n        // Special handling for free routes (§4.3 of rav-handling.md)\n        if (rule.paymentRequired === false) {\n          // Free route: if client sent SignedSubRAV, verify but don't generate unsigned\n          if (pctx.meta.signedSubRav && finalCost === 0n) {\n            this.log(\n              '📝 Free route with SignedSubRAV - verified but not generating unsigned SubRAV'\n            );\n            // Set minimal response state for free routes\n            pctx.state.cost = finalCost;\n            // Don't generate unsignedSubRav or headerValue for free routes\n          } else if (pctx.meta.signedSubRav && finalCost > 0n) {\n            // This shouldn't happen - free routes should have cost=0\n            throw new Error('FREE_ROUTE_WITH_COST: free routes should have cost=0');\n          } else {\n            // Free route without SignedSubRAV - normal free processing\n            this.log('📝 Free route without SignedSubRAV - no payment processing needed');\n            pctx.state.cost = finalCost;\n          }\n        } else {\n          // Paid route: always generate SubRAV and header (even if cost=0 per §4.2)\n          // Require a baseline: SignedSubRAV, latestSignedSubRav, or subChannelInfo\n          const hasSigned = !!pctx.meta.signedSubRav;\n          const hasLatest = !!pctx.state && !!pctx.state.latestSignedSubRav;\n          const hasSubState = !!pctx.state && !!(pctx.state as any).subChannelInfo;\n\n          this.log('🔍 Baseline check:', {\n            hasSigned,\n            hasLatest,\n            hasSubState,\n            hasState: !!pctx.state,\n            stateKeys: pctx.state ? Object.keys(pctx.state) : [],\n          });\n\n          if (!hasSigned && !hasLatest && !hasSubState) {\n            return this.fail(pctx, Errors.channelContextMissing());\n          }\n\n          this.log('🔧 Generating SubRAV with finalCost:', finalCost);\n          const { unsignedSubRAV, serviceTxRef, headerValue } = this.generateNextSubRAV({\n            signedSubRAV: pctx.meta.signedSubRav,\n            latestSignedSubRav: pctx.state?.latestSignedSubRav,\n            subChannelInfo: pctx.state?.subChannelInfo!,\n            chainId: pctx.state?.chainId!,\n            clientTxRef: pctx.meta.clientTxRef,\n            cost: finalCost,\n            costUsd: usdCost,\n          });\n          this.log('🔧 Generated SubRAV:', {\n            nonce: unsignedSubRAV.nonce,\n            accumulatedAmount: unsignedSubRAV.accumulatedAmount,\n            headerValue: !!headerValue,\n          });\n          pctx.state.unsignedSubRav = unsignedSubRAV;\n          pctx.state.serviceTxRef = serviceTxRef;\n          pctx.state.nonce = unsignedSubRAV.nonce;\n          pctx.state.headerValue = headerValue;\n        }\n\n        this.log('✅ Billing settled successfully');\n      }\n\n      return pctx as typeof ctx;\n    } catch (error) {\n      this.log('🚨 Billing settlement error:', error);\n      const p = this.asPreprocessed(ctx as BillingContext);\n      p.state.cost = 0n;\n      return this.fail(p, Errors.internal(String(error)));\n    }\n  }\n\n  /**\n   * Step D: Persist billing state to storage\n   */\n  async persist(ctx: PreprocessedBillingContext): Promise<void>;\n  async persist(ctx: BillingContext): Promise<void>;\n  async persist(ctx: BillingContext | PreprocessedBillingContext): Promise<void> {\n    const pctx = this.asPreprocessed(ctx as BillingContext);\n    if (!pctx.state?.unsignedSubRav) {\n      this.log('⚠️ No unsignedSubRAV to persist');\n      return;\n    }\n\n    try {\n      this.log('💾 Persisting billing state');\n\n      const newSubRAV = pctx.state.unsignedSubRav;\n\n      // the previous pending SubRAV is removed in the preProcess step.\n      // Clean up previous pending SubRAV (nonce - 1) to prevent accumulation\n      // if (newSubRAV.nonce > 1n) {\n      //   const prevNonce = newSubRAV.nonce - 1n;\n      //   try {\n      //     await this.pendingSubRAVStore.remove(\n      //       newSubRAV.channelId,\n      //       newSubRAV.vmIdFragment,\n      //       prevNonce\n      //     );\n      //     this.log('🗑️ Removed previous pending SubRAV:', {\n      //       channelId: newSubRAV.channelId,\n      //       nonce: prevNonce.toString(),\n      //     });\n      //   } catch (error) {\n      //     this.log('⚠️ Failed to remove previous pending SubRAV:', error);\n      //     // Don't fail the entire operation for cleanup errors\n      //   }\n      // }\n\n      // Store the new unsigned SubRAV for future verification\n      await this.pendingSubRAVStore.save(newSubRAV);\n\n      // Mark as persisted\n      pctx.state.persisted = true;\n\n      // Trigger reactive claim if enabled and conditions are met\n      if (\n        this.config.claimTriggerService &&\n        this.config.minClaimAmount &&\n        pctx.state.subChannelInfo &&\n        pctx.state.latestSignedSubRav\n      ) {\n        try {\n          // Calculate delta: latest signed accumulated amount - last claimed amount\n          const latestAccumulated = pctx.state.latestSignedSubRav.subRav.accumulatedAmount;\n          const lastClaimed = pctx.state.subChannelInfo.lastClaimedAmount;\n          const delta = latestAccumulated > lastClaimed ? latestAccumulated - lastClaimed : 0n;\n\n          this.log('Reactive claim evaluation', {\n            channelId: newSubRAV.channelId,\n            vmIdFragment: newSubRAV.vmIdFragment,\n            latestAccumulated: latestAccumulated.toString(),\n            lastClaimed: lastClaimed.toString(),\n            delta: delta.toString(),\n            minClaimAmount: this.config.minClaimAmount.toString(),\n          });\n\n          if (delta >= this.config.minClaimAmount) {\n            await this.config.claimTriggerService.maybeQueue(\n              newSubRAV.channelId,\n              newSubRAV.vmIdFragment,\n              delta\n            );\n            this.log('Reactive claim queued', {\n              channelId: newSubRAV.channelId,\n              vmIdFragment: newSubRAV.vmIdFragment,\n              delta: delta.toString(),\n            });\n          }\n        } catch (error) {\n          this.log('⚠️ Reactive claim trigger failed', { error });\n          // Don't fail the persist operation for claim trigger errors\n        }\n      }\n\n      this.log('✅ Billing state persisted successfully');\n    } catch (error) {\n      this.log('🚨 Persistence error:', error);\n      throw error;\n    }\n  }\n\n  /**\n   * Clear expired pending SubRAV proposals\n   */\n  async clearExpiredProposals(maxAgeMinutes: number = 30): Promise<number> {\n    const maxAge = maxAgeMinutes * 60 * 1000; // Convert to milliseconds\n    const clearedCount = await this.pendingSubRAVStore.cleanup(maxAge);\n\n    this.log(\n      `Cleared ${clearedCount} expired pending SubRAV proposals (older than ${maxAgeMinutes} minutes)`\n    );\n    return clearedCount;\n  }\n\n  /**\n   * Get payment processing statistics\n   */\n  getProcessingStats(): PaymentProcessingStats {\n    return { ...this.stats };\n  }\n\n  /**\n   * Find pending SubRAV proposal by channel and nonce\n   */\n  async findPendingProposal(\n    channelId: string,\n    vmIdFragment: string,\n    nonce: bigint\n  ): Promise<SubRAV | null> {\n    return await this.pendingSubRAVStore.find(channelId, vmIdFragment, nonce);\n  }\n\n  /**\n   * Find the latest pending SubRAV proposal for a channel (for recovery scenarios)\n   */\n  async findLatestPendingProposal(channelId: string, vmIdFragment: string): Promise<SubRAV | null> {\n    return await this.pendingSubRAVStore.findLatestBySubChannel(channelId, vmIdFragment);\n  }\n\n  /**\n   * Generate SubRAV and header synchronously for post-flight billing\n   */\n  private generateNextSubRAV(params: {\n    signedSubRAV?: SignedSubRAV;\n    latestSignedSubRav?: SignedSubRAV;\n    subChannelInfo: SubChannelInfo;\n    chainId: bigint;\n    clientTxRef: string;\n    cost: bigint;\n    costUsd: bigint;\n  }): {\n    unsignedSubRAV: SubRAV;\n    serviceTxRef: string;\n    headerValue: string;\n  } {\n    const serviceTxRef = `srv-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n    const current = params.signedSubRAV?.subRav ??\n      params.latestSignedSubRav?.subRav ?? {\n        channelId: params.subChannelInfo.channelId,\n        vmIdFragment: params.subChannelInfo.vmIdFragment,\n        nonce: params.subChannelInfo.lastConfirmedNonce,\n        accumulatedAmount: params.subChannelInfo.lastClaimedAmount,\n        chainId: params.chainId,\n        channelEpoch: params.subChannelInfo.epoch,\n        version: 1,\n      };\n\n    const next = this.buildNextUnsigned(current, params.cost);\n\n    // Generate header using HttpPaymentCodec (new payload shape)\n    const responsePayload = {\n      subRav: next,\n      cost: params.cost,\n      costUsd: params.costUsd,\n      clientTxRef: params.clientTxRef,\n      serviceTxRef,\n      version: 1,\n    } as any;\n\n    const headerValue = HttpPaymentCodec.buildResponseHeader(responsePayload);\n\n    return { unsignedSubRAV: next, serviceTxRef, headerValue };\n  }\n\n  /**\n   * Build next unsigned SubRAV following the prior signed SubRAV, reused by async/sync paths.\n   */\n  private buildNextUnsigned(current: SubRAV, cost: bigint): SubRAV {\n    const channelId = current.channelId;\n    const vmIdFragment = current.vmIdFragment;\n    const currentNonce = current.nonce;\n    const nextNonce = currentNonce + 1n;\n    const newAccumulatedAmount = current.accumulatedAmount + cost;\n\n    return {\n      version: 1,\n      chainId: current.chainId,\n      channelId,\n      channelEpoch: current.channelEpoch,\n      vmIdFragment,\n      nonce: nextNonce,\n      accumulatedAmount: newAccumulatedAmount,\n    };\n  }\n\n  /**\n   * Try to locate sub-channel using DIDAuth fallback (§4.4 of rav-handling.md)\n   */\n  private async tryDIDAuthFallback(\n    ctx: BillingContext\n  ): Promise<{ channelId: string; vmIdFragment: string } | null> {\n    try {\n      const didInfo = ctx.meta.didInfo;\n      if (!didInfo || !didInfo.did || !didInfo.keyId) {\n        this.log('No DIDAuth info available for fallback');\n        return null;\n      }\n\n      // Extract vmIdFragment from keyId (format: \"did:example:123#key-1\")\n      const keyIdParts = didInfo.keyId.split('#');\n      if (keyIdParts.length < 2) {\n        this.log('Invalid keyId format for DIDAuth fallback:', didInfo.keyId);\n        return null;\n      }\n      const vmIdFragment = keyIdParts[1];\n\n      // Get payee DID from the payee client\n      const payeeDid = await this.config.payeeClient.getPayeeDid();\n      const defaultAssetId = this.config.defaultAssetId || '0x3::gas_coin::RGas';\n\n      // Use actual cryptographic derivation matching Move contract logic\n      const channelId = deriveChannelId(didInfo.did, payeeDid, defaultAssetId);\n\n      this.log('DIDAuth fallback derived:', {\n        channelId,\n        vmIdFragment,\n        payerDid: didInfo.did,\n        payeeDid,\n      });\n      return { channelId, vmIdFragment };\n    } catch (error) {\n      this.log('Error in DIDAuth fallback:', error);\n      return null;\n    }\n  }\n\n  // ---------- Internal helpers ----------\n\n  private asPreprocessed(ctx: BillingContext): PreprocessedBillingContext {\n    if (!ctx.state) {\n      ctx.state = {};\n    }\n    return ctx as PreprocessedBillingContext;\n  }\n\n  private attachErrorHeader(ctx: PreprocessedBillingContext, error: PaymentError): void {\n    try {\n      if (!ctx.state.serviceTxRef) {\n        ctx.state.serviceTxRef = `srv-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n      }\n      ctx.state.headerValue = HttpPaymentCodec.buildResponseHeader({\n        error,\n        clientTxRef: ctx.meta.clientTxRef,\n        serviceTxRef: ctx.state.serviceTxRef,\n        version: 1,\n      } as any);\n    } catch (e) {\n      this.log('Failed to build error header:', e);\n    }\n  }\n\n  private fail(\n    ctx: PreprocessedBillingContext,\n    error: PaymentError,\n    options?: { attachHeader?: boolean }\n  ): PreprocessedBillingContext {\n    ctx.state.error = error;\n    if (options?.attachHeader !== false) {\n      this.attachErrorHeader(ctx, error);\n    }\n    return ctx;\n  }\n\n  /**\n   * Debug logging\n   */\n  private log(...args: any[]): void {\n    this.logger.debug(...args);\n  }\n}\n","import { AssetInfo } from '../../core/types';\n\n/**\n * Rate provider types for USD pricing and multi-asset settlement\n */\n\n/**\n * Rate provider interface for fetching USD exchange rates\n */\nexport interface RateProvider {\n  /**\n   * Get the price of an asset in picoUSD per minimum unit\n   * @param assetId - Asset identifier (e.g. '0x3::gas_coin::RGas', 'ethereum', etc.)\n   * @returns Price in picoUSD per minimum unit (10^-12 USD)\n   */\n  getPricePicoUSD(assetId: string): Promise<bigint>;\n\n  /**\n   * Get asset information including decimals\n   * @param assetId - Asset identifier\n   * @returns Asset information or null if not found\n   */\n  getAssetInfo(assetId: string): Promise<AssetInfo | null>;\n\n  /**\n   * Get the timestamp of the last price update for an asset\n   * @param assetId - Asset identifier\n   * @returns Timestamp in milliseconds, or null if never updated\n   */\n  getLastUpdated(assetId: string): number | null;\n\n  /**\n   * Clear cached data for an asset\n   * @param assetId - Asset identifier, or undefined to clear all\n   */\n  clearCache(assetId?: string): void;\n}\n\n/**\n * Base rate provider with common functionality\n */\nexport abstract class BaseRateProvider implements RateProvider {\n  protected cache = new Map<\n    string,\n    {\n      price: bigint;\n      timestamp: number;\n      assetInfo?: AssetInfo;\n    }\n  >();\n  protected cacheTimeout: number;\n\n  constructor(\n    cacheTimeoutMs = 60000 // 1 minute default\n  ) {\n    this.cacheTimeout = cacheTimeoutMs;\n  }\n\n  abstract getPricePicoUSD(assetId: string): Promise<bigint>;\n\n  abstract getAssetInfo(assetId: string): Promise<AssetInfo | null>;\n\n  getLastUpdated(assetId: string): number | null {\n    const cached = this.cache.get(assetId);\n    return cached?.timestamp || null;\n  }\n\n  clearCache(assetId?: string): void {\n    if (assetId) {\n      this.cache.delete(assetId);\n    } else {\n      this.cache.clear();\n    }\n  }\n\n  protected updateCache(assetId: string, price: bigint, assetInfo?: AssetInfo): void {\n    this.cache.set(assetId, {\n      price,\n      timestamp: Date.now(),\n      assetInfo,\n    });\n  }\n\n  protected isCacheValid(assetId: string): boolean {\n    const cached = this.cache.get(assetId);\n    if (!cached) return false;\n    return Date.now() - cached.timestamp < this.cacheTimeout;\n  }\n\n  protected getCachedPrice(assetId: string): bigint | null {\n    const cached = this.cache.get(assetId);\n    if (!cached || !this.isCacheValid(assetId)) return null;\n    return cached.price;\n  }\n}\n\n/**\n * Rate fetch result with metadata\n */\nexport interface RateResult {\n  /** Price in picoUSD */\n  price: bigint;\n  /** Timestamp when fetched */\n  timestamp: number;\n  /** Data source identifier */\n  provider: string;\n  /** Asset identifier */\n  assetId: string;\n}\n\n/**\n * Conversion result with exchange rate information for audit trail\n */\nexport interface ConversionResult {\n  /** Final asset cost in minimum units */\n  assetCost: bigint;\n  /** Original USD cost in picoUSD */\n  usdCost: bigint;\n  /** Exchange rate used (picoUSD per minimum unit) */\n  priceUsed: bigint;\n  /** Timestamp when rate was fetched */\n  priceTimestamp: number;\n  /** Rate provider identifier */\n  rateProvider: string;\n  /** Asset identifier used */\n  assetId: string;\n}\n\n/**\n * Rate provider error types\n */\nexport class RateProviderError extends Error {\n  constructor(\n    message: string,\n    public readonly assetId?: string,\n    public readonly provider?: string\n  ) {\n    super(message);\n    this.name = 'RateProviderError';\n  }\n}\n\nexport class RateNotFoundError extends RateProviderError {\n  constructor(assetId: string, provider: string) {\n    super(`Rate not found for asset ${assetId}`, assetId, provider);\n    this.name = 'RateNotFoundError';\n  }\n}\n\nexport class RateStaleError extends RateProviderError {\n  constructor(assetId: string, provider: string, lastUpdated?: number) {\n    super(`Rate for asset ${assetId} is stale (last updated: ${lastUpdated})`, assetId, provider);\n    this.name = 'RateStaleError';\n  }\n}\n","import { RateProvider, ConversionResult, RateProviderError, RateResult } from '../rate/types';\n\n/**\n * Convert a USD cost (in picoUSD) to the smallest unit of the requested asset\n * using the supplied `RateProvider`.\n */\nexport async function convertUsdToAsset(\n  usdCost: bigint,\n  assetId: string,\n  rateProvider: RateProvider\n): Promise<ConversionResult> {\n  if (usdCost === 0n) {\n    return {\n      assetCost: 0n,\n      usdCost,\n      priceUsed: 0n,\n      priceTimestamp: Date.now(),\n      rateProvider: 'none',\n      assetId,\n    };\n  }\n\n  try {\n    const price = await rateProvider.getPricePicoUSD(assetId);\n    const priceTimestamp = rateProvider.getLastUpdated(assetId) ?? Date.now();\n\n    if (price <= 0n) {\n      throw new RateProviderError(`Invalid price for asset ${assetId}: ${price}`, assetId);\n    }\n\n    // Ceil division to avoid under-charging\n    const assetCost = (usdCost + price - 1n) / price;\n\n    return {\n      assetCost,\n      usdCost,\n      priceUsed: price,\n      priceTimestamp,\n      rateProvider: 'rate-provider',\n      assetId,\n    };\n  } catch (err) {\n    if (err instanceof RateProviderError) {\n      throw err;\n    }\n    throw new RateProviderError(`Failed to convert USD to asset ${assetId}: ${err}`, assetId);\n  }\n}\n\n/**\n * Convert using a pre-fetched price (synchronous, no I/O)\n */\nexport function convertUsdToAssetUsingPrice(usdCost: bigint, rate: RateResult): ConversionResult {\n  if (usdCost === 0n) {\n    return {\n      assetCost: 0n,\n      usdCost,\n      priceUsed: rate.price,\n      priceTimestamp: rate.timestamp,\n      rateProvider: rate.provider,\n      assetId: rate.assetId,\n    };\n  }\n\n  if (rate.price <= 0n) {\n    throw new RateProviderError(\n      `Invalid price for asset ${rate.assetId}: ${rate.price}`,\n      rate.assetId,\n      rate.provider\n    );\n  }\n\n  const assetCost = (usdCost + rate.price - 1n) / rate.price;\n  return {\n    assetCost,\n    usdCost,\n    priceUsed: rate.price,\n    priceTimestamp: rate.timestamp,\n    rateProvider: rate.provider,\n    assetId: rate.assetId,\n  };\n}\n","import { Strategy, BillingContext } from '../core/types';\n\n/**\n * Base class for all billing strategies\n */\nexport abstract class BaseStrategy implements Strategy {\n  /**\n   * Default implementation: most strategies don't require execution results\n   */\n  readonly deferred: boolean = false;\n  /**\n   * Convert string or bigint to bigint\n   * Handles scientific notation strings like \"5e12\"\n   */\n  protected toBigInt(value: string | bigint | number): bigint {\n    if (typeof value === 'bigint') {\n      return value;\n    }\n    if (typeof value === 'number') {\n      return BigInt(value);\n    }\n    // Handle scientific notation\n    if (value.includes('e') || value.includes('E')) {\n      const num = parseFloat(value);\n      return BigInt(Math.round(num));\n    }\n    return BigInt(value);\n  }\n\n  /**\n   * Abstract method to be implemented by concrete strategies\n   */\n  abstract evaluate(ctx: BillingContext, units: number): bigint;\n}\n","import { BaseStrategy } from './base';\nimport { BillingContext } from '../core/types';\n\n/**\n * Configuration for PerRequest strategy\n */\nexport interface PerRequestConfig {\n  /** Fixed price per request */\n  price: string | bigint | number;\n}\n\n/**\n * Per-request fixed pricing strategy\n * Charges a fixed amount for each request regardless of content\n */\nexport class PerRequestStrategy extends BaseStrategy {\n  private readonly price: bigint;\n\n  constructor(config: PerRequestConfig) {\n    super();\n    this.price = this.toBigInt(config.price);\n  }\n\n  override evaluate(ctx: BillingContext, units: number): bigint {\n    const u = Number.isFinite(units) && units > 0 ? Math.floor(units) : 1;\n    return this.price * BigInt(u);\n  }\n}\n","import type { BillingContext } from '../core/types';\nimport { BaseStrategy } from './base';\n\n/**\n * PerToken strategy configuration\n */\nexport interface PerTokenConfig {\n  /** Price per token in picoUSD */\n  unitPricePicoUSD: string | bigint;\n}\n\n/**\n * Per-token billing strategy\n *\n * Calculates cost based on token usage: unitPricePicoUSD × tokens\n */\nexport class PerTokenStrategy extends BaseStrategy {\n  /**\n   * PerToken strategy requires execution results (usage data) from LLM calls\n   */\n  readonly deferred: boolean = true;\n\n  private readonly unitPrice: bigint;\n\n  constructor(config: PerTokenConfig) {\n    super();\n    this.unitPrice = this.toBigInt(config.unitPricePicoUSD);\n  }\n\n  override evaluate(ctx: BillingContext, units: number): bigint {\n    const tokenCount = Number.isFinite(units) && units > 0 ? Math.floor(units) : 1;\n    return this.unitPrice * BigInt(tokenCount);\n  }\n}\n","import type { BillingContext } from '../core/types';\nimport { BaseStrategy } from './base';\n\n/**\n * FinalCost strategy configuration\n * - No options. Incoming usage MUST be picoUSD (integer) value.\n */\nexport interface FinalCostConfig {}\n\n/**\n * Final-cost passthrough billing strategy\n *\n * This strategy is used when the application already knows the final USD cost\n * (either computed internally or received from a provider). The application\n * MUST pass picoUSD (integer) via the `usage` parameter to `settle()`.\n * This strategy returns that picoUSD as bigint for downstream asset conversion.\n */\nexport class FinalCostStrategy extends BaseStrategy {\n  /** Requires post-flight usage to be available */\n  readonly deferred: boolean = true;\n\n  constructor(_config: FinalCostConfig = {}) {\n    super();\n  }\n\n  override evaluate(_ctx: BillingContext, units: number): bigint {\n    const value = Number.isFinite(units) && units > 0 ? Math.floor(units) : 0;\n    return BigInt(value);\n  }\n}\n","export { BaseStrategy } from './base';\nimport { PerRequestStrategy, PerRequestConfig } from './perRequest';\nimport { PerTokenStrategy, PerTokenConfig } from './perToken';\nimport { FinalCostStrategy, FinalCostConfig } from './finalCost';\n\nexport { PerRequestStrategy, PerRequestConfig, PerTokenStrategy, PerTokenConfig };\nexport { FinalCostStrategy, FinalCostConfig };\n\n// Explicit registration API to avoid side-effect imports\nexport function registerBuiltinStrategies(): void {\n  // Use dynamic import/require to avoid triggering module side effects at import time\n  // eslint-disable-next-line @typescript-eslint/no-var-requires\n  const { register: registerStrategy } =\n    require('../core/strategy-registry') as typeof import('../core/strategy-registry');\n  registerStrategy('PerRequest', cfg => new PerRequestStrategy(cfg as any));\n  registerStrategy('PerToken', cfg => new PerTokenStrategy(cfg as any));\n  registerStrategy('FinalCost', cfg => new FinalCostStrategy(cfg as any));\n}\n","import { MultibaseCodec } from '@nuwa-ai/identity-kit';\nimport type { SignedSubRAV, SubRAV } from '../../core/types';\nimport type { PaymentCodec } from '../../codecs/PaymentCodec';\nimport { EncodingError, DecodingError } from '../../codecs/PaymentCodec';\nimport type {\n  PaymentHeaderPayload,\n  HttpRequestPayload,\n  PaymentResponsePayload as HttpResponsePayload,\n} from '../../core/types';\n\n/**\n * HTTP-specific payment codec\n *\n * Handles encoding/decoding of payment data for HTTP protocol\n * using X-Payment-Channel-Data header format\n */\nexport class HttpPaymentCodec implements PaymentCodec {\n  private static readonly HEADER_NAME = 'X-Payment-Channel-Data';\n\n  /**\n   * Encode payment header payload for HTTP request header (new interface)\n   */\n  encodePayload(payload: PaymentHeaderPayload): string {\n    try {\n      return HttpPaymentCodec.buildRequestHeader(payload);\n    } catch (error) {\n      throw new EncodingError(\n        'Failed to encode HTTP payment data',\n        error instanceof Error ? error : new Error(String(error))\n      );\n    }\n  }\n\n  /**\n   * Decode HTTP request header to payment header payload (new interface)\n   */\n  decodePayload(encoded: string): PaymentHeaderPayload {\n    try {\n      return HttpPaymentCodec.parseRequestHeader(encoded);\n    } catch (error) {\n      throw new DecodingError(\n        'Failed to decode HTTP payment data',\n        error instanceof Error ? error : new Error(String(error))\n      );\n    }\n  }\n\n  /**\n   * Encode SubRAV proposal for HTTP response header\n   */\n  encodeResponse(subRAV: SubRAV, cost: bigint, serviceTxRef: string, metadata?: any): string {\n    try {\n      const payload: HttpResponsePayload = {\n        subRav: subRAV,\n        cost,\n        serviceTxRef,\n        version: 1,\n        ...metadata,\n      };\n\n      return HttpPaymentCodec.buildResponseHeader(payload);\n    } catch (error) {\n      throw new EncodingError(\n        'Failed to encode HTTP response payment data',\n        error instanceof Error ? error : new Error(String(error))\n      );\n    }\n  }\n\n  /**\n   * Encode protocol-level error for HTTP response header\n   */\n  encodeError(\n    error: { code: string; message?: string },\n    metadata?: { clientTxRef?: string; serviceTxRef?: string; version?: number }\n  ): string {\n    try {\n      const payload: HttpResponsePayload = {\n        error,\n        clientTxRef: metadata?.clientTxRef,\n        serviceTxRef: metadata?.serviceTxRef,\n        version: metadata?.version ?? 1,\n      } as HttpResponsePayload;\n      return HttpPaymentCodec.buildResponseHeader(payload);\n    } catch (error) {\n      throw new EncodingError(\n        'Failed to encode HTTP response error data',\n        error instanceof Error ? error : new Error(String(error))\n      );\n    }\n  }\n\n  /**\n   * Decode HTTP response header to SubRAV proposal\n   */\n  decodeResponse(encoded: string): {\n    subRAV?: SubRAV;\n    cost?: bigint;\n    serviceTxRef?: string;\n    metadata?: any;\n    error?: { code: string; message?: string };\n    version?: number;\n  } {\n    try {\n      const payload = HttpPaymentCodec.parseResponseHeader(encoded);\n\n      return {\n        subRAV: payload.subRav,\n        cost: payload.cost,\n        serviceTxRef: payload.serviceTxRef,\n        metadata: payload.clientTxRef ? { clientTxRef: payload.clientTxRef } : undefined,\n        error: payload.error,\n        version: payload.version,\n      };\n    } catch (error) {\n      throw new DecodingError(\n        'Failed to decode HTTP response payment data',\n        error instanceof Error ? error : new Error(String(error))\n      );\n    }\n  }\n\n  // ============================================================================\n  // Static HTTP Header Building Methods\n  // ============================================================================\n\n  /**\n   * Build HTTP request header value\n   */\n  static buildRequestHeader(payload: PaymentHeaderPayload): string {\n    // Convert payload to serializable format\n    const serializable: any = {\n      maxAmount: payload.maxAmount.toString(),\n      clientTxRef: payload.clientTxRef,\n      version: payload.version.toString(),\n    };\n\n    // signedSubRav is now optional\n    if (payload.signedSubRav) {\n      serializable.signedSubRav = this.serializeSignedSubRAV(payload.signedSubRav);\n    }\n\n    // Convert to JSON and encode\n    const json = JSON.stringify(serializable);\n    return MultibaseCodec.encodeBase64url(json);\n  }\n\n  /**\n   * Parse HTTP request header value\n   */\n  static parseRequestHeader(headerValue: string): PaymentHeaderPayload {\n    try {\n      const json = MultibaseCodec.decodeBase64urlToString(headerValue);\n      const data = JSON.parse(json);\n\n      // clientTxRef is now required\n      if (!data.clientTxRef) {\n        throw new Error('clientTxRef is required in payment header');\n      }\n\n      const result: PaymentHeaderPayload = {\n        maxAmount: data.maxAmount ? BigInt(data.maxAmount) : BigInt(0), // Handle old format without maxAmount\n        clientTxRef: data.clientTxRef,\n        version: parseInt(data.version) || 1,\n      };\n\n      // signedSubRav is now optional\n      if (data.signedSubRav) {\n        result.signedSubRav = this.deserializeSignedSubRAV(data.signedSubRav);\n      }\n\n      return result;\n    } catch (error) {\n      throw new Error(`Failed to parse request header: ${error}`);\n    }\n  }\n\n  /**\n   * Build HTTP response header value\n   */\n  static buildResponseHeader(payload: HttpResponsePayload): string {\n    const serializable: any = {\n      clientTxRef: payload.clientTxRef,\n      serviceTxRef: payload.serviceTxRef,\n      version: (payload.version ?? 1).toString(),\n    };\n\n    if (payload.subRav && payload.cost !== undefined) {\n      serializable.subRav = this.serializeSubRAV(payload.subRav);\n      serializable.cost = payload.cost.toString();\n      if (payload.costUsd !== undefined) {\n        serializable.costUsd = payload.costUsd.toString();\n      }\n    }\n\n    if (payload.error) {\n      serializable.error = payload.error;\n    }\n\n    const json = JSON.stringify(serializable);\n    return MultibaseCodec.encodeBase64url(json);\n  }\n\n  /**\n   * Parse HTTP response header value\n   */\n  static parseResponseHeader(headerValue: string): HttpResponsePayload {\n    try {\n      const json = MultibaseCodec.decodeBase64urlToString(headerValue);\n      const data = JSON.parse(json);\n\n      const payload: HttpResponsePayload = {\n        clientTxRef: data.clientTxRef,\n        serviceTxRef: data.serviceTxRef,\n        version: parseInt(data.version) || 1,\n      } as HttpResponsePayload;\n\n      // Success path\n      if (data.subRav && (data.cost !== undefined || data.amountDebited !== undefined)) {\n        payload.subRav = this.deserializeSubRAV(data.subRav);\n        // Support old amountDebited for early servers\n        const costStr = data.cost ?? data.amountDebited;\n        payload.cost = costStr !== undefined ? BigInt(costStr) : undefined;\n        if (data.costUsd !== undefined) {\n          payload.costUsd = BigInt(data.costUsd);\n        }\n      }\n\n      // Error path\n      if (data.error) {\n        payload.error = data.error;\n      } else if (data.errorCode !== undefined) {\n        // Map legacy numeric errorCode to string code\n        payload.error = { code: String(data.errorCode), message: data.message };\n      }\n\n      return payload;\n    } catch (error) {\n      throw new Error(`Failed to parse response header: ${error}`);\n    }\n  }\n\n  /**\n   * Get HTTP header name for payment data\n   */\n  static getHeaderName(): string {\n    return this.HEADER_NAME;\n  }\n\n  /**\n   * Check if request contains payment data\n   */\n  static hasPaymentData(headers: Record<string, string | string[]>): boolean {\n    const headerName = this.getHeaderName();\n    return !!(headers[headerName.toLowerCase()] || headers[headerName]);\n  }\n\n  /**\n   * Extract payment header value from request headers\n   */\n  static extractPaymentHeader(\n    headers: Record<string, string | string[] | undefined>\n  ): string | null {\n    const headerName = this.getHeaderName();\n    const headerValue = headers[headerName.toLowerCase()] || headers[headerName];\n\n    if (Array.isArray(headerValue)) {\n      return headerValue[0] || null;\n    }\n\n    return headerValue || null;\n  }\n\n  /**\n   * Extract payment data from request headers\n   */\n  static extractPaymentData(headers: Record<string, string>): PaymentHeaderPayload | null {\n    const headerValue =\n      headers[this.getHeaderName().toLowerCase()] || headers[this.getHeaderName()];\n\n    if (!headerValue) {\n      return null;\n    }\n\n    try {\n      return this.parseRequestHeader(headerValue);\n    } catch (error) {\n      throw new Error(`Invalid payment channel header: ${error}`);\n    }\n  }\n\n  /**\n   * Add payment data to response headers\n   */\n  static addPaymentData(\n    headers: Record<string, string>,\n    payload: HttpResponsePayload\n  ): Record<string, string> {\n    const headerValue = this.buildResponseHeader(payload);\n    return {\n      ...headers,\n      [this.getHeaderName()]: headerValue,\n    };\n  }\n\n  /**\n   * Validate payment requirements for a request\n   */\n  static validatePaymentRequirement(\n    paymentData: PaymentHeaderPayload | null,\n    requiredAmount: bigint\n  ): { valid: boolean; error?: string } {\n    if (!paymentData) {\n      return { valid: false, error: 'Payment required' };\n    }\n\n    if (paymentData.maxAmount < requiredAmount) {\n      return { valid: false, error: 'Insufficient payment allowance' };\n    }\n\n    return { valid: true };\n  }\n\n  // ============================================================================\n  // Private Serialization Helpers\n  // ============================================================================\n\n  /**\n   * Helper: Serialize SubRAV for JSON transport\n   */\n  private static serializeSubRAV(subRav: SubRAV): Record<string, string> {\n    return {\n      version: subRav.version.toString(),\n      chainId: subRav.chainId.toString(),\n      channelId: subRav.channelId,\n      channelEpoch: subRav.channelEpoch.toString(),\n      vmIdFragment: subRav.vmIdFragment,\n      accumulatedAmount: subRav.accumulatedAmount.toString(),\n      nonce: subRav.nonce.toString(),\n    };\n  }\n\n  /**\n   * Helper: Deserialize SubRAV from JSON transport\n   */\n  private static deserializeSubRAV(data: Record<string, string>): SubRAV {\n    return {\n      version: parseInt(data.version),\n      chainId: BigInt(data.chainId),\n      channelId: data.channelId,\n      channelEpoch: BigInt(data.channelEpoch),\n      vmIdFragment: data.vmIdFragment,\n      accumulatedAmount: BigInt(data.accumulatedAmount),\n      nonce: BigInt(data.nonce),\n    };\n  }\n\n  /**\n   * Helper: Serialize SignedSubRAV for JSON transport\n   */\n  private static serializeSignedSubRAV(\n    signedSubRav: SignedSubRAV | undefined\n  ): Record<string, any> | undefined {\n    if (!signedSubRav) {\n      return undefined;\n    }\n\n    return {\n      subRav: this.serializeSubRAV(signedSubRav.subRav),\n      signature: MultibaseCodec.encodeBase64url(signedSubRav.signature),\n    };\n  }\n\n  /**\n   * Helper: Deserialize SignedSubRAV from JSON transport\n   */\n  private static deserializeSignedSubRAV(\n    data: Record<string, any> | undefined\n  ): SignedSubRAV | undefined {\n    if (!data) {\n      return undefined;\n    }\n\n    return {\n      subRav: this.deserializeSubRAV(data.subRav),\n      signature: MultibaseCodec.decodeBase64url(data.signature),\n    };\n  }\n}\n","import type { SignedSubRAV } from '../core/types';\n\n/**\n * Protocol-agnostic payment codec interface\n *\n * Implementations handle encoding/decoding of payment data\n * for specific protocols (HTTP, MCP, A2A, etc.)\n */\nexport interface PaymentCodec {}\n\n/**\n * Error types for codec operations\n */\nexport class CodecError extends Error {\n  constructor(\n    message: string,\n    public readonly cause?: Error\n  ) {\n    super(message);\n    this.name = 'CodecError';\n  }\n}\n\nexport class EncodingError extends CodecError {\n  constructor(message: string, cause?: Error) {\n    super(`Encoding failed: ${message}`, cause);\n    this.name = 'EncodingError';\n  }\n}\n\nexport class DecodingError extends CodecError {\n  constructor(message: string, cause?: Error) {\n    super(`Decoding failed: ${message}`, cause);\n    this.name = 'DecodingError';\n  }\n}\n","/**\n * Channel utilities for payment channel operations\n *\n * Provides pure functions for channel ID derivation and other channel-related operations\n * that don't require blockchain interaction.\n */\n\nimport { parseDid } from '@nuwa-ai/identity-kit';\nimport { bcs, sha3_256, toHEX, Serializer, RoochAddress } from '@roochnetwork/rooch-sdk';\n\n/**\n * Channel key structure matching Move contract ChannelKey\n */\nexport interface ChannelKey {\n  sender: string;\n  receiver: string;\n  coin_type: string;\n}\n\n/**\n * BCS Schema for ChannelKey - matches Move contract exactly\n */\nexport const ChannelKeySchema: any = bcs.struct('ChannelKey', {\n  sender: bcs.Address,\n  receiver: bcs.Address,\n  coin_type: bcs.string(),\n});\n\n// ==================== BCS Schema Definitions ====================\n\n// CancellationInfo struct\nexport interface CancellationInfo {\n  initiated_time: bigint;\n  pending_amount: bigint;\n}\n\nexport const CancellationInfoSchema: any = bcs.struct('CancellationInfo', {\n  initiated_time: bcs.u64(),\n  pending_amount: bcs.u256(),\n});\n\n// SubChannel struct\nexport interface SubChannel {\n  pk_multibase: string;\n  method_type: string;\n  last_claimed_amount: bigint;\n  last_confirmed_nonce: bigint;\n}\n\nexport const SubChannelSchema: any = bcs.struct('SubChannel', {\n  pk_multibase: bcs.string(),\n  method_type: bcs.string(),\n  last_claimed_amount: bcs.u256(),\n  last_confirmed_nonce: bcs.u64(),\n});\n\n// PaymentChannel struct - matches Move contract exactly\nexport interface PaymentChannelData {\n  sender: string;\n  receiver: string;\n  coin_type: string;\n  sub_channels: string; // ObjectID as hex string (Table handle)\n  status: number;\n  channel_epoch: bigint;\n  cancellation_info: CancellationInfo | null;\n}\n\nexport const PaymentChannelSchema: any = bcs.struct('PaymentChannel', {\n  sender: bcs.Address,\n  receiver: bcs.Address,\n  coin_type: bcs.string(),\n  sub_channels: bcs.ObjectId, // Table<String, SubChannel> stored as ObjectID\n  status: bcs.u8(),\n  channel_epoch: bcs.u64(),\n  cancellation_info: bcs.option(CancellationInfoSchema),\n});\n\n// PaymentHub structure definition matching the Move contract\nexport interface PaymentHub {\n  multi_coin_store: string; // ObjectID as hex string\n  active_channels: string; // ObjectID as hex string\n}\n\nexport const PaymentHubSchema: any = bcs.struct('PaymentHub', {\n  multi_coin_store: bcs.ObjectId,\n  active_channels: bcs.ObjectId, // Table<String, u64>\n});\n\n// Balance struct - matches multi_coin_store.move\nexport interface BalanceData {\n  value: bigint;\n}\n\nexport const BalanceSchema: any = bcs.struct('Balance', {\n  value: bcs.u256(),\n});\n\n// CoinStoreField struct - matches multi_coin_store.move\nexport interface CoinStoreFieldData {\n  coin_type: string;\n  balance: BalanceData;\n  frozen: boolean;\n}\n\nexport const CoinStoreFieldSchema: any = bcs.struct('CoinStoreField', {\n  coin_type: bcs.string(),\n  balance: BalanceSchema,\n  frozen: bcs.bool(),\n});\n\n// DynamicField struct for parsing Table fields\nexport interface DynamicField<K, V> {\n  name: K;\n  value: V;\n}\n\nexport const DynamicFieldSubChannelSchema: any = bcs.struct('DynamicField', {\n  name: bcs.string(),\n  value: SubChannelSchema,\n});\n\nexport const DynamicFieldCoinStoreSchema: any = bcs.struct('DynamicField', {\n  name: bcs.string(),\n  value: CoinStoreFieldSchema,\n});\n\nexport const DynamicFieldU64Schema: any = bcs.struct('DynamicField', {\n  name: bcs.string(),\n  value: bcs.u64(),\n});\n\n/**\n * Derive channel ID from payer DID, payee DID, and asset ID\n *\n * This function replicates the exact same logic as the Move contract's\n * object::custom_object_id<ChannelKey, PaymentChannel>(key) calculation.\n *\n * @param payerDid - Payer DID (e.g., \"did:rooch:...\")\n * @param payeeDid - Payee DID (e.g., \"did:rooch:...\")\n * @param assetId - Asset ID (e.g., \"0x3::gas_coin::RGas\")\n * @returns Channel object ID as hex string\n */\nexport function deriveChannelId(payerDid: string, payeeDid: string, assetId: string): string {\n  // Parse and validate DIDs\n  const payerParsed = parseDid(payerDid);\n  const payeeParsed = parseDid(payeeDid);\n\n  if (payerParsed.method !== 'rooch') {\n    throw new Error(`Invalid payer DID method: expected 'rooch', got '${payerParsed.method}'`);\n  }\n  if (payeeParsed.method !== 'rooch') {\n    throw new Error(`Invalid payee DID method: expected 'rooch', got '${payeeParsed.method}'`);\n  }\n\n  return calcChannelObjectId(payerParsed.identifier, payeeParsed.identifier, assetId);\n}\n\n/**\n * Calculate channel object ID using the same logic as Move contract\n *\n * This replicates object::custom_object_id<ChannelKey, PaymentChannel>(key)\n * from payment_channel.move using proper BCS serialization.\n *\n * @param senderAddress - Sender address\n * @param receiverAddress - Receiver address\n * @param coinType - Coin type string\n * @returns Channel object ID as hex string\n */\nexport function calcChannelObjectId(\n  senderAddress: string,\n  receiverAddress: string,\n  coinType: string\n): string {\n  const normalizedCoinType = normalizeAssetId(coinType);\n\n  // Create ChannelKey struct - this must match the Move struct exactly\n  const channelKey: ChannelKey = {\n    sender: senderAddress,\n    receiver: receiverAddress,\n    coin_type: normalizedCoinType,\n  };\n\n  // Create PaymentChannel struct tag\n  const paymentChannelStructTag = {\n    address: '0x3',\n    module: 'payment_channel',\n    name: 'PaymentChannel',\n    type_params: [],\n  };\n\n  // Implement custom_object_id logic:\n  // 1. BCS serialize the ChannelKey struct (not JSON!)\n  // 2. Append the PaymentChannel struct tag canonical string as bytes\n  // 3. SHA3-256 hash the combined bytes\n  // 4. Return as ObjectID\n\n  // BCS serialize the ChannelKey\n  const idBytes = ChannelKeySchema.serialize(channelKey).toBytes();\n\n  // Get PaymentChannel struct tag canonical string as bytes\n  const typeBytes = new TextEncoder().encode(\n    Serializer.structTagToCanonicalString(paymentChannelStructTag)\n  );\n\n  // Concatenate: bcs(ChannelKey) + canonical_string(PaymentChannel)\n  const bytes = new Uint8Array(idBytes.length + typeBytes.length);\n  bytes.set(idBytes);\n  bytes.set(typeBytes, idBytes.length);\n\n  // SHA3-256 hash\n  const hash = sha3_256(bytes);\n  return `0x${toHEX(hash)}`;\n}\n\n/**\n * Normalize asset ID to canonical string representation\n * @param assetId Asset ID string\n * @returns Canonical asset ID string\n */\nexport function normalizeAssetId(assetId: string): string {\n  try {\n    // Use Rooch SDK's built-in parser with address normalization\n    const typeTag = Serializer.typeTagParseFromStr(assetId, true);\n\n    // Ensure it's a struct type (not a primitive type)\n    if (!('struct' in typeTag)) {\n      throw new Error(`Asset ID must be a struct type, got: ${assetId}`);\n    }\n\n    return Serializer.structTagToCanonicalString(typeTag.struct as any);\n  } catch (error) {\n    throw new Error(`Failed to parse asset ID: ${assetId} - ${error}`);\n  }\n}\n\n/**\n * Validate channel ID format\n * @param channelId Channel ID to validate\n * @returns True if valid format\n */\nexport function isValidChannelId(channelId: string): boolean {\n  // Channel ID should be a hex string starting with 0x\n  return /^0x[a-fA-F0-9]{64}$/.test(channelId);\n}\n\n/**\n * Extract channel information from channel ID (if possible)\n * Note: This is a one-way function, channel ID cannot be reversed to get original inputs\n * @param channelId Channel ID\n * @returns Basic channel info or null if invalid\n */\nexport function parseChannelIdInfo(\n  channelId: string\n): { isValid: boolean; objectId: string } | null {\n  if (!isValidChannelId(channelId)) {\n    return null;\n  }\n\n  return {\n    isValid: true,\n    objectId: channelId,\n  };\n}\n\n// ==================== PaymentHub Utilities ====================\n\n/**\n * Calculate PaymentHub ID using the same algorithm as in Move\n *\n * Replicates the logic from moveos_types::moveos_std::object::account_named_object_id\n * and payment_channel.move::get_payment_hub_id function\n *\n * @param ownerAddress - Owner address (DID identifier or hex address)\n * @returns PaymentHub object ID as hex string\n */\nexport function calculatePaymentHubId(ownerAddress: string): string {\n  // Create PaymentHub struct tag using the same approach as ChannelUtils\n  const paymentHubStructTag = {\n    address: '0x3',\n    module: 'payment_channel',\n    name: 'PaymentHub',\n    type_params: [],\n  };\n\n  // Get canonical string representation using Serializer\n  const canonicalStructTag = Serializer.structTagToCanonicalString(paymentHubStructTag);\n\n  const roochAddress = new RoochAddress(ownerAddress);\n\n  // Convert owner address to bytes - Rooch SDK handles the address format conversion\n  const ownerBytes = roochAddress.toBytes();\n\n  // Append struct tag bytes (canonical string format)\n  const structTagBytes = new TextEncoder().encode(canonicalStructTag);\n\n  // Combine owner address bytes + struct tag bytes (browser-friendly)\n  const combined = new Uint8Array(ownerBytes.length + structTagBytes.length);\n  combined.set(ownerBytes, 0);\n  combined.set(structTagBytes, ownerBytes.length);\n\n  // Calculate SHA3-256 hash\n  const hash = sha3_256(combined);\n\n  // Return as hex string with 0x prefix (ObjectID format)\n  return '0x' + toHEX(hash);\n}\n\n/**\n * Derive a FieldKey from a string value.\n * This follows Rooch's FieldKey::derive_from_string logic:\n * hash(bcs(MoveString) || canonical_type_tag_string)\n *\n * @param value - The string value to derive field key from\n * @returns FieldKey as hex string\n */\nexport function deriveFieldKeyFromString(value: string): string {\n  try {\n    // BCS serialize the value as MoveString using Rooch's bcs library\n    const keyBytes = bcs.string().serialize(value).toBytes();\n\n    // Get the canonical type tag string for String type\n    // Must use full canonical address format (32-byte) as specified in Rust implementation\n    const stringTypeTag =\n      '0x0000000000000000000000000000000000000000000000000000000000000001::string::String';\n    const typeTagBytes = new TextEncoder().encode(stringTypeTag);\n\n    // Concatenate: bcs(key) + canonical_type_tag_string\n    const combinedBytes = new Uint8Array(keyBytes.length + typeTagBytes.length);\n    combinedBytes.set(keyBytes);\n    combinedBytes.set(typeTagBytes, keyBytes.length);\n\n    // SHA3-256 hash\n    const hash = sha3_256(combinedBytes);\n    return `0x${toHEX(hash)}`;\n  } catch (error) {\n    throw new Error(`Failed to derive field key: ${error}`);\n  }\n}\n\n/**\n * Derive field key for coin type asset ID\n * @param coinType - Asset ID (e.g., \"0x3::gas_coin::RGas\")\n * @returns FieldKey as hex string\n */\nexport function deriveCoinTypeFieldKey(coinType: string): string {\n  const assetIdCanonical = normalizeAssetId(coinType);\n  return deriveFieldKeyFromString(assetIdCanonical);\n}\n\n// ==================== BCS Parsing Utilities ====================\n\n/**\n * Parse PaymentChannel data from BCS hex string\n * @param value BCS encoded hex string from object state\n * @returns Parsed PaymentChannelData\n */\nexport function parsePaymentChannelData(value: string): PaymentChannelData {\n  try {\n    // Remove '0x' prefix if present\n    const bcsHex = value.startsWith('0x') ? value.slice(2) : value;\n    const bcsBytes = new Uint8Array(\n      bcsHex.match(/.{1,2}/g)?.map((byte: string) => parseInt(byte, 16)) || []\n    );\n\n    // Parse using BCS schema\n    const parsed = PaymentChannelSchema.parse(bcsBytes);\n\n    return {\n      sender: parsed.sender,\n      receiver: parsed.receiver,\n      coin_type: parsed.coin_type,\n      sub_channels: parsed.sub_channels,\n      status: parsed.status,\n      channel_epoch: BigInt(parsed.channel_epoch),\n      cancellation_info: parsed.cancellation_info\n        ? {\n            initiated_time: BigInt(parsed.cancellation_info.initiated_time),\n            pending_amount: BigInt(parsed.cancellation_info.pending_amount),\n          }\n        : null,\n    };\n  } catch (error) {\n    throw new Error(`Failed to parse PaymentChannel data: ${error}`);\n  }\n}\n\n/**\n * Parse PaymentHub data from BCS hex string\n * @param value BCS encoded hex string from object state\n * @returns Parsed PaymentHub\n */\nexport function parsePaymentHubData(value: string): PaymentHub {\n  try {\n    if (typeof value === 'string' && value.startsWith('0x')) {\n      // Parse BCS bytes using PaymentHubSchema (browser-friendly hex decode)\n      const hex = value.slice(2);\n      const bcsBytes = new Uint8Array(hex.length / 2);\n      for (let i = 0; i < bcsBytes.length; i++) {\n        bcsBytes[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16);\n      }\n      const parsed = PaymentHubSchema.parse(bcsBytes);\n\n      return {\n        multi_coin_store: parsed.multi_coin_store,\n        active_channels: parsed.active_channels,\n      };\n    } else {\n      throw new Error('Unexpected PaymentHub value format');\n    }\n  } catch (error) {\n    throw new Error(`Failed to parse PaymentHub data: ${error}`);\n  }\n}\n\n/**\n * Parse a DynamicField<String, SubChannel> from BCS hex string\n * @param value BCS encoded hex string from a DynamicField\n * @returns Parsed DynamicField<String, SubChannel> object\n */\nexport function parseDynamicFieldSubChannel(value: string): DynamicField<string, SubChannel> {\n  try {\n    // Remove '0x' prefix if present\n    const bcsHex = value.startsWith('0x') ? value.slice(2) : value;\n    const bcsBytes = new Uint8Array(\n      bcsHex.match(/.{1,2}/g)?.map((byte: string) => parseInt(byte, 16)) || []\n    );\n\n    // Parse using DynamicField BCS schema\n    const parsed = DynamicFieldSubChannelSchema.parse(bcsBytes);\n\n    return {\n      name: parsed.name,\n      value: {\n        pk_multibase: parsed.value.pk_multibase,\n        method_type: parsed.value.method_type,\n        last_claimed_amount: BigInt(parsed.value.last_claimed_amount),\n        last_confirmed_nonce: BigInt(parsed.value.last_confirmed_nonce),\n      },\n    };\n  } catch (error) {\n    throw new Error(`Failed to parse DynamicField<String, SubChannel>: ${error}`);\n  }\n}\n\n/**\n * Parse a DynamicField<String, CoinStoreField> from BCS hex string\n * @param value BCS encoded hex string from a DynamicField\n * @returns Parsed DynamicField<String, CoinStoreField> object\n */\nexport function parseDynamicFieldCoinStore(\n  value: string\n): DynamicField<string, CoinStoreFieldData> {\n  try {\n    const hex = value.startsWith('0x') ? value.slice(2) : value;\n    const bcsBytes = new Uint8Array(hex.length / 2);\n    for (let i = 0; i < bcsBytes.length; i++) {\n      bcsBytes[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16);\n    }\n    const parsed = DynamicFieldCoinStoreSchema.parse(bcsBytes);\n\n    return {\n      name: parsed.name as string,\n      value: parsed.value as CoinStoreFieldData,\n    };\n  } catch (error) {\n    throw new Error(`Failed to parse DynamicField<String, CoinStoreField>: ${error}`);\n  }\n}\n\n/**\n * Parse a DynamicField<String, u64> from BCS hex string\n * @param value BCS encoded hex string from a DynamicField\n * @returns Parsed DynamicField<String, u64> object\n */\nexport function parseDynamicFieldU64(value: string): DynamicField<string, number> {\n  try {\n    const hex = value.startsWith('0x') ? value.slice(2) : value;\n    const bcsBytes = new Uint8Array(hex.length / 2);\n    for (let i = 0; i < bcsBytes.length; i++) {\n      bcsBytes[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16);\n    }\n    const parsed = DynamicFieldU64Schema.parse(bcsBytes);\n\n    return {\n      name: parsed.name as string,\n      value: Number(parsed.value), // Convert bigint to number for count\n    };\n  } catch (error) {\n    throw new Error(`Failed to parse DynamicField<String, u64>: ${error}`);\n  }\n}\n\n/**\n * Safely convert balance value to bigint\n * @param balanceValue - The balance value from BCS parsing (could be string or bigint)\n * @returns Balance as bigint\n */\nexport function safeBalanceToBigint(balanceValue: any): bigint {\n  if (typeof balanceValue === 'string') {\n    return BigInt(balanceValue);\n  } else if (typeof balanceValue === 'bigint') {\n    return balanceValue;\n  } else {\n    return BigInt(0);\n  }\n}\n","import type { ChannelInfo, SignedSubRAV, SubChannelInfo, SubRAV } from './types';\nimport type { BillingContext, BillingRule } from '../billing';\nimport { PaymentErrorCode } from '../errors/codes';\nimport type { PendingSubRAVRepository } from '../storage/interfaces/PendingSubRAVRepository';\nimport type { RAVRepository } from '../storage/interfaces/RAVRepository';\nimport type { DIDDocument } from '@nuwa-ai/identity-kit';\nimport { SubRAVSigner } from './SubRav';\n\nexport interface RavVerifyDeps {\n  pendingRepo: PendingSubRAVRepository;\n  ravRepo: RAVRepository;\n  debug?: boolean;\n}\n\nexport type RavDecision = 'ALLOW' | 'REQUIRE_SIGNATURE_402' | 'CONFLICT' | 'CHANNEL_NOT_FOUND';\n\nexport interface RavVerifyResult {\n  decision: RavDecision;\n  signedVerified: boolean;\n  pendingMatched: boolean;\n  error?: { code: string; message: string };\n}\n\nexport interface RavVerifyParams {\n  channelInfo: ChannelInfo;\n  subChannelInfo: SubChannelInfo;\n  billingRule: BillingRule;\n  payerDidDoc: DIDDocument;\n  /** Signed SubRAV from client (optional in FREE mode) */\n  signedSubRav?: SignedSubRAV;\n  /** Latest pending SubRAV from pending repository, it should match the signed SubRAV */\n  latestPendingSubRav?: SubRAV;\n  /** Latest signed SubRAV from repository, it is the previous version of the signed SubRAV */\n  latestSignedSubRav?: SignedSubRAV;\n  /** Debug mode */\n  debug?: boolean;\n}\n\nexport async function verify(params: RavVerifyParams): Promise<RavVerifyResult> {\n  const result: RavVerifyResult = {\n    decision: 'ALLOW',\n    signedVerified: !params.signedSubRav, // default to true if no signedSubRav is provided\n    pendingMatched: false,\n  };\n\n  const signed = params.signedSubRav;\n  const billingRule = params.billingRule;\n  const isFreeRoute = !!billingRule && billingRule.paymentRequired === false;\n\n  // 3) signature verification (if SignedSubRAV is provided)\n  if (signed) {\n    const ok = await SubRAVSigner.verify(signed, { didDocument: params.payerDidDoc });\n    result.signedVerified = !!ok;\n    if (!ok) {\n      result.error = {\n        code: PaymentErrorCode.INVALID_SIGNATURE,\n        message: `Invalid signature for signed SubRAV`,\n      } as any;\n      return finalize();\n    }\n  }\n\n  // 2) pending priority check\n\n  if (params.latestPendingSubRav) {\n    if (!signed) {\n      if (!isFreeRoute) {\n        result.decision = 'REQUIRE_SIGNATURE_402';\n        result.error = {\n          code: PaymentErrorCode.PAYMENT_REQUIRED,\n          message: `Signature required for pending proposal (channel: ${params.channelInfo.channelId}, nonce: ${params.latestPendingSubRav.nonce})`,\n        } as any;\n        return finalize();\n      }\n    } else {\n      const matches =\n        signed.subRav.channelId === params.latestPendingSubRav.channelId &&\n        signed.subRav.vmIdFragment === params.latestPendingSubRav.vmIdFragment &&\n        signed.subRav.nonce === params.latestPendingSubRav.nonce;\n      if (!matches) {\n        result.decision = 'CONFLICT';\n        result.error = {\n          code: PaymentErrorCode.RAV_CONFLICT,\n          message: `SignedSubRAV does not match pending proposal (expected nonce: ${params.latestPendingSubRav.nonce}, received: ${signed.subRav.nonce})`,\n        } as any;\n        return finalize();\n      }\n      result.pendingMatched = true;\n    }\n  } else {\n    //if no pending, it means the server lost the pending proposal.\n    //we check the signed subrav with the latest signed subrav or subchannel state\n    if (signed) {\n      if (params.latestSignedSubRav) {\n        if (\n          signed.subRav.channelId === params.latestSignedSubRav.subRav.channelId &&\n          signed.subRav.vmIdFragment === params.latestSignedSubRav.subRav.vmIdFragment &&\n          signed.subRav.nonce > params.latestSignedSubRav.subRav.nonce &&\n          signed.subRav.accumulatedAmount > params.latestSignedSubRav.subRav.accumulatedAmount\n        ) {\n          result.decision = 'ALLOW';\n        } else if (\n          // Special case: Allow nonce that is exactly +1 from latest signed SubRAV\n          // This handles the race condition where server sent a proposal via in-band frame\n          // but hasn't persisted it to pendingSubRAVStore yet\n          signed.subRav.channelId === params.latestSignedSubRav.subRav.channelId &&\n          signed.subRav.vmIdFragment === params.latestSignedSubRav.subRav.vmIdFragment &&\n          signed.subRav.nonce === params.latestSignedSubRav.subRav.nonce + 1n &&\n          signed.subRav.accumulatedAmount >= params.latestSignedSubRav.subRav.accumulatedAmount\n        ) {\n          // TODO: This is a temporary workaround for the race condition in streaming responses\n          // where the in-band payment frame is sent before the pending SubRAV is persisted.\n          // A proper fix would be to ensure the pending SubRAV is saved before sending the frame.\n          result.decision = 'ALLOW';\n        } else {\n          result.decision = 'CONFLICT';\n          result.error = {\n            code: PaymentErrorCode.RAV_CONFLICT,\n            message: `SignedSubRAV does not match latest signed SubRAV (expected nonce: ${params.latestSignedSubRav.subRav.nonce}, received: ${signed.subRav.nonce})`,\n          } as any;\n          return finalize();\n        }\n      } else {\n        //there no latestSignedSubRav, it means the server lost the signed subrav.\n        //we check the signed subrav with the subchannel state\n        if (\n          signed.subRav.channelId === params.subChannelInfo.channelId &&\n          signed.subRav.vmIdFragment === params.subChannelInfo.vmIdFragment &&\n          signed.subRav.nonce > params.subChannelInfo.lastConfirmedNonce &&\n          signed.subRav.accumulatedAmount > params.subChannelInfo.lastClaimedAmount\n        ) {\n          result.decision = 'ALLOW';\n        } else {\n          result.decision = 'CONFLICT';\n          result.error = {\n            code: PaymentErrorCode.RAV_CONFLICT,\n            message: `SignedSubRAV does not match subchannel state (expected nonce: ${params.subChannelInfo.lastConfirmedNonce}, received: ${signed.subRav.nonce})`,\n          } as any;\n          return finalize();\n        }\n      }\n    }\n  }\n\n  return finalize();\n\n  function finalize(): RavVerifyResult {\n    // Leave detailed logging to caller using DebugLogger\n    return result;\n  }\n}\n","import type { SubRAV } from './types';\n\n/**\n * Payment utility functions that are used across different payment processors\n */\nexport class PaymentUtils {\n  /**\n   * Generate transaction reference\n   */\n  static generateTxRef(): string {\n    return `tx_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n  }\n\n  /**\n   * Check if two SubRAVs match (ignoring signature)\n   */\n  static subRAVsMatch(subRAV1: SubRAV, subRAV2: SubRAV): boolean {\n    return (\n      subRAV1.version === subRAV2.version &&\n      subRAV1.chainId === subRAV2.chainId &&\n      subRAV1.channelId === subRAV2.channelId &&\n      subRAV1.channelEpoch === subRAV2.channelEpoch &&\n      subRAV1.vmIdFragment === subRAV2.vmIdFragment &&\n      subRAV1.accumulatedAmount === subRAV2.accumulatedAmount &&\n      subRAV1.nonce === subRAV2.nonce\n    );\n  }\n\n  /**\n   * Generate unique ID for tracking\n   */\n  static generateId(prefix: string = ''): string {\n    const timestamp = Date.now().toString(36);\n    const random = Math.random().toString(36).substring(2, 9);\n    return prefix ? `${prefix}_${timestamp}_${random}` : `${timestamp}_${random}`;\n  }\n\n  /**\n   * Safe BigInt comparison\n   */\n  static compareBigInt(a: bigint, b: bigint): number {\n    if (a < b) return -1;\n    if (a > b) return 1;\n    return 0;\n  }\n}\n","/**\n * Chain-agnostic Payment Channel Payer Client\n *\n * This client provides a unified interface for payment channel operations\n * from the Payer perspective, using the IPaymentChannelContract abstraction.\n */\n\nimport type { AssetInfo, SubChannelInfo, ChannelInfo, SignedSubRAV, SubRAV } from '../core/types';\nimport type {\n  IPaymentChannelContract,\n  OpenChannelResult,\n  OpenChannelParams as ContractOpenChannelParams,\n  OpenChannelWithSubChannelParams as ContractOpenChannelWithSubChannelParams,\n} from '../contracts/IPaymentChannelContract';\nimport type { SignerInterface } from '@nuwa-ai/identity-kit';\nimport type { ChannelRepository } from '../storage/interfaces/ChannelRepository';\nimport { SubRAVSigner } from '../core/SubRav';\nimport { PaymentHubClient } from './PaymentHubClient';\n\nexport interface PayerOpenChannelParams {\n  payeeDid: string;\n  assetId: string;\n}\n\nexport interface PayerOpenChannelWithSubChannelParams {\n  payeeDid: string;\n  assetId: string;\n  vmIdFragment?: string;\n}\n\n/**\n * Storage options for PaymentChannelPayerClient\n */\nexport interface PayerStorageOptions {\n  channelRepo: ChannelRepository;\n}\n\nexport interface PaymentChannelPayerClientOptions {\n  contract: IPaymentChannelContract;\n  signer: SignerInterface;\n  keyId?: string;\n  storageOptions: PayerStorageOptions;\n}\n\nexport interface NextSubRAVOptions {\n  channelId?: string;\n  keyId?: string;\n}\n\nexport interface SignSubRAVOptions {\n  validateBeforeSigning?: boolean;\n  maxAmount?: bigint; // Optional: refuse to sign if amount exceeds this limit\n}\n\n/**\n * Chain-agnostic Payment Channel Payer Client\n *\n * Provides high-level APIs for payment channel operations from the Payer perspective:\n * - Opening channels and authorizing sub-channels\n * - Generating and managing SubRAVs\n * - Multi-channel support with flexible switching\n *\n * Uses composite keys (channelId:keyId) to avoid conflicts between channels.\n * Supports both single-channel (auto-select first active) and multi-channel usage.\n */\nexport class PaymentChannelPayerClient {\n  private contract: IPaymentChannelContract;\n  private signer: SignerInterface;\n  private keyId?: string;\n  private channelRepo: ChannelRepository;\n  private chainIdCache?: bigint;\n  private activeChannelId?: string;\n  private defaultAssetId: string;\n\n  constructor(options: PaymentChannelPayerClientOptions) {\n    this.contract = options.contract;\n    this.signer = options.signer;\n    this.keyId = options.keyId;\n    this.defaultAssetId = '0x3::gas_coin::RGas';\n    // Initialize storage\n    this.channelRepo = options.storageOptions.channelRepo;\n  }\n\n  // -------- Channel Management --------\n\n  /**\n   * Open a new payment channel\n   */\n  async openChannel(params: PayerOpenChannelParams): Promise<ChannelInfo> {\n    const payerDid = await this.signer.getDid();\n\n    const openParams: ContractOpenChannelParams = {\n      payerDid,\n      payeeDid: params.payeeDid,\n      assetId: params.assetId,\n      signer: this.signer,\n    };\n\n    const result = await this.contract.openChannel(openParams);\n\n    const channelInfo: ChannelInfo = {\n      channelId: result.channelId,\n      payerDid,\n      payeeDid: params.payeeDid,\n      assetId: params.assetId,\n      epoch: BigInt(0),\n      status: 'active',\n    };\n\n    // Cache channel metadata using channelId as key\n    await this.channelRepo.setChannelMetadata(result.channelId, channelInfo);\n\n    // Set as active channel if no active channel is set\n    if (!this.activeChannelId) {\n      this.activeChannelId = result.channelId;\n    }\n\n    return channelInfo;\n  }\n\n  /**\n   * Open a payment channel with a sub-channel in one transaction\n   */\n  async openChannelWithSubChannel(\n    params: PayerOpenChannelWithSubChannelParams\n  ): Promise<OpenChannelResult> {\n    const payerDid = await this.signer.getDid();\n    const useFragment = params.vmIdFragment || this.extractFragment(this.keyId || '');\n\n    const openParams: ContractOpenChannelWithSubChannelParams = {\n      payerDid,\n      payeeDid: params.payeeDid,\n      assetId: params.assetId,\n      vmIdFragment: useFragment,\n      signer: this.signer,\n    };\n\n    const result = await this.contract.openChannelWithSubChannel(openParams);\n\n    // Cache channel metadata\n    const metadata: ChannelInfo = {\n      channelId: result.channelId,\n      payerDid,\n      payeeDid: params.payeeDid,\n      assetId: params.assetId,\n      epoch: BigInt(0),\n      status: 'active',\n    };\n\n    await this.channelRepo.setChannelMetadata(result.channelId, metadata);\n\n    // Initialize sub-channel state for this key\n    await this.channelRepo.updateSubChannelState(result.channelId, useFragment, {\n      channelId: result.channelId,\n      epoch: BigInt(0),\n      vmIdFragment: useFragment,\n      lastClaimedAmount: BigInt(0),\n      lastConfirmedNonce: BigInt(0),\n      lastUpdated: Date.now(),\n    });\n\n    // Set as active channel if no active channel is set\n    if (!this.activeChannelId) {\n      this.activeChannelId = result.channelId;\n    }\n\n    return result;\n  }\n\n  /**\n   * Authorize a sub-channel for an existing channel\n   */\n  async authorizeSubChannel(params: { channelId: string; vmIdFragment?: string }): Promise<void> {\n    const payerDid = await this.signer.getDid();\n    const useFragment = params.vmIdFragment || this.extractFragment(this.keyId || '');\n\n    await this.contract.authorizeSubChannel({\n      channelId: params.channelId,\n      vmIdFragment: useFragment,\n      signer: this.signer,\n    });\n\n    // Initialize sub-channel state\n    await this.channelRepo.updateSubChannelState(params.channelId, useFragment, {\n      channelId: params.channelId,\n      epoch: BigInt(0),\n      vmIdFragment: useFragment,\n      lastClaimedAmount: BigInt(0),\n      lastConfirmedNonce: BigInt(0),\n      lastUpdated: Date.now(),\n    });\n  }\n\n  /**\n   * Set the active channel for subsequent operations\n   * This is a convenience method for single-channel usage patterns\n   */\n  async setActiveChannel(channelId: string): Promise<void> {\n    // Verify the channel exists and is active\n    const metadata = await this.channelRepo.getChannelMetadata(channelId);\n    if (!metadata) {\n      throw new Error(`Channel ${channelId} not found in local storage`);\n    }\n    if (metadata.status !== 'active') {\n      throw new Error(`Channel ${channelId} is not active (status: ${metadata.status})`);\n    }\n\n    this.activeChannelId = channelId;\n  }\n\n  // -------- SubRAV Signing (for API clients) --------\n\n  /**\n   * Sign a SubRAV generated by a service provider\n   * The caller should validate the SubRAV with previous rav before signing it\n   * This is used by API clients to approve payment requests from services\n   */\n  async signSubRAV(subRAV: SubRAV): Promise<SignedSubRAV> {\n    await this.validateSubRAV(subRAV);\n    // Determine which key to use for signing\n    const payerDid = await this.signer.getDid();\n    const expectedKeyId = `${payerDid}#${subRAV.vmIdFragment}`;\n\n    // Use the keyId that matches the SubRAV's vmIdFragment\n    const useKeyId = this.keyId || expectedKeyId;\n\n    // Verify that our keyId matches the SubRAV\n    const ourFragment = this.extractFragment(useKeyId);\n    if (ourFragment !== subRAV.vmIdFragment) {\n      throw new Error(`Key fragment mismatch: our ${ourFragment}, SubRAV ${subRAV.vmIdFragment}`);\n    }\n\n    // Sign the SubRAV\n    const signedSubRAV = SubRAVSigner.sign(subRAV, this.signer, useKeyId);\n\n    return signedSubRAV;\n  }\n\n  /**\n   * Validate a SubRAV via on chain information\n   */\n  private async validateSubRAV(subRAV: SubRAV): Promise<void> {\n    // 1. Verify channel exists and is active\n    const channelInfo = await this.contract.getChannelStatus({ channelId: subRAV.channelId });\n\n    // 2. Verify epoch matches\n    if (channelInfo.epoch !== subRAV.channelEpoch) {\n      throw new Error(\n        `Epoch mismatch: channel ${channelInfo.epoch}, SubRAV ${subRAV.channelEpoch}`\n      );\n    }\n\n    // When the subchannel is created, the nonce is 0\n    if (subRAV.nonce === BigInt(0)) {\n      throw new Error(`SubRAV nonce cannot be 0`);\n    }\n\n    const expectedChainId = await this.getChainId();\n    if (subRAV.chainId !== expectedChainId) {\n      throw new Error(`Chain ID mismatch: expected ${expectedChainId}, got ${subRAV.chainId}`);\n    }\n  }\n\n  /**\n   * Get a PaymentHubClient instance that reuses this client's contract and signer\n   * This is the recommended way to access payment hub operations\n   */\n  getHubClient(): PaymentHubClient {\n    return new PaymentHubClient({\n      contract: this.contract,\n      signer: this.signer,\n      defaultAssetId: this.defaultAssetId,\n    });\n  }\n\n  /**\n   * Close a payment channel\n   */\n  async closeChannel(channelId: string, cooperative: boolean = true): Promise<{ txHash: string }> {\n    const result = await this.contract.closeChannel({\n      channelId,\n      cooperative,\n      signer: this.signer,\n    });\n\n    // Update cache to mark channel as closed\n    const metadata = await this.channelRepo.getChannelMetadata(channelId);\n    if (metadata) {\n      metadata.status = 'closed';\n      await this.channelRepo.setChannelMetadata(channelId, metadata);\n    }\n\n    // Clear active channel if this was the active one\n    if (this.activeChannelId === channelId) {\n      this.activeChannelId = undefined;\n    }\n\n    return { txHash: result.txHash };\n  }\n\n  /**\n   * Get channel information\n   */\n  async getChannelInfo(channelId: string): Promise<ChannelInfo> {\n    return this.contract.getChannelStatus({ channelId });\n  }\n\n  /**\n   * Get channels for the current payer\n   */\n  async getChannelsByPayer(payerDid: string): Promise<ChannelInfo[]> {\n    const result = await this.channelRepo.listChannelMetadata({ payerDid });\n    return result.items;\n  }\n\n  /**\n   * Get the currently active channel ID\n   */\n  getActiveChannelId(): string | undefined {\n    return this.activeChannelId;\n  }\n\n  getContract(): IPaymentChannelContract {\n    return this.contract;\n  }\n\n  // -------- Asset Information --------\n\n  /**\n   * Get asset information\n   */\n  async getAssetInfo(assetId: string): Promise<AssetInfo> {\n    return this.contract.getAssetInfo(assetId);\n  }\n\n  /**\n   * Get asset price in pUSD\n   */\n  async getAssetPrice(assetId: string): Promise<bigint> {\n    return this.contract.getAssetPrice(assetId);\n  }\n\n  public async getChainId(): Promise<bigint> {\n    if (this.chainIdCache === undefined) {\n      this.chainIdCache = await this.contract.getChainId();\n    }\n    return this.chainIdCache;\n  }\n\n  /**\n   * Get on-chain sub-channel info (state) for the specified vmIdFragment\n   */\n  async getSubChannelInfo(channelId: string, vmIdFragment: string): Promise<SubChannelInfo> {\n    return this.contract.getSubChannel({ channelId, vmIdFragment });\n  }\n\n  // -------- Private Helpers --------\n\n  /**\n   * Extract fragment from full key ID\n   */\n  private extractFragment(keyId: string): string {\n    const parts = keyId.split('#');\n    return parts[parts.length - 1] || keyId;\n  }\n}\n","import { BaseRateProvider, RateProviderError, RateNotFoundError } from './types';\nimport { AssetInfo } from '../../core/types';\nimport { DebugLogger } from '@nuwa-ai/identity-kit';\nimport type { IPaymentChannelContract } from '../../contracts/IPaymentChannelContract';\n\n/**\n * Contract-based rate provider that uses on-chain oracle/swap prices\n *\n * This provider leverages the payment channel contract's getAssetPrice() method\n * to fetch real-time prices from on-chain sources like oracles or DEX pools.\n */\nexport class ContractRateProvider extends BaseRateProvider {\n  private contract: IPaymentChannelContract;\n  private logger: DebugLogger;\n\n  constructor(\n    contract: IPaymentChannelContract,\n    cacheTimeoutMs = 30000 // 30 seconds default for on-chain data\n  ) {\n    super(cacheTimeoutMs);\n    this.contract = contract;\n    this.logger = DebugLogger.get('ContractRateProvider');\n  }\n\n  async getPricePicoUSD(assetId: string): Promise<bigint> {\n    // Check cache first\n    const cached = this.getCachedPrice(assetId);\n    if (cached !== null) {\n      return cached;\n    }\n\n    try {\n      // Get price from contract (already in picoUSD)\n      const pricePicoUsd = await this.contract.getAssetPrice(assetId);\n\n      if (pricePicoUsd <= 0n) {\n        throw new RateNotFoundError(\n          `Contract returned invalid price for ${assetId}: ${pricePicoUsd}`,\n          assetId\n        );\n      }\n\n      // Get asset info for caching\n      let assetInfo: AssetInfo | undefined;\n      try {\n        assetInfo = await this.contract.getAssetInfo(assetId);\n      } catch (error) {\n        this.logger.warn(`Failed to get asset info for ${assetId}, using price only:`, error);\n      }\n\n      // Cache the result\n      this.updateCache(assetId, pricePicoUsd, assetInfo);\n\n      return pricePicoUsd;\n    } catch (error) {\n      // Try to return stale cache as fallback\n      const staleCache = this.cache.get(assetId);\n      if (staleCache) {\n        this.logger.warn(`Using stale contract price cache for ${assetId} due to error:`, error);\n        return staleCache.price;\n      }\n\n      if (error instanceof RateProviderError) {\n        throw error;\n      }\n      throw new RateProviderError(`Failed to get contract price for ${assetId}: ${error}`, assetId);\n    }\n  }\n\n  async getAssetInfo(assetId: string): Promise<AssetInfo | null> {\n    // Check cache first\n    const cached = this.cache.get(assetId);\n    if (cached?.assetInfo) {\n      return cached.assetInfo;\n    }\n\n    try {\n      // Get asset info from contract\n      const info = await this.contract.getAssetInfo(assetId);\n\n      // Cache the result\n      this.updateCache(assetId, cached?.price || 0n, info);\n      return info;\n    } catch (error) {\n      this.logger.warn(`Failed to get asset info for ${assetId}:`, error);\n      throw error;\n    }\n  }\n\n  /**\n   * Force refresh price from contract (bypass cache)\n   */\n  async refreshPrice(assetId: string): Promise<bigint> {\n    this.clearCache(assetId);\n    return this.getPricePicoUSD(assetId);\n  }\n\n  /**\n   * Get current chain ID from contract\n   */\n  async getChainId(): Promise<bigint> {\n    return this.contract.getChainId();\n  }\n}\n","/**\n * PaymentHub Client\n *\n * This client provides a unified interface for payment hub operations,\n * focusing solely on deposit, withdraw, and balance management.\n * It's designed to be created from PaymentChannelPayerClient or PaymentChannelPayeeClient\n * to reuse the same contract instance and signer.\n */\n\nimport type { SignerInterface } from '@nuwa-ai/identity-kit';\nimport type {\n  IPaymentChannelContract,\n  DepositParams,\n  WithdrawParams,\n} from '../contracts/IPaymentChannelContract';\nimport type { RateProvider } from '../billing/rate/types';\nimport { ContractRateProvider } from '../billing/rate/contract';\n\nexport interface PaymentHubClientOptions {\n  contract: IPaymentChannelContract;\n  signer: SignerInterface;\n  defaultAssetId: string;\n  rateProvider?: RateProvider;\n}\n\nexport interface BalanceOptions {\n  ownerDid?: string;\n  assetId?: string;\n}\n\nexport interface HasBalanceOptions extends BalanceOptions {\n  requiredAmount?: bigint;\n}\n\n/**\n * Chain-agnostic Payment Hub Client\n *\n * Provides high-level APIs for payment hub operations:\n * - Depositing funds to hub\n * - Withdrawing funds from hub\n * - Querying hub balances\n *\n * This client operates independently of specific channels or VM keys,\n * focusing purely on the DID-level hub management.\n */\nexport class PaymentHubClient {\n  private contract: IPaymentChannelContract;\n  private signer: SignerInterface;\n  private defaultAssetId: string;\n  private rateProvider: RateProvider;\n\n  constructor(options: PaymentHubClientOptions) {\n    this.contract = options.contract;\n    this.signer = options.signer;\n    this.defaultAssetId = options.defaultAssetId;\n    this.rateProvider = options.rateProvider || new ContractRateProvider(this.contract);\n  }\n\n  // -------- Hub Operations --------\n\n  /**\n   * Deposit funds to the payment hub for the current signer\n   */\n  async deposit(assetId: string, amount: bigint, ownerDid?: string): Promise<{ txHash: string }> {\n    if (!ownerDid) {\n      ownerDid = await this.signer.getDid();\n    }\n    const params: DepositParams = {\n      ownerDid,\n      assetId,\n      amount,\n      signer: this.signer,\n    };\n\n    const result = await this.contract.depositToHub(params);\n    return { txHash: result.txHash };\n  }\n\n  /**\n   * Withdraw funds from the payment hub to the owner's account\n   * @param assetId Asset to withdraw\n   * @param amount Amount to withdraw (0 = withdraw all)\n   * @param recipient Optional recipient address/DID (defaults to owner's account)\n   */\n  async withdraw(assetId: string, amount: bigint, recipient?: string): Promise<{ txHash: string }> {\n    const ownerDid = await this.signer.getDid();\n\n    const params: WithdrawParams = {\n      ownerDid,\n      assetId,\n      amount,\n      recipient,\n      signer: this.signer,\n    };\n\n    const result = await this.contract.withdrawFromHub(params);\n    return { txHash: result.txHash };\n  }\n\n  /**\n   * Get balance of a specific asset in the payment hub\n   */\n  async getBalance(options: BalanceOptions = {}): Promise<bigint> {\n    const ownerDid = options.ownerDid || (await this.signer.getDid());\n    const assetId = options.assetId || this.defaultAssetId;\n    return this.contract.getHubBalance(ownerDid, assetId);\n  }\n\n  /**\n   * Get balance and its value in picoUSD using a rate provider.\n   * Returns: { assetId, balance, pricePicoUSD, balancePicoUSD }\n   */\n  async getBalanceWithUsd(options: BalanceOptions = {}): Promise<{\n    assetId: string;\n    balance: bigint;\n    pricePicoUSD: bigint;\n    balancePicoUSD: bigint;\n  }> {\n    const ownerDid = options.ownerDid || (await this.signer.getDid());\n    const assetId = options.assetId || this.defaultAssetId;\n    const balance = await this.contract.getHubBalance(ownerDid, assetId);\n\n    const pricePicoUSD = await this.rateProvider.getPricePicoUSD(assetId);\n    const balancePicoUSD = balance * pricePicoUSD;\n\n    return { assetId, balance, pricePicoUSD, balancePicoUSD };\n  }\n\n  /**\n   * Get all balances in the hub for all assets\n   */\n  async getAllBalances(ownerDid?: string): Promise<Record<string, bigint>> {\n    if (!ownerDid) {\n      ownerDid = await this.signer.getDid();\n    }\n    return this.contract.getAllHubBalances(ownerDid);\n  }\n\n  /**\n   * Get active channels counts for all assets\n   */\n  async getActiveChannelsCounts(ownerDid?: string): Promise<Record<string, number>> {\n    if (!ownerDid) {\n      ownerDid = await this.signer.getDid();\n    }\n    return this.contract.getActiveChannelsCounts(ownerDid);\n  }\n\n  /**\n   * Check if hub has sufficient balance for a payment\n   */\n  async hasBalance(options: HasBalanceOptions = {}): Promise<boolean> {\n    const { requiredAmount = BigInt(0), ...balanceOptions } = options;\n    const balance = await this.getBalance(balanceOptions);\n    return balance >= requiredAmount;\n  }\n}\n","/**\n * Chain-agnostic Payment Channel Payee Client\n *\n * This client provides a unified interface for payment channel operations\n * from the Payee perspective, using the IPaymentChannelContract abstraction.\n */\n\nimport type { AssetInfo, SubChannelInfo, ChannelInfo, SignedSubRAV, SubRAV } from '../core/types';\nimport type { IPaymentChannelContract, ClaimResult } from '../contracts/IPaymentChannelContract';\nimport type { SignerInterface, DIDResolver } from '@nuwa-ai/identity-kit';\nimport type { ChannelRepository, RAVRepository, PendingSubRAVRepository } from '../storage';\nimport { SubRAVUtils } from '../core/SubRav';\nimport { PaymentUtils } from '../core/PaymentUtils';\nimport { PaymentHubClient } from './PaymentHubClient';\n\n/**\n * Storage options for PaymentChannelPayeeClient\n */\nexport interface PayeeStorageOptions {\n  channelRepo: ChannelRepository;\n  ravRepo: RAVRepository;\n  pendingSubRAVRepo: PendingSubRAVRepository;\n}\n\nexport interface PaymentChannelPayeeClientOptions {\n  contract: IPaymentChannelContract;\n  signer: SignerInterface;\n  didResolver: DIDResolver; // Required for signature verification\n  storageOptions: PayeeStorageOptions;\n}\n\nexport interface VerificationResult {\n  isValid: boolean;\n  error?: string;\n  details?: {\n    signatureValid: boolean;\n    channelExists: boolean;\n    epochMatches: boolean;\n    nonceProgression: boolean;\n    amountValid: boolean;\n  };\n}\n\nexport interface ClaimOptions {\n  signedSubRAV: SignedSubRAV;\n}\n\nexport interface GenerateSubRAVParams {\n  channelId: string;\n  payerKeyId: string; // Full keyId like \"did:example:payer#key1\"\n  amount: bigint;\n  description?: string; // Optional description for the charge\n}\n\nexport interface ListChannelsOptions {\n  status?: 'active' | 'closed' | 'closing';\n  offset?: number;\n  limit?: number;\n}\n\n/**\n * Chain-agnostic Payment Channel Payee Client\n *\n * Provides high-level APIs for payment channel operations from the Payee perspective:\n * - Verifying received SubRAVs\n * - Claiming payments from channels\n * - Managing channel lifecycle from payee side\n * - Monitoring channel states and balances\n *\n * This client is designed to be used by service providers who need to:\n * 1. Validate incoming payment receipts (SubRAVs)\n * 2. Submit claims to retrieve payments\n * 3. Monitor and manage payment channels\n */\nexport class PaymentChannelPayeeClient {\n  private contract: IPaymentChannelContract;\n  private signer: SignerInterface;\n  private didResolver: DIDResolver;\n  private channelRepo: ChannelRepository;\n  private ravRepo: RAVRepository;\n  private pendingSubRAVRepo: PendingSubRAVRepository;\n  private chainIdCache?: bigint;\n  private defaultAssetId: string;\n\n  constructor(options: PaymentChannelPayeeClientOptions) {\n    this.contract = options.contract;\n    this.signer = options.signer;\n    this.didResolver = options.didResolver;\n    this.defaultAssetId = '0x3::gas_coin::RGas';\n\n    // Initialize repositories\n    this.channelRepo = options.storageOptions.channelRepo;\n    this.ravRepo = options.storageOptions.ravRepo;\n    this.pendingSubRAVRepo = options.storageOptions.pendingSubRAVRepo;\n  }\n\n  // -------- Public accessors for internal components --------\n\n  /**\n   * Get the RAV repository used by this client\n   * This is needed for ClaimScheduler to access the same RAV data\n   */\n  getRAVRepository(): RAVRepository {\n    return this.ravRepo;\n  }\n\n  getDidResolver(): DIDResolver {\n    return this.didResolver;\n  }\n\n  /**\n   * Get the contract instance used by this client\n   * This is needed for ClaimScheduler to perform claims\n   */\n  getContract(): IPaymentChannelContract {\n    return this.contract;\n  }\n\n  /**\n   * Get the channel repository used by this client\n   */\n  getChannelRepository(): ChannelRepository {\n    return this.channelRepo;\n  }\n\n  /**\n   * Get sub-channel state by (channelId, vmIdFragment)\n   * If not found locally, try deriving from on-chain and sync into repository.\n   */\n  async getSubChannelState(\n    channelId: string,\n    vmIdFragment: string\n  ): Promise<SubChannelInfo | null> {\n    // 1) Try local repository first (no side effects)\n    const local = await this.channelRepo.getSubChannelState(channelId, vmIdFragment);\n    if (local) return local;\n\n    // 2) Fallback to chain: derive baseline (sync-from-chain is allowed to update repo)\n    try {\n      const [channelInfo, subInfo] = await Promise.all([\n        this.getChannelInfoCached(channelId),\n        this.contract.getSubChannel({ channelId, vmIdFragment }),\n      ]);\n\n      const derived: SubChannelInfo = {\n        channelId,\n        epoch: channelInfo.epoch,\n        vmIdFragment: subInfo.vmIdFragment,\n        lastClaimedAmount: subInfo.lastClaimedAmount,\n        lastConfirmedNonce: subInfo.lastConfirmedNonce,\n        lastUpdated: Date.now(),\n      };\n\n      // Sync to local repository as it's sourced from chain\n      await this.channelRepo.updateSubChannelState(channelId, vmIdFragment, derived);\n      return derived;\n    } catch {\n      // Chain fallback failed (e.g., sub-channel not authorized yet)\n      return null;\n    }\n  }\n\n  /**\n   * Get the payee DID from this client's signer\n   */\n  async getPayeeDid(): Promise<string> {\n    return await this.signer.getDid();\n  }\n\n  /**\n   * Get the pending SubRAV repository used by this client\n   */\n  getPendingSubRAVRepository(): PendingSubRAVRepository {\n    return this.pendingSubRAVRepo;\n  }\n\n  // -------- Claims Management --------\n\n  /**\n   * Claim payment from a channel using a signed SubRAV\n   */\n  async claimFromChannel(options: ClaimOptions): Promise<ClaimResult> {\n    const { signedSubRAV } = options;\n\n    // Submit claim to blockchain\n    const claimParams = {\n      signedSubRAV,\n      signer: this.signer,\n    };\n\n    const result = await this.contract.claimFromChannel(claimParams);\n    return result;\n  }\n\n  /**\n   * Batch claim multiple SubRAVs\n   * Falls back to individual claims\n   */\n  async batchClaimFromChannels(signedSubRAVs: SignedSubRAV[]): Promise<ClaimResult[]> {\n    const results: ClaimResult[] = [];\n\n    for (const signedSubRAV of signedSubRAVs) {\n      try {\n        const result = await this.claimFromChannel({ signedSubRAV });\n        results.push(result);\n      } catch (error) {\n        // Continue with other claims even if one fails\n        throw error;\n      }\n    }\n\n    return results;\n  }\n\n  // -------- Channel Management --------\n\n  /**\n   * Close a payment channel (from payee side)\n   */\n  async closeChannel(channelId: string, cooperative: boolean = true): Promise<{ txHash: string }> {\n    const result = await this.contract.closeChannel({\n      channelId,\n      cooperative,\n      signer: this.signer,\n    });\n\n    // Update local cache to mark channel as closed\n    const metadata = await this.channelRepo.getChannelMetadata(channelId);\n    if (metadata) {\n      metadata.status = 'closed';\n      await this.channelRepo.setChannelMetadata(channelId, metadata);\n    }\n\n    return { txHash: result.txHash };\n  }\n\n  /**\n   * Get channel information\n   */\n  async getChannelInfo(channelId: string): Promise<ChannelInfo> {\n    return this.contract.getChannelStatus({ channelId });\n  }\n\n  /**\n   * Get channel info with caching using ChannelRepository\n   * This checks local storage first, then falls back to chain if not found or stale\n   */\n  private async getChannelInfoCached(\n    channelId: string,\n    forceRefresh: boolean = false\n  ): Promise<ChannelInfo> {\n    // Try to get from local storage first (unless forced refresh)\n    if (!forceRefresh) {\n      const cachedMetadata = await this.channelRepo.getChannelMetadata(channelId);\n      if (cachedMetadata) {\n        // Convert ChannelMetadata to ChannelInfo\n        return cachedMetadata;\n      }\n    }\n\n    // Fetch from chain and cache\n    try {\n      const channelInfo = await this.contract.getChannelStatus({ channelId });\n\n      // Store in cache as ChannelMetadata\n      await this.channelRepo.setChannelMetadata(channelId, channelInfo);\n\n      return channelInfo;\n    } catch (error) {\n      // If chain call fails and we have stale cache, use it\n      if (!forceRefresh) {\n        const staleMetadata = await this.channelRepo.getChannelMetadata(channelId);\n        if (staleMetadata) {\n          return staleMetadata;\n        }\n      }\n      throw error;\n    }\n  }\n\n  /**\n   * List active channels where this payee is involved\n   */\n  async listActiveChannels(options: ListChannelsOptions = {}): Promise<ChannelInfo[]> {\n    const payeeDid = await this.signer.getDid();\n\n    // Get channels from storage first\n    const storageResult = await this.channelRepo.listChannelMetadata(\n      {\n        payeeDid,\n        status: options.status || 'active',\n      },\n      {\n        offset: options.offset || 0,\n        limit: options.limit || 50,\n      }\n    );\n\n    // Get current status for each channel (using cache for efficiency)\n    const channelInfos: ChannelInfo[] = [];\n    for (const metadata of storageResult.items) {\n      try {\n        const info = await this.getChannelInfoCached(metadata.channelId);\n        channelInfos.push(info);\n      } catch (error) {}\n    }\n\n    return channelInfos;\n  }\n\n  /**\n   * Sync channel state from blockchain to local storage\n   * This force-refreshes the cached channel metadata\n   */\n  async syncChannelState(channelId: string): Promise<void> {\n    try {\n      // Force refresh from chain and update cache\n      await this.getChannelInfoCached(channelId, true);\n    } catch (error) {\n      throw error;\n    }\n  }\n\n  // -------- Asset Information --------\n\n  /**\n   * Get asset information\n   */\n  async getAssetInfo(assetId: string): Promise<AssetInfo> {\n    return this.contract.getAssetInfo(assetId);\n  }\n\n  /**\n   * Get asset price in pUSD\n   */\n  async getAssetPrice(assetId: string): Promise<bigint> {\n    return this.contract.getAssetPrice(assetId);\n  }\n\n  // -------- Private Helpers --------\n\n  /**\n   * Extract vmIdFragment from full keyId (e.g., \"did:example:payer#key1\" → \"key1\")\n   */\n  private extractVmIdFragment(keyId: string): string {\n    const parts = keyId.split('#');\n    if (parts.length !== 2) {\n      throw new Error(\n        `Invalid keyId format: ${keyId}. Expected format: \"did:example:payer#fragment\"`\n      );\n    }\n    return parts[1];\n  }\n\n  /**\n   * Get cached chain ID or fetch from contract\n   */\n  private async getChainId(): Promise<bigint> {\n    if (this.chainIdCache === undefined) {\n      this.chainIdCache = await this.contract.getChainId();\n    }\n    return this.chainIdCache;\n  }\n\n  /**\n   * Get a PaymentHubClient instance that reuses this client's contract and signer\n   * Primarily useful for balance queries and withdraw operations on the payee side\n   */\n  getHubClient(): PaymentHubClient {\n    return new PaymentHubClient({\n      contract: this.contract,\n      signer: this.signer,\n      defaultAssetId: this.defaultAssetId,\n    });\n  }\n\n  /**\n   * Get channel health metrics\n   */\n  async getChannelHealth(channelId: string): Promise<{\n    isHealthy: boolean;\n    issues: string[];\n    lastActivity?: Date;\n    pendingClaims: number;\n  }> {\n    const issues: string[] = [];\n\n    try {\n      const channelInfo = await this.getChannelInfoCached(channelId);\n\n      // Check if channel is closed\n      if (channelInfo.status === 'closed') {\n        issues.push('Channel is closed');\n      }\n\n      // Check if channel is closing\n      if (channelInfo.status === 'closing') {\n        issues.push('Channel is in closing state');\n      }\n\n      // In production, add more health checks like:\n      // - Check for stuck transactions\n      // - Monitor claim success rates\n      // - Check for unusual nonce gaps\n\n      return {\n        isHealthy: issues.length === 0,\n        issues,\n        pendingClaims: 0, // Would query from contract/storage\n      };\n    } catch (error) {\n      return {\n        isHealthy: false,\n        issues: [`Channel access failed: ${error}`],\n        pendingClaims: 0,\n      };\n    }\n  }\n}\n","/**\n * Rooch Payment Channel Contract Implementation\n *\n * Implementation of IPaymentChannelContract for Rooch blockchain.\n * Provides concrete implementation of payment channel operations using Rooch SDK.\n */\n\nimport {\n  RoochClient,\n  Transaction,\n  Args,\n  Signer,\n  EventView,\n  getRoochNodeUrl,\n  type NetworkType,\n  Serializer,\n  normalizeRoochAddress,\n  sha3_256,\n  toHEX,\n  RoochAddress,\n} from '@roochnetwork/rooch-sdk';\nimport { bcs } from '@roochnetwork/rooch-sdk';\n\nimport type {\n  IPaymentChannelContract,\n  OpenChannelParams,\n  OpenChannelResult,\n  OpenChannelWithSubChannelParams,\n  AuthorizeSubChannelParams,\n  TxResult,\n  ClaimParams,\n  ClaimResult,\n  CloseParams,\n  ChannelStatusParams,\n  SubChannelParams,\n  SubChannelInfo,\n  DepositParams,\n  WithdrawParams,\n} from '../contracts/IPaymentChannelContract';\nimport type { AssetInfo, SignedSubRAV, SubRAV, ChannelInfo } from '../core/types';\nimport { SubRAVCodec } from '../core/SubRav';\nimport {\n  calcChannelObjectId,\n  normalizeAssetId,\n  calculatePaymentHubId,\n  deriveFieldKeyFromString,\n  deriveCoinTypeFieldKey,\n  parsePaymentChannelData,\n  parsePaymentHubData,\n  parseDynamicFieldSubChannel,\n  parseDynamicFieldCoinStore,\n  parseDynamicFieldU64,\n  safeBalanceToBigint,\n  PaymentChannelData,\n  PaymentHub,\n  SubChannel,\n  DynamicField,\n  CoinStoreFieldData,\n} from './ChannelUtils';\nimport { DebugLogger, SignerInterface, DidAccountSigner, parseDid } from '@nuwa-ai/identity-kit';\n\nexport interface RoochContractOptions {\n  rpcUrl?: string;\n  network?: 'local' | 'dev' | 'test' | 'main';\n  contractAddress?: string;\n  debug?: boolean;\n}\n\n// BCS Schema definitions for Rooch Move types\nexport const CloseProofSchema: any = bcs.struct('CloseProof', {\n  vm_id_fragment: bcs.string(),\n  accumulated_amount: bcs.u256(),\n  nonce: bcs.u64(),\n  sender_signature: bcs.vector(bcs.u8()),\n});\n\nexport const CloseProofsSchema: any = bcs.struct('CloseProofs', {\n  proofs: bcs.vector(CloseProofSchema),\n});\n\nexport const CancelProofSchema: any = bcs.struct('CancelProof', {\n  vm_id_fragment: bcs.string(),\n  accumulated_amount: bcs.u256(),\n  nonce: bcs.u64(),\n});\n\nexport const CancelProofsSchema: any = bcs.struct('CancelProofs', {\n  proofs: bcs.vector(CancelProofSchema),\n});\n\n// BCS Schema definitions are now in ChannelUtils.ts\n\nconst RGAS_CANONICAL_TAG: string =\n  '0x0000000000000000000000000000000000000000000000000000000000000003::gas_coin::RGas';\n\n/**\n * Default contract address for Rooch payment channels\n */\nconst DEFAULT_PAYMENT_CHANNEL_MODULE = '0x3::payment_channel';\n\n/**\n * Rooch implementation of the Payment Channel Contract\n *\n * This implementation provides complete functionality for payment channels\n * using the Rooch blockchain and corresponding Move contracts.\n */\nexport class RoochPaymentChannelContract implements IPaymentChannelContract {\n  private client: RoochClient;\n  private contractAddress: string;\n  private logger: DebugLogger;\n\n  constructor(options: RoochContractOptions = {}) {\n    const rpcUrl = options.rpcUrl || this.getDefaultRpcUrl(options.network || 'test');\n    this.client = new RoochClient({ url: rpcUrl });\n    this.contractAddress = options.contractAddress || DEFAULT_PAYMENT_CHANNEL_MODULE;\n    this.logger = DebugLogger.get('RoochPaymentChannelContract');\n\n    if (options.debug) {\n      this.logger.setLevel('debug');\n    }\n\n    this.logger.debug(`RoochPaymentChannelContract initialized with rpcUrl: ${rpcUrl}`);\n  }\n\n  async openChannel(params: OpenChannelParams): Promise<OpenChannelResult> {\n    try {\n      this.logger.debug('Opening payment channel with params:', params);\n\n      // Parse and validate DIDs first\n      const payerParsed = parseDid(params.payerDid);\n      const payeeParsed = parseDid(params.payeeDid);\n\n      if (payerParsed.method !== 'rooch') {\n        throw new Error(`Invalid payer DID method: expected 'rooch', got '${payerParsed.method}'`);\n      }\n      if (payeeParsed.method !== 'rooch') {\n        throw new Error(`Invalid payee DID method: expected 'rooch', got '${payeeParsed.method}'`);\n      }\n\n      const signer = await this.convertSigner(params.signer);\n\n      // Create transaction to open channel\n      const transaction = this.createTransaction();\n      transaction.callFunction({\n        target: `${this.contractAddress}::open_channel_entry`,\n        typeArgs: [params.assetId], // CoinType as type argument\n        args: [Args.address(payeeParsed.identifier)],\n        maxGas: 100000000,\n      });\n\n      this.logger.debug('Executing openChannel transaction');\n\n      // Execute transaction\n      const result = await this.client.signAndExecuteTransaction({\n        transaction,\n        signer,\n        option: { withOutput: true },\n      });\n\n      if (result.execution_info.status.type !== 'executed') {\n        throw new Error(`Transaction failed: ${JSON.stringify(result.execution_info)}`);\n      }\n\n      // Calculate the expected channel ID deterministically\n      const channelId = calcChannelObjectId(\n        payerParsed.identifier,\n        payeeParsed.identifier,\n        params.assetId\n      );\n\n      return {\n        channelId,\n        txHash: result.execution_info.tx_hash || '',\n        blockHeight: BigInt(0), // TODO: Extract from result if available\n        events: result.output?.events,\n      };\n    } catch (error) {\n      this.logger.error('Error opening channel:', error);\n      throw error;\n    }\n  }\n\n  async openChannelWithSubChannel(\n    params: OpenChannelWithSubChannelParams\n  ): Promise<OpenChannelResult> {\n    try {\n      this.logger.debug('Opening payment channel with sub-channel in one step:', params);\n\n      // Parse and validate DIDs first\n      const payerParsed = parseDid(params.payerDid);\n      const payeeParsed = parseDid(params.payeeDid);\n\n      if (payerParsed.method !== 'rooch') {\n        throw new Error(`Invalid payer DID method: expected 'rooch', got '${payerParsed.method}'`);\n      }\n      if (payeeParsed.method !== 'rooch') {\n        throw new Error(`Invalid payee DID method: expected 'rooch', got '${payeeParsed.method}'`);\n      }\n\n      const signer = await this.convertSigner(params.signer);\n\n      // Create transaction to open channel with sub-channel\n      const transaction = this.createTransaction();\n      transaction.callFunction({\n        target: `${this.contractAddress}::open_channel_with_sub_channel_entry`,\n        typeArgs: [params.assetId], // CoinType as type argument\n        args: [Args.address(payeeParsed.identifier), Args.string(params.vmIdFragment)],\n        maxGas: 100000000,\n      });\n\n      this.logger.debug('Executing openChannelWithSubChannel transaction');\n\n      // Execute transaction\n      const result = await this.client.signAndExecuteTransaction({\n        transaction,\n        signer,\n        option: { withOutput: true },\n      });\n\n      if (result.execution_info.status.type !== 'executed') {\n        throw new Error(`Transaction failed: ${JSON.stringify(result.execution_info)}`);\n      }\n\n      // Calculate the expected channel ID deterministically\n      const channelId = calcChannelObjectId(\n        payerParsed.identifier,\n        payeeParsed.identifier,\n        params.assetId\n      );\n\n      return {\n        channelId,\n        txHash: result.execution_info.tx_hash || '',\n        blockHeight: BigInt(0), // TODO: Extract from result if available\n        events: result.output?.events,\n      };\n    } catch (error) {\n      this.logger.error('Error opening channel with sub-channel:', error);\n      throw error;\n    }\n  }\n\n  async authorizeSubChannel(params: AuthorizeSubChannelParams): Promise<TxResult> {\n    try {\n      this.logger.debug('Authorizing sub-channel with params:', params);\n\n      const signer = await this.convertSigner(params.signer);\n\n      // Create transaction to authorize sub-channel\n      const transaction = this.createTransaction();\n      transaction.callFunction({\n        target: `${this.contractAddress}::authorize_sub_channel_entry`,\n        args: [Args.objectId(params.channelId), Args.string(params.vmIdFragment)],\n        maxGas: 100000000,\n      });\n\n      this.logger.debug('Executing authorizeSubChannel transaction');\n\n      // Execute transaction\n      const result = await this.client.signAndExecuteTransaction({\n        transaction,\n        signer,\n        option: { withOutput: true },\n      });\n\n      if (result.execution_info.status.type !== 'executed') {\n        throw new Error(`Transaction failed: ${JSON.stringify(result.execution_info)}`);\n      }\n\n      return {\n        txHash: result.execution_info.tx_hash || '',\n        blockHeight: BigInt(0),\n        events: result.output?.events,\n      };\n    } catch (error) {\n      this.logger.error('Error authorizing sub-channel:', error);\n      throw error;\n    }\n  }\n\n  async claimFromChannel(params: ClaimParams): Promise<ClaimResult> {\n    try {\n      this.logger.debug('Claiming from channel with params:', params);\n\n      const signer = await this.convertSigner(params.signer);\n      const { subRav, signature } = params.signedSubRAV;\n\n      // Create transaction to claim from channel\n      const transaction = this.createTransaction();\n      transaction.callFunction({\n        target: `${this.contractAddress}::claim_from_channel_entry`,\n        args: [\n          Args.objectId(subRav.channelId),\n          Args.string(subRav.vmIdFragment),\n          Args.u256(subRav.accumulatedAmount),\n          Args.u64(subRav.nonce),\n          Args.vec('u8', Array.from(signature)),\n        ],\n        maxGas: 100000000,\n      });\n\n      this.logger.debug('Executing claimFromChannel transaction');\n\n      // Execute transaction\n      const result = await this.client.signAndExecuteTransaction({\n        transaction,\n        signer,\n        option: { withOutput: true },\n      });\n\n      if (result.execution_info.status.type !== 'executed') {\n        throw new Error(`Transaction failed: ${JSON.stringify(result.execution_info)}`);\n      }\n\n      // Parse claimed amount from events\n      const claimedAmount = this.parseClaimedAmountFromEvents(result.output?.events);\n\n      return {\n        txHash: result.execution_info.tx_hash || '',\n        claimedAmount,\n        blockHeight: BigInt(0),\n        events: result.output?.events,\n      };\n    } catch (error) {\n      this.logger.error('Error claiming from channel:', error);\n      throw error;\n    }\n  }\n\n  async closeChannel(params: CloseParams): Promise<TxResult> {\n    try {\n      this.logger.debug('Closing channel with params:', params);\n\n      const signer = await this.convertSigner(params.signer);\n\n      const transaction = this.createTransaction();\n\n      if (params.cooperative && params.closeProofs) {\n        // Cooperative close with proofs\n        const serializedProofs = CloseProofsSchema.serialize(params.closeProofs).toBytes();\n\n        transaction.callFunction({\n          target: `${this.contractAddress}::close_channel_entry`,\n          args: [Args.objectId(params.channelId), Args.vec('u8', serializedProofs)],\n          maxGas: 100000000,\n        });\n      } else {\n        // Force close (initiate cancellation)\n        transaction.callFunction({\n          target: `${this.contractAddress}::initiate_cancellation_entry`,\n          args: [Args.objectId(params.channelId)],\n          maxGas: 100000000,\n        });\n      }\n\n      this.logger.debug('Executing closeChannel transaction');\n\n      // Execute transaction\n      const result = await this.client.signAndExecuteTransaction({\n        transaction,\n        signer,\n        option: { withOutput: true },\n      });\n\n      if (result.execution_info.status.type !== 'executed') {\n        throw new Error(`Transaction failed: ${JSON.stringify(result.execution_info)}`);\n      }\n\n      return {\n        txHash: result.execution_info.tx_hash || '',\n        blockHeight: BigInt(0),\n        events: result.output?.events,\n      };\n    } catch (error) {\n      this.logger.error('Error closing channel:', error);\n      throw error;\n    }\n  }\n\n  async getChannelStatus(params: ChannelStatusParams): Promise<ChannelInfo> {\n    try {\n      this.logger.debug('Getting channel status for channel:', params.channelId);\n\n      // Get channel state from blockchain\n      const channelObject = await this.client.getObjectStates({\n        ids: [params.channelId],\n      });\n\n      if (!channelObject || channelObject.length === 0 || !channelObject[0]) {\n        throw new Error(`Channel ${params.channelId} not found`);\n      }\n\n      const channelState = channelObject[0];\n\n      // Parse channel data from BCS - no need for view functions anymore\n      const channelData = parsePaymentChannelData(channelState.value);\n\n      // Convert status number to string\n      const statusString = this.convertChannelStatus(channelData.status);\n\n      const channel_sender = new RoochAddress(channelData.sender);\n      const channel_receiver = new RoochAddress(channelData.receiver);\n      return {\n        channelId: params.channelId,\n        payerDid: `did:rooch:${channel_sender.toBech32Address()}`,\n        payeeDid: `did:rooch:${channel_receiver.toBech32Address()}`,\n        assetId: channelData.coin_type,\n        epoch: channelData.channel_epoch,\n        status: statusString,\n      };\n    } catch (error) {\n      this.logger.error('Error getting channel status:', error);\n      throw error;\n    }\n  }\n\n  async getSubChannel(params: SubChannelParams): Promise<SubChannelInfo> {\n    try {\n      this.logger.debug('Getting sub-channel info for:', params);\n\n      // First get the channel to obtain the sub_channels table ID\n      const channelObject = await this.client.getObjectStates({\n        ids: [params.channelId],\n      });\n\n      if (!channelObject || channelObject.length === 0 || !channelObject[0]) {\n        throw new Error(`Channel ${params.channelId} not found`);\n      }\n\n      const channelData = parsePaymentChannelData(channelObject[0].value);\n\n      // Get the sub-channel data from the sub_channels Table\n      const subChannelData = await this.getSubChannelData(\n        channelData.sub_channels,\n        params.vmIdFragment\n      );\n\n      if (!subChannelData) {\n        throw new Error(\n          `Sub-channel ${params.vmIdFragment} not found in channel ${params.channelId}`\n        );\n      }\n\n      return {\n        channelId: params.channelId,\n        epoch: channelData.channel_epoch,\n        vmIdFragment: params.vmIdFragment,\n        publicKey: subChannelData.pk_multibase,\n        methodType: subChannelData.method_type,\n        lastClaimedAmount: subChannelData.last_claimed_amount,\n        lastConfirmedNonce: subChannelData.last_confirmed_nonce,\n      };\n    } catch (error) {\n      this.logger.error('Error getting sub-channel info:', error);\n      throw error;\n    }\n  }\n\n  async getAssetInfo(assetId: string): Promise<AssetInfo> {\n    this.logger.debug('Getting asset info for:', assetId);\n    let canonicalAssetId = normalizeAssetId(assetId);\n    // TODO: Add support for other assets\n    if (canonicalAssetId === RGAS_CANONICAL_TAG) {\n      let assetInfo: AssetInfo = {\n        assetId: canonicalAssetId,\n        symbol: this.parseAssetSymbol(assetId),\n        decimals: 8,\n      };\n      return assetInfo;\n    }\n    throw new Error(`Unsupported asset type: ${assetId}`);\n  }\n\n  async getAssetPrice(assetId: string): Promise<bigint> {\n    try {\n      this.logger.debug('Getting asset price for:', assetId);\n\n      // Normalize asset ID to canonical string\n      const canonicalAssetId = normalizeAssetId(assetId);\n\n      //Currently only support RGas\n      if (canonicalAssetId === RGAS_CANONICAL_TAG) {\n        // RGas pricing calculation:\n        // - 1 RGas = 0.01 USD\n        // - RGas has 8 decimals, so 1 RGas = 10^8 base units\n        // - 1 USD = 1,000,000,000,000 pUSD (pico-USD, not micro-USD!)\n        // - So 1 RGas = 0.01 * 1,000,000,000,000 = 10,000,000,000 pUSD\n        // - Therefore: 1 base unit = 10,000,000,000 pUSD / 10^8 = 100 pUSD\n        return BigInt(100); // 100 pUSD per smallest RGas unit\n      }\n\n      // Unknown asset type\n      throw new Error(`Unsupported asset type: ${assetId}`);\n    } catch (error) {\n      this.logger.error('Error getting asset price:', error);\n      throw error;\n    }\n  }\n\n  async getChainId(): Promise<bigint> {\n    try {\n      this.logger.debug('Getting chain ID');\n\n      // Use RoochClient's getChainId method\n      const chainId = await this.client.getChainId();\n      return BigInt(chainId);\n    } catch (error) {\n      this.logger.error('Error getting chain ID:', error);\n      throw error;\n    }\n  }\n\n  async depositToHub(params: DepositParams): Promise<TxResult> {\n    try {\n      this.logger.debug('Depositing to payment hub with params:', params);\n\n      // Parse and validate owner DID\n      const ownerParsed = parseDid(params.ownerDid);\n      if (ownerParsed.method !== 'rooch') {\n        throw new Error(`Invalid owner DID method: expected 'rooch', got '${ownerParsed.method}'`);\n      }\n\n      const signer = await this.convertSigner(params.signer);\n\n      // Create transaction to deposit to hub\n      const transaction = this.createTransaction();\n      transaction.callFunction({\n        target: `${this.contractAddress}::deposit_to_hub_entry`,\n        typeArgs: [params.assetId], // CoinType as type argument\n        args: [Args.address(ownerParsed.identifier), Args.u256(params.amount)],\n        maxGas: 100000000,\n      });\n\n      this.logger.debug('Executing depositToHub transaction');\n\n      // Execute transaction\n      const result = await this.client.signAndExecuteTransaction({\n        transaction,\n        signer,\n        option: { withOutput: true },\n      });\n\n      if (result.execution_info.status.type !== 'executed') {\n        throw new Error(`Transaction failed: ${JSON.stringify(result.execution_info)}`);\n      }\n\n      return {\n        txHash: result.execution_info.tx_hash || '',\n        blockHeight: BigInt(0),\n        events: result.output?.events,\n      };\n    } catch (error) {\n      this.logger.error('Error depositing to hub:', error);\n      throw error;\n    }\n  }\n\n  async withdrawFromHub(params: WithdrawParams): Promise<TxResult> {\n    try {\n      this.logger.debug('Withdrawing from payment hub with params:', params);\n\n      // Parse and validate owner DID\n      const ownerParsed = parseDid(params.ownerDid);\n      if (ownerParsed.method !== 'rooch') {\n        throw new Error(`Invalid owner DID method: expected 'rooch', got '${ownerParsed.method}'`);\n      }\n\n      const signer = await this.convertSigner(params.signer);\n\n      // Create transaction to withdraw from hub\n      const transaction = this.createTransaction();\n      transaction.callFunction({\n        target: `${this.contractAddress}::withdraw_from_hub_entry`,\n        typeArgs: [params.assetId], // CoinType as type argument\n        args: [Args.u256(params.amount)],\n        maxGas: 100000000,\n      });\n\n      this.logger.debug('Executing withdrawFromHub transaction');\n\n      // Execute transaction\n      const result = await this.client.signAndExecuteTransaction({\n        transaction,\n        signer,\n        option: { withOutput: true },\n      });\n\n      if (result.execution_info.status.type !== 'executed') {\n        throw new Error(`Transaction failed: ${JSON.stringify(result.execution_info)}`);\n      }\n\n      return {\n        txHash: result.execution_info.tx_hash || '',\n        blockHeight: BigInt(0),\n        events: result.output?.events,\n      };\n    } catch (error) {\n      this.logger.error('Error withdrawing from hub:', error);\n      throw error;\n    }\n  }\n\n  async getHubBalance(ownerDid: string, assetId: string): Promise<bigint> {\n    try {\n      this.logger.debug('Getting hub balance for DID:', ownerDid, 'asset:', assetId);\n\n      // Get PaymentHub object\n      const paymentHub = await this.getPaymentHub(ownerDid);\n      if (!paymentHub) {\n        this.logger.debug('PaymentHub not found for owner:', ownerDid);\n        return BigInt(0);\n      }\n\n      this.logger.debug('MultiCoinStore ID extracted:', paymentHub.multi_coin_store);\n      // Query the specific field for this coin type in the multi_coin_store\n      const fieldKey = deriveCoinTypeFieldKey(assetId);\n      const fieldStates = await this.client.getFieldStates({\n        objectId: paymentHub.multi_coin_store,\n        fieldKey: [fieldKey],\n      });\n\n      if (!fieldStates || fieldStates.length === 0 || !fieldStates[0]) {\n        // Asset not found in the store, balance is 0\n        this.logger.debug('Asset not found in multi_coin_store:', assetId);\n        return BigInt(0);\n      }\n\n      // Parse the DynamicField<String, CoinStoreField> to get balance\n      const fieldState = fieldStates[0];\n      const fieldValue = fieldState.value;\n\n      if (typeof fieldValue === 'string' && fieldValue.startsWith('0x')) {\n        // Parse BCS bytes using DynamicFieldCoinStoreSchema\n        try {\n          this.logger.debug(\n            'Parsing DynamicField<String, CoinStoreField> from BCS hex:',\n            fieldValue\n          );\n          const parsed = parseDynamicFieldCoinStore(fieldValue);\n\n          this.logger.debug('Parsed DynamicField:', parsed);\n\n          // Extract balance from the parsed CoinStoreField and ensure it's bigint\n          return safeBalanceToBigint(parsed.value.balance.value);\n        } catch (parseError) {\n          this.logger.warn('Failed to parse CoinStoreField BCS data:', parseError);\n          return BigInt(0);\n        }\n      } else if (fieldValue && typeof fieldValue === 'object' && 'value' in fieldValue) {\n        // If already parsed\n        const coinStoreField = (fieldValue as any).value;\n        if (coinStoreField && typeof coinStoreField === 'object' && 'balance' in coinStoreField) {\n          return BigInt(coinStoreField.balance as string);\n        }\n      }\n\n      this.logger.warn('Could not parse balance from field state');\n      return BigInt(0);\n    } catch (error) {\n      this.logger.error('Error getting hub balance:', error);\n      // Return 0 instead of throwing for balance queries\n      return BigInt(0);\n    }\n  }\n\n  async getAllHubBalances(ownerDid: string): Promise<Record<string, bigint>> {\n    try {\n      this.logger.debug('Getting all hub balances for DID:', ownerDid);\n\n      // Get PaymentHub object\n      const paymentHub = await this.getPaymentHub(ownerDid);\n      if (!paymentHub) {\n        this.logger.debug('PaymentHub not found for owner:', ownerDid);\n        return {};\n      }\n\n      this.logger.debug(\n        'MultiCoinStore ID extracted for all balances:',\n        paymentHub.multi_coin_store\n      );\n\n      // List all field states in multi_coin_store to get all coin types and balances\n      const balances: Record<string, bigint> = {};\n      let cursor = null;\n      // We only need to get the first 100 fields for now\n      const pageSize = 100;\n\n      // while (true) {\n      const fieldStates = await this.client.listFieldStates({\n        objectId: paymentHub.multi_coin_store,\n        cursor,\n        limit: pageSize.toString(),\n      });\n\n      if (!fieldStates || !fieldStates.data) {\n        return balances;\n      }\n\n      for (const state of fieldStates.data) {\n        try {\n          // Parse DynamicField<String, CoinStoreField>\n          const fieldValue = state.state.value;\n\n          if (typeof fieldValue === 'string' && fieldValue.startsWith('0x')) {\n            // Parse BCS bytes using DynamicFieldCoinStoreSchema\n            try {\n              this.logger.debug(\n                'Parsing DynamicField<String, CoinStoreField> from BCS hex:',\n                fieldValue\n              );\n              const parsed = parseDynamicFieldCoinStore(fieldValue);\n\n              this.logger.debug('Parsed DynamicField:', parsed);\n\n              // Extract coin type and balance from the parsed data\n              const coinType = parsed.name;\n              const balance = safeBalanceToBigint(parsed.value.balance.value);\n\n              if (coinType && balance > 0) {\n                balances[coinType] = balance;\n              }\n            } catch (parseError) {\n              this.logger.warn('Failed to parse CoinStoreField BCS data:', parseError);\n              continue;\n            }\n          } else {\n            this.logger.warn('Could not parse balance from field state');\n            throw new Error('Could not parse balance from field state');\n          }\n        } catch (parseError) {\n          this.logger.warn('Failed to parse field state for balance:', parseError);\n          continue;\n        }\n      }\n\n      // if (!fieldStates.has_next_page) {\n      //   break;\n      // }\n      // }\n      // cursor = fieldStates.next_cursor;\n      // }\n\n      return balances;\n    } catch (error) {\n      this.logger.error('Error getting all hub balances:', error);\n      // Return empty object instead of throwing\n      return {};\n    }\n  }\n\n  async getActiveChannelsCounts(ownerDid: string): Promise<Record<string, number>> {\n    try {\n      this.logger.debug('Getting active channels counts for DID:', ownerDid);\n\n      // Get PaymentHub object\n      const paymentHub = await this.getPaymentHub(ownerDid);\n      if (!paymentHub) {\n        this.logger.debug('PaymentHub not found for owner:', ownerDid);\n        return {};\n      }\n\n      this.logger.debug('Active channels table ID:', paymentHub.active_channels);\n\n      // List all field states in active_channels table to get all coin types and their counts\n      const channelCounts: Record<string, number> = {};\n      let cursor = null;\n      const pageSize = 100;\n\n      const fieldStates = await this.client.listFieldStates({\n        objectId: paymentHub.active_channels,\n        cursor,\n        limit: pageSize.toString(),\n      });\n\n      if (!fieldStates || !fieldStates.data) {\n        return channelCounts;\n      }\n\n      for (const state of fieldStates.data) {\n        try {\n          // Parse DynamicField<String, u64> for active channels counts\n          const fieldValue = state.state.value;\n\n          // Parse BCS bytes using DynamicFieldU64Schema\n          try {\n            this.logger.debug('Parsing DynamicField<String, u64> from BCS hex:', fieldValue);\n            const parsed = parseDynamicFieldU64(fieldValue);\n\n            this.logger.debug('Parsed DynamicField:', parsed);\n\n            // Extract coin type and count from the parsed data\n            const coinType = parsed.name;\n            const count = parsed.value;\n\n            if (coinType && count > 0) {\n              channelCounts[coinType] = count;\n            }\n          } catch (parseError) {\n            this.logger.warn('Failed to parse u64 BCS data:', parseError);\n            continue;\n          }\n        } catch (parseError) {\n          this.logger.warn('Failed to parse field state for active channels count:', parseError);\n          continue;\n        }\n      }\n\n      // if (!fieldStates.has_next_page) {\n      //   break;\n      // }\n      // cursor = fieldStates.next_cursor;\n\n      return channelCounts;\n    } catch (error) {\n      this.logger.error('Error getting active channels counts:', error);\n      // Return empty object instead of throwing\n      return {};\n    }\n  }\n\n  // PaymentHub ID calculation and field key derivation are now in ChannelUtils.ts\n\n  // Get PaymentHub object for a given owner DID\n  private async getPaymentHub(ownerDid: string): Promise<PaymentHub | null> {\n    try {\n      this.logger.debug('Getting PaymentHub for DID:', ownerDid);\n\n      // Parse and validate owner DID\n      const ownerParsed = parseDid(ownerDid);\n      if (ownerParsed.method !== 'rooch') {\n        throw new Error(`Invalid owner DID method: expected 'rooch', got '${ownerParsed.method}'`);\n      }\n\n      // Calculate hub ID\n      const hubId = calculatePaymentHubId(ownerParsed.identifier);\n\n      // Get PaymentHub object state\n      const hubObjectViews = await this.client.getObjectStates({ ids: [hubId] });\n\n      if (!hubObjectViews || hubObjectViews.length === 0 || !hubObjectViews[0]) {\n        this.logger.debug('PaymentHub not found for owner:', ownerDid);\n        return null;\n      }\n\n      const hubObjectView = hubObjectViews[0];\n\n      // Parse PaymentHub using BCS deserialization\n      try {\n        const hubValue = hubObjectView.value;\n\n        if (typeof hubValue === 'string' && hubValue.startsWith('0x')) {\n          // Parse BCS bytes using PaymentHubSchema\n          this.logger.debug('Parsing PaymentHub from BCS hex:', hubValue);\n          const parsed = parsePaymentHubData(hubValue);\n\n          this.logger.debug('Parsed PaymentHub:', parsed);\n\n          return parsed;\n        } else {\n          throw new Error('Unexpected PaymentHub value format');\n        }\n      } catch (parseError) {\n        this.logger.error('Failed to parse PaymentHub object:', parseError);\n        return null;\n      }\n    } catch (error) {\n      this.logger.error('Error getting PaymentHub:', error);\n      return null;\n    }\n  }\n\n  // Helper methods\n  private async convertSigner(signer: SignerInterface): Promise<Signer> {\n    if (signer instanceof Signer) {\n      return signer;\n    }\n    return DidAccountSigner.create(signer);\n  }\n\n  private createTransaction(): Transaction {\n    return new Transaction();\n  }\n\n  private getDefaultRpcUrl(network: string): string {\n    // Map our network names to Rooch SDK network names\n    const networkMap: { [key: string]: string } = {\n      local: 'localnet',\n      dev: 'devnet',\n      test: 'testnet',\n      main: 'mainnet',\n    };\n\n    const roochNetwork = networkMap[network] || network;\n    return getRoochNodeUrl(roochNetwork as any);\n  }\n\n  private parseChannelIdFromEvents(events?: EventView[]): string {\n    if (!events) {\n      throw new Error('No events found to parse channel ID');\n    }\n\n    for (const event of events) {\n      if (event.event_type.includes('PaymentChannelOpenedEvent')) {\n        // Parse the channel_id from event data using BCS\n        try {\n          // The event data contains the channel_id field\n          const eventDataHex = event.event_data.startsWith('0x')\n            ? event.event_data.slice(2)\n            : event.event_data;\n          const eventDataBytes = new Uint8Array(\n            eventDataHex.match(/.{1,2}/g)?.map((byte: string) => parseInt(byte, 16)) || []\n          );\n\n          // For now, extract channel_id manually - this would need proper BCS schema\n          // The PaymentChannelOpenedEvent should contain channel_id as first field\n          return event.event_data; // Return the raw event data for now\n        } catch (error) {\n          this.logger.error('Failed to parse channel ID from event:', error);\n          throw new Error(`Failed to parse channel ID from event: ${error}`);\n        }\n      }\n    }\n\n    throw new Error('PaymentChannelOpenedEvent not found in transaction events');\n  }\n\n  private parseClaimedAmountFromEvents(events?: EventView[]): bigint {\n    if (!events) {\n      return BigInt(0);\n    }\n\n    for (const event of events) {\n      if (event.event_type.includes('ChannelClaimedEvent')) {\n        // Parse the amount from event data\n        // TODO: Implement proper BCS event parsing\n        return BigInt(0);\n      }\n    }\n\n    return BigInt(0);\n  }\n\n  // parseChannelData method moved to ChannelUtils.parsePaymentChannelData\n\n  /**\n   * Get sub-channel data by VM ID fragment\n   * @param subChannelsTableId The ObjectID of the sub_channels Table\n   * @param vmIdFragment The VM ID fragment to query\n   * @returns SubChannel data or null if not found\n   */\n  private async getSubChannelData(\n    subChannelsTableId: string,\n    vmIdFragment: string\n  ): Promise<SubChannel | null> {\n    try {\n      this.logger.debug(\n        `Getting sub-channel data for: ${vmIdFragment} from table: ${subChannelsTableId}`\n      );\n\n      // Create field key from vm_id_fragment - this follows Rooch's FieldKey::derive_from_string logic\n      const fieldKey = deriveFieldKeyFromString(vmIdFragment);\n\n      // Query specific field by key using getFieldStates API\n      const fieldStates = await this.client.getFieldStates({\n        objectId: subChannelsTableId,\n        fieldKey: [fieldKey],\n      });\n\n      if (!fieldStates || fieldStates.length === 0 || !fieldStates[0]) {\n        this.logger.debug(`Sub-channel ${vmIdFragment} not found in table ${subChannelsTableId}`);\n        return null;\n      }\n\n      const fieldState = fieldStates[0];\n\n      // Parse the DynamicField<String, SubChannel> from BCS\n      const dynamicField = parseDynamicFieldSubChannel(fieldState.value);\n\n      return dynamicField.value;\n    } catch (error) {\n      this.logger.error('Error getting sub-channel data:', error);\n      return null;\n    }\n  }\n\n  private convertChannelStatus(status: number): 'active' | 'closing' | 'closed' {\n    switch (status) {\n      case 0:\n        return 'active';\n      case 1:\n        return 'closing';\n      case 2:\n        return 'closed';\n      default:\n        return 'closed';\n    }\n  }\n\n  private parseAssetSymbol(assetId: string): string {\n    // Extract symbol from asset ID\n    // Example: '0x3::gas_coin::RGas' -> 'RGas'\n    const parts = assetId.split('::');\n    return parts[parts.length - 1] || 'UNKNOWN';\n  }\n}\n","/**\n * Chain Factory for Payment Channel Contracts\n *\n * Provides factory methods to create chain-specific contract implementations\n * and payment channel clients based on configuration.\n */\n\nimport type { SignerInterface } from '@nuwa-ai/identity-kit';\nimport type { IPaymentChannelContract } from '../contracts/IPaymentChannelContract';\nimport {\n  PaymentChannelPayerClient,\n  type PaymentChannelPayerClientOptions,\n} from '../client/PaymentChannelPayerClient';\nimport {\n  RoochPaymentChannelContract,\n  type RoochContractOptions,\n} from '../rooch/RoochPaymentChannelContract';\n\n/**\n * Supported blockchain networks\n */\nexport type SupportedChain = 'rooch';\n\n/**\n * Chain configuration for Rooch\n */\nexport interface RoochChainConfig {\n  chain: 'rooch';\n  rpcUrl?: string;\n  network?: 'local' | 'dev' | 'test' | 'main';\n  contractAddress?: string;\n  debug?: boolean;\n}\n\n/**\n * Union type for all supported chain configurations\n */\nexport type ChainConfig = RoochChainConfig;\n\n/**\n * Factory options for creating payment channel clients\n */\nexport interface PaymentChannelFactoryOptions {\n  chainConfig: ChainConfig;\n  signer: SignerInterface;\n  keyId?: string;\n  storageOptions: PaymentChannelPayerClientOptions['storageOptions'];\n}\n\n/**\n * Chain Factory for creating payment channel contracts and clients\n */\nexport class PaymentChannelFactory {\n  /**\n   * Create a chain-specific contract implementation\n   */\n  static createContract(config: ChainConfig): IPaymentChannelContract {\n    switch (config.chain) {\n      case 'rooch':\n        return new RoochPaymentChannelContract({\n          rpcUrl: config.rpcUrl,\n          network: config.network,\n          contractAddress: config.contractAddress,\n          debug: config.debug,\n        });\n\n      default:\n        throw new Error(`Unsupported chain: ${(config as any).chain}`);\n    }\n  }\n\n  /**\n   * Create a payment channel client with chain-specific contract\n   */\n  static createClient(options: PaymentChannelFactoryOptions): PaymentChannelPayerClient {\n    const contract = this.createContract(options.chainConfig);\n\n    return new PaymentChannelPayerClient({\n      contract,\n      signer: options.signer,\n      keyId: options.keyId,\n      storageOptions: options.storageOptions,\n    });\n  }\n}\n\n/**\n * Convenience function to create a payment channel client\n */\nexport function createPaymentChannelClient(\n  options: PaymentChannelFactoryOptions\n): PaymentChannelPayerClient {\n  return PaymentChannelFactory.createClient(options);\n}\n","import { BillingRule } from './types';\n\n/**\n * Pure functional implementation of rule matching used by all environments\n * (Express / Koa / Cloudflare Workers / …).\n *\n * The function iterates over the provided rule list and returns the **first**\n * rule that satisfies the matching conditions. If no rule matches it returns\n * `undefined`.\n */\nexport function findRule(meta: Record<string, any>, rules: BillingRule[]): BillingRule | undefined {\n  for (const rule of rules) {\n    if (matchesRule(meta, rule)) {\n      return rule;\n    }\n  }\n  return undefined;\n}\n\n/**\n * Internal helper that determines whether a single rule applies to the given\n * request metadata.\n */\nfunction matchesRule(meta: Record<string, any>, rule: BillingRule): boolean {\n  // Catch-all default rule\n  if (rule.default) {\n    return true;\n  }\n\n  if (!rule.when) {\n    return false;\n  }\n\n  const when = rule.when as Record<string, any>;\n\n  // Path exact match\n  if (when.path && meta.path !== when.path) {\n    return false;\n  }\n\n  // Path regex match\n  if (when.pathRegex) {\n    const regex = new RegExp(when.pathRegex);\n    if (!regex.test(meta.path || '')) {\n      return false;\n    }\n  }\n\n  if (when.method && meta.method !== when.method) {\n    return false;\n  }\n\n  // Fallback: check all remaining keys strictly equal\n  for (const [key, value] of Object.entries(when)) {\n    if (['path', 'pathRegex', 'model', 'method', 'assetId'].includes(key)) {\n      continue; // already handled above\n    }\n\n    if (meta[key] !== value) {\n      return false;\n    }\n  }\n\n  return true;\n}\n","/**\n * Refactored HTTP Payment Middleware\n *\n * This middleware now serves as a protocol adapter that delegates payment\n * processing to the PaymentProcessor component. It focuses only on HTTP-specific\n * concerns like request/response handling and error mapping.\n */\n\nimport { PaymentProcessor } from '../../core/PaymentProcessor';\nimport type { PaymentProcessorConfig } from '../../core/PaymentProcessor';\nimport type { BillingContext } from '../../billing';\nimport { HttpPaymentCodec } from './HttpPaymentCodec';\nimport type {\n  PaymentHeaderPayload,\n  HttpRequestPayload,\n  HttpResponsePayload,\n  SignedSubRAV,\n} from '../../core/types';\nimport { PaymentChannelPayeeClient } from '../../client/PaymentChannelPayeeClient';\nimport type { BillingRule, RuleProvider } from '../../billing';\nimport type { RateProvider } from '../../billing/rate/types';\nimport { findRule } from '../../billing/core/rule-matcher';\nimport type { PendingSubRAVRepository } from '../../storage/interfaces/PendingSubRAVRepository';\n// Legacy ClaimScheduler removed\nimport type { RAVRepository } from '../../storage/interfaces/RAVRepository';\nimport { DIDResolver, DebugLogger } from '@nuwa-ai/identity-kit';\nimport { httpStatusFor, PaymentErrorCode } from '../../errors/codes';\n\n// Generic HTTP interfaces (framework-agnostic)\nexport interface GenericHttpRequest {\n  path: string;\n  method: string;\n  headers: Record<string, string | string[] | undefined>;\n  query: Record<string, any>;\n  body?: any;\n}\n\nexport interface ResponseAdapter {\n  setStatus(code: number): ResponseAdapter;\n  json(obj: any): ResponseAdapter | void;\n  setHeader(name: string, value: string): ResponseAdapter;\n}\n\ninterface ExpressResponse {\n  status(code: number): ExpressResponse;\n  json(obj: any): ExpressResponse;\n  setHeader(name: string, value: string): ExpressResponse;\n  headersSent: boolean;\n}\n\n/**\n * Configuration for the HTTP billing middleware\n */\nexport interface HttpBillingMiddlewareConfig {\n  /** Payment processor for handling billing */\n  processor: PaymentProcessor;\n\n  /** Rule provider for pre-matching billing rules (V2 optimization) */\n  ruleProvider: RuleProvider;\n\n  /** Debug logging */\n  debug?: boolean;\n  /** Reactive claim stats are exposed via ClaimTriggerService on admin APIs */\n}\n\n/**\n * HTTP-specific error codes mapped to HTTP status codes\n */\n// Deprecated: Use PaymentErrorCode from errors/codes\n// Keeping the name for potential external imports, but aligned to centralized enum\nexport const HttpPaymentErrorCode = PaymentErrorCode;\n\n/**\n * Refactored HTTP Billing Middleware\n *\n * Now serves as a thin protocol adapter that:\n * 1. Extracts HTTP-specific request data\n * 2. Delegates payment processing to PaymentProcessor\n * 3. Maps results back to HTTP responses\n * 4. Handles HTTP-specific error formatting\n */\nexport class HttpBillingMiddleware {\n  private processor: PaymentProcessor;\n  private codec: HttpPaymentCodec;\n  private config: HttpBillingMiddlewareConfig;\n  private logger: DebugLogger;\n\n  constructor(config: HttpBillingMiddlewareConfig) {\n    this.config = config;\n    this.processor = config.processor;\n    // Initialize HTTP codec\n    this.codec = new HttpPaymentCodec();\n    this.logger = DebugLogger.get('HttpBillingMiddleware');\n    this.logger.setLevel(config.debug ? 'debug' : 'info');\n  }\n\n  /**\n   * New unified billing handler using the three-step process\n   */\n  async handleWithNewAPI(req: GenericHttpRequest): Promise<BillingContext | null> {\n    try {\n      this.log('🔍 Processing HTTP payment request with new API:', req.method, req.path);\n\n      // Step 1: Find matching billing rule\n      const rule = this.findBillingRule(req);\n\n      if (!rule) {\n        this.log('📝 No billing rule matched - proceeding without payment processing');\n        return null;\n      }\n\n      // Step 2: Build initial billing context\n      const paymentData = this.extractPaymentData(req.headers);\n      const ctx = this.buildBillingContext(req, paymentData || undefined, rule);\n\n      // Step 3: Pre-process the request\n      const processedCtx = await this.processor.preProcess(ctx);\n\n      // Step 4: Check if verification failed\n      if (processedCtx.state && processedCtx.state.signedSubRavVerified === false) {\n        this.log('🚨 Payment verification failed during pre-processing');\n        return null;\n      }\n\n      this.log(`📋 Request pre-processed for ${rule.strategy.type}`);\n      if (processedCtx.state) {\n        this.log(`📋 Context state:`, {\n          signedSubRavVerified: processedCtx.state.signedSubRavVerified,\n          cost: processedCtx.state.cost,\n          headerValue: !!processedCtx.state.headerValue,\n        });\n      }\n      return processedCtx;\n    } catch (error) {\n      this.log('🚨 New API payment processing error:', error);\n      return null;\n    }\n  }\n\n  /**\n   * Complete billing settlement synchronously (Step B & C) - for on-headers use\n   */\n  settleBillingSync(ctx: BillingContext, usage?: number, resAdapter?: ResponseAdapter): boolean {\n    try {\n      this.log('🔄 Settling billing synchronously with usage:', usage);\n\n      // Use the processor's synchronous settle method\n      const settledCtx = this.processor.settle(ctx, usage);\n\n      // Check if this is a free route that should not generate headers\n      if (ctx.meta.billingRule && !ctx.meta.billingRule.paymentRequired) {\n        this.log('📝 Free route - skipping payment header generation');\n        return true; // Successfully handled, no header needed\n      }\n\n      if (!settledCtx.state?.headerValue) {\n        this.log('⚠️ No header value generated during settlement');\n        return false;\n      }\n\n      // Add response header if adapter provided\n      if (resAdapter) {\n        resAdapter.setHeader('X-Payment-Channel-Data', settledCtx.state.headerValue);\n        this.log('✅ Payment header added to response synchronously');\n      }\n\n      return true;\n    } catch (error) {\n      this.log('🚨 Synchronous billing settlement error:', error);\n      return false;\n    }\n  }\n\n  /** Save settlement payload for later polling by client (streaming scenarios) */\n  saveSettlement(ctx: BillingContext): void {\n    const state = ctx.state || {};\n    const payload = {\n      subRav: state.unsignedSubRav,\n      cost: state.cost,\n      // costUsd is not persisted in state; optional\n      clientTxRef: ctx.meta.clientTxRef,\n      serviceTxRef: state.serviceTxRef,\n      version: 1,\n    };\n    if (!payload.clientTxRef) return;\n  }\n\n  /**\n   * Persist billing results (Step D) - async persistence only\n   */\n  async persistBilling(ctx: BillingContext): Promise<void> {\n    try {\n      this.log('💾 Persisting billing results');\n\n      if (ctx.state?.unsignedSubRav) {\n        await this.processor.persist(ctx);\n        this.log('✅ Billing results persisted successfully');\n      } else {\n        this.log('⚠️ No SubRAV to persist');\n      }\n    } catch (error) {\n      this.log('🚨 Billing persistence error:', error);\n      throw error;\n    }\n  }\n\n  /**\n   * Find matching billing rule for the request\n   */\n  private findBillingRule(req: GenericHttpRequest): BillingRule | undefined {\n    if (!this.config.ruleProvider) {\n      throw new Error(\n        'RuleProvider is required for auto-detection. Please configure it in HttpBillingMiddlewareConfig.'\n      );\n    }\n\n    const meta = {\n      path: req.path,\n      method: req.method,\n      // Include other relevant metadata for rule matching\n      httpQuery: req.query,\n      httpBody: req.body,\n      httpHeaders: req.headers,\n    };\n\n    return findRule(meta, this.config.ruleProvider.getRules());\n  }\n\n  /**\n   * Extract payment data from HTTP request headers\n   */\n  extractPaymentData(\n    headers: Record<string, string | string[] | undefined>\n  ): PaymentHeaderPayload | null {\n    const headerValue = HttpPaymentCodec.extractPaymentHeader(headers);\n\n    if (!headerValue) {\n      return null;\n    }\n\n    try {\n      return this.codec.decodePayload(headerValue);\n    } catch (error) {\n      throw new Error(`Invalid payment channel header: ${error}`);\n    }\n  }\n\n  /**\n   * Build billing context from HTTP request\n   */\n  private buildBillingContext(\n    req: GenericHttpRequest,\n    paymentData?: PaymentHeaderPayload,\n    billingRule?: BillingRule\n  ): BillingContext {\n    return {\n      serviceId: this.processor.getServiceId(),\n      meta: {\n        operation: `${req.method.toLowerCase()}:${req.path}`,\n\n        // Pre-matched billing rule (V2 optimization)\n        billingRule,\n\n        // Payment data from HTTP headers\n        maxAmount: paymentData?.maxAmount,\n        signedSubRav: paymentData?.signedSubRav,\n        clientTxRef: paymentData?.clientTxRef || crypto.randomUUID(),\n        // DIDAuth (ExpressPaymentKit attaches didInfo onto req)\n        didInfo: (req as any).didInfo,\n\n        // HTTP-specific metadata for billing rules\n        method: req.method,\n        path: req.path,\n\n        // Also keep HTTP-prefixed versions for other uses\n        httpMethod: req.method,\n        httpPath: req.path,\n        httpQuery: req.query,\n        httpBody: req.body,\n        httpHeaders: req.headers,\n      },\n    };\n  }\n\n  /**\n   * Map error code to HTTP status code\n   */\n  private mapErrorToHttpStatus(errorCode?: string): number {\n    return httpStatusFor(errorCode as PaymentErrorCode);\n  }\n\n  /**\n   * Get payment processing statistics\n   */\n  getProcessingStats() {\n    return this.processor.getProcessingStats();\n  }\n\n  /**\n   * Find pending SubRAV proposal\n   */\n  async findPendingProposal(channelId: string, vmIdFragment: string, nonce: bigint): Promise<any> {\n    return await this.processor.findPendingProposal(channelId, vmIdFragment, nonce);\n  }\n\n  /**\n   * Find the latest pending SubRAV proposal for a channel\n   */\n  async findLatestPendingProposal(channelId: string, vmIdFragment: string): Promise<any> {\n    return await this.processor.findLatestPendingProposal(channelId, vmIdFragment);\n  }\n\n  /**\n   * Create ExpressJS ResponseAdapter\n   */\n  private createExpressResponseAdapter(res: ExpressResponse): ResponseAdapter {\n    return {\n      setStatus: (code: number) => {\n        res.status(code);\n        return this.createExpressResponseAdapter(res); // Return adapter for chaining\n      },\n      json: (obj: any) => {\n        res.json(obj);\n        // Note: Express res.json() returns void, so we return void to match interface\n      },\n      setHeader: (name: string, value: string) => {\n        res.setHeader(name, value);\n        return this.createExpressResponseAdapter(res); // Return adapter for chaining\n      },\n    };\n  }\n\n  /**\n   * Debug logging\n   */\n  private log(...args: any[]): void {\n    this.logger.debug(...args);\n  }\n\n  /**\n   * Static factory method for creating middleware\n   */\n  static create(config: HttpBillingMiddlewareConfig): HttpBillingMiddleware {\n    return new HttpBillingMiddleware(config);\n  }\n}\n\n/**\n * Utility function to create ExpressJS ResponseAdapter\n */\nexport function createExpressResponseAdapter(res: any): ResponseAdapter {\n  return {\n    setStatus: (code: number) => {\n      res.status(code);\n      return createExpressResponseAdapter(res);\n    },\n    json: (obj: any) => {\n      res.json(obj);\n    },\n    setHeader: (name: string, value: string) => {\n      res.setHeader(name, value);\n      return createExpressResponseAdapter(res);\n    },\n  };\n}\n\n// No longer re-export ProcessorPaymentResult; results are available via BillingContext.state\n\n/**\n * Utility function to create Koa ResponseAdapter (example for other frameworks)\n */\nexport function createKoaResponseAdapter(ctx: any): ResponseAdapter {\n  return {\n    setStatus: (code: number) => {\n      ctx.status = code;\n      return createKoaResponseAdapter(ctx);\n    },\n    json: (obj: any) => {\n      ctx.body = obj;\n    },\n    setHeader: (name: string, value: string) => {\n      ctx.set(name, value);\n      return createKoaResponseAdapter(ctx);\n    },\n  };\n}\n","/**\n * Framework-level API types for Payment Kit\n *\n * This file contains types for the API framework itself (handlers, context, etc.)\n * rather than specific data models which are defined in schema/.\n */\n\nimport { RAVRepository } from '../storage/interfaces/RAVRepository';\nimport type { ErrorCodeType, ApiError } from '../schema/core';\nimport { ChannelRepository } from '../storage/interfaces/ChannelRepository';\nimport { PendingSubRAVRepository } from '../storage/interfaces/PendingSubRAVRepository';\nimport { ClaimTriggerService } from '../core/ClaimTriggerService';\nimport { PaymentChannelPayeeClient } from '../client/PaymentChannelPayeeClient';\nimport { RateProvider } from '../billing';\nimport { PaymentProcessor } from '../core/PaymentProcessor';\n\n/**\n * Standard API response envelope\n * Generic container for all API responses\n */\nexport interface ApiResponse<T = unknown> {\n  success: boolean;\n  data?: T;\n  error?: ApiError;\n  timestamp: string;\n}\n\n/**\n * Standard error codes enum for convenient access\n * Note: The authoritative schema is in schema/core/ErrorCodeSchema\n */\nexport const ErrorCode = {\n  // Authentication & Authorization\n  UNAUTHORIZED: 'UNAUTHORIZED' as const,\n  FORBIDDEN: 'FORBIDDEN' as const,\n\n  // Payment related\n  PAYMENT_REQUIRED: 'PAYMENT_REQUIRED' as const,\n  INSUFFICIENT_FUNDS: 'INSUFFICIENT_FUNDS' as const,\n  CONFLICT: 'CONFLICT' as const,\n\n  // General errors\n  NOT_FOUND: 'NOT_FOUND' as const,\n  BAD_REQUEST: 'BAD_REQUEST' as const,\n  INTERNAL_ERROR: 'INTERNAL_ERROR' as const,\n  SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE' as const,\n} as const;\n\nexport type ErrorCode = ErrorCodeType;\n\n/**\n * Handler context interface\n * Contains all dependencies and configuration needed by API handlers\n */\nexport interface ApiContext {\n  config: {\n    serviceId: string;\n    serviceDid: string;\n    defaultAssetId: string;\n    defaultPricePicoUSD?: string;\n    adminDid?: string | string[];\n    debug?: boolean;\n  };\n  payeeClient: PaymentChannelPayeeClient;\n  rateProvider: RateProvider;\n  claimTriggerService?: ClaimTriggerService;\n  processor: PaymentProcessor;\n  ravRepository: RAVRepository;\n  channelRepo: ChannelRepository;\n  pendingSubRAVStore: PendingSubRAVRepository;\n}\n\n/**\n * Framework-agnostic handler signature\n * All API handlers must conform to this signature\n */\nexport type Handler<Ctx = ApiContext, Req = any, Res = any> = (\n  ctx: Ctx,\n  req: Req\n) => Promise<ApiResponse<Res>>;\n","import { ErrorCode, type ErrorCode as ErrorCodeType } from '../types/api';\nimport type { ApiError } from '../schema';\n\n/**\n * Base error class for Payment Kit\n */\nexport class PaymentKitError extends Error {\n  public readonly code: ErrorCodeType;\n  public readonly httpStatus: number;\n  public readonly details?: unknown;\n\n  constructor(code: ErrorCodeType | string, message: string, httpStatus = 500, details?: unknown) {\n    super(message);\n    this.name = 'PaymentKitError';\n    this.code = code as ErrorCodeType;\n    this.httpStatus = httpStatus;\n    this.details = details;\n  }\n\n  /**\n   * Convert to standard API error format\n   */\n  toApiError(): ApiError {\n    return {\n      code: this.code,\n      message: this.message,\n      details: this.details,\n      httpStatus: this.httpStatus,\n    };\n  }\n}\n\n/**\n * Convert any error to standard API error format\n */\nexport function toApiError(error: unknown): ApiError {\n  if (error instanceof PaymentKitError) {\n    return error.toApiError();\n  }\n\n  if (error instanceof Error) {\n    return {\n      code: ErrorCode.INTERNAL_ERROR,\n      message: error.message,\n      details: error.stack,\n      httpStatus: 500,\n    };\n  }\n\n  return {\n    code: ErrorCode.INTERNAL_ERROR,\n    message: String(error),\n    httpStatus: 500,\n  };\n}\n\n/**\n * Create a success response\n */\nexport function createSuccessResponse<T>(data: T): { success: true; data: T; timestamp: string } {\n  return {\n    success: true,\n    data,\n    timestamp: new Date().toISOString(),\n  };\n}\n\n/**\n * Create an error response\n */\nexport function createErrorResponse(error: ApiError): {\n  success: false;\n  error: ApiError;\n  timestamp: string;\n} {\n  return {\n    success: false,\n    error,\n    timestamp: new Date().toISOString(),\n  };\n}\n","import type { SubRAV } from './types';\n\n/**\n * Assert monotonic progression between previous and next SubRAV deltas.\n * - next.nonce must equal prev.nonce + 1\n * - next.accumulatedAmount must be > prev.accumulatedAmount\n *   (set allowSameAccumulated=true to allow equality in special cases)\n */\nexport function assertRavProgression(\n  prevNonce: bigint,\n  prevAccumulatedAmount: bigint,\n  nextNonce: bigint,\n  nextAccumulatedAmount: bigint,\n  allowSameAccumulated: boolean = false\n): void {\n  const expectedNonce = prevNonce + 1n;\n  if (nextNonce !== expectedNonce) {\n    throw new Error(`Invalid nonce: expected ${expectedNonce}, got ${nextNonce}`);\n  }\n\n  if (allowSameAccumulated) {\n    if (nextAccumulatedAmount < prevAccumulatedAmount) {\n      throw new Error(\n        `Amount must not decrease: previous ${prevAccumulatedAmount}, new ${nextAccumulatedAmount}`\n      );\n    }\n  } else {\n    if (nextAccumulatedAmount <= prevAccumulatedAmount) {\n      throw new Error(\n        `Amount must increase: previous ${prevAccumulatedAmount}, new ${nextAccumulatedAmount}`\n      );\n    }\n  }\n}\n\n/**\n * Convenience helper to assert progression using SubRAV objects.\n */\nexport function assertSubRavProgression(\n  prev: Pick<SubRAV, 'nonce' | 'accumulatedAmount'>,\n  next: Pick<SubRAV, 'nonce' | 'accumulatedAmount'>,\n  allowSameAccumulated: boolean = false\n): void {\n  assertRavProgression(\n    prev.nonce,\n    prev.accumulatedAmount,\n    next.nonce,\n    next.accumulatedAmount,\n    allowSameAccumulated\n  );\n}\n","import { DIDAuth, SignerInterface } from '@nuwa-ai/identity-kit';\n\n/**\n * Helper for generating DIDAuthV1 authorization headers\n */\nexport class DidAuthHelper {\n  /**\n   * Generate DIDAuthV1 authorization header for HTTP request\n   * @param payerDid - The payer's DID\n   * @param keyManager - Signer for creating the signature\n   * @param requestUrl - The target URL for the request\n   * @param method - HTTP method (optional, defaults to 'POST')\n   * @param keyId - Optional specific key ID to use (if not provided, uses first available)\n   * @returns Authorization header value or undefined if generation fails\n   */\n  static async generateAuthHeader(\n    payerDid: string,\n    keyManager: SignerInterface,\n    requestUrl: string,\n    method: string = 'POST',\n    keyId?: string\n  ): Promise<string | undefined> {\n    try {\n      let selectedKeyId = keyId;\n\n      if (!selectedKeyId) {\n        // Get available key IDs\n        const keyIds = await keyManager.listKeyIds();\n        if (keyIds.length === 0) {\n          throw new Error('No key IDs available for signing');\n        }\n        selectedKeyId = keyIds[0]; // Use first available key\n      }\n\n      // Create a signed object with proper payload structure\n      const signedObject = await DIDAuth.v1.createSignature(\n        {\n          operation: 'http_request',\n          params: {\n            uri: requestUrl,\n            method: method.toUpperCase(),\n          },\n        },\n        keyManager,\n        selectedKeyId\n      );\n\n      // Convert to authorization header\n      const authHeader = DIDAuth.v1.toAuthorizationHeader(signedObject);\n      return authHeader;\n    } catch (error) {\n      return undefined;\n    }\n  }\n\n  /**\n   * Generate DIDAuthV1 authorization header with specific key ID\n   * @param keyManager - Signer for creating the signature\n   * @param keyId - Specific key ID to use\n   * @param requestUrl - The target URL for the request\n   * @param method - HTTP method (optional, defaults to 'POST')\n   * @returns Authorization header value\n   */\n  static async generateAuthHeaderWithKeyId(\n    keyManager: SignerInterface,\n    keyId: string,\n    requestUrl: string,\n    method: string = 'POST'\n  ): Promise<string> {\n    // Create a signed object with proper payload structure\n    const signedObject = await DIDAuth.v1.createSignature(\n      {\n        operation: 'http_request',\n        params: {\n          uri: requestUrl,\n          method: method.toUpperCase(),\n        },\n      },\n      keyManager,\n      keyId\n    );\n\n    // Convert to authorization header\n    return DIDAuth.v1.toAuthorizationHeader(signedObject);\n  }\n}\n","import { z } from 'zod';\nimport { LosslessNumber } from 'lossless-json';\n\n/**\n * Helper to create a schema that accepts either BigInt, string, number, or LosslessNumber\n * and transforms it to BigInt for our internal use\n */\nexport const createBigIntSchema = () =>\n  z.union([\n    z.bigint(),\n    z.string().transform(BigInt),\n    z.number().transform(BigInt),\n    z.instanceof(LosslessNumber).transform(val => BigInt(val.toString())),\n  ]);\n\n/**\n * Core SubRAV schema that matches the SubRAV interface from core/types.ts\n * This is the authoritative schema for SubRAV objects across the entire payment-kit\n */\nexport const SubRAVSchema = z.object({\n  /** Protocol version (default: 1) */\n  version: z.number(),\n  /** Blockchain identifier (e.g., 4 for Rooch testnet) */\n  chainId: createBigIntSchema(),\n  /** Deterministic channel identifier (32-byte hex string) */\n  channelId: z.string(),\n  /** Channel epoch to prevent replay attacks across channel resets */\n  channelEpoch: createBigIntSchema(),\n  /** DID verification method fragment (e.g., 'key-1') */\n  vmIdFragment: z.string(),\n  /** Total amount ever sent through this sub-channel */\n  accumulatedAmount: createBigIntSchema(),\n  /** Strictly increasing nonce per sub-channel */\n  nonce: createBigIntSchema(),\n});\n\nexport type SubRAV = z.infer<typeof SubRAVSchema>;\n\n/**\n * SignedSubRAV schema that includes signature fields\n * This matches the SignedSubRAV interface from core/types.ts\n */\nexport const SignedSubRAVSchema = z.object({\n  /** SubRAV */\n  subRav: SubRAVSchema,\n  /** Cryptographic signature over the SubRAV */\n  signature: z.string(),\n});\n\nexport type SignedSubRAV = z.infer<typeof SignedSubRAVSchema>;\n\n/**\n * Asset information schema\n */\nexport const AssetInfoSchema = z.object({\n  /** Asset identifier (e.g., \"0x3::gas_coin::RGas\") */\n  id: z.string(),\n  /** Asset symbol (e.g., \"RGas\") */\n  symbol: z.string(),\n  /** Asset name (e.g., \"Rooch Gas\") */\n  name: z.string(),\n  /** Number of decimal places */\n  decimals: z.number(),\n});\n\nexport type AssetInfo = z.infer<typeof AssetInfoSchema>;\n\n/**\n * Channel status enumeration (matches core/types.ts)\n */\nexport const ChannelStatusSchema = z.enum(['active', 'closing', 'closed']);\n\nexport type ChannelStatus = z.infer<typeof ChannelStatusSchema>;\n\n/**\n * Channel information schema (matches core/types.ts ChannelInfo interface)\n */\nexport const ChannelInfoSchema = z.object({\n  /** Channel identifier */\n  channelId: z.string(),\n  /** Payer DID */\n  payerDid: z.string(),\n  /** Payee DID */\n  payeeDid: z.string(),\n  /** Asset identifier */\n  assetId: z.string(),\n  /** Channel epoch */\n  epoch: createBigIntSchema(),\n  /** Channel status */\n  status: ChannelStatusSchema,\n});\n\nexport type ChannelInfo = z.infer<typeof ChannelInfoSchema>;\n\n/**\n * Sub-channel state schema (matches contracts/IPaymentChannelContract SubChannelInfo)\n * Exposed for API schemas that need to serialize sub-channel state (e.g., recovery endpoint)\n */\nexport const SubChannelStateSchema = z.object({\n  /** Associated channel ID */\n  channelId: z.string(),\n  /** Channel epoch */\n  epoch: createBigIntSchema(),\n  /** DID verification method fragment */\n  vmIdFragment: z.string(),\n  /** Optional public key for the verification method */\n  publicKey: z.string().optional(),\n  /** Optional DID method type for the verification method */\n  methodType: z.string().optional(),\n  /** Last on-chain claimed amount for this sub-channel */\n  lastClaimedAmount: createBigIntSchema(),\n  /** Last on-chain confirmed nonce for this sub-channel */\n  lastConfirmedNonce: createBigIntSchema(),\n  /** Optional last updated timestamp (ms) for local caches */\n  lastUpdated: z.number().optional(),\n});\n\n/**\n * Service discovery information schema\n */\nexport const ServiceDiscoverySchema = z.object({\n  /** Protocol version */\n  version: z.number(),\n  /** Service identifier */\n  serviceId: z.string(),\n  /** Service DID */\n  serviceDid: z.string(),\n  /** Network identifier */\n  network: z.string(),\n  /** Default asset identifier */\n  defaultAssetId: z.string(),\n  /** Default price in pico USD (optional) */\n  defaultPricePicoUSD: z.string().optional(),\n  /** API base path */\n  basePath: z.string(),\n});\n\nexport type ServiceDiscovery = z.infer<typeof ServiceDiscoverySchema>;\n\n/**\n * Health check response schema\n */\nexport const HealthCheckSchema = z.object({\n  /** Operation success status */\n  success: z.boolean(),\n  /** Health status description */\n  status: z.string(),\n  /** Response timestamp in ISO-8601 format */\n  timestamp: z.string(),\n  /** Whether payment kit is enabled */\n  paymentKitEnabled: z.boolean(),\n});\n\nexport type HealthCheck = z.infer<typeof HealthCheckSchema>;\n\n/**\n * Claims policy configuration schema\n */\nexport const ClaimTriggerPolicySchema = z.object({\n  /** Minimum accumulated amount to trigger claim (in smallest unit) */\n  minClaimAmount: createBigIntSchema(),\n  /** Maximum number of concurrent claim operations */\n  maxConcurrentClaims: z.number().optional(),\n  /** Retry attempts for failed claims */\n  maxRetries: z.number().optional(),\n  /** Delay between retries in milliseconds */\n  retryDelayMs: z.number().optional(),\n  /** Whether to check hub balance before triggering claims */\n  requireHubBalance: z.boolean().optional(),\n  /** Fixed backoff for insufficient funds (ms) */\n  insufficientFundsBackoffMs: z.number().optional(),\n  /** Count insufficient funds as failures */\n  countInsufficientAsFailure: z.boolean().optional(),\n});\n\nexport type ClaimTriggerPolicy = z.infer<typeof ClaimTriggerPolicySchema>;\n\n/**\n * Claim trigger service status schema (reactive)\n */\nexport const ClaimTriggerStatusSchema = z.object({\n  /** Number of active claims currently processing */\n  active: z.number(),\n  /** Number of tasks queued for processing */\n  queued: z.number(),\n  /** Total successful claims */\n  successCount: z.number(),\n  /** Total failed claims */\n  failedCount: z.number(),\n  /** Total skipped claims */\n  skippedCount: z.number(),\n  /** Total insufficient funds occurrences */\n  insufficientFundsCount: z.number(),\n  /** Number of tasks in backoff (waiting for retry) */\n  backoffCount: z.number(),\n  /** Average claim processing time in milliseconds */\n  avgProcessingTimeMs: z.number(),\n  /** Claim trigger policy (reactive) */\n  policy: ClaimTriggerPolicySchema,\n});\n\nexport type ClaimTriggerStatus = z.infer<typeof ClaimTriggerStatusSchema>;\n\n/**\n * Payment processing statistics schema\n */\nexport const PaymentProcessingStatsSchema = z.object({\n  /** Total number of payment requests processed */\n  totalRequests: z.number(),\n  /** Number of successful payments */\n  successfulPayments: z.number(),\n  /** Number of failed payments */\n  failedPayments: z.number(),\n  /** Number of auto claims triggered */\n  autoClaimsTriggered: z.number(),\n});\n\nexport type PaymentProcessingStats = z.infer<typeof PaymentProcessingStatsSchema>;\n\n/**\n * Claims status information schema\n */\nexport const SystemStatusSchema = z.object({\n  /** Reactive claim trigger status */\n  claims: ClaimTriggerStatusSchema,\n  /** Payment processing statistics */\n  processor: PaymentProcessingStatsSchema,\n  /** Response timestamp in ISO-8601 format */\n  timestamp: z.string(),\n});\n\nexport type SystemStatus = z.infer<typeof SystemStatusSchema>;\n\n/**\n * Claim trigger request schema\n */\nexport const ClaimTriggerRequestSchema = z.object({\n  /** Channel identifier to trigger claim for */\n  channelId: z.string(),\n});\n\nexport type ClaimTriggerRequest = z.infer<typeof ClaimTriggerRequestSchema>;\n\n// Reactive mode: return queued/skipped summary rather than on-chain tx results\nexport const ClaimTriggerQueuedSchema = z.object({\n  vmIdFragment: z.string(),\n  delta: createBigIntSchema(),\n});\n\nexport const ClaimTriggerSkippedSchema = z.object({\n  vmIdFragment: z.string(),\n  reason: z.enum(['no_delta', 'below_threshold']),\n  delta: createBigIntSchema().optional(),\n  threshold: createBigIntSchema().optional(),\n});\n\n/**\n * Claim trigger response schema\n */\nexport const ClaimTriggerResponseSchema = z.object({\n  channelId: z.string(),\n  queued: z.array(ClaimTriggerQueuedSchema),\n  skipped: z.array(ClaimTriggerSkippedSchema),\n});\n\nexport type ClaimTriggerResponse = z.infer<typeof ClaimTriggerResponseSchema>;\n\n/**\n * Standard error codes enumeration - kept here as it's used for validating error responses\n */\nexport const ErrorCodeSchema = z.enum([\n  // Authentication & Authorization\n  'UNAUTHORIZED',\n  'FORBIDDEN',\n\n  // Payment related\n  'PAYMENT_REQUIRED',\n  'INSUFFICIENT_FUNDS',\n  'CONFLICT',\n\n  // General errors\n  'NOT_FOUND',\n  'BAD_REQUEST',\n  'INTERNAL_ERROR',\n  'SERVICE_UNAVAILABLE',\n]);\n\nexport type ErrorCodeType = z.infer<typeof ErrorCodeSchema>;\n\n/**\n * Standard API error structure - kept here as it's validated in responses\n */\nexport const ApiErrorSchema = z.object({\n  code: ErrorCodeSchema,\n  message: z.string(),\n  details: z.any().optional(),\n  httpStatus: z.number().optional(),\n});\n\nexport type ApiError = z.infer<typeof ApiErrorSchema>;\n\n/**\n * Persisted HTTP client state schema for JSON serialization\n * Used by HostChannelMappingStore for safe BigInt handling\n */\nexport const PersistedHttpClientStateSchema = z.object({\n  /** Channel identifier */\n  channelId: z.string().optional(),\n  /** Pending SubRAV data */\n  pendingSubRAV: SubRAVSchema.optional(),\n  /** Last update timestamp (ISO string) */\n  lastUpdated: z.string().optional(),\n});\n\nexport type PersistedHttpClientState = z.infer<typeof PersistedHttpClientStateSchema>;\n","/**\n * JSON utilities with BigInt support using lossless-json\n *\n * This module provides unified JSON serialization/deserialization\n * that properly handles BigInt values without manual field conversion.\n */\n\nimport { stringify, parse, LosslessNumber } from 'lossless-json';\n\n/**\n * Serialize any object to JSON string with BigInt support\n */\nexport function serializeJson(value: any): string {\n  const result = stringify(value);\n  if (result === undefined) {\n    throw new Error('Failed to serialize value to JSON');\n  }\n  return result;\n}\n\n/**\n * Parse JSON string to object with minimal processing\n * Now that we use Zod schemas for validation and transformation,\n * this function only handles basic lossless parsing without field-specific logic\n */\nexport function parseJson<T = any>(text: string): T {\n  return parse(text, (key, value) => {\n    // Convert LosslessNumber to safe numbers where possible\n    if (value instanceof LosslessNumber) {\n      const str = value.toString();\n      // Check if it's an integer (no decimal point)\n      if (str.indexOf('.') === -1 && str.indexOf('e') === -1 && str.indexOf('E') === -1) {\n        // For integer fields, convert to regular number if within safe range\n        const num = Number(str);\n        if (Number.isSafeInteger(num)) {\n          return num;\n        }\n        // Keep as LosslessNumber for large integers - Zod will handle BigInt conversion\n        return value;\n      }\n    }\n    return value;\n  }) as T;\n}\n\n/**\n * Response helper for Express routes\n */\nexport function sendJsonResponse(res: any, data: any): void {\n  res.setHeader('Content-Type', 'application/json');\n  res.send(serializeJson(data));\n}\n\n/**\n * Parse Response object to JSON with BigInt support\n */\nexport async function parseJsonResponse<T = any>(response: Response): Promise<T> {\n  const text = await response.text();\n  return parseJson<T>(text);\n}\n\n/**\n * Safe JSON stringify that handles BigInt by converting to string\n * Useful for logging and debugging\n */\nexport function safeStringify(value: any, space?: string | number): string {\n  return JSON.stringify(\n    value,\n    (key, val) => {\n      return typeof val === 'bigint' ? val.toString() : val;\n    },\n    space\n  );\n}\n","/**\n * Memory-based implementation of ChannelRepository\n * For testing and development environments\n */\n\nimport type { ChannelInfo, SubChannelInfo } from '../../core/types';\nimport type { ChannelRepository } from '../interfaces/ChannelRepository';\nimport type {\n  PaginationParams,\n  ChannelFilter,\n  PaginatedResult,\n  CacheStats,\n} from '../types/pagination';\n\nexport class MemoryChannelRepository implements ChannelRepository {\n  private channelMetadata = new Map<string, ChannelInfo>();\n  private subChannelStates = new Map<string, SubChannelInfo>();\n  private hitCount = 0;\n  private missCount = 0;\n\n  private getSubChannelKey(channelId: string, vmIdFragment: string): string {\n    return `${channelId}:${vmIdFragment}`;\n  }\n\n  // -------- Channel Metadata Operations --------\n\n  async getChannelMetadata(channelId: string): Promise<ChannelInfo | null> {\n    const result = this.channelMetadata.get(channelId) || null;\n    if (result) {\n      this.hitCount++;\n    } else {\n      this.missCount++;\n    }\n    return result;\n  }\n\n  async setChannelMetadata(channelId: string, metadata: ChannelInfo): Promise<void> {\n    this.channelMetadata.set(channelId, { ...metadata });\n  }\n\n  async listChannelMetadata(\n    filter?: ChannelFilter,\n    pagination?: PaginationParams\n  ): Promise<PaginatedResult<ChannelInfo>> {\n    let channels = Array.from(this.channelMetadata.values());\n\n    // Apply filters\n    if (filter) {\n      channels = channels.filter(channel => {\n        if (filter.payerDid && channel.payerDid !== filter.payerDid) return false;\n        if (filter.payeeDid && channel.payeeDid !== filter.payeeDid) return false;\n        if (filter.status && channel.status !== filter.status) return false;\n        if (filter.assetId && channel.assetId !== filter.assetId) return false;\n        // Note: ChannelInfo doesn't have createdAt field in current definition\n        // These filters are not supported yet\n        // if (filter.createdAfter && channel.createdAt < filter.createdAfter) return false;\n        // if (filter.createdBefore && channel.createdAt > filter.createdBefore) return false;\n        return true;\n      });\n    }\n\n    const totalCount = channels.length;\n\n    // Apply pagination\n    const offset = pagination?.offset || 0;\n    const limit = pagination?.limit || 50;\n    const paginatedChannels = channels.slice(offset, offset + limit);\n\n    return {\n      items: paginatedChannels,\n      totalCount,\n      hasMore: offset + limit < totalCount,\n    };\n  }\n\n  async removeChannelMetadata(channelId: string): Promise<void> {\n    this.channelMetadata.delete(channelId);\n  }\n\n  // -------- Sub-Channel State Operations --------\n\n  async getSubChannelState(\n    channelId: string,\n    vmIdFragment: string\n  ): Promise<SubChannelInfo | null> {\n    const key = this.getSubChannelKey(channelId, vmIdFragment);\n    const existing = this.subChannelStates.get(key);\n\n    if (existing) {\n      this.hitCount++;\n      return { ...existing };\n    }\n\n    this.missCount++;\n    return null;\n  }\n\n  async updateSubChannelState(\n    channelId: string,\n    vmIdFragment: string,\n    updates: Partial<SubChannelInfo>\n  ): Promise<void> {\n    const key = this.getSubChannelKey(channelId, vmIdFragment);\n    const existing = this.subChannelStates.get(key) || {\n      channelId,\n      vmIdFragment,\n      epoch: BigInt(0),\n      lastConfirmedNonce: BigInt(0),\n      lastClaimedAmount: BigInt(0),\n      lastUpdated: Date.now(),\n    };\n\n    const updated = {\n      ...existing,\n      ...updates,\n      lastUpdated: Date.now(),\n    };\n\n    this.subChannelStates.set(key, updated);\n  }\n\n  async listSubChannelStates(channelId: string): Promise<Record<string, SubChannelInfo>> {\n    const result: Record<string, SubChannelInfo> = {};\n\n    for (const [key, state] of this.subChannelStates.entries()) {\n      if (key.startsWith(channelId + ':')) {\n        // Extract vmIdFragment from the key (format: channelId:vmIdFragment)\n        const vmIdFragment = key.substring(channelId.length + 1);\n        result[vmIdFragment] = { ...state };\n      }\n    }\n\n    return result;\n  }\n\n  async removeSubChannelState(channelId: string, vmIdFragment: string): Promise<void> {\n    const key = this.getSubChannelKey(channelId, vmIdFragment);\n    this.subChannelStates.delete(key);\n  }\n\n  // -------- Management Operations --------\n\n  async getStats(): Promise<CacheStats> {\n    const totalAccess = this.hitCount + this.missCount;\n\n    return {\n      channelCount: this.channelMetadata.size,\n      subChannelCount: this.subChannelStates.size,\n      hitRate: totalAccess > 0 ? this.hitCount / totalAccess : 0,\n      sizeBytes: this.estimateSize(),\n    };\n  }\n\n  async clear(): Promise<void> {\n    this.channelMetadata.clear();\n    this.subChannelStates.clear();\n    this.hitCount = 0;\n    this.missCount = 0;\n  }\n\n  private estimateSize(): number {\n    // Rough estimation of memory usage (avoiding BigInt serialization issues)\n    let size = 0;\n\n    for (const channel of this.channelMetadata.values()) {\n      // Simple estimation without JSON.stringify to avoid BigInt issues\n      size += channel.channelId.length * 2;\n      size += channel.payerDid.length * 2;\n      size += channel.payeeDid.length * 2;\n      size += channel.assetId.length * 2;\n      size += 100; // Rough estimate for bigint and other fields\n    }\n\n    for (const state of this.subChannelStates.values()) {\n      // Simple estimation without JSON.stringify to avoid BigInt issues\n      size += state.channelId.length * 2;\n      size += 200; // Rough estimate for bigint fields and numbers\n    }\n\n    return size;\n  }\n}\n","/**\n * Browser IndexedDB-based ChannelRepository implementation\n */\n\nimport type { ChannelInfo, SubChannelInfo } from '../../core/types';\nimport type { ChannelRepository } from '../interfaces/ChannelRepository';\nimport type {\n  PaginationParams,\n  ChannelFilter,\n  PaginatedResult,\n  CacheStats,\n} from '../types/pagination';\n\nexport class IndexedDBChannelRepository implements ChannelRepository {\n  private dbName = 'nuwa-payment-kit-channels';\n  private version = 1;\n\n  private async getDB(): Promise<IDBDatabase> {\n    return new Promise((resolve, reject) => {\n      const request = indexedDB.open(this.dbName, this.version);\n\n      request.onerror = () => reject(request.error);\n      request.onsuccess = () => resolve(request.result);\n\n      request.onupgradeneeded = event => {\n        const db = (event.target as IDBOpenDBRequest).result;\n\n        // Channel metadata store\n        if (!db.objectStoreNames.contains('channels')) {\n          const store = db.createObjectStore('channels', { keyPath: 'channelId' });\n          store.createIndex('payerDid', 'payerDid', { unique: false });\n          store.createIndex('payeeDid', 'payeeDid', { unique: false });\n          store.createIndex('status', 'status', { unique: false });\n        }\n\n        // Sub-channel states store\n        if (!db.objectStoreNames.contains('subChannelStates')) {\n          const store = db.createObjectStore('subChannelStates', {\n            keyPath: ['channelId', 'vmIdFragment'],\n          });\n          store.createIndex('channelId', 'channelId', { unique: false });\n        }\n      };\n    });\n  }\n\n  // -------- Channel Metadata Operations --------\n\n  async getChannelMetadata(channelId: string): Promise<ChannelInfo | null> {\n    const db = await this.getDB();\n    const tx = db.transaction(['channels'], 'readonly');\n    const store = tx.objectStore('channels');\n\n    return new Promise((resolve, reject) => {\n      const request = store.get(channelId);\n      request.onsuccess = () => resolve(request.result || null);\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  async setChannelMetadata(channelId: string, metadata: ChannelInfo): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['channels'], 'readwrite');\n    const store = tx.objectStore('channels');\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.put({ ...metadata, channelId });\n      request.onsuccess = () => resolve();\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  async listChannelMetadata(\n    filter?: ChannelFilter,\n    pagination?: PaginationParams\n  ): Promise<PaginatedResult<ChannelInfo>> {\n    const db = await this.getDB();\n    const tx = db.transaction(['channels'], 'readonly');\n    const store = tx.objectStore('channels');\n\n    const channels: ChannelInfo[] = [];\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.openCursor();\n\n      request.onsuccess = () => {\n        const cursor = request.result;\n        if (cursor) {\n          const channel = cursor.value as ChannelInfo;\n\n          // Apply filters\n          let includeChannel = true;\n          if (filter) {\n            if (filter.payerDid && channel.payerDid !== filter.payerDid) includeChannel = false;\n            if (filter.payeeDid && channel.payeeDid !== filter.payeeDid) includeChannel = false;\n            if (filter.status && channel.status !== filter.status) includeChannel = false;\n            if (filter.assetId && channel.assetId !== filter.assetId) includeChannel = false;\n            // Note: ChannelInfo doesn't have createdAt field in current definition\n            // These filters are not supported yet\n            // if (filter.createdAfter && channel.createdAt < filter.createdAfter) includeChannel = false;\n            // if (filter.createdBefore && channel.createdAt > filter.createdBefore) includeChannel = false;\n          }\n\n          if (includeChannel) {\n            channels.push(channel);\n          }\n\n          cursor.continue();\n        } else {\n          resolve();\n        }\n      };\n\n      request.onerror = () => reject(request.error);\n    });\n\n    const totalCount = channels.length;\n\n    // Apply pagination\n    const offset = pagination?.offset || 0;\n    const limit = pagination?.limit || 50;\n    const paginatedChannels = channels.slice(offset, offset + limit);\n\n    return {\n      items: paginatedChannels,\n      totalCount,\n      hasMore: offset + limit < totalCount,\n    };\n  }\n\n  async removeChannelMetadata(channelId: string): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['channels'], 'readwrite');\n    const store = tx.objectStore('channels');\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.delete(channelId);\n      request.onsuccess = () => resolve();\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  // -------- Sub-Channel State Operations --------\n\n  async getSubChannelState(\n    channelId: string,\n    vmIdFragment: string\n  ): Promise<SubChannelInfo | null> {\n    const db = await this.getDB();\n    const tx = db.transaction(['subChannelStates'], 'readonly');\n    const store = tx.objectStore('subChannelStates');\n\n    const existing = await new Promise<SubChannelInfo | null>((resolve, reject) => {\n      const request = store.get([channelId, vmIdFragment]);\n      request.onsuccess = () => resolve(request.result || null);\n      request.onerror = () => reject(request.error);\n    });\n\n    if (existing) {\n      return {\n        ...existing,\n        lastConfirmedNonce: BigInt(\n          (existing as any).lastConfirmedNonce ?? (existing as any).nonce ?? 0\n        ),\n        lastClaimedAmount: BigInt(\n          (existing as any).lastClaimedAmount ?? (existing as any).accumulatedAmount ?? 0\n        ),\n      } as any;\n    }\n\n    return null;\n  }\n\n  async updateSubChannelState(\n    channelId: string,\n    vmIdFragment: string,\n    updates: Partial<SubChannelInfo>\n  ): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['subChannelStates'], 'readwrite');\n    const store = tx.objectStore('subChannelStates');\n\n    // Get existing state first\n    const existing = await new Promise<SubChannelInfo | null>((resolve, reject) => {\n      const request = store.get([channelId, vmIdFragment]);\n      request.onsuccess = () => resolve(request.result || null);\n      request.onerror = () => reject(request.error);\n    });\n\n    const baseState =\n      existing ||\n      ({\n        channelId,\n        vmIdFragment,\n        epoch: BigInt(0),\n        lastConfirmedNonce: BigInt(0),\n        lastClaimedAmount: BigInt(0),\n        lastUpdated: Date.now(),\n      } as any);\n\n    const updated = {\n      ...baseState,\n      ...updates,\n      channelId,\n      vmIdFragment,\n      lastUpdated: Date.now(),\n      // Convert bigints to strings for storage\n      lastConfirmedNonce:\n        (updates as any).lastConfirmedNonce?.toString() ||\n        (baseState as any).lastConfirmedNonce?.toString() ||\n        '0',\n      lastClaimedAmount:\n        (updates as any).lastClaimedAmount?.toString() ||\n        (baseState as any).lastClaimedAmount?.toString() ||\n        '0',\n    };\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.put(updated);\n      request.onsuccess = () => resolve();\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  async listSubChannelStates(channelId: string): Promise<Record<string, SubChannelInfo>> {\n    const db = await this.getDB();\n    const tx = db.transaction(['subChannelStates'], 'readonly');\n    const store = tx.objectStore('subChannelStates');\n    const index = store.index('channelId');\n\n    const result: Record<string, SubChannelInfo> = {};\n\n    await new Promise<void>((resolve, reject) => {\n      const request = index.openCursor(IDBKeyRange.only(channelId));\n\n      request.onsuccess = () => {\n        const cursor = request.result;\n        if (cursor) {\n          const state = cursor.value as any;\n          result[state.vmIdFragment] = {\n            ...state,\n            lastConfirmedNonce: BigInt((state as any).lastConfirmedNonce ?? state.nonce ?? 0),\n            lastClaimedAmount: BigInt(\n              (state as any).lastClaimedAmount ?? state.accumulatedAmount ?? 0\n            ),\n          } as any;\n          cursor.continue();\n        } else {\n          resolve();\n        }\n      };\n\n      request.onerror = () => reject(request.error);\n    });\n\n    return result;\n  }\n\n  async removeSubChannelState(channelId: string, vmIdFragment: string): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['subChannelStates'], 'readwrite');\n    const store = tx.objectStore('subChannelStates');\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.delete([channelId, vmIdFragment]);\n      request.onsuccess = () => resolve();\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  // -------- Management Operations --------\n\n  async getStats(): Promise<CacheStats> {\n    const db = await this.getDB();\n\n    const channelCount = await new Promise<number>((resolve, reject) => {\n      const tx = db.transaction(['channels'], 'readonly');\n      const store = tx.objectStore('channels');\n      const request = store.count();\n\n      request.onsuccess = () => resolve(request.result);\n      request.onerror = () => reject(request.error);\n    });\n\n    const subChannelCount = await new Promise<number>((resolve, reject) => {\n      const tx = db.transaction(['subChannelStates'], 'readonly');\n      const store = tx.objectStore('subChannelStates');\n      const request = store.count();\n\n      request.onsuccess = () => resolve(request.result);\n      request.onerror = () => reject(request.error);\n    });\n\n    return {\n      channelCount,\n      subChannelCount,\n      hitRate: undefined, // Not tracked in IndexedDB implementation\n      sizeBytes: undefined, // Hard to estimate in IndexedDB\n    };\n  }\n\n  async clear(): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['channels', 'subChannelStates'], 'readwrite');\n\n    await Promise.all([\n      new Promise<void>((resolve, reject) => {\n        const request = tx.objectStore('channels').clear();\n        request.onsuccess = () => resolve();\n        request.onerror = () => reject(request.error);\n      }),\n      new Promise<void>((resolve, reject) => {\n        const request = tx.objectStore('subChannelStates').clear();\n        request.onsuccess = () => resolve();\n        request.onerror = () => reject(request.error);\n      }),\n    ]);\n  }\n}\n","/**\n * Factory function for creating ChannelRepository instances\n */\n\nimport type { Pool } from 'pg';\nimport type { ChannelRepository } from '../interfaces/ChannelRepository';\nimport { MemoryChannelRepository } from '../memory/channel.memory';\nimport { IndexedDBChannelRepository } from '../indexeddb/channel.indexeddb';\nimport { SqlChannelRepository, type SqlChannelRepositoryOptions } from '../sql/channel.sql';\n\nexport interface ChannelRepositoryOptions {\n  /** Backend type to use */\n  backend?: 'memory' | 'indexeddb' | 'sql';\n  /** Database connection string for SQL backends */\n  connectionString?: string;\n  /** PostgreSQL connection pool (alternative to connectionString) */\n  pool?: Pool;\n  /** Table name prefix for SQL backends */\n  tablePrefix?: string;\n  /** Auto-create tables if they don't exist */\n  autoMigrate?: boolean;\n  /** Allow unsafe auto-migration in production */\n  allowUnsafeAutoMigrateInProd?: boolean;\n}\n\n/**\n * Create a ChannelRepository instance based on the specified backend\n */\nexport function createChannelRepo(options: ChannelRepositoryOptions = {}): ChannelRepository {\n  const { backend = 'memory' } = options;\n\n  switch (backend) {\n    case 'memory':\n      return new MemoryChannelRepository();\n\n    case 'indexeddb':\n      if (typeof window === 'undefined' || !window.indexedDB) {\n        throw new Error('IndexedDB is not available in this environment');\n      }\n      return new IndexedDBChannelRepository();\n\n    case 'sql':\n      // Do not create pool here; caller must provide a Pool (Node-only)\n      if (!options.pool) {\n        throw new Error('SQL backend requires a PostgreSQL connection pool');\n      }\n\n      const sqlOptions: SqlChannelRepositoryOptions = {\n        pool: options.pool,\n        tablePrefix: options.tablePrefix,\n        autoMigrate: options.autoMigrate,\n        allowUnsafeAutoMigrateInProd: options.allowUnsafeAutoMigrateInProd,\n      };\n\n      return new SqlChannelRepository(sqlOptions);\n\n    default:\n      throw new Error(`Unknown backend type: ${backend}`);\n  }\n}\n","/**\n * Memory-based implementation of RAVRepository\n * For testing and development environments\n */\n\nimport type { SignedSubRAV } from '../../core/types';\nimport type { RAVRepository } from '../interfaces/RAVRepository';\n\nexport class MemoryRAVRepository implements RAVRepository {\n  private ravs = new Map<string, SignedSubRAV[]>();\n  private claimedNonces = new Map<string, bigint>();\n\n  private getKey(channelId: string, vmIdFragment: string): string {\n    return `${channelId}:${vmIdFragment}`;\n  }\n\n  async save(rav: SignedSubRAV): Promise<void> {\n    const key = this.getKey(rav.subRav.channelId, rav.subRav.vmIdFragment);\n\n    if (!this.ravs.has(key)) {\n      this.ravs.set(key, []);\n    }\n\n    const ravList = this.ravs.get(key)!;\n\n    // Check if RAV with same nonce already exists (idempotent)\n    const existing = ravList.find(r => r.subRav.nonce === rav.subRav.nonce);\n    if (existing) {\n      return; // Already exists\n    }\n\n    // Insert in sorted order by nonce\n    ravList.push(rav);\n    ravList.sort((a, b) => Number(a.subRav.nonce - b.subRav.nonce));\n  }\n\n  async get(channelId: string, vmIdFragment: string, nonce: bigint): Promise<SignedSubRAV | null> {\n    const key = this.getKey(channelId, vmIdFragment);\n    const ravList = this.ravs.get(key);\n    if (!ravList) {\n      return null;\n    }\n\n    const rav = ravList.find(r => r.subRav.nonce === nonce);\n    if (!rav) {\n      return null;\n    }\n    return rav;\n  }\n\n  async getLatest(channelId: string, vmIdFragment: string): Promise<SignedSubRAV | null> {\n    const key = this.getKey(channelId, vmIdFragment);\n    const ravList = this.ravs.get(key);\n\n    if (!ravList || ravList.length === 0) {\n      return null;\n    }\n\n    return ravList[ravList.length - 1];\n  }\n\n  async *list(channelId: string): AsyncIterable<SignedSubRAV> {\n    for (const [key, ravList] of this.ravs.entries()) {\n      if (key.startsWith(channelId + ':')) {\n        for (const rav of ravList) {\n          yield rav;\n        }\n      }\n    }\n  }\n\n  async getUnclaimedRAVs(channelId: string): Promise<Map<string, SignedSubRAV>> {\n    const result = new Map<string, SignedSubRAV>();\n\n    for (const [key, ravList] of this.ravs.entries()) {\n      if (key.startsWith(channelId + ':')) {\n        const vmIdFragment = key.split(':')[1];\n        const claimedNonce = this.claimedNonces.get(key) || BigInt(0);\n\n        // Find the latest unclaimed RAV\n        for (let i = ravList.length - 1; i >= 0; i--) {\n          const rav = ravList[i];\n          if (rav.subRav.nonce > claimedNonce) {\n            result.set(vmIdFragment, rav);\n            break;\n          }\n        }\n      }\n    }\n\n    return result;\n  }\n\n  async markAsClaimed(channelId: string, vmIdFragment: string, nonce: bigint): Promise<void> {\n    const key = this.getKey(channelId, vmIdFragment);\n    this.claimedNonces.set(key, nonce);\n  }\n\n  async getStats(): Promise<{ totalRAVs: number; unclaimedRAVs: number }> {\n    let totalRAVs = 0;\n    let unclaimedRAVs = 0;\n\n    for (const [key, ravList] of this.ravs.entries()) {\n      totalRAVs += ravList.length;\n\n      const claimedNonce = this.claimedNonces.get(key) || BigInt(0);\n      for (const rav of ravList) {\n        if (rav.subRav.nonce > claimedNonce) {\n          unclaimedRAVs++;\n        }\n      }\n    }\n\n    return { totalRAVs, unclaimedRAVs };\n  }\n\n  async cleanup(): Promise<number> {\n    let cleanedCount = 0;\n\n    for (const [key, ravList] of this.ravs.entries()) {\n      const claimedNonce = this.claimedNonces.get(key);\n      if (claimedNonce !== undefined) {\n        const originalLength = ravList.length;\n\n        // Remove claimed RAVs\n        this.ravs.set(\n          key,\n          ravList.filter(rav => rav.subRav.nonce > claimedNonce)\n        );\n\n        cleanedCount += originalLength - this.ravs.get(key)!.length;\n      }\n    }\n\n    return cleanedCount;\n  }\n}\n","/**\n * Browser IndexedDB-based RAVRepository implementation\n */\n\nimport type { SignedSubRAV } from '../../core/types';\nimport type { RAVRepository } from '../interfaces/RAVRepository';\n\nexport class IndexedDBRAVRepository implements RAVRepository {\n  private dbName = 'nuwa-payment-kit-ravs';\n  private version = 1;\n\n  private async getDB(): Promise<IDBDatabase> {\n    return new Promise((resolve, reject) => {\n      const request = indexedDB.open(this.dbName, this.version);\n\n      request.onerror = () => reject(request.error);\n      request.onsuccess = () => resolve(request.result);\n\n      request.onupgradeneeded = event => {\n        const db = (event.target as IDBOpenDBRequest).result;\n\n        // RAVs store\n        if (!db.objectStoreNames.contains('ravs')) {\n          const store = db.createObjectStore('ravs', {\n            keyPath: ['channelId', 'vmIdFragment', 'nonce'],\n          });\n          store.createIndex('channelId', 'channelId', { unique: false });\n          store.createIndex('channel_vm', ['channelId', 'vmIdFragment'], { unique: false });\n        }\n\n        // Claims tracking store\n        if (!db.objectStoreNames.contains('claims')) {\n          db.createObjectStore('claims', {\n            keyPath: ['channelId', 'vmIdFragment'],\n          });\n        }\n      };\n    });\n  }\n\n  async save(rav: SignedSubRAV): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['ravs'], 'readwrite');\n    const store = tx.objectStore('ravs');\n\n    const record = {\n      channelId: rav.subRav.channelId,\n      vmIdFragment: rav.subRav.vmIdFragment,\n      nonce: rav.subRav.nonce.toString(),\n      accumulatedAmount: rav.subRav.accumulatedAmount.toString(),\n      ravData: rav,\n      timestamp: Date.now(),\n    };\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.put(record);\n      request.onsuccess = () => resolve();\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  async get(channelId: string, vmIdFragment: string, nonce: bigint): Promise<SignedSubRAV | null> {\n    const db = await this.getDB();\n    const tx = db.transaction(['ravs'], 'readonly');\n    const store = tx.objectStore('ravs');\n\n    return new Promise((resolve, reject) => {\n      const key = [channelId, vmIdFragment, nonce.toString()];\n      const request = store.get(key);\n      request.onsuccess = () => {\n        if (request.result) {\n          resolve(request.result.ravData);\n        } else {\n          resolve(null);\n        }\n      };\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  async getLatest(channelId: string, vmIdFragment: string): Promise<SignedSubRAV | null> {\n    const db = await this.getDB();\n    const tx = db.transaction(['ravs'], 'readonly');\n    const store = tx.objectStore('ravs');\n    const index = store.index('channel_vm');\n\n    return new Promise((resolve, reject) => {\n      const request = index.openCursor(\n        IDBKeyRange.only([channelId, vmIdFragment]),\n        'prev' // Latest first\n      );\n\n      request.onsuccess = () => {\n        const cursor = request.result;\n        if (cursor) {\n          resolve(cursor.value.ravData);\n        } else {\n          resolve(null);\n        }\n      };\n\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  async *list(channelId: string): AsyncIterable<SignedSubRAV> {\n    const db = await this.getDB();\n    const tx = db.transaction(['ravs'], 'readonly');\n    const store = tx.objectStore('ravs');\n    const index = store.index('channelId');\n\n    const request = index.openCursor(IDBKeyRange.only(channelId));\n\n    while (true) {\n      const cursor = await new Promise<IDBCursorWithValue | null>((resolve, reject) => {\n        request.onsuccess = () => resolve(request.result);\n        request.onerror = () => reject(request.error);\n      });\n\n      if (!cursor) break;\n\n      yield cursor.value.ravData;\n      cursor.continue();\n    }\n  }\n\n  async getUnclaimedRAVs(channelId: string): Promise<Map<string, SignedSubRAV>> {\n    const result = new Map<string, SignedSubRAV>();\n\n    // Get claimed nonces first\n    const claimedNonces = await this.getClaimedNonces(channelId);\n\n    for await (const rav of this.list(channelId)) {\n      const vmIdFragment = rav.subRav.vmIdFragment;\n      const claimedNonce = claimedNonces.get(vmIdFragment) || BigInt(0);\n\n      if (rav.subRav.nonce > claimedNonce) {\n        const existing = result.get(vmIdFragment);\n        if (!existing || rav.subRav.nonce > existing.subRav.nonce) {\n          result.set(vmIdFragment, rav);\n        }\n      }\n    }\n\n    return result;\n  }\n\n  private async getClaimedNonces(channelId: string): Promise<Map<string, bigint>> {\n    const db = await this.getDB();\n    const tx = db.transaction(['claims'], 'readonly');\n    const store = tx.objectStore('claims');\n\n    const result = new Map<string, bigint>();\n\n    return new Promise((resolve, reject) => {\n      const request = store.openCursor();\n\n      request.onsuccess = () => {\n        const cursor = request.result;\n        if (cursor) {\n          const record = cursor.value;\n          if (record.channelId === channelId) {\n            result.set(record.vmIdFragment, BigInt(record.claimedNonce));\n          }\n          cursor.continue();\n        } else {\n          resolve(result);\n        }\n      };\n\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  async markAsClaimed(channelId: string, vmIdFragment: string, nonce: bigint): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['claims'], 'readwrite');\n    const store = tx.objectStore('claims');\n\n    const record = {\n      channelId,\n      vmIdFragment,\n      claimedNonce: nonce.toString(),\n      timestamp: Date.now(),\n    };\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.put(record);\n      request.onsuccess = () => resolve();\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  async getStats(): Promise<{ totalRAVs: number; unclaimedRAVs: number }> {\n    const db = await this.getDB();\n\n    // Count total RAVs\n    const totalRAVs = await new Promise<number>((resolve, reject) => {\n      const tx = db.transaction(['ravs'], 'readonly');\n      const store = tx.objectStore('ravs');\n      const request = store.count();\n\n      request.onsuccess = () => resolve(request.result);\n      request.onerror = () => reject(request.error);\n    });\n\n    // Count unclaimed RAVs (this is an approximation - could be more precise)\n    let unclaimedRAVs = 0;\n    const channelVMs = new Set<string>();\n\n    // First pass: collect all channel-vm combinations\n    const tx1 = db.transaction(['ravs'], 'readonly');\n    const store1 = tx1.objectStore('ravs');\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store1.openCursor();\n\n      request.onsuccess = () => {\n        const cursor = request.result;\n        if (cursor) {\n          const record = cursor.value;\n          channelVMs.add(`${record.channelId}:${record.vmIdFragment}`);\n          cursor.continue();\n        } else {\n          resolve();\n        }\n      };\n\n      request.onerror = () => reject(request.error);\n    });\n\n    // For each channel-vm combination, check if there are unclaimed RAVs\n    for (const channelVM of channelVMs) {\n      const [channelId, vmIdFragment] = channelVM.split(':');\n      const unclaimed = await this.getUnclaimedRAVs(channelId);\n      if (unclaimed.has(vmIdFragment)) {\n        unclaimedRAVs++;\n      }\n    }\n\n    return { totalRAVs, unclaimedRAVs };\n  }\n\n  async cleanup(): Promise<number> {\n    // For IndexedDB, we can implement cleanup by removing claimed RAVs\n    let cleanedCount = 0;\n    const db = await this.getDB();\n\n    // Get all claimed nonces\n    const claimedNonces = new Map<string, bigint>();\n    const tx1 = db.transaction(['claims'], 'readonly');\n    const store1 = tx1.objectStore('claims');\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store1.openCursor();\n\n      request.onsuccess = () => {\n        const cursor = request.result;\n        if (cursor) {\n          const record = cursor.value;\n          claimedNonces.set(\n            `${record.channelId}:${record.vmIdFragment}`,\n            BigInt(record.claimedNonce)\n          );\n          cursor.continue();\n        } else {\n          resolve();\n        }\n      };\n\n      request.onerror = () => reject(request.error);\n    });\n\n    // Remove claimed RAVs\n    const tx2 = db.transaction(['ravs'], 'readwrite');\n    const store2 = tx2.objectStore('ravs');\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store2.openCursor();\n\n      request.onsuccess = () => {\n        const cursor = request.result;\n        if (cursor) {\n          const record = cursor.value;\n          const key = `${record.channelId}:${record.vmIdFragment}`;\n          const claimedNonce = claimedNonces.get(key);\n\n          if (claimedNonce && BigInt(record.nonce) <= claimedNonce) {\n            cursor.delete();\n            cleanedCount++;\n          }\n\n          cursor.continue();\n        } else {\n          resolve();\n        }\n      };\n\n      request.onerror = () => reject(request.error);\n    });\n\n    return cleanedCount;\n  }\n}\n","/**\n * Factory function for creating RAV repositories\n */\n\nimport type { Pool } from 'pg';\nimport type { RAVRepository } from '../interfaces/RAVRepository';\nimport { MemoryRAVRepository } from '../memory/rav.memory';\nimport { IndexedDBRAVRepository } from '../indexeddb/rav.indexeddb';\nimport { SqlRAVRepository, type SqlRAVRepositoryOptions } from '../sql/rav.sql';\n\nexport interface RAVRepositoryOptions {\n  /** Backend type to use */\n  backend?: 'memory' | 'indexeddb' | 'sql';\n  /** Database connection string for SQL backends */\n  connectionString?: string;\n  /** PostgreSQL connection pool (alternative to connectionString) */\n  pool?: Pool;\n  /** Table name prefix for SQL backends */\n  tablePrefix?: string;\n  /** Auto-create tables if they don't exist */\n  autoMigrate?: boolean;\n  /** Allow unsafe auto-migration in production */\n  allowUnsafeAutoMigrateInProd?: boolean;\n}\n\n/**\n * Create a RAV repository instance based on the specified backend\n */\nexport function createRAVRepo(options: RAVRepositoryOptions = {}): RAVRepository {\n  const { backend = 'memory' } = options;\n\n  switch (backend) {\n    case 'memory':\n      return new MemoryRAVRepository();\n\n    case 'indexeddb':\n      if (typeof window === 'undefined' || !window.indexedDB) {\n        throw new Error('IndexedDB is not available in this environment');\n      }\n      return new IndexedDBRAVRepository();\n\n    case 'sql':\n      // Do not create pool here; caller must provide a Pool (Node-only)\n      if (!options.pool) {\n        throw new Error('SQL backend requires a PostgreSQL connection pool');\n      }\n\n      const sqlOptions: SqlRAVRepositoryOptions = {\n        pool: options.pool,\n        tablePrefix: options.tablePrefix,\n        autoMigrate: options.autoMigrate,\n        allowUnsafeAutoMigrateInProd: options.allowUnsafeAutoMigrateInProd,\n      };\n\n      return new SqlRAVRepository(sqlOptions);\n\n    default:\n      throw new Error(`Unknown backend type: ${backend}`);\n  }\n}\n","/**\n * Memory-based implementation of PendingSubRAVRepository\n * For testing and development environments\n */\n\nimport type { SubRAV } from '../../core/types';\nimport type { PendingSubRAVRepository } from '../interfaces/PendingSubRAVRepository';\nimport type { PendingSubRAVStats } from '../types/pagination';\n\nexport class MemoryPendingSubRAVRepository implements PendingSubRAVRepository {\n  private proposals = new Map<string, { subRAV: SubRAV; timestamp: number }>();\n\n  private getKey(channelId: string, vmIdFragment: string, nonce: bigint): string {\n    return `${channelId}:${vmIdFragment}:${nonce}`;\n  }\n\n  async save(subRAV: SubRAV): Promise<void> {\n    const key = this.getKey(subRAV.channelId, subRAV.vmIdFragment, subRAV.nonce);\n    this.proposals.set(key, {\n      subRAV: { ...subRAV }, // Deep copy to avoid mutations\n      timestamp: Date.now(),\n    });\n  }\n\n  async find(channelId: string, vmIdFragment: string, nonce: bigint): Promise<SubRAV | null> {\n    const key = this.getKey(channelId, vmIdFragment, nonce);\n    const entry = this.proposals.get(key);\n\n    if (!entry) {\n      return null;\n    }\n\n    return { ...entry.subRAV }; // Return copy to avoid mutations\n  }\n\n  async findLatestBySubChannel(channelId: string, vmIdFragment: string): Promise<SubRAV | null> {\n    let latestSubRAV: SubRAV | null = null;\n    let maxNonce = BigInt(-1);\n\n    for (const [key, entry] of this.proposals) {\n      if (key.startsWith(`${channelId}:${vmIdFragment}:`)) {\n        const subRAV = entry.subRAV;\n        if (subRAV.nonce > maxNonce) {\n          maxNonce = subRAV.nonce;\n          latestSubRAV = subRAV;\n        }\n      }\n    }\n\n    return latestSubRAV ? { ...latestSubRAV } : null; // Return copy to avoid mutations\n  }\n\n  async remove(channelId: string, vmIdFragment: string, nonce: bigint): Promise<void> {\n    const key = this.getKey(channelId, vmIdFragment, nonce);\n    this.proposals.delete(key);\n  }\n\n  async cleanup(maxAgeMs: number = 30 * 60 * 1000): Promise<number> {\n    const now = Date.now();\n    const cutoff = now - maxAgeMs;\n    let cleanedCount = 0;\n\n    for (const [key, entry] of this.proposals.entries()) {\n      if (entry.timestamp < cutoff) {\n        this.proposals.delete(key);\n        cleanedCount++;\n      }\n    }\n\n    return cleanedCount;\n  }\n\n  async getStats(): Promise<PendingSubRAVStats> {\n    const byChannel: Record<string, number> = {};\n    let oldestTimestamp: number | undefined;\n    let newestTimestamp: number | undefined;\n\n    for (const [key, entry] of this.proposals.entries()) {\n      const channelId = key.split(':')[0];\n      byChannel[channelId] = (byChannel[channelId] || 0) + 1;\n\n      if (oldestTimestamp === undefined || entry.timestamp < oldestTimestamp) {\n        oldestTimestamp = entry.timestamp;\n      }\n      if (newestTimestamp === undefined || entry.timestamp > newestTimestamp) {\n        newestTimestamp = entry.timestamp;\n      }\n    }\n\n    return {\n      totalCount: this.proposals.size,\n      byChannel,\n      oldestTimestamp,\n      newestTimestamp,\n    };\n  }\n\n  async clear(): Promise<void> {\n    this.proposals.clear();\n  }\n}\n","/**\n * Browser IndexedDB-based PendingSubRAVRepository implementation\n */\n\nimport type { SubRAV } from '../../core/types';\nimport type { PendingSubRAVRepository } from '../interfaces/PendingSubRAVRepository';\nimport type { PendingSubRAVStats } from '../types/pagination';\n\nexport class IndexedDBPendingSubRAVRepository implements PendingSubRAVRepository {\n  private dbName = 'nuwa-payment-kit-pending-subravs';\n  private version = 2;\n\n  private async getDB(): Promise<IDBDatabase> {\n    return new Promise((resolve, reject) => {\n      const request = indexedDB.open(this.dbName, this.version);\n\n      request.onerror = () => reject(request.error);\n      request.onsuccess = () => resolve(request.result);\n\n      request.onupgradeneeded = event => {\n        const db = (event.target as IDBOpenDBRequest).result;\n        const oldVersion = (event as any).oldVersion as number | undefined;\n\n        // If upgrading from v1 (or creating fresh), ensure store has new keyPath including vmIdFragment\n        if (db.objectStoreNames.contains('pendingSubRAVs')) {\n          // For old schemas, drop and recreate with the new composite key\n          try {\n            db.deleteObjectStore('pendingSubRAVs');\n          } catch (_) {\n            // ignore if delete fails\n          }\n        }\n\n        const store = db.createObjectStore('pendingSubRAVs', {\n          keyPath: ['channelId', 'vmIdFragment', 'nonce'],\n        });\n        store.createIndex('channelId', 'channelId', { unique: false });\n        store.createIndex('subChannel', ['channelId', 'vmIdFragment'], { unique: false });\n        store.createIndex('timestamp', 'timestamp', { unique: false });\n      };\n    });\n  }\n\n  async save(subRAV: SubRAV): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['pendingSubRAVs'], 'readwrite');\n    const store = tx.objectStore('pendingSubRAVs');\n\n    const record = {\n      channelId: subRAV.channelId,\n      vmIdFragment: subRAV.vmIdFragment,\n      nonce: subRAV.nonce.toString(),\n      subRAVData: {\n        ...subRAV,\n        nonce: subRAV.nonce.toString(),\n        accumulatedAmount: subRAV.accumulatedAmount.toString(),\n      },\n      timestamp: Date.now(),\n    };\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.put(record);\n      request.onsuccess = () => resolve();\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  async find(channelId: string, vmIdFragment: string, nonce: bigint): Promise<SubRAV | null> {\n    const db = await this.getDB();\n    const tx = db.transaction(['pendingSubRAVs'], 'readonly');\n    const store = tx.objectStore('pendingSubRAVs');\n\n    const record = await new Promise<any>((resolve, reject) => {\n      const request = store.get([channelId, vmIdFragment, nonce.toString()]);\n      request.onsuccess = () => resolve(request.result);\n      request.onerror = () => reject(request.error);\n    });\n\n    if (!record) {\n      return null;\n    }\n\n    // Convert back to SubRAV with proper bigint types\n    return {\n      ...record.subRAVData,\n      nonce: BigInt(record.subRAVData.nonce),\n      accumulatedAmount: BigInt(record.subRAVData.accumulatedAmount),\n    };\n  }\n\n  async findLatestBySubChannel(channelId: string, vmIdFragment: string): Promise<SubRAV | null> {\n    const db = await this.getDB();\n    const tx = db.transaction(['pendingSubRAVs'], 'readonly');\n    const store = tx.objectStore('pendingSubRAVs');\n    const subChannelIndex = store.index('subChannel');\n\n    let latestSubRAV: SubRAV | null = null;\n    let maxNonce = BigInt(-1);\n\n    // Use cursor to iterate through all records for this channel\n    const cursorRequest = subChannelIndex.openCursor(IDBKeyRange.only([channelId, vmIdFragment]));\n\n    await new Promise<void>((resolve, reject) => {\n      cursorRequest.onsuccess = () => {\n        const cursor = cursorRequest.result;\n        if (cursor) {\n          const record = cursor.value;\n          const subRAV = {\n            ...record.subRAVData,\n            nonce: BigInt(record.subRAVData.nonce),\n            accumulatedAmount: BigInt(record.subRAVData.accumulatedAmount),\n          };\n\n          if (subRAV.nonce > maxNonce) {\n            maxNonce = subRAV.nonce;\n            latestSubRAV = subRAV;\n          }\n\n          cursor.continue();\n        } else {\n          resolve();\n        }\n      };\n      cursorRequest.onerror = () =>\n        reject(\n          new Error(\n            `Failed to iterate through pending SubRAVs for channel '${channelId}': ${cursorRequest.error?.message || 'Unknown error'}`\n          )\n        );\n    });\n\n    return latestSubRAV;\n  }\n\n  async remove(channelId: string, vmIdFragment: string, nonce: bigint): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['pendingSubRAVs'], 'readwrite');\n    const store = tx.objectStore('pendingSubRAVs');\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.delete([channelId, vmIdFragment, nonce.toString()]);\n      request.onsuccess = () => resolve();\n      request.onerror = () => reject(request.error);\n    });\n  }\n\n  async cleanup(maxAgeMs: number = 30 * 60 * 1000): Promise<number> {\n    const db = await this.getDB();\n    const tx = db.transaction(['pendingSubRAVs'], 'readwrite');\n    const store = tx.objectStore('pendingSubRAVs');\n    const index = store.index('timestamp');\n\n    const cutoff = Date.now() - maxAgeMs;\n    let cleanedCount = 0;\n\n    await new Promise<void>((resolve, reject) => {\n      const request = index.openCursor(IDBKeyRange.upperBound(cutoff));\n\n      request.onsuccess = () => {\n        const cursor = request.result;\n        if (cursor) {\n          cursor.delete();\n          cleanedCount++;\n          cursor.continue();\n        } else {\n          resolve();\n        }\n      };\n\n      request.onerror = () => reject(request.error);\n    });\n\n    return cleanedCount;\n  }\n\n  async getStats(): Promise<PendingSubRAVStats> {\n    const db = await this.getDB();\n    const tx = db.transaction(['pendingSubRAVs'], 'readonly');\n    const store = tx.objectStore('pendingSubRAVs');\n\n    const byChannel: Record<string, number> = {};\n    let oldestTimestamp: number | undefined;\n    let newestTimestamp: number | undefined;\n    let totalCount = 0;\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.openCursor();\n\n      request.onsuccess = () => {\n        const cursor = request.result;\n        if (cursor) {\n          const record = cursor.value;\n          totalCount++;\n\n          byChannel[record.channelId] = (byChannel[record.channelId] || 0) + 1;\n\n          if (oldestTimestamp === undefined || record.timestamp < oldestTimestamp) {\n            oldestTimestamp = record.timestamp;\n          }\n          if (newestTimestamp === undefined || record.timestamp > newestTimestamp) {\n            newestTimestamp = record.timestamp;\n          }\n\n          cursor.continue();\n        } else {\n          resolve();\n        }\n      };\n\n      request.onerror = () => reject(request.error);\n    });\n\n    return {\n      totalCount,\n      byChannel,\n      oldestTimestamp,\n      newestTimestamp,\n    };\n  }\n\n  async clear(): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['pendingSubRAVs'], 'readwrite');\n    const store = tx.objectStore('pendingSubRAVs');\n\n    await new Promise<void>((resolve, reject) => {\n      const request = store.clear();\n      request.onsuccess = () => resolve();\n      request.onerror = () => reject(request.error);\n    });\n  }\n}\n","/**\n * Factory function for creating PendingSubRAVRepository instances\n */\n\nimport type { Pool } from 'pg';\nimport type { PendingSubRAVRepository } from '../interfaces/PendingSubRAVRepository';\nimport { MemoryPendingSubRAVRepository } from '../memory/pendingSubRav.memory';\nimport { IndexedDBPendingSubRAVRepository } from '../indexeddb/pendingSubRav.indexeddb';\nimport {\n  SqlPendingSubRAVRepository,\n  type SqlPendingSubRAVRepositoryOptions,\n} from '../sql/pendingSubRav.sql';\n\nexport interface PendingSubRAVRepositoryOptions {\n  /** Backend type to use */\n  backend?: 'memory' | 'indexeddb' | 'sql';\n  /** Database connection string for SQL backends */\n  connectionString?: string;\n  /** PostgreSQL connection pool (alternative to connectionString) */\n  pool?: Pool;\n  /** Table name prefix for SQL backends */\n  tablePrefix?: string;\n  /** Auto-create tables if they don't exist */\n  autoMigrate?: boolean;\n  /** Allow unsafe auto-migration in production */\n  allowUnsafeAutoMigrateInProd?: boolean;\n}\n\n/**\n * Create a PendingSubRAVRepository instance based on the specified backend\n */\nexport function createPendingSubRAVRepo(\n  options: PendingSubRAVRepositoryOptions = {}\n): PendingSubRAVRepository {\n  const { backend = 'memory' } = options;\n\n  switch (backend) {\n    case 'memory':\n      return new MemoryPendingSubRAVRepository();\n\n    case 'indexeddb':\n      if (typeof window === 'undefined' || !window.indexedDB) {\n        throw new Error('IndexedDB is not available in this environment');\n      }\n      return new IndexedDBPendingSubRAVRepository();\n\n    case 'sql':\n      // Do not create pool here; caller must provide a Pool (Node-only)\n      if (!options.pool) {\n        throw new Error('SQL backend requires a PostgreSQL connection pool');\n      }\n\n      const sqlOptions: SqlPendingSubRAVRepositoryOptions = {\n        pool: options.pool,\n        tablePrefix: options.tablePrefix,\n        autoMigrate: options.autoMigrate,\n        allowUnsafeAutoMigrateInProd: options.allowUnsafeAutoMigrateInProd,\n      };\n\n      return new SqlPendingSubRAVRepository(sqlOptions);\n\n    default:\n      throw new Error(`Unknown backend type: ${backend}`);\n  }\n}\n","import type {\n  TransactionRecord,\n  TransactionStore,\n  TransactionStatus,\n} from '../interfaces/TransactionStore';\n\nexport class MemoryTransactionStore implements TransactionStore {\n  private records = new Map<string, TransactionRecord>();\n  private order: string[] = [];\n  private listeners = new Set<\n    (e: { type: 'created' | 'updated'; record: TransactionRecord }) => void\n  >();\n\n  constructor(private readonly maxRecords: number = 500) {}\n\n  async create(record: TransactionRecord): Promise<void> {\n    this.records.set(record.clientTxRef, record);\n    this.order.push(record.clientTxRef);\n    this.trim();\n    this.emit({ type: 'created', record });\n  }\n\n  async update(clientTxRef: string, updates: Partial<TransactionRecord>): Promise<void> {\n    const existing = this.records.get(clientTxRef);\n    if (!existing) return;\n    const updated = { ...existing, ...updates } as TransactionRecord;\n    this.records.set(clientTxRef, updated);\n    this.emit({ type: 'updated', record: updated });\n  }\n\n  async get(clientTxRef: string): Promise<TransactionRecord | null> {\n    return this.records.get(clientTxRef) || null;\n  }\n\n  async list(\n    filter?: {\n      status?: TransactionStatus;\n      channelId?: string;\n      protocol?: 'http' | 'mcp' | 'other';\n      since?: number;\n      until?: number;\n    },\n    pagination?: { offset?: number; limit?: number }\n  ): Promise<{ items: TransactionRecord[]; total: number; hasMore: boolean }> {\n    const offset = pagination?.offset ?? 0;\n    const limit = pagination?.limit ?? 50;\n    const items: TransactionRecord[] = [];\n    for (let i = this.order.length - 1; i >= 0; i--) {\n      const id = this.order[i];\n      const rec = this.records.get(id);\n      if (!rec) continue;\n      if (filter?.status && rec.status !== filter.status) continue;\n      if (filter?.channelId && rec.channelId !== filter.channelId) continue;\n      if (filter?.protocol && rec.protocol !== filter.protocol) continue;\n      if (typeof filter?.since === 'number' && rec.timestamp < filter.since) continue;\n      if (typeof filter?.until === 'number' && rec.timestamp > filter.until) continue;\n      items.push(rec);\n      if (items.length >= offset + limit) break;\n    }\n    const window = items.slice(offset, offset + limit);\n    const total = items.length;\n    const hasMore = total > offset + window.length;\n    return { items: window, total, hasMore };\n  }\n\n  async clear(): Promise<void> {\n    this.records.clear();\n    this.order = [];\n  }\n\n  subscribe(\n    cb: (e: { type: 'created' | 'updated'; record: TransactionRecord }) => void\n  ): () => void {\n    this.listeners.add(cb);\n    return () => this.listeners.delete(cb);\n  }\n\n  private trim(): void {\n    while (this.order.length > this.maxRecords) {\n      const oldest = this.order.shift();\n      if (oldest) this.records.delete(oldest);\n    }\n  }\n\n  private emit(e: { type: 'created' | 'updated'; record: TransactionRecord }): void {\n    for (const l of this.listeners) {\n      try {\n        l(e);\n      } catch {}\n    }\n  }\n}\n","import type {\n  TransactionRecord,\n  TransactionStatus,\n  TransactionStore,\n} from '../interfaces/TransactionStore';\n\n/**\n * IndexedDB-based TransactionStore\n */\nexport class IndexedDBTransactionStore implements TransactionStore {\n  private dbName = 'nuwa-payment-kit-transactions';\n  private version = 1;\n\n  private async getDB(): Promise<IDBDatabase> {\n    return new Promise((resolve, reject) => {\n      const request = indexedDB.open(this.dbName, this.version);\n\n      request.onerror = () => reject(request.error);\n      request.onsuccess = () => resolve(request.result);\n\n      request.onupgradeneeded = event => {\n        const db = (event.target as IDBOpenDBRequest).result;\n        if (!db.objectStoreNames.contains('transactions')) {\n          const store = db.createObjectStore('transactions', { keyPath: 'clientTxRef' });\n          store.createIndex('timestamp', 'timestamp', { unique: false });\n          store.createIndex('channelId', 'channelId', { unique: false });\n          store.createIndex('status', 'status', { unique: false });\n          store.createIndex('protocol', 'protocol', { unique: false });\n          store.createIndex('vmIdFragment', 'vmIdFragment', { unique: false });\n        }\n      };\n    });\n  }\n\n  async create(record: TransactionRecord): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['transactions'], 'readwrite');\n    const store = tx.objectStore('transactions');\n    await new Promise<void>((resolve, reject) => {\n      const req = store.put(this.serialize(record));\n      req.onsuccess = () => resolve();\n      req.onerror = () => reject(req.error);\n    });\n  }\n\n  async update(clientTxRef: string, updates: Partial<TransactionRecord>): Promise<void> {\n    const existing = await this.get(clientTxRef);\n    if (!existing) return;\n    const updated: TransactionRecord = { ...existing, ...updates } as TransactionRecord;\n    await this.create(updated);\n  }\n\n  async get(clientTxRef: string): Promise<TransactionRecord | null> {\n    const db = await this.getDB();\n    const tx = db.transaction(['transactions'], 'readonly');\n    const store = tx.objectStore('transactions');\n    return new Promise((resolve, reject) => {\n      const req = store.get(clientTxRef);\n      req.onsuccess = () => resolve(req.result ? this.deserialize(req.result) : null);\n      req.onerror = () => reject(req.error);\n    });\n  }\n\n  async list(\n    filter?: {\n      status?: TransactionStatus;\n      channelId?: string;\n      protocol?: 'http' | 'mcp' | 'other';\n      since?: number;\n      until?: number;\n    },\n    pagination?: { offset?: number; limit?: number }\n  ): Promise<{ items: TransactionRecord[]; total: number; hasMore: boolean }> {\n    const db = await this.getDB();\n    const tx = db.transaction(['transactions'], 'readonly');\n    const store = tx.objectStore('transactions');\n    const index = store.index('timestamp');\n\n    const items: TransactionRecord[] = [];\n    await new Promise<void>((resolve, reject) => {\n      const range = undefined; // full scan by time, we will filter in code\n      const req = index.openCursor(range, 'prev'); // newest first\n      req.onsuccess = () => {\n        const cursor = req.result as IDBCursorWithValue | null;\n        if (!cursor) return resolve();\n        const rec = this.deserialize(cursor.value);\n        if (filter?.status && rec.status !== filter.status) return cursor.continue();\n        if (filter?.channelId && rec.channelId !== filter.channelId) return cursor.continue();\n        if (filter?.protocol && rec.protocol !== filter.protocol) return cursor.continue();\n        if (typeof filter?.since === 'number' && rec.timestamp < filter.since)\n          return cursor.continue();\n        if (typeof filter?.until === 'number' && rec.timestamp > filter.until)\n          return cursor.continue();\n        items.push(rec);\n        cursor.continue();\n      };\n      req.onerror = () => reject(req.error);\n    });\n\n    const offset = pagination?.offset ?? 0;\n    const limit = pagination?.limit ?? 50;\n    const window = items.slice(offset, offset + limit);\n    const total = items.length;\n    const hasMore = total > offset + window.length;\n    return { items: window, total, hasMore };\n  }\n\n  async clear(): Promise<void> {\n    const db = await this.getDB();\n    const tx = db.transaction(['transactions'], 'readwrite');\n    const store = tx.objectStore('transactions');\n    await new Promise<void>((resolve, reject) => {\n      const req = store.clear();\n      req.onsuccess = () => resolve();\n      req.onerror = () => reject(req.error);\n    });\n  }\n\n  subscribe(): () => void {\n    // no-op; IndexedDB doesn't have native notifications; implement in caller if needed\n    return () => {};\n  }\n\n  private serialize(rec: TransactionRecord): any {\n    // Convert bigint fields inside payment snapshot to strings\n    const copy: any = { ...rec };\n    if (copy.payment) {\n      copy.payment = {\n        ...copy.payment,\n        cost: copy.payment.cost.toString(),\n        costUsd: copy.payment.costUsd.toString(),\n        nonce: copy.payment.nonce.toString(),\n      };\n    }\n    return copy;\n  }\n\n  private deserialize(obj: any): TransactionRecord {\n    const copy: any = { ...obj };\n    if (copy.payment) {\n      copy.payment = {\n        ...copy.payment,\n        cost: BigInt(copy.payment.cost),\n        costUsd: BigInt(copy.payment.costUsd),\n        nonce: BigInt(copy.payment.nonce),\n      };\n    }\n    return copy as TransactionRecord;\n  }\n}\n","import type { TransactionStore } from '../interfaces/TransactionStore';\nimport { MemoryTransactionStore } from '../memory/transaction.memory';\nimport { IndexedDBTransactionStore } from '../indexeddb/transactions.indexeddb';\n\nexport interface TransactionStoreOptions {\n  backend?: 'memory' | 'indexeddb';\n  maxRecords?: number; // memory only\n}\n\nexport function createTransactionStore(options: TransactionStoreOptions = {}): TransactionStore {\n  const backend = options.backend ?? 'memory';\n  switch (backend) {\n    case 'indexeddb':\n      return new IndexedDBTransactionStore();\n    case 'memory':\n    default:\n      return new MemoryTransactionStore(options.maxRecords);\n  }\n}\n","/**\n * Payment Kit Storage Layer\n *\n * Unified storage abstractions for channels, RAVs, and pending SubRAVs\n * with support for multiple backends (memory, IndexedDB, SQL)\n */\n\n// ==================== Type Exports ====================\nexport type {\n  PaginationParams,\n  PaginatedResult,\n  ChannelFilter,\n  CacheStats,\n  PendingSubRAVStats,\n} from './types/pagination';\n\n// ==================== Interface Exports ====================\nexport type { ChannelRepository } from './interfaces/ChannelRepository';\nexport type { RAVRepository } from './interfaces/RAVRepository';\nexport type { PendingSubRAVRepository } from './interfaces/PendingSubRAVRepository';\n\n// ==================== Factory Function Exports ====================\nexport { createChannelRepo, type ChannelRepositoryOptions } from './factories/createChannelRepo';\n\nexport { createRAVRepo, type RAVRepositoryOptions } from './factories/createRAVRepo';\n\nexport {\n  createPendingSubRAVRepo,\n  type PendingSubRAVRepositoryOptions,\n} from './factories/createPendingSubRAVRepo';\n\n// ==================== Implementation Exports (Optional) ====================\n// Export implementations for advanced use cases or testing\n\n// Memory implementations\nexport { MemoryChannelRepository } from './memory/channel.memory';\nexport { MemoryRAVRepository } from './memory/rav.memory';\nexport { MemoryPendingSubRAVRepository } from './memory/pendingSubRav.memory';\n\n// IndexedDB implementations\nexport { IndexedDBChannelRepository } from './indexeddb/channel.indexeddb';\nexport { IndexedDBRAVRepository } from './indexeddb/rav.indexeddb';\nexport { IndexedDBPendingSubRAVRepository } from './indexeddb/pendingSubRav.indexeddb';\n\n// SQL implementations\nexport { SqlChannelRepository, type SqlChannelRepositoryOptions } from './sql/channel.sql';\nexport { SqlRAVRepository, type SqlRAVRepositoryOptions } from './sql/rav.sql';\nexport {\n  SqlPendingSubRAVRepository,\n  type SqlPendingSubRAVRepositoryOptions,\n} from './sql/pendingSubRav.sql';\n\n// SQL serialization utilities\nexport { encodeSubRAV, decodeSubRAV, getSubRAVHex } from './sql/serialization';\n\n// ==================== Transaction Store Exports ====================\nexport type {\n  TransactionStore,\n  TransactionRecord,\n  TransactionStatus,\n  PaymentSnapshot,\n} from './interfaces/TransactionStore';\nexport { MemoryTransactionStore } from './memory/transaction.memory';\nexport { IndexedDBTransactionStore } from './indexeddb/transactions.indexeddb';\nexport {\n  createTransactionStore,\n  type TransactionStoreOptions,\n} from './factories/createTransactionStore';\n\n// ==================== Convenience Functions ====================\n\nimport { createChannelRepo as _createChannelRepo } from './factories/createChannelRepo';\nimport { createRAVRepo as _createRAVRepo } from './factories/createRAVRepo';\nimport { createPendingSubRAVRepo as _createPendingSubRAVRepo } from './factories/createPendingSubRAVRepo';\n\n/**\n * Create all repositories with the same backend configuration\n */\nexport function createStorageRepositories(options: {\n  backend?: 'memory' | 'indexeddb' | 'sql';\n  pool?: any; // Pool from 'pg'\n  connectionString?: string; // e.g., SUPABASE_DB_URL\n  tablePrefix?: string;\n  autoMigrate?: boolean;\n}) {\n  const opts: any = { ...options };\n  // Note: keep this module browser-safe; do not load 'pg' here.\n  return {\n    channelRepo: _createChannelRepo(opts),\n    ravRepo: _createRAVRepo(opts),\n    pendingSubRAVRepo: _createPendingSubRAVRepo(opts),\n  };\n}\n","import type { HostChannelMappingStore, PersistedHttpClientState } from '../types';\nimport { PersistedHttpClientStateSchema } from '../../../schema/core';\nimport { serializeJson, parseJson } from '../../../utils/json';\nimport {\n  ChannelRepository,\n  IndexedDBChannelRepository,\n  MemoryChannelRepository,\n  MemoryTransactionStore,\n  TransactionStore,\n  IndexedDBTransactionStore,\n} from '../../../storage';\n\n/**\n * Memory-based implementation of HostChannelMappingStore\n * Suitable for short-lived processes or testing\n */\nexport class MemoryHostChannelMappingStore implements HostChannelMappingStore {\n  private stateStore = new Map<string, PersistedHttpClientState>();\n\n  // New methods for full state management\n  async getState(host: string): Promise<PersistedHttpClientState | undefined> {\n    return this.stateStore.get(host);\n  }\n\n  async setState(host: string, state: PersistedHttpClientState): Promise<void> {\n    // Validate with Zod schema to ensure data integrity\n    const validatedState = PersistedHttpClientStateSchema.parse(state);\n\n    this.stateStore.set(host, validatedState);\n  }\n\n  async deleteState(host: string): Promise<void> {\n    this.stateStore.delete(host);\n  }\n\n  /**\n   * Clear all stored mappings and states\n   */\n  clear(): void {\n    this.stateStore.clear();\n  }\n}\n\n/**\n * LocalStorage-based implementation for browsers\n * Provides persistence across browser sessions\n */\nexport class LocalStorageHostChannelMappingStore implements HostChannelMappingStore {\n  private static readonly STATE_PREFIX = 'nuwa-payment-client-state:';\n\n  // New methods for full state management\n  async getState(host: string): Promise<PersistedHttpClientState | undefined> {\n    if (typeof localStorage === 'undefined') {\n      throw new Error('localStorage is not available');\n    }\n\n    const key = LocalStorageHostChannelMappingStore.STATE_PREFIX + host;\n    const value = localStorage.getItem(key);\n\n    if (!value) {\n      return undefined;\n    }\n\n    try {\n      // Parse JSON with lossless-json first\n      const parsedData = parseJson(value);\n      // Then validate and transform with Zod (handles BigInt conversion)\n      return PersistedHttpClientStateSchema.parse(parsedData);\n    } catch (error) {\n      return undefined;\n    }\n  }\n\n  async setState(host: string, state: PersistedHttpClientState): Promise<void> {\n    if (typeof localStorage === 'undefined') {\n      throw new Error('localStorage is not available');\n    }\n\n    const stateKey = LocalStorageHostChannelMappingStore.STATE_PREFIX + host;\n    const stateWithTimestamp = {\n      ...state,\n      lastUpdated: new Date().toISOString(),\n    };\n\n    // Validate and transform with Zod (ensures proper structure)\n    const validatedState = PersistedHttpClientStateSchema.parse(stateWithTimestamp);\n\n    // Use lossless-json for proper BigInt serialization\n    const serializedState = serializeJson(validatedState);\n\n    localStorage.setItem(stateKey, serializedState);\n\n    // channelId is part of state; no separate legacy mapping kept\n  }\n\n  async deleteState(host: string): Promise<void> {\n    if (typeof localStorage === 'undefined') {\n      throw new Error('localStorage is not available');\n    }\n\n    const stateKey = LocalStorageHostChannelMappingStore.STATE_PREFIX + host;\n    localStorage.removeItem(stateKey);\n  }\n\n  /**\n   * Clear all stored mappings and states\n   */\n  async clear(): Promise<void> {\n    if (typeof localStorage === 'undefined') {\n      throw new Error('localStorage is not available');\n    }\n\n    const keysToRemove: string[] = [];\n    for (let i = 0; i < localStorage.length; i++) {\n      const key = localStorage.key(i);\n      if (key && key.startsWith(LocalStorageHostChannelMappingStore.STATE_PREFIX)) {\n        keysToRemove.push(key);\n      }\n    }\n\n    keysToRemove.forEach(key => localStorage.removeItem(key));\n  }\n}\n\n/**\n * Auto-detect environment and create appropriate mapping store\n */\nexport function createDefaultMappingStore(): HostChannelMappingStore {\n  // Check if we're in a browser environment with localStorage\n  if (typeof window !== 'undefined' && typeof localStorage !== 'undefined') {\n    return new LocalStorageHostChannelMappingStore();\n  }\n\n  // Fall back to memory store for Node.js or environments without localStorage\n  return new MemoryHostChannelMappingStore();\n}\n\nexport function createDefaultChannelRepo(): ChannelRepository {\n  if (typeof window !== 'undefined' && typeof indexedDB !== 'undefined') {\n    return new IndexedDBChannelRepository();\n  }\n  return new MemoryChannelRepository();\n}\n\nexport function createDefaultTransactionStore(): TransactionStore {\n  if (typeof window !== 'undefined' && typeof indexedDB !== 'undefined') {\n    return new IndexedDBTransactionStore();\n  }\n  return new MemoryTransactionStore();\n}\n\n/**\n * Extract host from URL string\n */\nexport function extractHost(url: string): string {\n  try {\n    const urlObj = new URL(url);\n    return urlObj.host; // includes port if present\n  } catch (error) {\n    throw new Error(`Invalid URL: ${url}`);\n  }\n}\n\n// ==================== Namespaced Host Mapping Store ====================\n\nexport interface NamespaceProviders {\n  /** Resolve payer DID (async) */\n  getPayerDid: () => Promise<string>;\n}\n\n/**\n * A wrapper around HostChannelMappingStore adding DID/network namespacing to keys.\n * Composite key format: `${host}::${payerDid}`\n */\nexport class NamespacedHostChannelMappingStore implements HostChannelMappingStore {\n  constructor(\n    private readonly base: HostChannelMappingStore,\n    private readonly providers: NamespaceProviders\n  ) {}\n\n  private async buildKey(host: string): Promise<string> {\n    const payerDid = await this.providers.getPayerDid();\n    const ns = [host, payerDid].join('::');\n    return ns;\n  }\n\n  async getState(host: string): Promise<PersistedHttpClientState | undefined> {\n    const key = await this.buildKey(host);\n    return this.base.getState(key);\n  }\n\n  async setState(host: string, state: PersistedHttpClientState): Promise<void> {\n    const key = await this.buildKey(host);\n    return this.base.setState(key, state);\n  }\n\n  async deleteState(host: string): Promise<void> {\n    const key = await this.buildKey(host);\n    return this.base.deleteState(key);\n  }\n}\n\nexport function createNamespacedMappingStore(\n  base: HostChannelMappingStore,\n  providers: NamespaceProviders\n): HostChannelMappingStore {\n  return new NamespacedHostChannelMappingStore(base, providers);\n}\n","import { z } from 'zod';\nimport { SubRAVSchema, ChannelInfoSchema, SubChannelStateSchema } from '../core';\n\n/**\n * Schema for GET /recovery response\n * Uses core schemas for proper type safety and validation\n */\nexport const RecoveryResponseSchema = z.object({\n  /** Channel information if channel exists */\n  channel: ChannelInfoSchema.nullable(),\n  /** Pending SubRAV if any exists for recovery */\n  pendingSubRav: SubRAVSchema.nullable(),\n  /** Optional sub-channel state for current key fragment (if authorized) */\n  subChannel: SubChannelStateSchema.nullable().optional(),\n  /** Response timestamp in ISO-8601 format */\n  timestamp: z.string(),\n});\n\nexport type RecoveryResponse = z.infer<typeof RecoveryResponseSchema>;\n\n/**\n * The recovery endpoint currently does not accept any request body.\n * We still declare an empty schema so that the helper utilities work\n * consistently across every endpoint.\n */\nexport const RecoveryRequestSchema = z.object({}).passthrough();\n\nexport type RecoveryRequest = z.infer<typeof RecoveryRequestSchema>;\n","import { z } from 'zod';\nimport { SignedSubRAVSchema } from '../core';\n\n/**\n * Schema for POST /commit request\n */\nexport const CommitRequestSchema = z.object({\n  /** Signed SubRAV to be committed */\n  subRav: SignedSubRAVSchema,\n});\n\nexport type CommitRequest = z.infer<typeof CommitRequestSchema>;\n\n/**\n * Schema for POST /commit response\n */\nexport const CommitResponseSchema = z.object({\n  success: z.boolean(),\n});\n\nexport type CommitResponse = z.infer<typeof CommitResponseSchema>;\n","import { z } from 'zod';\nimport { ServiceDiscoverySchema } from '../core';\n\n/**\n * Schema for GET /.well-known/payment-service response (Discovery)\n * Uses the core ServiceDiscoverySchema for consistency\n */\nexport const DiscoveryResponseSchema = ServiceDiscoverySchema;\n\nexport type DiscoveryResponse = z.infer<typeof DiscoveryResponseSchema>;\n\n/**\n * Discovery endpoint doesn't accept request parameters\n */\nexport const DiscoveryRequestSchema = z.object({}).passthrough();\n\nexport type DiscoveryRequest = z.infer<typeof DiscoveryRequestSchema>;\n","import { z } from 'zod';\nimport { HealthCheckSchema } from '../core';\n\n/**\n * Schema for GET /health response\n * Uses the core HealthCheckSchema for consistency\n */\nexport const HealthResponseSchema = HealthCheckSchema;\n\nexport type HealthResponse = z.infer<typeof HealthResponseSchema>;\n\n/**\n * Health endpoint doesn't accept request parameters\n */\nexport const HealthRequestSchema = z.object({}).passthrough();\n\nexport type HealthRequest = z.infer<typeof HealthRequestSchema>;\n","import { z } from 'zod';\nimport { SignedSubRAVSchema } from '../core';\n\n/**\n * Schema for GET /subrav request (query parameters)\n */\nexport const SubRavRequestSchema = z.object({\n  /** Nonce as string (from query params), will be converted to BigInt in handler */\n  nonce: z.string(),\n});\n\nexport type SubRavRequest = z.infer<typeof SubRavRequestSchema>;\n\n/**\n * Schema for GET /subrav response - returns a SignedSubRAV if found\n * Uses the core SignedSubRAVSchema for consistency\n */\nexport const SubRavResponseSchema = SignedSubRAVSchema;\n\nexport type SubRavResponse = z.infer<typeof SubRavResponseSchema>;\n","import { z } from 'zod';\nimport {\n  SystemStatusSchema,\n  ClaimTriggerRequestSchema as CoreClaimTriggerRequestSchema,\n  ClaimTriggerResponseSchema as CoreClaimTriggerResponseSchema,\n} from '../core';\n\n/**\n * Schema for GET /admin/status response\n */\nexport const SystemStatusResponseSchema = SystemStatusSchema;\n\nexport type SystemStatusResponse = z.infer<typeof SystemStatusResponseSchema>;\n\n/**\n * Schema for POST /admin/claim-trigger request\n * Uses the core ClaimTriggerRequestSchema for consistency\n */\nexport const ClaimTriggerRequestSchema = CoreClaimTriggerRequestSchema;\n\nexport type ClaimTriggerRequest = z.infer<typeof ClaimTriggerRequestSchema>;\n\n/**\n * Schema for POST /admin/claim-trigger response\n * Uses the core ClaimTriggerResponseSchema for consistency\n */\nexport const ClaimTriggerResponseSchema = CoreClaimTriggerResponseSchema;\n\nexport type ClaimTriggerResponse = z.infer<typeof ClaimTriggerResponseSchema>;\n\n/**\n * Admin endpoints that don't accept request parameters use passthrough empty objects\n */\nexport const AdminRequestSchema = z.object({}).passthrough();\n\nexport type AdminRequest = z.infer<typeof AdminRequestSchema>;\n","import type {\n  HttpPayerOptions,\n  FetchLike,\n  PaymentRequestContext,\n  PaymentRequestHandle,\n} from './types';\nimport type {\n  SubRAV,\n  SignedSubRAV,\n  PaymentInfo,\n  PaymentResult,\n  SubChannelInfo,\n} from '../../core/types';\nimport type { ApiResponse } from '../../types/api';\nimport type {\n  DiscoveryResponse,\n  HealthResponse,\n  RecoveryResponse,\n  CommitResponse,\n} from '../../schema';\nimport { ErrorCode } from '../../types/api';\nimport { PaymentKitError } from '../../errors';\nimport { PaymentChannelPayerClient } from '../../client/PaymentChannelPayerClient';\nimport { assertSubRavProgression } from '../../core/SubRavValidator';\nimport { PaymentChannelFactory } from '../../factory/chainFactory';\nimport { DidAuthHelper } from './internal/DidAuthHelper';\nimport {\n  createDefaultMappingStore,\n  extractHost,\n  createDefaultChannelRepo,\n  createDefaultTransactionStore,\n  createNamespacedMappingStore,\n} from './internal/LocalStore';\nimport { parseJsonResponse, serializeJson } from '../../utils/json';\nimport { RecoveryResponseSchema, HealthResponseSchema } from '../../schema';\nimport type { z } from 'zod';\nimport { PaymentHubClient } from '../../client/PaymentHubClient';\nimport { DebugLogger } from '@nuwa-ai/identity-kit';\nimport { TransactionStore, type ChannelRepository } from '../../storage';\nimport { PaymentErrorCode } from '../../errors/codes';\nimport { wrapAndFilterInBandFrames } from './internal/StreamPaymentFilter';\nimport { isStreamLikeResponse } from './internal/utils';\nimport { RateProvider } from '../../billing/rate/types';\nimport { ContractRateProvider } from '../../billing/rate/contract';\nimport { RequestScheduler } from './internal/RequestScheduler';\n\n// Import new core modules\nimport { PaymentState } from './core/PaymentState';\nimport { PaymentProtocol } from './core/PaymentProtocol';\nimport { RequestManager } from './core/RequestManager';\nimport { ChannelManager } from './core/ChannelManager';\n\n/**\n * PaymentChannelHttpClient provides a high-level HTTP interface\n * for making requests with integrated payment channel functionality.\n *\n * This refactored version uses modular architecture while maintaining\n * backward compatibility with the original API.\n */\nexport class PaymentChannelHttpClient {\n  private payerClient: PaymentChannelPayerClient;\n  private options: HttpPayerOptions;\n  private fetchImpl: FetchLike;\n  private host: string;\n  private logger: DebugLogger;\n  private requestTimeoutMs: number;\n  private rateProvider: RateProvider;\n  private scheduler: RequestScheduler = new RequestScheduler();\n  private isCleanedUp = false;\n  private transactionStore: TransactionStore;\n  private channelRepo: ChannelRepository;\n  private protocolErrorByResponse: WeakMap<Response, PaymentKitError> = new WeakMap();\n\n  // New modular components\n  private paymentState: PaymentState;\n  private paymentProtocol: PaymentProtocol;\n  private requestManager: RequestManager;\n  private channelManager: ChannelManager;\n\n  constructor(options: HttpPayerOptions) {\n    this.options = options;\n    this.fetchImpl = options.fetchImpl || (globalThis as any).fetch?.bind(globalThis);\n    this.host = extractHost(options.baseUrl);\n    this.channelRepo = options.channelRepo || createDefaultChannelRepo();\n    this.transactionStore = options.transactionStore || createDefaultTransactionStore();\n\n    if (!this.fetchImpl) {\n      throw new Error('fetch implementation not available. Please provide fetchImpl option.');\n    }\n\n    // Initialize payment channel client\n    this.payerClient = PaymentChannelFactory.createClient({\n      chainConfig: options.chainConfig,\n      signer: options.signer,\n      keyId: options.keyId,\n      storageOptions: {\n        channelRepo: this.channelRepo,\n      },\n    });\n\n    this.rateProvider = new ContractRateProvider(this.payerClient.getContract());\n\n    this.logger = DebugLogger.get('PaymentChannelHttpClient');\n    this.logger.setLevel(this.options.debug ? 'debug' : 'info');\n\n    // Initialize configurable timeout\n    this.requestTimeoutMs = this.options.timeoutMs ?? 30000;\n    if (this.options.timeoutMsStream === undefined) {\n      this.options.timeoutMsStream = this.requestTimeoutMs;\n    }\n\n    // Initialize modular components\n    this.paymentState = new PaymentState();\n    this.paymentProtocol = new PaymentProtocol();\n    this.requestManager = new RequestManager(this.paymentState, this.requestTimeoutMs);\n\n    // Initialize mapping store\n    const baseMapping = options.mappingStore || createDefaultMappingStore();\n    const mappingStore = createNamespacedMappingStore(baseMapping, {\n      getPayerDid: async () => this.options.payerDid || (await this.options.signer.getDid()),\n    });\n\n    this.channelManager = new ChannelManager({\n      host: this.host,\n      baseUrl: options.baseUrl,\n      payerClient: this.payerClient,\n      paymentState: this.paymentState,\n      mappingStore,\n      fetchImpl: this.fetchImpl,\n      signer: options.signer,\n      keyId: options.keyId,\n      payerDid: options.payerDid,\n      payeeDid: options.payeeDid,\n      defaultAssetId: options.defaultAssetId,\n    });\n  }\n\n  /**\n   * Primary API – returns a handle with separate response and payment promises.\n   */\n  async requestWithPayment(\n    method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n    path: string,\n    init?: RequestInit\n  ): Promise<PaymentRequestHandle<Response>> {\n    return this.createRequestHandle(method, path, init);\n  }\n\n  /**\n   * Convenience: return only the HTTP response (non-blocking for payment).\n   */\n  async request(\n    method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n    path: string,\n    init?: RequestInit\n  ): Promise<Response> {\n    const handle = await this.createRequestHandle(method, path, init);\n    return handle.response;\n  }\n\n  /**\n   * Convenience: wait for response and payment (recommended for non-streaming endpoints).\n   */\n  async requestAndWaitForPayment(\n    method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n    path: string,\n    init?: RequestInit\n  ): Promise<PaymentResult<Response>> {\n    const handle = await this.createRequestHandle(method, path, init);\n    const data = await handle.response;\n    let payment: PaymentInfo | undefined = undefined;\n    try {\n      payment = await handle.payment;\n    } catch (e) {\n      this.log('[payment.error]', e);\n    }\n    return { data, payment };\n  }\n\n  /**\n   * Convenience methods for common HTTP verbs\n   */\n  async get<T = any>(path: string, init?: RequestInit): Promise<PaymentResult<T>> {\n    const result = await this.requestAndWaitForPayment('GET', path, init);\n    const data = await this.parseJsonAuto<T>(result.data);\n    return { data, payment: result.payment };\n  }\n\n  async post<T = any>(path: string, body?: any, init?: RequestInit): Promise<PaymentResult<T>> {\n    const requestInit = {\n      ...init,\n      body: body ? JSON.stringify(body) : undefined,\n      headers: {\n        'Content-Type': 'application/json',\n        ...init?.headers,\n      },\n    };\n    const result = await this.requestAndWaitForPayment('POST', path, requestInit);\n    const data = await this.parseJsonAuto<T>(result.data);\n    return { data, payment: result.payment };\n  }\n\n  async put<T = any>(path: string, body?: any, init?: RequestInit): Promise<PaymentResult<T>> {\n    const requestInit = {\n      ...init,\n      body: body ? JSON.stringify(body) : undefined,\n      headers: {\n        'Content-Type': 'application/json',\n        ...init?.headers,\n      },\n    };\n    const result = await this.requestAndWaitForPayment('PUT', path, requestInit);\n    const data = await this.parseJsonAuto<T>(result.data);\n    return { data, payment: result.payment };\n  }\n\n  async patch<T = any>(path: string, body?: any, init?: RequestInit): Promise<PaymentResult<T>> {\n    const requestInit = {\n      ...init,\n      body: body ? JSON.stringify(body) : undefined,\n      headers: {\n        'Content-Type': 'application/json',\n        ...init?.headers,\n      },\n    };\n    const result = await this.requestAndWaitForPayment('PATCH', path, requestInit);\n    const data = await this.parseJsonAuto<T>(result.data);\n    return { data, payment: result.payment };\n  }\n\n  async delete<T = any>(path: string, init?: RequestInit): Promise<PaymentResult<T>> {\n    const result = await this.requestAndWaitForPayment('DELETE', path, init);\n    const data = await this.parseJsonAuto<T>(result.data);\n    return { data, payment: result.payment };\n  }\n\n  /**\n   * Get the currently cached pending SubRAV\n   */\n  getPendingSubRAV(): SubRAV | null {\n    return this.paymentState.getPendingSubRAV() || null;\n  }\n\n  /**\n   * Clear the pending SubRAV cache\n   */\n  clearPendingSubRAV(): void {\n    this.paymentState.clearPendingSubRAV();\n    void this.persistClientState();\n  }\n\n  /**\n   * Get the current channel ID\n   */\n  getChannelId(): string | undefined {\n    return this.paymentState.getChannelId();\n  }\n\n  getPayerClient(): PaymentChannelPayerClient {\n    return this.payerClient;\n  }\n\n  getHubClient(): PaymentHubClient {\n    return this.payerClient.getHubClient();\n  }\n\n  getTransactionStore(): TransactionStore {\n    return this.transactionStore;\n  }\n\n  /**\n   * Discover service information\n   */\n  async discoverService(): Promise<DiscoveryResponse> {\n    return this.channelManager.discoverService();\n  }\n\n  async healthCheck(): Promise<HealthResponse> {\n    const healthUrl = this.channelManager.buildPaymentUrl('/health');\n    const response = await this.fetchImpl(healthUrl, { method: 'GET' });\n    return this.parseJsonAuto(response, HealthResponseSchema);\n  }\n\n  /**\n   * Recover channel state and pending SubRAV from service\n   */\n  async recoverFromService(): Promise<RecoveryResponse> {\n    return this.channelManager.recoverFromService();\n  }\n\n  /**\n   * Commit a signed SubRAV to the service\n   */\n  async commitSubRAV(signedSubRAV: SignedSubRAV): Promise<CommitResponse> {\n    await this.channelManager.commitSubRAV(signedSubRAV);\n    return { success: true };\n  }\n\n  buildPaymentUrl(endpoint: string): string {\n    return this.channelManager.buildPaymentUrl(endpoint);\n  }\n\n  getPersistedState(): any {\n    return this.paymentState.getPersistedState();\n  }\n\n  // NOTE: Additional methods will be added in subsequent parts\n  // This is a partial implementation to demonstrate the integration\n\n  private log(...args: any[]): void {\n    this.logger.debug(...args);\n  }\n\n  private async parseJsonAuto<T>(response: Response, schema?: z.ZodType<T>): Promise<T> {\n    // If protocol-level error was recorded for this response, prefer it\n    const protoErr = this.protocolErrorByResponse.get(response);\n    if (protoErr) {\n      throw protoErr;\n    }\n\n    const contentType = response.headers.get('content-type');\n    if (!contentType || !contentType.includes('application/json')) {\n      throw new Error('Response is not JSON');\n    }\n\n    if (!response.ok) {\n      throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n    }\n\n    let responseData: any;\n    try {\n      responseData = await parseJsonResponse<any>(response);\n    } catch (error) {\n      throw new Error('Failed to parse JSON response');\n    }\n\n    if (schema) {\n      if (responseData && typeof responseData === 'object' && 'success' in responseData) {\n        const apiResponse = responseData as ApiResponse<any>;\n        if (apiResponse.success) {\n          return schema.parse(apiResponse.data);\n        } else {\n          const error = apiResponse.error;\n          throw new PaymentKitError(\n            error?.code || ErrorCode.INTERNAL_ERROR,\n            error?.message || 'Unknown error',\n            error?.httpStatus || response.status,\n            error?.details\n          );\n        }\n      }\n      return schema.parse(responseData);\n    }\n\n    if (responseData && typeof responseData === 'object' && 'success' in responseData) {\n      const apiResponse = responseData as ApiResponse<T>;\n      if (apiResponse.success) {\n        return apiResponse.data as T;\n      } else {\n        const error = apiResponse.error;\n        throw new PaymentKitError(\n          error?.code || ErrorCode.INTERNAL_ERROR,\n          error?.message || 'Unknown error',\n          error?.httpStatus || response.status,\n          error?.details\n        );\n      }\n    }\n\n    return responseData as T;\n  }\n\n  /**\n   * Create a handle containing both response and payment promises\n   */\n  private async createRequestHandle(\n    method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n    path: string,\n    init?: RequestInit\n  ): Promise<PaymentRequestHandle<Response>> {\n    const fullUrl = path.startsWith('http') ? path : new URL(path, this.options.baseUrl).toString();\n    const clientTxRef = this.extractOrGenerateClientTxRef(init?.headers);\n\n    // Record trace origin for debugging\n    try {\n      const err = new Error(`[origin] ${method} ${fullUrl}`);\n      const stack = err.stack ? err.stack.split('\\n').slice(1, 10).join('\\n') : 'no stack';\n      this.requestManager.recordTraceOrigin(clientTxRef, stack);\n    } catch {}\n\n    // Use scheduler to serialize payable requests\n    let requestContext!: PaymentRequestContext;\n    let paymentResolve!: (v: PaymentInfo | undefined) => void;\n    let paymentReject!: (e: any) => void;\n    const paymentPromise: Promise<PaymentInfo | undefined> = new Promise((res, rej) => {\n      paymentResolve = res;\n      paymentReject = rej;\n    });\n\n    // Setup abort support\n    const controller = new AbortController();\n    let abort: (() => void) | undefined = () => {\n      controller.abort('aborted by PaymentRequestHandle');\n      try {\n        this.requestManager.rejectByRef(clientTxRef, new Error('Request aborted by caller'));\n      } catch (e) {\n        this.log('[abort.reject.error]', e);\n      }\n    };\n\n    if (init?.signal instanceof AbortSignal) {\n      if (init.signal.aborted) {\n        controller.abort(init.signal.reason);\n      } else {\n        const onAbort = () => controller.abort(init.signal!.reason);\n        init.signal.addEventListener('abort', onAbort, { once: true });\n      }\n    }\n\n    const responsePromise: Promise<Response> = this.scheduler.enqueue(async release => {\n      // Check if client has been cleaned up\n      if (this.isCleanedUp) {\n        throw new Error('Client has been cleaned up');\n      }\n\n      // Ensure prerequisites\n      await this.ensureKeyFragment();\n      await this.channelManager.ensureChannelReady();\n      await this.channelManager.discoverService();\n\n      // Try to recover pending SubRAV if needed\n      try {\n        await this.tryRecoverPendingIfNeeded();\n      } catch (e) {\n        this.log('[serialized.recover.error]', e);\n      }\n\n      // Prepare headers with payment data\n      const { headers, sentedSubRav } = await this.prepareHeaders(\n        fullUrl,\n        method,\n        clientTxRef,\n        init?.headers\n      );\n\n      // Build request context\n      requestContext = {\n        method,\n        url: fullUrl,\n        headers,\n        body: init?.body,\n        clientTxRef,\n      };\n\n      // Create payment promise\n      const channelId = this.paymentState.getChannelId();\n      const assetId = this.options.defaultAssetId || '0x3::gas_coin::RGas';\n\n      if (!channelId) {\n        throw new Error('Channel not initialized');\n      }\n\n      const pp = this.requestManager.createPaymentPromise(\n        clientTxRef,\n        requestContext,\n        sentedSubRav,\n        channelId,\n        assetId\n      );\n\n      // Attach release function\n      const pending = this.paymentState.getPendingPayment(clientTxRef);\n      if (pending) {\n        pending.release = () => {\n          try {\n            release();\n          } catch (e) {\n            this.log?.('[release.error]', e);\n          }\n          pending.release = undefined;\n        };\n      }\n\n      // Bridge internal promise to external one\n      void pp.then(paymentResolve).catch(paymentReject);\n\n      // Transaction logging\n      try {\n        await this.logTransaction(clientTxRef, requestContext, sentedSubRav);\n      } catch (e) {\n        this.log('[txlog.create.error]', e);\n      }\n\n      // Execute request\n      return this.executeRequest(requestContext, { ...init, signal: controller.signal });\n    });\n\n    this.log(\n      '[request.start]',\n      method,\n      fullUrl,\n      'clientTxRef=',\n      clientTxRef,\n      'channelId=',\n      this.paymentState.getChannelId()\n    );\n\n    // Handle response errors\n    responsePromise.catch(err => {\n      this.log('[response.error]', err);\n      try {\n        this.requestManager.resolveByRef(clientTxRef, undefined);\n      } catch (settleErr) {\n        this.log('[response.error.settle]', settleErr);\n      }\n    });\n\n    const startTs = Date.now();\n    const done = responsePromise.then(async (data: Response) => {\n      let payment: PaymentInfo | undefined = undefined;\n      try {\n        payment = await paymentPromise;\n      } catch (e) {\n        this.log?.('[payment.error]', e);\n      }\n      return { data, payment };\n    });\n\n    // Update transaction on response\n    void responsePromise\n      .then(res => {\n        const durationMs = Date.now() - startTs;\n        this.transactionStore?.update(clientTxRef, {\n          statusCode: res.status,\n          durationMs,\n        });\n        return res;\n      })\n      .catch(err => this.log('[txlog.update.error]', err));\n\n    return {\n      clientTxRef,\n      response: responsePromise,\n      payment: paymentPromise,\n      done,\n      abort,\n    };\n  }\n\n  /**\n   * Cleanup client state on logout\n   */\n  async logoutCleanup(\n    options: { clearMapping: boolean; reason?: string } = { clearMapping: true }\n  ): Promise<void> {\n    const reason = options?.reason || 'Logout cleanup';\n\n    // Mark client as cleaned up\n    this.isCleanedUp = true;\n\n    // Try to commit pending SubRAV\n    try {\n      const pending = this.paymentState.getPendingSubRAV();\n      if (pending) {\n        const vmIdFragment = this.paymentState.getVmIdFragment();\n        if (vmIdFragment && vmIdFragment === pending.vmIdFragment) {\n          const signed = await this.payerClient.signSubRAV(pending);\n          await this.channelManager.commitSubRAV(signed);\n          this.log('logoutCleanup: committed pending SubRAV on logout:', pending.nonce);\n        }\n      }\n    } catch (e) {\n      this.log('logoutCleanup: failed to commit pending SubRAV:', e);\n    }\n\n    // Clear scheduler and reject pending payments\n    this.scheduler.clear();\n    this.requestManager.rejectAll(new Error(reason));\n\n    // Reset state\n    this.paymentState.reset();\n\n    // Clear persisted mapping if requested\n    if (options?.clearMapping !== false) {\n      try {\n        const mappingStore = this.options.mappingStore || createDefaultMappingStore();\n        const namespacedStore = createNamespacedMappingStore(mappingStore, {\n          getPayerDid: async () => this.options.payerDid || (await this.options.signer.getDid()),\n        });\n        await namespacedStore.deleteState(this.host);\n      } catch (e) {\n        this.log('logoutCleanup: deleteState(mapping) failed:', e);\n      }\n    }\n\n    await this.persistClientState();\n  }\n\n  /**\n   * Compute unsettled amount for the current sub-channel\n   */\n  async getUnsettledAmountForSubChannel(): Promise<{\n    channelId: string;\n    vmIdFragment: string;\n    authorizedAccumulated: bigint;\n    lastClaimed: bigint;\n    unsettled: bigint;\n    unsettledUsd: bigint;\n    subChannelInfo: SubChannelInfo;\n    latestSubRavNonce?: bigint;\n  }> {\n    await this.channelManager.ensureChannelReady();\n    await this.ensureKeyFragment();\n\n    const channelInfo = this.paymentState.getChannelInfo();\n    const vmIdFragment = this.paymentState.getVmIdFragment();\n\n    if (!channelInfo || !vmIdFragment) {\n      throw new Error('Channel or vmIdFragment not initialized');\n    }\n\n    const assetId = channelInfo.assetId;\n    const channelId = channelInfo.channelId;\n\n    // Fetch on-chain sub-channel state\n    let subChannelInfo = this.paymentState.getSubChannelInfo();\n    if (!subChannelInfo) {\n      subChannelInfo = await this.payerClient.getSubChannelInfo(channelId, vmIdFragment);\n      this.paymentState.setSubChannelInfo(subChannelInfo);\n    }\n    const lastClaimed = subChannelInfo.lastClaimedAmount;\n\n    // Determine latest authorized accumulated value\n    let authorizedAccumulated: bigint | undefined = undefined;\n    let latestSubRavNonce: bigint | undefined = undefined;\n\n    const pending = this.paymentState.getPendingSubRAV();\n    if (pending && pending.channelId === channelId && pending.vmIdFragment === vmIdFragment) {\n      authorizedAccumulated = pending.accumulatedAmount;\n      latestSubRavNonce = pending.nonce;\n    } else {\n      // Try to recover from service\n      try {\n        const recovery = await this.channelManager.recoverFromService();\n        if (\n          recovery.pendingSubRav &&\n          recovery.pendingSubRav.channelId === channelId &&\n          recovery.pendingSubRav.vmIdFragment === vmIdFragment\n        ) {\n          authorizedAccumulated = recovery.pendingSubRav.accumulatedAmount;\n          latestSubRavNonce = recovery.pendingSubRav.nonce;\n        }\n      } catch (e) {\n        this.log('[unsettled.recover.error]', e);\n      }\n    }\n\n    if (authorizedAccumulated === undefined) {\n      authorizedAccumulated = lastClaimed;\n    }\n\n    const diff = authorizedAccumulated - lastClaimed;\n    const unsettled = diff > 0n ? diff : 0n;\n    const unsettledUsd = (await this.rateProvider.getPricePicoUSD(assetId)) * unsettled;\n\n    return {\n      channelId,\n      vmIdFragment,\n      authorizedAccumulated,\n      lastClaimed,\n      unsettled,\n      unsettledUsd,\n      subChannelInfo,\n      latestSubRavNonce,\n    };\n  }\n\n  // -------- Private Methods --------\n\n  /**\n   * Extract clientTxRef from headers or generate new one\n   */\n  private extractOrGenerateClientTxRef(providedHeaders?: HeadersInit): string {\n    if (providedHeaders) {\n      let clientTxRef: string | undefined;\n\n      if (providedHeaders instanceof Headers) {\n        clientTxRef = providedHeaders.get('X-Client-Tx-Ref') || undefined;\n      } else if (Array.isArray(providedHeaders)) {\n        const found = providedHeaders.find(([key]) => key.toLowerCase() === 'x-client-tx-ref');\n        clientTxRef = found?.[1];\n      } else if (typeof providedHeaders === 'object') {\n        clientTxRef =\n          (providedHeaders as Record<string, string>)['X-Client-Tx-Ref'] ||\n          (providedHeaders as Record<string, string>)['x-client-tx-ref'];\n      }\n\n      if (clientTxRef) {\n        return clientTxRef;\n      }\n    }\n\n    return crypto.randomUUID();\n  }\n\n  /**\n   * Ensure keyId and vmIdFragment are resolved\n   */\n  private async ensureKeyFragment(): Promise<void> {\n    if (this.paymentState.getKeyId() && this.paymentState.getVmIdFragment()) return;\n\n    let keyId = this.options.keyId;\n    if (!keyId) {\n      if (this.options.signer && typeof this.options.signer.listKeyIds === 'function') {\n        try {\n          const ids: string[] = await this.options.signer.listKeyIds();\n          keyId = Array.isArray(ids) && ids.length > 0 ? ids[0] : undefined;\n        } catch (e) {\n          this.log('listKeyIds failed:', e);\n        }\n      }\n    }\n\n    if (keyId) {\n      const parts = keyId.split('#');\n      const vmIdFragment = parts.length > 1 ? parts[1] : undefined;\n      if (vmIdFragment) {\n        this.paymentState.setKeyInfo(keyId, vmIdFragment);\n      }\n    }\n\n    if (!this.paymentState.getKeyId() || !this.paymentState.getVmIdFragment()) {\n      throw new Error('No keyId found');\n    }\n  }\n\n  /**\n   * Try to recover pending SubRAV if needed\n   */\n  private async tryRecoverPendingIfNeeded(): Promise<void> {\n    if (!this.paymentState.getPendingSubRAV()) {\n      try {\n        const recoveryData = await this.channelManager.recoverFromService();\n        if (recoveryData.pendingSubRav) {\n          this.paymentState.setPendingSubRAV(recoveryData.pendingSubRav);\n        }\n      } catch (error) {\n        this.log('Recovery failed:', error);\n      }\n    }\n  }\n\n  /**\n   * Prepare headers for the request\n   */\n  private async prepareHeaders(\n    fullUrl: string,\n    method: string,\n    clientTxRef: string,\n    providedHeaders?: HeadersInit\n  ): Promise<{ headers: Record<string, string>; sentedSubRav: SignedSubRAV | undefined }> {\n    const headers: Record<string, string> = {};\n\n    // Copy provided headers\n    if (providedHeaders) {\n      if (providedHeaders instanceof Headers) {\n        providedHeaders.forEach((value, key) => {\n          headers[key] = value;\n        });\n      } else if (Array.isArray(providedHeaders)) {\n        providedHeaders.forEach(([key, value]) => {\n          headers[key] = value;\n        });\n      } else {\n        Object.assign(headers, providedHeaders);\n      }\n    }\n\n    // Add DID authorization header\n    try {\n      const payerDid = this.options.payerDid || (await this.options.signer.getDid());\n      const authHeader = await DidAuthHelper.generateAuthHeader(\n        payerDid,\n        this.options.signer,\n        fullUrl,\n        method,\n        this.options.keyId\n      );\n      if (authHeader) {\n        headers['Authorization'] = authHeader;\n      }\n    } catch (error) {\n      this.log('Failed to generate DID auth header:', error);\n    }\n\n    // Add payment channel header\n    const sentedSubRav = await this.addPaymentChannelHeader(headers, clientTxRef);\n\n    this.log(\n      '[request.headers]',\n      method,\n      fullUrl,\n      'clientTxRef=',\n      clientTxRef,\n      'channelId=',\n      this.paymentState.getChannelId(),\n      'signedSubRav=',\n      !!sentedSubRav\n    );\n\n    return { headers, sentedSubRav };\n  }\n\n  /**\n   * Add payment channel data to headers\n   */\n  private async addPaymentChannelHeader(\n    headers: Record<string, string>,\n    clientTxRef: string\n  ): Promise<SignedSubRAV | undefined> {\n    if (!this.paymentState.getChannelId()) {\n      throw new Error('Channel not initialized');\n    }\n\n    try {\n      const signedSubRAV = await this.buildSignedSubRavIfNeeded();\n      const headerValue = this.paymentProtocol.encodeRequestHeader(\n        signedSubRAV,\n        clientTxRef,\n        this.options.maxAmount\n      );\n      headers[this.paymentProtocol.getHeaderName()] = headerValue;\n\n      if (signedSubRAV) {\n        this.log('Added payment header with SignedSubRAV');\n      } else {\n        this.log('Added payment header in FREE mode (clientTxRef only)');\n      }\n\n      return signedSubRAV;\n    } catch (error) {\n      this.log('Failed to add payment channel header:', error);\n      throw error;\n    }\n  }\n\n  /**\n   * Build and sign SubRAV if pending exists\n   */\n  private async buildSignedSubRavIfNeeded(): Promise<SignedSubRAV | undefined> {\n    const pending = this.paymentState.getPendingSubRAV();\n    if (!pending) {\n      this.log('No pending SubRAV - operating in FREE mode');\n      return undefined;\n    }\n\n    // Clear pending SubRAV\n    this.paymentState.clearPendingSubRAV();\n\n    const signed = await this.payerClient.signSubRAV(pending);\n    this.log('Signed pending SubRAV:', pending.nonce, pending.accumulatedAmount);\n\n    // Update highest observed nonce\n    this.paymentState.updateHighestNonce(pending.nonce);\n\n    return signed;\n  }\n\n  /**\n   * Execute the HTTP request\n   */\n  private async executeRequest(\n    context: PaymentRequestContext,\n    init?: RequestInit\n  ): Promise<Response> {\n    try {\n      const { headers: _, ...initWithoutHeaders } = init || {};\n\n      const response = await this.fetchImpl(context.url, {\n        method: context.method,\n        headers: context.headers,\n        body: context.body,\n        ...initWithoutHeaders,\n      });\n\n      // Handle response\n      await this.handleResponse(response, context);\n\n      // Handle streaming responses\n      if (\n        isStreamLikeResponse(response) &&\n        response.body &&\n        typeof (response.body as any).getReader === 'function'\n      ) {\n        const onActivity = () => {\n          if (context.clientTxRef && typeof this.options.timeoutMsStream === 'number') {\n            this.requestManager.extendTimeout(context.clientTxRef, this.options.timeoutMsStream);\n          }\n        };\n\n        const filtered = wrapAndFilterInBandFrames(\n          response,\n          async p => {\n            try {\n              const decoded = this.paymentProtocol.parseResponseHeader((p as any).headerValue);\n              if (decoded?.subRav && decoded.cost !== undefined) {\n                await this.handleProtocolSuccess({\n                  type: 'success',\n                  clientTxRef: decoded.clientTxRef,\n                  subRav: decoded.subRav,\n                  cost: decoded.cost as bigint,\n                  costUsd: decoded.costUsd as bigint | undefined,\n                  serviceTxRef: decoded.serviceTxRef,\n                });\n              }\n            } catch (e) {\n              this.log('[inband.decode.error]', e);\n            }\n          },\n          (...args: any[]) => this.log(...args),\n          onActivity\n        );\n\n        // Mark as streaming\n        if (this.transactionStore && context.clientTxRef) {\n          await this.transactionStore.update(context.clientTxRef, { stream: true });\n        }\n\n        // Set initial timeout for streaming\n        if (context.clientTxRef && typeof this.options.timeoutMsStream === 'number') {\n          this.requestManager.extendTimeout(context.clientTxRef, this.options.timeoutMsStream);\n        }\n\n        // Don't wrap for scheduler release - let payment promise control it\n        // This allows server time to process reactive claims before next request\n        return filtered;\n      }\n\n      return response;\n    } catch (error) {\n      this.log('Request failed:', error);\n      throw error;\n    }\n  }\n\n  /**\n   * Handle the HTTP response\n   */\n  private async handleResponse(response: Response, context?: PaymentRequestContext): Promise<void> {\n    const protocol = this.paymentProtocol.parseProtocolFromResponse(response, context);\n\n    if (protocol.type !== 'none') {\n      this.log(\n        '[response.header]',\n        'type=',\n        protocol.type,\n        'clientTxRef=',\n        (protocol as any).clientTxRef,\n        'status=',\n        response.status\n      );\n    } else {\n      this.log(\n        '[response.no-header]',\n        'status=',\n        response.status,\n        'pendingKeys=',\n        this.requestManager.getPendingKeys()\n      );\n    }\n\n    if (protocol.type === 'error') {\n      this.logTraceOrigin(protocol.clientTxRef);\n      await this.handleProtocolError(protocol);\n      // Record protocol error for this response; do not throw here to avoid double-throw.\n      this.protocolErrorByResponse.set(response, protocol.err);\n      return;\n    }\n\n    if (protocol.type === 'success') {\n      await this.handleProtocolSuccess(protocol);\n      return;\n    }\n\n    // No protocol header present\n    await this.handleNoProtocolHeader(response);\n  }\n\n  private async handleProtocolError(proto: {\n    type: 'error';\n    clientTxRef?: string;\n    err: PaymentKitError;\n  }): Promise<void> {\n    if (proto.clientTxRef && this.requestManager.resolveByRef(proto.clientTxRef, undefined)) {\n      this.paymentState.clearPendingSubRAV();\n      await this.persistClientState();\n      return;\n    }\n\n    // Handle cases with only one pending payment\n    const pendingPayments = this.paymentState.getAllPendingPayments();\n    if (pendingPayments.size === 1) {\n      const [[onlyKey]] = pendingPayments.entries();\n      this.requestManager.resolveByRef(onlyKey, undefined);\n      this.paymentState.clearPendingSubRAV();\n      await this.persistClientState();\n      return;\n    }\n\n    // Handle multiple pending payments\n    if (pendingPayments.size > 1) {\n      for (const [key] of pendingPayments.entries()) {\n        this.requestManager.resolveByRef(key, undefined);\n      }\n      this.paymentState.clearPendingSubRAV();\n      await this.persistClientState();\n    }\n  }\n\n  private async handleProtocolSuccess(proto: {\n    type: 'success';\n    clientTxRef?: string;\n    subRav: SubRAV;\n    cost: bigint;\n    costUsd?: bigint;\n    serviceTxRef?: string;\n  }): Promise<void> {\n    // Find matching pending payment\n    let pendingKey: string | undefined;\n    let pendingRequest = this.findMatchingPendingPayment(proto);\n\n    if (!pendingRequest) {\n      // No matching pending - cache for future use\n      if (proto.clientTxRef && this.paymentState.isRecentlyRejected(proto.clientTxRef)) {\n        this.log('[payment.late-success.ignored]', proto.clientTxRef);\n        return;\n      }\n      this.paymentState.setPendingSubRAV(proto.subRav);\n      await this.persistClientState();\n      return;\n    }\n\n    pendingKey = pendingRequest.key;\n\n    // Validate SubRAV progression\n    const prev = pendingRequest.pending.sendedSubRav?.subRav;\n    if (prev) {\n      try {\n        assertSubRavProgression(prev, proto.subRav, true);\n      } catch (e) {\n        this.requestManager.rejectByRef(\n          pendingKey,\n          new Error(\n            'Invalid SubRAV progression: ' +\n              (e as Error).message +\n              ', response: ' +\n              serializeJson({ subRav: proto.subRav, cost: proto.cost, costUsd: proto.costUsd }) +\n              ' prev: ' +\n              serializeJson(prev)\n          )\n        );\n        return;\n      }\n    }\n\n    // Cache next proposal for future request\n    this.paymentState.setPendingSubRAV(proto.subRav);\n    await this.persistClientState();\n\n    // Resolve payment\n    const paymentInfo: PaymentInfo = {\n      clientTxRef: proto.clientTxRef || pendingKey,\n      serviceTxRef: proto.serviceTxRef,\n      cost: proto.cost,\n      costUsd: proto.costUsd ?? BigInt(0),\n      nonce: proto.subRav.nonce,\n      channelId: pendingRequest.pending.channelId,\n      vmIdFragment: proto.subRav.vmIdFragment,\n      assetId: pendingRequest.pending.assetId,\n      timestamp: new Date().toISOString(),\n    };\n\n    this.requestManager.resolveByRef(pendingKey, paymentInfo);\n\n    // Update transaction log\n    try {\n      if (this.options.transactionLog?.enabled !== false && this.transactionStore) {\n        await this.transactionStore.update(paymentInfo.clientTxRef, {\n          payment: {\n            cost: paymentInfo.cost,\n            costUsd: paymentInfo.costUsd,\n            nonce: paymentInfo.nonce,\n            serviceTxRef: paymentInfo.serviceTxRef,\n          },\n          vmIdFragment: paymentInfo.vmIdFragment,\n          status: 'paid',\n        });\n      }\n    } catch (e) {\n      this.log('[txlog.finalize.error]', e);\n    }\n\n    this.log(\n      'Resolved payment for clientTxRef:',\n      paymentInfo.clientTxRef,\n      'cost:',\n      paymentInfo.cost.toString()\n    );\n\n    // Update highest observed nonce\n    this.paymentState.updateHighestNonce(paymentInfo.nonce);\n  }\n\n  private async handleNoProtocolHeader(response: Response): Promise<void> {\n    // Streaming responses are handled in wrapper layer\n    if (isStreamLikeResponse(response)) {\n      return;\n    }\n\n    // Non-streaming: treat as free endpoint\n    this.requestManager.resolveAllAsFree();\n\n    // Handle specific status codes\n    const error = this.paymentProtocol.handleStatusCode(response.status);\n    if (error) {\n      if (response.status === 402 || response.status === 409) {\n        this.paymentState.clearPendingSubRAV();\n        await this.persistClientState();\n      }\n      throw error;\n    }\n  }\n\n  /**\n   * Find matching pending payment for a protocol success response\n   */\n  private findMatchingPendingPayment(proto: {\n    clientTxRef?: string;\n    subRav: SubRAV;\n  }): { key: string; pending: any } | undefined {\n    const pendingPayments = this.paymentState.getAllPendingPayments();\n\n    // Try exact match first\n    if (proto.clientTxRef && pendingPayments.has(proto.clientTxRef)) {\n      return {\n        key: proto.clientTxRef,\n        pending: pendingPayments.get(proto.clientTxRef)!,\n      };\n    }\n\n    // Single pending payment\n    if (pendingPayments.size === 1) {\n      const [[key, pending]] = pendingPayments.entries();\n      return { key, pending };\n    }\n\n    // Try to match by SubRAV progression\n    if (pendingPayments.size > 1) {\n      for (const [k, p] of pendingPayments.entries()) {\n        const prevSent = p.sendedSubRav?.subRav;\n        if (!prevSent) continue;\n\n        try {\n          assertSubRavProgression(prevSent, proto.subRav, true);\n          return { key: k, pending: p };\n        } catch {\n          // Not a match\n        }\n      }\n    }\n\n    // Fallback to most recent\n    if (pendingPayments.size >= 1) {\n      const all = Array.from(pendingPayments.entries());\n      const [key, pending] = all[all.length - 1];\n      return { key, pending };\n    }\n\n    return undefined;\n  }\n\n  /**\n   * Log transaction details\n   */\n  private async logTransaction(\n    clientTxRef: string,\n    context: PaymentRequestContext,\n    sentedSubRav: SignedSubRAV | undefined\n  ): Promise<void> {\n    if (this.options.transactionLog?.enabled === false || !this.transactionStore) {\n      return;\n    }\n\n    const urlObj = new URL(context.url);\n    const sanitize = this.options.transactionLog?.sanitizeRequest;\n    const sanitized = sanitize ? sanitize(context.headers, context.body) : undefined;\n\n    const headersSummary = sanitized?.headersSummary ?? {\n      'content-type': context.headers['Content-Type'] || context.headers['content-type'] || '',\n    };\n\n    await this.transactionStore.create({\n      clientTxRef,\n      timestamp: Date.now(),\n      protocol: 'http',\n      method: context.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',\n      urlOrTarget: context.url,\n      operation: `${context.method}:${urlObj.pathname}`,\n      headersSummary,\n      requestBodyHash: sanitized?.requestBodyHash,\n      stream: false,\n      channelId: this.paymentState.getChannelId(),\n      vmIdFragment: sentedSubRav?.subRav?.vmIdFragment,\n      assetId: this.options.defaultAssetId || '0x3::gas_coin::RGas',\n      status: 'pending',\n    });\n  }\n\n  /**\n   * Log trace origin for debugging\n   */\n  private logTraceOrigin(clientTxRef?: string): void {\n    try {\n      if (clientTxRef) {\n        const origin = this.requestManager.getTraceOrigin(clientTxRef);\n        if (origin) {\n          this.log('[trace.origin]', clientTxRef, '\\n', origin);\n        }\n        this.requestManager.clearTraceOrigin(clientTxRef);\n      } else {\n        const snapshots = this.requestManager.getTraceSnapshots(5);\n        if (snapshots.length > 0) {\n          this.log('[trace.origin.scan]', JSON.stringify(snapshots));\n        }\n      }\n    } catch {}\n  }\n\n  /**\n   * Persist client state\n   */\n  private async persistClientState(): Promise<void> {\n    try {\n      const mappingStore = this.options.mappingStore || createDefaultMappingStore();\n      const namespacedStore = createNamespacedMappingStore(mappingStore, {\n        getPayerDid: async () => this.options.payerDid || (await this.options.signer.getDid()),\n      });\n\n      const state = this.paymentState.getPersistedState();\n      await namespacedStore.setState(this.host, state);\n\n      this.log('Persisted client state');\n    } catch (error) {\n      this.log('Failed to persist client state:', error);\n    }\n  }\n}\n","// Lightweight helper to wrap a streaming Response, parse in-band payment frames,\n// and filter them out so the application only sees business data.\n// Supports SSE (text/event-stream) and NDJSON (application/x-ndjson).\n\nexport interface InBandPaymentPayload {\n  // unified payload now carries only encoded header value\n  headerValue: string;\n}\n\nexport function wrapAndFilterInBandFrames(\n  response: Response,\n  onPayment: (payload: InBandPaymentPayload) => void | Promise<void>,\n  log: (...args: any[]) => void,\n  onActivity?: () => void\n): Response {\n  const originalBody = response.body as ReadableStream<Uint8Array> | null;\n  if (!originalBody || typeof (originalBody as any).getReader !== 'function') {\n    return response;\n  }\n\n  const reader = (originalBody as any).getReader();\n  const textDecoder = new TextDecoder();\n  const textEncoder = new TextEncoder();\n\n  const ct = (response.headers.get('content-type') || '').toLowerCase();\n  const isSSE = ct.includes('text/event-stream');\n  const isNDJSON = ct.includes('application/x-ndjson');\n\n  // After payment frame is handled, proactively close the filtered stream to avoid hanging\n  const afterPayment = (controller: ReadableStreamDefaultController<Uint8Array>) => {\n    try {\n      controller.close();\n      try {\n        reader.cancel();\n      } catch (e) {\n        log('[afterPayment.error]', e);\n      }\n    } catch (e) {\n      log('[afterPayment.error]', e);\n    }\n  };\n\n  const parser: InBandParser = isSSE\n    ? new SseInbandParser(textEncoder, onPayment, log, afterPayment)\n    : new NdjsonInbandParser(textEncoder, onPayment, log, afterPayment);\n\n  const filtered = new ReadableStream<Uint8Array>({\n    async pull(controller) {\n      try {\n        const { value, done } = await reader.read();\n        if (done) {\n          await parser.flush(controller);\n          controller.close();\n          return;\n        }\n        if (!value) return;\n        try {\n          onActivity?.();\n        } catch (e) {\n          log('[pull.onActivity.error]', e);\n        }\n        const chunkText = textDecoder.decode(value, { stream: true });\n        await parser.process(chunkText, controller);\n      } catch (e) {\n        try {\n          reader.cancel();\n        } catch (e) {\n          log('[pull.error]', e);\n        }\n        controller.error(e);\n      }\n    },\n    cancel() {\n      try {\n        reader.cancel();\n      } catch (e) {\n        log('[cancel.error]', e);\n      }\n    },\n  });\n\n  const headers = new Headers(response.headers);\n  headers.delete('content-length');\n  const filteredResponse = new Response(filtered as any, {\n    status: response.status,\n    statusText: response.statusText,\n    headers,\n  });\n  return filteredResponse;\n}\n\n// ---------------------------------------------------------------------------\n// Parsers\n// ---------------------------------------------------------------------------\n\ninterface InBandParser {\n  process(\n    textChunk: string,\n    controller: ReadableStreamDefaultController<Uint8Array>\n  ): Promise<void>;\n  flush(controller: ReadableStreamDefaultController<Uint8Array>): Promise<void>;\n}\n\nclass SseInbandParser implements InBandParser {\n  private buffer = '';\n  private pendingEvent: string[] = [];\n  constructor(\n    private encoder: TextEncoder,\n    private onPayment: (payload: InBandPaymentPayload) => void | Promise<void>,\n    private log: (...args: any[]) => void,\n    private onAfterPayment: (controller: ReadableStreamDefaultController<Uint8Array>) => void\n  ) {}\n\n  async process(\n    textChunk: string,\n    controller: ReadableStreamDefaultController<Uint8Array>\n  ): Promise<void> {\n    this.buffer += textChunk;\n    const lines = this.buffer.split(/\\r?\\n/);\n    this.buffer = lines.pop() ?? '';\n    for (const line of lines) {\n      this.pendingEvent.push(line);\n      if (line === '') {\n        const isPayment = this.pendingEvent.some(l => {\n          const m = l.match(/^data:\\s*(.+)$/);\n          if (!m) return false;\n          try {\n            const o = JSON.parse(m[1]);\n            return !!(o?.nuwa_payment_header || o?.__nuwa_payment_header__);\n          } catch {\n            return false;\n          }\n        });\n        if (!isPayment) {\n          for (const out of this.pendingEvent) controller.enqueue(this.encoder.encode(out + '\\n'));\n        } else {\n          try {\n            const dataLine = this.pendingEvent.find(l => l.startsWith('data: '));\n            if (dataLine) {\n              const payload = JSON.parse(dataLine.slice(6));\n              const headerValue = payload?.nuwa_payment_header || payload?.__nuwa_payment_header__;\n              if (typeof headerValue === 'string') {\n                await safeHandlePayment({ headerValue }, this.onPayment, this.log);\n                this.onAfterPayment(controller);\n              }\n            }\n          } catch (e) {\n            this.log('[process.error]', e);\n          }\n        }\n        this.pendingEvent = [];\n      }\n    }\n  }\n\n  async flush(controller: ReadableStreamDefaultController<Uint8Array>): Promise<void> {\n    if (!this.buffer) return;\n    this.pendingEvent.push(this.buffer);\n    const isPayment = this.pendingEvent.some(l => {\n      const m = l.match(/^data:\\s*(.+)$/);\n      if (!m) return false;\n      try {\n        const o = JSON.parse(m[1]);\n        return !!(o?.nuwa_payment_header || o?.__nuwa_payment_header__);\n      } catch {\n        return false;\n      }\n    });\n    if (!isPayment) {\n      for (const out of this.pendingEvent) controller.enqueue(this.encoder.encode(out + '\\n'));\n    } else {\n      try {\n        const dataLine = this.pendingEvent.find(l => l.startsWith('data: '));\n        if (dataLine) {\n          const payload = JSON.parse(dataLine.slice(6));\n          const headerValue = payload?.nuwa_payment_header || payload?.__nuwa_payment_header__;\n          if (typeof headerValue === 'string') {\n            await safeHandlePayment({ headerValue }, this.onPayment, this.log);\n            this.onAfterPayment(controller);\n          }\n        }\n      } catch (e) {\n        this.log('[flush.error]', e);\n      }\n    }\n    this.pendingEvent = [];\n    this.buffer = '';\n  }\n}\n\nclass NdjsonInbandParser implements InBandParser {\n  private buffer = '';\n  constructor(\n    private encoder: TextEncoder,\n    private onPayment: (payload: InBandPaymentPayload) => void | Promise<void>,\n    private log: (...args: any[]) => void,\n    private onAfterPayment: (controller: ReadableStreamDefaultController<Uint8Array>) => void\n  ) {}\n\n  async process(\n    textChunk: string,\n    controller: ReadableStreamDefaultController<Uint8Array>\n  ): Promise<void> {\n    this.buffer += textChunk;\n    const lines = this.buffer.split(/\\r?\\n/);\n    this.buffer = lines.pop() ?? '';\n    for (const line of lines) {\n      const t = line.trim();\n      if (!t) continue;\n      let drop = false;\n      try {\n        const obj = JSON.parse(t);\n        const headerValue = obj?.__nuwa_payment_header__ || obj?.nuwa_payment_header;\n        if (typeof headerValue === 'string') {\n          drop = true;\n          await safeHandlePayment({ headerValue }, this.onPayment, this.log);\n          this.onAfterPayment(controller);\n        }\n      } catch (e) {\n        this.log('[process.error]', e);\n      }\n      if (!drop) controller.enqueue(this.encoder.encode(line + '\\n'));\n    }\n  }\n\n  async flush(controller: ReadableStreamDefaultController<Uint8Array>): Promise<void> {\n    if (!this.buffer) return;\n    const t = this.buffer.trim();\n    let drop = false;\n    try {\n      const obj = JSON.parse(t);\n      const headerValue = obj?.__nuwa_payment_header__ || obj?.nuwa_payment_header;\n      if (typeof headerValue === 'string') {\n        drop = true;\n        await safeHandlePayment({ headerValue }, this.onPayment, this.log);\n        this.onAfterPayment(controller);\n      }\n    } catch (e) {\n      this.log('[flush.error]', e);\n    }\n    if (!drop) controller.enqueue(this.encoder.encode(this.buffer + '\\n'));\n    this.buffer = '';\n  }\n}\n\nasync function safeHandlePayment(\n  p: any,\n  onPayment: (payload: InBandPaymentPayload) => void | Promise<void>,\n  log: (...args: any[]) => void\n): Promise<void> {\n  try {\n    if (p && typeof p.headerValue === 'string') {\n      await onPayment(p as InBandPaymentPayload);\n    }\n  } catch (e) {\n    log('[inband.handle.error]', (e as Error)?.message || String(e));\n  }\n}\n","/**\n * Detect if a fetch Response should be treated as streaming for payment in-band parsing.\n * Strictly checks Content-Type to avoid false positives (e.g., chunked JSON).\n */\nexport function isStreamLikeResponse(response: Response): boolean {\n  const ct = (response.headers.get('content-type') || '').toLowerCase();\n  return ct.includes('text/event-stream') || ct.includes('application/x-ndjson');\n}\n","import { DebugLogger } from '@nuwa-ai/identity-kit';\n\ntype StartFn<T> = (release: () => void) => Promise<T>;\n\nexport class RequestScheduler {\n  private queue: Array<() => Promise<void>> = [];\n  private active = 0;\n  private readonly concurrency = 1;\n  private logger = DebugLogger.get('RequestScheduler');\n  private isShutdown = false;\n\n  enqueue<T>(start: StartFn<T>): Promise<T> {\n    return new Promise<T>((outerResolve, outerReject) => {\n      // Reject immediately if shutdown\n      if (this.isShutdown) {\n        outerReject(new Error('RequestScheduler is shutdown'));\n        return;\n      }\n\n      const task = async () => {\n        this.active += 1;\n        let released = false;\n        const release = () => {\n          if (released) return;\n          released = true;\n          this.active -= 1;\n          this.flush();\n        };\n        try {\n          const result = await start(release);\n          outerResolve(result);\n        } catch (e) {\n          this.logger.debug('Task failed:', e);\n          try {\n            release();\n          } catch (releaseError) {\n            this.logger.debug('Error during release:', releaseError);\n          }\n          outerReject(e);\n          return;\n        }\n      };\n      this.queue.push(task);\n      this.flush();\n    });\n  }\n\n  private flush() {\n    while (this.active < this.concurrency && this.queue.length > 0) {\n      const next = this.queue.shift()!;\n      void next();\n    }\n  }\n\n  /**\n   * Clear the queue and prevent any new tasks from being enqueued\n   */\n  clear(): void {\n    this.isShutdown = true;\n    const queueSize = this.queue.length;\n    this.queue = [];\n    this.logger.debug('RequestScheduler cleared, queue size was:', queueSize);\n  }\n}\n","import type {\n  HttpClientState,\n  PersistedHttpClientState,\n  PendingPaymentRequest,\n  HostChannelMappingStore,\n} from '../types';\nimport type { SubRAV, ChannelInfo, SubChannelInfo } from '../../../core/types';\nimport { DebugLogger } from '@nuwa-ai/identity-kit';\n\n/**\n * PaymentState manages all client state in a centralized way.\n * This includes channel information, pending payments, and cached SubRAVs.\n */\nexport class PaymentState {\n  private logger: DebugLogger;\n  private state: HttpClientState;\n  private channelId?: string;\n  private channelInfo?: ChannelInfo;\n  private subChannelInfo?: SubChannelInfo;\n  private keyId?: string;\n  private vmIdFragment?: string;\n  private pendingSubRAV?: SubRAV;\n  private highestObservedNonce?: bigint;\n  private recentlyRejectedRefs = new Set<string>();\n\n  constructor() {\n    this.logger = DebugLogger.get('PaymentState');\n    this.state = {\n      pendingPayments: new Map(),\n    };\n  }\n\n  // Channel management\n  setChannelId(channelId: string | undefined): void {\n    this.channelId = channelId;\n    this.logger.debug('Channel ID set:', channelId);\n  }\n\n  getChannelId(): string | undefined {\n    return this.channelId;\n  }\n\n  setChannelInfo(info: ChannelInfo | undefined): void {\n    this.channelInfo = info;\n  }\n\n  getChannelInfo(): ChannelInfo | undefined {\n    return this.channelInfo;\n  }\n\n  setSubChannelInfo(info: SubChannelInfo | undefined): void {\n    this.subChannelInfo = info;\n  }\n\n  getSubChannelInfo(): SubChannelInfo | undefined {\n    return this.subChannelInfo;\n  }\n\n  // Key management\n  setKeyInfo(keyId: string, vmIdFragment: string): void {\n    this.keyId = keyId;\n    this.vmIdFragment = vmIdFragment;\n    this.logger.debug('Key info set:', { keyId, vmIdFragment });\n  }\n\n  getKeyId(): string | undefined {\n    return this.keyId;\n  }\n\n  getVmIdFragment(): string | undefined {\n    return this.vmIdFragment;\n  }\n\n  // Pending SubRAV management\n  setPendingSubRAV(subRav: SubRAV | undefined): void {\n    // Apply monotonic guard to prevent rollback\n    if (subRav && this.shouldAcceptSubRAV(subRav)) {\n      this.pendingSubRAV = subRav;\n      this.logger.debug('Pending SubRAV set:', subRav.nonce);\n    }\n  }\n\n  getPendingSubRAV(): SubRAV | undefined {\n    return this.pendingSubRAV;\n  }\n\n  clearPendingSubRAV(): void {\n    this.pendingSubRAV = undefined;\n    this.logger.debug('Pending SubRAV cleared');\n  }\n\n  // Monotonic nonce guard\n  updateHighestNonce(nonce: bigint): void {\n    if (!this.highestObservedNonce || nonce > this.highestObservedNonce) {\n      this.highestObservedNonce = nonce;\n    }\n  }\n\n  private shouldAcceptSubRAV(subRav: SubRAV): boolean {\n    // Fragment guard\n    if (this.vmIdFragment && subRav.vmIdFragment !== this.vmIdFragment) {\n      this.logger.debug('Rejecting SubRAV: fragment mismatch');\n      return false;\n    }\n\n    // Nonce guard\n    const currentNonce = this.pendingSubRAV?.nonce;\n    if (\n      (this.highestObservedNonce && subRav.nonce <= this.highestObservedNonce) ||\n      (currentNonce && subRav.nonce <= currentNonce)\n    ) {\n      this.logger.debug('Rejecting SubRAV: nonce not progressive');\n      return false;\n    }\n\n    return true;\n  }\n\n  // Pending payments management\n  addPendingPayment(clientTxRef: string, request: PendingPaymentRequest): void {\n    this.state.pendingPayments?.set(clientTxRef, request);\n    this.logger.debug('Pending payment added:', clientTxRef);\n  }\n\n  getPendingPayment(clientTxRef: string): PendingPaymentRequest | undefined {\n    return this.state.pendingPayments?.get(clientTxRef);\n  }\n\n  removePendingPayment(clientTxRef: string): void {\n    this.state.pendingPayments?.delete(clientTxRef);\n    this.logger.debug('Pending payment removed:', clientTxRef);\n  }\n\n  getAllPendingPayments(): Map<string, PendingPaymentRequest> {\n    return this.state.pendingPayments || new Map();\n  }\n\n  clearAllPendingPayments(): void {\n    this.state.pendingPayments?.clear();\n    this.logger.debug('All pending payments cleared');\n  }\n\n  // Rejected refs tracking\n  markAsRejected(clientTxRef: string): void {\n    this.recentlyRejectedRefs.add(clientTxRef);\n  }\n\n  isRecentlyRejected(clientTxRef: string): boolean {\n    return this.recentlyRejectedRefs.has(clientTxRef);\n  }\n\n  // State persistence\n  getPersistedState(): PersistedHttpClientState {\n    return {\n      channelId: this.channelId,\n      pendingSubRAV: this.pendingSubRAV,\n      lastUpdated: new Date().toISOString(),\n    };\n  }\n\n  loadPersistedState(state: PersistedHttpClientState): void {\n    if (state.channelId) {\n      this.channelId = state.channelId;\n    }\n    if (state.pendingSubRAV && this.shouldAcceptSubRAV(state.pendingSubRAV)) {\n      this.pendingSubRAV = state.pendingSubRAV;\n    }\n    this.logger.debug('Persisted state loaded');\n  }\n\n  // Reset state\n  reset(): void {\n    this.channelId = undefined;\n    this.channelInfo = undefined;\n    this.subChannelInfo = undefined;\n    this.keyId = undefined;\n    this.vmIdFragment = undefined;\n    this.pendingSubRAV = undefined;\n    this.highestObservedNonce = undefined;\n    this.recentlyRejectedRefs.clear();\n    this.state.pendingPayments?.clear();\n    this.logger.debug('State reset');\n  }\n}\n","import type { SubRAV, SignedSubRAV } from '../../../core/types';\nimport type { PaymentRequestContext } from '../types';\nimport { HttpPaymentCodec } from '../internal/codec';\nimport { PaymentKitError } from '../../../errors';\nimport { DebugLogger } from '@nuwa-ai/identity-kit';\nimport { PaymentErrorCode } from '../../../errors/codes';\n\nexport interface PaymentHeaderData {\n  subRav?: SubRAV;\n  signedSubRav?: SignedSubRAV;\n  cost?: bigint;\n  costUsd?: bigint;\n  clientTxRef?: string;\n  serviceTxRef?: string;\n  error?: {\n    code: string;\n    message?: string;\n  };\n}\n\nexport type ProtocolResult =\n  | { type: 'none' }\n  | { type: 'error'; clientTxRef?: string; err: PaymentKitError }\n  | {\n      type: 'success';\n      clientTxRef?: string;\n      subRav: SubRAV;\n      cost: bigint;\n      costUsd?: bigint;\n      serviceTxRef?: string;\n    };\n\n/**\n * PaymentProtocol handles all protocol-specific logic including:\n * - SubRAV signing\n * - Header encoding/decoding\n * - Response parsing\n */\nexport class PaymentProtocol {\n  private logger: DebugLogger;\n  private codec: HttpPaymentCodec;\n\n  constructor() {\n    this.logger = DebugLogger.get('PaymentProtocol');\n    this.codec = new HttpPaymentCodec();\n  }\n\n  /**\n   * Encode payment header for requests\n   */\n  encodeRequestHeader(\n    signedSubRAV: SignedSubRAV | undefined,\n    clientTxRef: string,\n    maxAmount: bigint = BigInt(0)\n  ): string {\n    return this.codec.encodePayload({\n      signedSubRav: signedSubRAV,\n      maxAmount,\n      clientTxRef,\n      version: 1,\n    });\n  }\n\n  /**\n   * Parse payment header from response\n   */\n  parseResponseHeader(headerValue: string): PaymentHeaderData {\n    try {\n      return HttpPaymentCodec.parseResponseHeader(headerValue);\n    } catch (error) {\n      this.logger.debug('Failed to parse payment header:', error);\n      throw error;\n    }\n  }\n\n  /**\n   * Extract protocol information from response headers\n   */\n  parseProtocolFromResponse(response: Response, context?: PaymentRequestContext): ProtocolResult {\n    const headerName = HttpPaymentCodec.getHeaderName();\n    let paymentHeader = response.headers.get(headerName);\n\n    if (!paymentHeader) {\n      paymentHeader = response.headers.get(headerName.toLowerCase());\n    }\n\n    if (!paymentHeader) {\n      return { type: 'none' };\n    }\n\n    try {\n      const payload = this.parseResponseHeader(paymentHeader);\n\n      if (payload?.error) {\n        const code = payload.error.code;\n        const message = payload.error.message || response.statusText || 'Payment error';\n        return {\n          type: 'error',\n          clientTxRef: payload.clientTxRef || context?.clientTxRef,\n          err: new PaymentKitError(code, message, response.status),\n        };\n      }\n\n      if (payload?.subRav && payload.cost !== undefined) {\n        return {\n          type: 'success',\n          clientTxRef: payload.clientTxRef || context?.clientTxRef,\n          subRav: payload.subRav,\n          cost: payload.cost,\n          costUsd: payload.costUsd,\n          serviceTxRef: payload.serviceTxRef,\n        };\n      }\n\n      return { type: 'none' };\n    } catch (e) {\n      this.logger.debug('Failed to parse payment response header:', e);\n      return { type: 'none' };\n    }\n  }\n\n  /**\n   * Handle protocol errors based on HTTP status codes\n   */\n  handleStatusCode(status: number): PaymentKitError | null {\n    switch (status) {\n      case 402:\n        return new PaymentKitError(\n          PaymentErrorCode.PAYMENT_REQUIRED,\n          'Payment required - insufficient balance or invalid proposal',\n          402\n        );\n      case 409:\n        return new PaymentKitError(\n          PaymentErrorCode.RAV_CONFLICT,\n          'SubRAV conflict - cleared pending proposal',\n          409\n        );\n      default:\n        return null;\n    }\n  }\n\n  /**\n   * Get header name for payment protocol\n   */\n  getHeaderName(): string {\n    return HttpPaymentCodec.getHeaderName();\n  }\n}\n","import type { PendingPaymentRequest, PaymentRequestContext } from '../types';\nimport type { SignedSubRAV, PaymentInfo } from '../../../core/types';\nimport { DebugLogger } from '@nuwa-ai/identity-kit';\nimport { PaymentState } from './PaymentState';\n\nexport interface RequestTracker {\n  clientTxRef: string;\n  resolve: (info: PaymentInfo | undefined) => void;\n  reject: (error: Error) => void;\n  timeoutId: NodeJS.Timeout;\n  release?: () => void;\n}\n\n/**\n * RequestManager handles request tracking, timeouts, and payment resolution.\n */\nexport class RequestManager {\n  private logger: DebugLogger;\n  private paymentState: PaymentState;\n  private defaultTimeoutMs: number;\n  private traceOrigins = new Map<string, string>();\n\n  constructor(paymentState: PaymentState, defaultTimeoutMs: number = 30000) {\n    this.logger = DebugLogger.get('RequestManager');\n    this.paymentState = paymentState;\n    this.defaultTimeoutMs = defaultTimeoutMs;\n  }\n\n  /**\n   * Create a payment promise for tracking request payment info\n   */\n  createPaymentPromise(\n    clientTxRef: string,\n    requestContext: PaymentRequestContext,\n    sentedSubRav: SignedSubRAV | undefined,\n    channelId: string,\n    assetId: string,\n    timeoutMs?: number\n  ): Promise<PaymentInfo | undefined> {\n    return new Promise((resolve, reject) => {\n      const timeout = timeoutMs || this.defaultTimeoutMs;\n\n      // Set timeout for cleanup\n      const timeoutId = setTimeout(() => {\n        const pending = this.paymentState.getPendingPayment(clientTxRef);\n        if (pending) {\n          // Release scheduler queue if applicable\n          try {\n            pending.release?.();\n          } catch (e) {\n            this.logger.debug('[release.error]', e);\n          }\n          this.paymentState.removePendingPayment(clientTxRef);\n          this.logger.debug('[payment.timeout]', 'clientTxRef=', clientTxRef);\n          reject(new Error('Payment resolution timeout'));\n        }\n      }, timeout);\n\n      const pendingRequest: PendingPaymentRequest = {\n        resolve,\n        reject,\n        timestamp: new Date(),\n        channelId,\n        assetId,\n        timeoutId,\n        sendedSubRav: sentedSubRav,\n        requestContext,\n      };\n\n      this.paymentState.addPendingPayment(clientTxRef, pendingRequest);\n\n      this.logger.debug(\n        '[payment.pending.create]',\n        'clientTxRef=',\n        clientTxRef,\n        'channelId=',\n        channelId,\n        'signedSubRav=',\n        !!sentedSubRav\n      );\n    });\n  }\n\n  /**\n   * Extend timeout for a specific pending payment (used for streaming)\n   */\n  extendTimeout(clientTxRef: string, newTimeoutMs: number): void {\n    const pending = this.paymentState.getPendingPayment(clientTxRef);\n    if (!pending) return;\n\n    clearTimeout(pending.timeoutId);\n    pending.timeoutId = setTimeout(() => {\n      if (this.paymentState.getPendingPayment(clientTxRef)) {\n        try {\n          pending.release?.();\n        } catch (e) {\n          this.logger.debug('[release.error]', e);\n        }\n        this.paymentState.removePendingPayment(clientTxRef);\n        this.logger.debug('[payment.timeout.stream]', 'clientTxRef=', clientTxRef);\n        pending.reject(new Error('Payment resolution timeout'));\n      }\n    }, newTimeoutMs);\n\n    this.logger.debug('[payment.timeout.extend]', 'clientTxRef=', clientTxRef, 'ms=', newTimeoutMs);\n  }\n\n  /**\n   * Resolve a pending payment by reference\n   */\n  resolveByRef(clientTxRef: string, info: PaymentInfo | undefined): boolean {\n    const pending = this.paymentState.getPendingPayment(clientTxRef);\n    if (!pending) return false;\n\n    clearTimeout(pending.timeoutId);\n\n    // Always release scheduler when payment is resolved\n    // This matches the original implementation behavior\n    try {\n      pending.release?.();\n    } catch (e) {\n      this.logger.debug('[release.error]', e);\n    }\n    pending.resolve(info);\n    this.paymentState.removePendingPayment(clientTxRef);\n    this.clearTraceOrigin(clientTxRef);\n\n    this.logger.debug('[payment.pending.resolve]', 'clientTxRef=', clientTxRef);\n    return true;\n  }\n\n  /**\n   * Reject a pending payment by reference\n   */\n  rejectByRef(clientTxRef: string, err: Error): boolean {\n    const pending = this.paymentState.getPendingPayment(clientTxRef);\n    if (!pending) return false;\n\n    clearTimeout(pending.timeoutId);\n    try {\n      pending.release?.();\n    } catch (e) {\n      this.logger.debug('[release.error]', e);\n    }\n    pending.reject(err);\n    this.paymentState.removePendingPayment(clientTxRef);\n    this.paymentState.markAsRejected(clientTxRef);\n    this.clearTraceOrigin(clientTxRef);\n\n    this.logger.debug(\n      '[payment.pending.reject]',\n      'clientTxRef=',\n      clientTxRef,\n      'error=',\n      err.message\n    );\n    return true;\n  }\n\n  /**\n   * Reject all pending payments\n   */\n  rejectAll(err: Error): void {\n    const pendingPayments = this.paymentState.getAllPendingPayments();\n\n    for (const [key, pending] of pendingPayments.entries()) {\n      clearTimeout(pending.timeoutId);\n      try {\n        pending.release?.();\n      } catch (e) {\n        this.logger.debug('[release.error]', e);\n      }\n      try {\n        pending.reject(err);\n      } catch (e) {\n        this.logger.debug('[pending.reject.error]', e);\n      }\n    }\n\n    this.paymentState.clearAllPendingPayments();\n  }\n\n  /**\n   * Resolve all pending payments as free\n   */\n  resolveAllAsFree(): void {\n    const pendingPayments = this.paymentState.getAllPendingPayments();\n    const keys: string[] = [];\n\n    for (const [key, pending] of pendingPayments.entries()) {\n      clearTimeout(pending.timeoutId);\n      try {\n        pending.release?.();\n      } catch (e) {\n        this.logger.debug('[release.error]', e);\n      }\n      pending.resolve(undefined);\n      keys.push(key);\n    }\n\n    this.paymentState.clearAllPendingPayments();\n\n    if (keys.length > 0) {\n      this.logger.debug('[payment.pending.free]', 'resolved', keys.length, 'requests as free');\n    }\n  }\n\n  /**\n   * Get all pending payment keys\n   */\n  getPendingKeys(): string[] {\n    return Array.from(this.paymentState.getAllPendingPayments().keys());\n  }\n\n  /**\n   * Record trace origin for debugging\n   */\n  recordTraceOrigin(clientTxRef: string, origin: string): void {\n    this.traceOrigins.set(clientTxRef, origin);\n  }\n\n  /**\n   * Get trace origin for a client transaction reference\n   */\n  getTraceOrigin(clientTxRef: string): string | undefined {\n    return this.traceOrigins.get(clientTxRef);\n  }\n\n  /**\n   * Clear trace origin\n   */\n  clearTraceOrigin(clientTxRef: string): void {\n    this.traceOrigins.delete(clientTxRef);\n  }\n\n  /**\n   * Get trace origin snapshots for debugging\n   */\n  getTraceSnapshots(limit: number = 5): Array<{ key: string; head: string }> {\n    const snapshots: Array<{ key: string; head: string }> = [];\n\n    for (const [key, stack] of this.traceOrigins.entries()) {\n      snapshots.push({ key, head: stack.split('\\n')[0] });\n      if (snapshots.length >= limit) break;\n    }\n\n    return snapshots;\n  }\n}\n","import type { HostChannelMappingStore } from '../types';\nimport type { RecoveryResponse, DiscoveryResponse } from '../../../schema';\nimport { RecoveryResponseSchema } from '../../../schema';\nimport type { FetchLike } from '../types';\nimport { PaymentChannelPayerClient } from '../../../client/PaymentChannelPayerClient';\nimport { PaymentState } from './PaymentState';\nimport { DebugLogger } from '@nuwa-ai/identity-kit';\nimport { DidAuthHelper } from '../internal/DidAuthHelper';\nimport { serializeJson } from '../../../utils/json';\nimport type { SignedSubRAV } from '../../../core/types';\n\nexport interface ChannelManagerOptions {\n  host: string;\n  baseUrl: string;\n  payerClient: PaymentChannelPayerClient;\n  paymentState: PaymentState;\n  mappingStore: HostChannelMappingStore;\n  fetchImpl: FetchLike;\n  signer: any;\n  keyId?: string;\n  payerDid?: string;\n  payeeDid?: string;\n  defaultAssetId?: string;\n}\n\n/**\n * ChannelManager handles channel lifecycle operations including:\n * - Channel creation and restoration\n * - Service discovery\n * - Channel recovery\n * - SubRAV commits\n */\nexport class ChannelManager {\n  private logger: DebugLogger;\n  private options: ChannelManagerOptions;\n  private discoveredBasePath?: string;\n  private cachedDiscoveryInfo?: DiscoveryResponse;\n  private ensureReadyPromise?: Promise<void>;\n\n  constructor(options: ChannelManagerOptions) {\n    this.options = options;\n    this.logger = DebugLogger.get('ChannelManager');\n  }\n\n  /**\n   * Ensure channel is ready for use\n   */\n  async ensureChannelReady(): Promise<void> {\n    const channelId = this.options.paymentState.getChannelId();\n\n    if (channelId) {\n      this.logger.debug('Channel already ready:', channelId);\n      return;\n    }\n\n    if (!this.ensureReadyPromise) {\n      this.ensureReadyPromise = this.doEnsureChannelReady().finally(() => {\n        this.ensureReadyPromise = undefined;\n      });\n    }\n\n    await this.ensureReadyPromise;\n  }\n\n  private async doEnsureChannelReady(): Promise<void> {\n    // Try to load persisted state first\n    await this.loadPersistedState();\n\n    // If we still don't have a channel, initialize it\n    if (!this.options.paymentState.getChannelId()) {\n      await this.initializeChannel();\n    }\n  }\n\n  /**\n   * Initialize or restore payment channel\n   */\n  private async initializeChannel(): Promise<void> {\n    this.logger.debug('Initializing channel for host:', this.options.host);\n\n    try {\n      // First, try to recover existing channel from server\n      try {\n        const recoveryData = await this.recoverFromService();\n        if (recoveryData.channel) {\n          await this.applyRecovery(recoveryData, {\n            authorizeIfMissing: true,\n            requireVmFragment: true,\n          });\n          this.logger.debug(\n            'Recovered active channel from server:',\n            recoveryData.channel.channelId\n          );\n\n          // Update mapping store\n          await this.persistState();\n          return;\n        }\n      } catch (error) {\n        this.logger.debug('Server recovery failed, will create new channel:', error);\n      }\n\n      // Create new channel\n      await this.createNewChannel();\n    } catch (error) {\n      this.logger.error('Failed to initialize channel:', error);\n      throw error;\n    }\n  }\n\n  /**\n   * Create a new payment channel\n   */\n  private async createNewChannel(): Promise<void> {\n    const defaultAssetId = this.options.defaultAssetId || '0x3::gas_coin::RGas';\n\n    // Get payee DID from options or discover from service\n    let payeeDid = this.options.payeeDid;\n\n    if (!payeeDid) {\n      const serviceInfo = await this.discoverService();\n      payeeDid = serviceInfo.serviceDid;\n      this.logger.debug('Discovered payeeDid from service:', payeeDid);\n    }\n\n    const channelInfo = await this.options.payerClient.openChannelWithSubChannel({\n      payeeDid,\n      assetId: defaultAssetId,\n    });\n\n    this.options.paymentState.setChannelId(channelInfo.channelId);\n\n    try {\n      const fullChannelInfo = await this.options.payerClient.getChannelInfo(channelInfo.channelId);\n      this.options.paymentState.setChannelInfo(fullChannelInfo);\n\n      const vmIdFragment = this.options.paymentState.getVmIdFragment();\n      if (vmIdFragment) {\n        const subChannelInfo = await this.options.payerClient.getSubChannelInfo(\n          channelInfo.channelId,\n          vmIdFragment\n        );\n        this.options.paymentState.setSubChannelInfo(subChannelInfo);\n      }\n    } catch (e) {\n      this.logger.debug('Failed to get channel/subchannel info:', e);\n    }\n\n    await this.persistState();\n    this.logger.debug('Created new channel:', channelInfo.channelId);\n  }\n\n  /**\n   * Discover service information\n   */\n  async discoverService(): Promise<DiscoveryResponse> {\n    if (!this.cachedDiscoveryInfo) {\n      await this.performDiscovery();\n    }\n\n    if (this.cachedDiscoveryInfo) {\n      return this.cachedDiscoveryInfo;\n    }\n\n    throw new Error('Service discovery failed: No discovery information available');\n  }\n\n  private async performDiscovery(): Promise<void> {\n    const discoveryUrl = new URL('/.well-known/nuwa-payment/info', this.options.baseUrl);\n\n    try {\n      const response = await this.options.fetchImpl(discoveryUrl.toString(), {\n        method: 'GET',\n        headers: {\n          Accept: 'application/json',\n        },\n      });\n\n      if (response.ok) {\n        const serviceInfo = (await response.json()) as DiscoveryResponse;\n        this.logger.debug('Service discovery successful:', serviceInfo);\n\n        this.cachedDiscoveryInfo = serviceInfo;\n        if (serviceInfo.basePath) {\n          this.discoveredBasePath = serviceInfo.basePath;\n        }\n      }\n    } catch (error) {\n      this.logger.debug('Service discovery failed:', error);\n    }\n\n    // Set fallback basePath\n    if (!this.discoveredBasePath) {\n      this.discoveredBasePath = '/payment-channel';\n    }\n  }\n\n  /**\n   * Recover channel state from service\n   */\n  async recoverFromService(): Promise<RecoveryResponse> {\n    const recoveryUrl = this.buildPaymentUrl('/recovery');\n\n    try {\n      const payerDid = this.options.payerDid || (await this.options.signer.getDid());\n      const authHeader = await DidAuthHelper.generateAuthHeader(\n        payerDid,\n        this.options.signer,\n        recoveryUrl,\n        'GET',\n        this.options.keyId\n      );\n\n      const headers: Record<string, string> = {\n        Accept: 'application/json',\n      };\n\n      if (authHeader) {\n        headers['Authorization'] = authHeader;\n      }\n\n      const response = await this.options.fetchImpl(recoveryUrl, {\n        method: 'GET',\n        headers,\n      });\n\n      if (!response.ok) {\n        throw new Error(`Failed to recover from service: HTTP ${response.status}`);\n      }\n\n      const jsonData = await response.json();\n\n      // Log the raw response for debugging\n      this.logger.debug('Raw recovery response:', serializeJson(jsonData));\n\n      // Check if response is in ApiResponse format\n      let dataToValidate = jsonData;\n      if (jsonData && typeof jsonData === 'object' && 'success' in jsonData) {\n        if (jsonData.success && 'data' in jsonData) {\n          dataToValidate = jsonData.data;\n        } else if (!jsonData.success) {\n          const error = jsonData.error || {};\n          throw new Error(error.message || 'Recovery request failed');\n        }\n      }\n\n      try {\n        const recoveryData = RecoveryResponseSchema.parse(dataToValidate);\n        this.logger.debug('Recovery completed successfully');\n        return recoveryData;\n      } catch (parseError) {\n        // If parsing fails, log the error and return the raw data\n        // This maintains backward compatibility\n        this.logger.debug('Recovery response parsing failed:', parseError);\n        this.logger.debug('Returning raw recovery data');\n        return dataToValidate as RecoveryResponse;\n      }\n    } catch (error) {\n      const errorMessage = `Recovery failed: ${error instanceof Error ? error.message : String(error)}`;\n      this.logger.debug(errorMessage);\n      throw new Error(errorMessage);\n    }\n  }\n\n  /**\n   * Apply recovery response to client state\n   */\n  private async applyRecovery(\n    recovery: RecoveryResponse,\n    options?: { authorizeIfMissing?: boolean; requireVmFragment?: boolean }\n  ): Promise<void> {\n    // Update channel info\n    if (recovery.channel) {\n      this.options.paymentState.setChannelId(recovery.channel.channelId);\n\n      try {\n        const channelInfo = await this.options.payerClient.getChannelInfo(\n          recovery.channel.channelId\n        );\n        this.options.paymentState.setChannelInfo(channelInfo);\n      } catch (e) {\n        this.logger.debug('GetChannelInfo failed during recovery:', e);\n      }\n    }\n\n    // Accept pending proposal\n    if (recovery.pendingSubRav) {\n      this.options.paymentState.setPendingSubRAV(recovery.pendingSubRav);\n    }\n\n    // Handle sub-channel authorization if needed\n    if (options?.authorizeIfMissing && recovery.channel) {\n      await this.ensureSubChannelAuthorized(recovery, options.requireVmFragment);\n    }\n  }\n\n  private async ensureSubChannelAuthorized(\n    recovery: RecoveryResponse,\n    requireVmFragment?: boolean\n  ): Promise<void> {\n    const channelId = this.options.paymentState.getChannelId();\n    if (!channelId) return;\n\n    let vmIdFragment =\n      recovery.subChannel?.vmIdFragment || this.options.paymentState.getVmIdFragment();\n\n    if (!vmIdFragment && requireVmFragment) {\n      if (this.options.keyId) {\n        const parts = this.options.keyId.split('#');\n        vmIdFragment = parts.length > 1 ? parts[1] : '';\n      }\n      if (!vmIdFragment) {\n        throw new Error(\n          'Recovered channel but sub-channel cannot be authorized: missing vmIdFragment.'\n        );\n      }\n    }\n\n    if (vmIdFragment && !recovery.subChannel) {\n      try {\n        await this.options.payerClient.authorizeSubChannel({\n          channelId,\n          vmIdFragment,\n        });\n        await this.waitForSubChannelAuthorization(channelId, vmIdFragment);\n\n        const subChannelInfo = await this.options.payerClient.getSubChannelInfo(\n          channelId,\n          vmIdFragment\n        );\n        this.options.paymentState.setSubChannelInfo(subChannelInfo);\n      } catch (e) {\n        this.logger.debug('Sub-channel authorization failed during recovery:', e);\n      }\n    }\n  }\n\n  /**\n   * Wait for sub-channel authorization to be visible on-chain\n   */\n  private async waitForSubChannelAuthorization(\n    channelId: string,\n    vmIdFragment: string,\n    attempts: number = 10,\n    delayMs: number = 500\n  ): Promise<void> {\n    for (let i = 0; i < attempts; i++) {\n      try {\n        await this.options.payerClient.getSubChannelInfo(channelId, vmIdFragment);\n        this.logger.debug('Sub-channel visible on-chain:', vmIdFragment);\n        return;\n      } catch {\n        await new Promise(resolve => setTimeout(resolve, delayMs));\n      }\n    }\n    throw new Error('Sub-channel authorization not visible on-chain within timeout');\n  }\n\n  /**\n   * Commit a signed SubRAV to the service\n   */\n  async commitSubRAV(signedSubRAV: SignedSubRAV): Promise<void> {\n    const commitUrl = this.buildPaymentUrl('/commit');\n\n    try {\n      const payerDid = this.options.payerDid || (await this.options.signer.getDid());\n      const authHeader = await DidAuthHelper.generateAuthHeader(\n        payerDid,\n        this.options.signer,\n        commitUrl,\n        'POST',\n        this.options.keyId\n      );\n\n      const headers: Record<string, string> = {\n        Accept: 'application/json',\n        'Content-Type': 'application/json',\n      };\n\n      if (authHeader) {\n        headers['Authorization'] = authHeader;\n      }\n\n      const response = await this.options.fetchImpl(commitUrl, {\n        method: 'POST',\n        headers,\n        body: serializeJson({ subRav: signedSubRAV }),\n      });\n\n      if (!response.ok) {\n        const errorBody = await response.text();\n        throw new Error(`Failed to commit SubRAV: HTTP ${response.status} - ${errorBody}`);\n      }\n\n      this.logger.debug('SubRAV committed successfully');\n    } catch (error) {\n      const errorMessage = `SubRAV commit failed: ${error instanceof Error ? error.message : String(error)}`;\n      this.logger.debug(errorMessage);\n      throw new Error(errorMessage);\n    }\n  }\n\n  /**\n   * Load persisted state from storage\n   */\n  private async loadPersistedState(): Promise<void> {\n    try {\n      const persistedState = await this.options.mappingStore.getState(this.options.host);\n      if (persistedState) {\n        this.options.paymentState.loadPersistedState(persistedState);\n        this.logger.debug('Loaded persisted state');\n      }\n    } catch (error) {\n      this.logger.debug('Failed to load persisted state:', error);\n    }\n  }\n\n  /**\n   * Persist current state to storage\n   */\n  private async persistState(): Promise<void> {\n    try {\n      const state = this.options.paymentState.getPersistedState();\n      await this.options.mappingStore.setState(this.options.host, state);\n      this.logger.debug('Persisted state');\n    } catch (error) {\n      this.logger.debug('Failed to persist state:', error);\n    }\n  }\n\n  /**\n   * Build URL for payment-related endpoints\n   */\n  buildPaymentUrl(endpoint: string): string {\n    const basePath = this.discoveredBasePath || '/payment-channel';\n    return new URL(`${basePath}${endpoint}`, this.options.baseUrl).toString();\n  }\n\n  /**\n   * Get the discovered base path\n   */\n  getBasePath(): string {\n    return this.discoveredBasePath || '/payment-channel';\n  }\n}\n","import type {\n  HealthResponse,\n  SystemStatusResponse,\n  ClaimTriggerRequest,\n  ClaimTriggerResponse,\n  SubRavRequest,\n  SubRavResponse,\n} from '../../schema';\nimport { PaymentChannelHttpClient } from './PaymentChannelHttpClient';\n\n/**\n * PaymentChannelAdminClient provides a simplified interface for calling\n * Payment Kit admin endpoints.\n *\n * This is a lightweight wrapper around PaymentChannelHttpClient that\n * provides type-safe admin API calls without the complexity of payment\n * channel management.\n *\n * Features:\n * - Type-safe admin API calls\n * - Reuses existing PaymentChannelHttpClient functionality\n * - No additional setup required\n */\nexport class PaymentChannelAdminClient {\n  private httpClient: PaymentChannelHttpClient;\n\n  constructor(httpClient: PaymentChannelHttpClient) {\n    this.httpClient = httpClient;\n  }\n\n  /**\n   * Build URL for payment-related endpoints (internal use)\n   */\n  private buildPaymentUrl(endpoint: string): string {\n    // Use the public buildPaymentUrl method\n    return this.httpClient.buildPaymentUrl(endpoint);\n  }\n\n  /**\n   * Health check endpoint (public, no auth required)\n   */\n  async healthCheck(): Promise<HealthResponse> {\n    return this.httpClient.healthCheck();\n  }\n\n  /**\n   * Get system internal status (admin only)\n   */\n  async getSystemStatus(): Promise<SystemStatusResponse> {\n    const result = await this.httpClient.get<SystemStatusResponse>(\n      this.buildPaymentUrl('/admin/status')\n    );\n    return result.data;\n  }\n\n  /**\n   * Manually trigger a claim for a specific channel (admin only)\n   */\n  async triggerClaim(request: ClaimTriggerRequest): Promise<ClaimTriggerResponse> {\n    const result = await this.httpClient.post<ClaimTriggerResponse>(\n      this.buildPaymentUrl('/admin/claim-trigger'),\n      request\n    );\n    return result.data;\n  }\n\n  /**\n   * Query SubRAV details (requires auth, users can only query their own)\n   */\n  async querySubRav(request: SubRavRequest): Promise<SubRavResponse> {\n    const queryPath = `/subrav?nonce=${encodeURIComponent(request.nonce)}`;\n    const result = await this.httpClient.get<SubRavResponse>(this.buildPaymentUrl(queryPath));\n    return result.data;\n  }\n\n  /**\n   * Discover service information\n   */\n  async discoverService(): Promise<any> {\n    return this.httpClient.discoverService();\n  }\n}\n\n/**\n * Create an admin client from an existing PaymentChannelHttpClient\n */\nexport function createAdminClient(httpClient: PaymentChannelHttpClient): PaymentChannelAdminClient {\n  return new PaymentChannelAdminClient(httpClient);\n}\n","/**\n * Core helper functions for IdentityEnv integration\n *\n * This module provides the shared utility function to extract chain configuration\n * from IdentityEnv instances. Specific integration functions are located in their\n * respective modules for better discoverability:\n *\n * - createHttpClientFromEnv: integrations/http/fromIdentityEnv\n * - createExpressPaymentKitFromEnv: transport/express/fromIdentityEnv\n */\n\nimport type { IdentityEnv } from '@nuwa-ai/identity-kit';\nimport { ChainConfig } from '../factory/chainFactory';\n\n/**\n * Extract ChainConfig from IdentityEnv's registered VDRs\n *\n * @param env IdentityEnv instance with registered VDRs\n * @returns ChainConfig for payment channel operations\n * @throws Error if no supported VDR is found\n */\nexport function getChainConfigFromEnv(env: IdentityEnv): ChainConfig {\n  const roochVdr = env.registry.getVDR('rooch');\n\n  if (!roochVdr) {\n    throw new Error(\n      'RoochVDR not registered in IdentityEnv. Please ensure bootstrapIdentityEnv was called with method=\"rooch\" or useVDR(\"rooch\") was called.'\n    );\n  }\n\n  // Access the options from RoochVDR instance\n  // Note: This assumes RoochVDR has an 'options' property with the configuration\n  const vdrOptions = (roochVdr as any).options || {};\n\n  return {\n    chain: 'rooch' as const,\n    rpcUrl: vdrOptions.rpcUrl,\n    network: vdrOptions.network || 'test',\n    debug: vdrOptions.debug || false,\n  };\n}\n","import type { SignerInterface, IdentityEnv } from '@nuwa-ai/identity-kit';\nimport type { HttpPayerOptions } from './types';\nimport { PaymentChannelHttpClient } from './PaymentChannelHttpClient';\nimport { getChainConfigFromEnv } from '../../helpers/fromIdentityEnv';\n\n/**\n * Simple options for creating PaymentChannelHttpClient with IdentityEnv (recommended)\n */\nexport interface CreateHttpClientOptions {\n  /** Target service base URL, e.g., https://api.example.com */\n  baseUrl: string;\n\n  /** Pre-configured IdentityEnv (contains VDR registry, KeyManager, and chain config) */\n  env: IdentityEnv;\n\n  /** Optional maximum amount per request (defaults to 50 cents USD) */\n  maxAmount?: bigint;\n\n  /** Optional debug mode (inherits from IdentityEnv if not specified) */\n  debug?: boolean;\n\n  /** Optional error handler */\n  onError?: (err: unknown) => void;\n\n  /** Optional custom fetch implementation */\n  fetchImpl?: HttpPayerOptions['fetchImpl'];\n\n  /** Optional mapping store */\n  mappingStore?: HttpPayerOptions['mappingStore'];\n\n  /** Optional channel repository */\n  channelRepo?: HttpPayerOptions['channelRepo'];\n\n  /** Timeout for pending payment resolution in milliseconds (non-streaming). */\n  timeoutMs?: number;\n\n  /** Per-frame idle timeout for streaming responses; defaults to timeoutMs if unspecified. */\n  timeoutMsStream?: number;\n}\n\n/**\n * Advanced options for creating PaymentChannelHttpClient with manual configuration\n * Most users should prefer CreateHttpClientOptions with IdentityEnv\n */\nexport interface CreateHttpPayerClientOptions {\n  /** Target service base URL, e.g., https://api.example.com */\n  baseUrl: string;\n\n  /** Signer for payment channel operations and DID authentication */\n  signer: SignerInterface;\n\n  /** Optional key ID (defaults to first available) */\n  keyId?: string;\n\n  /** Optional RPC URL (defaults to localhost) */\n  rpcUrl?: string;\n\n  /** Optional network (defaults to 'local') */\n  network?: 'local' | 'dev' | 'test' | 'main';\n\n  /** Optional DID (will be derived from signer if not provided) */\n  payerDid?: string;\n\n  /** Optional maximum amount per request */\n  maxAmount?: bigint;\n\n  /** Optional debug mode */\n  debug?: boolean;\n\n  /** Optional error handler */\n  onError?: (err: unknown) => void;\n\n  /** Optional custom fetch implementation */\n  fetchImpl?: HttpPayerOptions['fetchImpl'];\n\n  /** Optional mapping store */\n  mappingStore?: HttpPayerOptions['mappingStore'];\n}\n\n/**\n * Create PaymentChannelHttpClient with IdentityEnv (recommended approach)\n * Automatically performs service discovery and uses optimal defaults\n *\n * @param options - Simple configuration options with IdentityEnv\n * @returns Promise resolving to configured PaymentChannelHttpClient instance\n *\n * @example\n * ```typescript\n * import { bootstrapIdentityEnv, createHttpClient } from '@nuwa-ai/payment-kit';\n *\n * // 1. Set up identity environment (once per app)\n * const env = await bootstrapIdentityEnv({\n *   method: 'rooch',\n *   vdrOptions: { rpcUrl: 'https://testnet.rooch.network', network: 'test' }\n * });\n *\n * // 2. Create HTTP client with automatic service discovery\n * const client = await createHttpClient({\n *   baseUrl: 'https://api.llm-gateway.com',\n *   env,\n *   maxAmount: BigInt('500000000000'), // 50 cents USD\n * });\n *\n * // 3. Use it!\n * const result = await client.get('/v1/echo?q=hello');\n * ```\n */\nexport async function createHttpClient(\n  options: CreateHttpClientOptions\n): Promise<PaymentChannelHttpClient> {\n  const chainConfig = getChainConfigFromEnv(options.env);\n\n  const httpPayerOptions: HttpPayerOptions = {\n    baseUrl: options.baseUrl,\n    chainConfig,\n    signer: options.env.keyManager,\n    // keyId will be set dynamically below if not provided\n    maxAmount: options.maxAmount || BigInt('500000000000'), // Default: 50 cents USD\n    debug: options.debug ?? chainConfig.debug,\n    onError: options.onError,\n    fetchImpl: options.fetchImpl,\n    mappingStore: options.mappingStore,\n    channelRepo: options.channelRepo,\n    timeoutMs: options.timeoutMs,\n    timeoutMsStream: options.timeoutMsStream,\n  };\n\n  // If caller did not explicitly provide a keyId, pick the first available from the KeyManager\n  try {\n    if (!httpPayerOptions.keyId) {\n      const keyIds = await options.env.keyManager.listKeyIds?.();\n      if (keyIds && keyIds.length > 0) {\n        httpPayerOptions.keyId = keyIds[0];\n      }\n    }\n  } catch {\n    // If we cannot resolve a keyId automatically, continue without it – the downstream\n    // code will throw a clear error so that the caller can address the issue.\n  }\n\n  const client = new PaymentChannelHttpClient(httpPayerOptions);\n\n  // Automatically perform service discovery\n  try {\n    const serviceInfo = await client.discoverService();\n    // Optional debug handled by client's logger\n  } catch (error) {\n    // Client will retry when needed\n    // Continue anyway - the client will attempt discovery again when needed\n  }\n\n  return client;\n}\n","/**\n * Utility functions for Payment Kit\n */\n\nexport * from './bigint';\nexport * from './json';\n\n// Import and re-export existing utils from other modules\nexport { DebugLogger } from '@nuwa-ai/identity-kit';\n\n/**\n * Generate a random nonce for SubRAV\n */\nexport function generateNonce(): bigint {\n  return BigInt(Date.now()) * BigInt(1000) + BigInt(Math.floor(Math.random() * 1000));\n}\n\n/**\n * Extract fragment from DID keyId\n * Example: 'did:rooch:0x123#test-key' -> 'test-key'\n */\nexport function extractFragment(keyId: string): string {\n  const hashIndex = keyId.indexOf('#');\n  if (hashIndex === -1) {\n    throw new Error(`No fragment found in keyId: ${keyId}`);\n  }\n  return keyId.substring(hashIndex + 1);\n}\n\n/**\n * Validate hex string format\n */\nexport function isValidHex(hex: string, expectedLength?: number): boolean {\n  if (!hex || typeof hex !== 'string') {\n    return false;\n  }\n\n  if (!hex.startsWith('0x')) {\n    return false;\n  }\n\n  const hexPart = hex.substring(2);\n\n  // Check if it contains only valid hex characters\n  if (!/^[0-9a-fA-F]*$/.test(hexPart)) {\n    return false;\n  }\n\n  // Check expected length if provided\n  if (expectedLength !== undefined && hexPart.length !== expectedLength) {\n    return false;\n  }\n\n  return true;\n}\n\n/**\n * Format amount for display with decimals\n */\nexport function formatAmount(amount: bigint, decimals: number = 18): string {\n  const divisor = BigInt(10 ** decimals);\n  const whole = amount / divisor;\n  const remainder = amount % divisor;\n\n  if (remainder === 0n) {\n    return whole.toString();\n  }\n\n  const remainderStr = remainder.toString().padStart(decimals, '0');\n  return `${whole}.${remainderStr.replace(/0+$/, '')}`;\n}\n\n/**\n * Generate a channel ID (placeholder implementation)\n */\nexport function generateChannelId(): string {\n  return `0x${Math.random().toString(16).substring(2).padStart(64, '0')}`;\n}\n\n/**\n * Convert BigInt to string\n */\nexport function bigintToString(value: bigint): string {\n  return value.toString();\n}\n\n/**\n * Convert string to BigInt\n */\nexport function stringToBigint(value: string): bigint {\n  return BigInt(value);\n}\n\n/**\n * Format picoUSD amount to human-readable USD string\n * @param picoUsd Amount in picoUSD (1 USD = 1,000,000,000,000 picoUSD)\n * @returns Formatted USD string (e.g., \"$0.0123\")\n */\nexport function formatUsdAmount(picoUsd: bigint, maxFractionDigits: number = 12): string {\n  // 1 USD = 1,000,000,000,000 picoUSD\n  const divisor = 1_000_000_000_000n;\n  const whole = picoUsd / divisor;\n  const remainder = picoUsd % divisor;\n  // Ensure bounds for fraction digits\n  const digits = Math.max(0, Math.min(12, Math.floor(maxFractionDigits)));\n  // Format remainder as a 12-digit string, optionally truncate for max fraction digits (default 12)\n  const fullRemainderStr = remainder.toString().padStart(12, '0');\n  const usedRemainder = digits === 12 ? fullRemainderStr : fullRemainderStr.slice(0, digits);\n  // Remove trailing zeros; if all zeros, show a single zero\n  const fractional = usedRemainder.replace(/0+$/, '') || '0';\n  return `$${whole.toString()}.${fractional}`;\n}\n","import express, { Router, RequestHandler } from 'express';\nimport { findRule as coreFindRule } from '../../billing/core/rule-matcher';\nimport type { BillingRule, StrategyConfig, RuleProvider } from '../../billing';\n\n/**\n * Route options for registering routes with billing\n */\nexport interface RouteOptions {\n  /**\n   * Pricing strategy.\n   * 0 / '0' means free (skip billing logic)\n   */\n  pricing: bigint | string | StrategyConfig;\n\n  /**\n   * Whether DID authentication is required.\n   * Default rules:\n   *   pricing == 0  → false\n   *   pricing  > 0  → true\n   * If developer explicitly sets false with pricing>0, framework will throw error during startup.\n   */\n  authRequired?: boolean;\n\n  /**\n   * Whether admin authorization is required (implies authRequired: true).\n   * Admin routes require both DID authentication and admin permission check.\n   */\n  adminOnly?: boolean;\n\n  /**\n   * Whether this route produces streaming responses (SSE/NDJSON/chunked).\n   * If true, settlement header will not be written pre-body; provider should settle on finish.\n   */\n  streaming?: boolean;\n}\n\n/**\n * Options when creating a BillableRouter\n */\nexport interface BillableRouterOptions {\n  /** Service identifier used in billing config */\n  serviceId: string;\n  /** Default price (picoUSD) when no rule matches. Optional */\n  defaultPricePicoUSD?: bigint | string;\n  /** Config version – defaults to 1 */\n  version?: number;\n}\n\n/**\n * BillableRouter helps you declare Express routes and their pricing in one place.\n *\n */\nexport class BillableRouter implements RuleProvider {\n  /** The underlying Express Router you should mount into your app */\n  public readonly router: Router;\n  /** Collected billing rules */\n  private readonly rules: BillingRule[] = [];\n  private readonly opts: BillableRouterOptions;\n\n  constructor(opts: BillableRouterOptions) {\n    this.opts = { version: 1, ...opts };\n    this.router = express.Router();\n\n    // Add default rule if provided\n    if (opts.defaultPricePicoUSD !== undefined) {\n      const pricing =\n        typeof opts.defaultPricePicoUSD === 'string'\n          ? BigInt(opts.defaultPricePicoUSD)\n          : opts.defaultPricePicoUSD;\n      const authRequired = pricing > 0n;\n      const paymentRequired = pricing > 0n;\n\n      this.rules.push({\n        id: 'default-pricing',\n        default: true,\n        strategy: {\n          type: 'PerRequest',\n          price: opts.defaultPricePicoUSD.toString(),\n        },\n        authRequired,\n        adminOnly: false,\n        paymentRequired,\n      });\n    }\n  }\n\n  // ---------------------------------------------------------------------\n  // Public helpers for HTTP verbs\n  // ---------------------------------------------------------------------\n\n  get(\n    path: string,\n    options: RouteOptions | bigint | string | StrategyConfig,\n    handler: RequestHandler,\n    id?: string\n  ) {\n    return this.register('get', path, options, handler, id);\n  }\n\n  post(\n    path: string,\n    options: RouteOptions | bigint | string | StrategyConfig,\n    handler: RequestHandler,\n    id?: string\n  ) {\n    return this.register('post', path, options, handler, id);\n  }\n\n  put(\n    path: string,\n    options: RouteOptions | bigint | string | StrategyConfig,\n    handler: RequestHandler,\n    id?: string\n  ) {\n    return this.register('put', path, options, handler, id);\n  }\n\n  delete(\n    path: string,\n    options: RouteOptions | bigint | string | StrategyConfig,\n    handler: RequestHandler,\n    id?: string\n  ) {\n    return this.register('delete', path, options, handler, id);\n  }\n\n  patch(\n    path: string,\n    options: RouteOptions | bigint | string | StrategyConfig,\n    handler: RequestHandler,\n    id?: string\n  ) {\n    return this.register('patch', path, options, handler, id);\n  }\n\n  /**\n   * Access the collected billing rules (mainly for testing)\n   */\n  getRules(): BillingRule[] {\n    return [...this.rules];\n  }\n\n  /**\n   * Find a billing rule that matches the given HTTP method + path using the\n   * shared core rule-matcher (single source of truth).\n   */\n  findRule(method: string, path: string): BillingRule | undefined {\n    return coreFindRule({ method: method.toUpperCase(), path }, this.rules);\n  }\n\n  // ---------------------------------------------------------------------\n  // Internal helper to collect rule + register to Express\n  // ---------------------------------------------------------------------\n  private register(\n    method: string,\n    path: string,\n    options: RouteOptions | bigint | string | StrategyConfig,\n    handler: RequestHandler,\n    id?: string\n  ) {\n    // Route registration\n\n    // Normalize options to RouteOptions\n    let routeOptions: RouteOptions;\n    if (typeof options === 'object' && 'pricing' in options) {\n      // It's already RouteOptions\n      routeOptions = options as RouteOptions;\n    } else {\n      // Legacy usage: pricing only (bigint, string, or StrategyConfig)\n      routeOptions = { pricing: options as bigint | string | StrategyConfig };\n    }\n\n    // Determine strategy config\n    let strategy: StrategyConfig;\n    if (typeof routeOptions.pricing === 'object' && 'type' in routeOptions.pricing) {\n      // It's already a strategy config\n      strategy = routeOptions.pricing;\n    } else {\n      // It's a fixed price, create PerRequest strategy\n      strategy = {\n        type: 'PerRequest',\n        price: routeOptions.pricing.toString(),\n      };\n    }\n\n    // Validate and determine auth and payment requirements\n    const adminOnly = routeOptions.adminOnly || false;\n    let authRequired = routeOptions.authRequired;\n\n    // Validation: adminOnly implies authRequired\n    if (adminOnly && authRequired === false) {\n      throw new Error(\n        `Route ${method.toUpperCase()} ${path}: adminOnly requires authRequired to be true or undefined`\n      );\n    }\n\n    // Auto-determine payment requirement based on pricing strategy\n    const pricing =\n      typeof routeOptions.pricing === 'string'\n        ? BigInt(routeOptions.pricing)\n        : routeOptions.pricing;\n    let paymentRequired: boolean;\n    if (typeof pricing === 'bigint') {\n      // Fixed price: only require payment if price > 0\n      paymentRequired = pricing > 0n;\n    } else {\n      // Dynamic strategy: always require payment\n      paymentRequired = true;\n    }\n\n    // Determine final auth requirement\n    if (authRequired === undefined) {\n      if (adminOnly) {\n        // Admin routes always require auth\n        authRequired = true;\n      } else {\n        // Default behavior: payment requires auth\n        if (paymentRequired) {\n          authRequired = true;\n        } else {\n          // Free endpoints don't require auth by default\n          authRequired = false;\n        }\n      }\n    }\n\n    // Collect billing rule\n    const rule: BillingRule = {\n      id: id || `${method}:${path}`,\n      when: {\n        path,\n        method: method.toUpperCase(),\n      },\n      strategy,\n      authRequired,\n      adminOnly,\n      paymentRequired,\n    };\n\n    // Rule created\n\n    // Insert rule with proper ordering:\n    // 1. Specific rules (non-default) should be added in registration order\n    // 2. Default rules should always be at the end\n    if (rule.default) {\n      // Keep default pricing rule at the end\n      // Keep default rule at end\n      this.rules.push(rule);\n    } else {\n      // Find the position to insert: before the first default rule, or at the end\n      const firstDefaultIndex = this.rules.findIndex(r => r.default);\n      if (firstDefaultIndex >= 0) {\n        // Insert before the first default rule\n        // Insert before default\n        this.rules.splice(firstDefaultIndex, 0, rule);\n      } else {\n        // No default rules yet, add to the end\n        // Add to end\n        this.rules.push(rule);\n      }\n    }\n\n    // Registration done\n\n    // Delegate to Express Router\n    (this.router as any)[method](path, handler);\n    return this;\n  }\n}\n\n// Re-export express so consumers don’t have to import twice\nexport { express as _express };\n","import { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type { Handler, ApiContext } from '../../types/api';\nimport { toApiError, createErrorResponse } from '../../errors';\nimport { sendJsonResponse } from '../../utils/json';\n\n/**\n * Prepare request data from Express Request object\n * Extracted from PaymentKitExpressAdapter for reuse\n */\nfunction prepareRequestData(req: Request): any {\n  let baseData: any = {};\n\n  // Extract from URL parameters\n  if (req.params && Object.keys(req.params).length > 0) {\n    baseData = { ...baseData, ...req.params };\n  }\n\n  // Extract from query parameters\n  if (req.query && Object.keys(req.query).length > 0) {\n    baseData = { ...baseData, ...req.query };\n  }\n\n  // Extract from request body\n  if (req.body && Object.keys(req.body).length > 0) {\n    baseData = { ...baseData, ...req.body };\n  }\n\n  // Add DID info if available (set by auth middleware)\n  if ((req as any).didInfo) {\n    baseData.didInfo = (req as any).didInfo;\n  }\n\n  return baseData;\n}\n\n/**\n * Convert PaymentKit Handler to Express RequestHandler\n * This adapter bridges the gap between PaymentKit's abstract Handler interface\n * and Express's concrete RequestHandler interface\n */\nexport function toExpressHandler<Ctx extends ApiContext, Req, Res>(\n  ctx: Ctx,\n  handler: Handler<Ctx, Req, Res>\n): RequestHandler {\n  return async (req: Request, res: Response, next: NextFunction) => {\n    try {\n      // Prepare request data from Express request\n      const requestData = prepareRequestData(req);\n\n      // Execute PaymentKit handler with proper context and data\n      const result = await handler(ctx, requestData as unknown as Req);\n\n      // Send JSON response using unified utility\n      sendJsonResponse(res, result);\n    } catch (error) {\n      // Convert to API error and pass to Express error handler\n      const apiError = toApiError(error);\n      const errorResponse = createErrorResponse(apiError);\n\n      res.status(apiError.httpStatus || 500);\n      sendJsonResponse(res, errorResponse);\n    }\n  };\n}\n\n/**\n * Options for registering handlers with BillableRouter\n */\nexport interface RegisterHandlersOptions {\n  /** Path prefix to add to all handler paths (e.g. '/payment-channel') */\n  pathPrefix?: string;\n}\n\n/**\n * Register PaymentKit handlers directly with BillableRouter\n * This eliminates the need for dummyHandler and separate routing layers\n */\nexport function registerHandlersWithBillableRouter(\n  handlerConfigs: Record<string, any>,\n  context: ApiContext,\n  billableRouter: any,\n  options?: RegisterHandlersOptions\n): void {\n  const prefix = options?.pathPrefix?.replace(/\\/$/, '') ?? '';\n\n  Object.entries(handlerConfigs).forEach(([handlerName, config]) => {\n    // Now handlerName is a semantic name (e.g., 'recovery', 'commit')\n    // and path is a property of config\n    const { method, path, options: routeOptions, handler } = config;\n\n    // Skip handlers without path (they're not REST endpoints)\n    if (!path) {\n      return;\n    }\n\n    // Build full path with prefix\n    const fullPath = prefix ? `${prefix}/${path.replace(/^\\//, '')}` : path;\n\n    // Convert PaymentKit Handler to Express RequestHandler\n    const expressHandler = toExpressHandler(context, handler);\n\n    // Get the HTTP method in lowercase for BillableRouter\n    const httpMethod = method || 'GET'; // Default to GET if not specified\n    const methodName = httpMethod.toLowerCase() as 'get' | 'post' | 'put' | 'delete' | 'patch';\n\n    // Validate method is supported\n    if (!billableRouter[methodName]) {\n      throw new Error(`Unsupported HTTP method: ${httpMethod}`);\n    }\n\n    // Register directly with BillableRouter using the public API\n    // Use handlerName as ruleId for clearer billing rule identification\n    billableRouter[methodName](fullPath, routeOptions, expressHandler, handlerName);\n\n    // Registered successfully\n  });\n}\n","import express, { Router, RequestHandler, Request, Response, NextFunction } from 'express';\nimport onHeaders from 'on-headers';\nimport { BillableRouter, RouteOptions } from './BillableRouter';\nimport { registerHandlersWithBillableRouter } from './HandlerRestAdapter';\nimport {\n  HttpBillingMiddleware,\n  ResponseAdapter,\n} from '../../middlewares/http/HttpBillingMiddleware';\nimport { RateProvider } from '../../billing';\nimport { ContractRateProvider } from '../../billing/rate/contract';\nimport { PaymentChannelPayeeClient } from '../../client/PaymentChannelPayeeClient';\nimport { RoochPaymentChannelContract } from '../../rooch/RoochPaymentChannelContract';\nimport {\n  createStorageRepositories,\n  type ChannelRepository,\n  type PendingSubRAVRepository,\n  type RAVRepository,\n} from '../../storage';\n// Removed legacy ClaimScheduler in favor of reactive ClaimTriggerService\nimport { DIDAuth, VDRRegistry, RoochVDR } from '@nuwa-ai/identity-kit';\nimport type { SignerInterface, DIDResolver } from '@nuwa-ai/identity-kit';\nimport { DebugLogger } from '@nuwa-ai/identity-kit';\nimport type { IPaymentChannelContract } from '../../contracts/IPaymentChannelContract';\nimport { BuiltInApiHandlers } from '../../api';\nimport type { ApiContext } from '../../types/api';\nimport { HttpPaymentCodec } from '../../middlewares/http/HttpPaymentCodec';\nimport { httpStatusFor, PaymentErrorCode } from '../../errors/codes';\nimport { registerBuiltinStrategies } from '../../billing/strategies';\nimport { PaymentProcessor } from '../../core/PaymentProcessor';\nimport { HubBalanceService, type HubBalanceServiceOptions } from '../../core/HubBalanceService';\nimport { ClaimTriggerService, DEFAULT_REACTIVE_CLAIM_POLICY } from '../../core/ClaimTriggerService';\nimport { isStreamingRequest } from './utils';\n\n/**\n * Configuration for creating ExpressPaymentKit\n */\nexport interface ExpressPaymentKitOptions {\n  /** Service identifier */\n  serviceId: string;\n  /** Service private key (or KMS Signer) */\n  signer: SignerInterface;\n\n  /** Optional RPC URL (defaults to env.ROOCH_NODE_URL) */\n  rpcUrl?: string;\n  /** Optional network (defaults to 'local') */\n  network?: 'local' | 'dev' | 'test' | 'main';\n  /** Default asset ID for settlement */\n  defaultAssetId?: string;\n  /** Default price in picoUSD when no rule matches */\n  defaultPricePicoUSD?: string | bigint;\n\n  /**\n   * Prefix under which all payment-channel routes are mounted.\n   * Defaults to \"/payment-channel\".\n   * Example: \"/billing\" or \"/api/pay\"\n   */\n  basePath?: string;\n\n  /** One or more DIDs that are authorized to call admin endpoints (defaults to service signer DID) */\n  adminDid?: string | string[];\n  /** Debug logging */\n  debug?: boolean;\n\n  // Legacy polling scheduler removed; reactive claims are the default\n\n  /** PaymentHub balance caching configuration */\n  hubBalance?: {\n    /** Normal cache TTL in milliseconds */\n    ttlMs?: number;\n    /** Negative cache TTL for zero balances */\n    negativeTtlMs?: number;\n    /** Stale-while-revalidate window in milliseconds */\n    staleWhileRevalidateMs?: number;\n    /** Maximum cache entries */\n    maxEntries?: number;\n  };\n\n  /** Claim triggering configuration */\n  claim?: {\n    /** Minimum accumulated amount to trigger a claim (bigint or string) */\n    minClaimAmount?: bigint | string;\n    /** Require hub balance check before triggering claims (default: true) */\n    requireHubBalance?: boolean;\n    /** Maximum concurrent claims across all sub-channels (default: 5) */\n    maxConcurrentClaims?: number;\n    /** Maximum retry attempts for failed claims (default: 3) */\n    maxRetries?: number;\n    /** Delay between retry attempts in milliseconds (default: 60000ms = 60s) */\n    retryDelayMs?: number;\n  };\n}\n\n/**\n * Express Payment Kit interface\n */\nexport interface ExpressPaymentKit {\n  /** Express Router to mount in your app */\n  readonly router: Router;\n\n  /** HTTP verb methods for registering routes with billing */\n  get(path: string, options: RouteOptions, handler: RequestHandler, ruleId?: string): this;\n  post(path: string, options: RouteOptions, handler: RequestHandler, ruleId?: string): this;\n  put(path: string, options: RouteOptions, handler: RequestHandler, ruleId?: string): this;\n  delete(path: string, options: RouteOptions, handler: RequestHandler, ruleId?: string): this;\n  patch(path: string, options: RouteOptions, handler: RequestHandler, ruleId?: string): this;\n\n  /** Get the underlying PayeeClient for advanced operations */\n  getPayeeClient(): PaymentChannelPayeeClient;\n}\n\n/**\n * Implementation of ExpressPaymentKit\n */\nclass ExpressPaymentKitImpl implements ExpressPaymentKit {\n  public readonly router: Router;\n  private readonly billableRouter: BillableRouter;\n  private readonly middleware: HttpBillingMiddleware;\n  private readonly config: ExpressPaymentKitOptions;\n  private readonly payeeClient: PaymentChannelPayeeClient;\n  private readonly rateProvider: RateProvider;\n  private readonly serviceDid: string;\n  // claimScheduler removed\n  // Hold storage repositories explicitly for reuse across components\n  private readonly channelRepo: ChannelRepository;\n  private readonly ravRepo: RAVRepository;\n  private readonly pendingSubRAVRepo: PendingSubRAVRepository;\n  private readonly processor: PaymentProcessor;\n  private readonly logger: DebugLogger;\n  // New services for reactive claim and hub balance\n  private readonly hubBalanceService: HubBalanceService;\n  private readonly claimTriggerService?: ClaimTriggerService;\n\n  constructor(\n    config: ExpressPaymentKitOptions,\n    deps: {\n      contract: IPaymentChannelContract;\n      signer: SignerInterface;\n      didResolver: DIDResolver;\n      rateProvider: RateProvider;\n      serviceDid: string;\n    },\n    prebuiltStorage?: {\n      channelRepo: ChannelRepository;\n      ravRepo: RAVRepository;\n      pendingSubRAVRepo: PendingSubRAVRepository;\n    }\n  ) {\n    this.logger = DebugLogger.get('ExpressPaymentKit');\n    this.config = config;\n    this.rateProvider = deps.rateProvider;\n    this.serviceDid = deps.serviceDid;\n    // Ensure built-in billing strategies are registered when server starts\n    registerBuiltinStrategies();\n\n    // Resolve storage repositories\n    const storage = prebuiltStorage ?? this.resolveStorageFromEnv();\n    this.channelRepo = storage.channelRepo;\n    this.ravRepo = storage.ravRepo;\n    this.pendingSubRAVRepo = storage.pendingSubRAVRepo;\n\n    // Create PayeeClient inside impl to ensure shared storage\n    this.payeeClient = new PaymentChannelPayeeClient({\n      contract: deps.contract,\n      signer: deps.signer,\n      didResolver: deps.didResolver,\n      storageOptions: {\n        channelRepo: this.channelRepo,\n        ravRepo: this.ravRepo,\n        pendingSubRAVRepo: this.pendingSubRAVRepo,\n      },\n    });\n\n    // Create single billable router for all routes (business + built-in)\n    this.billableRouter = new BillableRouter({\n      serviceId: config.serviceId,\n      defaultPricePicoUSD: config.defaultPricePicoUSD,\n    });\n\n    // Initialize HubBalanceService (always enabled)\n    this.hubBalanceService = new HubBalanceService({\n      contract: deps.contract,\n      defaultAssetId: config.defaultAssetId || '0x3::gas_coin::RGas',\n      ttlMs: config.hubBalance?.ttlMs,\n      negativeTtlMs: config.hubBalance?.negativeTtlMs,\n      staleWhileRevalidateMs: config.hubBalance?.staleWhileRevalidateMs,\n      maxEntries: config.hubBalance?.maxEntries,\n      debug: config.debug,\n    });\n\n    // Initialize ClaimTriggerService with flattened config\n    this.claimTriggerService = new ClaimTriggerService({\n      policy: {\n        minClaimAmount: this.config.claim?.minClaimAmount,\n        maxConcurrentClaims: this.config.claim?.maxConcurrentClaims,\n        maxRetries: this.config.claim?.maxRetries,\n        retryDelayMs: this.config.claim?.retryDelayMs,\n        requireHubBalance: this.config.claim?.requireHubBalance,\n      },\n      contract: deps.contract,\n      signer: deps.signer, // Pass the payee signer\n      ravRepo: this.ravRepo,\n      channelRepo: this.channelRepo,\n      debug: config.debug,\n    });\n\n    const claimPolicy = this.claimTriggerService.getPolicy();\n\n    // Initialize PaymentProcessor with config\n    this.processor = new PaymentProcessor({\n      payeeClient: this.payeeClient,\n      serviceId: config.serviceId,\n      defaultAssetId: config.defaultAssetId,\n      rateProvider: this.rateProvider,\n      pendingSubRAVStore: this.pendingSubRAVRepo,\n      ravRepository: this.ravRepo,\n      didResolver: this.payeeClient.getDidResolver(),\n      hubBalanceService: this.hubBalanceService,\n      claimTriggerService: this.claimTriggerService,\n      minClaimAmount: claimPolicy.minClaimAmount,\n      debug: config.debug,\n    });\n\n    // Create HTTP billing middleware with ClaimScheduler\n    this.middleware = new HttpBillingMiddleware({\n      processor: this.processor,\n      ruleProvider: this.billableRouter,\n    });\n\n    // Create main router\n    this.router = express.Router();\n\n    // Set up discovery endpoint and routes\n    this.setupRoutes();\n\n    // Polling scheduler removed; reactive claim mode is default\n  }\n\n  /**\n   * Resolve storage repositories based on environment variables.\n   * Priority: PAYMENTKIT_CONNECTION_STRING > SUPABASE_DB_URL > DATABASE_URL.\n   * Backend selection: PAYMENTKIT_BACKEND or infer from connection string.\n   */\n  private resolveStorageFromEnv(): {\n    channelRepo: ChannelRepository;\n    ravRepo: RAVRepository;\n    pendingSubRAVRepo: PendingSubRAVRepository;\n  } {\n    const backendEnv = process.env.PAYMENTKIT_BACKEND as 'sql' | 'memory' | undefined;\n    const backend: 'sql' | 'memory' = backendEnv === 'sql' ? 'sql' : 'memory';\n    const connectionString =\n      backend === 'sql'\n        ? process.env.PAYMENTKIT_CONNECTION_STRING ||\n          process.env.SUPABASE_DB_URL ||\n          process.env.DATABASE_URL\n        : undefined;\n\n    const tablePrefix = process.env.PAYMENTKIT_TABLE_PREFIX || 'nuwa_';\n    const autoMigrate =\n      process.env.PAYMENTKIT_AUTO_MIGRATE === 'true' || process.env.NODE_ENV !== 'production';\n\n    let channelRepo: ChannelRepository;\n    let ravRepo: RAVRepository;\n    let pendingSubRAVRepo: PendingSubRAVRepository;\n    if (backend === 'sql') {\n      // Defer Pool creation to runtime via dynamic import factory\n      // eslint-disable-next-line @typescript-eslint/no-var-requires\n      const sql = require('../../storage/sql/index');\n      const repos = sql.createSqlStorageRepositories({\n        connectionString: connectionString!,\n        tablePrefix,\n        autoMigrate,\n        allowUnsafeAutoMigrateInProd:\n          process.env.PAYMENTKIT_ALLOW_UNSAFE_AUTO_MIGRATE_IN_PROD === 'true',\n      });\n      // If it returned a Promise (ESM dynamic factory), this will be a thenable\n      if (typeof repos.then === 'function') {\n        throw new Error(\n          'createSqlStorageRepositories() is async; use the async factory to build ExpressPaymentKit or pre-create repositories and inject'\n        );\n      }\n      ({ channelRepo, ravRepo, pendingSubRAVRepo } = repos);\n    } else {\n      ({ channelRepo, ravRepo, pendingSubRAVRepo } = createStorageRepositories({\n        backend: 'memory',\n        tablePrefix,\n        autoMigrate,\n      }));\n    }\n\n    return { channelRepo, ravRepo, pendingSubRAVRepo };\n  }\n\n  /**\n   * Set up all routes including discovery endpoint and payment-related routes\n   */\n  private setupRoutes(): void {\n    const basePath = this.config.basePath || '/payment-channel';\n\n    // Create API context for handlers\n    const apiContext: ApiContext = {\n      config: {\n        serviceId: this.config.serviceId,\n        serviceDid: this.serviceDid,\n        defaultAssetId: this.config.defaultAssetId || '0x3::gas_coin::RGas',\n        defaultPricePicoUSD: this.config.defaultPricePicoUSD?.toString(),\n        adminDid: this.config.adminDid,\n        debug: this.config.debug,\n      },\n      payeeClient: this.payeeClient,\n      rateProvider: this.rateProvider,\n      // Expose reactive claim trigger for admin/status handlers\n      claimTriggerService: this.claimTriggerService,\n      processor: this.processor,\n      ravRepository: this.ravRepo,\n      channelRepo: this.channelRepo,\n      pendingSubRAVStore: this.pendingSubRAVRepo,\n    };\n\n    // 1. Discovery endpoint (well-known, completely public - no middleware)\n    // This is handled directly to maintain compatibility and avoid billing\n    this.router.get('/.well-known/nuwa-payment/info', (req: Request, res: Response) => {\n      this.handleDiscoveryRequest(req, res);\n    });\n\n    // 2. Register built-in handlers with prefix using the single BillableRouter\n    registerHandlersWithBillableRouter(BuiltInApiHandlers, apiContext, this.billableRouter, {\n      pathPrefix: basePath,\n    });\n\n    // 3. Create billing middleware wrapper and mount all routes\n    const billingWrapper = this.createBillingWrapper();\n    this.router.use(billingWrapper);\n    this.router.use(this.billableRouter.router);\n  }\n\n  /**\n   * Handle discovery requests for the well-known endpoint\n   * Note: Uses direct response format (not ApiResponse) to comply with well-known URI standards\n   */\n  private handleDiscoveryRequest(req: Request, res: Response): void {\n    const discoveryInfo: any = {\n      version: 1,\n      serviceId: this.config.serviceId,\n      serviceDid: this.serviceDid,\n      network: this.config.network || 'test',\n      defaultAssetId: this.config.defaultAssetId || '0x3::gas_coin::RGas',\n      basePath: this.config.basePath || '/payment-channel',\n    };\n\n    if (this.config.defaultPricePicoUSD) {\n      discoveryInfo.defaultPricePicoUSD = this.config.defaultPricePicoUSD.toString();\n    }\n\n    // Set cache headers as recommended in the spec\n    res.set('Cache-Control', 'max-age=3600, public');\n    res.json(discoveryInfo);\n  }\n\n  /**\n   * Create billing middleware wrapper with automatic pre/post-flight detection\n   */\n  private createBillingWrapper(): RequestHandler {\n    return async (req: Request, res: Response, next: NextFunction) => {\n      try {\n        // Step 1: Find matching billing rule to determine auth and billing requirements\n        const rule = this.billableRouter.findRule(req.method, req.path);\n\n        // Step 2: Authentication (based on rule configuration)\n        const needAuth = rule?.authRequired ?? false;\n        const needAdminAuth = rule?.adminOnly ?? false;\n\n        if (needAuth || needAdminAuth) {\n          await this.performDIDAuth(req, res);\n        }\n\n        if (needAdminAuth) {\n          await this.performAdminAuth(req, res);\n        }\n\n        // Step 3: Apply billing middleware (for all registered routes)\n        if (rule) {\n          // Create response adapter for framework-agnostic billing\n          const resAdapter = this.createResponseAdapter(res);\n\n          // Use new unified billing API\n          const billingContext = await this.middleware.handleWithNewAPI(req);\n\n          if (!billingContext) {\n            // No billing rule matched - proceed without payment\n\n            return next();\n          }\n\n          // Unified handling for both pre-flight and post-flight\n          res.locals.billingContext = billingContext;\n\n          // If processor marked a protocol-level error, short-circuit and return immediately\n          // Note: This is the error short-circuit from the pre-processing stage. The header writing in onHeaders is the unified exit for the settlement stage.\n          if (billingContext.state?.error) {\n            const err = billingContext.state.error as { code: string; message?: string };\n            const status = this.mapErrorCodeToHttpStatus(err.code);\n            const headerValue = this.buildProtocolErrorHeader(req, err);\n            this.ensureExposeHeader(res);\n            res.setHeader(HttpPaymentCodec.getHeaderName(), headerValue);\n\n            return res.status(status).json({\n              success: false,\n              error: { code: err.code, message: err.message, httpStatus: status },\n            });\n          }\n\n          let billingCompleted = false;\n          let headerWritten = false;\n          const isStreaming = isStreamingRequest(req as any, rule as any);\n\n          // Intercept headers to write payment header synchronously\n          // Note: This is the unified exit for the settlement stage, which writes the success/failure payment header; it is complementary to the pre-processing error short-circuit rather than redundant.\n          if (!isStreaming) {\n            onHeaders(res, () => {\n              if (headerWritten) return;\n              headerWritten = true;\n              try {\n                this.ensureExposeHeader(res);\n                const raw = (res.locals as any).usage;\n                const units =\n                  typeof raw === 'number' && Number.isFinite(raw) && raw >= 0 ? Math.floor(raw) : 0;\n                this.middleware.settleBillingSync(billingContext, units, resAdapter);\n              } catch (error) {}\n            });\n          }\n\n          // Inject in-band payment frame for streaming just before end (best-effort)\n          if (isStreaming) {\n            const originalEnd = (res as any).end?.bind(res) || res.end;\n            (res as any).end = (...args: any[]) => {\n              try {\n                if (!billingCompleted) {\n                  const raw = (res.locals as any).usage;\n                  const units =\n                    typeof raw === 'number' && Number.isFinite(raw) && raw >= 0\n                      ? Math.floor(raw)\n                      : 0;\n                  const settled: any = this.processor.settle(billingContext, units);\n                  if (!headerWritten) {\n                    try {\n                      this.ensureExposeHeader(res);\n                      if (settled?.state?.headerValue) {\n                        res.setHeader('X-Payment-Channel-Data', settled.state.headerValue);\n                      }\n                    } catch {}\n                  }\n                  try {\n                    const headerValue: string | undefined = settled?.state?.headerValue;\n                    if (headerValue) {\n                      const ct = (res.getHeader('Content-Type') as string) || '';\n                      const sseObj = { nuwa_payment_header: headerValue };\n                      const ndjsonObj = { __nuwa_payment_header__: headerValue };\n                      const frameSSE = `data: ${JSON.stringify(sseObj)}\\n\\n`;\n                      const frameNDJSON = JSON.stringify(ndjsonObj) + '\\n';\n                      if (ct.includes('text/event-stream')) {\n                        try {\n                          // Ensure event boundary so we don't concatenate into previous frame\n                          (res as any).write?.('\\n\\n');\n                          (res as any).write?.(frameSSE);\n                        } catch {}\n                      } else if (ct.includes('application/x-ndjson')) {\n                        try {\n                          // Ensure record boundary for NDJSON\n                          (res as any).write?.('\\n');\n                          (res as any).write?.(frameNDJSON);\n                        } catch {}\n                      } else {\n                        // For other content types, do not force insertion to avoid breaking protocol\n                        this.logger.warn('Streaming response with unsupported content type:', ct);\n                      }\n                    }\n                  } catch {}\n                  if (settled?.state?.unsignedSubRav) {\n                    // TODO: Race condition - the in-band payment frame is sent before this async\n                    // persist completes. If client sends next request immediately, server may not\n                    // find the pending SubRAV yet. See temporary workaround in RavVerifier.ts\n                    this.middleware.persistBilling(settled).catch(() => {});\n                  }\n                  billingCompleted = true;\n                }\n              } catch {}\n              return originalEnd(...args);\n            };\n          }\n\n          // Persist after response is sent\n          res.on('finish', async () => {\n            if (billingCompleted) return;\n            billingCompleted = true;\n            try {\n              if (isStreaming) {\n                // Streaming: settle at finish and persist\n                const raw = (res.locals as any).usage;\n                const units =\n                  typeof raw === 'number' && Number.isFinite(raw) && raw >= 0 ? Math.floor(raw) : 0;\n                const settled = this.processor.settle(billingContext, units) as any;\n                if (!headerWritten) {\n                  // Trailers are not widely supported; rely on polling/in-band. Still expose header if possible.\n                  try {\n                    this.ensureExposeHeader(res);\n                    if (settled?.state?.headerValue) {\n                      res.setHeader('X-Payment-Channel-Data', settled.state.headerValue);\n                    }\n                  } catch {}\n                }\n                if (settled?.state?.unsignedSubRav) {\n                  await this.middleware.persistBilling(settled);\n                }\n              } else if (billingContext.state?.unsignedSubRav) {\n                await this.middleware.persistBilling(billingContext);\n              }\n            } catch (error) {}\n          });\n\n          return next();\n        } else {\n        }\n\n        next();\n      } catch (error) {\n        res.status(500).json({\n          error: 'Payment processing failed',\n          details: error instanceof Error ? error.message : String(error),\n        });\n      }\n    };\n  }\n\n  /**\n   * Ensure CORS exposes our payment header to browsers so client JS can read it.\n   */\n  private ensureExposeHeader(res: Response) {\n    const headerName = HttpPaymentCodec.getHeaderName();\n    const existing = res.getHeader('Access-Control-Expose-Headers');\n    const current = (\n      Array.isArray(existing) ? existing.join(',') : (existing as string | undefined) || ''\n    )\n      .split(',')\n      .map(s => s.trim())\n      .filter(Boolean);\n    if (!current.map(s => s.toLowerCase()).includes(headerName.toLowerCase())) {\n      current.push(headerName);\n      res.setHeader('Access-Control-Expose-Headers', current.join(', '));\n    }\n  }\n\n  /**\n   * Perform admin authorization check\n   */\n  private async performAdminAuth(req: express.Request, res: express.Response): Promise<void> {\n    try {\n      // Get allowed admin DIDs (default to service DID)\n      const allowedDids = Array.isArray(this.config.adminDid)\n        ? this.config.adminDid\n        : this.config.adminDid\n          ? [this.config.adminDid]\n          : [this.serviceDid];\n\n      // Get DID from request (set by performDIDAuth)\n      const didInfo = (req as any).didInfo;\n      if (!didInfo || !didInfo.did) {\n        throw new Error('DID authentication required for admin access');\n      }\n\n      // Check if signer DID is authorized for admin operations\n      const signerDid = didInfo.did;\n      if (!allowedDids.includes(signerDid)) {\n        throw new Error(`Access denied. DID ${signerDid} not authorized for admin operations`);\n      }\n\n      if (this.config.debug) {\n        console.log(`✅ Admin authorization successful for DID: ${signerDid}`);\n      }\n    } catch (error) {\n      throw new Error(\n        `Admin authorization failed: ${error instanceof Error ? error.message : String(error)}`\n      );\n    }\n  }\n\n  /**\n   * Perform DID authentication using DIDAuthV1 scheme\n   */\n  private async performDIDAuth(req: express.Request, res: express.Response): Promise<void> {\n    const AUTH_SCHEME = 'DIDAuthV1';\n    const HEADER_PREFIX = `${AUTH_SCHEME} `;\n\n    try {\n      const authHeader = req.headers.authorization;\n\n      if (this.config.debug) {\n        console.log(\n          `🔐 performDIDAuth: Authorization present=${!!authHeader}, startsWithDIDAuthV1=${\n            !!authHeader && authHeader.startsWith(HEADER_PREFIX)\n          }`\n        );\n      }\n\n      if (!authHeader || !authHeader.startsWith(HEADER_PREFIX)) {\n        throw new Error('Missing or invalid Authorization header');\n      }\n\n      // Perform cryptographic verification via Nuwa Identity Kit\n      const verifyResult = await DIDAuth.v1.verifyAuthHeader(authHeader, VDRRegistry.getInstance());\n\n      if (!verifyResult.ok) {\n        throw new Error(verifyResult.error);\n      }\n\n      // Success path: extract signer DID and set it on the request\n      (req as any).didInfo = {\n        did: verifyResult.signedObject.signature.signer_did,\n        keyId: verifyResult.signedObject.signature.key_id,\n      };\n    } catch (error) {\n      throw new Error(\n        `DID authentication failed: ${error instanceof Error ? error.message : String(error)}`\n      );\n    }\n  }\n\n  // HTTP verb methods\n  get(path: string, options: RouteOptions, handler: RequestHandler, ruleId?: string): this {\n    this.validateRouteOptions(options);\n    this.billableRouter.get(path, options, handler, ruleId);\n    return this;\n  }\n\n  post(path: string, options: RouteOptions, handler: RequestHandler, ruleId?: string): this {\n    this.validateRouteOptions(options);\n    this.billableRouter.post(path, options, handler, ruleId);\n    return this;\n  }\n\n  put(path: string, options: RouteOptions, handler: RequestHandler, ruleId?: string): this {\n    this.validateRouteOptions(options);\n    this.billableRouter.put(path, options, handler, ruleId);\n    return this;\n  }\n\n  delete(path: string, options: RouteOptions, handler: RequestHandler, ruleId?: string): this {\n    this.validateRouteOptions(options);\n    this.billableRouter.delete(path, options, handler, ruleId);\n    return this;\n  }\n\n  patch(path: string, options: RouteOptions, handler: RequestHandler, ruleId?: string): this {\n    this.validateRouteOptions(options);\n    this.billableRouter.patch(path, options, handler, ruleId);\n    return this;\n  }\n\n  /**\n   * Validate route options according to the security rules\n   */\n  private validateRouteOptions(options: RouteOptions): void {\n    const pricing = typeof options.pricing === 'string' ? BigInt(options.pricing) : options.pricing;\n    const pricingAmount = typeof pricing === 'bigint' ? pricing : BigInt(0);\n\n    // Rule: If pricing > 0 and authRequired is explicitly false, throw error\n    if (pricingAmount > 0 && options.authRequired === false) {\n      throw new Error(\n        'Cannot create anonymous paid endpoints: pricing > 0 requires authRequired to be true or undefined'\n      );\n    }\n\n    // Rule: If adminOnly is true and authRequired is explicitly false, throw error\n    if (options.adminOnly && options.authRequired === false) {\n      throw new Error(\n        'Cannot create admin endpoints without authentication: adminOnly requires authRequired to be true or undefined'\n      );\n    }\n  }\n\n  /**\n   * Create Express ResponseAdapter for framework-agnostic billing\n   */\n  private createResponseAdapter(res: Response): ResponseAdapter {\n    return {\n      setStatus: (code: number) => {\n        res.status(code);\n        return this.createResponseAdapter(res);\n      },\n      json: (obj: any) => {\n        res.json(obj);\n      },\n      setHeader: (name: string, value: string) => {\n        if (!res.headersSent) {\n          res.setHeader(name, value);\n        } else if (this.config.debug) {\n          console.warn(`⚠️ Cannot set header '${name}' after headers sent`);\n        }\n        return this.createResponseAdapter(res);\n      },\n    };\n  }\n\n  /**\n   * Map PaymentError code to HTTP status code (shared by preProcess short-circuit)\n   */\n  private mapErrorCodeToHttpStatus(code?: string): number {\n    return httpStatusFor(code as PaymentErrorCode);\n  }\n\n  /**\n   * Build protocol error header consistently from request headers and error\n   */\n  private buildProtocolErrorHeader(req: Request, err: { code: string; message?: string }): string {\n    let clientTxRef: string | undefined;\n    try {\n      const headerValueIn = HttpPaymentCodec.extractPaymentHeader(req.headers as any);\n      if (headerValueIn) {\n        const payload = HttpPaymentCodec.parseRequestHeader(headerValueIn);\n        clientTxRef = payload.clientTxRef;\n      }\n    } catch {}\n    return HttpPaymentCodec.buildResponseHeader({\n      error: { code: err.code, message: err.message },\n      clientTxRef,\n      version: 1,\n    } as any);\n  }\n\n  /**\n   * Get the underlying PayeeClient for advanced operations\n   */\n  getPayeeClient(): PaymentChannelPayeeClient {\n    return this.payeeClient;\n  }\n}\n\n/**\n * Create an ExpressPaymentKit instance\n */\nexport async function createExpressPaymentKit(\n  config: ExpressPaymentKitOptions\n): Promise<ExpressPaymentKit> {\n  // Validate configuration\n  if (!config.signer) {\n    throw new Error('Service private key (signer) is required');\n  }\n\n  // Get service DID from signer\n  const serviceDid = await (async () => {\n    const maybe = (config.signer as any).getDid?.();\n    return typeof maybe?.then === 'function' ? await maybe : maybe;\n  })();\n\n  // Set up blockchain connection\n  const rpcUrl = config.rpcUrl;\n  const network = config.network || 'test';\n\n  // Initialize contract\n  const contract = new RoochPaymentChannelContract({\n    rpcUrl,\n    network,\n    debug: config.debug || false,\n  });\n\n  // Set up DID resolver with VDRRegistry\n  const roochVDR = new RoochVDR({\n    rpcUrl,\n    network,\n  });\n\n  const vdrRegistry = VDRRegistry.getInstance();\n  vdrRegistry.registerVDR(roochVDR);\n\n  // Create default ContractRateProvider\n  const rateProvider = new ContractRateProvider(contract, 30_000);\n\n  // Optionally prebuild SQL storage repos via dynamic import so callers don't need changes\n  let prebuiltStorage:\n    | {\n        channelRepo: ChannelRepository;\n        ravRepo: RAVRepository;\n        pendingSubRAVRepo: PendingSubRAVRepository;\n      }\n    | undefined;\n\n  try {\n    const backendEnv = process.env.PAYMENTKIT_BACKEND as 'sql' | 'memory' | undefined;\n    if (backendEnv === 'sql') {\n      const connectionString =\n        process.env.PAYMENTKIT_CONNECTION_STRING ||\n        process.env.SUPABASE_DB_URL ||\n        process.env.DATABASE_URL;\n      if (!connectionString) {\n        throw new Error(\n          'PAYMENTKIT_BACKEND=sql requires PAYMENTKIT_CONNECTION_STRING (or SUPABASE_DB_URL / DATABASE_URL)'\n        );\n      }\n      const { createSqlStorageRepositories }: any = await import('../../storage/sql/index');\n      prebuiltStorage = await createSqlStorageRepositories({\n        connectionString,\n        tablePrefix: process.env.PAYMENTKIT_TABLE_PREFIX || 'nuwa_',\n        autoMigrate:\n          process.env.PAYMENTKIT_AUTO_MIGRATE === 'true' || process.env.NODE_ENV !== 'production',\n        allowUnsafeAutoMigrateInProd:\n          process.env.PAYMENTKIT_ALLOW_UNSAFE_AUTO_MIGRATE_IN_PROD === 'true',\n      });\n    }\n  } catch (e) {\n    // If SQL setup fails, surface meaningful error; otherwise continue with memory backend\n    if ((process.env.PAYMENTKIT_BACKEND as string) === 'sql') {\n      throw e;\n    }\n  }\n\n  return new ExpressPaymentKitImpl(\n    config,\n    {\n      contract,\n      signer: config.signer,\n      didResolver: vdrRegistry,\n      rateProvider,\n      serviceDid,\n    },\n    prebuiltStorage\n  );\n}\n\n// ---------------------------------------------------------------------------\n// Express augmentation to include `didInfo`\n// ---------------------------------------------------------------------------\n\ndeclare global {\n  namespace Express {\n    interface Request {\n      didInfo?: {\n        did: string;\n        keyId: string;\n      };\n    }\n  }\n}\n","import type { InternalRecoveryRequest } from '../../types/internal';\nimport { PaymentKitError, createSuccessResponse } from '../../errors';\nimport type { Handler, ApiContext } from '../../types/api';\nimport { ErrorCode } from '../../types/api';\nimport type { RecoveryResponse } from '../../schema';\nimport { deriveChannelId } from '../../rooch/ChannelUtils';\n\n/**\n * Handle recovery endpoint requests\n * Requires DID authentication\n */\nexport const handleRecovery: Handler<ApiContext, {}, RecoveryResponse> = async (ctx, req) => {\n  try {\n    const internalReq = req as InternalRecoveryRequest;\n    if (!internalReq.didInfo || !internalReq.didInfo.did || !internalReq.didInfo.keyId) {\n      throw new PaymentKitError(ErrorCode.UNAUTHORIZED, 'DID authentication required', 401);\n    }\n\n    const clientDid = internalReq.didInfo.did;\n\n    // Derive channelId deterministically using ChannelUtils\n    const defaultAssetId = ctx.config.defaultAssetId ?? '0x3::gas_coin::RGas';\n    const channelId = deriveChannelId(clientDid, ctx.config.serviceDid, defaultAssetId);\n\n    let channel: any = null;\n    try {\n      channel = await ctx.payeeClient.getChannelInfo(channelId);\n    } catch (_) {\n      // Channel doesn't exist yet - this is normal for first-time clients\n    }\n\n    // Extract vmIdFragment from DID keyId and find latest pending for sub-channel\n    const keyParts = internalReq.didInfo.keyId.split('#');\n    const vmIdFragment = keyParts.length > 1 ? keyParts[1] : '';\n    const pending = vmIdFragment\n      ? await ctx.pendingSubRAVStore.findLatestBySubChannel(channelId, vmIdFragment)\n      : null;\n\n    // Try to get sub-channel state for this vmIdFragment (authorized -> state exists)\n    let subChannel = null as any;\n    if (channel && vmIdFragment) {\n      try {\n        const state = await ctx.payeeClient.getSubChannelState(channelId, vmIdFragment);\n        if (state) {\n          subChannel = state;\n        }\n      } catch (_) {\n        // sub-channel may not be authorized yet; that's fine\n      }\n    }\n\n    const response: RecoveryResponse = {\n      channel: channel ?? null,\n      pendingSubRav: pending ?? null,\n      subChannel: subChannel ?? null,\n      timestamp: new Date().toISOString(),\n    };\n\n    return createSuccessResponse(response);\n  } catch (error) {\n    if (error instanceof PaymentKitError) {\n      throw error;\n    }\n    throw new PaymentKitError(\n      ErrorCode.INTERNAL_ERROR,\n      'Failed to perform recovery',\n      500,\n      error instanceof Error ? error.message : String(error)\n    );\n  }\n};\n","import type { InternalCommitRequest } from '../../types/internal';\nimport { createSuccessResponse, PaymentKitError } from '../../errors';\nimport type { Handler, ApiContext } from '../../types/api';\nimport { ErrorCode } from '../../types/api';\nimport type { CommitResponse, CommitRequest } from '../../schema';\n\n/**\n * Handle commit endpoint requests\n * Requires DID authentication\n */\nexport const handleCommit: Handler<ApiContext, CommitRequest, CommitResponse> = async (\n  ctx,\n  req\n) => {\n  try {\n    if (!req.subRav) {\n      throw new PaymentKitError(ErrorCode.BAD_REQUEST, 'subRav required', 400);\n    }\n\n    try {\n      //await ctx.payeeClient.processSignedSubRAV(req.subRav);\n      //TODO: Implement commit\n      return createSuccessResponse({ success: false });\n    } catch (e) {\n      throw new PaymentKitError(ErrorCode.CONFLICT, (e as Error).message, 409);\n    }\n  } catch (error) {\n    if (error instanceof PaymentKitError) {\n      throw error;\n    }\n    throw new PaymentKitError(\n      ErrorCode.INTERNAL_ERROR,\n      'Failed to commit SubRAV',\n      500,\n      error instanceof Error ? error.message : String(error)\n    );\n  }\n};\n","import type { InternalClaimTriggerRequest, InternalSubRavRequest } from '../../types/internal';\nimport { createSuccessResponse, PaymentKitError } from '../../errors';\nimport type { Handler, ApiContext } from '../../types/api';\nimport { ErrorCode } from '../../types/api';\nimport type {\n  HealthResponse,\n  SystemStatusResponse,\n  ClaimTriggerRequest,\n  ClaimTriggerResponse,\n} from '../../schema';\nimport { DebugLogger } from '@nuwa-ai/identity-kit';\n\n/**\n * Handle admin system status endpoint requests\n * Admin only endpoint\n */\nexport const handleAdminStatus: Handler<ApiContext, {}, SystemStatusResponse> = async (\n  ctx,\n  req\n) => {\n  try {\n    // Prefer reactive claim trigger status when available; fallback to legacy scheduler\n    const stats = ctx.claimTriggerService?.getStatus();\n    const claimsStatus = stats\n      ? {\n          active: stats.active,\n          queued: stats.queued,\n          successCount: stats.successCount,\n          failedCount: stats.failedCount,\n          skippedCount: stats.skippedCount,\n          insufficientFundsCount: stats.insufficientFundsCount,\n          backoffCount: stats.backoffCount,\n          avgProcessingTimeMs: stats.avgProcessingTimeMs,\n          policy: {\n            minClaimAmount: stats.policy.minClaimAmount,\n            maxConcurrentClaims: stats.policy.maxConcurrentClaims,\n            maxRetries: stats.policy.maxRetries,\n            retryDelayMs: stats.policy.retryDelayMs,\n            requireHubBalance: stats.policy.requireHubBalance,\n            insufficientFundsBackoffMs: stats.policy.insufficientFundsBackoffMs,\n            countInsufficientAsFailure: stats.policy.countInsufficientAsFailure,\n          },\n        }\n      : {\n          active: 0,\n          queued: 0,\n          successCount: 0,\n          failedCount: 0,\n          skippedCount: 0,\n          insufficientFundsCount: 0,\n          backoffCount: 0,\n          avgProcessingTimeMs: 0,\n          policy: {\n            minClaimAmount: 0n,\n            maxConcurrentClaims: 0,\n            maxRetries: 0,\n            retryDelayMs: 0,\n            requireHubBalance: false,\n            insufficientFundsBackoffMs: 0,\n            countInsufficientAsFailure: false,\n          },\n        };\n    const processingStats = ctx.processor.getProcessingStats();\n\n    const result: SystemStatusResponse = {\n      claims: claimsStatus,\n      processor: processingStats,\n      timestamp: new Date().toISOString(),\n    };\n\n    return createSuccessResponse(result);\n  } catch (error) {\n    throw new PaymentKitError(\n      ErrorCode.INTERNAL_ERROR,\n      'Failed to retrieve system status',\n      500,\n      error instanceof Error ? error.message : String(error)\n    );\n  }\n};\n\n/**\n * Handle admin claim trigger endpoint requests\n * Admin only endpoint\n */\nexport const handleAdminClaimTrigger: Handler<\n  ApiContext,\n  ClaimTriggerRequest,\n  ClaimTriggerResponse\n> = async (ctx, req) => {\n  try {\n    // Diagnostic/manual trigger: enqueue a reactive claim for all known sub-channels under the channelId\n    // Behavior:\n    // - Reads latest SignedSubRAVs for each vmIdFragment under the channel (from ravRepo)\n    // - Computes delta vs current SubChannelInfo\n    // - If delta >= minClaimAmount, queue claim via ClaimTriggerService\n    // - Returns an empty results array immediately; status can be observed via /admin/status\n\n    if (!ctx.claimTriggerService) {\n      return createSuccessResponse({ channelId: req.channelId, queued: [], skipped: [] });\n    }\n\n    const channelId = req.channelId;\n    const queued: { vmIdFragment: string; delta: bigint }[] = [];\n    const skipped: {\n      vmIdFragment: string;\n      reason: 'no_delta' | 'below_threshold';\n      delta?: bigint;\n      threshold?: bigint;\n    }[] = [];\n\n    try {\n      // List all sub-channels we have state for\n      const subStates = await ctx.channelRepo.listSubChannelStates(channelId);\n      const vmIds = Object.keys(subStates);\n\n      for (const vmIdFragment of vmIds) {\n        const latest = await ctx.ravRepository.getLatest(channelId, vmIdFragment);\n        const state = subStates[vmIdFragment];\n        if (!latest || !state) continue;\n\n        const accumulated = latest.subRav.accumulatedAmount;\n        const lastClaimed = state.lastClaimedAmount;\n        const delta = accumulated > lastClaimed ? accumulated - lastClaimed : 0n;\n\n        if (delta <= 0n) {\n          skipped.push({ vmIdFragment, reason: 'no_delta' });\n          continue;\n        }\n        // enqueue regardless of threshold; ClaimTriggerService will decide to skip/queue by policy\n        await ctx.claimTriggerService.maybeQueue(channelId, vmIdFragment, delta);\n        queued.push({ vmIdFragment, delta });\n      }\n    } catch (e) {\n      DebugLogger.error('Failed to trigger claim', e);\n      // swallow diagnostic errors; return partial\n    }\n\n    // Response schema expects ScheduledClaimResult[]; in reactive mode we return an empty list\n    // and rely on /admin/status for detailed progress.\n    return createSuccessResponse({ channelId, queued, skipped });\n  } catch (error) {\n    throw new PaymentKitError(\n      ErrorCode.INTERNAL_ERROR,\n      'Failed to trigger claim',\n      500,\n      error instanceof Error ? error.message : String(error)\n    );\n  }\n};\n","import type { InternalSubRavRequest } from '../../types/internal';\nimport { PaymentKitError, createSuccessResponse } from '../../errors';\nimport type { Handler, ApiContext } from '../../types/api';\nimport { ErrorCode } from '../../types/api';\nimport type { SubRavRequest } from '../../schema';\nimport { deriveChannelId } from '../../rooch/ChannelUtils';\n\n/**\n * Handle SubRAV query endpoint requests\n * Requires DID authentication\n * Users can only query SubRAVs from channels they own\n */\nexport const handleSubRavQuery: Handler<ApiContext, SubRavRequest, any> = async (ctx, req) => {\n  try {\n    // Keep handler free of direct console logging\n\n    // Check if user is authenticated\n    const internalReq = req as InternalSubRavRequest;\n    if (!internalReq.didInfo || !internalReq.didInfo.did || !internalReq.didInfo.keyId) {\n      throw new PaymentKitError(ErrorCode.UNAUTHORIZED, 'DID authentication required', 401);\n    }\n\n    const clientDid = internalReq.didInfo.did;\n\n    // Derive the expected channelId for this user\n    const defaultAssetId = ctx.config.defaultAssetId ?? '0x3::gas_coin::RGas';\n    const channelId = deriveChannelId(clientDid, ctx.config.serviceDid, defaultAssetId);\n\n    // Extract vmIdFragment from DID keyId (format: did:...#fragment)\n    // Extract vmIdFragment from DID keyId (format: did:...#fragment)\n    const keyParts = internalReq.didInfo.keyId.split('#');\n    const vmIdFragment = keyParts.length > 1 ? keyParts[1] : '';\n    if (!vmIdFragment) {\n      throw new PaymentKitError(ErrorCode.BAD_REQUEST, 'Invalid DID keyId: missing fragment', 400);\n    }\n    const subRAV = await ctx.ravRepository.get(channelId, vmIdFragment, BigInt(req.nonce));\n\n    if (subRAV) {\n      return createSuccessResponse(subRAV);\n    } else {\n      throw new PaymentKitError(ErrorCode.NOT_FOUND, 'SubRAV not found', 404);\n    }\n  } catch (error) {\n    if (error instanceof PaymentKitError) {\n      throw error;\n    }\n\n    throw new PaymentKitError(\n      ErrorCode.INTERNAL_ERROR,\n      'Failed to retrieve SubRAV',\n      500,\n      error instanceof Error ? error.message : String(error)\n    );\n  }\n};\n","import { createSuccessResponse } from '../../errors';\nimport type { ApiContext, Handler } from '../../types/api';\nimport type { HealthResponse } from '../../schema';\n\n/**\n * Handle admin health endpoint requests\n * Public endpoint, no authentication required\n */\nexport const handleHealth: Handler<ApiContext, {}, HealthResponse> = async (ctx, req) => {\n  const response: HealthResponse = {\n    success: true,\n    status: 'healthy',\n    timestamp: new Date().toISOString(),\n    paymentKitEnabled: true,\n  };\n\n  return createSuccessResponse(response);\n};\n","import type { Handler, ApiContext } from '../types/api';\nimport type { RouteOptions } from '../transport/express/BillableRouter';\nimport type { z } from 'zod';\n\n/**\n * Pair of Zod schemas for request / response.\n */\nexport type ZodSchemaPair<Req, Res> = {\n  request: z.ZodType<Req, any, any>;\n  response: z.ZodType<Res, any, any>;\n};\n\n/**\n * Wrap a business handler with runtime Zod validation.\n *\n * 1. Validate the raw request against the provided request schema. If parsing\n *    fails Zod will throw a descriptive error that will propagate up the call\n *    chain.\n * 2. Delegate to the underlying business handler.\n * 3. (Optional – not yet implemented) Validate the handler's response against\n *    the response schema. This step will be enabled once all handlers return\n *    plain data objects instead of the ApiResponse envelope.\n */\nexport function createValidatedHandler<Req, Res>(params: {\n  schema: ZodSchemaPair<Req, Res>;\n  handler: Handler<ApiContext, Req, Res>;\n}): Handler<ApiContext, Req, Res> {\n  const { schema, handler } = params;\n\n  return async (ctx, rawReq) => {\n    // 1️⃣ Validate & transform the incoming request.\n    const req = schema.request.parse(rawReq);\n\n    // Preserve auth context injected by middleware (e.g., didInfo) that\n    // may be stripped by schema parsing. Handlers may read it via Internal*Request.\n    const enrichedReq: any = { ...req };\n    if ((rawReq as any) && (rawReq as any).didInfo) {\n      enrichedReq.didInfo = (rawReq as any).didInfo;\n    }\n\n    // 2️⃣ Execute business logic.\n    const rawRes = await handler(ctx, enrichedReq as any);\n\n    // TODO: 3️⃣ Response validation once migration is complete.\n    return rawRes;\n  };\n}\n","/**\n * Built-in API handlers registry for Payment Kit\n */\n\nimport type { Handler, ApiContext } from '../types/api';\nimport type { RouteOptions } from '../transport/express/BillableRouter';\nimport {\n  handleRecovery,\n  handleCommit,\n  handleHealth,\n  handleAdminStatus,\n  handleAdminClaimTrigger,\n  handleSubRavQuery,\n} from './handlers';\n\nimport { createValidatedHandler } from './utils';\nimport {\n  RecoveryRequestSchema,\n  RecoveryResponseSchema,\n  CommitRequestSchema,\n  CommitResponseSchema,\n  HealthRequestSchema,\n  HealthResponseSchema,\n  SubRavRequestSchema,\n  SubRavResponseSchema,\n  AdminRequestSchema,\n  SystemStatusResponseSchema,\n  ClaimTriggerRequestSchema,\n  ClaimTriggerResponseSchema,\n} from '../schema';\n\n/**\n * Configuration for a built-in API handler\n */\nexport interface ApiHandlerConfig {\n  handler: Handler<ApiContext, any, any>;\n  options: RouteOptions;\n  description?: string;\n  // HTTP method for REST adapters (MCP/JSON-RPC adapters may ignore this)\n  method?: 'GET' | 'POST' | 'DELETE';\n  // REST path for HTTP adapters (other adapters may ignore this)\n  path?: string;\n}\n\n/**\n * Registry of built-in API handlers with their configuration\n * Key format: semantic handler name (protocol agnostic)\n */\nexport const BuiltInApiHandlers: Record<string, ApiHandlerConfig> = {\n  // Note: Discovery endpoint is handled directly in ExpressPaymentKit at root level\n  // to comply with well-known URI RFC specifications\n\n  // Core payment operations\n  recovery: {\n    handler: createValidatedHandler({\n      schema: {\n        request: RecoveryRequestSchema,\n        response: RecoveryResponseSchema,\n      },\n      handler: handleRecovery,\n    }),\n    method: 'GET',\n    path: '/recovery',\n    options: { pricing: '0', authRequired: true },\n    description: 'Recover channel state and pending SubRAV',\n  },\n\n  commit: {\n    handler: createValidatedHandler({\n      schema: {\n        request: CommitRequestSchema,\n        response: CommitResponseSchema,\n      },\n      handler: handleCommit,\n    }),\n    method: 'POST',\n    path: '/commit',\n    options: { pricing: '0', authRequired: true },\n    description: 'Commit a signed SubRAV to the service',\n  },\n\n  // System operations\n  health: {\n    handler: createValidatedHandler({\n      schema: {\n        request: HealthRequestSchema,\n        response: HealthResponseSchema,\n      },\n      handler: handleHealth,\n    }),\n    method: 'GET',\n    path: '/health',\n    options: { pricing: '0', authRequired: false },\n    description: 'Health check endpoint (public)',\n  },\n\n  subravQuery: {\n    handler: createValidatedHandler({\n      schema: {\n        request: SubRavRequestSchema,\n        response: SubRavResponseSchema,\n      },\n      handler: handleSubRavQuery,\n    }),\n    method: 'GET',\n    path: '/subrav',\n    options: { pricing: '0', authRequired: true },\n    description: 'Get SubRAV details (requires auth, users can only query their own)',\n  },\n\n  // Admin operations\n  adminStatus: {\n    handler: createValidatedHandler({\n      schema: {\n        request: AdminRequestSchema,\n        response: SystemStatusResponseSchema,\n      },\n      handler: handleAdminStatus,\n    }),\n    method: 'GET',\n    path: '/admin/status',\n    options: { pricing: '0', adminOnly: true },\n    description: 'Get system internal status (claims, processor, etc.) (admin only)',\n  },\n\n  adminClaimTrigger: {\n    handler: createValidatedHandler({\n      schema: {\n        request: ClaimTriggerRequestSchema,\n        response: ClaimTriggerResponseSchema,\n      },\n      handler: handleAdminClaimTrigger,\n    }),\n    method: 'POST',\n    path: '/admin/claim-trigger',\n    options: { pricing: '0', adminOnly: true },\n    description: 'Manually trigger claim for a specific channel (admin only)',\n  },\n} as const;\n\nexport * from './handlers';\n","import type { IPaymentChannelContract } from '../contracts/IPaymentChannelContract';\nimport { DebugLogger } from '@nuwa-ai/identity-kit';\nimport { Errors } from '../errors/codes';\n\n/**\n * Cache key for PaymentHub balance\n */\nexport interface HubBalanceCacheKey {\n  ownerDid: string;\n  assetId: string;\n}\n\n/**\n * Cached balance value with metadata\n */\nexport interface HubBalanceCacheValue {\n  balance: bigint;\n  updatedAt: number; // ms epoch\n  source: 'onchain' | 'adjusted';\n}\n\n/**\n * Configuration options for HubBalanceService\n */\nexport interface HubBalanceServiceOptions {\n  /** Contract instance for on-chain operations */\n  contract: IPaymentChannelContract;\n\n  /** Default asset ID if not specified in requests */\n  defaultAssetId: string;\n\n  /** Normal cache TTL in milliseconds (default: 5000ms = 5s) */\n  ttlMs?: number;\n\n  /** Negative cache TTL in milliseconds for zero balances (default: 2000ms = 2s) */\n  negativeTtlMs?: number;\n\n  /** Stale-while-revalidate window in milliseconds (default: 30000ms = 30s) */\n  staleWhileRevalidateMs?: number;\n\n  /** Maximum cache entries (LRU eviction, default: 10000) */\n  maxEntries?: number;\n\n  /** Debug logging */\n  debug?: boolean;\n}\n\n/**\n * Internal cache entry with expiration and staleness tracking\n */\ninterface CacheEntry extends HubBalanceCacheValue {\n  expiresAt: number;\n  staleAt: number;\n  isRefreshing?: boolean;\n}\n\n/**\n * Statistics for observability\n */\nexport interface HubBalanceStats {\n  size: number;\n  hits: number;\n  misses: number;\n  staleHits: number;\n  refreshes: number;\n  errors: number;\n}\n\n/**\n * PaymentHub balance service with short TTL caching and SWR (Stale-While-Revalidate)\n *\n * Features:\n * - Short TTL for balance freshness (2-5s recommended)\n * - Negative caching for zero balances (1-2s recommended)\n * - SWR: serve stale data while refreshing in background\n * - LRU eviction to prevent memory leaks\n * - No adjust() method to avoid local truth drift\n */\nexport class HubBalanceService {\n  private readonly contract: IPaymentChannelContract;\n  private readonly defaultAssetId: string;\n  private readonly ttlMs: number;\n  private readonly negativeTtlMs: number;\n  private readonly staleWhileRevalidateMs: number;\n  private readonly maxEntries: number;\n  private readonly logger: DebugLogger;\n\n  // LRU cache: Map maintains insertion order, we'll manage LRU manually\n  private readonly cache = new Map<string, CacheEntry>();\n  private readonly stats: HubBalanceStats = {\n    size: 0,\n    hits: 0,\n    misses: 0,\n    staleHits: 0,\n    refreshes: 0,\n    errors: 0,\n  };\n\n  constructor(options: HubBalanceServiceOptions) {\n    this.contract = options.contract;\n    this.defaultAssetId = options.defaultAssetId;\n    this.ttlMs = options.ttlMs ?? 5000; // 5s\n    this.negativeTtlMs = options.negativeTtlMs ?? 2000; // 2s\n    this.staleWhileRevalidateMs = options.staleWhileRevalidateMs ?? 30000; // 30s\n    this.maxEntries = options.maxEntries ?? 10000;\n\n    this.logger = DebugLogger.get('HubBalanceService');\n    this.logger.setLevel(options.debug ? 'debug' : 'info');\n\n    this.logger.info('HubBalanceService initialized', {\n      ttlMs: this.ttlMs,\n      negativeTtlMs: this.negativeTtlMs,\n      staleWhileRevalidateMs: this.staleWhileRevalidateMs,\n      maxEntries: this.maxEntries,\n    });\n  }\n\n  /**\n   * Get PaymentHub balance with caching and SWR\n   * Priority: cache hit > stale hit (with background refresh) > on-chain fetch\n   */\n  async getBalance(ownerDid: string, assetId?: string): Promise<bigint> {\n    const effectiveAssetId = assetId ?? this.defaultAssetId;\n    const cacheKey = this.buildCacheKey(ownerDid, effectiveAssetId);\n    const now = Date.now();\n\n    const entry = this.cache.get(cacheKey);\n\n    if (entry) {\n      // Move to end (LRU)\n      this.cache.delete(cacheKey);\n      this.cache.set(cacheKey, entry);\n\n      if (now < entry.expiresAt) {\n        // Fresh hit\n        this.stats.hits++;\n        this.logger.debug('Cache hit (fresh)', {\n          ownerDid,\n          assetId: effectiveAssetId,\n          balance: entry.balance.toString(),\n        });\n        return entry.balance;\n      } else if (now < entry.staleAt) {\n        // Stale hit - serve stale data while refreshing in background\n        this.stats.staleHits++;\n        this.logger.debug('Cache hit (stale)', {\n          ownerDid,\n          assetId: effectiveAssetId,\n          balance: entry.balance.toString(),\n        });\n\n        // Trigger background refresh if not already refreshing\n        if (!entry.isRefreshing) {\n          entry.isRefreshing = true;\n          this.refreshInBackground(ownerDid, effectiveAssetId, cacheKey).finally(() => {\n            if (this.cache.has(cacheKey)) {\n              this.cache.get(cacheKey)!.isRefreshing = false;\n            }\n          });\n        }\n\n        return entry.balance;\n      }\n      // Entry is too stale, fall through to fresh fetch\n    }\n\n    // Cache miss or entry too stale\n    this.stats.misses++;\n    this.logger.debug('Cache miss', { ownerDid, assetId: effectiveAssetId });\n\n    return this.fetchAndCache(ownerDid, effectiveAssetId, cacheKey);\n  }\n\n  /**\n   * Force refresh balance from on-chain (bypass cache)\n   */\n  async refresh(ownerDid: string, assetId: string): Promise<bigint> {\n    const cacheKey = this.buildCacheKey(ownerDid, assetId);\n    this.logger.debug('Force refresh', { ownerDid, assetId });\n\n    // Remove existing cache entry\n    this.cache.delete(cacheKey);\n    this.stats.refreshes++;\n\n    return this.fetchAndCache(ownerDid, assetId, cacheKey);\n  }\n\n  /**\n   * Get cache statistics for observability\n   */\n  getStats(): HubBalanceStats {\n    return {\n      ...this.stats,\n      size: this.cache.size,\n    };\n  }\n\n  /**\n   * Clear all cached entries\n   */\n  clear(): void {\n    this.cache.clear();\n    this.logger.info('Cache cleared');\n  }\n\n  /**\n   * Remove specific entry from cache\n   */\n  invalidate(ownerDid: string, assetId?: string): void {\n    const effectiveAssetId = assetId ?? this.defaultAssetId;\n    const cacheKey = this.buildCacheKey(ownerDid, effectiveAssetId);\n    this.cache.delete(cacheKey);\n    this.logger.debug('Cache entry invalidated', { ownerDid, assetId: effectiveAssetId });\n  }\n\n  private buildCacheKey(ownerDid: string, assetId: string): string {\n    return `${ownerDid}:${assetId}`;\n  }\n\n  private async fetchAndCache(\n    ownerDid: string,\n    assetId: string,\n    cacheKey: string\n  ): Promise<bigint> {\n    try {\n      this.logger.debug('Fetching balance from on-chain', { ownerDid, assetId });\n\n      const balance = await this.contract.getHubBalance(ownerDid, assetId);\n      const now = Date.now();\n\n      // Use negative TTL for zero balances\n      const ttl = balance === 0n ? this.negativeTtlMs : this.ttlMs;\n\n      const entry: CacheEntry = {\n        balance,\n        updatedAt: now,\n        source: 'onchain',\n        expiresAt: now + ttl,\n        staleAt: now + this.staleWhileRevalidateMs,\n        isRefreshing: false,\n      };\n\n      this.setCache(cacheKey, entry);\n\n      this.logger.debug('Balance cached', {\n        ownerDid,\n        assetId,\n        balance: balance.toString(),\n        ttl,\n        expiresAt: new Date(entry.expiresAt).toISOString(),\n      });\n\n      return balance;\n    } catch (error) {\n      this.stats.errors++;\n      this.logger.error('Failed to fetch balance', { ownerDid, assetId, error });\n      throw Errors.hubBalanceFetchFailed(error, ownerDid, assetId);\n    }\n  }\n\n  private async refreshInBackground(\n    ownerDid: string,\n    assetId: string,\n    cacheKey: string\n  ): Promise<void> {\n    try {\n      this.logger.debug('Background refresh started', { ownerDid, assetId });\n      await this.fetchAndCache(ownerDid, assetId, cacheKey);\n      this.logger.debug('Background refresh completed', { ownerDid, assetId });\n    } catch (error) {\n      this.logger.warn('Background refresh failed', { ownerDid, assetId, error });\n      // Don't throw - background refresh failures should not affect the response\n    }\n  }\n\n  private setCache(key: string, entry: CacheEntry): void {\n    // Implement LRU eviction\n    if (this.cache.size >= this.maxEntries) {\n      // Remove oldest entry (first in Map)\n      const firstKey = this.cache.keys().next().value;\n      if (firstKey) {\n        this.cache.delete(firstKey);\n        this.logger.debug('LRU eviction', { evictedKey: firstKey });\n      }\n    }\n\n    this.cache.set(key, entry);\n  }\n}\n","import type { IPaymentChannelContract } from '../contracts/IPaymentChannelContract';\nimport type { RAVRepository } from '../storage/interfaces/RAVRepository';\nimport type { ChannelRepository } from '../storage/interfaces/ChannelRepository';\nimport type { SignedSubRAV } from './types';\nimport { DebugLogger, type SignerInterface } from '@nuwa-ai/identity-kit';\n\n/**\n * Claim policy configuration\n */\nexport interface ClaimPolicy {\n  /** Minimum accumulated amount to trigger a claim */\n  minClaimAmount: bigint;\n\n  /** Maximum number of concurrent claims across all sub-channels */\n  maxConcurrentClaims: number;\n\n  /** Maximum retry attempts for failed claims */\n  maxRetries: number;\n\n  /** Delay between retry attempts in milliseconds */\n  retryDelayMs: number;\n\n  /** Whether to check PaymentHub balance before triggering claims */\n  requireHubBalance: boolean;\n\n  /** Fixed backoff when insufficient funds detected (ms) */\n  insufficientFundsBackoffMs: number;\n\n  /** Whether to count insufficient funds as failures in stats */\n  countInsufficientAsFailure: boolean;\n}\n\n/**\n * Default claim policy for reactive claims\n */\nexport const DEFAULT_REACTIVE_CLAIM_POLICY: ClaimPolicy = {\n  // 1 RGas minimum (10,000,000 base units)\n  minClaimAmount: BigInt('10000000'),\n  // Reactive mode can be more aggressive with concurrency\n  maxConcurrentClaims: 10,\n  maxRetries: 3,\n  retryDelayMs: 60_000,\n  requireHubBalance: true,\n  insufficientFundsBackoffMs: 30_000,\n  countInsufficientAsFailure: false,\n};\n\n/**\n * Configuration for ClaimTriggerService\n */\n// Input shape accepts string for minClaimAmount for convenience\nexport type ClaimPolicyInput = Omit<ClaimPolicy, 'minClaimAmount'> & {\n  minClaimAmount: bigint | string;\n};\n\nexport interface ClaimTriggerOptions {\n  /** Claim triggering policy (optional, uses DEFAULT_REACTIVE_CLAIM_POLICY if not provided) */\n  policy?: Partial<ClaimPolicyInput>;\n\n  /** Contract instance for on-chain claim operations */\n  contract: IPaymentChannelContract;\n\n  /** Signer for claim transactions (payee signer) */\n  signer: SignerInterface;\n\n  /** RAV repository to get latest signed SubRAVs */\n  ravRepo: RAVRepository;\n\n  /** Channel repository for SubChannelInfo state updates */\n  channelRepo: ChannelRepository;\n\n  /** Debug logging */\n  debug?: boolean;\n}\n\n/**\n * Claim task in the queue\n */\ninterface ClaimTask {\n  channelId: string;\n  vmIdFragment: string;\n  delta: bigint;\n  attempts: number;\n  nextRetryAt: number;\n  createdAt: number;\n}\n\n/**\n * Statistics for observability\n */\nexport interface ClaimTriggerStats {\n  /** Number of active claims currently processing */\n  active: number;\n\n  /** Number of tasks queued for processing */\n  queued: number;\n\n  /** Total successful claims */\n  successCount: number;\n\n  /** Total failed claims */\n  failedCount: number;\n\n  /** Total skipped claims (e.g., insufficient funds precheck) */\n  skippedCount: number;\n\n  /** Total insufficient funds occurrences */\n  insufficientFundsCount: number;\n\n  /** Number of tasks in backoff (waiting for retry) */\n  backoffCount: number;\n\n  /** Average claim processing time in milliseconds */\n  avgProcessingTimeMs: number;\n\n  /** Claim policy snapshot */\n  policy: ClaimPolicy;\n}\n\n/**\n * Result of a single claim execution attempt\n */\ntype ClaimExecutionResult =\n  | {\n      status: 'skipped';\n      reason:\n        | 'insufficient_funds'\n        | 'below_threshold'\n        | 'concurrency_limit'\n        | 'already_processing'\n        | 'already_queued';\n      context?: Record<string, unknown>;\n    }\n  | {\n      status: 'succeeded';\n      txHash: string;\n      claimedAmount?: bigint;\n    };\n\n/**\n * Event-driven Claim Trigger Service\n *\n * Replaces polling-based ClaimScheduler with reactive claim triggering.\n * Claims are triggered by incoming requests when delta reaches threshold.\n *\n * Features:\n * - Concurrent claim processing with limits\n * - Retry with exponential backoff\n * - Prevents duplicate claims for same sub-channel\n * - Comprehensive statistics and observability\n */\nexport class ClaimTriggerService {\n  private readonly policy: ClaimPolicy;\n  private readonly contract: IPaymentChannelContract;\n  private readonly signer: SignerInterface;\n  private readonly ravRepo: RAVRepository;\n  private readonly channelRepo: ChannelRepository;\n  private readonly logger: DebugLogger;\n\n  // Concurrency control\n  private readonly activeClaims = new Set<string>(); // \"${channelId}:${vmIdFragment}\"\n  private readonly claimQueue = new Map<string, ClaimTask>();\n\n  // Statistics\n  private readonly stats = {\n    successCount: 0,\n    failedCount: 0,\n    skippedCount: 0,\n    insufficientFundsCount: 0,\n    totalProcessingTime: 0,\n  };\n\n  // Processing workers\n  private processingInterval?: NodeJS.Timeout;\n  private readonly processingIntervalMs = 1000; // Check queue every 1s\n\n  constructor(options: ClaimTriggerOptions) {\n    // Merge user policy with defaults, ignoring null/undefined overrides\n    const overrides = options.policy ? this.sanitizePolicy(options.policy) : undefined;\n    this.policy = {\n      ...DEFAULT_REACTIVE_CLAIM_POLICY,\n      ...(overrides || {}),\n    };\n\n    this.contract = options.contract;\n    this.signer = options.signer;\n    this.ravRepo = options.ravRepo;\n    this.channelRepo = options.channelRepo;\n\n    this.logger = DebugLogger.get('ClaimTriggerService');\n    this.logger.setLevel(options.debug ? 'debug' : 'info');\n\n    this.logger.info('ClaimTriggerService initialized', {\n      minClaimAmount: this.policy.minClaimAmount.toString(),\n      maxConcurrentClaims: this.policy.maxConcurrentClaims,\n      maxRetries: this.policy.maxRetries,\n      requireHubBalance: this.policy.requireHubBalance,\n    });\n\n    // Start background processing\n    this.startProcessing();\n  }\n\n  private sanitizePolicy(policy: Partial<ClaimPolicyInput>): Partial<ClaimPolicy> {\n    const result: Partial<ClaimPolicy> = {};\n    for (const [key, value] of Object.entries(policy) as [keyof ClaimPolicyInput, any][]) {\n      if (value == null) continue;\n      if (key === 'minClaimAmount') {\n        (result as any)[key] = typeof value === 'string' ? BigInt(value) : value;\n      } else {\n        (result as any)[key] = value;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Maybe queue a claim based on delta and policy\n   * Called from PaymentProcessor.persist()\n   */\n  async maybeQueue(channelId: string, vmIdFragment: string, delta: bigint): Promise<void> {\n    const key = this.buildKey(channelId, vmIdFragment);\n\n    this.logger.debug('maybeQueue called', {\n      channelId,\n      vmIdFragment,\n      delta: delta.toString(),\n      minClaimAmount: this.policy.minClaimAmount.toString(),\n    });\n\n    // Check if delta meets minimum threshold\n    if (delta < this.policy.minClaimAmount) {\n      this.logger.debug('Delta below threshold, skipping', {\n        delta: delta.toString(),\n        threshold: this.policy.minClaimAmount.toString(),\n      });\n      this.stats.skippedCount++;\n      return;\n    }\n\n    // Check if already processing this sub-channel\n    if (this.activeClaims.has(key)) {\n      this.logger.debug('Claim already in progress, skipping', { channelId, vmIdFragment });\n      this.stats.skippedCount++;\n      return;\n    }\n\n    // Check if already queued\n    if (this.claimQueue.has(key)) {\n      this.logger.debug('Claim already queued, updating delta', {\n        channelId,\n        vmIdFragment,\n        oldDelta: this.claimQueue.get(key)!.delta.toString(),\n        newDelta: delta.toString(),\n      });\n      // Update delta in existing task\n      this.claimQueue.get(key)!.delta = delta;\n      return;\n    }\n\n    // Check global concurrency limit (active + queued)\n    const totalInFlight = this.activeClaims.size + this.claimQueue.size;\n    if (totalInFlight >= this.policy.maxConcurrentClaims) {\n      this.logger.debug('Concurrent claims limit reached, skipping', {\n        totalInFlight,\n        limit: this.policy.maxConcurrentClaims,\n      });\n      this.stats.skippedCount++;\n      return;\n    }\n\n    // Queue the claim task\n    const task: ClaimTask = {\n      channelId,\n      vmIdFragment,\n      delta,\n      attempts: 0,\n      nextRetryAt: Date.now(),\n      createdAt: Date.now(),\n    };\n\n    this.claimQueue.set(key, task);\n    this.logger.info('Claim queued', { channelId, vmIdFragment, delta: delta.toString() });\n  }\n\n  /**\n   * Get current status and statistics\n   */\n  getStatus(): ClaimTriggerStats {\n    const now = Date.now();\n    const backoffCount = Array.from(this.claimQueue.values()).filter(\n      task => task.nextRetryAt > now\n    ).length;\n\n    return {\n      active: this.activeClaims.size,\n      queued: this.claimQueue.size,\n      successCount: this.stats.successCount,\n      failedCount: this.stats.failedCount,\n      skippedCount: this.stats.skippedCount,\n      insufficientFundsCount: this.stats.insufficientFundsCount,\n      backoffCount,\n      avgProcessingTimeMs:\n        this.stats.successCount > 0 ? this.stats.totalProcessingTime / this.stats.successCount : 0,\n      policy: {\n        minClaimAmount: this.policy.minClaimAmount,\n        maxConcurrentClaims: this.policy.maxConcurrentClaims,\n        maxRetries: this.policy.maxRetries,\n        retryDelayMs: this.policy.retryDelayMs,\n        requireHubBalance: this.policy.requireHubBalance,\n        insufficientFundsBackoffMs: this.policy.insufficientFundsBackoffMs,\n        countInsufficientAsFailure: this.policy.countInsufficientAsFailure,\n      },\n    };\n  }\n\n  /**\n   * Getter for current claim policy\n   */\n  getPolicy(): ClaimPolicy {\n    return this.policy;\n  }\n\n  /**\n   * Stop background processing\n   */\n  destroy(): void {\n    if (this.processingInterval) {\n      clearInterval(this.processingInterval);\n      this.processingInterval = undefined;\n    }\n    this.logger.info('ClaimTriggerService destroyed');\n  }\n\n  private buildKey(channelId: string, vmIdFragment: string): string {\n    return `${channelId}:${vmIdFragment}`;\n  }\n\n  /**\n   * Test helper: process the queue immediately once without waiting for interval\n   */\n  async processNow(): Promise<void> {\n    await this.processQueue();\n  }\n\n  private startProcessing(): void {\n    this.processingInterval = setInterval(() => {\n      this.processQueue().catch(error => {\n        this.logger.error('Queue processing error', { error });\n      });\n    }, this.processingIntervalMs);\n  }\n\n  private async processQueue(): Promise<void> {\n    const now = Date.now();\n\n    // Find tasks ready for processing\n    const readyTasks: ClaimTask[] = [];\n    for (const [key, task] of this.claimQueue) {\n      if (task.nextRetryAt <= now && !this.activeClaims.has(key)) {\n        readyTasks.push(task);\n      }\n    }\n\n    if (readyTasks.length === 0) {\n      return;\n    }\n\n    this.logger.debug('Processing queue', { readyTasks: readyTasks.length });\n\n    // Process tasks up to concurrency limit\n    const slotsAvailable = this.policy.maxConcurrentClaims - this.activeClaims.size;\n    const tasksToProcess = readyTasks.slice(0, slotsAvailable);\n\n    for (const task of tasksToProcess) {\n      const key = this.buildKey(task.channelId, task.vmIdFragment);\n\n      // Remove from queue and mark as active\n      this.claimQueue.delete(key);\n      this.activeClaims.add(key);\n\n      // Process task asynchronously\n      this.processClaimTask(task, key).finally(() => {\n        this.activeClaims.delete(key);\n      });\n    }\n  }\n\n  private async processClaimTask(task: ClaimTask, key: string): Promise<void> {\n    const startTime = Date.now();\n    task.attempts++;\n\n    this.logger.info('Processing claim', {\n      channelId: task.channelId,\n      vmIdFragment: task.vmIdFragment,\n      delta: task.delta.toString(),\n      attempt: task.attempts,\n    });\n\n    try {\n      const result = await this.executeClaim(task.channelId, task.vmIdFragment);\n\n      if (result.status === 'succeeded') {\n        // Success\n        const processingTime = Date.now() - startTime;\n        this.stats.successCount++;\n        this.stats.totalProcessingTime += processingTime;\n\n        this.logger.info('Claim successful', {\n          channelId: task.channelId,\n          vmIdFragment: task.vmIdFragment,\n          processingTimeMs: processingTime,\n          txHash: result.txHash,\n        });\n        return;\n      }\n\n      if (result.status === 'skipped') {\n        // Skipped due to preconditions (e.g., insufficient funds)\n        this.stats.skippedCount++;\n        if (result.reason === 'insufficient_funds') {\n          this.stats.insufficientFundsCount++;\n        }\n        // Schedule backoff for insufficient funds\n        const backoffMs =\n          result.reason === 'insufficient_funds'\n            ? this.policy.insufficientFundsBackoffMs\n            : this.policy.retryDelayMs;\n        task.nextRetryAt = Date.now() + backoffMs;\n        this.logger.warn('Claim skipped due to precondition', {\n          channelId: task.channelId,\n          vmIdFragment: task.vmIdFragment,\n          reason: result.reason,\n          backoffMs,\n        });\n        // Re-queue for later\n        this.claimQueue.set(key, task);\n        return;\n      }\n    } catch (error) {\n      this.logger.error('Claim failed', {\n        channelId: task.channelId,\n        vmIdFragment: task.vmIdFragment,\n        attempt: task.attempts,\n        error,\n      });\n\n      // Check if should retry\n      if (task.attempts < this.policy.maxRetries) {\n        // Uniform exponential backoff for unexpected errors.\n        const backoffMs = this.policy.retryDelayMs * Math.pow(2, task.attempts - 1);\n\n        task.nextRetryAt = Date.now() + backoffMs;\n\n        // Re-queue for retry\n        this.claimQueue.set(key, task);\n\n        this.logger.info('Claim scheduled for retry', {\n          channelId: task.channelId,\n          vmIdFragment: task.vmIdFragment,\n          attempt: task.attempts,\n          nextRetryAt: new Date(task.nextRetryAt).toISOString(),\n          backoffMs,\n        });\n      } else {\n        // Max retries reached\n        this.stats.failedCount++;\n        this.logger.error('Claim failed permanently after max retries', {\n          channelId: task.channelId,\n          vmIdFragment: task.vmIdFragment,\n          maxRetries: this.policy.maxRetries,\n        });\n      }\n    }\n  }\n\n  private async executeClaim(\n    channelId: string,\n    vmIdFragment: string\n  ): Promise<ClaimExecutionResult> {\n    this.logger.debug('Executing claim', { channelId, vmIdFragment });\n\n    // Get latest signed SubRAV\n    const latestSignedRAV = await this.ravRepo.getLatest(channelId, vmIdFragment);\n    if (!latestSignedRAV) {\n      throw new Error(`No signed SubRAV found for ${channelId}:${vmIdFragment}`);\n    }\n\n    // Get current sub-channel info for delta calculation\n    const subChannelInfo = await this.channelRepo.getSubChannelState(channelId, vmIdFragment);\n    if (!subChannelInfo) {\n      throw new Error(`No SubChannelInfo found for channel ${channelId}:${vmIdFragment}`);\n    }\n\n    // Get channel metadata to access assetId and payerDid\n    const channelMetadata = await this.channelRepo.getChannelMetadata(channelId);\n    if (!channelMetadata) {\n      throw new Error(`No ChannelInfo found for channel ${channelId}`);\n    }\n\n    // Calculate delta (amount to claim)\n    const accumulatedAmount = latestSignedRAV.subRav.accumulatedAmount;\n    const lastClaimedAmount = subChannelInfo.lastClaimedAmount;\n    const delta =\n      accumulatedAmount > lastClaimedAmount ? accumulatedAmount - lastClaimedAmount : 0n;\n\n    this.logger.debug('Found latest signed SubRAV with detailed info', {\n      channelId,\n      vmIdFragment,\n      nonce: latestSignedRAV.subRav.nonce.toString(),\n      accumulatedAmount: accumulatedAmount.toString(),\n      lastClaimedAmount: lastClaimedAmount.toString(),\n      delta: delta.toString(),\n      assetId: channelMetadata.assetId,\n      payerDid: channelMetadata.payerDid,\n      payeeDid: channelMetadata.payeeDid,\n    });\n\n    // Verify on-chain balance before attempting claim\n    try {\n      const onChainBalance = await this.contract.getHubBalance(\n        channelMetadata.payerDid,\n        channelMetadata.assetId\n      );\n      this.logger.debug('On-chain hub balance verification', {\n        channelId,\n        payerDid: channelMetadata.payerDid,\n        assetId: channelMetadata.assetId,\n        onChainBalance: onChainBalance.toString(),\n        deltaToWithdraw: delta.toString(),\n        sufficient: onChainBalance >= delta,\n        minClaimAmount: this.policy.minClaimAmount.toString(),\n      });\n\n      if (onChainBalance < delta) {\n        this.logger.warn('Insufficient on-chain hub balance detected before claim', {\n          channelId,\n          payerDid: channelMetadata.payerDid,\n          assetId: channelMetadata.assetId,\n          onChainBalance: onChainBalance.toString(),\n          deltaToWithdraw: delta.toString(),\n          deficit: (delta - onChainBalance).toString(),\n        });\n\n        // Return skipped result instead of throwing\n        return {\n          status: 'skipped',\n          reason: 'insufficient_funds',\n          context: {\n            onChainBalance: onChainBalance.toString(),\n            delta: delta.toString(),\n            payerDid: channelMetadata.payerDid,\n            assetId: channelMetadata.assetId,\n          },\n        };\n      }\n    } catch (balanceError) {\n      // For balance API errors, log and continue (do not skip)\n      this.logger.warn('Failed to verify on-chain balance before claim', {\n        channelId,\n        payerDid: channelMetadata.payerDid,\n        assetId: channelMetadata.assetId,\n        error: balanceError instanceof Error ? balanceError.message : String(balanceError),\n      });\n      // Continue with claim attempt\n    }\n\n    // Execute claim on-chain\n    this.logger.debug('Attempting claim on-chain', {\n      channelId,\n      vmIdFragment,\n    });\n\n    const claimResult = await this.contract.claimFromChannel({\n      signedSubRAV: latestSignedRAV,\n      signer: this.signer,\n    });\n\n    this.logger.debug('Claim transaction submitted', {\n      channelId,\n      vmIdFragment,\n      txHash: claimResult.txHash,\n      claimedAmount: claimResult.claimedAmount?.toString(),\n    });\n\n    // Update local state after successful claim\n    await Promise.all([\n      // Update SubChannelInfo state\n      this.channelRepo.updateSubChannelState(channelId, vmIdFragment, {\n        lastClaimedAmount: latestSignedRAV.subRav.accumulatedAmount,\n        lastConfirmedNonce: latestSignedRAV.subRav.nonce,\n        lastUpdated: Date.now(),\n      }),\n\n      // Mark RAV as claimed\n      this.ravRepo.markAsClaimed(channelId, vmIdFragment, latestSignedRAV.subRav.nonce),\n    ]);\n\n    this.logger.debug('Successfully updated local state after claim', {\n      channelId,\n      vmIdFragment,\n      newLastClaimedAmount: latestSignedRAV.subRav.accumulatedAmount.toString(),\n      newLastConfirmedNonce: latestSignedRAV.subRav.nonce.toString(),\n    });\n\n    this.logger.info('Local state updated after claim', {\n      channelId,\n      vmIdFragment,\n      lastClaimedAmount: latestSignedRAV.subRav.accumulatedAmount.toString(),\n      lastConfirmedNonce: latestSignedRAV.subRav.nonce.toString(),\n    });\n\n    return {\n      status: 'succeeded',\n      txHash: claimResult.txHash,\n      claimedAmount: claimResult.claimedAmount,\n    };\n  }\n}\n","import type { Request } from 'express';\n\n/**\n * Determine whether the current HTTP request should be treated as streaming.\n *\n * Heuristics:\n * - Explicit route option: rule.streaming === true\n * - Body flag: body.stream === true\n * - Query flag: ?stream=true\n * - Path hint: contains ':stream' suffix\n */\nexport function isStreamingRequest(req: Request, rule?: { streaming?: boolean }): boolean {\n  const routeStreaming = !!(rule as any)?.streaming;\n  const bodyStreaming = typeof req.body === 'object' && !!(req as any).body?.stream === true;\n  const queryStreaming =\n    typeof req.query === 'object' &&\n    (((req.query as any).stream as any) === 'true' || ((req.query as any).stream as any) === true);\n  const pathStreaming = typeof req.path === 'string' && req.path.includes(':stream');\n  return routeStreaming || bodyStreaming || queryStreaming || pathStreaming;\n}\n","/**\n * IdentityEnv integration for ExpressPaymentKit\n */\n\nimport type { IdentityEnv } from '@nuwa-ai/identity-kit';\nimport { getChainConfigFromEnv } from '../../helpers/fromIdentityEnv';\nimport {\n  createExpressPaymentKit,\n  type ExpressPaymentKitOptions,\n  type ExpressPaymentKit,\n} from './ExpressPaymentKit';\n\n/**\n * Create ExpressPaymentKit using IdentityEnv's KeyManager and chain config\n *\n * @param env IdentityEnv instance\n * @param opts ExpressPaymentKitOptions without signer, rpcUrl, and network (will be provided by env)\n * @returns Promise resolving to configured ExpressPaymentKit instance\n */\nexport async function createExpressPaymentKitFromEnv(\n  env: IdentityEnv,\n  opts: Omit<ExpressPaymentKitOptions, 'signer' | 'rpcUrl' | 'network'>\n): Promise<ExpressPaymentKit> {\n  const chainConfig = getChainConfigFromEnv(env);\n\n  // Type assertion to ensure we have a rooch chain config\n  if (chainConfig.chain !== 'rooch') {\n    throw new Error(\n      `Unsupported chain type: ${chainConfig.chain}. Only 'rooch' is currently supported.`\n    );\n  }\n\n  return createExpressPaymentKit({\n    ...opts,\n    signer: env.keyManager,\n    rpcUrl: chainConfig.rpcUrl,\n    network: chainConfig.network,\n  });\n}\n"],"mappings":"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","names":["vm","express","PaymentErrorCode","import_identity_kit","error","import_identity_kit","import_rooch_sdk","import_identity_kit","import_identity_kit","import_rooch_sdk","import_identity_kit","import_identity_kit","import_identity_kit","SubRAVSchema","import_lossless_json","window","window","import_zod","SubRAVSchema","import_zod","import_zod","import_zod","import_zod","import_zod","import_identity_kit","e","import_identity_kit","import_identity_kit","import_identity_kit","import_identity_kit","import_identity_kit","import_identity_kit","express","import_express","import_identity_kit","import_identity_kit","import_identity_kit","import_identity_kit","express","onHeaders","createSqlStorageRepositories"]}