@relai-fi/x402 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +96 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.js +100 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/server.ts","../src/client.ts","../src/relay-feedback.ts","../src/utils/payload-converter.ts"],"sourcesContent":["// src/types.ts\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** RelAI Facilitator URL */\nexport const RELAI_FACILITATOR_URL = 'https://facilitator.x402.fi';\n\n// ============================================================================\n// Supported Networks\n// ============================================================================\n\n/** All networks supported by RelAI facilitator */\nexport type RelaiNetwork =\n | 'solana'\n | 'solana-devnet'\n | 'base'\n | 'avalanche'\n | 'skale-base'\n | 'skale-base-sepolia'\n | 'skale-bite'\n | 'polygon'\n | 'ethereum'\n | 'telos';\n\n/** CAIP-2 network identifiers */\nexport const NETWORK_CAIP2: Record<RelaiNetwork, string> = {\n 'solana': 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n 'solana-devnet': 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n 'base': 'eip155:8453',\n 'avalanche': 'eip155:43114',\n 'skale-base': 'eip155:1187947933',\n 'skale-base-sepolia': 'eip155:324705682',\n 'skale-bite': 'eip155:103698795',\n 'polygon': 'eip155:137',\n 'ethereum': 'eip155:1',\n 'telos': 'eip155:40',\n};\n\n/** Reverse lookup: CAIP-2 → simple network name */\nexport const CAIP2_TO_NETWORK: Record<string, RelaiNetwork> = Object.fromEntries(\n Object.entries(NETWORK_CAIP2).map(([k, v]) => [v, k as RelaiNetwork])\n) as Record<string, RelaiNetwork>;\n\n/** Chain IDs for EVM networks */\nexport const CHAIN_IDS: Record<string, number> = {\n 'base': 8453,\n 'avalanche': 43114,\n 'skale-base': 1187947933,\n 'skale-base-sepolia': 324705682,\n 'skale-bite': 103698795,\n 'polygon': 137,\n 'ethereum': 1,\n 'telos': 40,\n};\n\nexport interface NetworkToken {\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n domainVersion?: string;\n isStableUsd?: boolean;\n standards?: string[];\n}\n\n/** Token metadata per network (default token is always the first entry) */\nexport const NETWORK_TOKENS: Partial<Record<RelaiNetwork, NetworkToken[]>> = {\n 'solana': [\n {\n address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',\n symbol: 'USDC',\n name: 'USD Coin',\n decimals: 6,\n },\n ],\n 'solana-devnet': [\n {\n address: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',\n symbol: 'USDC',\n name: 'USD Coin (Devnet)',\n decimals: 6,\n },\n ],\n 'base': [\n { address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', symbol: 'USDC', name: 'USD Coin', decimals: 6, domainVersion: '2', isStableUsd: true },\n ],\n 'avalanche': [\n {\n address: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n symbol: 'USDC',\n name: 'USD Coin',\n decimals: 6,\n domainVersion: '2',\n isStableUsd: true,\n },\n ],\n 'telos': [\n {\n address: '0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b',\n symbol: 'USDC',\n name: 'USD Coin',\n decimals: 6,\n isStableUsd: true,\n standards: ['eip2612'],\n },\n ],\n 'skale-base': [\n {\n address: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n symbol: 'USDC',\n name: 'Bridged USDC (SKALE Bridge)',\n decimals: 6,\n domainVersion: '2',\n isStableUsd: true,\n },\n {\n address: '0x2bF5bF154b515EaA82C31a65ec11554fF5aF7fCA',\n symbol: 'USDT',\n name: 'Bridged USDT (SKALE Bridge)',\n decimals: 6,\n domainVersion: '1',\n isStableUsd: true,\n },\n {\n address: '0x1aeeCFE5454c83B42D8A316246CAc9739E7f690e',\n symbol: 'WBTC',\n name: 'Wrapped Bitcoin',\n decimals: 8,\n domainVersion: '1',\n isStableUsd: false,\n },\n {\n address: '0x7bD39ABBd0Dd13103542cAe3276C7fA332bCA486',\n symbol: 'WETH',\n name: 'Wrapped Ether',\n decimals: 18,\n domainVersion: '1',\n isStableUsd: false,\n },\n ],\n 'skale-base-sepolia': [\n {\n address: '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n symbol: 'USDC',\n name: 'Bridged USDC (SKALE Bridge)',\n decimals: 6,\n domainVersion: '2',\n isStableUsd: true,\n },\n {\n address: '0x3ca0a49f511c2c89c4dcbbf1731120d8919050bf',\n symbol: 'USDT',\n name: 'Bridged USDT (SKALE Bridge)',\n decimals: 6,\n domainVersion: '1',\n isStableUsd: true,\n },\n {\n address: '0x4512eacd4186b025186e1cf6cc0d89497c530e87',\n symbol: 'WBTC',\n name: 'Wrapped Bitcoin',\n decimals: 8,\n domainVersion: '1',\n isStableUsd: false,\n },\n {\n address: '0xf94056bd7f6965db3757e1b145f200b7346b4fc0',\n symbol: 'WETH',\n name: 'Wrapped Ether',\n decimals: 18,\n domainVersion: '1',\n isStableUsd: false,\n },\n ],\n 'skale-bite': [\n {\n address: '0xc4083B1E81ceb461Ccef3FDa8A9F24F0d764B6D8',\n symbol: 'USDC',\n name: 'USDC',\n decimals: 6,\n domainVersion: '1',\n isStableUsd: true,\n },\n ],\n 'polygon': [\n {\n address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n symbol: 'USDC',\n name: 'USD Coin',\n decimals: 6,\n domainVersion: '2',\n isStableUsd: true,\n },\n ],\n 'ethereum': [\n {\n address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n symbol: 'USDC',\n name: 'USD Coin',\n decimals: 6,\n domainVersion: '2',\n isStableUsd: true,\n },\n ],\n};\n\nexport function resolveToken(network: RelaiNetwork, asset?: string): NetworkToken | null {\n const tokens = NETWORK_TOKENS[network];\n if (!tokens || tokens.length === 0) return null;\n if (!asset) return tokens[0];\n\n const normalized = String(asset).toLowerCase();\n return tokens.find((token) => token.address.toLowerCase() === normalized) || null;\n}\n\n/** USDC contract addresses per network */\nexport const USDC_ADDRESSES: Record<RelaiNetwork, string> = {\n 'solana': 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',\n 'solana-devnet': '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',\n 'base': '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'avalanche': '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n 'skale-base': '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n 'skale-base-sepolia': '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n 'skale-bite': '0xc4083B1E81ceb461Ccef3FDa8A9F24F0d764B6D8',\n 'polygon': '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n 'ethereum': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n 'telos': '0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b',\n};\n\n/** Explorer URLs per network */\nexport const EXPLORER_TX_URL: Record<RelaiNetwork, (tx: string) => string> = {\n 'solana': (tx) => `https://solscan.io/tx/${tx}`,\n 'solana-devnet': (tx) => `https://solscan.io/tx/${tx}?cluster=devnet`,\n 'base': (tx) => `https://basescan.org/tx/${tx}`,\n 'avalanche': (tx) => `https://snowtrace.io/tx/${tx}`,\n 'skale-base': (tx) => `https://skale-base-explorer.skalenodes.com/tx/${tx}`,\n 'skale-base-sepolia': (tx) => `https://base-sepolia-testnet-explorer.skalenodes.com/tx/${tx}`,\n 'skale-bite': (tx) => `https://base-sepolia-testnet.explorer.skalenodes.com/tx/${tx}`,\n 'polygon': (tx) => `https://polygonscan.com/tx/${tx}`,\n 'ethereum': (tx) => `https://etherscan.io/tx/${tx}`,\n 'telos': (tx) => `https://teloscan.io/tx/${tx}`,\n};\n\n/** Human-readable network labels */\nexport const NETWORK_LABELS: Record<RelaiNetwork, string> = {\n 'solana': 'Solana',\n 'solana-devnet': 'Solana Devnet',\n 'base': 'Base',\n 'avalanche': 'Avalanche',\n 'skale-base': 'SKALE Base',\n 'skale-base-sepolia': 'SKALE Base Sepolia',\n 'skale-bite': 'SKALE BITE V2',\n 'polygon': 'Polygon',\n 'ethereum': 'Ethereum',\n 'telos': 'Telos EVM',\n};\n\n/** Legacy CAIP-2 exports for backward compatibility */\nexport const SOLANA_MAINNET_NETWORK = NETWORK_CAIP2['solana'];\nexport const BASE_MAINNET_NETWORK = NETWORK_CAIP2['base'];\n\n/** Legacy USDC exports for backward compatibility */\nexport const USDC_SOLANA = USDC_ADDRESSES['solana'];\nexport const USDC_BASE = USDC_ADDRESSES['base'];\n\n/** All supported RelAI networks list */\nexport const RELAI_NETWORKS: RelaiNetwork[] = [\n 'solana',\n 'solana-devnet',\n 'base',\n 'avalanche',\n 'skale-base',\n 'skale-base-sepolia',\n 'skale-bite',\n 'polygon',\n 'ethereum',\n 'telos',\n];\n\n/** Check if a network is Solana-based */\nexport function isSolana(network: string): boolean {\n return network === 'solana' || network === 'solana-devnet' || network.startsWith('solana:');\n}\n\n/** Check if a network is EVM-based */\nexport function isEvm(network: string): boolean {\n return ['base', 'avalanche', 'skale-base', 'skale-base-sepolia', 'skale-bite', 'polygon', 'ethereum', 'telos'].includes(network) || network.startsWith('eip155:');\n}\n\n/** Normalize CAIP-2 or simple name to RelaiNetwork */\nexport function normalizeNetwork(network: string): RelaiNetwork | null {\n if (RELAI_NETWORKS.includes(network as RelaiNetwork)) return network as RelaiNetwork;\n const fromCaip2 = CAIP2_TO_NETWORK[network];\n if (fromCaip2) return fromCaip2;\n // Partial match\n if (network.startsWith('solana:')) return 'solana';\n if (network.startsWith('eip155:')) {\n const chainId = parseInt(network.split(':')[1]);\n const entry = Object.entries(CHAIN_IDS).find(([, id]) => id === chainId);\n if (entry) return entry[0] as RelaiNetwork;\n }\n return null;\n}\n\n// ============================================================================\n// Wallet Types\n// ============================================================================\n\n/** Solana wallet interface */\nexport interface SolanaWallet {\n publicKey: { toString(): string } | null;\n signTransaction: ((tx: unknown) => Promise<unknown>) | null;\n signAllTransactions?: ((txs: unknown[]) => Promise<unknown[]>) | null;\n}\n\n/** EVM wallet interface (viem-compatible) */\nexport interface EvmWallet {\n address: string;\n signTypedData: (params: unknown) => Promise<string>;\n chain?: { id: number };\n}\n\n/** Wallet set for multi-chain support */\nexport interface WalletSet {\n solana?: SolanaWallet;\n evm?: EvmWallet;\n}\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\n/** Extra fields in payment requirements */\nexport interface AcceptsExtra {\n feePayer?: string;\n decimals?: number;\n name?: string;\n version?: string;\n [key: string]: unknown;\n}\n\n/** A single payment option */\nexport interface PaymentAccept {\n x402Version?: 1 | 2;\n scheme: string;\n network: string;\n maxAmountRequired?: string;\n amount?: string;\n asset: string;\n payTo: string;\n maxTimeoutSeconds?: number;\n extra?: AcceptsExtra;\n resource?: string;\n description?: string;\n mimeType?: string;\n outputSchema?: unknown;\n}\n\n/** Resource info for v2 */\nexport interface ResourceInfo {\n url: string;\n description?: string;\n mimeType?: string;\n}\n\n/** Payment requirements (402 response) */\nexport interface PaymentRequired {\n x402Version: 1 | 2;\n error?: string;\n accepts: PaymentAccept[];\n resource?: ResourceInfo;\n extensions?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Config Types (server-specific types are in server.ts)\n// ============================================================================\n","// src/server.ts\nimport {\n NETWORK_CAIP2,\n USDC_ADDRESSES,\n RELAI_FACILITATOR_URL,\n resolveToken,\n type NetworkToken,\n type RelaiNetwork,\n} from './types';\nimport type { RelaiPlugin, PluginContext, PluginResult } from './plugins';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Server-side MPP verifier. When provided, protect() will accept\n * Authorization: Payment credentials and verify them via this handler.\n *\n * Compatible with mppx Mppx.create() server instances.\n *\n * @example\n * ```typescript\n * import { Mppx, tempo } from 'mppx/server';\n *\n * const mppx = Mppx.create({\n * secretKey: process.env.MPP_SECRET_KEY,\n * methods: [tempo.charge({ recipient: '0x...', currency: USDC, decimals: 6 })],\n * });\n *\n * const relai = new Relai({\n * network: 'base',\n * mpp: mppx,\n * });\n * ```\n */\n/**\n * MPP server handler — compatible with `Mppx.create()` from `mppx/server`.\n *\n * The `charge()` method returns a handler function that:\n * - On a request WITHOUT a Payment credential → returns `{ status: 402, challenge: Response }`\n * - On a request WITH a valid credential → returns `{ status: 200, withReceipt: fn }`\n */\nexport interface MppServerHandler {\n charge(params: Record<string, unknown>): (request: Request) => Promise<MppChargeResult>;\n}\n\nexport type MppChargeResult = {\n status: number;\n challenge?: Response;\n withReceipt?: (response: Response) => Response;\n receipt?: { method?: string; reference?: string; status?: string };\n};\n\nexport interface RelaiServerConfig {\n /** Network to accept payments on */\n network: RelaiNetwork;\n /** RelAI facilitator URL (default: https://facilitator.x402.fi) */\n facilitatorUrl?: string;\n /** Plugins to extend protect() behavior (e.g. freeTier, rateLimit) */\n plugins?: RelaiPlugin[];\n /**\n * Optional MPP (Machine Payment Protocol) server handler.\n * When set, protect() accepts Authorization: Payment credentials\n * (Tempo, Stripe MPP) alongside standard x402 payments.\n */\n mpp?: MppServerHandler;\n}\n\nexport type DynamicPrice = number | ((req: any) => number | Promise<number>);\n\nexport type RelaiIntegritasFlow = 'single' | 'dual';\n\nexport interface RelaiIntegritasOptions {\n /** Enable Integritas by default for this endpoint */\n enabled?: boolean;\n /** Default flow when Integritas is enabled */\n flow?: RelaiIntegritasFlow;\n}\n\nexport interface ProtectOptions {\n /** Price in USD (e.g., 0.01 for 1 cent) */\n price: DynamicPrice;\n /** Optional token asset address for networks supporting multiple tokens */\n asset?: string;\n /** Wallet address to receive payments, or stripePayTo() for Stripe settlement */\n payTo: string | StripePayTo;\n /** Description shown to payer */\n description?: string;\n /** MIME type of the response (default: application/json) */\n mimeType?: string;\n /** Maximum timeout in seconds (default: 60) */\n maxTimeoutSeconds?: number;\n /** Integritas options (or simple boolean enable flag) */\n integritas?: boolean | RelaiIntegritasOptions;\n /** Override network for this endpoint */\n network?: RelaiNetwork;\n /** Override feePayer address (Solana only) — bypasses facilitator /supported fetch */\n feePayer?: string;\n /** Custom validation after payment is settled */\n customRules?: (req: any) => boolean | Promise<boolean>;\n /** Callback when 402 is returned (no payment provided) */\n onPaymentRequired?: (req: any, info: { price: number; network: RelaiNetwork }) => void;\n /** Callback when payment is settled successfully */\n onPaymentSettled?: (req: any, result: SettleResult) => void;\n /** Callback on error */\n onError?: (req: any, error: unknown) => void;\n}\n\nexport interface SettleResult {\n success: boolean;\n transaction?: string;\n payer?: string;\n network?: string;\n splitTransfers?: Record<string, unknown>;\n integritasFeePaid?: boolean;\n provenance?: Record<string, unknown>;\n integritas?: Record<string, unknown>;\n error?: string;\n errorReason?: string;\n}\n\nexport interface PaymentInfo {\n verified: boolean;\n transactionId?: string;\n payer?: string;\n network: RelaiNetwork;\n amount: number;\n}\n\n// ============================================================================\n// Stripe Pay-To Helper\n// ============================================================================\n\n/** Config returned by stripePayTo() - used by protect() to create Stripe deposit addresses */\nexport interface StripePayTo {\n readonly __brand: 'stripePayTo';\n readonly secretKey: string;\n /** Stripe crypto deposits network (default: 'base') */\n readonly stripeNetwork: string;\n}\n\n/**\n * Create a Stripe pay-to configuration for x402 payments.\n * Payments settle as USD in your Stripe Dashboard - no crypto knowledge required.\n *\n * Stripe creates a fresh PaymentIntent + deposit address per request.\n * Network is auto-set to Base (Stripe settles USDC on Base).\n *\n * @example\n * ```typescript\n * import Relai, { stripePayTo } from '@relai-fi/x402/server';\n *\n * const relai = new Relai({ network: 'base' });\n *\n * app.get('/api/data', relai.protect({\n * price: 0.01,\n * payTo: stripePayTo(process.env.STRIPE_SECRET_KEY!),\n * }), (req, res) => {\n * res.json({ data: 'paid content' });\n * });\n * ```\n */\nexport function stripePayTo(\n stripeSecretKey: string,\n options?: { network?: string },\n): StripePayTo {\n if (!stripeSecretKey) {\n throw new Error('stripePayTo requires a Stripe secret key');\n }\n return {\n __brand: 'stripePayTo' as const,\n secretKey: stripeSecretKey,\n stripeNetwork: options?.network || 'base',\n };\n}\n\nconst USD_PRICE_CACHE_TTL_MS = 60 * 1000;\nconst usdPriceCache = new Map<string, { usd: number; expiresAt: number }>();\n\nconst GECKOTERMINAL_NETWORK_BY_RELAI: Partial<Record<RelaiNetwork, string>> = {\n polygon: 'polygon_pos',\n};\n\nconst COINGECKO_ID_BY_SYMBOL: Record<string, string> = {\n WETH: 'ethereum',\n WBTC: 'bitcoin',\n USDT: 'tether',\n EURC: 'euro-coin',\n DAI: 'dai',\n cbETH: 'coinbase-wrapped-staked-eth',\n cbBTC: 'coinbase-wrapped-btc',\n};\n\nfunction isStableUsdToken(token: NetworkToken): boolean {\n if (token.isStableUsd === true) return true;\n const symbol = String(token.symbol || '').toUpperCase();\n return symbol === 'USDC' || symbol === 'USDT';\n}\n\nasync function fetchUsdPriceFromCoinGecko(coinId: string): Promise<number> {\n const now = Date.now();\n const cached = usdPriceCache.get(coinId);\n if (cached && cached.expiresAt > now) {\n return cached.usd;\n }\n\n const url = `https://api.coingecko.com/api/v3/simple/price?ids=${encodeURIComponent(coinId)}&vs_currencies=usd`;\n const res = await fetch(url, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n });\n\n if (!res.ok) {\n throw new Error(`CoinGecko price request failed: HTTP ${res.status}`);\n }\n\n const payload = await res.json() as Record<string, { usd?: number }>;\n const usd = Number(payload?.[coinId]?.usd);\n if (!Number.isFinite(usd) || usd <= 0) {\n throw new Error(`CoinGecko returned invalid usd price for ${coinId}`);\n }\n\n usdPriceCache.set(coinId, {\n usd,\n expiresAt: now + USD_PRICE_CACHE_TTL_MS,\n });\n\n return usd;\n}\n\nasync function fetchUsdPriceFromGeckoTerminal(network: RelaiNetwork, tokenAddress: string): Promise<number> {\n const geckoNetwork = GECKOTERMINAL_NETWORK_BY_RELAI[network];\n if (!geckoNetwork) {\n throw new Error(`GeckoTerminal network not configured for ${network}`);\n }\n\n const normalizedAddress = String(tokenAddress || '').trim().toLowerCase();\n if (!normalizedAddress) {\n throw new Error('GeckoTerminal requires a token address');\n }\n\n const cacheKey = `gt:${geckoNetwork}:${normalizedAddress}`;\n const now = Date.now();\n const cached = usdPriceCache.get(cacheKey);\n if (cached && cached.expiresAt > now) {\n return cached.usd;\n }\n\n const url = `https://api.geckoterminal.com/api/v2/networks/${encodeURIComponent(geckoNetwork)}/tokens/${encodeURIComponent(normalizedAddress)}`;\n const res = await fetch(url, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n });\n\n if (!res.ok) {\n throw new Error(`GeckoTerminal price request failed: HTTP ${res.status}`);\n }\n\n const payload = await res.json() as { data?: { attributes?: { price_usd?: string | number } } };\n const usd = Number(payload?.data?.attributes?.price_usd);\n if (!Number.isFinite(usd) || usd <= 0) {\n throw new Error(`GeckoTerminal returned invalid usd price for ${normalizedAddress} on ${geckoNetwork}`);\n }\n\n usdPriceCache.set(cacheKey, {\n usd,\n expiresAt: now + USD_PRICE_CACHE_TTL_MS,\n });\n\n return usd;\n}\n\nasync function resolveAmountAtomicFromUsd({\n priceUsd,\n token,\n network,\n}: {\n priceUsd: number;\n token: NetworkToken;\n network: RelaiNetwork;\n}): Promise<string> {\n const decimals = Number(token.decimals);\n if (!Number.isFinite(decimals) || decimals < 0) {\n throw new Error(`Invalid token decimals for ${token.symbol || token.address}`);\n }\n\n if (isStableUsdToken(token)) {\n const units = Math.floor(priceUsd * Math.pow(10, decimals));\n return String(Math.max(1, units));\n }\n\n const symbol = String(token.symbol || '').toUpperCase();\n const coinGeckoId = COINGECKO_ID_BY_SYMBOL[symbol];\n if (!coinGeckoId) {\n throw new Error(`No USD quote source configured for token ${symbol || token.address} on ${network}`);\n }\n\n const overrideEnv = process.env[`EVM_TOKEN_PRICE_${symbol}_USD`];\n let usdPerToken: number;\n if (overrideEnv && Number(overrideEnv) > 0) {\n usdPerToken = Number(overrideEnv);\n } else {\n try {\n usdPerToken = await fetchUsdPriceFromCoinGecko(coinGeckoId);\n } catch (coinGeckoError) {\n try {\n usdPerToken = await fetchUsdPriceFromGeckoTerminal(network, token.address);\n } catch (geckoTerminalError) {\n throw new Error(\n `USD quote failed for ${symbol || token.address} on ${network}. CoinGecko: ${coinGeckoError instanceof Error ? coinGeckoError.message : String(coinGeckoError)}; GeckoTerminal: ${geckoTerminalError instanceof Error ? geckoTerminalError.message : String(geckoTerminalError)}`,\n );\n }\n }\n }\n\n const tokenAmount = priceUsd / usdPerToken;\n const rawUnits = tokenAmount * Math.pow(10, decimals);\n\n if (!Number.isFinite(rawUnits) || rawUnits <= 0) {\n throw new Error(\n `Invalid conversion result for token ${symbol || token.address}: priceUsd=${priceUsd}, usdPerToken=${usdPerToken}`,\n );\n }\n\n return String(Math.max(1, Math.floor(rawUnits)));\n}\n\n/** @internal Type guard for StripePayTo */\nfunction isStripePayTo(payTo: unknown): payTo is StripePayTo {\n return (\n typeof payTo === 'object' &&\n payTo !== null &&\n (payTo as any).__brand === 'stripePayTo'\n );\n}\n\nfunction parseBooleanHeader(value: unknown): boolean | null {\n if (value == null) return null;\n const normalized = String(value).trim().toLowerCase();\n if (normalized === 'true' || normalized === '1' || normalized === 'yes' || normalized === 'on') {\n return true;\n }\n if (normalized === 'false' || normalized === '0' || normalized === 'no' || normalized === 'off') {\n return false;\n }\n return null;\n}\n\nfunction normalizeIntegritasFlow(value: unknown): RelaiIntegritasFlow | undefined {\n const normalized = String(value || '').trim().toLowerCase();\n if (normalized === 'single') return 'single';\n if (normalized === 'dual') return 'dual';\n return undefined;\n}\n\nfunction normalizeIntegritasOptions(\n value: boolean | RelaiIntegritasOptions | undefined,\n): { enabled: boolean; flow?: RelaiIntegritasFlow } {\n if (value === true) return { enabled: true };\n if (value === false || value == null) return { enabled: false };\n\n const flow = normalizeIntegritasFlow(value.flow);\n const enabled =\n typeof value.enabled === 'boolean'\n ? value.enabled\n : true;\n\n return {\n enabled,\n ...(flow ? { flow } : {}),\n };\n}\n\n/**\n * @internal Create a Stripe PaymentIntent with crypto payment method\n * and extract the deposit address.\n */\nasync function createStripeDepositAddress(\n secretKey: string,\n amountUsdCents: number,\n network: string = 'base',\n): Promise<string> {\n const params = new URLSearchParams();\n params.append('amount', String(amountUsdCents));\n params.append('currency', 'usd');\n params.append('payment_method_types[]', 'crypto');\n params.append('payment_method_data[type]', 'crypto');\n params.append('confirm', 'true');\n\n const res = await fetch('https://api.stripe.com/v1/payment_intents', {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${secretKey}`,\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: params.toString(),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({})) as any;\n const msg = err?.error?.message || res.statusText;\n\n // Provide actionable guidance for common issues\n if (msg.includes('unknown parameter') || msg.includes('crypto')) {\n throw new Error(\n `Stripe crypto payins not enabled on this account. ` +\n `Enable at: https://support.stripe.com/questions/get-started-with-pay-with-crypto ` +\n `(Original: ${msg})`,\n );\n }\n throw new Error(`Stripe PaymentIntent creation failed: ${msg}`);\n }\n\n const pi = await res.json() as any;\n const depositDetails = pi.next_action?.crypto_collect_deposit_details;\n if (!depositDetails) {\n throw new Error(\n 'Stripe PaymentIntent missing crypto deposit details. ' +\n 'Ensure crypto payins are enabled: https://support.stripe.com/questions/get-started-with-pay-with-crypto',\n );\n }\n\n const address = depositDetails.deposit_addresses?.[network]?.address;\n if (!address) {\n throw new Error(`No Stripe deposit address for network: ${network}`);\n }\n\n return address;\n}\n\n// ============================================================================\n// Relai Server SDK\n// ============================================================================\n\n/**\n * Server-side SDK for protecting Express endpoints with x402 micropayments.\n * Settles payments through the RelAI facilitator (zero gas fees for users).\n *\n * Supports: Solana, Base, Avalanche, SKALE Base, SKALE Base Sepolia, SKALE BITE, Polygon, and Ethereum.\n *\n * @example\n * ```typescript\n * import Relai from '@relai-fi/x402/server';\n *\n * const relai = new Relai({ network: 'base' });\n *\n * app.get('/api/data', relai.protect({\n * payTo: '0xYourWallet',\n * price: 0.01, // $0.01 USDC\n * }), (req, res) => {\n * res.json({ data: 'Protected content', payment: req.payment });\n * });\n * ```\n */\nexport class Relai {\n private network: RelaiNetwork;\n private facilitatorUrl: string;\n private feePayerCache: Map<string, string> = new Map(); // Cache feePayer per network\n private plugins: RelaiPlugin[];\n private pluginInitPromise: Promise<void> | null = null;\n private mpp?: MppServerHandler;\n\n constructor(config: RelaiServerConfig) {\n this.network = config.network;\n this.facilitatorUrl = config.facilitatorUrl || RELAI_FACILITATOR_URL;\n this.plugins = config.plugins ?? [];\n this.mpp = config.mpp;\n }\n\n private async runPluginInit(): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.onInit) {\n try {\n await plugin.onInit();\n } catch (err) {\n console.warn(`[Relai] Plugin '${plugin.name}' init failed:`, err);\n }\n }\n }\n }\n\n /**\n * Get feePayer address for a network (cached)\n */\n private async getFeePayer(caip2: string): Promise<string | undefined> {\n // Check cache first\n if (this.feePayerCache.has(caip2)) {\n return this.feePayerCache.get(caip2);\n }\n\n // If using RelAI facilitator, use hardcoded address (no fetch needed)\n const isRelAI = this.facilitatorUrl.includes('facilitator.x402.fi') || \n this.facilitatorUrl.includes('relai');\n \n if (isRelAI) {\n const relaiFeePayer = '0x1892f72fdB3A966b2AD8595aA5f7741Ef72d6085';\n this.feePayerCache.set(caip2, relaiFeePayer);\n return relaiFeePayer;\n }\n\n // For other facilitators, fetch from /supported\n try {\n const supportedUrl = `${this.facilitatorUrl}/supported`;\n const supportedRes = await fetch(supportedUrl);\n if (supportedRes.ok) {\n const supportedData = await supportedRes.json();\n // Cache all feePayers from supported kinds\n supportedData.kinds?.forEach((kind: any) => {\n if (kind.network && kind.extra?.feePayer) {\n this.feePayerCache.set(kind.network, kind.extra.feePayer);\n }\n });\n return this.feePayerCache.get(caip2);\n }\n } catch (err) {\n // feePayer MUST come from facilitator - cannot use env for security\n console.error(`[Relai] Failed to fetch feePayer from facilitator: ${err}`);\n }\n return undefined;\n }\n\n /**\n * Express middleware to protect an endpoint with x402 micropayments.\n *\n * Flow:\n * 1. No payment header → returns 402 with payment requirements\n * 2. Payment header present → calls RelAI facilitator `/settle`\n * 3. Settlement success → sets `PAYMENT-RESPONSE` header, attaches `req.payment`, calls `next()`\n */\n protect(options: ProtectOptions) {\n const self = this;\n\n return async (req: any, res: any, next: any) => {\n try {\n // -----------------------------------------------------------\n // Preflight probe: respond 200 immediately so the preflight\n // plugin (or external clients) can verify the endpoint is alive.\n // -----------------------------------------------------------\n if (req.headers['x-preflight'] === 'true' || req.headers['x-preflight'] === '1') {\n return res.status(200).json({ status: 'ok', preflight: true });\n }\n\n // Resolve dynamic price\n const resolvedPrice = typeof options.price === 'function'\n ? await options.price(req)\n : options.price;\n\n if (typeof resolvedPrice !== 'number' || !isFinite(resolvedPrice) || resolvedPrice <= 0) {\n return res.status(400).json({ error: 'Invalid price configuration' });\n }\n\n // Resolve network (Stripe auto-sets to base)\n const stripeConfig = isStripePayTo(options.payTo) ? options.payTo : null;\n const network = stripeConfig\n ? (stripeConfig.stripeNetwork as RelaiNetwork) || 'base'\n : (options.network || self.network);\n const caip2 = NETWORK_CAIP2[network];\n const requestedAsset =\n typeof options.asset === 'string' && options.asset.trim() !== ''\n ? options.asset.trim()\n : undefined;\n const explicitToken = requestedAsset ? resolveToken(network, requestedAsset) : null;\n if (requestedAsset && !explicitToken) {\n return res.status(400).json({\n error: `Unsupported asset ${requestedAsset} for network ${network}`,\n });\n }\n\n const fallbackToken: NetworkToken = {\n address: USDC_ADDRESSES[network],\n symbol: 'USDC',\n name: network === 'skale-bite' ? 'USDC' : 'USD Coin',\n decimals: 6,\n domainVersion: network === 'skale-bite' ? '1' : '2',\n isStableUsd: true,\n };\n const token = explicitToken || resolveToken(network) || fallbackToken;\n const asset = token.address;\n const tokenName = token.name || 'USD Coin';\n const tokenVersion = token.domainVersion || (network === 'skale-bite' ? '1' : '2');\n const tokenDecimals = Number.isFinite(Number(token.decimals)) ? Number(token.decimals) : 6;\n\n let amount: string;\n try {\n amount = await resolveAmountAtomicFromUsd({\n priceUsd: resolvedPrice,\n token,\n network,\n });\n } catch (err) {\n console.error('[Relai] Failed to convert USD amount to token units:', err);\n return res.status(500).json({\n error: 'Failed to quote token amount for payment requirements',\n });\n }\n\n const configuredIntegritas = normalizeIntegritasOptions(options.integritas);\n const headerIntegritasEnabled = parseBooleanHeader(req.headers['x-integritas']);\n const headerIntegritasFlow = normalizeIntegritasFlow(req.headers['x-integritas-flow']);\n const integritasEnabled =\n headerIntegritasEnabled === null\n ? configuredIntegritas.enabled\n : headerIntegritasEnabled;\n const integritasFlow = headerIntegritasFlow || configuredIntegritas.flow;\n const integritasMode =\n integritasFlow === 'single'\n ? 'single_signature_fee_included'\n : (integritasFlow === 'dual' ? 'dual_signature_split' : undefined);\n\n // Check for payment header (base64-encoded JSON)\n const paymentHeader =\n req.headers['x-payment'] ||\n req.headers['payment-signature'] ||\n req.headers['x-payment-signature'];\n\n // -----------------------------------------------------------\n // MPP: check for Authorization: Payment credential\n // -----------------------------------------------------------\n const authHeader = req.headers['authorization'] || '';\n console.log(`[Relai] MPP check: paymentHeader=${!!paymentHeader}, hasMpp=${!!self.mpp}, authHeader=${authHeader?.slice(0, 30)}`);\n if (!paymentHeader && self.mpp && /^Payment\\s+/i.test(authHeader)) {\n try {\n // Use the same amount format as the challenge (USD with 6 decimals)\n const mppAmount = resolvedPrice.toFixed(6);\n\n // Build a web Request from the Express req for the mppx handler\n const mppUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;\n const mppHeaders = new Headers();\n for (const [k, v] of Object.entries(req.headers)) {\n if (typeof v === 'string') mppHeaders.set(k, v);\n }\n const mppRequest = new Request(mppUrl, { method: req.method, headers: mppHeaders });\n\n // Call the charge handler — it detects the credential in Authorization header\n // and verifies it against the HMAC-signed challenge\n const chargeHandler = self.mpp.charge({ amount: mppAmount } as any);\n const mppResult = await chargeHandler(mppRequest);\n console.log(`[Relai] MPP charge result: status=${mppResult.status}, keys=${Object.keys(mppResult)}, hasChallenge=${!!mppResult.challenge}, hasWithReceipt=${!!mppResult.withReceipt}`);\n if (mppResult.status === 402 && mppResult.challenge instanceof Response) {\n const retryAuth = mppResult.challenge.headers.get('www-authenticate');\n console.log(`[Relai] MPP re-challenged (credential not accepted). New WWW-Auth: ${retryAuth?.slice(0, 60)}`);\n }\n\n // MPP charge genuinely failed (not a 402 re-challenge, which is normal handshake)\n // Only notify plugins for non-402 failures (e.g. 500, invalid credential, etc.)\n if (mppResult.status !== 200 && !mppResult.withReceipt && mppResult.status !== 402) {\n if (self.plugins.length > 0) {\n const mppFailCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n const mppFailResult: SettleResult = {\n success: false,\n payer: 'mpp',\n error: `MPP charge failed with status ${mppResult.status}`,\n };\n for (const plugin of self.plugins) {\n if (!plugin.afterSettled) continue;\n try {\n await plugin.afterSettled(req, mppFailResult, mppFailCtx);\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' afterSettled error (non-blocking):`, pluginErr);\n }\n }\n }\n }\n\n if (mppResult.status === 200 || mppResult.withReceipt) {\n // Payment verified by mppx\n const receipt = mppResult.receipt || {};\n const paymentInfo: PaymentInfo = {\n verified: true,\n transactionId: receipt.reference || '',\n payer: receipt.method || 'mpp',\n network,\n amount: resolvedPrice,\n };\n req.payment = paymentInfo;\n req.x402Payer = receipt.method ? `${receipt.method}-mpp` : 'mpp';\n req.x402Paid = true;\n req.x402Transaction = receipt.reference || '';\n req.x402Network = network;\n\n // Use withReceipt to attach Payment-Receipt header\n if (mppResult.withReceipt) {\n const dummyResponse = new Response(null);\n const receiptResponse = mppResult.withReceipt(dummyResponse);\n const receiptHeader = receiptResponse.headers.get('payment-receipt');\n if (receiptHeader) res.setHeader('Payment-Receipt', receiptHeader);\n }\n\n options.onPaymentSettled?.(req, {\n success: true,\n transaction: receipt.reference,\n payer: req.x402Payer,\n } as SettleResult);\n\n // Plugin hooks: afterSettled\n if (self.plugins.length > 0) {\n const settleCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n for (const plugin of self.plugins) {\n if (!plugin.afterSettled) continue;\n try {\n await plugin.afterSettled(req, {\n success: true,\n transaction: receipt.reference,\n payer: req.x402Payer,\n } as SettleResult, settleCtx);\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' afterSettled error (non-blocking):`, pluginErr);\n }\n }\n }\n\n return next();\n }\n } catch (mppErr) {\n console.warn(`[Relai] MPP verification failed (${mppErr instanceof Error ? mppErr.message : mppErr}), falling through to x402`);\n\n // Notify plugins of MPP failure\n if (self.plugins.length > 0) {\n const mppErrCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n const mppErrResult: SettleResult = {\n success: false,\n payer: 'mpp',\n error: mppErr instanceof Error ? mppErr.message : String(mppErr),\n };\n for (const plugin of self.plugins) {\n if (!plugin.afterSettled) continue;\n try {\n await plugin.afterSettled(req, mppErrResult, mppErrCtx);\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' afterSettled error (non-blocking):`, pluginErr);\n }\n }\n }\n }\n }\n\n // -----------------------------------------------------------\n // Plugin hooks: beforePaymentCheck\n // If any plugin returns { skip: true }, bypass payment entirely.\n // Ensure plugins are initialized (config synced) before checking.\n // -----------------------------------------------------------\n if (!paymentHeader && self.plugins.length > 0) {\n if (!self.pluginInitPromise) {\n self.pluginInitPromise = self.runPluginInit();\n }\n await self.pluginInitPromise;\n const pluginCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n\n for (const plugin of self.plugins) {\n if (!plugin.beforePaymentCheck) continue;\n try {\n const pluginResult = await plugin.beforePaymentCheck(req, pluginCtx);\n\n // Reject: plugin blocks the request entirely (e.g. service unhealthy)\n if (pluginResult?.reject) {\n const rejectStatus = pluginResult.rejectStatus || 503;\n if (pluginResult.headers) {\n for (const [k, v] of Object.entries(pluginResult.headers)) {\n res.setHeader(k, v);\n }\n }\n return res.status(rejectStatus).json({\n error: pluginResult.rejectMessage || 'Service unavailable',\n plugin: plugin.name,\n });\n }\n\n // Skip: bypass payment and serve content for free\n if (pluginResult?.skip) {\n // Set plugin-provided headers\n if (pluginResult.headers) {\n for (const [k, v] of Object.entries(pluginResult.headers)) {\n res.setHeader(k, v);\n }\n }\n // Attach plugin metadata to request\n req.pluginMeta = { ...(req.pluginMeta || {}), ...(pluginResult.meta || {}) };\n req.x402Paid = false;\n req.x402Free = true;\n req.x402Plugin = plugin.name;\n // Still set up afterSettled interceptor so plugins (e.g. refund) can\n // re-issue a credit if the endpoint fails on this free call too.\n const skipPluginsWithHook = self.plugins.filter((p) => !!p.afterSettled);\n if (skipPluginsWithHook.length > 0) {\n const skipCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n const skipResult: SettleResult = {\n success: true,\n payer: req.headers?.['x-wallet-address'] || req.headers?.['x-buyer-address'] || req.ip || req.socket?.remoteAddress || 'unknown',\n transaction: '',\n } as any;\n const originalJsonSkip = (res as any).json?.bind(res);\n const originalSendSkip = (res as any).send?.bind(res);\n let skipFired = false;\n const fireSkipAfterSettled = (statusCode: number) => {\n if (skipFired) return;\n skipFired = true;\n const resultWithStatus = { ...skipResult, statusCode };\n for (const p of skipPluginsWithHook) {\n p.afterSettled!(req, resultWithStatus, skipCtx).catch((e: unknown) => {\n console.warn(`[Relai] Plugin '${p.name}' afterSettled (skip) error:`, e);\n });\n }\n };\n if (typeof originalJsonSkip === 'function') {\n (res as any).json = function (body: unknown) {\n fireSkipAfterSettled(res.statusCode ?? 200);\n (res as any).json = originalJsonSkip;\n return originalJsonSkip(body);\n };\n }\n if (typeof originalSendSkip === 'function') {\n (res as any).send = function (body: unknown) {\n fireSkipAfterSettled(res.statusCode ?? 200);\n (res as any).send = originalSendSkip;\n return originalSendSkip(body);\n };\n }\n }\n return next();\n }\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' beforePaymentCheck error (non-blocking):`, pluginErr);\n }\n }\n }\n\n // -----------------------------------------------------------\n // No payment → return 402 Payment Required\n // -----------------------------------------------------------\n if (!paymentHeader) {\n options.onPaymentRequired?.(req, { price: resolvedPrice, network });\n\n // Resolve payTo address (Stripe creates a fresh deposit address per request)\n let resolvedPayTo: string;\n if (stripeConfig) {\n const amountInCents = Math.max(1, Math.round(resolvedPrice * 100));\n resolvedPayTo = await createStripeDepositAddress(\n stripeConfig.secretKey,\n amountInCents,\n stripeConfig.stripeNetwork,\n );\n } else {\n resolvedPayTo = options.payTo as string;\n }\n\n // Get facilitator feePayer address — use explicit override if provided, otherwise fetch\n const feePayer = (options.feePayer as string | undefined) || await self.getFeePayer(caip2);\n\n let paymentRequiredResponse: any = {\n x402Version: 2,\n error: 'Payment required',\n resource: {\n url: `${req.protocol}://${req.get('host')}${req.originalUrl}`,\n description: options.description || 'API access',\n mimeType: options.mimeType || 'application/json',\n },\n accepts: [{\n scheme: 'exact',\n network: caip2,\n amount,\n asset,\n payTo: resolvedPayTo,\n maxTimeoutSeconds: options.maxTimeoutSeconds || 60,\n extra: {\n name: tokenName,\n version: tokenVersion,\n decimals: tokenDecimals,\n symbol: token.symbol,\n ...(feePayer && { feePayer }), // Add feePayer if available\n ...(integritasEnabled ? { integritasEnabled: true } : {}),\n ...(integritasFlow ? { integritasFlow } : {}),\n ...(integritasMode ? { integritasMode } : {}),\n ...(integritasFlow === 'single' ? { integritasSingleSignature: true } : {}),\n },\n }],\n ...((configuredIntegritas.enabled || integritasEnabled || !!integritasFlow)\n ? {\n extensions: {\n integritas: {\n available: true,\n selectedFlow: integritasFlow || null,\n availableFlows: ['single', 'dual'],\n enabled: integritasEnabled,\n },\n },\n }\n : {}),\n };\n\n // Plugin hooks: enrich402Response (e.g. bridge adds extensions.bridge)\n if (self.plugins.length > 0) {\n const enrichCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n for (const plugin of self.plugins) {\n if (!plugin.enrich402Response) continue;\n try {\n paymentRequiredResponse = plugin.enrich402Response(paymentRequiredResponse, enrichCtx) || paymentRequiredResponse;\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' enrich402Response error (non-blocking):`, pluginErr);\n }\n }\n }\n\n // Add MPP challenge header if mpp is configured\n if (self.mpp?.charge) {\n try {\n const mppAmount = resolvedPrice.toFixed(6);\n const chargeHandler = self.mpp.charge({ amount: mppAmount } as any);\n const mockReq = new Request(`${req.protocol}://${req.get('host')}${req.originalUrl}`);\n const mppResult = await chargeHandler(mockReq);\n if (mppResult?.challenge instanceof Response) {\n const wwwAuth = mppResult.challenge.headers.get('www-authenticate');\n if (wwwAuth) {\n res.setHeader('WWW-Authenticate', wwwAuth);\n }\n }\n } catch {\n // Non-fatal — x402 response is still valid without MPP headers\n }\n }\n\n return res.status(402).json(paymentRequiredResponse);\n }\n\n // -----------------------------------------------------------\n // Payment header present → parse and settle via facilitator\n // -----------------------------------------------------------\n let paymentProof: any;\n try {\n // Try base64 first (standard x402 format)\n const decoded = Buffer.from(paymentHeader, 'base64').toString('utf-8');\n paymentProof = JSON.parse(decoded);\n } catch {\n try {\n // Fallback: raw JSON string\n paymentProof = JSON.parse(paymentHeader);\n } catch {\n return res.status(400).json({\n x402Version: 2,\n error: 'Invalid payment header — expected base64-encoded JSON',\n });\n }\n }\n\n // -----------------------------------------------------------\n // Bridged payment: trust the bridge proof (already settled)\n // -----------------------------------------------------------\n if (paymentProof.bridged === true && paymentProof.targetTxId) {\n console.log(`[Relai] Bridged payment accepted: source=${paymentProof.sourceTxId}, target=${paymentProof.targetTxId}`);\n\n const paymentInfo: PaymentInfo = {\n verified: true,\n transactionId: paymentProof.targetTxId,\n payer: paymentProof.sourceTxId || 'bridge',\n network,\n amount: resolvedPrice,\n };\n req.payment = paymentInfo;\n req.x402Payer = paymentProof.sourceTxId || 'bridge';\n req.x402Paid = true;\n req.x402Transaction = paymentProof.targetTxId;\n req.x402Network = network;\n req.x402Bridged = true;\n req.x402SourceChain = paymentProof.sourceChain;\n\n const paymentResponse = {\n x402Version: 2,\n scheme: 'exact',\n network: caip2,\n transaction: paymentProof.targetTxId,\n payer: paymentProof.sourceTxId,\n amount,\n asset,\n bridged: true,\n };\n res.setHeader(\n 'PAYMENT-RESPONSE',\n Buffer.from(JSON.stringify(paymentResponse)).toString('base64'),\n );\n\n options.onPaymentSettled?.(req, { success: true, transaction: paymentProof.targetTxId, payer: paymentProof.sourceTxId } as SettleResult);\n\n return next();\n }\n\n // -----------------------------------------------------------\n // Standard payment: settle via facilitator\n // -----------------------------------------------------------\n\n // Resolve payTo for settle (extract from signed proof when using Stripe)\n let settlePayTo: string;\n if (stripeConfig) {\n settlePayTo =\n paymentProof.payload?.authorization?.to ||\n paymentProof.accepted?.payTo ||\n '';\n if (!settlePayTo) {\n return res.status(400).json({\n x402Version: 2,\n error: 'Cannot extract destination address from payment proof',\n });\n }\n } else {\n settlePayTo = options.payTo as string;\n }\n\n // Build payment requirements for facilitator\n const paymentRequirements = {\n scheme: 'exact',\n network: caip2,\n amount,\n asset,\n payTo: settlePayTo,\n maxTimeoutSeconds: options.maxTimeoutSeconds || 60,\n extra: {\n name: tokenName,\n version: tokenVersion,\n decimals: tokenDecimals,\n symbol: token.symbol,\n ...(integritasEnabled ? { integritasEnabled: true } : {}),\n ...(integritasFlow ? { integritasFlow } : {}),\n ...(integritasMode ? { integritasMode } : {}),\n ...(integritasFlow === 'single' ? { integritasSingleSignature: true } : {}),\n },\n };\n\n // Call facilitator /settle\n const settleUrl = `${self.facilitatorUrl}/settle`;\n const settleRes = await fetch(settleUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n paymentPayload: paymentProof,\n paymentRequirements,\n }),\n });\n\n const result: SettleResult = await settleRes.json() as SettleResult;\n\n if (!result.success) {\n // Notify plugins of settlement failure (circuit breaker, refund, etc.)\n if (self.plugins.length > 0) {\n const failCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n for (const plugin of self.plugins) {\n if (!plugin.afterSettled) continue;\n try {\n await plugin.afterSettled(req, result, failCtx);\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' afterSettled error (non-blocking):`, pluginErr);\n }\n }\n }\n\n return res.status(402).json({\n x402Version: 2,\n error: result.errorReason || result.error || 'Payment settlement failed',\n });\n }\n\n // Attach payment info to request\n const paymentInfo: PaymentInfo = {\n verified: true,\n transactionId: result.transaction,\n payer: result.payer,\n network,\n amount: resolvedPrice,\n };\n req.payment = paymentInfo;\n req.x402Payer = result.payer;\n req.x402Paid = true;\n req.x402Transaction = result.transaction;\n req.x402Network = network;\n\n // Set x402 v2 PAYMENT-RESPONSE header (base64 JSON)\n const paymentResponse = {\n x402Version: 2,\n scheme: 'exact',\n network: caip2,\n transaction: result.transaction,\n payer: result.payer,\n amount,\n asset,\n };\n res.setHeader(\n 'PAYMENT-RESPONSE',\n Buffer.from(JSON.stringify(paymentResponse)).toString('base64'),\n );\n\n options.onPaymentSettled?.(req, result);\n\n // Plugin hooks: afterSettled — called AFTER the handler responds so plugins\n // can see the actual HTTP status code (e.g. circuit breaker, refund).\n if (self.plugins.length > 0) {\n const settleCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n const pluginsWithHook = self.plugins.filter((p) => !!p.afterSettled);\n if (pluginsWithHook.length > 0) {\n // Wrap res.json / res.send to fire afterSettled with actual statusCode\n const originalJson = (res as any).json?.bind(res);\n const originalSend = (res as any).send?.bind(res);\n let afterSettledFired = false;\n const fireAfterSettled = (statusCode: number) => {\n if (afterSettledFired) return;\n afterSettledFired = true;\n const resultWithStatus = { ...result, statusCode };\n for (const plugin of pluginsWithHook) {\n plugin.afterSettled!(req, resultWithStatus, settleCtx).catch((e: unknown) => {\n console.warn(`[Relai] Plugin '${plugin.name}' afterSettled error (non-blocking):`, e);\n });\n }\n };\n if (typeof originalJson === 'function') {\n (res as any).json = function (body: unknown) {\n fireAfterSettled(res.statusCode ?? 200);\n (res as any).json = originalJson; // restore\n return originalJson(body);\n };\n }\n if (typeof originalSend === 'function') {\n (res as any).send = function (body: unknown) {\n fireAfterSettled(res.statusCode ?? 200);\n (res as any).send = originalSend; // restore\n return originalSend(body);\n };\n }\n }\n }\n\n // Custom validation after payment\n if (options.customRules) {\n const valid = await options.customRules(req);\n if (!valid) {\n return res.status(403).json({ error: 'Custom validation failed' });\n }\n }\n\n next();\n } catch (error) {\n options.onError?.(req, error);\n console.error('[Relai] Protection error:', error);\n res.status(500).json({ error: 'Internal server error' });\n }\n };\n }\n}\n\nexport default Relai;\n","// src/client.ts\nimport {\n Connection,\n PublicKey,\n TransactionMessage,\n VersionedTransaction,\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 { SolanaWallet, EvmWallet, WalletSet } from './types';\nimport {\n RELAI_FACILITATOR_URL,\n NETWORK_CAIP2,\n CHAIN_IDS,\n NETWORK_TOKENS,\n isSolana,\n isEvm,\n normalizeNetwork,\n type RelaiNetwork,\n} from './types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type X402NetworkSelectionMode = 'prefer_then_any' | 'strict_preferred';\n\n/**\n * MPP (Machine Payment Protocol) handler for automatic Tempo/Stripe payment.\n * When provided, the client will detect WWW-Authenticate: Payment challenges\n * on 402 responses and use this handler to create credentials automatically.\n *\n * @example\n * ```typescript\n * import { Mppx, tempo } from 'mppx/client';\n * import { privateKeyToAccount } from 'viem/accounts';\n *\n * const mppx = Mppx.create({\n * methods: [tempo.charge({ account: privateKeyToAccount('0x...') })],\n * polyfill: false,\n * });\n *\n * const client = createX402Client({\n * wallets: { evm: evmWallet },\n * mpp: mppx,\n * });\n * ```\n */\nexport interface MppHandler {\n /** Create a credential string from a 402 response containing a WWW-Authenticate challenge. */\n createCredential(response: Response): Promise<string>;\n}\n\nexport interface X402ClientConfig {\n /** Multi-chain wallets (Solana + EVM) */\n wallets?: WalletSet;\n /** Single Solana wallet (legacy shortcut) */\n wallet?: SolanaWallet;\n /** Custom facilitator URL, default: RelAI facilitator */\n facilitatorUrl?: string;\n /** Optional Relay WebSocket transport for /relay/:apiId endpoints */\n relayWs?: X402RelayWsConfig;\n /** Preferred network when multiple options available */\n preferredNetwork?: RelaiNetwork;\n /**\n * How to handle 402 accepts when preferredNetwork is set.\n * - prefer_then_any (default): prefer preferredNetwork, then fall back to any payable option.\n * - strict_preferred: only accept preferredNetwork, fail otherwise.\n */\n networkSelectionMode?: X402NetworkSelectionMode;\n /** Custom Solana RPC URL */\n solanaRpcUrl?: string;\n /** Custom EVM RPC URLs per network (e.g. { 'skale-base': 'https://...' }) */\n evmRpcUrls?: Record<string, string>;\n /** Maximum payment amount in atomic units */\n maxAmountAtomic?: string;\n /** Default Integritas behavior for outgoing requests */\n integritas?: boolean | X402IntegritasConfig;\n /** Enable verbose logging */\n verbose?: boolean;\n /** Default headers added to every request (e.g. X-Service-Key, X-Agent-ID for agent use) */\n defaultHeaders?: Record<string, string>;\n /**\n * Optional MPP (Machine Payment Protocol) handler.\n * When set, the client automatically handles WWW-Authenticate: Payment\n * challenges (Tempo, Stripe) on 402 responses before falling back to x402.\n * Pass an mppx client instance (from `Mppx.create()`).\n */\n mpp?: MppHandler;\n}\n\nexport type X402IntegritasFlow = 'single' | 'dual';\n\nexport interface X402IntegritasConfig {\n /** Enable Integritas stamp request headers */\n enabled?: boolean;\n /** Preferred Integritas flow for the request */\n flow?: X402IntegritasFlow;\n}\n\nexport interface X402RequestOptions {\n /** Per-request Integritas override */\n integritas?: boolean | X402IntegritasConfig;\n}\n\nexport type X402FetchInit = RequestInit & {\n /** SDK-specific per-request options (not forwarded to fetch as-is) */\n x402?: X402RequestOptions;\n};\n\nexport interface RelayWebSocketLike {\n readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n addEventListener?: (type: string, listener: (...args: any[]) => void) => void;\n removeEventListener?: (type: string, listener: (...args: any[]) => void) => void;\n on?: (type: string, listener: (...args: any[]) => void) => void;\n off?: (type: string, listener: (...args: any[]) => void) => void;\n removeListener?: (type: string, listener: (...args: any[]) => void) => void;\n onopen?: ((event: unknown) => void) | null;\n onmessage?: ((event: unknown) => void) | null;\n onerror?: ((event: unknown) => void) | null;\n onclose?: ((event: unknown) => void) | null;\n}\n\nexport type RelayWebSocketFactory = (url: string) => RelayWebSocketLike;\n\nexport interface X402RelayWsConfig {\n /** Enable WebSocket transport for relay URLs (still falls back to HTTP by default). */\n enabled?: boolean;\n /** Explicit WebSocket relay URL (default is derived from relay URL host). */\n wsUrl?: string;\n /** Timeout for WS connect and preflight call in milliseconds. Default: 5000. */\n preflightTimeoutMs?: number;\n /** Timeout for paid WS retry in milliseconds. Default: 10000. */\n paymentTimeoutMs?: number;\n /** Fallback to standard HTTP x402 flow when WS transport fails. Default: true. */\n fallbackToHttp?: boolean;\n /** Custom WebSocket factory, useful in runtimes without global WebSocket. */\n webSocketFactory?: RelayWebSocketFactory;\n}\n\nexport interface X402RelayWsError {\n code: number;\n message: string;\n data?: unknown;\n paymentRequired?: unknown;\n}\n\nexport interface X402RelayWsResponse {\n id?: string | number;\n result?: unknown;\n error?: X402RelayWsError;\n paymentResponse?: unknown;\n metadata?: Record<string, unknown>;\n}\n\nexport interface X402Client {\n /** Fetch with automatic x402 payment handling */\n fetch(input: string | URL | Request, init?: X402FetchInit): Promise<Response>;\n}\n\ntype RelaySocketEventName = 'open' | 'message' | 'error' | 'close';\ntype RelaySocketListener = (...args: any[]) => void;\n\ninterface RelayWsCallRequest {\n relayUrl: string;\n requestMethod: string;\n requestHeaders: Record<string, string>;\n requestBody?: unknown;\n paymentPayload?: unknown;\n timeoutMs: number;\n}\n\n/**\n * Create an x402 client for automatic payment handling.\n * Supports all RelAI facilitator networks: Solana, Base, Avalanche, SKALE Base, SKALE Base Sepolia, SKALE BITE, Polygon, and Ethereum.\n * Auto-detects the correct chain from the 402 response and picks the right\n * signing method (Solana SPL transfer, EVM EIP-3009 transferWithAuthorization).\n *\n * @example\n * ```typescript\n * import { createX402Client } from '@relai-fi/x402';\n *\n * const client = createX402Client({\n * wallets: { solana: solanaWallet, evm: evmWalletClient },\n * });\n *\n * // Automatically handles 402 on any RelAI-supported network\n * const response = await client.fetch('https://api.example.com/protected');\n * ```\n */\n// Networks that use EIP-2612 permit instead of EIP-3009 transferWithAuthorization (currently none)\nconst PERMIT_NETWORKS = new Set<string>([]);\n\n// Default EVM RPC URLs\nconst DEFAULT_EVM_RPC_URLS: Record<string, string> = {\n 'skale-base': 'https://skale-base.skalenodes.com/v1/base',\n 'skale-base-sepolia': 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha',\n 'skale-bite': 'https://base-sepolia-testnet.skalenodes.com/v1/bite-v2-sandbox',\n 'base': 'https://mainnet.base.org',\n 'avalanche': 'https://api.avax.network/ext/bc/C/rpc',\n 'polygon': 'https://polygon-rpc.com',\n 'ethereum': 'https://ethereum-rpc.publicnode.com',\n 'telos': 'https://rpc.telos.net',\n};\n\nexport function createX402Client(config: X402ClientConfig): X402Client {\n const {\n wallets = {},\n wallet: legacyWallet,\n facilitatorUrl = RELAI_FACILITATOR_URL,\n relayWs,\n preferredNetwork,\n networkSelectionMode = 'prefer_then_any',\n solanaRpcUrl = 'https://api.mainnet-beta.solana.com',\n evmRpcUrls = {},\n maxAmountAtomic,\n integritas,\n verbose = false,\n defaultHeaders = {},\n mpp,\n } = config;\n\n const relayWsEnabled = relayWs?.enabled === true;\n const relayWsPreflightTimeoutMs = relayWs?.preflightTimeoutMs ?? 5000;\n const relayWsPaymentTimeoutMs = relayWs?.paymentTimeoutMs ?? 10000;\n const relayWsFallbackToHttp = relayWs?.fallbackToHttp ?? true;\n const defaultIntegritas = normalizeIntegritasOptions(integritas);\n const relayWsReservedSubdomains = new Set<string>([\n 'www',\n 'api',\n 'localhost',\n 'admin',\n 'app',\n 'dashboard',\n 'docs',\n 'documentation',\n 'status',\n 'blog',\n 'facilitator',\n ]);\n\n const log = verbose ? console.log.bind(console, '[relai-x402]') : () => {};\n\n // Merge legacy wallet into wallet set\n const effectiveWallets: WalletSet = { ...wallets };\n if (legacyWallet && !effectiveWallets.solana) {\n effectiveWallets.solana = legacyWallet;\n }\n\n const hasSolanaWallet = Boolean(\n effectiveWallets.solana?.publicKey && effectiveWallets.solana?.signTransaction\n );\n if (hasSolanaWallet) log('Solana wallet ready');\n\n function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n }\n\n function parseJsonSafe(value: string): unknown {\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n }\n\n function addSocketListener(\n socket: RelayWebSocketLike,\n eventName: RelaySocketEventName,\n listener: RelaySocketListener,\n ): void {\n if (socket.addEventListener) {\n socket.addEventListener(eventName, listener);\n return;\n }\n\n if (socket.on) {\n socket.on(eventName, listener);\n }\n }\n\n function removeSocketListener(\n socket: RelayWebSocketLike,\n eventName: RelaySocketEventName,\n listener: RelaySocketListener,\n ): void {\n if (socket.removeEventListener) {\n socket.removeEventListener(eventName, listener);\n return;\n }\n\n if (socket.off) {\n socket.off(eventName, listener);\n return;\n }\n\n if (socket.removeListener) {\n socket.removeListener(eventName, listener);\n }\n }\n\n function resolveRelayWsUrl(relayUrl: string): string {\n if (relayWs?.wsUrl && relayWs.wsUrl.trim() !== '') {\n return relayWs.wsUrl.trim();\n }\n\n const parsedRelayUrl = new URL(relayUrl);\n const wsProtocol = parsedRelayUrl.protocol === 'https:' ? 'wss:' : 'ws:';\n return `${wsProtocol}//${parsedRelayUrl.host}/api/ws/relay`;\n }\n\n function resolveRelayWhitelabel(parsedRelayUrl: URL): string | null {\n const hostParts = parsedRelayUrl.hostname.toLowerCase().split('.').filter(Boolean);\n if (hostParts.length < 2) {\n return null;\n }\n\n const candidate = decodeURIComponent(hostParts[0] || '').trim();\n if (!candidate) {\n return null;\n }\n\n if (relayWsReservedSubdomains.has(candidate.toLowerCase())) {\n return null;\n }\n\n const lastPart = hostParts[hostParts.length - 1];\n const secondLastPart = hostParts[hostParts.length - 2];\n const isX402WhitelabelHost = hostParts.length >= 3 && secondLastPart === 'x402' && lastPart === 'fi';\n const isLocalWhitelabelHost = hostParts.length === 2 && lastPart === 'localhost';\n\n if (!isX402WhitelabelHost && !isLocalWhitelabelHost) {\n return null;\n }\n\n return candidate;\n }\n\n function resolveRelayTarget(relayUrl: string): { apiId: string; path: string } {\n const parsedRelayUrl = new URL(relayUrl);\n const match = parsedRelayUrl.pathname.match(/\\/relay\\/([^/]+)(\\/.*)?$/);\n if (match) {\n const apiId = decodeURIComponent(match[1]);\n const pathPart = match[2] || '/';\n return {\n apiId,\n path: `${pathPart}${parsedRelayUrl.search || ''}`,\n };\n }\n\n const whitelabel = resolveRelayWhitelabel(parsedRelayUrl);\n if (!whitelabel) {\n throw new Error(\n `[relai-x402] Unsupported relay URL format for WS transport: ${relayUrl}. ` +\n 'Expected /relay/:apiId/... or <whitelabel>.x402.fi/...',\n );\n }\n\n const pathPart = parsedRelayUrl.pathname && parsedRelayUrl.pathname !== ''\n ? parsedRelayUrl.pathname\n : '/';\n return {\n apiId: whitelabel,\n path: `${pathPart}${parsedRelayUrl.search || ''}`,\n };\n }\n\n function isRelayRequestUrl(requestUrl: string): boolean {\n try {\n resolveRelayTarget(requestUrl);\n return true;\n } catch {\n return false;\n }\n }\n\n function headersToRecord(headersInit?: HeadersInit): Record<string, string> {\n if (!headersInit) return {};\n\n const output: Record<string, string> = {};\n\n if (typeof Headers !== 'undefined' && headersInit instanceof Headers) {\n headersInit.forEach((value, key) => {\n output[key] = value;\n });\n return output;\n }\n\n if (Array.isArray(headersInit)) {\n for (const [key, value] of headersInit) {\n output[key] = value;\n }\n return output;\n }\n\n for (const [key, value] of Object.entries(headersInit)) {\n if (typeof value === 'string') {\n output[key] = value;\n } else if (Array.isArray(value)) {\n output[key] = value.join(', ');\n } else if (value !== undefined && value !== null) {\n output[key] = String(value);\n }\n }\n\n return output;\n }\n\n function hasHeaderCaseInsensitive(headers: Record<string, string>, headerName: string): boolean {\n const normalized = headerName.toLowerCase();\n return Object.keys(headers).some((key) => key.toLowerCase() === normalized);\n }\n\n function normalizeIntegritasFlow(value: unknown): X402IntegritasFlow | undefined {\n const normalized = String(value || '').trim().toLowerCase();\n if (normalized === 'single') return 'single';\n if (normalized === 'dual') return 'dual';\n return undefined;\n }\n\n function normalizeIntegritasOptions(\n value: boolean | X402IntegritasConfig | undefined,\n ): { enabled: boolean; flow?: X402IntegritasFlow } {\n if (value === true) return { enabled: true };\n if (value === false || value == null) return { enabled: false };\n\n const flow = normalizeIntegritasFlow(value.flow);\n const enabled =\n typeof value.enabled === 'boolean'\n ? value.enabled\n : true;\n\n return {\n enabled,\n ...(flow ? { flow } : {}),\n };\n }\n\n function resolveIntegritasOptions(\n override: boolean | X402IntegritasConfig | undefined,\n ): { enabled: boolean; flow?: X402IntegritasFlow } {\n if (override === undefined) {\n return defaultIntegritas;\n }\n\n if (typeof override === 'boolean') {\n return {\n enabled: override,\n ...(override && defaultIntegritas.flow ? { flow: defaultIntegritas.flow } : {}),\n };\n }\n\n const flow = normalizeIntegritasFlow(override.flow) || defaultIntegritas.flow;\n const enabled =\n typeof override.enabled === 'boolean'\n ? override.enabled\n : defaultIntegritas.enabled;\n\n return {\n enabled,\n ...(enabled && flow ? { flow } : {}),\n };\n }\n\n function stripInternalInit(init?: X402FetchInit): RequestInit | undefined {\n if (!init) return undefined;\n const { x402: _x402, ...requestInit } = init;\n return requestInit;\n }\n\n function applyIntegritasHeaders(\n headers: Record<string, string>,\n options: { enabled: boolean; flow?: X402IntegritasFlow },\n ): Record<string, string> {\n if (!options.enabled) return headers;\n\n if (!hasHeaderCaseInsensitive(headers, 'x-integritas')) {\n headers['X-Integritas'] = 'true';\n }\n\n if (options.flow && !hasHeaderCaseInsensitive(headers, 'x-integritas-flow')) {\n headers['X-Integritas-Flow'] = options.flow;\n }\n\n return headers;\n }\n\n function getRequestMethod(input: string | URL | Request, init?: RequestInit): string {\n const inputMethod = input instanceof Request ? input.method : undefined;\n return (init?.method || inputMethod || 'GET').toUpperCase();\n }\n\n async function bodyInitToWsPayload(bodyInit: unknown): Promise<unknown> {\n if (bodyInit === undefined || bodyInit === null) {\n return undefined;\n }\n\n if (typeof bodyInit === 'string') {\n const parsed = parseJsonSafe(bodyInit);\n return parsed === null ? bodyInit : parsed;\n }\n\n if (typeof URLSearchParams !== 'undefined' && bodyInit instanceof URLSearchParams) {\n return bodyInit.toString();\n }\n\n if (typeof FormData !== 'undefined' && bodyInit instanceof FormData) {\n const entries: Record<string, string> = {};\n for (const [key, value] of bodyInit.entries()) {\n entries[key] = typeof value === 'string' ? value : value.name;\n }\n return entries;\n }\n\n if (typeof Blob !== 'undefined' && bodyInit instanceof Blob) {\n const text = await bodyInit.text();\n if (!text) return undefined;\n const parsed = parseJsonSafe(text);\n return parsed === null ? text : parsed;\n }\n\n if (bodyInit instanceof ArrayBuffer) {\n return Array.from(new Uint8Array(bodyInit));\n }\n\n if (ArrayBuffer.isView(bodyInit)) {\n return Array.from(new Uint8Array(bodyInit.buffer, bodyInit.byteOffset, bodyInit.byteLength));\n }\n\n if (typeof Buffer !== 'undefined' && Buffer.isBuffer(bodyInit)) {\n return Array.from(bodyInit.values());\n }\n\n if (isRecord(bodyInit)) {\n return bodyInit;\n }\n\n return String(bodyInit);\n }\n\n async function resolveRequestBody(input: string | URL | Request, init?: RequestInit): Promise<unknown> {\n if (init && Object.prototype.hasOwnProperty.call(init, 'body')) {\n return bodyInitToWsPayload(init.body as unknown);\n }\n\n if (input instanceof Request) {\n const method = getRequestMethod(input, init);\n if (method === 'GET' || method === 'HEAD') {\n return undefined;\n }\n\n try {\n const cloned = input.clone();\n const text = await cloned.text();\n if (!text) return undefined;\n const parsed = parseJsonSafe(text);\n return parsed === null ? text : parsed;\n } catch {\n return undefined;\n }\n }\n\n return undefined;\n }\n\n function getRequestHeaders(input: string | URL | Request, init?: RequestInit): Record<string, string> {\n const fromInput = input instanceof Request ? headersToRecord(input.headers) : {};\n const fromInit = headersToRecord(init?.headers);\n const merged = {\n ...defaultHeaders,\n ...fromInput,\n ...fromInit,\n };\n\n if (!merged.Accept && !merged.accept) {\n merged.Accept = 'application/json';\n }\n\n return merged;\n }\n\n function toMessageString(data: unknown): string {\n if (typeof data === 'string') {\n return data;\n }\n\n if (isRecord(data) && typeof data.data !== 'undefined') {\n return toMessageString(data.data);\n }\n\n if (typeof Buffer !== 'undefined' && Buffer.isBuffer(data)) {\n return data.toString('utf8');\n }\n\n if (data instanceof ArrayBuffer) {\n const bytes = new Uint8Array(data);\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('utf8');\n }\n if (typeof TextDecoder !== 'undefined') {\n return new TextDecoder().decode(bytes);\n }\n throw new Error('Unsupported WebSocket message data type');\n }\n\n if (ArrayBuffer.isView(data)) {\n const bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('utf8');\n }\n if (typeof TextDecoder !== 'undefined') {\n return new TextDecoder().decode(bytes);\n }\n throw new Error('Unsupported WebSocket message data type');\n }\n\n throw new Error('Unsupported WebSocket message data type');\n }\n\n function getWebSocketFactory(): RelayWebSocketFactory {\n if (relayWs?.webSocketFactory) {\n return relayWs.webSocketFactory;\n }\n\n if (typeof WebSocket !== 'undefined') {\n return (wsUrl: string) => new WebSocket(wsUrl) as unknown as RelayWebSocketLike;\n }\n\n throw new Error(\n '[relai-x402] WebSocket is not available in this runtime. Provide relayWs.webSocketFactory.',\n );\n }\n\n async function relayCallOverWebSocket(request: RelayWsCallRequest): Promise<X402RelayWsResponse> {\n const wsFactory = getWebSocketFactory();\n const wsUrl = resolveRelayWsUrl(request.relayUrl);\n const target = resolveRelayTarget(request.relayUrl);\n const requestId = `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n const socket = wsFactory(wsUrl);\n\n return new Promise<X402RelayWsResponse>((resolve, reject) => {\n let settled = false;\n\n const settleResolve = (value: X402RelayWsResponse) => {\n if (settled) return;\n settled = true;\n cleanup();\n try {\n socket.close();\n } catch {\n // Ignore close errors.\n }\n resolve(value);\n };\n\n const settleReject = (error: Error) => {\n if (settled) return;\n settled = true;\n cleanup();\n try {\n socket.close();\n } catch {\n // Ignore close errors.\n }\n reject(error);\n };\n\n const timeoutId = setTimeout(() => {\n settleReject(new Error(`[relai-x402] Timed out waiting for WS relay response after ${request.timeoutMs}ms`));\n }, request.timeoutMs);\n\n const cleanup = () => {\n clearTimeout(timeoutId);\n removeSocketListener(socket, 'open', onOpen);\n removeSocketListener(socket, 'message', onMessage);\n removeSocketListener(socket, 'error', onError);\n removeSocketListener(socket, 'close', onClose);\n };\n\n const onOpen = () => {\n const envelope: Record<string, unknown> = {\n id: requestId,\n method: 'relay.call',\n params: {\n apiId: target.apiId,\n path: target.path,\n requestMethod: request.requestMethod,\n requestHeaders: request.requestHeaders,\n ...(request.requestBody !== undefined ? { requestBody: request.requestBody } : {}),\n },\n };\n\n if (request.paymentPayload !== undefined) {\n envelope.payment = request.paymentPayload;\n }\n\n try {\n socket.send(JSON.stringify(envelope));\n } catch {\n settleReject(new Error('[relai-x402] Failed to send WS relay request'));\n }\n };\n\n const onMessage = (...args: any[]) => {\n const payload = args.length > 0 ? args[0] : undefined;\n\n let parsed: unknown;\n try {\n parsed = parseJsonSafe(toMessageString(payload));\n } catch {\n return;\n }\n\n if (!isRecord(parsed)) return;\n\n const responseId =\n typeof parsed.id === 'string' || typeof parsed.id === 'number' ? String(parsed.id) : '';\n if (responseId !== requestId) return;\n\n settleResolve(parsed as X402RelayWsResponse);\n };\n\n const onError = () => {\n settleReject(new Error('[relai-x402] WebSocket relay transport error'));\n };\n\n const onClose = () => {\n settleReject(new Error('[relai-x402] WebSocket relay connection closed before response'));\n };\n\n addSocketListener(socket, 'open', onOpen);\n addSocketListener(socket, 'message', onMessage);\n addSocketListener(socket, 'error', onError);\n addSocketListener(socket, 'close', onClose);\n });\n }\n\n function extractPaymentRequirementsFromWsError(error: X402RelayWsError): any | null {\n const candidates: unknown[] = [error.paymentRequired, error.data];\n\n for (const candidate of candidates) {\n if (!isRecord(candidate)) continue;\n\n if (Array.isArray(candidate.accepts)) {\n return candidate;\n }\n\n if (isRecord(candidate.paymentRequired) && Array.isArray(candidate.paymentRequired.accepts)) {\n return candidate.paymentRequired;\n }\n\n if (isRecord(candidate.data) && Array.isArray(candidate.data.accepts)) {\n return candidate.data;\n }\n }\n\n return null;\n }\n\n function buildWsResponse(wsResponse: X402RelayWsResponse): Response {\n const statusFromMetadata =\n isRecord(wsResponse.metadata) && typeof wsResponse.metadata.status === 'number'\n ? wsResponse.metadata.status\n : 200;\n const status = Number.isInteger(statusFromMetadata) && statusFromMetadata >= 100 && statusFromMetadata <= 599\n ? statusFromMetadata\n : 200;\n\n const headers = new Headers();\n headers.set('Content-Type', 'application/json');\n\n if (wsResponse.paymentResponse !== undefined) {\n headers.set('PAYMENT-RESPONSE', encodeBase64Json(wsResponse.paymentResponse));\n }\n\n const bodyPayload = wsResponse.result === undefined ? null : wsResponse.result;\n return new Response(JSON.stringify(bodyPayload), {\n status,\n headers,\n });\n }\n\n // -----------------------------------------------------------------------\n // Select a payment option from the 402 response's `accepts` array\n // -----------------------------------------------------------------------\n function selectAcceptForWallet(a: any): { accept: any; chain: 'solana' | 'evm' } | null {\n const net = a.network || '';\n if (isSolana(net) && hasSolanaWallet) {\n return { accept: a, chain: 'solana' };\n }\n if (isEvm(net) && effectiveWallets.evm) {\n return { accept: a, chain: 'evm' };\n }\n return null;\n }\n\n function buildNoWalletError(accepts: any[], isWs: boolean): string {\n const networks = accepts.map((a: any) => a.network).join(', ');\n if (preferredNetwork && networkSelectionMode === 'strict_preferred') {\n const preferredCaip2 = NETWORK_CAIP2[preferredNetwork];\n return (\n `[relai-x402] Preferred network ${preferredNetwork} (${preferredCaip2}) is required, ` +\n `but no compatible wallet is connected. Available networks: ${networks}`\n );\n }\n\n return `[relai-x402] No wallet available for${isWs ? ' WS' : ''} networks: ${networks}`;\n }\n\n function selectAccept(accepts: any[]): { accept: any; chain: 'solana' | 'evm' } | null {\n // 1) Preferred network first\n if (preferredNetwork) {\n const caip2 = NETWORK_CAIP2[preferredNetwork];\n for (const a of accepts) {\n const net = a.network || '';\n if (net === preferredNetwork || net === caip2) {\n const selected = selectAcceptForWallet(a);\n if (selected) {\n return selected;\n }\n }\n }\n\n if (networkSelectionMode === 'strict_preferred') {\n return null;\n }\n }\n\n // 2) First option we have a wallet for\n for (const a of accepts) {\n const selected = selectAcceptForWallet(a);\n if (selected) {\n return selected;\n }\n }\n\n return null;\n }\n\n // -----------------------------------------------------------------------\n // Bridge extension — cross-chain payment routing (x402 bridge spec)\n // -----------------------------------------------------------------------\n\n function getBridgeExtension(requirements: any): any | null {\n const ext = requirements?.extensions?.bridge;\n if (!ext?.info?.settleEndpoint || !Array.isArray(ext.info.supportedSourceChains)) return null;\n return ext.info;\n }\n\n function selectBridgeSource(bridge: any): { chain: 'solana' | 'evm'; network: string; asset: string } | null {\n const sourceChains: string[] = bridge.supportedSourceChains || [];\n const sourceAssets: string[] = bridge.supportedSourceAssets || [];\n for (const caip2 of sourceChains) {\n if (isSolana(caip2) && hasSolanaWallet) {\n const asset = sourceAssets.find((a: string) => !a.startsWith('0x')) || '';\n return { chain: 'solana', network: caip2, asset };\n }\n if (isEvm(caip2) && effectiveWallets.evm) {\n const asset = sourceAssets.find((a: string) => a.startsWith('0x')) || '';\n return { chain: 'evm', network: caip2, asset };\n }\n }\n return null;\n }\n\n async function executeBridgePayment(\n bridge: any,\n accepts: any[],\n requirements: any,\n url: string,\n ): Promise<string> {\n const source = selectBridgeSource(bridge);\n if (!source) {\n throw new Error('[relai-x402] bridge extension found but no wallet matches supported source chains');\n }\n\n // Pick first accept as the target (merchant's preferred chain)\n const targetAccept = accepts[0];\n const amount = targetAccept.amount || targetAccept.maxAmountRequired;\n\n log(`Bridge: ${source.network} → ${targetAccept.network}, amount=${amount}`);\n\n // Amount guard\n if (maxAmountAtomic && BigInt(amount) > BigInt(maxAmountAtomic)) {\n throw new Error(`[relai-x402] Amount ${amount} exceeds max ${maxAmountAtomic}`);\n }\n\n // Build source-chain payment header (same logic as direct payment)\n let sourcePaymentHeader: string;\n if (source.chain === 'solana') {\n // Build a synthetic accept entry for the source chain.\n // payTo must be the bridge facilitator's Solana wallet (bridge.payTo),\n // NOT the merchant's address (which may be an EVM address).\n // feePayer comes from bridge.info — facilitator sponsors Solana gas.\n if (!bridge.payTo) {\n throw new Error('[relai-x402] bridge.info.payTo is required for Solana source payments');\n }\n const sourceAccept = {\n scheme: 'exact',\n network: source.network,\n asset: source.asset,\n payTo: bridge.payTo,\n amount: targetAccept.amount || targetAccept.maxAmountRequired,\n extra: {\n ...(bridge.feePayerSvm ? { feePayer: bridge.feePayerSvm } : {}),\n decimals: 6,\n },\n };\n sourcePaymentHeader = await buildSolanaPayment(sourceAccept, requirements, url);\n } else {\n const evmNetwork = normalizeNetwork(source.network);\n const usePermit = evmNetwork && PERMIT_NETWORKS.has(evmNetwork);\n const sourceAccept = {\n ...targetAccept,\n network: source.network,\n asset: source.asset || targetAccept.asset,\n ...(bridge.payTo ? { payTo: bridge.payTo } : {}),\n };\n sourcePaymentHeader = usePermit\n ? await buildEvmPermitPayment(sourceAccept, requirements, url)\n : await buildEvmPayment(sourceAccept, requirements, url);\n }\n\n // POST to bridge settle endpoint\n const bridgeRes = await fetch(bridge.settleEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n sourcePayment: sourcePaymentHeader,\n sourceChain: source.network,\n targetAccept,\n requirements,\n resource: url,\n paymentFacilitator: bridge.paymentFacilitator || null,\n ...(bridge.serviceKeyHash ? { serviceKeyHash: bridge.serviceKeyHash } : {}),\n }),\n });\n\n if (!bridgeRes.ok) {\n const err = await bridgeRes.json().catch(() => ({}));\n throw new Error(`[relai-x402] bridge settle failed: ${err.error || bridgeRes.status}`);\n }\n\n const bridgeData = await bridgeRes.json();\n if (!bridgeData.xPayment) {\n throw new Error('[relai-x402] bridge endpoint did not return xPayment header');\n }\n\n log(`Bridge settled: sourceTx=${bridgeData.sourceTxId}, targetTx=${bridgeData.targetTxId}`);\n return bridgeData.xPayment;\n }\n\n // -----------------------------------------------------------------------\n // JSON-RPC helper (for reading EVM contract state without ethers)\n // -----------------------------------------------------------------------\n async function evmRpcCall(rpcUrl: string, to: string, data: string): Promise<string> {\n const res = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_call',\n params: [{ to, data }, 'latest'],\n id: 1,\n }),\n });\n const json = await res.json();\n if (json.error) throw new Error(`RPC error: ${json.error.message}`);\n return json.result;\n }\n\n function getEvmRpcUrl(network: string): string {\n return evmRpcUrls[network] || DEFAULT_EVM_RPC_URLS[network] || '';\n }\n\n // -----------------------------------------------------------------------\n // Build EVM payment — EIP-2612 permit (for SKALE Base)\n // -----------------------------------------------------------------------\n async function buildEvmPermitPayment(\n accept: any,\n requirements: any,\n url: string,\n ): Promise<string> {\n const evmWallet = effectiveWallets.evm!;\n const extra = accept.extra || {};\n\n const rawNetwork = accept.network || '';\n const network = normalizeNetwork(rawNetwork);\n const chainId = network ? CHAIN_IDS[network] : parseInt(rawNetwork.split(':')[1] || '8453');\n const paymentAmount = accept.amount || accept.maxAmountRequired;\n const spender = extra.feePayer || accept.payTo;\n const usdcAddress = accept.asset;\n\n const rpcUrl = getEvmRpcUrl(network || rawNetwork);\n if (!rpcUrl) throw new Error(`[relai-x402] No EVM RPC URL for network ${network || rawNetwork}`);\n\n log('Building EIP-2612 permit on chain', chainId);\n\n // Read nonce from USDC contract: nonces(address) = 0x7ecebe00\n const paddedAddress = evmWallet.address.toLowerCase().replace('0x', '').padStart(64, '0');\n const nonceHex = await evmRpcCall(rpcUrl, usdcAddress, '0x7ecebe00' + paddedAddress);\n const nonce = nonceHex ? parseInt(nonceHex, 16) : 0;\n if (isNaN(nonce)) throw new Error(`[relai-x402] Failed to read permit nonce from ${usdcAddress} on ${rpcUrl}`);\n log(' Permit nonce:', nonce);\n\n // Read token name: name() = 0x06fdde03\n const nameHex = await evmRpcCall(rpcUrl, usdcAddress, '0x06fdde03');\n // Decode ABI-encoded string\n let tokenName = 'USD Coin';\n try {\n const offset = parseInt(nameHex.slice(2, 66), 16) * 2;\n const length = parseInt(nameHex.slice(2 + offset, 2 + offset + 64), 16);\n const hex = nameHex.slice(2 + offset + 64, 2 + offset + 64 + length * 2);\n tokenName = decodeURIComponent(hex.replace(/[0-9a-f]{2}/g, '%$&'));\n } catch {\n tokenName = extra.name || 'USD Coin';\n }\n log(' Token name:', tokenName);\n\n const deadline = Math.floor(Date.now() / 1000) + 600; // 10 min\n\n const domain = {\n name: tokenName,\n version: extra.version || '2',\n chainId,\n verifyingContract: usdcAddress,\n };\n\n const types = {\n Permit: [\n { name: 'owner', type: 'address' },\n { name: 'spender', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n };\n\n const message = {\n owner: evmWallet.address,\n spender,\n value: paymentAmount,\n nonce: String(nonce),\n deadline: String(deadline),\n };\n\n log('Signing EIP-2612 permit:', message);\n\n const signature = await evmWallet.signTypedData({\n domain,\n types,\n message,\n primaryType: 'Permit',\n });\n\n // Split signature into v, r, s\n const sigHex = (signature as string).replace('0x', '');\n const r = '0x' + sigHex.slice(0, 64);\n const s = '0x' + sigHex.slice(64, 128);\n const v = parseInt(sigHex.slice(128, 130), 16);\n\n log(' Permit signed: v=%d r=%s s=%s', v, r, s);\n\n // Build x402 v2 payment payload (SKALE format)\n const paymentPayload = {\n x402Version: 2,\n scheme: 'exact',\n network: network || rawNetwork,\n payload: {\n userAddress: evmWallet.address,\n permit: { deadline: String(deadline), v, r, s },\n amount: paymentAmount,\n },\n };\n\n return encodeBase64Json(paymentPayload);\n }\n\n // -----------------------------------------------------------------------\n // Build EVM payment (EIP-3009 transferWithAuthorization)\n // -----------------------------------------------------------------------\n async function buildEvmPayment(\n accept: any,\n requirements: any,\n url: string,\n ): Promise<string> {\n const evmWallet = effectiveWallets.evm!;\n const extra = accept.extra || {};\n\n const rawNetwork = accept.network || '';\n const network = normalizeNetwork(rawNetwork);\n const chainId = network ? CHAIN_IDS[network] : parseInt(rawNetwork.split(':')[1] || '8453');\n\n const paymentAmount = accept.amount || accept.maxAmountRequired;\n\n // EIP-3009 transferWithAuthorization does NOT require approve\n // Facilitator executes transfer directly with user's signature (zero gas for user)\n \n // For relayer-based facilitators (0xGasless), 'to' is the payTo (merchant).\n // For standard x402 (RelAI), 'to' is also payTo (merchant).\n const useRelayer = !!extra.relayerContract;\n\n const rpcUrl = getEvmRpcUrl(network || rawNetwork);\n const defaultTokenVersion = chainId === CHAIN_IDS['skale-bite'] ? '1' : '2';\n\n let tokenName = extra.name || 'USD Coin';\n if (!useRelayer && rpcUrl) {\n try {\n // Read token name from contract to avoid EIP-712 domain mismatch across bridged assets.\n const nameHex = await evmRpcCall(rpcUrl, accept.asset, '0x06fdde03');\n const offset = parseInt(nameHex.slice(2, 66), 16) * 2;\n const length = parseInt(nameHex.slice(2 + offset, 2 + offset + 64), 16);\n const hex = nameHex.slice(2 + offset + 64, 2 + offset + 64 + length * 2);\n tokenName = decodeURIComponent(hex.replace(/[0-9a-f]{2}/g, '%$&'));\n } catch {\n tokenName = extra.name || 'USD Coin';\n }\n }\n\n // EIP-3009 transferWithAuthorization typed data\n // When extra.relayerContract is present (e.g. 0xGasless), sign against the\n // relayer contract's EIP-712 domain instead of the token contract's domain.\n const domain = {\n name: useRelayer ? (extra.domainName || 'A402') : tokenName,\n version: useRelayer ? (extra.domainVersion || '1') : (extra.version || defaultTokenVersion),\n chainId,\n verifyingContract: useRelayer ? extra.relayerContract : accept.asset,\n };\n\n // Detect whether token supports EIP-2612 permit (but not EIP-3009)\n const tokenNetworkKey = network || rawNetwork;\n const networkTokens = NETWORK_TOKENS[tokenNetworkKey as keyof typeof NETWORK_TOKENS];\n const assetLower = (accept.asset || '').toLowerCase();\n const tokenInfo = networkTokens?.find((t: any) => t.address.toLowerCase() === assetLower) || networkTokens?.[0];\n const tokenStandards: string[] = Array.isArray(tokenInfo?.standards) ? tokenInfo.standards : [];\n const hasEip3009 = tokenStandards.some((s: string) => s.toLowerCase() === 'eip3009');\n const hasEip2612 = tokenStandards.some((s: string) => s.toLowerCase() === 'eip2612');\n const usePermit2612 = !hasEip3009 && hasEip2612;\n\n let message: Record<string, unknown>;\n let signature: string;\n let authorizationScheme: string;\n\n if (usePermit2612) {\n // EIP-2612 permit flow: read nonce from contract, sign Permit typed data\n // spender = feePayer (RelAI backend) who will call permit + transferFrom\n const spender = extra.feePayer || accept.payTo;\n const deadline = Math.floor(Date.now() / 1000) + 3600;\n\n let nonce = 0;\n if (rpcUrl) {\n try {\n const paddedAddress = evmWallet.address.toLowerCase().replace('0x', '').padStart(64, '0');\n const nonceHex = await evmRpcCall(rpcUrl, accept.asset, '0x7ecebe00' + paddedAddress);\n nonce = nonceHex ? parseInt(nonceHex, 16) : 0;\n } catch { nonce = 0; }\n }\n\n const permitTypes = {\n Permit: [\n { name: 'owner', type: 'address' },\n { name: 'spender', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n };\n\n message = {\n owner: evmWallet.address,\n spender,\n value: paymentAmount,\n nonce: String(nonce),\n deadline: String(deadline),\n };\n\n log('Signing EIP-2612 permit on chain', chainId);\n\n signature = await evmWallet.signTypedData({\n domain,\n types: permitTypes,\n message,\n primaryType: 'Permit',\n });\n\n authorizationScheme = 'eip2612';\n } else {\n // EIP-3009 transferWithAuthorization flow (default)\n const validAfter = 0;\n const validBefore = Math.floor(Date.now() / 1000) + 3600;\n const nonce = '0x' + [...crypto.getRandomValues(new Uint8Array(32))]\n .map(b => b.toString(16).padStart(2, '0')).join('');\n\n const transferTypes = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n message = {\n from: evmWallet.address,\n to: accept.payTo,\n value: paymentAmount,\n validAfter: String(validAfter),\n validBefore: String(validBefore),\n nonce,\n };\n\n log('Signing EIP-3009 transferWithAuthorization on chain', chainId);\n\n signature = await evmWallet.signTypedData({\n domain,\n types: transferTypes,\n message,\n primaryType: 'TransferWithAuthorization',\n });\n\n authorizationScheme = 'eip3009';\n }\n\n // Build x402 v2 payment payload\n const paymentPayload = {\n x402Version: 2,\n resource: requirements.resource || { url },\n accepted: accept,\n payload: {\n authorization: message,\n signature,\n authorizationScheme,\n },\n facilitatorUrl,\n };\n\n return encodeBase64Json(paymentPayload);\n }\n\n // -----------------------------------------------------------------------\n // Build Solana payment (SPL transfer with fee payer sponsorship)\n // -----------------------------------------------------------------------\n async function buildSolanaPayment(\n accept: any,\n requirements: any,\n url: string,\n ): Promise<string> {\n const solWallet = effectiveWallets.solana!;\n const extra = accept.extra || {};\n\n if (!extra.feePayer) {\n throw new Error('[relai-x402] Missing feePayer in Solana payment requirements');\n }\n\n const connection = new Connection(solanaRpcUrl, 'confirmed');\n const userPubkey = new PublicKey(solWallet.publicKey!.toString());\n const merchantPubkey = new PublicKey(accept.payTo);\n const feePayerPubkey = new PublicKey(extra.feePayer);\n const mintPubkey = new PublicKey(accept.asset);\n const paymentAmount = BigInt(accept.amount || accept.maxAmountRequired);\n\n log('Building Solana SPL transfer');\n log(' User:', userPubkey.toBase58());\n log(' Merchant:', merchantPubkey.toBase58());\n log(' FeePayer:', feePayerPubkey.toBase58());\n log(' Mint:', mintPubkey.toBase58());\n log(' Amount:', paymentAmount.toString());\n\n // Determine token program (TOKEN_PROGRAM_ID vs TOKEN_2022)\n const mintInfo = await getMint(connection, mintPubkey);\n const programId = mintInfo.address.equals(mintPubkey)\n ? (mintInfo as any).owner?.toBase58?.() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n // Get ATAs (allowOffCurve=true for smart wallets / PDA signers)\n const sourceAta = await getAssociatedTokenAddress(\n mintPubkey, userPubkey, true, programId,\n );\n const destinationAta = await getAssociatedTokenAddress(\n mintPubkey, merchantPubkey, true, programId,\n );\n\n log(' Source ATA:', sourceAta.toBase58());\n log(' Dest ATA:', destinationAta.toBase58());\n\n // Build transfer instruction\n const transferIx = createTransferCheckedInstruction(\n sourceAta,\n mintPubkey,\n destinationAta,\n userPubkey,\n paymentAmount,\n mintInfo.decimals,\n [],\n programId,\n );\n\n // Build versioned transaction with feePayer\n const { blockhash } = await connection.getLatestBlockhash('confirmed');\n const message = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: blockhash,\n instructions: [transferIx],\n }).compileToV0Message();\n\n const transaction = new VersionedTransaction(message);\n\n // User signs (feePayer signs on backend/facilitator side)\n const signedTx = await solWallet.signTransaction!(transaction) as VersionedTransaction;\n log('Transaction signed by user');\n\n // Serialize to base64\n const serializedTx = Buffer.from(signedTx.serialize()).toString('base64');\n\n // Build x402 v2 payment payload\n const paymentPayload = {\n x402Version: 2,\n resource: requirements.resource || { url },\n accepted: accept,\n payload: {\n transaction: serializedTx,\n },\n };\n\n return encodeBase64Json(paymentPayload);\n }\n\n // -----------------------------------------------------------------------\n // Main fetch\n // -----------------------------------------------------------------------\n function encodeBase64Json(payload: unknown): string {\n const serialized = JSON.stringify(payload);\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(serialized, 'utf8').toString('base64');\n }\n if (typeof btoa !== 'undefined') {\n return btoa(serialized);\n }\n throw new Error('[relai-x402] Base64 encoding is not available in this runtime');\n }\n\n function decodeBase64Json(encoded: string): any | null {\n try {\n const normalized = encoded.trim().replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, '=');\n const decoded = typeof Buffer !== 'undefined'\n ? Buffer.from(padded, 'base64').toString('utf8')\n : atob(padded);\n return JSON.parse(decoded);\n } catch {\n return null;\n }\n }\n\n function parsePaymentRequiredHeader(response: Response): any | null {\n const headerValue =\n response.headers.get('payment-required') ||\n response.headers.get('PAYMENT-REQUIRED') ||\n response.headers.get('x-payment-required') ||\n response.headers.get('X-PAYMENT-REQUIRED');\n\n if (!headerValue) return null;\n\n const trimmed = headerValue.trim();\n if (!trimmed) return null;\n\n try {\n return JSON.parse(trimmed);\n } catch {\n return decodeBase64Json(trimmed);\n }\n }\n\n function getAccepts(requirements: any): any[] {\n if (!requirements || typeof requirements !== 'object') {\n return [];\n }\n\n if (Array.isArray(requirements.accepts)) {\n return requirements.accepts;\n }\n\n if (requirements.paymentRequired && Array.isArray(requirements.paymentRequired.accepts)) {\n return requirements.paymentRequired.accepts;\n }\n\n if (requirements.data && Array.isArray(requirements.data.accepts)) {\n return requirements.data.accepts;\n }\n\n return [];\n }\n\n async function x402Fetch(\n input: string | URL | Request,\n init?: X402FetchInit,\n ): Promise<Response> {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;\n log('Request:', url);\n\n const requestInit = stripInternalInit(init);\n const integritasOptions = resolveIntegritasOptions(init?.x402?.integritas);\n const requestMethod = getRequestMethod(input, requestInit);\n const requestHeaders = applyIntegritasHeaders(\n getRequestHeaders(input, requestInit),\n integritasOptions,\n );\n const requestInitWithHeaders: RequestInit = {\n ...(requestInit || {}),\n headers: requestHeaders,\n };\n const requestBody = await resolveRequestBody(input, requestInitWithHeaders);\n\n if (relayWsEnabled && isRelayRequestUrl(url)) {\n let wsPaymentPhaseStarted = false;\n try {\n log('Using WebSocket relay transport');\n\n const wsPreflightResponse = await relayCallOverWebSocket({\n relayUrl: url,\n requestMethod,\n requestHeaders,\n requestBody,\n timeoutMs: relayWsPreflightTimeoutMs,\n });\n\n if (!wsPreflightResponse.error) {\n return buildWsResponse(wsPreflightResponse);\n }\n\n if (Number(wsPreflightResponse.error.code) !== 402) {\n throw new Error(wsPreflightResponse.error.message || '[relai-x402] WebSocket relay request failed');\n }\n\n const wsRequirements = extractPaymentRequirementsFromWsError(wsPreflightResponse.error);\n if (!wsRequirements) {\n throw new Error(\n wsPreflightResponse.error.message || '[relai-x402] No payment requirements in WS 402 response'\n );\n }\n\n const wsAccepts = getAccepts(wsRequirements);\n if (!wsAccepts.length) {\n throw new Error('[relai-x402] No payment options in WS 402 response');\n }\n\n if (wsAccepts.length > 1) {\n throw new Error(\n '[relai-x402] WS relay currently supports a single payment payload; use HTTP flow for multi-accept payments'\n );\n }\n\n const wsSelected = selectAccept(wsAccepts);\n if (!wsSelected) {\n throw new Error(buildNoWalletError(wsAccepts, true));\n }\n\n const { accept, chain } = wsSelected;\n const amount = accept.amount || accept.maxAmountRequired;\n\n if (maxAmountAtomic && BigInt(amount) > BigInt(maxAmountAtomic)) {\n throw new Error(`[relai-x402] Amount ${amount} exceeds max ${maxAmountAtomic}`);\n }\n\n wsPaymentPhaseStarted = true;\n\n let paymentHeader: string | null = null;\n if (chain === 'solana' && hasSolanaWallet) {\n paymentHeader = await buildSolanaPayment(accept, wsRequirements, url);\n } else if (chain === 'evm') {\n const evmNetwork = normalizeNetwork(accept.network || '');\n const usePermit = evmNetwork && PERMIT_NETWORKS.has(evmNetwork);\n paymentHeader = usePermit\n ? await buildEvmPermitPayment(accept, wsRequirements, url)\n : await buildEvmPayment(accept, wsRequirements, url);\n }\n\n if (!paymentHeader) {\n throw new Error('[relai-x402] Unexpected state - no WS payment handler matched');\n }\n\n const paymentPayload = decodeBase64Json(paymentHeader);\n if (!paymentPayload) {\n throw new Error('[relai-x402] Failed to decode payment payload for WS relay call');\n }\n\n const wsPaidResponse = await relayCallOverWebSocket({\n relayUrl: url,\n requestMethod,\n requestHeaders,\n requestBody,\n paymentPayload,\n timeoutMs: relayWsPaymentTimeoutMs,\n });\n\n if (wsPaidResponse.error) {\n throw new Error(wsPaidResponse.error.message || '[relai-x402] WebSocket paid relay request failed');\n }\n\n return buildWsResponse(wsPaidResponse);\n } catch (wsError) {\n const wsMessage = wsError instanceof Error ? wsError.message : String(wsError);\n log('WebSocket relay transport failed:', wsMessage);\n\n if (wsPaymentPhaseStarted) {\n // Do not retry over HTTP after payment flow has started (may trigger duplicate signing/payment prompts).\n throw wsError instanceof Error ? wsError : new Error(`[relai-x402] ${wsMessage}`);\n }\n\n if (!relayWsFallbackToHttp) {\n throw wsError instanceof Error ? wsError : new Error(`[relai-x402] ${wsMessage}`);\n }\n\n log('Falling back to HTTP x402 flow');\n }\n }\n\n const response = await fetch(input, requestInitWithHeaders);\n if (response.status !== 402) return response;\n\n log('Got 402 Payment Required');\n\n // ── MPP: check for WWW-Authenticate: Payment challenge ──────────────\n if (mpp) {\n const wwwAuth = response.headers.get('www-authenticate');\n if (wwwAuth && /^Payment\\s+/i.test(wwwAuth.trim())) {\n log('MPP challenge detected in WWW-Authenticate header');\n try {\n const credential = await mpp.createCredential(response);\n if (credential) {\n log('MPP credential created, retrying with Authorization: Payment');\n const mppRetry = await fetch(input, {\n ...requestInitWithHeaders,\n headers: {\n ...requestHeaders,\n 'Authorization': credential.startsWith('Payment ') ? credential : `Payment ${credential}`,\n },\n });\n if (mppRetry.status !== 402) {\n return mppRetry;\n }\n log('MPP retry still returned 402, falling through to x402');\n }\n } catch (mppErr) {\n log(`MPP payment failed (${mppErr instanceof Error ? mppErr.message : mppErr}), falling through to x402`);\n }\n }\n }\n // ── End MPP ─────────────────────────────────────────────────────────\n\n let requirementsFromBody: any = null;\n try {\n requirementsFromBody = await response.clone().json();\n } catch {}\n\n const requirementsFromHeader = parsePaymentRequiredHeader(response);\n\n let requirements: any = requirementsFromBody;\n let accepts = getAccepts(requirementsFromBody);\n\n if (!accepts.length && requirementsFromHeader) {\n const headerAccepts = getAccepts(requirementsFromHeader);\n\n if (headerAccepts.length || !requirements || typeof requirements !== 'object') {\n requirements = requirementsFromHeader;\n accepts = headerAccepts;\n log('402 body missing accepts; using PAYMENT-REQUIRED header fallback');\n }\n }\n\n if (!requirements || typeof requirements !== 'object') {\n throw new Error('[relai-x402] Failed to parse 402 response body/header');\n }\n\n if (!accepts.length) throw new Error('[relai-x402] No payment options in 402 response');\n\n const selected = selectAccept(accepts);\n if (!selected) {\n // Fallback: check bridge extension for cross-chain routing\n const bridge = getBridgeExtension(requirements);\n if (bridge && selectBridgeSource(bridge)) {\n log('No direct wallet match — attempting bridge extension flow');\n const paymentHeader = await executeBridgePayment(bridge, accepts, requirements, url);\n log('Retrying with X-PAYMENT header (bridge)');\n return fetch(input, {\n ...requestInitWithHeaders,\n headers: { ...requestHeaders, 'X-PAYMENT': paymentHeader },\n });\n }\n throw new Error(buildNoWalletError(accepts, false));\n }\n\n const { accept, chain } = selected;\n const amount = accept.amount || accept.maxAmountRequired;\n log(`Selected: ${chain} / ${accept.network} / amount=${amount}`);\n\n // Amount guard\n if (maxAmountAtomic && BigInt(amount) > BigInt(maxAmountAtomic)) {\n throw new Error(`[relai-x402] Amount ${amount} exceeds max ${maxAmountAtomic}`);\n }\n\n // Solana — build SPL transfer natively (no x402-solana dependency)\n if (chain === 'solana' && hasSolanaWallet) {\n const paymentHeader = await buildSolanaPayment(accept, requirements, url);\n log('Retrying with X-PAYMENT header (Solana)');\n return fetch(input, {\n ...requestInitWithHeaders,\n headers: {\n ...requestHeaders,\n 'X-PAYMENT': paymentHeader,\n },\n });\n }\n\n // EVM — build payment header and retry\n if (chain === 'evm') {\n const evmNetwork = normalizeNetwork(accept.network || '');\n const usePermit = evmNetwork && PERMIT_NETWORKS.has(evmNetwork);\n const paymentHeader = usePermit\n ? await buildEvmPermitPayment(accept, requirements, url)\n : await buildEvmPayment(accept, requirements, url);\n log('Retrying with X-PAYMENT header');\n return fetch(input, {\n ...requestInitWithHeaders,\n headers: {\n ...requestHeaders,\n 'X-PAYMENT': paymentHeader,\n },\n });\n }\n\n throw new Error('[relai-x402] Unexpected state - no payment handler matched');\n }\n\n return { fetch: x402Fetch };\n}\n\nexport default createX402Client;\n","// src/relay-feedback.ts\n// Standalone utility for submitting ERC-8004 feedback about third-party APIs.\n// Not a plugin — call directly from your relay/aggregator application code.\n\nimport { ethers } from 'ethers';\n\nexport interface RelayFeedbackConfig {\n /**\n * ERC-8004 agentId (NFT tokenId) of the **target API** you are calling.\n */\n agentId: string | number;\n /**\n * Whether the API call succeeded.\n */\n success: boolean;\n /**\n * Elapsed milliseconds for the API call.\n */\n responseTimeMs?: number;\n /**\n * Endpoint path of the called API (e.g. '/v1/data').\n */\n endpoint?: string;\n /**\n * Private key of the **relay/third-party** wallet that signs feedback.\n * MUST be different from the API owner's wallet — ReputationRegistry\n * may restrict self-feedback. Wallet needs CREDIT tokens on SKALE Base.\n * Default: process.env.FEEDBACK_WALLET_PRIVATE_KEY\n */\n feedbackWalletPrivateKey?: string;\n /**\n * SKALE Base Sepolia RPC URL.\n * Default: process.env.ERC8004_RPC_URL or SKALE Base Sepolia public RPC.\n */\n rpcUrl?: string;\n /**\n * ERC-8004 ReputationRegistry contract address.\n * Default: process.env.ERC8004_REPUTATION_REGISTRY\n */\n reputationRegistryAddress?: string;\n}\n\nconst RELAY_FEEDBACK_REPUTATION_ABI = [\n 'function giveFeedback(uint256 agentId, int128 value, uint8 valueDecimals, string tag1, string tag2, string endpoint, string feedbackURI, bytes32 feedbackHash) external',\n];\n\n/**\n * Submit ERC-8004 on-chain feedback about a **third-party API** you called.\n *\n * Call this fire-and-forget from your relay/aggregator after every external API call.\n * Uses a separate relay wallet (not the API owner's key) to avoid self-feedback restrictions.\n *\n * Records:\n * - `successRate`: 10000 (= 100%) on success, 0 on failure — 2 decimal places\n * - `responseTime`: elapsed milliseconds\n *\n * @example\n * ```typescript\n * import { submitRelayFeedback } from '@relai-fi/x402/relay-feedback';\n *\n * // after calling an external API:\n * const start = Date.now();\n * const result = await fetch('https://other-api.com/data');\n * submitRelayFeedback({\n * agentId: '5',\n * success: result.ok,\n * responseTimeMs: Date.now() - start,\n * endpoint: '/data',\n * });\n * ```\n */\nexport function submitRelayFeedback(config: RelayFeedbackConfig): void {\n const agentId = String(config.agentId);\n const endpoint = config.endpoint ?? '';\n const responseTimeMs = config.responseTimeMs ?? 0;\n\n const privateKey = config.feedbackWalletPrivateKey\n ?? (typeof process !== 'undefined'\n ? process.env?.FEEDBACK_WALLET_PRIVATE_KEY ?? process.env?.ERC8004_FEEDBACK_WALLET_PRIVATE_KEY\n : undefined);\n const reputationAddress = config.reputationRegistryAddress\n ?? (typeof process !== 'undefined' ? process.env?.ERC8004_REPUTATION_REGISTRY : undefined);\n const rpcUrl = config.rpcUrl\n ?? (typeof process !== 'undefined' ? process.env?.ERC8004_RPC_URL : undefined)\n ?? 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha';\n\n if (!privateKey || !reputationAddress) {\n console.warn('[relai:submitRelayFeedback] FEEDBACK_WALLET_PRIVATE_KEY or ERC8004_REPUTATION_REGISTRY not set — skipping');\n return;\n }\n\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n const signer = new ethers.Wallet(privateKey, provider);\n const reputation = new ethers.Contract(reputationAddress, RELAY_FEEDBACK_REPUTATION_ABI, signer);\n const id = BigInt(agentId);\n\n (async () => {\n const successValue = config.success ? 10000n : 0n;\n try {\n const srTx = await reputation.giveFeedback(\n id, successValue, 2, 'successRate', '', endpoint, '', ethers.ZeroHash,\n );\n await srTx.wait();\n console.log(`[relai:submitRelayFeedback] successRate confirmed agentId=${agentId} success=${config.success}`);\n } catch (err: any) {\n console.warn(`[relai:submitRelayFeedback] successRate failed (non-fatal): ${err?.message}`);\n }\n\n if (responseTimeMs > 0) {\n try {\n const rtTx = await reputation.giveFeedback(\n id, BigInt(Math.max(0, Math.round(responseTimeMs))), 0, 'responseTime', '', endpoint, '', ethers.ZeroHash,\n );\n console.log(`[relai:submitRelayFeedback] responseTime sent agentId=${agentId} ms=${responseTimeMs} tx=${rtTx.hash}`);\n } catch (err: any) {\n console.warn(`[relai:submitRelayFeedback] responseTime failed (non-fatal): ${err?.message}`);\n }\n }\n })();\n}\n","/**\n * Utility to convert x402 payment payloads between v1 and v2 formats.\n * \n * V1 PaymentPayload format:\n * {\n * \"x402Version\": 1,\n * \"scheme\": \"exact\",\n * \"network\": \"solana\",\n * \"payload\": { ... }\n * }\n * \n * V2 PaymentPayload format:\n * {\n * \"x402Version\": 2,\n * \"resource\": { \"url\": \"...\", \"description\": \"...\", \"mimeType\": \"...\" },\n * \"accepted\": { \"scheme\": \"exact\", \"network\": \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\", ... },\n * \"payload\": { ... }\n * }\n */\n\n// Network name mappings between v1 (simple names) and v2 (CAIP-2)\nexport const NETWORK_V1_TO_V2: Record<string, string> = {\n 'solana': 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n 'solana-devnet': 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n 'base': 'eip155:8453',\n 'base-sepolia': 'eip155:84532',\n 'ethereum': 'eip155:1',\n 'polygon': 'eip155:137',\n 'avalanche': 'eip155:43114',\n 'skale-base': 'eip155:1187947933',\n 'skale-base-sepolia': 'eip155:324705682',\n 'peaq': 'eip155:3338',\n 'sei': 'eip155:1329',\n 'telos': 'eip155:40',\n};\n\nexport const NETWORK_V2_TO_V1: Record<string, string> = Object.fromEntries(\n Object.entries(NETWORK_V1_TO_V2).map(([k, v]) => [v, k])\n);\n\n/**\n * Convert CAIP-2 network identifier to simple v1 network name\n */\nexport function networkV2ToV1(caip2Network: string): string {\n if (!caip2Network) return 'solana';\n \n // Direct lookup\n if (NETWORK_V2_TO_V1[caip2Network]) {\n return NETWORK_V2_TO_V1[caip2Network];\n }\n \n // Handle partial matches for Solana\n if (caip2Network.startsWith('solana:')) {\n const chainId = caip2Network.split(':')[1];\n if (chainId === '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp') return 'solana';\n if (chainId === 'EtWTRABZaYq6iMfeYKouRu166VU2xqa1') return 'solana-devnet';\n return 'solana';\n }\n \n // Handle EVM chains by chain ID\n if (caip2Network.startsWith('eip155:')) {\n const chainId = caip2Network.split(':')[1];\n const mapping: Record<string, string> = {\n '1': 'ethereum',\n '137': 'polygon',\n '8453': 'base',\n '84532': 'base-sepolia',\n '43114': 'avalanche',\n '1187947933': 'skale-base',\n '324705682': 'skale-base-sepolia',\n '3338': 'peaq',\n '1329': 'sei',\n '40': 'telos',\n };\n return mapping[chainId] || caip2Network;\n }\n \n return caip2Network;\n}\n\n/**\n * Convert simple v1 network name to CAIP-2 identifier\n */\nexport function networkV1ToV2(v1Network: string): string {\n if (!v1Network) return 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\n return NETWORK_V1_TO_V2[v1Network] || v1Network;\n}\n\nexport type X402Version = 1 | 2;\n\nexport interface V1PaymentPayload {\n x402Version: 1;\n scheme: string;\n network: string;\n payload: {\n transaction?: string;\n signature?: string;\n authorization?: unknown;\n };\n facilitatorUrl?: string;\n}\n\nexport interface V2PaymentPayload {\n x402Version: 2;\n resource: {\n url: string;\n description?: string;\n mimeType?: string;\n };\n accepted: {\n scheme: string;\n network: string;\n amount?: string;\n maxAmountRequired?: string;\n asset?: string;\n payTo?: string;\n maxTimeoutSeconds?: number;\n extra?: Record<string, unknown>;\n };\n payload: {\n transaction?: string;\n signature?: string;\n authorization?: unknown;\n };\n facilitatorUrl?: string;\n}\n\nexport type PaymentPayload = V1PaymentPayload | V2PaymentPayload;\n\n/**\n * Detect x402 version from payload\n */\nexport function detectPayloadVersion(payload: unknown): X402Version | null {\n if (!payload || typeof payload !== 'object') return null;\n \n const p = payload as Record<string, unknown>;\n \n if (p.x402Version === 1) return 1;\n if (p.x402Version === 2) return 2;\n \n // Heuristics if x402Version is missing\n if ('accepted' in p && 'resource' in p) return 2;\n if ('scheme' in p && 'network' in p && !('accepted' in p)) return 1;\n \n return null;\n}\n\n/**\n * Convert v2 payment payload to v1 format\n */\nexport function convertV2ToV1(v2Payload: V2PaymentPayload): V1PaymentPayload {\n const accepted = v2Payload.accepted || {};\n \n return {\n x402Version: 1,\n scheme: accepted.scheme || 'exact',\n network: networkV2ToV1(accepted.network),\n payload: v2Payload.payload,\n };\n}\n\n/**\n * Convert v1 payment payload to v2 format\n */\nexport function convertV1ToV2(\n v1Payload: V1PaymentPayload,\n resourceInfo: { url?: string; description?: string; mimeType?: string } = {}\n): V2PaymentPayload {\n return {\n x402Version: 2,\n resource: {\n url: resourceInfo.url || '',\n description: resourceInfo.description || '',\n mimeType: resourceInfo.mimeType || 'application/json',\n },\n accepted: {\n scheme: v1Payload.scheme || 'exact',\n network: networkV1ToV2(v1Payload.network),\n },\n payload: v1Payload.payload,\n };\n}\n\n/**\n * Convert payment payload to target version\n */\nexport function convertPayloadToVersion(\n payload: PaymentPayload,\n targetVersion: X402Version,\n options: { resourceInfo?: { url?: string; description?: string; mimeType?: string } } = {}\n): PaymentPayload | null {\n const sourceVersion = detectPayloadVersion(payload);\n \n if (!sourceVersion) {\n console.warn('[payload-converter] Could not detect source payload version');\n return null;\n }\n \n // No conversion needed\n if (sourceVersion === targetVersion) {\n return payload;\n }\n \n // V2 -> V1\n if (sourceVersion === 2 && targetVersion === 1) {\n return convertV2ToV1(payload as V2PaymentPayload);\n }\n \n // V1 -> V2\n if (sourceVersion === 1 && targetVersion === 2) {\n return convertV1ToV2(payload as V1PaymentPayload, options.resourceInfo);\n }\n \n return null;\n}\n\n/**\n * Normalize payment header for target x402 version\n */\nexport function normalizePaymentHeader(\n base64Header: string,\n targetVersion: X402Version,\n options: { resourceInfo?: { url?: string; description?: string; mimeType?: string } } = {}\n): { header: string; payload: PaymentPayload } | null {\n if (!base64Header) return null;\n \n try {\n const decoded = JSON.parse(\n typeof window !== 'undefined' \n ? atob(base64Header) \n : Buffer.from(base64Header, 'base64').toString()\n );\n const converted = convertPayloadToVersion(decoded, targetVersion, options);\n \n if (!converted) {\n return null;\n }\n \n const encoded = typeof window !== 'undefined'\n ? btoa(JSON.stringify(converted))\n : Buffer.from(JSON.stringify(converted)).toString('base64');\n \n return {\n header: encoded,\n payload: converted,\n };\n } catch (e) {\n console.error('[payload-converter] Failed to normalize header:', e);\n return null;\n }\n}\n\n/**\n * Check if network is Solana-based\n */\nexport function isSolanaNetwork(network: string): boolean {\n return network === 'solana' || \n network === 'solana-devnet' || \n network.startsWith('solana:');\n}\n\n/**\n * Check if network is EVM-based\n */\nexport function isEvmNetwork(network: string): boolean {\n const evmNetworks = ['base', 'base-sepolia', 'ethereum', 'polygon', 'avalanche', 'skale-base', 'skale-base-sepolia', 'skale-bite', 'peaq', 'sei', 'telos'];\n return evmNetworks.includes(network) || network.startsWith('eip155:');\n}\n\n// ============================================================================\n// Amount Conversion Utilities\n// ============================================================================\n\n/**\n * Convert USD amount to atomic units\n * @param usd - Amount in USD (e.g., 0.05)\n * @param decimals - Token decimals (default: 6 for USDC)\n * @returns Atomic units as string\n */\nexport function toAtomicUnits(usd: number, decimals: number = 6): string {\n return Math.floor(usd * Math.pow(10, decimals)).toString();\n}\n\n/**\n * Convert atomic units to USD amount\n * @param atomic - Atomic units (string or bigint)\n * @param decimals - Token decimals (default: 6 for USDC)\n * @returns USD amount as number\n */\nexport function fromAtomicUnits(atomic: string | bigint, decimals: number = 6): number {\n const value = typeof atomic === 'bigint' ? atomic : BigInt(atomic);\n return Number(value) / Math.pow(10, decimals);\n}\n\n/**\n * Format USD amount for display\n * @param usd - Amount in USD\n * @param maxDecimals - Maximum decimal places (default: 4)\n * @returns Formatted string\n */\nexport function formatUsd(usd: number, maxDecimals: number = 4): string {\n if (usd < 0.0001) return '<$0.0001';\n return `$${usd.toFixed(maxDecimals).replace(/\\.?0+$/, '')}`;\n}\n"],"mappings":"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","names":["paymentInfo","paymentResponse","normalizeIntegritasOptions","pathPart","normalizeIntegritasFlow","accept","chain","amount"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/server.ts","../src/client.ts","../src/relay-feedback.ts","../src/payment-codes.ts","../src/utils/payload-converter.ts"],"sourcesContent":["// src/types.ts\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** RelAI Facilitator URL */\nexport const RELAI_FACILITATOR_URL = 'https://facilitator.x402.fi';\n\n// ============================================================================\n// Supported Networks\n// ============================================================================\n\n/** All networks supported by RelAI facilitator */\nexport type RelaiNetwork =\n | 'solana'\n | 'solana-devnet'\n | 'base'\n | 'avalanche'\n | 'skale-base'\n | 'skale-base-sepolia'\n | 'skale-bite'\n | 'polygon'\n | 'ethereum'\n | 'telos';\n\n/** CAIP-2 network identifiers */\nexport const NETWORK_CAIP2: Record<RelaiNetwork, string> = {\n 'solana': 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n 'solana-devnet': 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n 'base': 'eip155:8453',\n 'avalanche': 'eip155:43114',\n 'skale-base': 'eip155:1187947933',\n 'skale-base-sepolia': 'eip155:324705682',\n 'skale-bite': 'eip155:103698795',\n 'polygon': 'eip155:137',\n 'ethereum': 'eip155:1',\n 'telos': 'eip155:40',\n};\n\n/** Reverse lookup: CAIP-2 → simple network name */\nexport const CAIP2_TO_NETWORK: Record<string, RelaiNetwork> = Object.fromEntries(\n Object.entries(NETWORK_CAIP2).map(([k, v]) => [v, k as RelaiNetwork])\n) as Record<string, RelaiNetwork>;\n\n/** Chain IDs for EVM networks */\nexport const CHAIN_IDS: Record<string, number> = {\n 'base': 8453,\n 'avalanche': 43114,\n 'skale-base': 1187947933,\n 'skale-base-sepolia': 324705682,\n 'skale-bite': 103698795,\n 'polygon': 137,\n 'ethereum': 1,\n 'telos': 40,\n};\n\nexport interface NetworkToken {\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n domainVersion?: string;\n isStableUsd?: boolean;\n standards?: string[];\n}\n\n/** Token metadata per network (default token is always the first entry) */\nexport const NETWORK_TOKENS: Partial<Record<RelaiNetwork, NetworkToken[]>> = {\n 'solana': [\n {\n address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',\n symbol: 'USDC',\n name: 'USD Coin',\n decimals: 6,\n },\n ],\n 'solana-devnet': [\n {\n address: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',\n symbol: 'USDC',\n name: 'USD Coin (Devnet)',\n decimals: 6,\n },\n ],\n 'base': [\n { address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', symbol: 'USDC', name: 'USD Coin', decimals: 6, domainVersion: '2', isStableUsd: true },\n ],\n 'avalanche': [\n {\n address: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n symbol: 'USDC',\n name: 'USD Coin',\n decimals: 6,\n domainVersion: '2',\n isStableUsd: true,\n },\n ],\n 'telos': [\n {\n address: '0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b',\n symbol: 'USDC',\n name: 'USD Coin',\n decimals: 6,\n isStableUsd: true,\n standards: ['eip2612'],\n },\n ],\n 'skale-base': [\n {\n address: '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n symbol: 'USDC',\n name: 'Bridged USDC (SKALE Bridge)',\n decimals: 6,\n domainVersion: '2',\n isStableUsd: true,\n },\n {\n address: '0x2bF5bF154b515EaA82C31a65ec11554fF5aF7fCA',\n symbol: 'USDT',\n name: 'Bridged USDT (SKALE Bridge)',\n decimals: 6,\n domainVersion: '1',\n isStableUsd: true,\n },\n {\n address: '0x1aeeCFE5454c83B42D8A316246CAc9739E7f690e',\n symbol: 'WBTC',\n name: 'Wrapped Bitcoin',\n decimals: 8,\n domainVersion: '1',\n isStableUsd: false,\n },\n {\n address: '0x7bD39ABBd0Dd13103542cAe3276C7fA332bCA486',\n symbol: 'WETH',\n name: 'Wrapped Ether',\n decimals: 18,\n domainVersion: '1',\n isStableUsd: false,\n },\n ],\n 'skale-base-sepolia': [\n {\n address: '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n symbol: 'USDC',\n name: 'Bridged USDC (SKALE Bridge)',\n decimals: 6,\n domainVersion: '2',\n isStableUsd: true,\n },\n {\n address: '0x3ca0a49f511c2c89c4dcbbf1731120d8919050bf',\n symbol: 'USDT',\n name: 'Bridged USDT (SKALE Bridge)',\n decimals: 6,\n domainVersion: '1',\n isStableUsd: true,\n },\n {\n address: '0x4512eacd4186b025186e1cf6cc0d89497c530e87',\n symbol: 'WBTC',\n name: 'Wrapped Bitcoin',\n decimals: 8,\n domainVersion: '1',\n isStableUsd: false,\n },\n {\n address: '0xf94056bd7f6965db3757e1b145f200b7346b4fc0',\n symbol: 'WETH',\n name: 'Wrapped Ether',\n decimals: 18,\n domainVersion: '1',\n isStableUsd: false,\n },\n ],\n 'skale-bite': [\n {\n address: '0xc4083B1E81ceb461Ccef3FDa8A9F24F0d764B6D8',\n symbol: 'USDC',\n name: 'USDC',\n decimals: 6,\n domainVersion: '1',\n isStableUsd: true,\n },\n ],\n 'polygon': [\n {\n address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n symbol: 'USDC',\n name: 'USD Coin',\n decimals: 6,\n domainVersion: '2',\n isStableUsd: true,\n },\n ],\n 'ethereum': [\n {\n address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n symbol: 'USDC',\n name: 'USD Coin',\n decimals: 6,\n domainVersion: '2',\n isStableUsd: true,\n },\n ],\n};\n\nexport function resolveToken(network: RelaiNetwork, asset?: string): NetworkToken | null {\n const tokens = NETWORK_TOKENS[network];\n if (!tokens || tokens.length === 0) return null;\n if (!asset) return tokens[0];\n\n const normalized = String(asset).toLowerCase();\n return tokens.find((token) => token.address.toLowerCase() === normalized) || null;\n}\n\n/** USDC contract addresses per network */\nexport const USDC_ADDRESSES: Record<RelaiNetwork, string> = {\n 'solana': 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',\n 'solana-devnet': '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',\n 'base': '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n 'avalanche': '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n 'skale-base': '0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20',\n 'skale-base-sepolia': '0x2e08028E3C4c2356572E096d8EF835cD5C6030bD',\n 'skale-bite': '0xc4083B1E81ceb461Ccef3FDa8A9F24F0d764B6D8',\n 'polygon': '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n 'ethereum': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n 'telos': '0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b',\n};\n\n/** Explorer URLs per network */\nexport const EXPLORER_TX_URL: Record<RelaiNetwork, (tx: string) => string> = {\n 'solana': (tx) => `https://solscan.io/tx/${tx}`,\n 'solana-devnet': (tx) => `https://solscan.io/tx/${tx}?cluster=devnet`,\n 'base': (tx) => `https://basescan.org/tx/${tx}`,\n 'avalanche': (tx) => `https://snowtrace.io/tx/${tx}`,\n 'skale-base': (tx) => `https://skale-base-explorer.skalenodes.com/tx/${tx}`,\n 'skale-base-sepolia': (tx) => `https://base-sepolia-testnet-explorer.skalenodes.com/tx/${tx}`,\n 'skale-bite': (tx) => `https://base-sepolia-testnet.explorer.skalenodes.com/tx/${tx}`,\n 'polygon': (tx) => `https://polygonscan.com/tx/${tx}`,\n 'ethereum': (tx) => `https://etherscan.io/tx/${tx}`,\n 'telos': (tx) => `https://teloscan.io/tx/${tx}`,\n};\n\n/** Human-readable network labels */\nexport const NETWORK_LABELS: Record<RelaiNetwork, string> = {\n 'solana': 'Solana',\n 'solana-devnet': 'Solana Devnet',\n 'base': 'Base',\n 'avalanche': 'Avalanche',\n 'skale-base': 'SKALE Base',\n 'skale-base-sepolia': 'SKALE Base Sepolia',\n 'skale-bite': 'SKALE BITE V2',\n 'polygon': 'Polygon',\n 'ethereum': 'Ethereum',\n 'telos': 'Telos EVM',\n};\n\n/** Legacy CAIP-2 exports for backward compatibility */\nexport const SOLANA_MAINNET_NETWORK = NETWORK_CAIP2['solana'];\nexport const BASE_MAINNET_NETWORK = NETWORK_CAIP2['base'];\n\n/** Legacy USDC exports for backward compatibility */\nexport const USDC_SOLANA = USDC_ADDRESSES['solana'];\nexport const USDC_BASE = USDC_ADDRESSES['base'];\n\n/** All supported RelAI networks list */\nexport const RELAI_NETWORKS: RelaiNetwork[] = [\n 'solana',\n 'solana-devnet',\n 'base',\n 'avalanche',\n 'skale-base',\n 'skale-base-sepolia',\n 'skale-bite',\n 'polygon',\n 'ethereum',\n 'telos',\n];\n\n/** Check if a network is Solana-based */\nexport function isSolana(network: string): boolean {\n return network === 'solana' || network === 'solana-devnet' || network.startsWith('solana:');\n}\n\n/** Check if a network is EVM-based */\nexport function isEvm(network: string): boolean {\n return ['base', 'avalanche', 'skale-base', 'skale-base-sepolia', 'skale-bite', 'polygon', 'ethereum', 'telos'].includes(network) || network.startsWith('eip155:');\n}\n\n/** Normalize CAIP-2 or simple name to RelaiNetwork */\nexport function normalizeNetwork(network: string): RelaiNetwork | null {\n if (RELAI_NETWORKS.includes(network as RelaiNetwork)) return network as RelaiNetwork;\n const fromCaip2 = CAIP2_TO_NETWORK[network];\n if (fromCaip2) return fromCaip2;\n // Partial match\n if (network.startsWith('solana:')) return 'solana';\n if (network.startsWith('eip155:')) {\n const chainId = parseInt(network.split(':')[1]);\n const entry = Object.entries(CHAIN_IDS).find(([, id]) => id === chainId);\n if (entry) return entry[0] as RelaiNetwork;\n }\n return null;\n}\n\n// ============================================================================\n// Wallet Types\n// ============================================================================\n\n/** Solana wallet interface */\nexport interface SolanaWallet {\n publicKey: { toString(): string } | null;\n signTransaction: ((tx: unknown) => Promise<unknown>) | null;\n signAllTransactions?: ((txs: unknown[]) => Promise<unknown[]>) | null;\n}\n\n/** EVM wallet interface (viem-compatible) */\nexport interface EvmWallet {\n address: string;\n signTypedData: (params: unknown) => Promise<string>;\n chain?: { id: number };\n}\n\n/** Wallet set for multi-chain support */\nexport interface WalletSet {\n solana?: SolanaWallet;\n evm?: EvmWallet;\n}\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\n/** Extra fields in payment requirements */\nexport interface AcceptsExtra {\n feePayer?: string;\n decimals?: number;\n name?: string;\n version?: string;\n [key: string]: unknown;\n}\n\n/** A single payment option */\nexport interface PaymentAccept {\n x402Version?: 1 | 2;\n scheme: string;\n network: string;\n maxAmountRequired?: string;\n amount?: string;\n asset: string;\n payTo: string;\n maxTimeoutSeconds?: number;\n extra?: AcceptsExtra;\n resource?: string;\n description?: string;\n mimeType?: string;\n outputSchema?: unknown;\n}\n\n/** Resource info for v2 */\nexport interface ResourceInfo {\n url: string;\n description?: string;\n mimeType?: string;\n}\n\n/** Payment requirements (402 response) */\nexport interface PaymentRequired {\n x402Version: 1 | 2;\n error?: string;\n accepts: PaymentAccept[];\n resource?: ResourceInfo;\n extensions?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Config Types (server-specific types are in server.ts)\n// ============================================================================\n","// src/server.ts\nimport {\n NETWORK_CAIP2,\n USDC_ADDRESSES,\n RELAI_FACILITATOR_URL,\n resolveToken,\n type NetworkToken,\n type RelaiNetwork,\n} from './types';\nimport type { RelaiPlugin, PluginContext, PluginResult } from './plugins';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Server-side MPP verifier. When provided, protect() will accept\n * Authorization: Payment credentials and verify them via this handler.\n *\n * Compatible with mppx Mppx.create() server instances.\n *\n * @example\n * ```typescript\n * import { Mppx, tempo } from 'mppx/server';\n *\n * const mppx = Mppx.create({\n * secretKey: process.env.MPP_SECRET_KEY,\n * methods: [tempo.charge({ recipient: '0x...', currency: USDC, decimals: 6 })],\n * });\n *\n * const relai = new Relai({\n * network: 'base',\n * mpp: mppx,\n * });\n * ```\n */\n/**\n * MPP server handler — compatible with `Mppx.create()` from `mppx/server`.\n *\n * The `charge()` method returns a handler function that:\n * - On a request WITHOUT a Payment credential → returns `{ status: 402, challenge: Response }`\n * - On a request WITH a valid credential → returns `{ status: 200, withReceipt: fn }`\n */\nexport interface MppServerHandler {\n charge(params: Record<string, unknown>): (request: Request) => Promise<MppChargeResult>;\n}\n\nexport type MppChargeResult = {\n status: number;\n challenge?: Response;\n withReceipt?: (response: Response) => Response;\n receipt?: { method?: string; reference?: string; status?: string };\n};\n\nexport interface RelaiServerConfig {\n /** Network to accept payments on */\n network: RelaiNetwork;\n /** RelAI facilitator URL (default: https://facilitator.x402.fi) */\n facilitatorUrl?: string;\n /** Plugins to extend protect() behavior (e.g. freeTier, rateLimit) */\n plugins?: RelaiPlugin[];\n /**\n * Optional MPP (Machine Payment Protocol) server handler.\n * When set, protect() accepts Authorization: Payment credentials\n * (Tempo, Stripe MPP) alongside standard x402 payments.\n */\n mpp?: MppServerHandler;\n}\n\nexport type DynamicPrice = number | ((req: any) => number | Promise<number>);\n\nexport type RelaiIntegritasFlow = 'single' | 'dual';\n\nexport interface RelaiIntegritasOptions {\n /** Enable Integritas by default for this endpoint */\n enabled?: boolean;\n /** Default flow when Integritas is enabled */\n flow?: RelaiIntegritasFlow;\n}\n\nexport interface ProtectOptions {\n /** Price in USD (e.g., 0.01 for 1 cent) */\n price: DynamicPrice;\n /** Optional token asset address for networks supporting multiple tokens */\n asset?: string;\n /** Wallet address to receive payments, or stripePayTo() for Stripe settlement */\n payTo: string | StripePayTo;\n /** Description shown to payer */\n description?: string;\n /** MIME type of the response (default: application/json) */\n mimeType?: string;\n /** Maximum timeout in seconds (default: 60) */\n maxTimeoutSeconds?: number;\n /** Integritas options (or simple boolean enable flag) */\n integritas?: boolean | RelaiIntegritasOptions;\n /** Override network for this endpoint */\n network?: RelaiNetwork;\n /** Override feePayer address (Solana only) — bypasses facilitator /supported fetch */\n feePayer?: string;\n /** Custom validation after payment is settled */\n customRules?: (req: any) => boolean | Promise<boolean>;\n /** Callback when 402 is returned (no payment provided) */\n onPaymentRequired?: (req: any, info: { price: number; network: RelaiNetwork }) => void;\n /** Callback when payment is settled successfully */\n onPaymentSettled?: (req: any, result: SettleResult) => void;\n /** Callback on error */\n onError?: (req: any, error: unknown) => void;\n}\n\nexport interface SettleResult {\n success: boolean;\n transaction?: string;\n payer?: string;\n network?: string;\n splitTransfers?: Record<string, unknown>;\n integritasFeePaid?: boolean;\n provenance?: Record<string, unknown>;\n integritas?: Record<string, unknown>;\n error?: string;\n errorReason?: string;\n}\n\nexport interface PaymentInfo {\n verified: boolean;\n transactionId?: string;\n payer?: string;\n network: RelaiNetwork;\n amount: number;\n}\n\n// ============================================================================\n// Stripe Pay-To Helper\n// ============================================================================\n\n/** Config returned by stripePayTo() - used by protect() to create Stripe deposit addresses */\nexport interface StripePayTo {\n readonly __brand: 'stripePayTo';\n readonly secretKey: string;\n /** Stripe crypto deposits network (default: 'base') */\n readonly stripeNetwork: string;\n}\n\n/**\n * Create a Stripe pay-to configuration for x402 payments.\n * Payments settle as USD in your Stripe Dashboard - no crypto knowledge required.\n *\n * Stripe creates a fresh PaymentIntent + deposit address per request.\n * Network is auto-set to Base (Stripe settles USDC on Base).\n *\n * @example\n * ```typescript\n * import Relai, { stripePayTo } from '@relai-fi/x402/server';\n *\n * const relai = new Relai({ network: 'base' });\n *\n * app.get('/api/data', relai.protect({\n * price: 0.01,\n * payTo: stripePayTo(process.env.STRIPE_SECRET_KEY!),\n * }), (req, res) => {\n * res.json({ data: 'paid content' });\n * });\n * ```\n */\nexport function stripePayTo(\n stripeSecretKey: string,\n options?: { network?: string },\n): StripePayTo {\n if (!stripeSecretKey) {\n throw new Error('stripePayTo requires a Stripe secret key');\n }\n return {\n __brand: 'stripePayTo' as const,\n secretKey: stripeSecretKey,\n stripeNetwork: options?.network || 'base',\n };\n}\n\nconst USD_PRICE_CACHE_TTL_MS = 60 * 1000;\nconst usdPriceCache = new Map<string, { usd: number; expiresAt: number }>();\n\nconst GECKOTERMINAL_NETWORK_BY_RELAI: Partial<Record<RelaiNetwork, string>> = {\n polygon: 'polygon_pos',\n};\n\nconst COINGECKO_ID_BY_SYMBOL: Record<string, string> = {\n WETH: 'ethereum',\n WBTC: 'bitcoin',\n USDT: 'tether',\n EURC: 'euro-coin',\n DAI: 'dai',\n cbETH: 'coinbase-wrapped-staked-eth',\n cbBTC: 'coinbase-wrapped-btc',\n};\n\nfunction isStableUsdToken(token: NetworkToken): boolean {\n if (token.isStableUsd === true) return true;\n const symbol = String(token.symbol || '').toUpperCase();\n return symbol === 'USDC' || symbol === 'USDT';\n}\n\nasync function fetchUsdPriceFromCoinGecko(coinId: string): Promise<number> {\n const now = Date.now();\n const cached = usdPriceCache.get(coinId);\n if (cached && cached.expiresAt > now) {\n return cached.usd;\n }\n\n const url = `https://api.coingecko.com/api/v3/simple/price?ids=${encodeURIComponent(coinId)}&vs_currencies=usd`;\n const res = await fetch(url, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n });\n\n if (!res.ok) {\n throw new Error(`CoinGecko price request failed: HTTP ${res.status}`);\n }\n\n const payload = await res.json() as Record<string, { usd?: number }>;\n const usd = Number(payload?.[coinId]?.usd);\n if (!Number.isFinite(usd) || usd <= 0) {\n throw new Error(`CoinGecko returned invalid usd price for ${coinId}`);\n }\n\n usdPriceCache.set(coinId, {\n usd,\n expiresAt: now + USD_PRICE_CACHE_TTL_MS,\n });\n\n return usd;\n}\n\nasync function fetchUsdPriceFromGeckoTerminal(network: RelaiNetwork, tokenAddress: string): Promise<number> {\n const geckoNetwork = GECKOTERMINAL_NETWORK_BY_RELAI[network];\n if (!geckoNetwork) {\n throw new Error(`GeckoTerminal network not configured for ${network}`);\n }\n\n const normalizedAddress = String(tokenAddress || '').trim().toLowerCase();\n if (!normalizedAddress) {\n throw new Error('GeckoTerminal requires a token address');\n }\n\n const cacheKey = `gt:${geckoNetwork}:${normalizedAddress}`;\n const now = Date.now();\n const cached = usdPriceCache.get(cacheKey);\n if (cached && cached.expiresAt > now) {\n return cached.usd;\n }\n\n const url = `https://api.geckoterminal.com/api/v2/networks/${encodeURIComponent(geckoNetwork)}/tokens/${encodeURIComponent(normalizedAddress)}`;\n const res = await fetch(url, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n });\n\n if (!res.ok) {\n throw new Error(`GeckoTerminal price request failed: HTTP ${res.status}`);\n }\n\n const payload = await res.json() as { data?: { attributes?: { price_usd?: string | number } } };\n const usd = Number(payload?.data?.attributes?.price_usd);\n if (!Number.isFinite(usd) || usd <= 0) {\n throw new Error(`GeckoTerminal returned invalid usd price for ${normalizedAddress} on ${geckoNetwork}`);\n }\n\n usdPriceCache.set(cacheKey, {\n usd,\n expiresAt: now + USD_PRICE_CACHE_TTL_MS,\n });\n\n return usd;\n}\n\nasync function resolveAmountAtomicFromUsd({\n priceUsd,\n token,\n network,\n}: {\n priceUsd: number;\n token: NetworkToken;\n network: RelaiNetwork;\n}): Promise<string> {\n const decimals = Number(token.decimals);\n if (!Number.isFinite(decimals) || decimals < 0) {\n throw new Error(`Invalid token decimals for ${token.symbol || token.address}`);\n }\n\n if (isStableUsdToken(token)) {\n const units = Math.floor(priceUsd * Math.pow(10, decimals));\n return String(Math.max(1, units));\n }\n\n const symbol = String(token.symbol || '').toUpperCase();\n const coinGeckoId = COINGECKO_ID_BY_SYMBOL[symbol];\n if (!coinGeckoId) {\n throw new Error(`No USD quote source configured for token ${symbol || token.address} on ${network}`);\n }\n\n const overrideEnv = process.env[`EVM_TOKEN_PRICE_${symbol}_USD`];\n let usdPerToken: number;\n if (overrideEnv && Number(overrideEnv) > 0) {\n usdPerToken = Number(overrideEnv);\n } else {\n try {\n usdPerToken = await fetchUsdPriceFromCoinGecko(coinGeckoId);\n } catch (coinGeckoError) {\n try {\n usdPerToken = await fetchUsdPriceFromGeckoTerminal(network, token.address);\n } catch (geckoTerminalError) {\n throw new Error(\n `USD quote failed for ${symbol || token.address} on ${network}. CoinGecko: ${coinGeckoError instanceof Error ? coinGeckoError.message : String(coinGeckoError)}; GeckoTerminal: ${geckoTerminalError instanceof Error ? geckoTerminalError.message : String(geckoTerminalError)}`,\n );\n }\n }\n }\n\n const tokenAmount = priceUsd / usdPerToken;\n const rawUnits = tokenAmount * Math.pow(10, decimals);\n\n if (!Number.isFinite(rawUnits) || rawUnits <= 0) {\n throw new Error(\n `Invalid conversion result for token ${symbol || token.address}: priceUsd=${priceUsd}, usdPerToken=${usdPerToken}`,\n );\n }\n\n return String(Math.max(1, Math.floor(rawUnits)));\n}\n\n/** @internal Type guard for StripePayTo */\nfunction isStripePayTo(payTo: unknown): payTo is StripePayTo {\n return (\n typeof payTo === 'object' &&\n payTo !== null &&\n (payTo as any).__brand === 'stripePayTo'\n );\n}\n\nfunction parseBooleanHeader(value: unknown): boolean | null {\n if (value == null) return null;\n const normalized = String(value).trim().toLowerCase();\n if (normalized === 'true' || normalized === '1' || normalized === 'yes' || normalized === 'on') {\n return true;\n }\n if (normalized === 'false' || normalized === '0' || normalized === 'no' || normalized === 'off') {\n return false;\n }\n return null;\n}\n\nfunction normalizeIntegritasFlow(value: unknown): RelaiIntegritasFlow | undefined {\n const normalized = String(value || '').trim().toLowerCase();\n if (normalized === 'single') return 'single';\n if (normalized === 'dual') return 'dual';\n return undefined;\n}\n\nfunction normalizeIntegritasOptions(\n value: boolean | RelaiIntegritasOptions | undefined,\n): { enabled: boolean; flow?: RelaiIntegritasFlow } {\n if (value === true) return { enabled: true };\n if (value === false || value == null) return { enabled: false };\n\n const flow = normalizeIntegritasFlow(value.flow);\n const enabled =\n typeof value.enabled === 'boolean'\n ? value.enabled\n : true;\n\n return {\n enabled,\n ...(flow ? { flow } : {}),\n };\n}\n\n/**\n * @internal Create a Stripe PaymentIntent with crypto payment method\n * and extract the deposit address.\n */\nasync function createStripeDepositAddress(\n secretKey: string,\n amountUsdCents: number,\n network: string = 'base',\n): Promise<string> {\n const params = new URLSearchParams();\n params.append('amount', String(amountUsdCents));\n params.append('currency', 'usd');\n params.append('payment_method_types[]', 'crypto');\n params.append('payment_method_data[type]', 'crypto');\n params.append('confirm', 'true');\n\n const res = await fetch('https://api.stripe.com/v1/payment_intents', {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${secretKey}`,\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: params.toString(),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({})) as any;\n const msg = err?.error?.message || res.statusText;\n\n // Provide actionable guidance for common issues\n if (msg.includes('unknown parameter') || msg.includes('crypto')) {\n throw new Error(\n `Stripe crypto payins not enabled on this account. ` +\n `Enable at: https://support.stripe.com/questions/get-started-with-pay-with-crypto ` +\n `(Original: ${msg})`,\n );\n }\n throw new Error(`Stripe PaymentIntent creation failed: ${msg}`);\n }\n\n const pi = await res.json() as any;\n const depositDetails = pi.next_action?.crypto_collect_deposit_details;\n if (!depositDetails) {\n throw new Error(\n 'Stripe PaymentIntent missing crypto deposit details. ' +\n 'Ensure crypto payins are enabled: https://support.stripe.com/questions/get-started-with-pay-with-crypto',\n );\n }\n\n const address = depositDetails.deposit_addresses?.[network]?.address;\n if (!address) {\n throw new Error(`No Stripe deposit address for network: ${network}`);\n }\n\n return address;\n}\n\n// ============================================================================\n// Relai Server SDK\n// ============================================================================\n\n/**\n * Server-side SDK for protecting Express endpoints with x402 micropayments.\n * Settles payments through the RelAI facilitator (zero gas fees for users).\n *\n * Supports: Solana, Base, Avalanche, SKALE Base, SKALE Base Sepolia, SKALE BITE, Polygon, and Ethereum.\n *\n * @example\n * ```typescript\n * import Relai from '@relai-fi/x402/server';\n *\n * const relai = new Relai({ network: 'base' });\n *\n * app.get('/api/data', relai.protect({\n * payTo: '0xYourWallet',\n * price: 0.01, // $0.01 USDC\n * }), (req, res) => {\n * res.json({ data: 'Protected content', payment: req.payment });\n * });\n * ```\n */\nexport class Relai {\n private network: RelaiNetwork;\n private facilitatorUrl: string;\n private feePayerCache: Map<string, string> = new Map(); // Cache feePayer per network\n private plugins: RelaiPlugin[];\n private pluginInitPromise: Promise<void> | null = null;\n private mpp?: MppServerHandler;\n\n constructor(config: RelaiServerConfig) {\n this.network = config.network;\n this.facilitatorUrl = config.facilitatorUrl || RELAI_FACILITATOR_URL;\n this.plugins = config.plugins ?? [];\n this.mpp = config.mpp;\n }\n\n private async runPluginInit(): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.onInit) {\n try {\n await plugin.onInit();\n } catch (err) {\n console.warn(`[Relai] Plugin '${plugin.name}' init failed:`, err);\n }\n }\n }\n }\n\n /**\n * Get feePayer address for a network (cached)\n */\n private async getFeePayer(caip2: string): Promise<string | undefined> {\n // Check cache first\n if (this.feePayerCache.has(caip2)) {\n return this.feePayerCache.get(caip2);\n }\n\n // If using RelAI facilitator, use hardcoded address (no fetch needed)\n const isRelAI = this.facilitatorUrl.includes('facilitator.x402.fi') || \n this.facilitatorUrl.includes('relai');\n \n if (isRelAI) {\n const relaiFeePayer = '0x1892f72fdB3A966b2AD8595aA5f7741Ef72d6085';\n this.feePayerCache.set(caip2, relaiFeePayer);\n return relaiFeePayer;\n }\n\n // For other facilitators, fetch from /supported\n try {\n const supportedUrl = `${this.facilitatorUrl}/supported`;\n const supportedRes = await fetch(supportedUrl);\n if (supportedRes.ok) {\n const supportedData = await supportedRes.json();\n // Cache all feePayers from supported kinds\n supportedData.kinds?.forEach((kind: any) => {\n if (kind.network && kind.extra?.feePayer) {\n this.feePayerCache.set(kind.network, kind.extra.feePayer);\n }\n });\n return this.feePayerCache.get(caip2);\n }\n } catch (err) {\n // feePayer MUST come from facilitator - cannot use env for security\n console.error(`[Relai] Failed to fetch feePayer from facilitator: ${err}`);\n }\n return undefined;\n }\n\n /**\n * Express middleware to protect an endpoint with x402 micropayments.\n *\n * Flow:\n * 1. No payment header → returns 402 with payment requirements\n * 2. Payment header present → calls RelAI facilitator `/settle`\n * 3. Settlement success → sets `PAYMENT-RESPONSE` header, attaches `req.payment`, calls `next()`\n */\n protect(options: ProtectOptions) {\n const self = this;\n\n return async (req: any, res: any, next: any) => {\n try {\n // -----------------------------------------------------------\n // Preflight probe: respond 200 immediately so the preflight\n // plugin (or external clients) can verify the endpoint is alive.\n // -----------------------------------------------------------\n if (req.headers['x-preflight'] === 'true' || req.headers['x-preflight'] === '1') {\n return res.status(200).json({ status: 'ok', preflight: true });\n }\n\n // Resolve dynamic price\n const resolvedPrice = typeof options.price === 'function'\n ? await options.price(req)\n : options.price;\n\n if (typeof resolvedPrice !== 'number' || !isFinite(resolvedPrice) || resolvedPrice <= 0) {\n return res.status(400).json({ error: 'Invalid price configuration' });\n }\n\n // Resolve network (Stripe auto-sets to base)\n const stripeConfig = isStripePayTo(options.payTo) ? options.payTo : null;\n const network = stripeConfig\n ? (stripeConfig.stripeNetwork as RelaiNetwork) || 'base'\n : (options.network || self.network);\n const caip2 = NETWORK_CAIP2[network];\n const requestedAsset =\n typeof options.asset === 'string' && options.asset.trim() !== ''\n ? options.asset.trim()\n : undefined;\n const explicitToken = requestedAsset ? resolveToken(network, requestedAsset) : null;\n if (requestedAsset && !explicitToken) {\n return res.status(400).json({\n error: `Unsupported asset ${requestedAsset} for network ${network}`,\n });\n }\n\n const fallbackToken: NetworkToken = {\n address: USDC_ADDRESSES[network],\n symbol: 'USDC',\n name: network === 'skale-bite' ? 'USDC' : 'USD Coin',\n decimals: 6,\n domainVersion: network === 'skale-bite' ? '1' : '2',\n isStableUsd: true,\n };\n const token = explicitToken || resolveToken(network) || fallbackToken;\n const asset = token.address;\n const tokenName = token.name || 'USD Coin';\n const tokenVersion = token.domainVersion || (network === 'skale-bite' ? '1' : '2');\n const tokenDecimals = Number.isFinite(Number(token.decimals)) ? Number(token.decimals) : 6;\n\n let amount: string;\n try {\n amount = await resolveAmountAtomicFromUsd({\n priceUsd: resolvedPrice,\n token,\n network,\n });\n } catch (err) {\n console.error('[Relai] Failed to convert USD amount to token units:', err);\n return res.status(500).json({\n error: 'Failed to quote token amount for payment requirements',\n });\n }\n\n const configuredIntegritas = normalizeIntegritasOptions(options.integritas);\n const headerIntegritasEnabled = parseBooleanHeader(req.headers['x-integritas']);\n const headerIntegritasFlow = normalizeIntegritasFlow(req.headers['x-integritas-flow']);\n const integritasEnabled =\n headerIntegritasEnabled === null\n ? configuredIntegritas.enabled\n : headerIntegritasEnabled;\n const integritasFlow = headerIntegritasFlow || configuredIntegritas.flow;\n const integritasMode =\n integritasFlow === 'single'\n ? 'single_signature_fee_included'\n : (integritasFlow === 'dual' ? 'dual_signature_split' : undefined);\n\n // Check for payment header (base64-encoded JSON)\n const paymentHeader =\n req.headers['x-payment'] ||\n req.headers['payment-signature'] ||\n req.headers['x-payment-signature'];\n\n // -----------------------------------------------------------\n // MPP: check for Authorization: Payment credential\n // -----------------------------------------------------------\n const authHeader = req.headers['authorization'] || '';\n console.log(`[Relai] MPP check: paymentHeader=${!!paymentHeader}, hasMpp=${!!self.mpp}, authHeader=${authHeader?.slice(0, 30)}`);\n if (!paymentHeader && self.mpp && /^Payment\\s+/i.test(authHeader)) {\n try {\n // Use the same amount format as the challenge (USD with 6 decimals)\n const mppAmount = resolvedPrice.toFixed(6);\n\n // Build a web Request from the Express req for the mppx handler\n const mppUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;\n const mppHeaders = new Headers();\n for (const [k, v] of Object.entries(req.headers)) {\n if (typeof v === 'string') mppHeaders.set(k, v);\n }\n const mppRequest = new Request(mppUrl, { method: req.method, headers: mppHeaders });\n\n // Call the charge handler — it detects the credential in Authorization header\n // and verifies it against the HMAC-signed challenge\n const chargeHandler = self.mpp.charge({ amount: mppAmount } as any);\n const mppResult = await chargeHandler(mppRequest);\n console.log(`[Relai] MPP charge result: status=${mppResult.status}, keys=${Object.keys(mppResult)}, hasChallenge=${!!mppResult.challenge}, hasWithReceipt=${!!mppResult.withReceipt}`);\n if (mppResult.status === 402 && mppResult.challenge instanceof Response) {\n const retryAuth = mppResult.challenge.headers.get('www-authenticate');\n console.log(`[Relai] MPP re-challenged (credential not accepted). New WWW-Auth: ${retryAuth?.slice(0, 60)}`);\n }\n\n // MPP charge genuinely failed (not a 402 re-challenge, which is normal handshake)\n // Only notify plugins for non-402 failures (e.g. 500, invalid credential, etc.)\n if (mppResult.status !== 200 && !mppResult.withReceipt && mppResult.status !== 402) {\n if (self.plugins.length > 0) {\n const mppFailCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n const mppFailResult: SettleResult = {\n success: false,\n payer: 'mpp',\n error: `MPP charge failed with status ${mppResult.status}`,\n };\n for (const plugin of self.plugins) {\n if (!plugin.afterSettled) continue;\n try {\n await plugin.afterSettled(req, mppFailResult, mppFailCtx);\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' afterSettled error (non-blocking):`, pluginErr);\n }\n }\n }\n }\n\n if (mppResult.status === 200 || mppResult.withReceipt) {\n // Payment verified by mppx\n const receipt = mppResult.receipt || {};\n const paymentInfo: PaymentInfo = {\n verified: true,\n transactionId: receipt.reference || '',\n payer: receipt.method || 'mpp',\n network,\n amount: resolvedPrice,\n };\n req.payment = paymentInfo;\n req.x402Payer = receipt.method ? `${receipt.method}-mpp` : 'mpp';\n req.x402Paid = true;\n req.x402Transaction = receipt.reference || '';\n req.x402Network = network;\n\n // Use withReceipt to attach Payment-Receipt header\n if (mppResult.withReceipt) {\n const dummyResponse = new Response(null);\n const receiptResponse = mppResult.withReceipt(dummyResponse);\n const receiptHeader = receiptResponse.headers.get('payment-receipt');\n if (receiptHeader) res.setHeader('Payment-Receipt', receiptHeader);\n }\n\n options.onPaymentSettled?.(req, {\n success: true,\n transaction: receipt.reference,\n payer: req.x402Payer,\n } as SettleResult);\n\n // Plugin hooks: afterSettled\n if (self.plugins.length > 0) {\n const settleCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n for (const plugin of self.plugins) {\n if (!plugin.afterSettled) continue;\n try {\n await plugin.afterSettled(req, {\n success: true,\n transaction: receipt.reference,\n payer: req.x402Payer,\n } as SettleResult, settleCtx);\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' afterSettled error (non-blocking):`, pluginErr);\n }\n }\n }\n\n return next();\n }\n } catch (mppErr) {\n console.warn(`[Relai] MPP verification failed (${mppErr instanceof Error ? mppErr.message : mppErr}), falling through to x402`);\n\n // Notify plugins of MPP failure\n if (self.plugins.length > 0) {\n const mppErrCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n const mppErrResult: SettleResult = {\n success: false,\n payer: 'mpp',\n error: mppErr instanceof Error ? mppErr.message : String(mppErr),\n };\n for (const plugin of self.plugins) {\n if (!plugin.afterSettled) continue;\n try {\n await plugin.afterSettled(req, mppErrResult, mppErrCtx);\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' afterSettled error (non-blocking):`, pluginErr);\n }\n }\n }\n }\n }\n\n // -----------------------------------------------------------\n // Plugin hooks: beforePaymentCheck\n // If any plugin returns { skip: true }, bypass payment entirely.\n // Ensure plugins are initialized (config synced) before checking.\n // -----------------------------------------------------------\n if (!paymentHeader && self.plugins.length > 0) {\n if (!self.pluginInitPromise) {\n self.pluginInitPromise = self.runPluginInit();\n }\n await self.pluginInitPromise;\n const pluginCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n\n for (const plugin of self.plugins) {\n if (!plugin.beforePaymentCheck) continue;\n try {\n const pluginResult = await plugin.beforePaymentCheck(req, pluginCtx);\n\n // Reject: plugin blocks the request entirely (e.g. service unhealthy)\n if (pluginResult?.reject) {\n const rejectStatus = pluginResult.rejectStatus || 503;\n if (pluginResult.headers) {\n for (const [k, v] of Object.entries(pluginResult.headers)) {\n res.setHeader(k, v);\n }\n }\n return res.status(rejectStatus).json({\n error: pluginResult.rejectMessage || 'Service unavailable',\n plugin: plugin.name,\n });\n }\n\n // Skip: bypass payment and serve content for free\n if (pluginResult?.skip) {\n // Set plugin-provided headers\n if (pluginResult.headers) {\n for (const [k, v] of Object.entries(pluginResult.headers)) {\n res.setHeader(k, v);\n }\n }\n // Attach plugin metadata to request\n req.pluginMeta = { ...(req.pluginMeta || {}), ...(pluginResult.meta || {}) };\n req.x402Paid = false;\n req.x402Free = true;\n req.x402Plugin = plugin.name;\n // Still set up afterSettled interceptor so plugins (e.g. refund) can\n // re-issue a credit if the endpoint fails on this free call too.\n const skipPluginsWithHook = self.plugins.filter((p) => !!p.afterSettled);\n if (skipPluginsWithHook.length > 0) {\n const skipCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n const skipResult: SettleResult = {\n success: true,\n payer: req.headers?.['x-wallet-address'] || req.headers?.['x-buyer-address'] || req.ip || req.socket?.remoteAddress || 'unknown',\n transaction: '',\n } as any;\n const originalJsonSkip = (res as any).json?.bind(res);\n const originalSendSkip = (res as any).send?.bind(res);\n let skipFired = false;\n const fireSkipAfterSettled = (statusCode: number) => {\n if (skipFired) return;\n skipFired = true;\n const resultWithStatus = { ...skipResult, statusCode };\n for (const p of skipPluginsWithHook) {\n p.afterSettled!(req, resultWithStatus, skipCtx).catch((e: unknown) => {\n console.warn(`[Relai] Plugin '${p.name}' afterSettled (skip) error:`, e);\n });\n }\n };\n if (typeof originalJsonSkip === 'function') {\n (res as any).json = function (body: unknown) {\n fireSkipAfterSettled(res.statusCode ?? 200);\n (res as any).json = originalJsonSkip;\n return originalJsonSkip(body);\n };\n }\n if (typeof originalSendSkip === 'function') {\n (res as any).send = function (body: unknown) {\n fireSkipAfterSettled(res.statusCode ?? 200);\n (res as any).send = originalSendSkip;\n return originalSendSkip(body);\n };\n }\n }\n return next();\n }\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' beforePaymentCheck error (non-blocking):`, pluginErr);\n }\n }\n }\n\n // -----------------------------------------------------------\n // No payment → return 402 Payment Required\n // -----------------------------------------------------------\n if (!paymentHeader) {\n options.onPaymentRequired?.(req, { price: resolvedPrice, network });\n\n // Resolve payTo address (Stripe creates a fresh deposit address per request)\n let resolvedPayTo: string;\n if (stripeConfig) {\n const amountInCents = Math.max(1, Math.round(resolvedPrice * 100));\n resolvedPayTo = await createStripeDepositAddress(\n stripeConfig.secretKey,\n amountInCents,\n stripeConfig.stripeNetwork,\n );\n } else {\n resolvedPayTo = options.payTo as string;\n }\n\n // Get facilitator feePayer address — use explicit override if provided, otherwise fetch\n const feePayer = (options.feePayer as string | undefined) || await self.getFeePayer(caip2);\n\n let paymentRequiredResponse: any = {\n x402Version: 2,\n error: 'Payment required',\n resource: {\n url: `${req.protocol}://${req.get('host')}${req.originalUrl}`,\n description: options.description || 'API access',\n mimeType: options.mimeType || 'application/json',\n },\n accepts: [{\n scheme: 'exact',\n network: caip2,\n amount,\n asset,\n payTo: resolvedPayTo,\n maxTimeoutSeconds: options.maxTimeoutSeconds || 60,\n extra: {\n name: tokenName,\n version: tokenVersion,\n decimals: tokenDecimals,\n symbol: token.symbol,\n ...(feePayer && { feePayer }), // Add feePayer if available\n ...(integritasEnabled ? { integritasEnabled: true } : {}),\n ...(integritasFlow ? { integritasFlow } : {}),\n ...(integritasMode ? { integritasMode } : {}),\n ...(integritasFlow === 'single' ? { integritasSingleSignature: true } : {}),\n },\n }],\n ...((configuredIntegritas.enabled || integritasEnabled || !!integritasFlow)\n ? {\n extensions: {\n integritas: {\n available: true,\n selectedFlow: integritasFlow || null,\n availableFlows: ['single', 'dual'],\n enabled: integritasEnabled,\n },\n },\n }\n : {}),\n };\n\n // Plugin hooks: enrich402Response (e.g. bridge adds extensions.bridge)\n if (self.plugins.length > 0) {\n const enrichCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n for (const plugin of self.plugins) {\n if (!plugin.enrich402Response) continue;\n try {\n paymentRequiredResponse = plugin.enrich402Response(paymentRequiredResponse, enrichCtx) || paymentRequiredResponse;\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' enrich402Response error (non-blocking):`, pluginErr);\n }\n }\n }\n\n // Add MPP challenge header if mpp is configured\n if (self.mpp?.charge) {\n try {\n const mppAmount = resolvedPrice.toFixed(6);\n const chargeHandler = self.mpp.charge({ amount: mppAmount } as any);\n const mockReq = new Request(`${req.protocol}://${req.get('host')}${req.originalUrl}`);\n const mppResult = await chargeHandler(mockReq);\n if (mppResult?.challenge instanceof Response) {\n const wwwAuth = mppResult.challenge.headers.get('www-authenticate');\n if (wwwAuth) {\n res.setHeader('WWW-Authenticate', wwwAuth);\n }\n }\n } catch {\n // Non-fatal — x402 response is still valid without MPP headers\n }\n }\n\n return res.status(402).json(paymentRequiredResponse);\n }\n\n // -----------------------------------------------------------\n // Payment header present → parse and settle via facilitator\n // -----------------------------------------------------------\n let paymentProof: any;\n try {\n // Try base64 first (standard x402 format)\n const decoded = Buffer.from(paymentHeader, 'base64').toString('utf-8');\n paymentProof = JSON.parse(decoded);\n } catch {\n try {\n // Fallback: raw JSON string\n paymentProof = JSON.parse(paymentHeader);\n } catch {\n return res.status(400).json({\n x402Version: 2,\n error: 'Invalid payment header — expected base64-encoded JSON',\n });\n }\n }\n\n // -----------------------------------------------------------\n // Bridged payment: trust the bridge proof (already settled)\n // -----------------------------------------------------------\n if (paymentProof.bridged === true && paymentProof.targetTxId) {\n console.log(`[Relai] Bridged payment accepted: source=${paymentProof.sourceTxId}, target=${paymentProof.targetTxId}`);\n\n const paymentInfo: PaymentInfo = {\n verified: true,\n transactionId: paymentProof.targetTxId,\n payer: paymentProof.sourceTxId || 'bridge',\n network,\n amount: resolvedPrice,\n };\n req.payment = paymentInfo;\n req.x402Payer = paymentProof.sourceTxId || 'bridge';\n req.x402Paid = true;\n req.x402Transaction = paymentProof.targetTxId;\n req.x402Network = network;\n req.x402Bridged = true;\n req.x402SourceChain = paymentProof.sourceChain;\n\n const paymentResponse = {\n x402Version: 2,\n scheme: 'exact',\n network: caip2,\n transaction: paymentProof.targetTxId,\n payer: paymentProof.sourceTxId,\n amount,\n asset,\n bridged: true,\n };\n res.setHeader(\n 'PAYMENT-RESPONSE',\n Buffer.from(JSON.stringify(paymentResponse)).toString('base64'),\n );\n\n options.onPaymentSettled?.(req, { success: true, transaction: paymentProof.targetTxId, payer: paymentProof.sourceTxId } as SettleResult);\n\n return next();\n }\n\n // -----------------------------------------------------------\n // Standard payment: settle via facilitator\n // -----------------------------------------------------------\n\n // Resolve payTo for settle (extract from signed proof when using Stripe)\n let settlePayTo: string;\n if (stripeConfig) {\n settlePayTo =\n paymentProof.payload?.authorization?.to ||\n paymentProof.accepted?.payTo ||\n '';\n if (!settlePayTo) {\n return res.status(400).json({\n x402Version: 2,\n error: 'Cannot extract destination address from payment proof',\n });\n }\n } else {\n settlePayTo = options.payTo as string;\n }\n\n // Build payment requirements for facilitator\n const paymentRequirements = {\n scheme: 'exact',\n network: caip2,\n amount,\n asset,\n payTo: settlePayTo,\n maxTimeoutSeconds: options.maxTimeoutSeconds || 60,\n extra: {\n name: tokenName,\n version: tokenVersion,\n decimals: tokenDecimals,\n symbol: token.symbol,\n ...(integritasEnabled ? { integritasEnabled: true } : {}),\n ...(integritasFlow ? { integritasFlow } : {}),\n ...(integritasMode ? { integritasMode } : {}),\n ...(integritasFlow === 'single' ? { integritasSingleSignature: true } : {}),\n },\n };\n\n // Call facilitator /settle\n const settleUrl = `${self.facilitatorUrl}/settle`;\n const settleRes = await fetch(settleUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n paymentPayload: paymentProof,\n paymentRequirements,\n }),\n });\n\n const result: SettleResult = await settleRes.json() as SettleResult;\n\n if (!result.success) {\n // Notify plugins of settlement failure (circuit breaker, refund, etc.)\n if (self.plugins.length > 0) {\n const failCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n for (const plugin of self.plugins) {\n if (!plugin.afterSettled) continue;\n try {\n await plugin.afterSettled(req, result, failCtx);\n } catch (pluginErr) {\n console.warn(`[Relai] Plugin '${plugin.name}' afterSettled error (non-blocking):`, pluginErr);\n }\n }\n }\n\n return res.status(402).json({\n x402Version: 2,\n error: result.errorReason || result.error || 'Payment settlement failed',\n });\n }\n\n // Attach payment info to request\n const paymentInfo: PaymentInfo = {\n verified: true,\n transactionId: result.transaction,\n payer: result.payer,\n network,\n amount: resolvedPrice,\n };\n req.payment = paymentInfo;\n req.x402Payer = result.payer;\n req.x402Paid = true;\n req.x402Transaction = result.transaction;\n req.x402Network = network;\n\n // Set x402 v2 PAYMENT-RESPONSE header (base64 JSON)\n const paymentResponse = {\n x402Version: 2,\n scheme: 'exact',\n network: caip2,\n transaction: result.transaction,\n payer: result.payer,\n amount,\n asset,\n };\n res.setHeader(\n 'PAYMENT-RESPONSE',\n Buffer.from(JSON.stringify(paymentResponse)).toString('base64'),\n );\n\n options.onPaymentSettled?.(req, result);\n\n // Plugin hooks: afterSettled — called AFTER the handler responds so plugins\n // can see the actual HTTP status code (e.g. circuit breaker, refund).\n if (self.plugins.length > 0) {\n const settleCtx: PluginContext = {\n network,\n price: resolvedPrice,\n path: req.path || req.originalUrl || '/',\n method: (req.method || 'GET').toUpperCase(),\n };\n const pluginsWithHook = self.plugins.filter((p) => !!p.afterSettled);\n if (pluginsWithHook.length > 0) {\n // Wrap res.json / res.send to fire afterSettled with actual statusCode\n const originalJson = (res as any).json?.bind(res);\n const originalSend = (res as any).send?.bind(res);\n let afterSettledFired = false;\n const fireAfterSettled = (statusCode: number) => {\n if (afterSettledFired) return;\n afterSettledFired = true;\n const resultWithStatus = { ...result, statusCode };\n for (const plugin of pluginsWithHook) {\n plugin.afterSettled!(req, resultWithStatus, settleCtx).catch((e: unknown) => {\n console.warn(`[Relai] Plugin '${plugin.name}' afterSettled error (non-blocking):`, e);\n });\n }\n };\n if (typeof originalJson === 'function') {\n (res as any).json = function (body: unknown) {\n fireAfterSettled(res.statusCode ?? 200);\n (res as any).json = originalJson; // restore\n return originalJson(body);\n };\n }\n if (typeof originalSend === 'function') {\n (res as any).send = function (body: unknown) {\n fireAfterSettled(res.statusCode ?? 200);\n (res as any).send = originalSend; // restore\n return originalSend(body);\n };\n }\n }\n }\n\n // Custom validation after payment\n if (options.customRules) {\n const valid = await options.customRules(req);\n if (!valid) {\n return res.status(403).json({ error: 'Custom validation failed' });\n }\n }\n\n next();\n } catch (error) {\n options.onError?.(req, error);\n console.error('[Relai] Protection error:', error);\n res.status(500).json({ error: 'Internal server error' });\n }\n };\n }\n}\n\nexport default Relai;\n","// src/client.ts\nimport {\n Connection,\n PublicKey,\n TransactionMessage,\n VersionedTransaction,\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 { SolanaWallet, EvmWallet, WalletSet } from './types';\nimport {\n RELAI_FACILITATOR_URL,\n NETWORK_CAIP2,\n CHAIN_IDS,\n NETWORK_TOKENS,\n isSolana,\n isEvm,\n normalizeNetwork,\n type RelaiNetwork,\n} from './types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type X402NetworkSelectionMode = 'prefer_then_any' | 'strict_preferred';\n\n/**\n * MPP (Machine Payment Protocol) handler for automatic Tempo/Stripe payment.\n * When provided, the client will detect WWW-Authenticate: Payment challenges\n * on 402 responses and use this handler to create credentials automatically.\n *\n * @example\n * ```typescript\n * import { Mppx, tempo } from 'mppx/client';\n * import { privateKeyToAccount } from 'viem/accounts';\n *\n * const mppx = Mppx.create({\n * methods: [tempo.charge({ account: privateKeyToAccount('0x...') })],\n * polyfill: false,\n * });\n *\n * const client = createX402Client({\n * wallets: { evm: evmWallet },\n * mpp: mppx,\n * });\n * ```\n */\nexport interface MppHandler {\n /** Create a credential string from a 402 response containing a WWW-Authenticate challenge. */\n createCredential(response: Response): Promise<string>;\n}\n\nexport interface X402ClientConfig {\n /** Multi-chain wallets (Solana + EVM) */\n wallets?: WalletSet;\n /** Single Solana wallet (legacy shortcut) */\n wallet?: SolanaWallet;\n /** Custom facilitator URL, default: RelAI facilitator */\n facilitatorUrl?: string;\n /** Optional Relay WebSocket transport for /relay/:apiId endpoints */\n relayWs?: X402RelayWsConfig;\n /** Preferred network when multiple options available */\n preferredNetwork?: RelaiNetwork;\n /**\n * How to handle 402 accepts when preferredNetwork is set.\n * - prefer_then_any (default): prefer preferredNetwork, then fall back to any payable option.\n * - strict_preferred: only accept preferredNetwork, fail otherwise.\n */\n networkSelectionMode?: X402NetworkSelectionMode;\n /** Custom Solana RPC URL */\n solanaRpcUrl?: string;\n /** Custom EVM RPC URLs per network (e.g. { 'skale-base': 'https://...' }) */\n evmRpcUrls?: Record<string, string>;\n /** Maximum payment amount in atomic units */\n maxAmountAtomic?: string;\n /** Default Integritas behavior for outgoing requests */\n integritas?: boolean | X402IntegritasConfig;\n /** Enable verbose logging */\n verbose?: boolean;\n /** Default headers added to every request (e.g. X-Service-Key, X-Agent-ID for agent use) */\n defaultHeaders?: Record<string, string>;\n /**\n * Optional MPP (Machine Payment Protocol) handler.\n * When set, the client automatically handles WWW-Authenticate: Payment\n * challenges (Tempo, Stripe) on 402 responses before falling back to x402.\n * Pass an mppx client instance (from `Mppx.create()`).\n */\n mpp?: MppHandler;\n}\n\nexport type X402IntegritasFlow = 'single' | 'dual';\n\nexport interface X402IntegritasConfig {\n /** Enable Integritas stamp request headers */\n enabled?: boolean;\n /** Preferred Integritas flow for the request */\n flow?: X402IntegritasFlow;\n}\n\nexport interface X402RequestOptions {\n /** Per-request Integritas override */\n integritas?: boolean | X402IntegritasConfig;\n}\n\nexport type X402FetchInit = RequestInit & {\n /** SDK-specific per-request options (not forwarded to fetch as-is) */\n x402?: X402RequestOptions;\n};\n\nexport interface RelayWebSocketLike {\n readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n addEventListener?: (type: string, listener: (...args: any[]) => void) => void;\n removeEventListener?: (type: string, listener: (...args: any[]) => void) => void;\n on?: (type: string, listener: (...args: any[]) => void) => void;\n off?: (type: string, listener: (...args: any[]) => void) => void;\n removeListener?: (type: string, listener: (...args: any[]) => void) => void;\n onopen?: ((event: unknown) => void) | null;\n onmessage?: ((event: unknown) => void) | null;\n onerror?: ((event: unknown) => void) | null;\n onclose?: ((event: unknown) => void) | null;\n}\n\nexport type RelayWebSocketFactory = (url: string) => RelayWebSocketLike;\n\nexport interface X402RelayWsConfig {\n /** Enable WebSocket transport for relay URLs (still falls back to HTTP by default). */\n enabled?: boolean;\n /** Explicit WebSocket relay URL (default is derived from relay URL host). */\n wsUrl?: string;\n /** Timeout for WS connect and preflight call in milliseconds. Default: 5000. */\n preflightTimeoutMs?: number;\n /** Timeout for paid WS retry in milliseconds. Default: 10000. */\n paymentTimeoutMs?: number;\n /** Fallback to standard HTTP x402 flow when WS transport fails. Default: true. */\n fallbackToHttp?: boolean;\n /** Custom WebSocket factory, useful in runtimes without global WebSocket. */\n webSocketFactory?: RelayWebSocketFactory;\n}\n\nexport interface X402RelayWsError {\n code: number;\n message: string;\n data?: unknown;\n paymentRequired?: unknown;\n}\n\nexport interface X402RelayWsResponse {\n id?: string | number;\n result?: unknown;\n error?: X402RelayWsError;\n paymentResponse?: unknown;\n metadata?: Record<string, unknown>;\n}\n\nexport interface X402Client {\n /** Fetch with automatic x402 payment handling */\n fetch(input: string | URL | Request, init?: X402FetchInit): Promise<Response>;\n}\n\ntype RelaySocketEventName = 'open' | 'message' | 'error' | 'close';\ntype RelaySocketListener = (...args: any[]) => void;\n\ninterface RelayWsCallRequest {\n relayUrl: string;\n requestMethod: string;\n requestHeaders: Record<string, string>;\n requestBody?: unknown;\n paymentPayload?: unknown;\n timeoutMs: number;\n}\n\n/**\n * Create an x402 client for automatic payment handling.\n * Supports all RelAI facilitator networks: Solana, Base, Avalanche, SKALE Base, SKALE Base Sepolia, SKALE BITE, Polygon, and Ethereum.\n * Auto-detects the correct chain from the 402 response and picks the right\n * signing method (Solana SPL transfer, EVM EIP-3009 transferWithAuthorization).\n *\n * @example\n * ```typescript\n * import { createX402Client } from '@relai-fi/x402';\n *\n * const client = createX402Client({\n * wallets: { solana: solanaWallet, evm: evmWalletClient },\n * });\n *\n * // Automatically handles 402 on any RelAI-supported network\n * const response = await client.fetch('https://api.example.com/protected');\n * ```\n */\n// Networks that use EIP-2612 permit instead of EIP-3009 transferWithAuthorization (currently none)\nconst PERMIT_NETWORKS = new Set<string>([]);\n\n// Default EVM RPC URLs\nconst DEFAULT_EVM_RPC_URLS: Record<string, string> = {\n 'skale-base': 'https://skale-base.skalenodes.com/v1/base',\n 'skale-base-sepolia': 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha',\n 'skale-bite': 'https://base-sepolia-testnet.skalenodes.com/v1/bite-v2-sandbox',\n 'base': 'https://mainnet.base.org',\n 'avalanche': 'https://api.avax.network/ext/bc/C/rpc',\n 'polygon': 'https://polygon-rpc.com',\n 'ethereum': 'https://ethereum-rpc.publicnode.com',\n 'telos': 'https://rpc.telos.net',\n};\n\nexport function createX402Client(config: X402ClientConfig): X402Client {\n const {\n wallets = {},\n wallet: legacyWallet,\n facilitatorUrl = RELAI_FACILITATOR_URL,\n relayWs,\n preferredNetwork,\n networkSelectionMode = 'prefer_then_any',\n solanaRpcUrl = 'https://api.mainnet-beta.solana.com',\n evmRpcUrls = {},\n maxAmountAtomic,\n integritas,\n verbose = false,\n defaultHeaders = {},\n mpp,\n } = config;\n\n const relayWsEnabled = relayWs?.enabled === true;\n const relayWsPreflightTimeoutMs = relayWs?.preflightTimeoutMs ?? 5000;\n const relayWsPaymentTimeoutMs = relayWs?.paymentTimeoutMs ?? 10000;\n const relayWsFallbackToHttp = relayWs?.fallbackToHttp ?? true;\n const defaultIntegritas = normalizeIntegritasOptions(integritas);\n const relayWsReservedSubdomains = new Set<string>([\n 'www',\n 'api',\n 'localhost',\n 'admin',\n 'app',\n 'dashboard',\n 'docs',\n 'documentation',\n 'status',\n 'blog',\n 'facilitator',\n ]);\n\n const log = verbose ? console.log.bind(console, '[relai-x402]') : () => {};\n\n // Merge legacy wallet into wallet set\n const effectiveWallets: WalletSet = { ...wallets };\n if (legacyWallet && !effectiveWallets.solana) {\n effectiveWallets.solana = legacyWallet;\n }\n\n const hasSolanaWallet = Boolean(\n effectiveWallets.solana?.publicKey && effectiveWallets.solana?.signTransaction\n );\n if (hasSolanaWallet) log('Solana wallet ready');\n\n function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n }\n\n function parseJsonSafe(value: string): unknown {\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n }\n\n function addSocketListener(\n socket: RelayWebSocketLike,\n eventName: RelaySocketEventName,\n listener: RelaySocketListener,\n ): void {\n if (socket.addEventListener) {\n socket.addEventListener(eventName, listener);\n return;\n }\n\n if (socket.on) {\n socket.on(eventName, listener);\n }\n }\n\n function removeSocketListener(\n socket: RelayWebSocketLike,\n eventName: RelaySocketEventName,\n listener: RelaySocketListener,\n ): void {\n if (socket.removeEventListener) {\n socket.removeEventListener(eventName, listener);\n return;\n }\n\n if (socket.off) {\n socket.off(eventName, listener);\n return;\n }\n\n if (socket.removeListener) {\n socket.removeListener(eventName, listener);\n }\n }\n\n function resolveRelayWsUrl(relayUrl: string): string {\n if (relayWs?.wsUrl && relayWs.wsUrl.trim() !== '') {\n return relayWs.wsUrl.trim();\n }\n\n const parsedRelayUrl = new URL(relayUrl);\n const wsProtocol = parsedRelayUrl.protocol === 'https:' ? 'wss:' : 'ws:';\n return `${wsProtocol}//${parsedRelayUrl.host}/api/ws/relay`;\n }\n\n function resolveRelayWhitelabel(parsedRelayUrl: URL): string | null {\n const hostParts = parsedRelayUrl.hostname.toLowerCase().split('.').filter(Boolean);\n if (hostParts.length < 2) {\n return null;\n }\n\n const candidate = decodeURIComponent(hostParts[0] || '').trim();\n if (!candidate) {\n return null;\n }\n\n if (relayWsReservedSubdomains.has(candidate.toLowerCase())) {\n return null;\n }\n\n const lastPart = hostParts[hostParts.length - 1];\n const secondLastPart = hostParts[hostParts.length - 2];\n const isX402WhitelabelHost = hostParts.length >= 3 && secondLastPart === 'x402' && lastPart === 'fi';\n const isLocalWhitelabelHost = hostParts.length === 2 && lastPart === 'localhost';\n\n if (!isX402WhitelabelHost && !isLocalWhitelabelHost) {\n return null;\n }\n\n return candidate;\n }\n\n function resolveRelayTarget(relayUrl: string): { apiId: string; path: string } {\n const parsedRelayUrl = new URL(relayUrl);\n const match = parsedRelayUrl.pathname.match(/\\/relay\\/([^/]+)(\\/.*)?$/);\n if (match) {\n const apiId = decodeURIComponent(match[1]);\n const pathPart = match[2] || '/';\n return {\n apiId,\n path: `${pathPart}${parsedRelayUrl.search || ''}`,\n };\n }\n\n const whitelabel = resolveRelayWhitelabel(parsedRelayUrl);\n if (!whitelabel) {\n throw new Error(\n `[relai-x402] Unsupported relay URL format for WS transport: ${relayUrl}. ` +\n 'Expected /relay/:apiId/... or <whitelabel>.x402.fi/...',\n );\n }\n\n const pathPart = parsedRelayUrl.pathname && parsedRelayUrl.pathname !== ''\n ? parsedRelayUrl.pathname\n : '/';\n return {\n apiId: whitelabel,\n path: `${pathPart}${parsedRelayUrl.search || ''}`,\n };\n }\n\n function isRelayRequestUrl(requestUrl: string): boolean {\n try {\n resolveRelayTarget(requestUrl);\n return true;\n } catch {\n return false;\n }\n }\n\n function headersToRecord(headersInit?: HeadersInit): Record<string, string> {\n if (!headersInit) return {};\n\n const output: Record<string, string> = {};\n\n if (typeof Headers !== 'undefined' && headersInit instanceof Headers) {\n headersInit.forEach((value, key) => {\n output[key] = value;\n });\n return output;\n }\n\n if (Array.isArray(headersInit)) {\n for (const [key, value] of headersInit) {\n output[key] = value;\n }\n return output;\n }\n\n for (const [key, value] of Object.entries(headersInit)) {\n if (typeof value === 'string') {\n output[key] = value;\n } else if (Array.isArray(value)) {\n output[key] = value.join(', ');\n } else if (value !== undefined && value !== null) {\n output[key] = String(value);\n }\n }\n\n return output;\n }\n\n function hasHeaderCaseInsensitive(headers: Record<string, string>, headerName: string): boolean {\n const normalized = headerName.toLowerCase();\n return Object.keys(headers).some((key) => key.toLowerCase() === normalized);\n }\n\n function normalizeIntegritasFlow(value: unknown): X402IntegritasFlow | undefined {\n const normalized = String(value || '').trim().toLowerCase();\n if (normalized === 'single') return 'single';\n if (normalized === 'dual') return 'dual';\n return undefined;\n }\n\n function normalizeIntegritasOptions(\n value: boolean | X402IntegritasConfig | undefined,\n ): { enabled: boolean; flow?: X402IntegritasFlow } {\n if (value === true) return { enabled: true };\n if (value === false || value == null) return { enabled: false };\n\n const flow = normalizeIntegritasFlow(value.flow);\n const enabled =\n typeof value.enabled === 'boolean'\n ? value.enabled\n : true;\n\n return {\n enabled,\n ...(flow ? { flow } : {}),\n };\n }\n\n function resolveIntegritasOptions(\n override: boolean | X402IntegritasConfig | undefined,\n ): { enabled: boolean; flow?: X402IntegritasFlow } {\n if (override === undefined) {\n return defaultIntegritas;\n }\n\n if (typeof override === 'boolean') {\n return {\n enabled: override,\n ...(override && defaultIntegritas.flow ? { flow: defaultIntegritas.flow } : {}),\n };\n }\n\n const flow = normalizeIntegritasFlow(override.flow) || defaultIntegritas.flow;\n const enabled =\n typeof override.enabled === 'boolean'\n ? override.enabled\n : defaultIntegritas.enabled;\n\n return {\n enabled,\n ...(enabled && flow ? { flow } : {}),\n };\n }\n\n function stripInternalInit(init?: X402FetchInit): RequestInit | undefined {\n if (!init) return undefined;\n const { x402: _x402, ...requestInit } = init;\n return requestInit;\n }\n\n function applyIntegritasHeaders(\n headers: Record<string, string>,\n options: { enabled: boolean; flow?: X402IntegritasFlow },\n ): Record<string, string> {\n if (!options.enabled) return headers;\n\n if (!hasHeaderCaseInsensitive(headers, 'x-integritas')) {\n headers['X-Integritas'] = 'true';\n }\n\n if (options.flow && !hasHeaderCaseInsensitive(headers, 'x-integritas-flow')) {\n headers['X-Integritas-Flow'] = options.flow;\n }\n\n return headers;\n }\n\n function getRequestMethod(input: string | URL | Request, init?: RequestInit): string {\n const inputMethod = input instanceof Request ? input.method : undefined;\n return (init?.method || inputMethod || 'GET').toUpperCase();\n }\n\n async function bodyInitToWsPayload(bodyInit: unknown): Promise<unknown> {\n if (bodyInit === undefined || bodyInit === null) {\n return undefined;\n }\n\n if (typeof bodyInit === 'string') {\n const parsed = parseJsonSafe(bodyInit);\n return parsed === null ? bodyInit : parsed;\n }\n\n if (typeof URLSearchParams !== 'undefined' && bodyInit instanceof URLSearchParams) {\n return bodyInit.toString();\n }\n\n if (typeof FormData !== 'undefined' && bodyInit instanceof FormData) {\n const entries: Record<string, string> = {};\n for (const [key, value] of bodyInit.entries()) {\n entries[key] = typeof value === 'string' ? value : value.name;\n }\n return entries;\n }\n\n if (typeof Blob !== 'undefined' && bodyInit instanceof Blob) {\n const text = await bodyInit.text();\n if (!text) return undefined;\n const parsed = parseJsonSafe(text);\n return parsed === null ? text : parsed;\n }\n\n if (bodyInit instanceof ArrayBuffer) {\n return Array.from(new Uint8Array(bodyInit));\n }\n\n if (ArrayBuffer.isView(bodyInit)) {\n return Array.from(new Uint8Array(bodyInit.buffer, bodyInit.byteOffset, bodyInit.byteLength));\n }\n\n if (typeof Buffer !== 'undefined' && Buffer.isBuffer(bodyInit)) {\n return Array.from(bodyInit.values());\n }\n\n if (isRecord(bodyInit)) {\n return bodyInit;\n }\n\n return String(bodyInit);\n }\n\n async function resolveRequestBody(input: string | URL | Request, init?: RequestInit): Promise<unknown> {\n if (init && Object.prototype.hasOwnProperty.call(init, 'body')) {\n return bodyInitToWsPayload(init.body as unknown);\n }\n\n if (input instanceof Request) {\n const method = getRequestMethod(input, init);\n if (method === 'GET' || method === 'HEAD') {\n return undefined;\n }\n\n try {\n const cloned = input.clone();\n const text = await cloned.text();\n if (!text) return undefined;\n const parsed = parseJsonSafe(text);\n return parsed === null ? text : parsed;\n } catch {\n return undefined;\n }\n }\n\n return undefined;\n }\n\n function getRequestHeaders(input: string | URL | Request, init?: RequestInit): Record<string, string> {\n const fromInput = input instanceof Request ? headersToRecord(input.headers) : {};\n const fromInit = headersToRecord(init?.headers);\n const merged = {\n ...defaultHeaders,\n ...fromInput,\n ...fromInit,\n };\n\n if (!merged.Accept && !merged.accept) {\n merged.Accept = 'application/json';\n }\n\n return merged;\n }\n\n function toMessageString(data: unknown): string {\n if (typeof data === 'string') {\n return data;\n }\n\n if (isRecord(data) && typeof data.data !== 'undefined') {\n return toMessageString(data.data);\n }\n\n if (typeof Buffer !== 'undefined' && Buffer.isBuffer(data)) {\n return data.toString('utf8');\n }\n\n if (data instanceof ArrayBuffer) {\n const bytes = new Uint8Array(data);\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('utf8');\n }\n if (typeof TextDecoder !== 'undefined') {\n return new TextDecoder().decode(bytes);\n }\n throw new Error('Unsupported WebSocket message data type');\n }\n\n if (ArrayBuffer.isView(data)) {\n const bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('utf8');\n }\n if (typeof TextDecoder !== 'undefined') {\n return new TextDecoder().decode(bytes);\n }\n throw new Error('Unsupported WebSocket message data type');\n }\n\n throw new Error('Unsupported WebSocket message data type');\n }\n\n function getWebSocketFactory(): RelayWebSocketFactory {\n if (relayWs?.webSocketFactory) {\n return relayWs.webSocketFactory;\n }\n\n if (typeof WebSocket !== 'undefined') {\n return (wsUrl: string) => new WebSocket(wsUrl) as unknown as RelayWebSocketLike;\n }\n\n throw new Error(\n '[relai-x402] WebSocket is not available in this runtime. Provide relayWs.webSocketFactory.',\n );\n }\n\n async function relayCallOverWebSocket(request: RelayWsCallRequest): Promise<X402RelayWsResponse> {\n const wsFactory = getWebSocketFactory();\n const wsUrl = resolveRelayWsUrl(request.relayUrl);\n const target = resolveRelayTarget(request.relayUrl);\n const requestId = `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n const socket = wsFactory(wsUrl);\n\n return new Promise<X402RelayWsResponse>((resolve, reject) => {\n let settled = false;\n\n const settleResolve = (value: X402RelayWsResponse) => {\n if (settled) return;\n settled = true;\n cleanup();\n try {\n socket.close();\n } catch {\n // Ignore close errors.\n }\n resolve(value);\n };\n\n const settleReject = (error: Error) => {\n if (settled) return;\n settled = true;\n cleanup();\n try {\n socket.close();\n } catch {\n // Ignore close errors.\n }\n reject(error);\n };\n\n const timeoutId = setTimeout(() => {\n settleReject(new Error(`[relai-x402] Timed out waiting for WS relay response after ${request.timeoutMs}ms`));\n }, request.timeoutMs);\n\n const cleanup = () => {\n clearTimeout(timeoutId);\n removeSocketListener(socket, 'open', onOpen);\n removeSocketListener(socket, 'message', onMessage);\n removeSocketListener(socket, 'error', onError);\n removeSocketListener(socket, 'close', onClose);\n };\n\n const onOpen = () => {\n const envelope: Record<string, unknown> = {\n id: requestId,\n method: 'relay.call',\n params: {\n apiId: target.apiId,\n path: target.path,\n requestMethod: request.requestMethod,\n requestHeaders: request.requestHeaders,\n ...(request.requestBody !== undefined ? { requestBody: request.requestBody } : {}),\n },\n };\n\n if (request.paymentPayload !== undefined) {\n envelope.payment = request.paymentPayload;\n }\n\n try {\n socket.send(JSON.stringify(envelope));\n } catch {\n settleReject(new Error('[relai-x402] Failed to send WS relay request'));\n }\n };\n\n const onMessage = (...args: any[]) => {\n const payload = args.length > 0 ? args[0] : undefined;\n\n let parsed: unknown;\n try {\n parsed = parseJsonSafe(toMessageString(payload));\n } catch {\n return;\n }\n\n if (!isRecord(parsed)) return;\n\n const responseId =\n typeof parsed.id === 'string' || typeof parsed.id === 'number' ? String(parsed.id) : '';\n if (responseId !== requestId) return;\n\n settleResolve(parsed as X402RelayWsResponse);\n };\n\n const onError = () => {\n settleReject(new Error('[relai-x402] WebSocket relay transport error'));\n };\n\n const onClose = () => {\n settleReject(new Error('[relai-x402] WebSocket relay connection closed before response'));\n };\n\n addSocketListener(socket, 'open', onOpen);\n addSocketListener(socket, 'message', onMessage);\n addSocketListener(socket, 'error', onError);\n addSocketListener(socket, 'close', onClose);\n });\n }\n\n function extractPaymentRequirementsFromWsError(error: X402RelayWsError): any | null {\n const candidates: unknown[] = [error.paymentRequired, error.data];\n\n for (const candidate of candidates) {\n if (!isRecord(candidate)) continue;\n\n if (Array.isArray(candidate.accepts)) {\n return candidate;\n }\n\n if (isRecord(candidate.paymentRequired) && Array.isArray(candidate.paymentRequired.accepts)) {\n return candidate.paymentRequired;\n }\n\n if (isRecord(candidate.data) && Array.isArray(candidate.data.accepts)) {\n return candidate.data;\n }\n }\n\n return null;\n }\n\n function buildWsResponse(wsResponse: X402RelayWsResponse): Response {\n const statusFromMetadata =\n isRecord(wsResponse.metadata) && typeof wsResponse.metadata.status === 'number'\n ? wsResponse.metadata.status\n : 200;\n const status = Number.isInteger(statusFromMetadata) && statusFromMetadata >= 100 && statusFromMetadata <= 599\n ? statusFromMetadata\n : 200;\n\n const headers = new Headers();\n headers.set('Content-Type', 'application/json');\n\n if (wsResponse.paymentResponse !== undefined) {\n headers.set('PAYMENT-RESPONSE', encodeBase64Json(wsResponse.paymentResponse));\n }\n\n const bodyPayload = wsResponse.result === undefined ? null : wsResponse.result;\n return new Response(JSON.stringify(bodyPayload), {\n status,\n headers,\n });\n }\n\n // -----------------------------------------------------------------------\n // Select a payment option from the 402 response's `accepts` array\n // -----------------------------------------------------------------------\n function selectAcceptForWallet(a: any): { accept: any; chain: 'solana' | 'evm' } | null {\n const net = a.network || '';\n if (isSolana(net) && hasSolanaWallet) {\n return { accept: a, chain: 'solana' };\n }\n if (isEvm(net) && effectiveWallets.evm) {\n return { accept: a, chain: 'evm' };\n }\n return null;\n }\n\n function buildNoWalletError(accepts: any[], isWs: boolean): string {\n const networks = accepts.map((a: any) => a.network).join(', ');\n if (preferredNetwork && networkSelectionMode === 'strict_preferred') {\n const preferredCaip2 = NETWORK_CAIP2[preferredNetwork];\n return (\n `[relai-x402] Preferred network ${preferredNetwork} (${preferredCaip2}) is required, ` +\n `but no compatible wallet is connected. Available networks: ${networks}`\n );\n }\n\n return `[relai-x402] No wallet available for${isWs ? ' WS' : ''} networks: ${networks}`;\n }\n\n function selectAccept(accepts: any[]): { accept: any; chain: 'solana' | 'evm' } | null {\n // 1) Preferred network first\n if (preferredNetwork) {\n const caip2 = NETWORK_CAIP2[preferredNetwork];\n for (const a of accepts) {\n const net = a.network || '';\n if (net === preferredNetwork || net === caip2) {\n const selected = selectAcceptForWallet(a);\n if (selected) {\n return selected;\n }\n }\n }\n\n if (networkSelectionMode === 'strict_preferred') {\n return null;\n }\n }\n\n // 2) First option we have a wallet for\n for (const a of accepts) {\n const selected = selectAcceptForWallet(a);\n if (selected) {\n return selected;\n }\n }\n\n return null;\n }\n\n // -----------------------------------------------------------------------\n // Bridge extension — cross-chain payment routing (x402 bridge spec)\n // -----------------------------------------------------------------------\n\n function getBridgeExtension(requirements: any): any | null {\n const ext = requirements?.extensions?.bridge;\n if (!ext?.info?.settleEndpoint || !Array.isArray(ext.info.supportedSourceChains)) return null;\n return ext.info;\n }\n\n function selectBridgeSource(bridge: any): { chain: 'solana' | 'evm'; network: string; asset: string } | null {\n const sourceChains: string[] = bridge.supportedSourceChains || [];\n const sourceAssets: string[] = bridge.supportedSourceAssets || [];\n for (const caip2 of sourceChains) {\n if (isSolana(caip2) && hasSolanaWallet) {\n const asset = sourceAssets.find((a: string) => !a.startsWith('0x')) || '';\n return { chain: 'solana', network: caip2, asset };\n }\n if (isEvm(caip2) && effectiveWallets.evm) {\n const asset = sourceAssets.find((a: string) => a.startsWith('0x')) || '';\n return { chain: 'evm', network: caip2, asset };\n }\n }\n return null;\n }\n\n async function executeBridgePayment(\n bridge: any,\n accepts: any[],\n requirements: any,\n url: string,\n ): Promise<string> {\n const source = selectBridgeSource(bridge);\n if (!source) {\n throw new Error('[relai-x402] bridge extension found but no wallet matches supported source chains');\n }\n\n // Pick first accept as the target (merchant's preferred chain)\n const targetAccept = accepts[0];\n const amount = targetAccept.amount || targetAccept.maxAmountRequired;\n\n log(`Bridge: ${source.network} → ${targetAccept.network}, amount=${amount}`);\n\n // Amount guard\n if (maxAmountAtomic && BigInt(amount) > BigInt(maxAmountAtomic)) {\n throw new Error(`[relai-x402] Amount ${amount} exceeds max ${maxAmountAtomic}`);\n }\n\n // Build source-chain payment header (same logic as direct payment)\n let sourcePaymentHeader: string;\n if (source.chain === 'solana') {\n // Build a synthetic accept entry for the source chain.\n // payTo must be the bridge facilitator's Solana wallet (bridge.payTo),\n // NOT the merchant's address (which may be an EVM address).\n // feePayer comes from bridge.info — facilitator sponsors Solana gas.\n if (!bridge.payTo) {\n throw new Error('[relai-x402] bridge.info.payTo is required for Solana source payments');\n }\n const sourceAccept = {\n scheme: 'exact',\n network: source.network,\n asset: source.asset,\n payTo: bridge.payTo,\n amount: targetAccept.amount || targetAccept.maxAmountRequired,\n extra: {\n ...(bridge.feePayerSvm ? { feePayer: bridge.feePayerSvm } : {}),\n decimals: 6,\n },\n };\n sourcePaymentHeader = await buildSolanaPayment(sourceAccept, requirements, url);\n } else {\n const evmNetwork = normalizeNetwork(source.network);\n const usePermit = evmNetwork && PERMIT_NETWORKS.has(evmNetwork);\n const sourceAccept = {\n ...targetAccept,\n network: source.network,\n asset: source.asset || targetAccept.asset,\n ...(bridge.payTo ? { payTo: bridge.payTo } : {}),\n };\n sourcePaymentHeader = usePermit\n ? await buildEvmPermitPayment(sourceAccept, requirements, url)\n : await buildEvmPayment(sourceAccept, requirements, url);\n }\n\n // POST to bridge settle endpoint\n const bridgeRes = await fetch(bridge.settleEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n sourcePayment: sourcePaymentHeader,\n sourceChain: source.network,\n targetAccept,\n requirements,\n resource: url,\n paymentFacilitator: bridge.paymentFacilitator || null,\n ...(bridge.serviceKeyHash ? { serviceKeyHash: bridge.serviceKeyHash } : {}),\n }),\n });\n\n if (!bridgeRes.ok) {\n const err = await bridgeRes.json().catch(() => ({}));\n throw new Error(`[relai-x402] bridge settle failed: ${err.error || bridgeRes.status}`);\n }\n\n const bridgeData = await bridgeRes.json();\n if (!bridgeData.xPayment) {\n throw new Error('[relai-x402] bridge endpoint did not return xPayment header');\n }\n\n log(`Bridge settled: sourceTx=${bridgeData.sourceTxId}, targetTx=${bridgeData.targetTxId}`);\n return bridgeData.xPayment;\n }\n\n // -----------------------------------------------------------------------\n // JSON-RPC helper (for reading EVM contract state without ethers)\n // -----------------------------------------------------------------------\n async function evmRpcCall(rpcUrl: string, to: string, data: string): Promise<string> {\n const res = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_call',\n params: [{ to, data }, 'latest'],\n id: 1,\n }),\n });\n const json = await res.json();\n if (json.error) throw new Error(`RPC error: ${json.error.message}`);\n return json.result;\n }\n\n function getEvmRpcUrl(network: string): string {\n return evmRpcUrls[network] || DEFAULT_EVM_RPC_URLS[network] || '';\n }\n\n // -----------------------------------------------------------------------\n // Build EVM payment — EIP-2612 permit (for SKALE Base)\n // -----------------------------------------------------------------------\n async function buildEvmPermitPayment(\n accept: any,\n requirements: any,\n url: string,\n ): Promise<string> {\n const evmWallet = effectiveWallets.evm!;\n const extra = accept.extra || {};\n\n const rawNetwork = accept.network || '';\n const network = normalizeNetwork(rawNetwork);\n const chainId = network ? CHAIN_IDS[network] : parseInt(rawNetwork.split(':')[1] || '8453');\n const paymentAmount = accept.amount || accept.maxAmountRequired;\n const spender = extra.feePayer || accept.payTo;\n const usdcAddress = accept.asset;\n\n const rpcUrl = getEvmRpcUrl(network || rawNetwork);\n if (!rpcUrl) throw new Error(`[relai-x402] No EVM RPC URL for network ${network || rawNetwork}`);\n\n log('Building EIP-2612 permit on chain', chainId);\n\n // Read nonce from USDC contract: nonces(address) = 0x7ecebe00\n const paddedAddress = evmWallet.address.toLowerCase().replace('0x', '').padStart(64, '0');\n const nonceHex = await evmRpcCall(rpcUrl, usdcAddress, '0x7ecebe00' + paddedAddress);\n const nonce = nonceHex ? parseInt(nonceHex, 16) : 0;\n if (isNaN(nonce)) throw new Error(`[relai-x402] Failed to read permit nonce from ${usdcAddress} on ${rpcUrl}`);\n log(' Permit nonce:', nonce);\n\n // Read token name: name() = 0x06fdde03\n const nameHex = await evmRpcCall(rpcUrl, usdcAddress, '0x06fdde03');\n // Decode ABI-encoded string\n let tokenName = 'USD Coin';\n try {\n const offset = parseInt(nameHex.slice(2, 66), 16) * 2;\n const length = parseInt(nameHex.slice(2 + offset, 2 + offset + 64), 16);\n const hex = nameHex.slice(2 + offset + 64, 2 + offset + 64 + length * 2);\n tokenName = decodeURIComponent(hex.replace(/[0-9a-f]{2}/g, '%$&'));\n } catch {\n tokenName = extra.name || 'USD Coin';\n }\n log(' Token name:', tokenName);\n\n const deadline = Math.floor(Date.now() / 1000) + 600; // 10 min\n\n const domain = {\n name: tokenName,\n version: extra.version || '2',\n chainId,\n verifyingContract: usdcAddress,\n };\n\n const types = {\n Permit: [\n { name: 'owner', type: 'address' },\n { name: 'spender', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n };\n\n const message = {\n owner: evmWallet.address,\n spender,\n value: paymentAmount,\n nonce: String(nonce),\n deadline: String(deadline),\n };\n\n log('Signing EIP-2612 permit:', message);\n\n const signature = await evmWallet.signTypedData({\n domain,\n types,\n message,\n primaryType: 'Permit',\n });\n\n // Split signature into v, r, s\n const sigHex = (signature as string).replace('0x', '');\n const r = '0x' + sigHex.slice(0, 64);\n const s = '0x' + sigHex.slice(64, 128);\n const v = parseInt(sigHex.slice(128, 130), 16);\n\n log(' Permit signed: v=%d r=%s s=%s', v, r, s);\n\n // Build x402 v2 payment payload (SKALE format)\n const paymentPayload = {\n x402Version: 2,\n scheme: 'exact',\n network: network || rawNetwork,\n payload: {\n userAddress: evmWallet.address,\n permit: { deadline: String(deadline), v, r, s },\n amount: paymentAmount,\n },\n };\n\n return encodeBase64Json(paymentPayload);\n }\n\n // -----------------------------------------------------------------------\n // Build EVM payment (EIP-3009 transferWithAuthorization)\n // -----------------------------------------------------------------------\n async function buildEvmPayment(\n accept: any,\n requirements: any,\n url: string,\n ): Promise<string> {\n const evmWallet = effectiveWallets.evm!;\n const extra = accept.extra || {};\n\n const rawNetwork = accept.network || '';\n const network = normalizeNetwork(rawNetwork);\n const chainId = network ? CHAIN_IDS[network] : parseInt(rawNetwork.split(':')[1] || '8453');\n\n const paymentAmount = accept.amount || accept.maxAmountRequired;\n\n // EIP-3009 transferWithAuthorization does NOT require approve\n // Facilitator executes transfer directly with user's signature (zero gas for user)\n \n // For relayer-based facilitators (0xGasless), 'to' is the payTo (merchant).\n // For standard x402 (RelAI), 'to' is also payTo (merchant).\n const useRelayer = !!extra.relayerContract;\n\n const rpcUrl = getEvmRpcUrl(network || rawNetwork);\n const defaultTokenVersion = chainId === CHAIN_IDS['skale-bite'] ? '1' : '2';\n\n let tokenName = extra.name || 'USD Coin';\n if (!useRelayer && rpcUrl) {\n try {\n // Read token name from contract to avoid EIP-712 domain mismatch across bridged assets.\n const nameHex = await evmRpcCall(rpcUrl, accept.asset, '0x06fdde03');\n const offset = parseInt(nameHex.slice(2, 66), 16) * 2;\n const length = parseInt(nameHex.slice(2 + offset, 2 + offset + 64), 16);\n const hex = nameHex.slice(2 + offset + 64, 2 + offset + 64 + length * 2);\n tokenName = decodeURIComponent(hex.replace(/[0-9a-f]{2}/g, '%$&'));\n } catch {\n tokenName = extra.name || 'USD Coin';\n }\n }\n\n // EIP-3009 transferWithAuthorization typed data\n // When extra.relayerContract is present (e.g. 0xGasless), sign against the\n // relayer contract's EIP-712 domain instead of the token contract's domain.\n const domain = {\n name: useRelayer ? (extra.domainName || 'A402') : tokenName,\n version: useRelayer ? (extra.domainVersion || '1') : (extra.version || defaultTokenVersion),\n chainId,\n verifyingContract: useRelayer ? extra.relayerContract : accept.asset,\n };\n\n // Detect whether token supports EIP-2612 permit (but not EIP-3009)\n const tokenNetworkKey = network || rawNetwork;\n const networkTokens = NETWORK_TOKENS[tokenNetworkKey as keyof typeof NETWORK_TOKENS];\n const assetLower = (accept.asset || '').toLowerCase();\n const tokenInfo = networkTokens?.find((t: any) => t.address.toLowerCase() === assetLower) || networkTokens?.[0];\n const tokenStandards: string[] = Array.isArray(tokenInfo?.standards) ? tokenInfo.standards : [];\n const hasEip3009 = tokenStandards.some((s: string) => s.toLowerCase() === 'eip3009');\n const hasEip2612 = tokenStandards.some((s: string) => s.toLowerCase() === 'eip2612');\n const usePermit2612 = !hasEip3009 && hasEip2612;\n\n let message: Record<string, unknown>;\n let signature: string;\n let authorizationScheme: string;\n\n if (usePermit2612) {\n // EIP-2612 permit flow: read nonce from contract, sign Permit typed data\n // spender = feePayer (RelAI backend) who will call permit + transferFrom\n const spender = extra.feePayer || accept.payTo;\n const deadline = Math.floor(Date.now() / 1000) + 3600;\n\n let nonce = 0;\n if (rpcUrl) {\n try {\n const paddedAddress = evmWallet.address.toLowerCase().replace('0x', '').padStart(64, '0');\n const nonceHex = await evmRpcCall(rpcUrl, accept.asset, '0x7ecebe00' + paddedAddress);\n nonce = nonceHex ? parseInt(nonceHex, 16) : 0;\n } catch { nonce = 0; }\n }\n\n const permitTypes = {\n Permit: [\n { name: 'owner', type: 'address' },\n { name: 'spender', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n };\n\n message = {\n owner: evmWallet.address,\n spender,\n value: paymentAmount,\n nonce: String(nonce),\n deadline: String(deadline),\n };\n\n log('Signing EIP-2612 permit on chain', chainId);\n\n signature = await evmWallet.signTypedData({\n domain,\n types: permitTypes,\n message,\n primaryType: 'Permit',\n });\n\n authorizationScheme = 'eip2612';\n } else {\n // EIP-3009 transferWithAuthorization flow (default)\n const validAfter = 0;\n const validBefore = Math.floor(Date.now() / 1000) + 3600;\n const nonce = '0x' + [...crypto.getRandomValues(new Uint8Array(32))]\n .map(b => b.toString(16).padStart(2, '0')).join('');\n\n const transferTypes = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n message = {\n from: evmWallet.address,\n to: accept.payTo,\n value: paymentAmount,\n validAfter: String(validAfter),\n validBefore: String(validBefore),\n nonce,\n };\n\n log('Signing EIP-3009 transferWithAuthorization on chain', chainId);\n\n signature = await evmWallet.signTypedData({\n domain,\n types: transferTypes,\n message,\n primaryType: 'TransferWithAuthorization',\n });\n\n authorizationScheme = 'eip3009';\n }\n\n // Build x402 v2 payment payload\n const paymentPayload = {\n x402Version: 2,\n resource: requirements.resource || { url },\n accepted: accept,\n payload: {\n authorization: message,\n signature,\n authorizationScheme,\n },\n facilitatorUrl,\n };\n\n return encodeBase64Json(paymentPayload);\n }\n\n // -----------------------------------------------------------------------\n // Build Solana payment (SPL transfer with fee payer sponsorship)\n // -----------------------------------------------------------------------\n async function buildSolanaPayment(\n accept: any,\n requirements: any,\n url: string,\n ): Promise<string> {\n const solWallet = effectiveWallets.solana!;\n const extra = accept.extra || {};\n\n if (!extra.feePayer) {\n throw new Error('[relai-x402] Missing feePayer in Solana payment requirements');\n }\n\n const connection = new Connection(solanaRpcUrl, 'confirmed');\n const userPubkey = new PublicKey(solWallet.publicKey!.toString());\n const merchantPubkey = new PublicKey(accept.payTo);\n const feePayerPubkey = new PublicKey(extra.feePayer);\n const mintPubkey = new PublicKey(accept.asset);\n const paymentAmount = BigInt(accept.amount || accept.maxAmountRequired);\n\n log('Building Solana SPL transfer');\n log(' User:', userPubkey.toBase58());\n log(' Merchant:', merchantPubkey.toBase58());\n log(' FeePayer:', feePayerPubkey.toBase58());\n log(' Mint:', mintPubkey.toBase58());\n log(' Amount:', paymentAmount.toString());\n\n // Determine token program (TOKEN_PROGRAM_ID vs TOKEN_2022)\n const mintInfo = await getMint(connection, mintPubkey);\n const programId = mintInfo.address.equals(mintPubkey)\n ? (mintInfo as any).owner?.toBase58?.() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n // Get ATAs (allowOffCurve=true for smart wallets / PDA signers)\n const sourceAta = await getAssociatedTokenAddress(\n mintPubkey, userPubkey, true, programId,\n );\n const destinationAta = await getAssociatedTokenAddress(\n mintPubkey, merchantPubkey, true, programId,\n );\n\n log(' Source ATA:', sourceAta.toBase58());\n log(' Dest ATA:', destinationAta.toBase58());\n\n // Build transfer instruction\n const transferIx = createTransferCheckedInstruction(\n sourceAta,\n mintPubkey,\n destinationAta,\n userPubkey,\n paymentAmount,\n mintInfo.decimals,\n [],\n programId,\n );\n\n // Build versioned transaction with feePayer\n const { blockhash } = await connection.getLatestBlockhash('confirmed');\n const message = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: blockhash,\n instructions: [transferIx],\n }).compileToV0Message();\n\n const transaction = new VersionedTransaction(message);\n\n // User signs (feePayer signs on backend/facilitator side)\n const signedTx = await solWallet.signTransaction!(transaction) as VersionedTransaction;\n log('Transaction signed by user');\n\n // Serialize to base64\n const serializedTx = Buffer.from(signedTx.serialize()).toString('base64');\n\n // Build x402 v2 payment payload\n const paymentPayload = {\n x402Version: 2,\n resource: requirements.resource || { url },\n accepted: accept,\n payload: {\n transaction: serializedTx,\n },\n };\n\n return encodeBase64Json(paymentPayload);\n }\n\n // -----------------------------------------------------------------------\n // Main fetch\n // -----------------------------------------------------------------------\n function encodeBase64Json(payload: unknown): string {\n const serialized = JSON.stringify(payload);\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(serialized, 'utf8').toString('base64');\n }\n if (typeof btoa !== 'undefined') {\n return btoa(serialized);\n }\n throw new Error('[relai-x402] Base64 encoding is not available in this runtime');\n }\n\n function decodeBase64Json(encoded: string): any | null {\n try {\n const normalized = encoded.trim().replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, '=');\n const decoded = typeof Buffer !== 'undefined'\n ? Buffer.from(padded, 'base64').toString('utf8')\n : atob(padded);\n return JSON.parse(decoded);\n } catch {\n return null;\n }\n }\n\n function parsePaymentRequiredHeader(response: Response): any | null {\n const headerValue =\n response.headers.get('payment-required') ||\n response.headers.get('PAYMENT-REQUIRED') ||\n response.headers.get('x-payment-required') ||\n response.headers.get('X-PAYMENT-REQUIRED');\n\n if (!headerValue) return null;\n\n const trimmed = headerValue.trim();\n if (!trimmed) return null;\n\n try {\n return JSON.parse(trimmed);\n } catch {\n return decodeBase64Json(trimmed);\n }\n }\n\n function getAccepts(requirements: any): any[] {\n if (!requirements || typeof requirements !== 'object') {\n return [];\n }\n\n if (Array.isArray(requirements.accepts)) {\n return requirements.accepts;\n }\n\n if (requirements.paymentRequired && Array.isArray(requirements.paymentRequired.accepts)) {\n return requirements.paymentRequired.accepts;\n }\n\n if (requirements.data && Array.isArray(requirements.data.accepts)) {\n return requirements.data.accepts;\n }\n\n return [];\n }\n\n async function x402Fetch(\n input: string | URL | Request,\n init?: X402FetchInit,\n ): Promise<Response> {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;\n log('Request:', url);\n\n const requestInit = stripInternalInit(init);\n const integritasOptions = resolveIntegritasOptions(init?.x402?.integritas);\n const requestMethod = getRequestMethod(input, requestInit);\n const requestHeaders = applyIntegritasHeaders(\n getRequestHeaders(input, requestInit),\n integritasOptions,\n );\n const requestInitWithHeaders: RequestInit = {\n ...(requestInit || {}),\n headers: requestHeaders,\n };\n const requestBody = await resolveRequestBody(input, requestInitWithHeaders);\n\n if (relayWsEnabled && isRelayRequestUrl(url)) {\n let wsPaymentPhaseStarted = false;\n try {\n log('Using WebSocket relay transport');\n\n const wsPreflightResponse = await relayCallOverWebSocket({\n relayUrl: url,\n requestMethod,\n requestHeaders,\n requestBody,\n timeoutMs: relayWsPreflightTimeoutMs,\n });\n\n if (!wsPreflightResponse.error) {\n return buildWsResponse(wsPreflightResponse);\n }\n\n if (Number(wsPreflightResponse.error.code) !== 402) {\n throw new Error(wsPreflightResponse.error.message || '[relai-x402] WebSocket relay request failed');\n }\n\n const wsRequirements = extractPaymentRequirementsFromWsError(wsPreflightResponse.error);\n if (!wsRequirements) {\n throw new Error(\n wsPreflightResponse.error.message || '[relai-x402] No payment requirements in WS 402 response'\n );\n }\n\n const wsAccepts = getAccepts(wsRequirements);\n if (!wsAccepts.length) {\n throw new Error('[relai-x402] No payment options in WS 402 response');\n }\n\n if (wsAccepts.length > 1) {\n throw new Error(\n '[relai-x402] WS relay currently supports a single payment payload; use HTTP flow for multi-accept payments'\n );\n }\n\n const wsSelected = selectAccept(wsAccepts);\n if (!wsSelected) {\n throw new Error(buildNoWalletError(wsAccepts, true));\n }\n\n const { accept, chain } = wsSelected;\n const amount = accept.amount || accept.maxAmountRequired;\n\n if (maxAmountAtomic && BigInt(amount) > BigInt(maxAmountAtomic)) {\n throw new Error(`[relai-x402] Amount ${amount} exceeds max ${maxAmountAtomic}`);\n }\n\n wsPaymentPhaseStarted = true;\n\n let paymentHeader: string | null = null;\n if (chain === 'solana' && hasSolanaWallet) {\n paymentHeader = await buildSolanaPayment(accept, wsRequirements, url);\n } else if (chain === 'evm') {\n const evmNetwork = normalizeNetwork(accept.network || '');\n const usePermit = evmNetwork && PERMIT_NETWORKS.has(evmNetwork);\n paymentHeader = usePermit\n ? await buildEvmPermitPayment(accept, wsRequirements, url)\n : await buildEvmPayment(accept, wsRequirements, url);\n }\n\n if (!paymentHeader) {\n throw new Error('[relai-x402] Unexpected state - no WS payment handler matched');\n }\n\n const paymentPayload = decodeBase64Json(paymentHeader);\n if (!paymentPayload) {\n throw new Error('[relai-x402] Failed to decode payment payload for WS relay call');\n }\n\n const wsPaidResponse = await relayCallOverWebSocket({\n relayUrl: url,\n requestMethod,\n requestHeaders,\n requestBody,\n paymentPayload,\n timeoutMs: relayWsPaymentTimeoutMs,\n });\n\n if (wsPaidResponse.error) {\n throw new Error(wsPaidResponse.error.message || '[relai-x402] WebSocket paid relay request failed');\n }\n\n return buildWsResponse(wsPaidResponse);\n } catch (wsError) {\n const wsMessage = wsError instanceof Error ? wsError.message : String(wsError);\n log('WebSocket relay transport failed:', wsMessage);\n\n if (wsPaymentPhaseStarted) {\n // Do not retry over HTTP after payment flow has started (may trigger duplicate signing/payment prompts).\n throw wsError instanceof Error ? wsError : new Error(`[relai-x402] ${wsMessage}`);\n }\n\n if (!relayWsFallbackToHttp) {\n throw wsError instanceof Error ? wsError : new Error(`[relai-x402] ${wsMessage}`);\n }\n\n log('Falling back to HTTP x402 flow');\n }\n }\n\n const response = await fetch(input, requestInitWithHeaders);\n if (response.status !== 402) return response;\n\n log('Got 402 Payment Required');\n\n // ── MPP: check for WWW-Authenticate: Payment challenge ──────────────\n if (mpp) {\n const wwwAuth = response.headers.get('www-authenticate');\n if (wwwAuth && /^Payment\\s+/i.test(wwwAuth.trim())) {\n log('MPP challenge detected in WWW-Authenticate header');\n try {\n const credential = await mpp.createCredential(response);\n if (credential) {\n log('MPP credential created, retrying with Authorization: Payment');\n const mppRetry = await fetch(input, {\n ...requestInitWithHeaders,\n headers: {\n ...requestHeaders,\n 'Authorization': credential.startsWith('Payment ') ? credential : `Payment ${credential}`,\n },\n });\n if (mppRetry.status !== 402) {\n return mppRetry;\n }\n log('MPP retry still returned 402, falling through to x402');\n }\n } catch (mppErr) {\n log(`MPP payment failed (${mppErr instanceof Error ? mppErr.message : mppErr}), falling through to x402`);\n }\n }\n }\n // ── End MPP ─────────────────────────────────────────────────────────\n\n let requirementsFromBody: any = null;\n try {\n requirementsFromBody = await response.clone().json();\n } catch {}\n\n const requirementsFromHeader = parsePaymentRequiredHeader(response);\n\n let requirements: any = requirementsFromBody;\n let accepts = getAccepts(requirementsFromBody);\n\n if (!accepts.length && requirementsFromHeader) {\n const headerAccepts = getAccepts(requirementsFromHeader);\n\n if (headerAccepts.length || !requirements || typeof requirements !== 'object') {\n requirements = requirementsFromHeader;\n accepts = headerAccepts;\n log('402 body missing accepts; using PAYMENT-REQUIRED header fallback');\n }\n }\n\n if (!requirements || typeof requirements !== 'object') {\n throw new Error('[relai-x402] Failed to parse 402 response body/header');\n }\n\n if (!accepts.length) throw new Error('[relai-x402] No payment options in 402 response');\n\n const selected = selectAccept(accepts);\n if (!selected) {\n // Fallback: check bridge extension for cross-chain routing\n const bridge = getBridgeExtension(requirements);\n if (bridge && selectBridgeSource(bridge)) {\n log('No direct wallet match — attempting bridge extension flow');\n const paymentHeader = await executeBridgePayment(bridge, accepts, requirements, url);\n log('Retrying with X-PAYMENT header (bridge)');\n return fetch(input, {\n ...requestInitWithHeaders,\n headers: { ...requestHeaders, 'X-PAYMENT': paymentHeader },\n });\n }\n throw new Error(buildNoWalletError(accepts, false));\n }\n\n const { accept, chain } = selected;\n const amount = accept.amount || accept.maxAmountRequired;\n log(`Selected: ${chain} / ${accept.network} / amount=${amount}`);\n\n // Amount guard\n if (maxAmountAtomic && BigInt(amount) > BigInt(maxAmountAtomic)) {\n throw new Error(`[relai-x402] Amount ${amount} exceeds max ${maxAmountAtomic}`);\n }\n\n // Solana — build SPL transfer natively (no x402-solana dependency)\n if (chain === 'solana' && hasSolanaWallet) {\n const paymentHeader = await buildSolanaPayment(accept, requirements, url);\n log('Retrying with X-PAYMENT header (Solana)');\n return fetch(input, {\n ...requestInitWithHeaders,\n headers: {\n ...requestHeaders,\n 'X-PAYMENT': paymentHeader,\n },\n });\n }\n\n // EVM — build payment header and retry\n if (chain === 'evm') {\n const evmNetwork = normalizeNetwork(accept.network || '');\n const usePermit = evmNetwork && PERMIT_NETWORKS.has(evmNetwork);\n const paymentHeader = usePermit\n ? await buildEvmPermitPayment(accept, requirements, url)\n : await buildEvmPayment(accept, requirements, url);\n log('Retrying with X-PAYMENT header');\n return fetch(input, {\n ...requestInitWithHeaders,\n headers: {\n ...requestHeaders,\n 'X-PAYMENT': paymentHeader,\n },\n });\n }\n\n throw new Error('[relai-x402] Unexpected state - no payment handler matched');\n }\n\n return { fetch: x402Fetch };\n}\n\nexport default createX402Client;\n","// src/relay-feedback.ts\n// Standalone utility for submitting ERC-8004 feedback about third-party APIs.\n// Not a plugin — call directly from your relay/aggregator application code.\n\nimport { ethers } from 'ethers';\n\nexport interface RelayFeedbackConfig {\n /**\n * ERC-8004 agentId (NFT tokenId) of the **target API** you are calling.\n */\n agentId: string | number;\n /**\n * Whether the API call succeeded.\n */\n success: boolean;\n /**\n * Elapsed milliseconds for the API call.\n */\n responseTimeMs?: number;\n /**\n * Endpoint path of the called API (e.g. '/v1/data').\n */\n endpoint?: string;\n /**\n * Private key of the **relay/third-party** wallet that signs feedback.\n * MUST be different from the API owner's wallet — ReputationRegistry\n * may restrict self-feedback. Wallet needs CREDIT tokens on SKALE Base.\n * Default: process.env.FEEDBACK_WALLET_PRIVATE_KEY\n */\n feedbackWalletPrivateKey?: string;\n /**\n * SKALE Base Sepolia RPC URL.\n * Default: process.env.ERC8004_RPC_URL or SKALE Base Sepolia public RPC.\n */\n rpcUrl?: string;\n /**\n * ERC-8004 ReputationRegistry contract address.\n * Default: process.env.ERC8004_REPUTATION_REGISTRY\n */\n reputationRegistryAddress?: string;\n}\n\nconst RELAY_FEEDBACK_REPUTATION_ABI = [\n 'function giveFeedback(uint256 agentId, int128 value, uint8 valueDecimals, string tag1, string tag2, string endpoint, string feedbackURI, bytes32 feedbackHash) external',\n];\n\n/**\n * Submit ERC-8004 on-chain feedback about a **third-party API** you called.\n *\n * Call this fire-and-forget from your relay/aggregator after every external API call.\n * Uses a separate relay wallet (not the API owner's key) to avoid self-feedback restrictions.\n *\n * Records:\n * - `successRate`: 10000 (= 100%) on success, 0 on failure — 2 decimal places\n * - `responseTime`: elapsed milliseconds\n *\n * @example\n * ```typescript\n * import { submitRelayFeedback } from '@relai-fi/x402/relay-feedback';\n *\n * // after calling an external API:\n * const start = Date.now();\n * const result = await fetch('https://other-api.com/data');\n * submitRelayFeedback({\n * agentId: '5',\n * success: result.ok,\n * responseTimeMs: Date.now() - start,\n * endpoint: '/data',\n * });\n * ```\n */\nexport function submitRelayFeedback(config: RelayFeedbackConfig): void {\n const agentId = String(config.agentId);\n const endpoint = config.endpoint ?? '';\n const responseTimeMs = config.responseTimeMs ?? 0;\n\n const privateKey = config.feedbackWalletPrivateKey\n ?? (typeof process !== 'undefined'\n ? process.env?.FEEDBACK_WALLET_PRIVATE_KEY ?? process.env?.ERC8004_FEEDBACK_WALLET_PRIVATE_KEY\n : undefined);\n const reputationAddress = config.reputationRegistryAddress\n ?? (typeof process !== 'undefined' ? process.env?.ERC8004_REPUTATION_REGISTRY : undefined);\n const rpcUrl = config.rpcUrl\n ?? (typeof process !== 'undefined' ? process.env?.ERC8004_RPC_URL : undefined)\n ?? 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha';\n\n if (!privateKey || !reputationAddress) {\n console.warn('[relai:submitRelayFeedback] FEEDBACK_WALLET_PRIVATE_KEY or ERC8004_REPUTATION_REGISTRY not set — skipping');\n return;\n }\n\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n const signer = new ethers.Wallet(privateKey, provider);\n const reputation = new ethers.Contract(reputationAddress, RELAY_FEEDBACK_REPUTATION_ABI, signer);\n const id = BigInt(agentId);\n\n (async () => {\n const successValue = config.success ? 10000n : 0n;\n try {\n const srTx = await reputation.giveFeedback(\n id, successValue, 2, 'successRate', '', endpoint, '', ethers.ZeroHash,\n );\n await srTx.wait();\n console.log(`[relai:submitRelayFeedback] successRate confirmed agentId=${agentId} success=${config.success}`);\n } catch (err: any) {\n console.warn(`[relai:submitRelayFeedback] successRate failed (non-fatal): ${err?.message}`);\n }\n\n if (responseTimeMs > 0) {\n try {\n const rtTx = await reputation.giveFeedback(\n id, BigInt(Math.max(0, Math.round(responseTimeMs))), 0, 'responseTime', '', endpoint, '', ethers.ZeroHash,\n );\n console.log(`[relai:submitRelayFeedback] responseTime sent agentId=${agentId} ms=${responseTimeMs} tx=${rtTx.hash}`);\n } catch (err: any) {\n console.warn(`[relai:submitRelayFeedback] responseTime failed (non-fatal): ${err?.message}`);\n }\n }\n })();\n}\n","/**\n * Payment Code API — BLIK-style x402 payment codes\n *\n * generatePaymentCode() — sign EIP-3009 authorization and register on SKALE L3\n * redeemPaymentCode() — redeem a code (payee calls this, triggers Base L2 settlement)\n * getPaymentCode() — check code status\n */\n\nexport interface PaymentCodeConfig {\n facilitatorUrl?: string;\n}\n\nexport interface GeneratePaymentCodeParams {\n /** EIP-3009 signer — must implement signTypedData */\n signer: {\n getAddress(): Promise<string>;\n signTypedData(domain: object, types: object, value: object): Promise<string>;\n };\n /** Payee wallet address */\n to: string;\n /** Amount in USDC micro-units (6 decimals), e.g. 1000 = $0.001 */\n value: string | bigint;\n /** USDC contract address on Base L2 (defaults to Base mainnet USDC) */\n usdcContract?: string;\n /** TTL in seconds (default: 120) */\n ttl?: number;\n}\n\nexport interface PaymentCode {\n code: string;\n validBefore: number;\n expiresIn: number;\n}\n\nexport interface RedeemResult {\n success: boolean;\n code: string;\n l3TxHash: string;\n l2TxHash: string;\n explorerUrl: string;\n amount: string;\n from: string;\n to: string;\n}\n\nexport interface CodeStatus {\n code: string;\n from: string;\n to: string;\n value: string;\n validBefore: number;\n redeemed: boolean;\n expired: boolean;\n redeemable: boolean;\n}\n\nconst DEFAULT_FACILITATOR = \"https://relai.fi/facilitator\";\nconst DEFAULT_USDC_BASE = \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\";\n\n// EIP-3009 domain + types for USDC on Base\nconst EIP3009_TYPES = {\n TransferWithAuthorization: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n ],\n};\n\nfunction randomBytes32(): string {\n const bytes = new Uint8Array(32);\n if (typeof globalThis.crypto !== \"undefined\") {\n globalThis.crypto.getRandomValues(bytes);\n } else {\n // Node.js fallback\n const { randomBytes } = require(\"crypto\");\n randomBytes(32).copy(Buffer.from(bytes.buffer));\n }\n return \"0x\" + Array.from(bytes).map(b => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/**\n * Generate a BLIK-style x402 payment code backed by EIP-3009.\n *\n * @example\n * const { code } = await generatePaymentCode(config, {\n * signer: walletClient,\n * to: \"0xMerchant...\",\n * value: \"1000\", // $0.001 USDC\n * ttl: 120,\n * });\n * // code = \"X7K9P2AB\"\n */\nexport async function generatePaymentCode(\n config: PaymentCodeConfig,\n params: GeneratePaymentCodeParams\n): Promise<PaymentCode> {\n const { signer, to, value, usdcContract, ttl = 120 } = params;\n const facilitatorUrl = config.facilitatorUrl || DEFAULT_FACILITATOR;\n const usdc = usdcContract || DEFAULT_USDC_BASE;\n\n const from = await signer.getAddress();\n const now = Math.floor(Date.now() / 1000);\n const validAfter = 0;\n const validBefore = now + ttl;\n const nonce = randomBytes32();\n\n // Sign EIP-3009 authorization\n const domain = {\n name: \"USD Coin\",\n version: \"2\",\n chainId: 8453, // Base mainnet\n verifyingContract: usdc,\n };\n\n const message = {\n from,\n to,\n value: BigInt(value).toString(),\n validAfter,\n validBefore,\n nonce,\n };\n\n const signature = await signer.signTypedData(domain, EIP3009_TYPES, message);\n\n // Register on SKALE L3 via server\n const res = await fetch(`${facilitatorUrl}/payment-codes`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n from,\n to,\n value: BigInt(value).toString(),\n validAfter,\n validBefore,\n nonce,\n signature,\n usdcContract: usdc,\n }),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(`Failed to register payment code: ${(err as any).error || res.status}`);\n }\n\n return res.json() as Promise<PaymentCode>;\n}\n\n/**\n * Redeem a payment code. Triggers Base L2 settlement via relayer.\n *\n * @example\n * const result = await redeemPaymentCode(config, \"X7K9P2AB\");\n * // result.l2TxHash = \"0x...\"\n */\nexport async function redeemPaymentCode(\n config: PaymentCodeConfig,\n code: string\n): Promise<RedeemResult> {\n const facilitatorUrl = config.facilitatorUrl || DEFAULT_FACILITATOR;\n\n const res = await fetch(`${facilitatorUrl}/payment-codes/${code.toUpperCase()}/redeem`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(`Failed to redeem payment code: ${(err as any).error || res.status}`);\n }\n\n return res.json() as Promise<RedeemResult>;\n}\n\n/**\n * Get the status of a payment code.\n */\nexport async function getPaymentCode(\n config: PaymentCodeConfig,\n code: string\n): Promise<CodeStatus> {\n const facilitatorUrl = config.facilitatorUrl || DEFAULT_FACILITATOR;\n\n const res = await fetch(`${facilitatorUrl}/payment-codes/${code.toUpperCase()}`);\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(`Payment code not found: ${(err as any).error || res.status}`);\n }\n\n return res.json() as Promise<CodeStatus>;\n}\n","/**\n * Utility to convert x402 payment payloads between v1 and v2 formats.\n * \n * V1 PaymentPayload format:\n * {\n * \"x402Version\": 1,\n * \"scheme\": \"exact\",\n * \"network\": \"solana\",\n * \"payload\": { ... }\n * }\n * \n * V2 PaymentPayload format:\n * {\n * \"x402Version\": 2,\n * \"resource\": { \"url\": \"...\", \"description\": \"...\", \"mimeType\": \"...\" },\n * \"accepted\": { \"scheme\": \"exact\", \"network\": \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\", ... },\n * \"payload\": { ... }\n * }\n */\n\n// Network name mappings between v1 (simple names) and v2 (CAIP-2)\nexport const NETWORK_V1_TO_V2: Record<string, string> = {\n 'solana': 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n 'solana-devnet': 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n 'base': 'eip155:8453',\n 'base-sepolia': 'eip155:84532',\n 'ethereum': 'eip155:1',\n 'polygon': 'eip155:137',\n 'avalanche': 'eip155:43114',\n 'skale-base': 'eip155:1187947933',\n 'skale-base-sepolia': 'eip155:324705682',\n 'peaq': 'eip155:3338',\n 'sei': 'eip155:1329',\n 'telos': 'eip155:40',\n};\n\nexport const NETWORK_V2_TO_V1: Record<string, string> = Object.fromEntries(\n Object.entries(NETWORK_V1_TO_V2).map(([k, v]) => [v, k])\n);\n\n/**\n * Convert CAIP-2 network identifier to simple v1 network name\n */\nexport function networkV2ToV1(caip2Network: string): string {\n if (!caip2Network) return 'solana';\n \n // Direct lookup\n if (NETWORK_V2_TO_V1[caip2Network]) {\n return NETWORK_V2_TO_V1[caip2Network];\n }\n \n // Handle partial matches for Solana\n if (caip2Network.startsWith('solana:')) {\n const chainId = caip2Network.split(':')[1];\n if (chainId === '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp') return 'solana';\n if (chainId === 'EtWTRABZaYq6iMfeYKouRu166VU2xqa1') return 'solana-devnet';\n return 'solana';\n }\n \n // Handle EVM chains by chain ID\n if (caip2Network.startsWith('eip155:')) {\n const chainId = caip2Network.split(':')[1];\n const mapping: Record<string, string> = {\n '1': 'ethereum',\n '137': 'polygon',\n '8453': 'base',\n '84532': 'base-sepolia',\n '43114': 'avalanche',\n '1187947933': 'skale-base',\n '324705682': 'skale-base-sepolia',\n '3338': 'peaq',\n '1329': 'sei',\n '40': 'telos',\n };\n return mapping[chainId] || caip2Network;\n }\n \n return caip2Network;\n}\n\n/**\n * Convert simple v1 network name to CAIP-2 identifier\n */\nexport function networkV1ToV2(v1Network: string): string {\n if (!v1Network) return 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\n return NETWORK_V1_TO_V2[v1Network] || v1Network;\n}\n\nexport type X402Version = 1 | 2;\n\nexport interface V1PaymentPayload {\n x402Version: 1;\n scheme: string;\n network: string;\n payload: {\n transaction?: string;\n signature?: string;\n authorization?: unknown;\n };\n facilitatorUrl?: string;\n}\n\nexport interface V2PaymentPayload {\n x402Version: 2;\n resource: {\n url: string;\n description?: string;\n mimeType?: string;\n };\n accepted: {\n scheme: string;\n network: string;\n amount?: string;\n maxAmountRequired?: string;\n asset?: string;\n payTo?: string;\n maxTimeoutSeconds?: number;\n extra?: Record<string, unknown>;\n };\n payload: {\n transaction?: string;\n signature?: string;\n authorization?: unknown;\n };\n facilitatorUrl?: string;\n}\n\nexport type PaymentPayload = V1PaymentPayload | V2PaymentPayload;\n\n/**\n * Detect x402 version from payload\n */\nexport function detectPayloadVersion(payload: unknown): X402Version | null {\n if (!payload || typeof payload !== 'object') return null;\n \n const p = payload as Record<string, unknown>;\n \n if (p.x402Version === 1) return 1;\n if (p.x402Version === 2) return 2;\n \n // Heuristics if x402Version is missing\n if ('accepted' in p && 'resource' in p) return 2;\n if ('scheme' in p && 'network' in p && !('accepted' in p)) return 1;\n \n return null;\n}\n\n/**\n * Convert v2 payment payload to v1 format\n */\nexport function convertV2ToV1(v2Payload: V2PaymentPayload): V1PaymentPayload {\n const accepted = v2Payload.accepted || {};\n \n return {\n x402Version: 1,\n scheme: accepted.scheme || 'exact',\n network: networkV2ToV1(accepted.network),\n payload: v2Payload.payload,\n };\n}\n\n/**\n * Convert v1 payment payload to v2 format\n */\nexport function convertV1ToV2(\n v1Payload: V1PaymentPayload,\n resourceInfo: { url?: string; description?: string; mimeType?: string } = {}\n): V2PaymentPayload {\n return {\n x402Version: 2,\n resource: {\n url: resourceInfo.url || '',\n description: resourceInfo.description || '',\n mimeType: resourceInfo.mimeType || 'application/json',\n },\n accepted: {\n scheme: v1Payload.scheme || 'exact',\n network: networkV1ToV2(v1Payload.network),\n },\n payload: v1Payload.payload,\n };\n}\n\n/**\n * Convert payment payload to target version\n */\nexport function convertPayloadToVersion(\n payload: PaymentPayload,\n targetVersion: X402Version,\n options: { resourceInfo?: { url?: string; description?: string; mimeType?: string } } = {}\n): PaymentPayload | null {\n const sourceVersion = detectPayloadVersion(payload);\n \n if (!sourceVersion) {\n console.warn('[payload-converter] Could not detect source payload version');\n return null;\n }\n \n // No conversion needed\n if (sourceVersion === targetVersion) {\n return payload;\n }\n \n // V2 -> V1\n if (sourceVersion === 2 && targetVersion === 1) {\n return convertV2ToV1(payload as V2PaymentPayload);\n }\n \n // V1 -> V2\n if (sourceVersion === 1 && targetVersion === 2) {\n return convertV1ToV2(payload as V1PaymentPayload, options.resourceInfo);\n }\n \n return null;\n}\n\n/**\n * Normalize payment header for target x402 version\n */\nexport function normalizePaymentHeader(\n base64Header: string,\n targetVersion: X402Version,\n options: { resourceInfo?: { url?: string; description?: string; mimeType?: string } } = {}\n): { header: string; payload: PaymentPayload } | null {\n if (!base64Header) return null;\n \n try {\n const decoded = JSON.parse(\n typeof window !== 'undefined' \n ? atob(base64Header) \n : Buffer.from(base64Header, 'base64').toString()\n );\n const converted = convertPayloadToVersion(decoded, targetVersion, options);\n \n if (!converted) {\n return null;\n }\n \n const encoded = typeof window !== 'undefined'\n ? btoa(JSON.stringify(converted))\n : Buffer.from(JSON.stringify(converted)).toString('base64');\n \n return {\n header: encoded,\n payload: converted,\n };\n } catch (e) {\n console.error('[payload-converter] Failed to normalize header:', e);\n return null;\n }\n}\n\n/**\n * Check if network is Solana-based\n */\nexport function isSolanaNetwork(network: string): boolean {\n return network === 'solana' || \n network === 'solana-devnet' || \n network.startsWith('solana:');\n}\n\n/**\n * Check if network is EVM-based\n */\nexport function isEvmNetwork(network: string): boolean {\n const evmNetworks = ['base', 'base-sepolia', 'ethereum', 'polygon', 'avalanche', 'skale-base', 'skale-base-sepolia', 'skale-bite', 'peaq', 'sei', 'telos'];\n return evmNetworks.includes(network) || network.startsWith('eip155:');\n}\n\n// ============================================================================\n// Amount Conversion Utilities\n// ============================================================================\n\n/**\n * Convert USD amount to atomic units\n * @param usd - Amount in USD (e.g., 0.05)\n * @param decimals - Token decimals (default: 6 for USDC)\n * @returns Atomic units as string\n */\nexport function toAtomicUnits(usd: number, decimals: number = 6): string {\n return Math.floor(usd * Math.pow(10, decimals)).toString();\n}\n\n/**\n * Convert atomic units to USD amount\n * @param atomic - Atomic units (string or bigint)\n * @param decimals - Token decimals (default: 6 for USDC)\n * @returns USD amount as number\n */\nexport function fromAtomicUnits(atomic: string | bigint, decimals: number = 6): number {\n const value = typeof atomic === 'bigint' ? atomic : BigInt(atomic);\n return Number(value) / Math.pow(10, decimals);\n}\n\n/**\n * Format USD amount for display\n * @param usd - Amount in USD\n * @param maxDecimals - Maximum decimal places (default: 4)\n * @returns Formatted string\n */\nexport function formatUsd(usd: number, maxDecimals: number = 4): string {\n if (usd < 0.0001) return '<$0.0001';\n return `$${usd.toFixed(maxDecimals).replace(/\\.?0+$/, '')}`;\n}\n"],"mappings":"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","names":["paymentInfo","paymentResponse","normalizeIntegritasOptions","pathPart","normalizeIntegritasFlow","accept","chain","amount"]}
|