{"version":3,"sources":["../../src/types/x402-protocol.ts","../../src/utils/helpers.ts","../../src/server/facilitator-client.ts","../../src/server/payment-handler.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { Network } from \"@payai/x402/types\";\n\n/**\n * Solana-specific x402 Protocol Types (v2)\n * These are Solana-only variants of x402 protocol types\n */\n\n// CAIP-2 network identifiers for Solana\nexport const SOLANA_MAINNET_CAIP2 =\n  \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\" as const;\nexport const SOLANA_DEVNET_CAIP2 =\n  \"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1\" as const;\n\n/**\n * Solana network type - supports both simple and CAIP-2 formats\n * Simple: \"solana\" | \"solana-devnet\" (for user-facing config)\n * CAIP-2: \"solana:chainId\" (used in protocol)\n */\nexport type SolanaNetworkSimple = \"solana\" | \"solana-devnet\";\nexport type SolanaNetworkCAIP2 =\n  | typeof SOLANA_MAINNET_CAIP2\n  | typeof SOLANA_DEVNET_CAIP2;\nexport type SolanaNetwork = SolanaNetworkSimple | SolanaNetworkCAIP2;\n\n/**\n * Check if a network string is a Solana network (any format)\n */\nexport function isSolanaNetwork(network: string): network is SolanaNetwork {\n  return (\n    network === \"solana\" ||\n    network === \"solana-devnet\" ||\n    network.startsWith(\"solana:\")\n  );\n}\n\n/**\n * Check if network is mainnet\n */\nexport function isSolanaMainnet(network: string): boolean {\n  return network === \"solana\" || network === SOLANA_MAINNET_CAIP2;\n}\n\n/**\n * Check if network is devnet\n */\nexport function isSolanaDevnet(network: string): boolean {\n  return network === \"solana-devnet\" || network === SOLANA_DEVNET_CAIP2;\n}\n\n/**\n * Convert simple network name to CAIP-2 format\n */\nexport function toCAIP2Network(network: SolanaNetworkSimple): Network {\n  switch (network) {\n    case \"solana\":\n      return SOLANA_MAINNET_CAIP2;\n    case \"solana-devnet\":\n      return SOLANA_DEVNET_CAIP2;\n  }\n}\n\n/**\n * Convert CAIP-2 network to simple name (for display/config)\n */\nexport function toSimpleNetwork(network: string): SolanaNetworkSimple {\n  if (network === SOLANA_MAINNET_CAIP2 || network === \"solana\") {\n    return \"solana\";\n  }\n  return \"solana-devnet\";\n}\n","import type { VersionedTransaction } from \"@solana/web3.js\";\nimport type { PaymentRequirements, PaymentPayload } from \"@payai/x402/types\";\nimport {\n  type TokenAsset,\n  SOLANA_MAINNET_CAIP2,\n  SOLANA_DEVNET_CAIP2,\n  isSolanaMainnet,\n} from \"../types\";\n\n/**\n * Helper utilities for x402 payment processing (v2)\n */\n\n// USDC token addresses\nconst USDC_MAINNET = \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\";\nconst USDC_DEVNET = \"4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU\";\n\n/**\n * Create v2 payment payload from a signed transaction\n * Encodes transaction and payment details for X-PAYMENT header\n *\n * @param transaction - Signed Solana VersionedTransaction\n * @param paymentRequirements - The accepted payment requirements\n * @param resourceUrl - URL of the protected resource\n * @returns Base64-encoded payment payload for X-PAYMENT header\n */\nexport function createPaymentPayload(\n  transaction: VersionedTransaction,\n  paymentRequirements: PaymentRequirements,\n  resourceUrl: string,\n): string {\n  // Serialize the signed transaction to base64\n  const base64Transaction = Buffer.from(transaction.serialize()).toString(\n    \"base64\",\n  );\n\n  // Create v2 payment payload\n  const paymentPayload: PaymentPayload = {\n    x402Version: 2,\n    resource: {\n      url: resourceUrl,\n      description: (paymentRequirements.extra?.description as string) || \"\",\n      mimeType:\n        (paymentRequirements.extra?.mimeType as string) || \"application/json\",\n    },\n    accepted: paymentRequirements,\n    payload: {\n      transaction: base64Transaction,\n    },\n  };\n\n  // Encode payment payload as base64 for X-PAYMENT header\n  const paymentHeader = Buffer.from(JSON.stringify(paymentPayload)).toString(\n    \"base64\",\n  );\n\n  return paymentHeader;\n}\n\n/**\n * Get default RPC URL for a given Solana network\n * @param network - Network in any format (simple or CAIP-2)\n * @returns Default RPC URL for the network\n */\nexport function getDefaultRpcUrl(network: string): string {\n  if (isSolanaMainnet(network)) {\n    return \"https://api.mainnet-beta.solana.com\";\n  }\n  return \"https://api.devnet.solana.com\";\n}\n\n/**\n * Get RPC URL for a CAIP-2 network identifier\n * @param network - Network in CAIP-2 format (e.g., \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\")\n * @returns RPC URL for the network\n */\nexport function getRpcUrlForNetwork(network: string): string {\n  if (network === SOLANA_MAINNET_CAIP2) {\n    return \"https://api.mainnet-beta.solana.com\";\n  }\n  if (network === SOLANA_DEVNET_CAIP2) {\n    return \"https://api.devnet.solana.com\";\n  }\n  // Fallback for unknown networks\n  return \"https://api.devnet.solana.com\";\n}\n\n/**\n * Get default USDC token asset for a given Solana network\n * @param network - Network in any format (simple or CAIP-2)\n * @returns USDC token asset configuration\n */\nexport function getDefaultTokenAsset(network: string): TokenAsset {\n  if (isSolanaMainnet(network)) {\n    return {\n      address: USDC_MAINNET,\n      decimals: 6,\n    };\n  }\n  return {\n    address: USDC_DEVNET,\n    decimals: 6,\n  };\n}\n\n/**\n * Convert human-readable amount to token's smallest unit (atomic units)\n * @param amount - Human-readable amount (e.g., 2.5 for 2.5 USDC)\n * @param decimals - Token decimals (e.g., 6 for USDC, 9 for SOL)\n * @returns Amount in atomic units as string\n */\nexport function toAtomicUnits(amount: number, decimals: number): string {\n  return Math.floor(amount * Math.pow(10, decimals)).toString();\n}\n\n/**\n * Convert token's atomic units to human-readable amount\n * @param atomicUnits - Token amount in smallest units (as string or bigint)\n * @param decimals - Token decimals (e.g., 6 for USDC, 9 for SOL)\n * @returns Human-readable amount\n */\nexport function fromAtomicUnits(\n  atomicUnits: string | bigint | number,\n  decimals: number,\n): number {\n  return Number(atomicUnits) / Math.pow(10, decimals);\n}\n","import type {\n  PaymentRequirements,\n  PaymentPayload,\n  VerifyResponse,\n  SettleResponse,\n  SupportedResponse,\n} from \"@payai/x402/types\";\nimport { isSolanaNetwork } from \"../types\";\n\n/**\n * Facilitator supported kind (from /supported endpoint)\n */\ninterface SupportedKind {\n  x402Version: number;\n  scheme: string;\n  network: string;\n  extra?: {\n    feePayer?: string;\n    [key: string]: unknown;\n  };\n}\n\n/**\n * Client for communicating with x402 facilitator service (v2)\n */\nexport class FacilitatorClient {\n  constructor(private facilitatorUrl: string) {}\n\n  /**\n   * Get supported payment kinds from facilitator\n   */\n  async getSupported(): Promise<SupportedResponse> {\n    const response = await fetch(`${this.facilitatorUrl}/supported`);\n    if (!response.ok) {\n      throw new Error(`Facilitator /supported returned ${response.status}`);\n    }\n    return response.json();\n  }\n\n  /**\n   * Get fee payer address for a Solana network\n   * @param network - Network in any format (simple or CAIP-2)\n   */\n  async getFeePayer(network: string): Promise<string> {\n    const supportedData = await this.getSupported();\n\n    // Look for network support - match by CAIP-2 prefix for Solana networks\n    const networkSupport = (supportedData.kinds as SupportedKind[])?.find(\n      (kind) =>\n        kind.scheme === \"exact\" &&\n        isSolanaNetwork(kind.network) &&\n        isSolanaNetwork(network) &&\n        // Match if both are same network type (mainnet or devnet)\n        (kind.network.includes(\"devnet\") === network.includes(\"devnet\") ||\n          kind.network === network),\n    );\n\n    if (!networkSupport?.extra?.feePayer) {\n      throw new Error(\n        `Facilitator does not support network \"${network}\" with scheme \"exact\" or feePayer not provided`,\n      );\n    }\n\n    return networkSupport.extra.feePayer;\n  }\n\n  /**\n   * Verify payment with facilitator\n   * @returns VerifyResponse with isValid and optional invalidReason\n   */\n  async verifyPayment(\n    paymentHeader: string,\n    paymentRequirements: PaymentRequirements,\n  ): Promise<VerifyResponse> {\n    try {\n      // Decode the base64 payment payload\n      const paymentPayload: PaymentPayload = JSON.parse(\n        Buffer.from(paymentHeader, \"base64\").toString(\"utf8\"),\n      );\n\n      const verifyPayload = {\n        paymentPayload,\n        paymentRequirements,\n      };\n\n      const response = await fetch(`${this.facilitatorUrl}/verify`, {\n        method: \"POST\",\n        headers: {\n          \"Content-Type\": \"application/json\",\n        },\n        body: JSON.stringify(verifyPayload),\n      });\n\n      if (!response.ok) {\n        const errorBody = await response.text();\n        console.error(\n          `Facilitator /verify returned ${response.status}:`,\n          errorBody,\n        );\n        return {\n          isValid: false,\n          invalidReason: \"unexpected_verify_error\",\n        };\n      }\n\n      // Facilitator returns VerifyResponse with status 200 even when validation fails\n      const facilitatorResponse: VerifyResponse = await response.json();\n      return facilitatorResponse;\n    } catch (error) {\n      console.error(\"Payment verification failed:\", error);\n      return {\n        isValid: false,\n        invalidReason: \"unexpected_verify_error\",\n      };\n    }\n  }\n\n  /**\n   * Settle payment with facilitator\n   * @returns SettleResponse with success status and optional errorReason\n   */\n  async settlePayment(\n    paymentHeader: string,\n    paymentRequirements: PaymentRequirements,\n  ): Promise<SettleResponse> {\n    try {\n      // Decode the base64 payment payload\n      const paymentPayload: PaymentPayload = JSON.parse(\n        Buffer.from(paymentHeader, \"base64\").toString(\"utf8\"),\n      );\n\n      const settlePayload = {\n        paymentPayload,\n        paymentRequirements,\n      };\n\n      const response = await fetch(`${this.facilitatorUrl}/settle`, {\n        method: \"POST\",\n        headers: {\n          \"Content-Type\": \"application/json\",\n        },\n        body: JSON.stringify(settlePayload),\n      });\n\n      if (!response.ok) {\n        const errorBody = await response.text();\n        console.error(\n          `Facilitator /settle returned ${response.status}:`,\n          errorBody,\n        );\n        return {\n          success: false,\n          errorReason: \"unexpected_settle_error\",\n          transaction: \"\",\n          network: paymentRequirements.network,\n        };\n      }\n\n      // Facilitator returns SettleResponse with status 200 even when settlement fails\n      const facilitatorResponse: SettleResponse = await response.json();\n      return facilitatorResponse;\n    } catch (error) {\n      console.error(\"Payment settlement failed:\", error);\n      return {\n        success: false,\n        errorReason: \"unexpected_settle_error\",\n        transaction: \"\",\n        network: paymentRequirements.network,\n      };\n    }\n  }\n}\n","import type {\n  PaymentRequirements,\n  PaymentRequired,\n  VerifyResponse,\n  SettleResponse,\n  Network,\n} from \"@payai/x402/types\";\nimport type { X402ServerConfig, RouteConfig, TokenAsset } from \"../types\";\nimport { toCAIP2Network } from \"../types\";\nimport { getDefaultRpcUrl, getDefaultTokenAsset } from \"../utils\";\nimport { FacilitatorClient } from \"./facilitator-client\";\n\n/**\n * Internal configuration with defaults resolved\n */\ninterface InternalConfig {\n  network: string; // CAIP-2 format\n  treasuryAddress: string;\n  facilitatorUrl: string;\n  rpcUrl: string;\n  defaultToken: TokenAsset;\n  defaultDescription: string;\n  defaultTimeoutSeconds: number;\n}\n\n/**\n * x402 Payment Handler for server-side payment processing (v2)\n * Framework agnostic - works with any Node.js HTTP framework\n */\nexport class X402PaymentHandler {\n  private facilitatorClient: FacilitatorClient;\n  private config: InternalConfig;\n\n  constructor(config: X402ServerConfig) {\n    const defaultToken =\n      config.defaultToken || getDefaultTokenAsset(config.network);\n\n    this.config = {\n      network: toCAIP2Network(config.network),\n      treasuryAddress: config.treasuryAddress,\n      facilitatorUrl: config.facilitatorUrl,\n      rpcUrl: config.rpcUrl || getDefaultRpcUrl(config.network),\n      defaultToken,\n      defaultDescription: config.defaultDescription || \"Payment required\",\n      defaultTimeoutSeconds: config.defaultTimeoutSeconds || 300,\n    };\n\n    this.facilitatorClient = new FacilitatorClient(config.facilitatorUrl);\n  }\n\n  /**\n   * Extract payment header from request headers (v2)\n   * Pass in headers object from any framework (Next.js, Express, etc.)\n   *\n   * Note: v2 uses PAYMENT-SIGNATURE header (v1 used X-PAYMENT)\n   */\n  extractPayment(\n    headers: Record<string, string | string[] | undefined> | Headers,\n  ): string | null {\n    // Handle Headers object (Next.js, Fetch API)\n    if (headers instanceof Headers) {\n      // v2 header (PAYMENT-SIGNATURE)\n      return (\n        headers.get(\"PAYMENT-SIGNATURE\") || headers.get(\"payment-signature\")\n      );\n    }\n\n    // Handle plain object (Express, Fastify, etc.)\n    // v2 header (PAYMENT-SIGNATURE)\n    const paymentSignature =\n      headers[\"PAYMENT-SIGNATURE\"] || headers[\"payment-signature\"];\n    return Array.isArray(paymentSignature)\n      ? paymentSignature[0] || null\n      : paymentSignature || null;\n  }\n\n  /**\n   * Create payment requirements for a protected resource\n   *\n   * @param routeConfig - Route-specific configuration\n   * @param resourceUrl - URL of the protected resource\n   * @returns Payment requirements object\n   */\n  async createPaymentRequirements(\n    routeConfig: RouteConfig,\n    resourceUrl: string,\n  ): Promise<PaymentRequirements> {\n    // Get fee payer from facilitator\n    const feePayer = await this.facilitatorClient.getFeePayer(\n      this.config.network,\n    );\n\n    const paymentRequirements: PaymentRequirements = {\n      scheme: \"exact\",\n      network: this.config.network as Network,\n      amount: routeConfig.amount,\n      payTo: this.config.treasuryAddress,\n      maxTimeoutSeconds:\n        routeConfig.maxTimeoutSeconds || this.config.defaultTimeoutSeconds,\n      asset: routeConfig.asset.address,\n      extra: {\n        feePayer,\n        description: routeConfig.description || this.config.defaultDescription,\n        mimeType: routeConfig.mimeType || \"application/json\",\n        resource: resourceUrl,\n      },\n    };\n\n    return paymentRequirements;\n  }\n\n  /**\n   * Create a 402 Payment Required response body (v2)\n   * Use this with your framework's response method\n   *\n   * @param requirements - Payment requirements (from createPaymentRequirements)\n   * @param resourceUrl - URL of the protected resource\n   */\n  create402Response(\n    requirements: PaymentRequirements,\n    resourceUrl: string,\n  ): {\n    status: 402;\n    body: PaymentRequired;\n  } {\n    return {\n      status: 402,\n      body: {\n        x402Version: 2,\n        resource: {\n          url: resourceUrl,\n          description: (requirements.extra?.description as string) || \"\",\n          mimeType:\n            (requirements.extra?.mimeType as string) || \"application/json\",\n        },\n        accepts: [requirements],\n        error: \"Payment required\",\n      },\n    };\n  }\n\n  /**\n   * Verify payment with facilitator\n   * @returns VerifyResponse with isValid and optional invalidReason\n   */\n  async verifyPayment(\n    paymentHeader: string,\n    paymentRequirements: PaymentRequirements,\n  ): Promise<VerifyResponse> {\n    return this.facilitatorClient.verifyPayment(\n      paymentHeader,\n      paymentRequirements,\n    );\n  }\n\n  /**\n   * Settle payment with facilitator\n   * @returns SettleResponse with success status and optional errorReason\n   */\n  async settlePayment(\n    paymentHeader: string,\n    paymentRequirements: PaymentRequirements,\n  ): Promise<SettleResponse> {\n    return this.facilitatorClient.settlePayment(\n      paymentHeader,\n      paymentRequirements,\n    );\n  }\n\n  /**\n   * Get the network in CAIP-2 format\n   */\n  getNetwork(): string {\n    return this.config.network;\n  }\n\n  /**\n   * Get the treasury address\n   */\n  getTreasuryAddress(): string {\n    return this.config.treasuryAddress;\n  }\n}\n"]}