{"version":3,"sources":["../../src/types/x402-protocol.ts","../../src/utils/helpers.ts","../../src/client/transaction-builder.ts","../../src/client/payment-interceptor.ts","../../src/client/index.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 PAYMENT-SIGNATURE 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 PAYMENT-SIGNATURE 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 PAYMENT-SIGNATURE header\n  const paymentHeader = Buffer.from(JSON.stringify(paymentPayload)).toString('base64');\n\n  return paymentHeader;\n}\n\n/**\n * Create v1 payment payload from a signed transaction\n * Encodes transaction for X-PAYMENT header (v1 format)\n *\n * @param transaction - Signed Solana VersionedTransaction\n * @param paymentRequirements - The accepted payment requirements\n * @returns Base64-encoded payment payload for X-PAYMENT header\n */\nexport function createPaymentPayloadV1(\n  transaction: VersionedTransaction,\n  paymentRequirements: PaymentRequirements\n): string {\n  // Serialize the signed transaction to base64\n  const base64Transaction = Buffer.from(transaction.serialize()).toString('base64');\n\n  // Create v1 payment payload (simpler format)\n  const paymentPayload = {\n    x402Version: 1,\n    scheme: paymentRequirements.scheme,\n    network: paymentRequirements.network,\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 {\n  PublicKey,\n  Connection,\n  TransactionMessage,\n  VersionedTransaction,\n  ComputeBudgetProgram,\n  type TransactionInstruction,\n} from \"@solana/web3.js\";\nimport {\n  getAssociatedTokenAddress,\n  createTransferCheckedInstruction,\n  getMint,\n  TOKEN_PROGRAM_ID,\n  TOKEN_2022_PROGRAM_ID,\n} from \"@solana/spl-token\";\nimport type { PaymentRequirements } from \"@payai/x402/types\";\nimport type { WalletAdapter } from \"../types\";\n\n// Constants for compute budget\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 20_000; // Sufficient for SPL token transfer\nconst DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1; // Minimal price\n\n/**\n * Build and sign a Solana transaction for x402 payment (v2)\n *\n * @param wallet - Wallet adapter for signing\n * @param paymentRequirements - Payment requirements from server\n * @param rpcUrl - Solana RPC URL\n * @returns Signed VersionedTransaction ready to be serialized\n */\nexport async function createSolanaPaymentTransaction(\n  wallet: WalletAdapter,\n  paymentRequirements: PaymentRequirements,\n  rpcUrl: string,\n): Promise<VersionedTransaction> {\n  const connection = new Connection(rpcUrl, \"confirmed\");\n\n  // Extract fee payer from payment requirements\n  const feePayer = paymentRequirements.extra?.feePayer as string | undefined;\n  if (!feePayer) {\n    throw new Error(\n      \"Missing facilitator feePayer in payment requirements (extra.feePayer).\",\n    );\n  }\n  const feePayerPubkey = new PublicKey(feePayer);\n\n  // Get wallet address - support both Anza wallet-adapter (publicKey) and custom implementations (address)\n  const walletAddress = wallet?.publicKey?.toString() || wallet?.address;\n  if (!walletAddress) {\n    throw new Error(\"Missing connected Solana wallet address or publicKey\");\n  }\n  const userPubkey = new PublicKey(walletAddress);\n\n  // Get destination (payTo)\n  if (!paymentRequirements.payTo) {\n    throw new Error(\"Missing payTo in payment requirements\");\n  }\n  const destination = new PublicKey(paymentRequirements.payTo);\n\n  // Get token mint\n  if (!paymentRequirements.asset) {\n    throw new Error(\"Missing token mint for SPL transfer\");\n  }\n  const mintPubkey = new PublicKey(paymentRequirements.asset);\n\n  const instructions: TransactionInstruction[] = [];\n\n  // The facilitator REQUIRES ComputeBudget instructions in positions 0 and 1\n  instructions.push(\n    ComputeBudgetProgram.setComputeUnitLimit({\n      units: DEFAULT_COMPUTE_UNIT_LIMIT,\n    }),\n  );\n\n  instructions.push(\n    ComputeBudgetProgram.setComputeUnitPrice({\n      microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n    }),\n  );\n\n  // Determine program (token vs token-2022) by reading mint owner\n  const mintInfo = await connection.getAccountInfo(mintPubkey, \"confirmed\");\n  const programId =\n    mintInfo?.owner?.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n      ? TOKEN_2022_PROGRAM_ID\n      : TOKEN_PROGRAM_ID;\n\n  // Fetch mint to get decimals\n  const mint = await getMint(connection, mintPubkey, undefined, programId);\n\n  // Derive source and destination ATAs\n  const sourceAta = await getAssociatedTokenAddress(\n    mintPubkey,\n    userPubkey,\n    false,\n    programId,\n  );\n  const destinationAta = await getAssociatedTokenAddress(\n    mintPubkey,\n    destination,\n    false,\n    programId,\n  );\n\n  // Check if source ATA exists (user must already have token account)\n  const sourceAtaInfo = await connection.getAccountInfo(sourceAta, \"confirmed\");\n  if (!sourceAtaInfo) {\n    throw new Error(\n      `User does not have an Associated Token Account for ${paymentRequirements.asset}. Please create one first or ensure you have the required token.`,\n    );\n  }\n\n  // Check if destination ATA exists (receiver must already have token account)\n  const destAtaInfo = await connection.getAccountInfo(\n    destinationAta,\n    \"confirmed\",\n  );\n  if (!destAtaInfo) {\n    throw new Error(\n      `Destination does not have an Associated Token Account for ${paymentRequirements.asset}. The receiver must create their token account before receiving payments.`,\n    );\n  }\n\n  // Get payment amount - v2 uses `amount`, support legacy `maxAmountRequired` for compatibility\n  const amountStr =\n    paymentRequirements.amount ||\n    (paymentRequirements as unknown as { maxAmountRequired?: string })\n      .maxAmountRequired;\n\n  if (!amountStr) {\n    throw new Error(\"Missing amount in payment requirements\");\n  }\n  const amount = BigInt(amountStr);\n\n  // TransferChecked instruction\n  instructions.push(\n    createTransferCheckedInstruction(\n      sourceAta,\n      mintPubkey,\n      destinationAta,\n      userPubkey,\n      amount,\n      mint.decimals,\n      [],\n      programId,\n    ),\n  );\n\n  // Get recent blockhash\n  const { blockhash } = await connection.getLatestBlockhash(\"confirmed\");\n\n  const message = new TransactionMessage({\n    payerKey: feePayerPubkey,\n    recentBlockhash: blockhash,\n    instructions,\n  }).compileToV0Message();\n\n  // Create transaction\n  const transaction = new VersionedTransaction(message);\n\n  // Sign with user's wallet\n  if (typeof wallet?.signTransaction !== \"function\") {\n    throw new Error(\"Connected wallet does not support signTransaction\");\n  }\n\n  const userSignedTx = await wallet.signTransaction(transaction);\n\n  return userSignedTx;\n}\n","import type { PaymentRequirements, PaymentRequired } from \"@payai/x402/types\";\nimport { safeBase64Decode } from \"@payai/x402/utils\";\nimport type { WalletAdapter } from \"../types\";\nimport { isSolanaNetwork } from \"../types\";\nimport { createSolanaPaymentTransaction } from \"./transaction-builder\";\nimport { createPaymentPayload, createPaymentPayloadV1 } from \"../utils\";\n\n/**\n * x402 Response structure (v1 body format)\n */\ninterface X402ResponseV1 extends PaymentRequired {\n  accepts: PaymentRequirements[];\n}\n\n/**\n * Decode a base64-encoded PAYMENT-REQUIRED header\n */\nfunction decodePaymentRequiredHeader(header: string): PaymentRequired {\n  const decoded = safeBase64Decode(header);\n  return JSON.parse(decoded) as PaymentRequired;\n}\n\n/**\n * Create a custom fetch function that automatically handles x402 payments (v2)\n *\n * @param fetchFn - Base fetch function to use\n * @param wallet - Wallet adapter for signing transactions\n * @param rpcUrl - Solana RPC URL\n * @param maxValue - Maximum payment amount in atomic units (0 = no limit)\n * @param verbose - Enable verbose logging (default: false)\n * @returns Wrapped fetch function with automatic payment handling\n */\nexport function createPaymentFetch(\n  fetchFn: typeof fetch,\n  wallet: WalletAdapter,\n  rpcUrl: string,\n  maxValue: bigint = BigInt(0),\n  verbose: boolean = false,\n) {\n  const log = (...args: unknown[]) => {\n    if (verbose) console.log(\"[x402-solana]\", ...args);\n  };\n\n  return async (input: RequestInfo, init?: RequestInit): Promise<Response> => {\n    const url = typeof input === \"string\" ? input : input.url;\n    log(\"Making initial request to:\", url);\n\n    // Make initial request\n    const response = await fetchFn(input, init);\n    log(\"Initial response status:\", response.status);\n\n    // If not 402, return as-is\n    if (response.status !== 402) {\n      return response;\n    }\n\n    log(\"Got 402, parsing payment requirements...\");\n\n    // Parse payment requirements from 402 response\n    // v2: Read from PAYMENT-REQUIRED header (base64-encoded)\n    // v1 fallback: Read from response body\n    let paymentRequired: PaymentRequired;\n    let protocolVersion: 1 | 2;\n\n    const paymentRequiredHeader = response.headers.get(\"PAYMENT-REQUIRED\");\n    if (paymentRequiredHeader) {\n      // v2: Decode from header\n      log(\"Found PAYMENT-REQUIRED header (v2 protocol)\");\n      paymentRequired = decodePaymentRequiredHeader(paymentRequiredHeader);\n      protocolVersion = 2;\n    } else {\n      // v1 fallback: Parse from body\n      log(\"No PAYMENT-REQUIRED header, falling back to body (v1 protocol)\");\n      const rawResponse = (await response.json()) as X402ResponseV1;\n      paymentRequired = rawResponse;\n      protocolVersion = 1;\n    }\n\n    log(\"Payment requirements:\", JSON.stringify(paymentRequired, null, 2));\n    log(\"Protocol version:\", protocolVersion);\n\n    const parsedPaymentRequirements: PaymentRequirements[] =\n      paymentRequired.accepts || [];\n\n    // Select first suitable payment requirement for Solana\n    // Supports both simple format (\"solana\", \"solana-devnet\") and CAIP-2 format (\"solana:chainId\")\n    const selectedRequirements = parsedPaymentRequirements.find(\n      (req: PaymentRequirements) =>\n        req.scheme === \"exact\" && isSolanaNetwork(req.network),\n    );\n\n    if (!selectedRequirements) {\n      console.error(\n        \"❌ No suitable Solana payment requirements found. Available networks:\",\n        parsedPaymentRequirements.map((req) => req.network),\n      );\n      throw new Error(\"No suitable Solana payment requirements found\");\n    }\n\n    // Check amount against max value if specified\n    // v2 uses `amount`, but we also support legacy `maxAmountRequired` for backwards compatibility\n    const paymentAmount = BigInt(\n      selectedRequirements.amount ||\n        (selectedRequirements as unknown as { maxAmountRequired?: string })\n          .maxAmountRequired ||\n        \"0\",\n    );\n\n    if (maxValue > BigInt(0) && paymentAmount > maxValue) {\n      throw new Error(\"Payment amount exceeds maximum allowed\");\n    }\n\n    // Get the resource URL for the payment payload\n    const resourceUrl = typeof input === \"string\" ? input : input.url;\n\n    log(\"Creating signed transaction...\");\n\n    // Create signed transaction\n    const signedTransaction = await createSolanaPaymentTransaction(\n      wallet,\n      selectedRequirements,\n      rpcUrl,\n    );\n    log(\"Transaction signed successfully\");\n\n    // Create payment payload based on protocol version\n    let paymentHeader: string;\n    let headerName: string;\n\n    if (protocolVersion === 2) {\n      // v2: Use PAYMENT-SIGNATURE header with full payload\n      paymentHeader = createPaymentPayload(\n        signedTransaction,\n        selectedRequirements,\n        resourceUrl,\n      );\n      headerName = \"PAYMENT-SIGNATURE\";\n    } else {\n      // v1: Use X-PAYMENT header with simpler payload\n      paymentHeader = createPaymentPayloadV1(\n        signedTransaction,\n        selectedRequirements,\n      );\n      headerName = \"X-PAYMENT\";\n    }\n\n    log(\"Payment header created, length:\", paymentHeader.length);\n    log(\"Using header:\", headerName);\n\n    // Retry with appropriate payment header\n    const newInit = {\n      ...init,\n      headers: {\n        ...(init?.headers || {}),\n        [headerName]: paymentHeader,\n      },\n    };\n\n    log(`Retrying request with ${headerName} header...`);\n    const retryResponse = await fetchFn(input, newInit);\n    log(\"Retry response status:\", retryResponse.status);\n\n    return retryResponse;\n  };\n}\n","import type { X402ClientConfig } from \"../types\";\nimport { getDefaultRpcUrl } from \"../utils\";\nimport { createPaymentFetch } from \"./payment-interceptor\";\n\n/**\n * x402 Solana Client (v2)\n * Handles automatic payment for x402-protected endpoints\n */\nexport class X402Client {\n  private paymentFetch: ReturnType<typeof createPaymentFetch>;\n\n  constructor(config: X402ClientConfig) {\n    const rpcUrl = config.rpcUrl || getDefaultRpcUrl(config.network);\n\n    // Use custom fetch if provided, otherwise use native fetch\n    // globalThis.fetch works in both browser and Node.js (18+)\n    const fetchFn = config.customFetch || globalThis.fetch.bind(globalThis);\n\n    this.paymentFetch = createPaymentFetch(\n      fetchFn,\n      config.wallet,\n      rpcUrl,\n      config.amount || BigInt(0),\n      config.verbose || false,\n    );\n  }\n\n  /**\n   * Make a fetch request with automatic x402 payment handling.\n   * If a customFetch was provided in the config, it will be used for all requests.\n   */\n  async fetch(input: RequestInfo, init?: RequestInit): Promise<Response> {\n    return this.paymentFetch(input, init);\n  }\n}\n\n/**\n * Create an x402 client instance\n */\nexport function createX402Client(config: X402ClientConfig): X402Client {\n  return new X402Client(config);\n}\n\n// Re-export types for convenience\nexport type { X402ClientConfig, WalletAdapter } from \"../types\";\n"]}